Small fixes + add ability to un/export pins from pin_test
authorJeremy Tan <[email protected]>
Fri, 27 Sep 2013 08:58:37 +0000 (16:58 +0800)
committerJeremy Tan <[email protected]>
Fri, 27 Sep 2013 08:58:37 +0000 (16:58 +0800)
server/bbb_pin.c
server/bbb_pin.h
server/bbb_pin_defines.c
server/bbb_pin_defines.h
server/pin_test.c

index f351f53..a652b97 100644 (file)
@@ -10,7 +10,6 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <ctype.h>
 #include "options.h"
 
 /**
@@ -109,6 +108,7 @@ bool GPIO_Export(int pin)
 
 /**
  * Unexport a GPIO pin and close its' file descriptors
+ * @param pin The GPIO number to be unexported
  */
 void GPIO_Unexport(int pin)
 {
@@ -349,13 +349,21 @@ bool GPIO_Read(int pin, bool *result)
        }
 
        GPIO_Pin *gpio = &g_gpio[g_pin_gpio_to_index[pin]];
+       if (!gpio->initialised)
+       {
+               AbortBool("GPIO %d is not initialised.", pin);
+       }
 
        if (pwrite(gpio->fd_direction, "in", 2, 0) != 2)
-               AbortBool("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)
+       {
                AbortBool("Couldn't read GPIO %d value - %s", pin, strerror(errno));
+       }
 
        *result = (c == '1');
        return true;
@@ -386,36 +394,36 @@ bool PWM_Set(int pin, bool polarity, long period, long duty)
        // Have to stop PWM before changing it
        if (pwrite(pwm->fd_run, "0", 1, 0) != 1)
        {
-               AbortBool("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)
        {
-               AbortBool("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));
+               AbortBool("Couldn't zero the duty for PWM %d - %s", pin, strerror(errno));
        }
 
        if (fprintf(pwm->file_period, "%lu", period) < 0)
        {
-               AbortBool("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)
        {
-               AbortBool("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)
        {
-               AbortBool("Couldn't start PWM%d - %s", pin, strerror(errno));
+               AbortBool("Couldn't start PWM %d - %s", pin, strerror(errno));
        }
 
        return true;
@@ -424,18 +432,25 @@ bool PWM_Set(int pin, bool polarity, long period, long duty)
 /**
  * Deactivate a PWM pin
  * @param pin - The syfs pin number
+ * @return true on success, false otherwise
  */
-void PWM_Stop(int pin)
+bool PWM_Stop(int pin)
 {
        if (pin < 0 || pin >= PWM_NUM_PINS)
        {
-               Abort("Invalid PWM pin number %d specified.", pin);
+               AbortBool("Invalid PWM pin number %d specified.", pin);
+       }
+       else if (!g_pwm[pin].initialised)
+       {
+               AbortBool("PWM %d is not initialised.", pin);
        }
 
        if (pwrite(g_pwm[pin].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));
        }
+
+       return true;
 }
 
 /**
@@ -461,6 +476,7 @@ bool ADC_Read(int id, int *value)
        {
                AbortBool("ADC %d read failed: %s", id, strerror(errno));
        }
+
        *value = strtol(adc_str, NULL, 10);
        return true;
 }
\ No newline at end of file
index 0b5f345..9eb011e 100644 (file)
@@ -28,10 +28,10 @@ extern bool GPIO_Set(int pin, bool value);
 extern bool ADC_Read(int id, int *value);
 
 extern bool PWM_Set(int pin, bool polarity, long period, long duty); // period and duty are in ns
-extern void PWM_Stop(int pin);
+extern bool PWM_Stop(int pin);
 
 #else
-//Empty defines so it compiles on any platform that's not the BBB
+//'Empty' defines so it compiles on any platform that's not the BBB
 
 extern bool GPIO_Export(int pin);
 extern void GPIO_Unexport(int pin);
@@ -45,13 +45,14 @@ extern void GPIO_Unexport(int pin);
 #define ADC_Export(pin) true
 #define ADC_Unexport(pin)
 
+//Hack to both zero the result field (so it's never uninitialised) and return true
 #define GPIO_Read(pin, result) ((*(result) = 0) == 0)
 #define GPIO_Set(pin, value) true
 
 #define ADC_Read(id, value) ((*(value) = 0) == 0)
 
 #define PWM_Set(pin, polarity, period, duty) true
-#define PWM_Stop(pin)
+#define PWM_Stop(pin) true
 
 #endif //_BBB
 
index df5b5c0..23e03c5 100644 (file)
@@ -1,5 +1,7 @@
 #include "bbb_pin_defines.h"
 
+/* Luts and stuff. Yay magic numbers **/
+
 /** 
  * 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]
@@ -50,4 +52,4 @@ const unsigned char g_pin_index_to_gpio[GPIO_NUM_PINS] = {
  */
 const unsigned char g_pin_safe_pwm[PWM_NUM_SAFE_PINS] = {
        0, 2, 4, 6, 7
-};
\ No newline at end of file
+}; //blergh
\ No newline at end of file
index a7aa932..ea7de7e 100644 (file)
 #define GPIO2_31 95
 #define GPIO2_32 96
 
-/* Luts */
+/** Export path **/
+#define GPIO_DEVICE_PATH "/sys/class/gpio"
+
 /** Number of useable GPIO pins **/
 #define GPIO_NUM_PINS 44
 /** The max usable GPIO number **/
 #define GPIO_MAX_NUMBER 117
 
+/* Luts */
 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"
-
 #define ADC_BITS 12
 #define ADC_DIGITS 5
 #define ADC0 0
index 2db079d..90ae626 100644 (file)
  */
 void Pin_Init()
 {
-       //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_SAFE_PINS; ++i)
-               PWM_Export(g_pin_safe_pwm[i]);*/
+       
 }
 
 /**
@@ -39,6 +30,34 @@ void Pin_Close()
                PWM_Unexport(g_pin_safe_pwm[i]);
 }
 
+bool Pin_Configure(const char *type, int pin_export, int num)
+{
+       bool ret = true;
+
+       if (strcmp(type, "gpo") == 0 || strcmp(type, "gpi") == 0)
+       {
+               if (pin_export < 0)
+                       GPIO_Unexport(num);
+               else
+                       ret = GPIO_Export(num);
+       }
+       else if (strcmp(type, "pwm") == 0)
+       {
+               if (pin_export < 0)
+                       PWM_Unexport(num);
+               else
+                       ret = PWM_Export(num);          
+       }
+       else if (strcmp(type, "adc") == 0)
+       {
+               if (pin_export < 0)
+                       ADC_Unexport(num);
+               else
+                       ret = ADC_Export(num);
+       }
+       return ret;
+}
+
 /**
  * Handle a request to the Pin test module
  * @param context - The FastCGI context
@@ -47,9 +66,10 @@ void Pin_Close()
 void Pin_Handler(FCGIContext *context, char * params)
 {
        
-       char * type = NULL;
+       const char * type = NULL;
        int num = 0;
-       bool set = true;
+       int pin_export = 0;
+       bool set = false;
        bool pol = false;
        double freq = 50;
        double duty = 0.5;
@@ -59,6 +79,7 @@ void Pin_Handler(FCGIContext *context, char * params)
        FCGIValue values[] = {
                {"type", &type, FCGI_REQUIRED(FCGI_STRING_T)},
                {"num", &num, FCGI_REQUIRED(FCGI_INT_T)}, 
+               {"export", &pin_export, FCGI_INT_T},
                {"set", &set, FCGI_BOOL_T},
                {"pol", &pol, FCGI_BOOL_T},
                {"freq", &freq, FCGI_DOUBLE_T},
@@ -69,6 +90,7 @@ void Pin_Handler(FCGIContext *context, char * params)
        typedef enum {
                TYPE,
                NUM,
+               EXPORT,
                SET,
                POL,
                FREQ,
@@ -82,7 +104,19 @@ void Pin_Handler(FCGIContext *context, char * params)
                return;
        }
 
-       Log(LOGDEBUG, "Params: type = %s, num = %d, set = %d, pol = %d, freq = %f, duty = %f", type, num, set, pol, freq, duty);
+       Log(LOGDEBUG, "Params: type = %s, num = %d, export = %d, set = %d, pol = %d, freq = %f, duty = %f", type, num, pin_export, set, pol, freq, duty);
+       if (pin_export != 0)
+       {
+               if (!Pin_Configure(type, pin_export, num))
+               {
+                       FCGI_RejectJSON(context, "Failed to (un)export the pin. Check that a valid number has been specified.");
+                       return;
+               }
+               FCGI_BeginJSON(context, STATUS_OK);
+               FCGI_JSONPair("description", "Pin (un)export OK!");
+               FCGI_EndJSON();
+               return;
+       }
 
        if (strcmp(type, "gpo") == 0)
        {
@@ -93,10 +127,15 @@ void Pin_Handler(FCGIContext *context, char * params)
                }
 
                Log(LOGDEBUG, "Setting GPIO%d to %d", num, set);
-               GPIO_Set(num, set);
-
-               FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
-               FCGI_PrintRaw("GPIO%d set to %d\n", num, set);
+               if (!GPIO_Set(num, set))
+               {
+                       FCGI_RejectJSON(context, "Failed to set the GPIO pin. Check that it's exported.");
+               }
+               else
+               {
+                       FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
+                       FCGI_PrintRaw("GPIO%d set to %d\n", num, set);
+               }
        }
        else if (strcmp(type, "gpi") == 0)
        {
@@ -106,13 +145,16 @@ void Pin_Handler(FCGIContext *context, char * params)
                        return;
                }
                Log(LOGDEBUG, "Reading GPIO%d", num);
-               FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
-               bool ret;
-               if (!GPIO_Read(num, &ret))
-                       FCGI_PrintRaw("GPIO%d read failed. Is it exported?", num);
+               bool val;
+               if (!GPIO_Read(num, &val))
+               {
+                       FCGI_RejectJSON(context, "Failed to read from the GPIO pin. Check that it's exported.");
+               }
                else
-                       FCGI_PrintRaw("GPIO%d reads %d\n", num, ret);
-
+               {
+                       FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
+                       FCGI_PrintRaw("GPIO%d reads %d\n", num, val);
+               }
        }
        else if (strcmp(type, "adc") == 0)
        {
@@ -122,14 +164,14 @@ void Pin_Handler(FCGIContext *context, char * params)
                        return;
                }
                Log(LOGDEBUG, "Reading ADC%d", num, set);
-               FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
                int raw_adc;
                if (!ADC_Read(num, &raw_adc))
                {
-                       FCGI_PrintRaw("ADC%d read failed. Is it initialised?", num);
+                       FCGI_RejectJSON(context, "ADC read failed. Check that it's exported.");
                }
                else
                {
+                       FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
                        FCGI_PrintRaw("ADC%d reads %d\n", num, raw_adc);
                }
        }
@@ -140,8 +182,6 @@ void Pin_Handler(FCGIContext *context, char * params)
                        FCGI_RejectJSON(context, "Invalid PWM pin");
                        return;
                }
-
-               FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
                
                if (set)
                {
@@ -149,14 +189,22 @@ void Pin_Handler(FCGIContext *context, char * params)
                        duty = duty < 0 ? 0 : duty > 1 ? 1 : duty;
                        long period_ns = (long)(1e9 / freq);
                        long duty_ns = (long)(duty * period_ns);
-                       PWM_Set(g_pin_safe_pwm[num], pol, period_ns, duty_ns);
-                       FCGI_PrintRaw("PWM%d set to period_ns = %lu (%f Hz), duty_ns = %lu (%f), polarity = %d", 
-                               num, period_ns, freq, duty_ns, duty*100, (int)pol);
+                       if (!PWM_Set(num, pol, period_ns, duty_ns))
+                       {
+                               FCGI_RejectJSON(context, "PWM set failed. Check if it's exported, and that there's no channel conflict.");
+                       }
+                       else
+                       {
+                               FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
+                               FCGI_PrintRaw("PWM%d set to period_ns = %lu (%f Hz), duty_ns = %lu (%f), polarity = %d", 
+                                       num, period_ns, freq, duty_ns, duty*100, (int)pol);
+                       }
                }
                else
                {
                        Log(LOGDEBUG, "Stopping PWM%d",num);
                        PWM_Stop(g_pin_safe_pwm[num]);
+                       FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
                        FCGI_PrintRaw("PWM%d stopped",num);
                }               
        }

UCC git Repository :: git.ucc.asn.au