Thu, 31 Jul 2014 21:04:06 +0200
Added Raspberry GPIO devices
/***************************************************************************** * Copyright (C) 2014 * * Michiel Broek <mbroek at mbse dot eu> * * This file is part of the mbsePi-apps * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * mbsePi-apps is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with thermferm; see the file COPYING. If not, write to the Free * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *****************************************************************************/ #include "devices.h" #include "thermferm.h" #include "xutil.h" extern int debug; extern sys_config Config; extern int my_shutdown; /* * Auto detect hotplugged or known to be present devices */ int devices_detect(void) { struct dirent *de; DIR *fd; devices_list *device, *ndev; int found, subdevices, i, rc = 0; char buf[40]; uuid_t uu; #ifdef HAVE_WIRINGPI_H int pin; #endif /* * Scan for 1-wire devices */ if ((fd = opendir((char *)"/sys/bus/w1/devices"))) { while ((de = readdir(fd))) { if (de->d_name[0] != '.') { found = FALSE; for (device = Config.devices; device; device = device->next) { if (strcmp(device->address,de->d_name) == 0) { found = TRUE; break; } } if (found == FALSE) { strncpy(buf, de->d_name, 2); buf[2] = '\0'; subdevices = 1; if (strcmp(buf, (char *)"29") == 0) subdevices = 8; if (strcmp(buf, (char *)"3a") == 0) subdevices = 2; for (i = 0; i < subdevices; i++) { ndev = (devices_list *)malloc(sizeof(devices_list)); ndev->next = NULL; ndev->version = 1; ndev->uuid = malloc(37); uuid_generate(uu); uuid_unparse(uu, ndev->uuid); ndev->type = DEVTYPE_W1; ndev->direction = DEVDIR_UNDEF; if (strcmp(buf, (char *)"10") == 0) { ndev->direction = DEVDIR_IN_ANALOG; ndev->description = xstrcpy((char *)"DS18S20 Digital thermometer"); } else if (strcmp(buf, (char *)"28") == 0) { ndev->direction = DEVDIR_IN_ANALOG; ndev->description = xstrcpy((char *)"DS18B20 Digital thermometer"); } else if (strcmp(buf, (char *)"29") == 0) { ndev->description = xstrcpy((char *)"DS2408 8 Channel addressable switch/LCD"); } else if (strcmp(buf, (char *)"3a") == 0) { ndev->description = xstrcpy((char *)"DS2413 Dual channel addressable switch"); } else if (strcmp(buf, (char *)"w1") == 0) { ndev->description = xstrcpy((char *)"Master System device"); } else { ndev->description = xstrcpy((char *)"Unknown device family "); ndev->description = xstrcat(ndev->description, buf); } ndev->value = ndev->inuse = 0; ndev->present = DEVPRESENT_YES; ndev->address = xstrcpy(de->d_name); ndev->subdevice = i; ndev->gpiopin = -1; ndev->comment = xstrcpy((char *)"Auto detected device"); ndev->timestamp = time(NULL); if (Config.devices == NULL) { Config.devices = ndev; } else { for (device = Config.devices; device; device = device->next) { if (device->next == NULL) { device->next = ndev; break; } } } rc++; } } } } } #ifdef HAVE_WIRINGPI_H if (piBoardRev() == 2) { /* * Support rev B boards only */ found = FALSE; for (device = Config.devices; device; device = device->next) { if (device->type == DEVTYPE_GPIO) { found = TRUE; break; } } if (found == FALSE) { /* * There were no GPIO devices found. */ subdevices = 12; pin = 0; for (i = 0; i < subdevices; i++) { if (i == 8) pin = 17; ndev = (devices_list *)malloc(sizeof(devices_list)); ndev->next = NULL; ndev->version = 1; ndev->uuid = malloc(37); uuid_generate(uu); uuid_unparse(uu, ndev->uuid); ndev->type = DEVTYPE_GPIO; ndev->value = digitalRead(pin); ndev->present = DEVPRESENT_YES; snprintf(buf, 39, "GPIO%d", i); ndev->address = xstrcpy(buf); snprintf(buf, 39, "Raspberry GPIO %d", i); ndev->description = xstrcpy(buf); ndev->subdevice = i; ndev->gpiopin = pin; ndev->timestamp = time(NULL); if (i == 7) { ndev->direction = DEVDIR_INTERN; ndev->inuse = 1; ndev->comment = xstrcpy((char *)"1-Wire bus"); } else { ndev->direction = DEVDIR_IN_BIN; ndev->inuse = 0; ndev->comment = xstrcpy((char *)"Raspberry GPIO"); } pin++; if (Config.devices == NULL) { Config.devices = ndev; } else { for (device = Config.devices; device; device = device->next) { if (device->next == NULL) { device->next = ndev; break; } } } rc++; } } } #endif return rc; } #ifdef HAVE_WIRINGPI_H PI_THREAD (my_devices_loop) #else void *my_devices_loop(void *threadid) #endif { devices_list *device; // char line[60], *p = NULL; // FILE *fp; // int temp, rc, deviation; syslog(LOG_NOTICE, "Thread my_devices_loop started"); if (debug) fprintf(stdout, "Thread my_devices_loop started\n"); /* * Loop forever until the external shutdown variable is set. */ for (;;) { /* * Here send our 1-wire sensors values */ for (device = Config.devices; device; device = device->next) { if (my_shutdown) break; /* * Build path to the on-wire sensor */ // device = xstrcpy((char *)"/sys/bus/w1/devices/"); // device = xstrcat(device, tmp1->master); // device = xstrcat(device, (char *)"/"); // device = xstrcat(device, tmp1->name); // device = xstrcat(device, (char *)"/w1_slave"); /* * Read sensor data */ // if ((fp = fopen(device, "r"))) { /* * The output looks like: * 72 01 4b 46 7f ff 0e 10 57 : crc=57 YES * 72 01 4b 46 7f ff 0e 10 57 t=23125 */ // fgets(line, 50, fp); // line[strlen(line)-1] = '\0'; // if ((line[36] == 'Y') && (line[37] == 'E')) { /* * CRC is Ok, continue */ // fgets(line, 50, fp); // line[strlen(line)-1] = '\0'; // strtok(line, (char *)"="); // p = strtok(NULL, (char *)"="); // rc = sscanf(p, "%d", &temp); // if ((rc == 1) && (tmp1->lastval != temp)) { /* * It is possible to have read errors or extreme values. * This can happen with bad connections so we compare the * value with the previous one. If the difference is too * much, we don't send that value. That also means that if * the next value is ok again, it will be marked invalid too. * Maximum error is 20 degrees for now. */ // deviation = 20000; // if ( (tmp1->lastval == 0) || // (tmp1->lastval && (temp > (tmp1->lastval - deviation)) && (temp < (tmp1->lastval + deviation))) ) { /* * Temperature is changed and valid, set flag. */ // tmp1->update = TRUE; // } else { // syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, tmp1->lastval, temp); // if (debug) { // fprintf(stdout, "deviation error deviation=%d, old=%d new=%d\n", deviation, tmp1->lastval, temp); // } // } // tmp1->lastval = temp; // } // } else { // syslog(LOG_NOTICE, "sensor %s/%s CRC error", tmp1->master, tmp1->name); // } // fclose(fp); // tmp1->present = 1; // } else { // tmp1->present = 0; // if (debug) // printf("sensor %s is missing\n", tmp1->name); // } // free(device); // device = NULL; } usleep(10000); } syslog(LOG_NOTICE, "Thread my_devices_loop stopped"); if (debug) fprintf(stdout, "Thread my_devices_loop stopped\n"); return 0; }