From e5a93abad7700d26b8d7363103593491a3f0a212 Mon Sep 17 00:00:00 2001 From: Jeremy Tan Date: Fri, 27 Sep 2013 14:41:48 +0800 Subject: [PATCH] (Almost done) pin refactoring --- notes/pin maps/GPIO pin correspondence.csv | 65 ----- .../GPIO pin correspondence unrestricted.csv | 6 - .../{ => gpio}/GPIO pin correspondence.xls | Bin 17920 -> 22528 bytes notes/pin maps/{ => gpio}/gpioindex_lut.py | 2 +- notes/pin maps/{ => gpio}/gpionums.csv | 6 - notes/pin maps/{ => gpio}/parseit.py | 2 +- notes/pin maps/{ => gpio}/readme.txt | 4 +- server/bbb_pin.c | 251 ++++++++++++------ server/bbb_pin.h | 36 +-- server/bbb_pin_defines.c | 48 ++-- server/bbb_pin_defines.h | 17 +- server/log.h | 3 +- server/main.c | 1 + server/pin_test.c | 31 ++- server/run.sh | Bin 2498 -> 2545 bytes server/sensor.c | 9 +- 16 files changed, 257 insertions(+), 224 deletions(-) delete mode 100644 notes/pin maps/GPIO pin correspondence.csv rename notes/pin maps/{ => gpio}/GPIO pin correspondence unrestricted.csv (88%) rename notes/pin maps/{ => gpio}/GPIO pin correspondence.xls (62%) rename notes/pin maps/{ => gpio}/gpioindex_lut.py (90%) rename notes/pin maps/{ => gpio}/gpionums.csv (89%) rename notes/pin maps/{ => gpio}/parseit.py (96%) rename notes/pin maps/{ => gpio}/readme.txt (66%) diff --git a/notes/pin maps/GPIO pin correspondence.csv b/notes/pin maps/GPIO pin correspondence.csv deleted file mode 100644 index ceb41a2..0000000 --- a/notes/pin maps/GPIO pin correspondence.csv +++ /dev/null @@ -1,65 +0,0 @@ -P8_03,38 -P8_04,39 -P8_05,34 -P8_06,35 -P8_07,66 -P8_08,67 -P8_09,69 -P8_10,68 -P8_11,45 -P8_12,44 -P8_13,23 -P8_14,26 -P8_15,47 -P8_16,46 -P8_17,27 -P8_18,65 -P8_19,22 -P8_20,63 -P8_21,62 -P8_22,37 -P8_23,36 -P8_24,33 -P8_25,1 -P8_26,61 -P8_27,86 -P8_28,88 -P8_29,87 -P8_30,89 -P8_31,10 -P8_32,11 -P8_33,9 -P8_34,81 -P8_35,8 -P8_36,80 -P8_37,78 -P8_38,79 -P8_39,76 -P8_40,77 -P8_41,74 -P8_42,75 -P8_43,72 -P8_44,73 -P8_45,70 -P8_46,71 -P9_11,30 -P9_12,60 -P9_13,31 -P9_14,50 -P9_15,48 -P9_16,51 -P9_17,5 -P9_18,4 -P9_19,13 -P9_20,12 -P9_21,3 -P9_22,2 -P9_23,49 -P9_24,15 -P9_25,117 -P9_26,14 -P9_27,115 -P9_28,113 -P9_29,111 -P9_30,112 -P9_31,110 diff --git a/notes/pin maps/GPIO pin correspondence unrestricted.csv b/notes/pin maps/gpio/GPIO pin correspondence unrestricted.csv similarity index 88% rename from notes/pin maps/GPIO pin correspondence unrestricted.csv rename to notes/pin maps/gpio/GPIO pin correspondence unrestricted.csv index c076e18..e73ff12 100644 --- a/notes/pin maps/GPIO pin correspondence unrestricted.csv +++ b/notes/pin maps/gpio/GPIO pin correspondence unrestricted.csv @@ -4,13 +4,11 @@ P8_09,69 P8_10,68 P8_11,45 P8_12,44 -P8_13,23 P8_14,26 P8_15,47 P8_16,46 P8_17,27 P8_18,65 -P8_19,22 P8_26,61 P8_27,86 P8_28,88 @@ -35,13 +33,9 @@ P8_46,71 P9_11,30 P9_12,60 P9_13,31 -P9_14,50 P9_15,48 -P9_16,51 P9_17,5 P9_18,4 -P9_21,3 -P9_22,2 P9_23,49 P9_24,15 P9_25,117 diff --git a/notes/pin maps/GPIO pin correspondence.xls b/notes/pin maps/gpio/GPIO pin correspondence.xls similarity index 62% rename from notes/pin maps/GPIO pin correspondence.xls rename to notes/pin maps/gpio/GPIO pin correspondence.xls index 3e7d55c549c3eaa383991d0c292e419c6fed7ccb..8b6ca996e1c51d764873ffc174705165a81eb1c4 100644 GIT binary patch literal 22528 zcmeHPYiu0V6+XMRlMOam=doD`i8HZHVmnU!%$vk(9!Y2+nD9zPkn7k>WAG!gowkws z*tX;!m8g&?qDX+$KUJmDsuC3{s!V@T320RnRjsHLs{ZdoR3a7Ne&0EFGP8Fl;Y~#~ zW6j*X-#Pc(J9o~x=bXFa{oQX@oqy(M>)#OXI4E`U?$Qcb7Q-|6+!fZF1@xsQR>QIr zp8=)EXJ`gi=X z!&ru6ScKvo$Sea=C-w3q%9V1pj&8MH*XZ?G<$Xb~2V}LJ&s-<>cK@esk5V&oJX_LF z-_>iYURUCpkzZ(=KP%EF>*Xc%x%ACPsO}=C8#2Q(CzCQJQ}W4DpGJ4d{kGI!g(t8^ zq_w@Zt-GzQcmIj);m4Nxjj+TYN#>TpoDNl&c9u(j(yY^vQx?as?uK6Cl^QlO<>76al`2gTnENtef|xk>z& z!YMV0|Nj}!NWj~3M>wC`Y#!e7@y<)&-Iu_-E`hH|#MzsUr{wyrze1mT4K6m$8oYim zcr;rt&6T<(ma8huv|L@O*K$o|xt3B9E!S2WmcFPf&pE7TPpzQ5Wpc-vQt@oxFZ0uiwe*ck=q3ynZLI-^uHD^7@^;ekX6h$s2I;2AsSB zCvU*X8*uUloV)=iZ@|eLaPkJ7yg?^#(8(Kg@&=u}K__oeK|EO#KD7F8+qc%S%ojjW#)SWz=AJm;Zn;+DjJewcXojjYLy`uwtSBe}dk4=>4 zoG#_XG;3sX#v#W3zYeg@x1e`+9o5G`Vo<%*h?&v(r70 zQhsoHc4}(&Y|qKrnevV0FHeq_@0=@_dlq<^9-Ch%&-F~qj?Y8gkCo@kb6+k`3|%4e zh4OsRQJ$V2??nG2v-9(lC#le+|%QSOKIdaEqM%^s5D63C4*E8}toYYT&=8Cd{!gY1-k zoPi9>cAQ*yYL85P@5t-Y(XeLeTgx-DLY`HnhwHEm);9gf2%ZOI z+nFS+cjVaSk9vPcbCorCkd?*^?~1E(cr3@~90Kn5K61I7#81i82`2~V|G^Q?NH%-K zyPFq2-ur{;+7b2`*5A9loR(a!^Lvdl{$M^SzS+ zG}4cmSex`?Is+ee23DUQy;Rdotz9796Xf0RaXcffSh=~r@h^)t`?#~*^F!A3{7^>j z0wpJ3SNAE>zK-50t97<|E>^E&mn)6_2t0wPU%Fv->df>^aQL`nSE^LHKMiFimxUM9 z&$=ar6+N#QZ>RxIOb>@~WIo0_^f9_WAL9z*WAK4B7@T|!M%U`M|t<)nKa=Fzij#@G)fYG*Hb!drHhI`P!lx!s)nQz%#t?=YYPCAlZoF8lN9_hzqmEkC_YDMn zGzHdfC}pzC)R@+(gbYj~FE_b1)ZqfCB5cDj32iFYhDK#=xMLQzp^g_ovo;K>*w3)` zgK)yNq3K0!XafZrqxQq#h5cBY`ipJqtJ=^;@|ZDe(||V6w#rC}^FUk4L-UNr`vYy! zXtbHUa`2uQ9D!E4UE9%i^1!TJ&S+vZ+7PVW(N?(r4rx0+l{}UvYscB8<{OPRRnX_g z{u)8!eC*bCje18%QRk>>X?bv%lqM%-pK{XT^2$LeSGwL0D~*TQyJFOb>s993Do&2701o4%t`ad$YE-0SwEu!qDRZ5Z zSyGwnsyMkS6u@CJi%#Z0hIqHdDo(Byd0@tQ6*w`Qm7^+?Yetbfrg{%og9g6JU5>_) z9RiIqxsnvQb*h}}jZ^Mc&h^?~$jSAksQkQ#Ym9TzWL{In$yKKa4wJdTI7=pTLlr02 zqN0$WGB>*3+qL(NRh(R*ir_HL7RR|oIa{hYxo#D?)vGc$InGw)+;oxik65XW!q}#= zdysb7-v*2%{Oh{-X#;kIa1gtdyYfHe|6R>L&uq_GL)ɘqab_ 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 diff --git a/notes/pin maps/gpioindex_lut.py b/notes/pin maps/gpio/gpioindex_lut.py similarity index 90% rename from notes/pin maps/gpioindex_lut.py rename to notes/pin maps/gpio/gpioindex_lut.py index a7b600b..a3241e3 100644 --- a/notes/pin maps/gpioindex_lut.py +++ b/notes/pin maps/gpio/gpioindex_lut.py @@ -14,7 +14,7 @@ def doit2(x): lutarr = [] reverse = [] - for i in range(128): + for i in range(118): #Max safe gpio is 117 lutarr.append(lut.get(i, 128)) for i in range(len(rlut)): reverse.append(rlut[i]) diff --git a/notes/pin maps/gpionums.csv b/notes/pin maps/gpio/gpionums.csv similarity index 89% rename from notes/pin maps/gpionums.csv rename to notes/pin maps/gpio/gpionums.csv index d0a7697..a7c061c 100644 --- a/notes/pin maps/gpionums.csv +++ b/notes/pin maps/gpio/gpionums.csv @@ -1,5 +1,3 @@ -2 -3 4 5 8 @@ -8,8 +6,6 @@ 11 14 15 -22 -23 26 27 30 @@ -20,8 +16,6 @@ 47 48 49 -50 -51 60 61 65 diff --git a/notes/pin maps/parseit.py b/notes/pin maps/gpio/parseit.py similarity index 96% rename from notes/pin maps/parseit.py rename to notes/pin maps/gpio/parseit.py index 3ebf5c0..e106f07 100644 --- a/notes/pin maps/parseit.py +++ b/notes/pin maps/gpio/parseit.py @@ -26,7 +26,7 @@ def doit(x): for i in range(0, 93): lutarr.append(lut.get(i, 0)) - for i in range(0, 128): + for i in range(0, 118): #Max safe GPIO is 117 reverselutarr.append(reverselut.get(i, 0)) return (lutarr, reverselutarr) diff --git a/notes/pin maps/readme.txt b/notes/pin maps/gpio/readme.txt similarity index 66% rename from notes/pin maps/readme.txt rename to notes/pin maps/gpio/readme.txt index 89e57b9..905aca5 100644 --- a/notes/pin maps/readme.txt +++ b/notes/pin maps/gpio/readme.txt @@ -1,3 +1,5 @@ GPIO Pin correspondence.xls - all maps with descriptions GPIO pin correspondence unrestricted.csv - all unused pins + hdmi pins -GPIO pin correspondence.csv - all gpio pins \ No newline at end of file +GPIO pin correspondence.csv - all gpio pins + +max usable gpio: 117 \ No newline at end of file diff --git a/server/bbb_pin.c b/server/bbb_pin.c index 5fb7874..db18f69 100644 --- a/server/bbb_pin.c +++ b/server/bbb_pin.c @@ -19,6 +19,7 @@ */ typedef struct { + bool initialised; int fd_value; int fd_direction; } GPIO_Pin; @@ -29,6 +30,7 @@ typedef struct */ typedef struct { + bool initialised; int fd_value; } ADC_Pin; @@ -38,6 +40,7 @@ typedef struct */ typedef struct { + bool initialised; int fd_run; FILE * file_duty; FILE * file_period; @@ -51,50 +54,57 @@ static ADC_Pin g_adc[ADC_NUM_PINS] = {{0}}; /** Array of PWM pins **/ static PWM_Pin g_pwm[PWM_NUM_PINS] = {{0}}; -static char g_buffer[BUFSIZ] = ""; - +static char g_buffer[BUFSIZ] = {0}; /** * Export a GPIO pin and open the file descriptors + * @param pin The GPIO number to be exported + * @return true on success, false otherwise */ -void GPIO_Export(int pin) +bool GPIO_Export(int pin) { - if (pin < 0 || pin >= GPIO_INDEX_SIZE || g_gpio_to_index[pin] == 128) + if (pin < 0 || pin > GPIO_MAX_NUMBER || g_pin_gpio_to_index[pin] == 128) { - Abort("Not a useable pin number: %d", pin); + AbortBool("Not a useable pin number: %d", pin); + } + + GPIO_Pin *gpio = &g_gpio[g_pin_gpio_to_index[pin]]; + if (gpio->initialised) + { + Log(LOGNOTE, "GPIO %d already initialised.", pin); + return true; } - GPIO_Pin *gpio = &g_gpio[g_gpio_to_index[pin]]; // Export the pin sprintf(g_buffer, "%s/export", GPIO_DEVICE_PATH); - FILE * export = fopen(g_buffer, "w"); - if (export == NULL) + FILE * file_export = fopen(g_buffer, "w"); + if (file_export == NULL) { - Abort("Couldn't open %s to export GPIO pin %d - %s", g_buffer, pin, strerror(errno)); + AbortBool("Couldn't open %s to export GPIO pin %d - %s", g_buffer, pin, strerror(errno)); } - - fprintf(export, "%d", pin); - fclose(export); + fprintf(file_export, "%d", pin); + fclose(file_export); // Setup direction file descriptor sprintf(g_buffer, "%s/gpio%d/direction", GPIO_DEVICE_PATH, pin); gpio->fd_direction = open(g_buffer, O_RDWR); if (gpio->fd_direction < 0) { - Abort("Couldn't open %s for GPIO pin %d - %s", g_buffer, pin, strerror(errno)); + AbortBool("Couldn't open %s for GPIO pin %d - %s", g_buffer, pin, strerror(errno)); } - // Setup value file descriptor sprintf(g_buffer, "%s/gpio%d/value", GPIO_DEVICE_PATH, pin); gpio->fd_value = open(g_buffer, O_RDWR); if (gpio->fd_value < 0) { - Abort("Couldn't open %s for GPIO pin %d - %s", g_buffer, pin, strerror(errno)); + close(gpio->fd_direction); + AbortBool("Couldn't open %s for GPIO pin %d - %s", g_buffer, pin, strerror(errno)); } + gpio->initialised = true; Log(LOGDEBUG, "Exported GPIO%d", pin); - //sleep(1); + return true; } /** @@ -102,85 +112,112 @@ void GPIO_Export(int pin) */ void GPIO_Unexport(int pin) { - if (pin < 0 || pin >= GPIO_INDEX_SIZE || g_gpio_to_index[pin] == 128) + if (pin < 0 || pin > GPIO_MAX_NUMBER || g_pin_gpio_to_index[pin] == 128) { Abort("Not a useable pin number: %d", pin); } - GPIO_Pin *gpio = &g_gpio[g_gpio_to_index[pin]]; + GPIO_Pin *gpio = &g_gpio[g_pin_gpio_to_index[pin]]; + if (!gpio->initialised) + { + Abort("GPIO %d is already uninitialised", pin); + } + // Close file descriptors close(gpio->fd_value); close(gpio->fd_direction); + // Uninitialise this one + gpio->initialised = false; // Unexport the pin - if (g_buffer[0] == '\0') sprintf(g_buffer, "%s/unexport", GPIO_DEVICE_PATH); - FILE * export = fopen(g_buffer, "w"); - if (export == NULL) + FILE * file_export = fopen(g_buffer, "w"); + if (file_export == NULL) { Abort("Couldn't open %s to export GPIO pin %d - %s", g_buffer, pin, strerror(errno)); } - fprintf(export, "%d", pin); - fclose(export); + fprintf(file_export, "%d", pin); + fclose(file_export); } - /** * Initialise all PWM pins and open file descriptors * @param pin - The sysfs pin number + * @return true if exported, false otherwise */ -void PWM_Export(int pin) +bool PWM_Export(int pin) { + //goto would make this easier... if (pin < 0 || pin >= PWM_NUM_PINS) { - Abort("Invalid PWM pin number %d specified.", pin); + AbortBool("Invalid PWM pin %d specified.", pin); } PWM_Pin *pwm = &g_pwm[pin]; + if (pwm->initialised) + { + Log(LOGNOTE, "PWM %d already exported.", pin); + return true; + } - if (pwm->file_duty != NULL) + // Try export the pin, doesn't matter if it's already exported. + sprintf(g_buffer, "%s/export", PWM_DEVICE_PATH); + FILE * file_export = fopen(g_buffer, "w"); + if (file_export == NULL) { - Abort("PWM %d already exported.", pin); + AbortBool("Couldn't open %s to export PWM pin %d - %s", + g_buffer, pin, strerror(errno)); } + fprintf(file_export, "%d\n", pin); + fclose(file_export); // Open file descriptors sprintf(g_buffer, "%s/pwm%d/run", PWM_DEVICE_PATH, pin); pwm->fd_run = open(g_buffer, O_WRONLY); if (pwm->fd_run < 0) { - Abort("Couldn't open %s for PWM%d - %s", g_buffer, pin, strerror(errno)); + AbortBool("Couldn't open %s for PWM%d - %s", g_buffer, pin, strerror(errno)); } sprintf(g_buffer, "%s/pwm%d/polarity", PWM_DEVICE_PATH, pin); pwm->fd_polarity = open(g_buffer, O_WRONLY); if (pwm->fd_polarity < 0) { - Abort("Couldn't open %s for PWM%d - %s", g_buffer, pin, strerror(errno)); + close(pwm->fd_run); + AbortBool("Couldn't open %s for PWM%d - %s", g_buffer, pin, strerror(errno)); } sprintf(g_buffer, "%s/pwm%d/period_ns", PWM_DEVICE_PATH, pin); pwm->file_period = fopen(g_buffer, "w"); if (pwm->file_period == NULL) { - Abort("Couldn't open %s for PWM%d - %s", g_buffer, pin, strerror(errno)); + close(pwm->fd_run); + close(pwm->fd_polarity); + AbortBool("Couldn't open %s for PWM%d - %s", g_buffer, pin, strerror(errno)); } sprintf(g_buffer, "%s/pwm%d/duty_ns", PWM_DEVICE_PATH, pin); pwm->file_duty = fopen(g_buffer, "w"); if (pwm->file_duty == NULL) { - Abort("Couldn't open %s for PWM%d - %s", g_buffer, pin, strerror(errno)); + close(pwm->fd_run); + close(pwm->fd_polarity); + fclose(pwm->file_period); + AbortBool("Couldn't open %s for PWM%d - %s", g_buffer, pin, strerror(errno)); } // Don't buffer the streams setbuf(pwm->file_period, NULL); setbuf(pwm->file_duty, NULL); + pwm->initialised = true; Log(LOGDEBUG, "Exported PWM%d", pin); + return true; } + /** * Unexport a PWM pin and close its file descriptors * @param pin - The sysfs pin number @@ -193,40 +230,58 @@ void PWM_Unexport(int pin) } PWM_Pin *pwm = &g_pwm[pin]; - // Close the file descriptors - if (pwm->fd_polarity != -1) - close(pwm->fd_polarity); - if (pwm->fd_run != -1) - close(pwm->fd_run); - if (pwm->file_period != NULL) - fclose(pwm->file_period); - if (pwm->file_duty != NULL) - fclose(pwm->file_duty); + if (!pwm->initialised) + { + Abort("PWM %d not initialised", pin); + } - //So that another call to PWM_Unexport is OK. - pwm->fd_polarity = pwm->fd_run = -1; - pwm->file_period = pwm->file_duty = NULL; + // Close the file descriptors + close(pwm->fd_polarity); + //Stop it, if it's still running + pwrite(pwm->fd_run, "0", 1, 0); + close(pwm->fd_run); + fclose(pwm->file_period); + fclose(pwm->file_duty); + + pwm->initialised = false; + + // Try unexport the pin, doesn't matter if it's already unexported. + sprintf(g_buffer, "%s/unexport", PWM_DEVICE_PATH); + FILE * file_unexport = fopen(g_buffer, "w"); + if (file_unexport == NULL) + { + Abort("Couldn't open %s to unexport PWM pin %d - %s", g_buffer, pin, strerror(errno)); + } + fprintf(file_unexport, "%d\n", pin); + fclose(file_unexport); } - /** * Initialise ADC structures * @param pin The ADC pin number */ -void ADC_Export(int pin) +bool ADC_Export(int pin) { if (pin < 0 || pin >= ADC_NUM_PINS) { - Abort("Invalid ADC pin %d specified.", pin); + AbortBool("Invalid ADC pin %d specified.", pin); + } + else if (g_adc[pin].initialised) + { + Log(LOGNOTE, "ADC %d already initialised", pin); + return true; } sprintf(g_buffer, "%s/in_voltage%d_raw", g_options.adc_device_path, pin); g_adc[pin].fd_value = open(g_buffer, O_RDONLY); if (g_adc[pin].fd_value <0) { - Abort("Couldn't open ADC %d device file %s - %s", pin, g_buffer, strerror(errno)); + AbortBool("Couldn't open ADC %d device file %s - %s", pin, g_buffer, strerror(errno)); } + + g_adc[pin].initialised = true; Log(LOGDEBUG, "Opened ADC %d", pin); + return true; } /** @@ -239,60 +294,71 @@ void ADC_Unexport(int pin) { Abort("Invalid ADC pin %d specified.", pin); } - if (pin != -1) - close(g_adc[pin].fd_value); + else if (!g_adc[pin].initialised) + { + Abort("ADC %d already uninitialised", pin); + } + close(g_adc[pin].fd_value); g_adc[pin].fd_value = -1; + g_adc[pin].initialised = false; } /** * Set a GPIO pin * @param pin - The pin to set. MUST have been exported before calling this function. */ -void GPIO_Set(int pin, bool value) +bool GPIO_Set(int pin, bool value) { - if (pin < 0 || pin >= GPIO_INDEX_SIZE || g_gpio_to_index[pin] == 128) + if (pin < 0 || pin > GPIO_MAX_NUMBER || g_pin_gpio_to_index[pin] == 128) { - Abort("Not a useable pin number: %d", pin); + AbortBool("Not a useable pin number: %d", pin); } - GPIO_Pin *gpio = &g_gpio[g_gpio_to_index[pin]]; - + GPIO_Pin *gpio = &g_gpio[g_pin_gpio_to_index[pin]]; + if (gpio->initialised) + { + AbortBool("GPIO %d is not initialised.", pin); + } + //Set the pin direction if (pwrite(gpio->fd_direction, "out", 3, 0) != 3) { - Abort("Couldn't set GPIO %d direction - %s", pin, strerror(errno)); + AbortBool("Couldn't set GPIO %d direction - %s", pin, strerror(errno)); } - char c = '0' + (value); + char c = value ? '1' : '0'; if (pwrite(gpio->fd_value, &c, 1, 0) != 1) { - Abort("Couldn't read GPIO %d value - %s", pin, strerror(errno)); + AbortBool("Couldn't read GPIO %d value - %s", pin, strerror(errno)); } + return true; } /** * Read from a GPIO Pin * @param pin - The pin to read + * @param result A pointer to store the result + * @return true on success, false otherwise */ -bool GPIO_Read(int pin) +bool GPIO_Read(int pin, bool *result) { - if (pin < 0 || pin >= GPIO_INDEX_SIZE || g_gpio_to_index[pin] == 128) + if (pin < 0 || pin > GPIO_MAX_NUMBER || g_pin_gpio_to_index[pin] == 128) { - Log(LOGERR, "Not a useable pin number: %d", pin); - return false; + AbortBool("Not a useable pin number: %d", pin); } - GPIO_Pin *gpio = &g_gpio[g_gpio_to_index[pin]]; + GPIO_Pin *gpio = &g_gpio[g_pin_gpio_to_index[pin]]; if (pwrite(gpio->fd_direction, "in", 2, 0) != 2) - Log(LOGERR,"Couldn't set GPIO %d direction - %s", pin, strerror(errno)); + AbortBool("Couldn't set GPIO %d direction - %s", pin, strerror(errno)); + char c = '0'; if (pread(gpio->fd_value, &c, 1, 0) != 1) - Log(LOGERR,"Couldn't read GPIO %d value - %s", pin, strerror(errno)); - - return (c == '1'); + AbortBool("Couldn't read GPIO %d value - %s", pin, strerror(errno)); + *result = (c == '1'); + return true; } /** @@ -302,43 +368,57 @@ bool GPIO_Read(int pin) * @param period - The period in ns * @param duty - The time the pin is active in ns */ -void PWM_Set(int pin, bool polarity, long period, long duty) +bool PWM_Set(int pin, bool polarity, long period, long duty) { Log(LOGDEBUG, "Pin %d, pol %d, period: %lu, duty: %lu", pin, polarity, period, duty); if (pin < 0 || pin >= PWM_NUM_PINS) { - Abort("Invalid PWM pin number %d specified.", pin); + AbortBool("Invalid PWM pin number %d specified.", pin); } PWM_Pin *pwm = &g_pwm[pin]; + if (!pwm->initialised) + { + AbortBool("PWM %d is not initialised.", pin); + } // Have to stop PWM before changing it if (pwrite(pwm->fd_run, "0", 1, 0) != 1) { - Abort("Couldn't stop PWM%d - %s", pin, strerror(errno)); + AbortBool("Couldn't stop PWM%d - %s", pin, strerror(errno)); } char c = polarity ? '1' : '0'; if (pwrite(pwm->fd_polarity, &c, 1, 0) != 1) { - Abort("Couldn't set PWM%d polarity - %s", pin, strerror(errno)); + AbortBool("Couldn't set PWM%d polarity - %s", pin, strerror(errno)); + } + + //This must be done first, otherwise period/duty settings can conflict + if (fwrite("0", 1, 1, pwm->file_duty) < 1) + { + AbortBool("Couldn't zero the duty for PWM%d - %s", pin, strerror(errno)); } if (fprintf(pwm->file_period, "%lu", period) < 0) { - Abort("Couldn't set period for PWM%d - %s", pin, strerror(errno)); + AbortBool("Couldn't set period for PWM%d - %s", pin, strerror(errno)); } + if (fprintf(pwm->file_duty, "%lu", duty) < 0) { - Abort("Couldn't set duty cycle for PWM%d - %s", pin, strerror(errno)); + AbortBool("Couldn't set duty cycle for PWM%d - %s", pin, strerror(errno)); } + if (pwrite(pwm->fd_run, "1", 1, 0) != 1) { - Abort("Couldn't start PWM%d - %s", pin, strerror(errno)); + AbortBool("Couldn't start PWM%d - %s", pin, strerror(errno)); } + + return true; } /** @@ -361,17 +441,26 @@ void PWM_Stop(int pin) /** * Read an ADC value * @param id - The ID of the ADC pin to read - * @returns - The reading of the ADC channel + * @param value - A pointer to store the value read from the ADC + * @returns - The true if succeeded, false otherwise. */ -int ADC_Read(int id) +bool ADC_Read(int id, int *value) { char adc_str[ADC_DIGITS] = {0}; - if (pread(g_adc[id].fd_value, adc_str, ADC_DIGITS-1, 0) == -1) + if (id < 0 || id >= ADC_NUM_PINS) + { + AbortBool("Invalid ADC pin %d specified.", id); + } + else if (!g_adc[id].initialised) { - Log(LOGERR, "ADC %d read failed: %s", id, strerror(errno)); - return 0; + AbortBool("ADC %d is not initialised.", id); } - return strtol(adc_str, NULL, 10); -} + if (pread(g_adc[id].fd_value, adc_str, ADC_DIGITS-1, 0) == -1) + { + AbortBool("ADC %d read failed: %s", id, strerror(errno)); + } + *value = strtol(adc_str, NULL, 10); + return true; +} \ No newline at end of file diff --git a/server/bbb_pin.h b/server/bbb_pin.h index ce91e5a..0b5f345 100644 --- a/server/bbb_pin.h +++ b/server/bbb_pin.h @@ -12,42 +12,46 @@ #if defined(_BBB) || defined(_BBB_PIN_SRC) // Initialise / Deinitialise functions -extern void GPIO_Export(int pin); +extern bool GPIO_Export(int pin); extern void GPIO_Unexport(int pin); -extern void PWM_Export(int pin); +extern bool PWM_Export(int pin); extern void PWM_Unexport(int pin); -extern void ADC_Export(int pin); +extern bool ADC_Export(int pin); extern void ADC_Unexport(int pin); // Pin reading/setting functions -extern bool GPIO_Read(int pin); -extern void GPIO_Set(int pin, bool value); +extern bool GPIO_Read(int pin, bool *result); +extern bool GPIO_Set(int pin, bool value); -extern int ADC_Read(int pin); +extern bool ADC_Read(int id, int *value); -extern void PWM_Set(int pin, bool polarity, long period, long duty); // period and duty are in ns +extern bool PWM_Set(int pin, bool polarity, long period, long duty); // period and duty are in ns extern void PWM_Stop(int pin); + #else //Empty defines so it compiles on any platform that's not the BBB -#define GPIO_Export(pin) + +extern bool GPIO_Export(int pin); +extern void GPIO_Unexport(int pin); + +#define GPIO_Export(pin) true #define GPIO_Unexport(pin) -#define PWM_Export(pin) +#define PWM_Export(pin) true #define PWM_Unexport(pin) -#define ADC_Export(pin) +#define ADC_Export(pin) true #define ADC_Unexport(pin) -#define GPIO_Read(pin) 0 -#define GPIO_Set(pin, value) - -#define ADC_Read(pin) 0 +#define GPIO_Read(pin, result) ((*(result) = 0) == 0) +#define GPIO_Set(pin, value) true -#define PWM_Set(pin, polarity, period, duty) -#define PWM_Stop(Pin) +#define ADC_Read(id, value) ((*(value) = 0) == 0) +#define PWM_Set(pin, polarity, period, duty) true +#define PWM_Stop(pin) #endif //_BBB diff --git a/server/bbb_pin_defines.c b/server/bbb_pin_defines.c index ff7caea..df5b5c0 100644 --- a/server/bbb_pin_defines.c +++ b/server/bbb_pin_defines.c @@ -1,47 +1,47 @@ #include "bbb_pin_defines.h" /** - * A lookup table from header number to GPIO pin number. - * e.g P8_13 is g_gpio_lut[0*46+13] = g_gpio_lut[13] - * e.g P9_13 is g_gpio_lut[1*46+13] = g_gpio_lut[59] + * A lookup table from the actual pin number to GPIO number. + * e.g P8_13 is g_pin_real_to_gpio[0*46+13] = g_pin_real_to_gpio[13] + * e.g P9_13 is g_pin_real_to_gpio[1*46+13] = g_pin_real_to_gpio[59] * * Where the returned value is 0, there is no GPIO pin * at that location. */ -const unsigned char g_pin_to_gpio[GPIO_LUT_SIZE] = { - 0, 0, 0, 0, 0, 0, 0, 66, 67, 69, 68, 45, 44, 23, - 26, 47, 46, 27, 65, 22, 0, 0, 0, 0, 0, 0, 61, 86, +const unsigned char g_pin_real_to_gpio[BBB_PIN_COUNT+1] = { + 0, 0, 0, 0, 0, 0, 0, 66, 67, 69, 68, 45, 44, 0, + 26, 47, 46, 27, 65, 0, 0, 0, 0, 0, 0, 0, 61, 86, 88, 87, 89, 10, 11, 9, 81, 8, 80, 78, 79, 76, 77, 74, 75, 72, 73, 70, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 30, 60, 31, 50, 48, 51, 5, 4, 0, 0, 3, 2, 49, + 0, 30, 60, 31, 0, 48, 0, 5, 4, 0, 0, 0, 0, 49, 15, 117, 14, 115, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /** - * Converts GPIO number to index for g_gpio, or 128 if no map. + * Maps a GPIO number to an index into g_gpio (only for use in bbb_pin.c) + * If there is no index for that GPIO number, 128 is returned. */ -const unsigned char g_gpio_to_index[GPIO_INDEX_SIZE] = { - 128, 128, 0, 1, 2, 3, 128, 128, 4, 5, 6, 7, 128, 128, - 8, 9, 128, 128, 128, 128, 128, 128, 10, 11, 128, 128, 12, 13, - 128, 128, 14, 15, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 16, 17, 18, 19, 20, 21, 22, 23, 128, 128, 128, 128, - 128, 128, 128, 128, 24, 25, 128, 128, 128, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 128, 128, - 128, 128, 43, 44, 45, 46, 128, 128, 128, 128, 128, 128, 128, 128, +const unsigned char g_pin_gpio_to_index[GPIO_MAX_NUMBER+1] = { + 128, 128, 128, 128, 0, 1, 128, 128, 2, 3, 4, 5, 128, 128, + 6, 7, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 8, 9, + 128, 128, 10, 11, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 12, 13, 14, 15, 16, 17, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 18, 19, 128, 128, 128, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 128, 128, + 128, 128, 37, 38, 39, 40, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 47, 128, 128, 48, 128, 49, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128 + 41, 128, 128, 42, 128, 43 }; /** - * Converts index number of g_gpio into the gpio number + * Maps an index in g_gpio to the corresponding GPIO number. */ -const unsigned char g_index_to_gpio[GPIO_NUM_PINS] = { - 2, 3, 4, 5, 8, 9, 10, 11, 14, 15, 22, 23, 26, 27, - 30, 31, 44, 45, 46, 47, 48, 49, 50, 51, 60, 61, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 86, 87, 88, 89, 112, 115, 117 +const unsigned char g_pin_index_to_gpio[GPIO_NUM_PINS] = { + 4, 5, 8, 9, 10, 11, 14, 15, 26, 27, 30, 31, 44, 45, + 46, 47, 48, 49, 60, 61, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 86, 87, 88, 89, 112, + 115, 117 }; /** diff --git a/server/bbb_pin_defines.h b/server/bbb_pin_defines.h index 05eb5a9..a7aa932 100644 --- a/server/bbb_pin_defines.h +++ b/server/bbb_pin_defines.h @@ -6,6 +6,9 @@ #ifndef _BBB_PIN_DEFINES_H #define _BBB_PIN_DEFINES_H +/** The number of expansion pins on the BBB **/ +#define BBB_PIN_COUNT 92 + /** GPIO0 defines **/ #define GPIO0_1 1 @@ -111,15 +114,15 @@ #define GPIO2_31 95 #define GPIO2_32 96 +/* Luts */ /** Number of useable GPIO pins **/ -#define GPIO_NUM_PINS 50 +#define GPIO_NUM_PINS 44 +/** The max usable GPIO number **/ +#define GPIO_MAX_NUMBER 117 -/* Luts */ -#define GPIO_LUT_SIZE 93 -#define GPIO_INDEX_SIZE 128 -extern const unsigned char g_pin_to_gpio[GPIO_LUT_SIZE]; -extern const unsigned char g_gpio_to_index[GPIO_INDEX_SIZE]; -extern const unsigned char g_index_to_gpio[GPIO_NUM_PINS]; +extern const unsigned char g_pin_real_to_gpio[BBB_PIN_COUNT+1]; +extern const unsigned char g_pin_gpio_to_index[GPIO_MAX_NUMBER+1]; +extern const unsigned char g_pin_index_to_gpio[GPIO_NUM_PINS]; /** Export path **/ #define GPIO_DEVICE_PATH "/sys/class/gpio" diff --git a/server/log.h b/server/log.h index cc6a7e5..cc038a0 100644 --- a/server/log.h +++ b/server/log.h @@ -11,7 +11,8 @@ #define Fatal(...) FatalEx(__func__, __FILE__, __LINE__, __VA_ARGS__) /*** Macro to abort function ***/ -#define Abort(...) LogEx(LOGERR, __func__, __FILE__, __LINE__, __VA_ARGS__); return +#define Abort(...) { LogEx(LOGERR, __func__, __FILE__, __LINE__, __VA_ARGS__); return; } +#define AbortBool(...) { LogEx(LOGERR, __func__, __FILE__, __LINE__, __VA_ARGS__); return false; } // An enum to make the severity of log messages human readable in code enum {LOGERR=0, LOGWARN=1, LOGNOTE=2, LOGINFO=3,LOGDEBUG=4}; diff --git a/server/main.c b/server/main.c index aff5b83..2ad9dcc 100644 --- a/server/main.c +++ b/server/main.c @@ -9,6 +9,7 @@ #include "sensor.h" #include "actuator.h" #include "control.h" +#include "pin_test.h" #include "bbb_pin_defines.h" // --- Standard headers --- // diff --git a/server/pin_test.c b/server/pin_test.c index 9e3ad23..2db079d 100644 --- a/server/pin_test.c +++ b/server/pin_test.c @@ -12,15 +12,16 @@ */ void Pin_Init() { - for (int i = 0; i < GPIO_NUM_PINS; ++i) + //Don't export anything; make the user do it. + /*for (int i = 0; i < GPIO_NUM_PINS; ++i) GPIO_Export(g_index_to_gpio[i]); for (int i = 0; i < ADC_NUM_PINS; ++i) ADC_Export(i); //Only export 'safe' PWM pins that don't interfere with one another - for (int i = 0; i < PWM_NUM_PINS; ++i) - PWM_Export(g_pin_safe_pwm[i]); + for (int i = 0; i < PWM_NUM_SAFE_PINS; ++i) + PWM_Export(g_pin_safe_pwm[i]);*/ } /** @@ -29,7 +30,7 @@ void Pin_Init() void Pin_Close() { for (int i = 0; i < GPIO_NUM_PINS; ++i) - GPIO_Unexport(g_index_to_gpio[i]); + GPIO_Unexport(g_pin_index_to_gpio[i]); for (int i = 0; i < ADC_NUM_PINS; ++i) ADC_Unexport(i); @@ -106,7 +107,11 @@ void Pin_Handler(FCGIContext *context, char * params) } Log(LOGDEBUG, "Reading GPIO%d", num); FCGI_PrintRaw("Content-type: text/plain\r\n\r\n"); - FCGI_PrintRaw("GPIO%d reads %d\n", num, GPIO_Read(num)); + bool ret; + if (!GPIO_Read(num, &ret)) + FCGI_PrintRaw("GPIO%d read failed. Is it exported?", num); + else + FCGI_PrintRaw("GPIO%d reads %d\n", num, ret); } else if (strcmp(type, "adc") == 0) @@ -118,7 +123,15 @@ void Pin_Handler(FCGIContext *context, char * params) } Log(LOGDEBUG, "Reading ADC%d", num, set); FCGI_PrintRaw("Content-type: text/plain\r\n\r\n"); - FCGI_PrintRaw("ADC%d reads %d\n", num, ADC_Read(num)); + int raw_adc; + if (!ADC_Read(num, &raw_adc)) + { + FCGI_PrintRaw("ADC%d read failed. Is it initialised?", num); + } + else + { + FCGI_PrintRaw("ADC%d reads %d\n", num, raw_adc); + } } else if (strcmp(type, "pwm") == 0) { @@ -153,8 +166,4 @@ void Pin_Handler(FCGIContext *context, char * params) FCGI_RejectJSON(context, "Invalid pin type"); } - - -} - -//EOF +} \ No newline at end of file diff --git a/server/run.sh b/server/run.sh index 98002e98facd10519fb0bfbf53f34309a5af81c4..5c0c61f1a5ceff63839c9305bbaae9035a70e941 100755 GIT binary patch delta 165 zcmXAju?@m76hw=JhLS9B5(N!H?7#@nBZpkDrNoZxPeKYGEQxNm>${djFaVv_Lc-C!Fv~? wu!1VYx`ZU=%B`Y0s70Ho*t?6yNG{h1J!4}=DE<%Y1!#}nlntxhd(KyjAAb)!CIA2c delta 118 zcmew;d`Ngh9rNT*%zcS2`FZLk3Z=!V3I*l4hWf_(rV1tb3i)NJMalWOsS26J#igkV z<(VZJ3dN}fiA9MesS3#%iFtXcISP6CB??KYnR)44%85BS`Q@o8Agv(T^i+kkqSV6D S)V$=%$?KS%H{WLwVg&#value = (double)ADC_Read(ADC0); //ADC #0 on the Beaglebone + ADC_Read(ADC0, &raw_adc); + d->value = (double)raw_adc; //ADC #0 on the Beaglebone //Log(LOGDEBUG, "Got value %f from ADC0", d->value); //GPIO_Set(GPIO0_30, false); set = !set; -- 2.20.1