semifix. PWM stuff mostly works. ADC should work.
authorJeremy Tan <[email protected]>
Thu, 26 Sep 2013 15:06:29 +0000 (23:06 +0800)
committerJeremy Tan <[email protected]>
Thu, 26 Sep 2013 15:06:29 +0000 (23:06 +0800)
CLEANUP NECESSARY

server/actuator.c
server/bbb_pin.c
server/bbb_pin.h
server/bbb_pin_defines.c
server/bbb_pin_defines.h
server/options.h
server/pin_test.c
server/run.sh

index 40f9b46..f5d7cd6 100644 (file)
@@ -32,7 +32,6 @@ void Actuator_Init()
        // Initialise pins used
        GPIO_Export(GPIO1_16);
        PWM_Export(EHRPWM0A);
-       PWM_Export(EHRPWM0B);
        
 }
 
index 5ab14e9..373bbac 100644 (file)
@@ -126,123 +126,122 @@ void GPIO_Unexport(int pin)
 }
 
 
-
-
 /**
- * Export all PWM pins and open file descriptors
- * @param pin - The pin number
+ * Initialise all PWM pins and open file descriptors
+ * @param pin - The sysfs pin number
  */
 void PWM_Export(int pin)
 {
-       if (pin < 0 || pin > PWM_NUM_PINS)
+       if (pin < 0 || pin >= PWM_NUM_PINS)
        {
-               Abort("Invalid pin number %d", pin);
+               Abort("Invalid PWM pin number %d specified.", pin);
        }
-       
-       // Export the pin
-       sprintf(g_buffer, "%s/export", PWM_DEVICE_PATH);
-       FILE * export = fopen(g_buffer, "w");
-       if (export == NULL)
+
+       PWM_Pin *pwm = &g_pwm[pin];
+
+       if (pwm->file_duty != NULL)
        {
-               Abort("Couldn't open %s to export PWM pin %d - %s", g_buffer, pin, strerror(errno));
+               Abort("PWM %d already exported.", pin);
        }
-       
-       fprintf(export, "%d\n", pin);
-       fclose(export);
 
        // Open file descriptors
        sprintf(g_buffer, "%s/pwm%d/run", PWM_DEVICE_PATH, pin);
-       g_pwm[pin].fd_run = open(g_buffer, O_WRONLY);
-       if (g_pwm[pin].fd_run < 0)
+       pwm->fd_run = open(g_buffer, O_WRONLY);
+       if (pwm->fd_run < 0)
        {
-               Abort("Couldn't open %s for PWM pin %d - %s", g_buffer, pin, strerror(errno));
+               Abort("Couldn't open %s for PWM%d - %s", g_buffer, pin, strerror(errno));
        }
 
-       sprintf(g_buffer, "%s/pwm%d/polarity",PWM_DEVICE_PATH, pin);
-       g_pwm[pin].fd_polarity = open(g_buffer, O_WRONLY);
-       if (g_pwm[pin].fd_polarity < 0)
+       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 pin %d - %s", g_buffer, pin, strerror(errno));
+               Abort("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);
-       g_pwm[pin].file_period = fopen(g_buffer, "w");
-       if (g_pwm[pin].file_period == NULL)
+       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 pin %d - %s", g_buffer, pin, strerror(errno));
+               Abort("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);
-       g_pwm[pin].file_duty = fopen(g_buffer, "w");
-       if (g_pwm[pin].file_duty == NULL)
+       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 pin %d - %s", g_buffer, pin, strerror(errno));
+               Abort("Couldn't open %s for PWM%d - %s", g_buffer, pin, strerror(errno));
        }
 
        // Don't buffer the streams
-       setbuf(g_pwm[pin].file_period, NULL);
-       setbuf(g_pwm[pin].file_duty, NULL);
+       setbuf(pwm->file_period, NULL);
+       setbuf(pwm->file_duty, NULL);   
 
-       
+       Log(LOGDEBUG, "Exported PWM%d", pin);
 }
 
 /**
  * Unexport a PWM pin and close its file descriptors
- * @param pin - The pin number
+ * @param pin - The sysfs pin number
  */
 void PWM_Unexport(int pin)
 {
-       if (pin < 0 || pin > PWM_NUM_PINS)
+       if (pin < 0 || pin >= PWM_NUM_PINS)
        {
-               Abort("Invalid pin number %d", pin);
+               Abort("Invalid PWM pin number %d specified.", pin);
        }
 
+       PWM_Pin *pwm = &g_pwm[pin];
        // Close the file descriptors
-       close(g_pwm[pin].fd_polarity);
-       close(g_pwm[pin].fd_run);
-       fclose(g_pwm[pin].file_period);
-       fclose(g_pwm[pin].file_duty);
-
-       //Unexport the pin
-       sprintf(g_buffer, "%s/unexport", PWM_DEVICE_PATH);
-       FILE * export = fopen(g_buffer, "w");
-       if (export == NULL)
-       {
-               Abort("Couldn't open %s to unexport PWM pin %d - %s", g_buffer, pin, strerror(errno));  
-       }
-       
-       fprintf(export, "%d", pin);
-       fclose(export);
+       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);
+
+       //So that another call to PWM_Unexport is OK.
+       pwm->fd_polarity = pwm->fd_run = -1;
+       pwm->file_period = pwm->file_duty = NULL;
 }
 
+
 /**
- * Export ADC pins; http://beaglebone.cameon.net/home/reading-the-analog-inputs-adc
- * Can't use sysfs like GPIO or PWM pins
- * Bloody annoying how inconsistent stuff is on the Beaglebone
+ * Initialise ADC structures
+ * @param pin The ADC pin number
  */
-void ADC_Export()
+void ADC_Export(int pin)
 {
-       for (int i = 0; i < ADC_NUM_PINS; ++i)
+       if (pin < 0 || pin >= ADC_NUM_PINS)
        {
-               sprintf(g_buffer, "%s/AIN%d", g_options.adc_device_path, i);
-               g_adc[i].fd_value = open(g_buffer, O_RDONLY);
-               if (g_adc[i].fd_value < 0)
-               {
-                       Abort("Couldn't open ADC %d device file %s - %s", i, g_buffer, strerror(errno));
-               }
-
-               //setbuf(g_adc[i].file_value, NULL);
+               Abort("Invalid ADC pin %d specified.", pin);
+       }
 
+       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));
        }
+       Log(LOGDEBUG, "Opened ADC %d", pin);
 }
 
 /**
  * Unexport ADC pins
+ * @param pin The ADC pin number
  */
-void ADC_Unexport()
+void ADC_Unexport(int pin)
 {
-       for (int i = 0; i < ADC_NUM_PINS; ++i)
-               close(g_adc[i].fd_value);
+       if (pin < 0 || pin >= ADC_NUM_PINS)
+       {
+               Abort("Invalid ADC pin %d specified.", pin);
+       }
+       if (pin != -1)
+               close(g_adc[pin].fd_value);     
+
+       g_adc[pin].fd_value = -1;
 }
 
 /**
@@ -297,7 +296,7 @@ bool GPIO_Read(int pin)
 
 /**
  * Activate a PWM pin
- * @param pin - The pin to activate
+ * @param pin - The sysfs pin number
  * @param polarity - if true, pin is active high, else active low
  * @param period - The period in ns
  * @param duty - The time the pin is active in ns
@@ -306,50 +305,52 @@ void PWM_Set(int pin, bool polarity, long period, long duty)
 {
        Log(LOGDEBUG, "Pin %d, pol %d, period: %lu, duty: %lu", pin, polarity, period, duty);
        
-       rewind(g_pwm[pin].file_duty);
-
-       if (fprintf(g_pwm[pin].file_duty, "0") == 0)
+       if (pin < 0 || pin >= PWM_NUM_PINS)
        {
-               Abort("Couldn't zero the duty cycle for PWM %d - s", pin, strerror(errno));
+               Abort("Invalid PWM pin number %d specified.", pin);
        }
-       
+
+       PWM_Pin *pwm = &g_pwm[pin];
+
        // Have to stop PWM before changing it
-       if (pwrite(g_pwm[pin].fd_run, "0", 1, 0) != 1)
+       if (pwrite(pwm->fd_run, "0", 1, 0) != 1)
        {
-               Abort("Couldn't stop PWM %d - %s", pin, strerror(errno));
+               Abort("Couldn't stop PWM%d - %s", pin, strerror(errno));
        }
 
-       char c = '0' + polarity;
-       if (pwrite(g_pwm[pin].fd_polarity, &c, 1, 0) != 1)
+       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));
+               Abort("Couldn't set PWM%d polarity - %s", pin, strerror(errno));
        }
-       
-       rewind(g_pwm[pin].file_period); 
-       rewind(g_pwm[pin].file_duty);
-       if (fprintf(g_pwm[pin].file_period, "%lu", period) == 0)
+
+       if (fprintf(pwm->file_period, "%lu", period) < 0)
        {
-               Abort("Couldn't set period for PWM %d - %s", pin, strerror(errno));
+               Abort("Couldn't set period for PWM%d - %s", pin, strerror(errno));
        }
 
-       if (fprintf(g_pwm[pin].file_duty, "%lu", duty) == 0)
+       if (fprintf(pwm->file_duty, "%lu", duty) < 0)
        {
-               Abort("Couldn't set duty cycle for PWM %d - %s", pin, strerror(errno));
+               Abort("Couldn't set duty cycle for PWM%d - %s", pin, strerror(errno));
        }
 
-       if (pwrite(g_pwm[pin].fd_run, "1", 1, 0) != 1)
+       if (pwrite(pwm->fd_run, "1", 1, 0) != 1)
        {
-               Abort("Couldn't start PWM %d - %s", pin, strerror(errno));
+               Abort("Couldn't start PWM%d - %s", pin, strerror(errno));
        }
-
 }
 
 /**
  * Deactivate a PWM pin
- * @param pin - The pin to turn off
+ * @param pin - The syfs pin number
  */
 void PWM_Stop(int pin)
 {
+       if (pin < 0 || pin >= PWM_NUM_PINS)
+       {
+               Abort("Invalid PWM pin number %d specified.", pin);
+       }
+
        if (pwrite(g_pwm[pin].fd_run, "0", 1, 0) != 1)
        {
                Abort("Couldn't stop PWM %d - %s", pin, strerror(errno));
@@ -363,26 +364,13 @@ void PWM_Stop(int pin)
  */
 int ADC_Read(int id)
 {
-       char adc_str[ADC_DIGITS] = "";
-       lseek(g_adc[id].fd_value, 0, SEEK_SET);
-       
-       int i = 0;
-       for (i = 0; i < ADC_DIGITS-1; ++i)
+       char adc_str[ADC_DIGITS] = {0};
+
+       if (pread(g_adc[id].fd_value, adc_str, ADC_DIGITS-1, 0) == -1)
        {
-               if (read(g_adc[id].fd_value, adc_str+i, 1) != 1)
-                       break;
-               if (adc_str[i] == '\n')
-               {
-                       adc_str[i] = '\0';
-                       break;
-               }
+               Log(LOGERR, "ADC %d read failed: %s", id, strerror(errno));
+               return 0;
        }
 
-       char * end;
-       int val = strtol(adc_str, &end, 10);
-       if (*end != '\0')
-       {
-               Log(LOGERR, "Read non integer from ADC %d - %s", id, adc_str);
-       }       
-       return val;     
+       return strtol(adc_str, NULL, 10);
 }
index 04c02b6..ef8e1be 100644 (file)
@@ -17,8 +17,8 @@ extern void GPIO_Unexport(int pin);
 extern void PWM_Export(int pin);
 extern void PWM_Unexport(int pin);
 
-extern void ADC_Export();
-extern void ADC_Unexport();
+extern void ADC_Export(int pin);
+extern void ADC_Unexport(int pin);
 
 // Pin reading/setting functions
 extern bool GPIO_Read(int pin);
index e89c6dc..ff7caea 100644 (file)
@@ -42,4 +42,12 @@ const unsigned char g_index_to_gpio[GPIO_NUM_PINS] = {
         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
+};
+
+/**
+ * Converts PWM index to PWM number
+ * e.g index 3 becomes 6 for /sys/class/pwm/pwm6
+ */
+const unsigned char g_pin_safe_pwm[PWM_NUM_SAFE_PINS] = {
+       0, 2, 4, 6, 7
 };
\ No newline at end of file
index 844b406..05eb5a9 100644 (file)
@@ -138,22 +138,29 @@ extern const unsigned char g_index_to_gpio[GPIO_NUM_PINS];
 /** Number of ADC pins **/
 #define ADC_NUM_PINS 8
 
-/** Path to export ADCs with**/
-#define ADC_EXPORT_PATH "/sys/devices/bone_capemgr.9/slots"
-/** Path at which ADCs appear **/
-#define ADC_DEVICE_PATH "/sys/devices/ocp.3/helper.16"
-
-/** PWM defines **/
-#define EHRPWM0A 0
-#define EHRPWM0B 1
-// No other PWM pins work!
+#define ADC_DEVICE_PATH "/sys/bus/iio/devices/iio:device0/"
+
+/** PWM names to sysfs numbers **/
+#define EHRPWM0A 0 //P9_22
+#define EHRPWM0B 1 //P9_21 - period paired with EHRPWM0A
+#define EHRPWM1A 3 //P9_14
+#define EHRPWM1B 4 //P9_16 - period paired with EHRPWM1A
+#define ECAP0    2 //P9_42
+#define ECAP2   7 //P9_28
+#define EHRPWM2A 5 //P8_19
+#define EHRPWM2B 6 //P8_13 - period paired with EHRPWM2A
 
 /** Number of PWM pins **/
-#define PWM_NUM_PINS 2
+#define PWM_NUM_PINS 8
+
+/** Number of PWM pins which are guaranteed not to interfere with one another **/
+#define PWM_NUM_SAFE_PINS 5
 
 /** Path to PWM sysfs **/
 #define PWM_DEVICE_PATH "/sys/class/pwm"
 
+/** Maps internal pin number to safe 'pwmX' number **/
+extern const unsigned char g_pin_safe_pwm[PWM_NUM_SAFE_PINS];
 
 #endif //_BBB_PIN_DEFINES_H
 
index f702e01..05f7ddf 100644 (file)
@@ -20,7 +20,7 @@ typedef struct
        struct timeval end_time;
 
        /** Path to ADC files **/
-       char * adc_device_path;
+       const char * adc_device_path;
 
        /*** Horrible horrible hack ***/
        int argc;
index bcdf92e..9e3ad23 100644 (file)
@@ -16,10 +16,11 @@ void Pin_Init()
                GPIO_Export(g_index_to_gpio[i]);
 
        for (int i = 0; i < ADC_NUM_PINS; ++i)
-               ADC_Export();
+               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(i);
+               PWM_Export(g_pin_safe_pwm[i]);
 }
 
 /**
@@ -34,7 +35,7 @@ void Pin_Close()
                ADC_Unexport(i);
 
        for (int i = 0; i < PWM_NUM_PINS; ++i)
-               PWM_Unexport(i);
+               PWM_Unexport(g_pin_safe_pwm[i]);
 }
 
 /**
@@ -121,7 +122,7 @@ void Pin_Handler(FCGIContext *context, char * params)
        }
        else if (strcmp(type, "pwm") == 0)
        {
-               if (num < 0 || num >= PWM_NUM_PINS)
+               if (num < 0 || num >= PWM_NUM_SAFE_PINS)
                {
                        FCGI_RejectJSON(context, "Invalid PWM pin");
                        return;
@@ -135,14 +136,14 @@ 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(num, pol, period_ns, duty_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);
                }
                else
                {
                        Log(LOGDEBUG, "Stopping PWM%d",num);
-                       PWM_Stop(num);
+                       PWM_Stop(g_pin_safe_pwm[num]);
                        FCGI_PrintRaw("PWM%d stopped",num);
                }               
        }
index 18af55b..c3e134c 100755 (executable)
Binary files a/server/run.sh and b/server/run.sh differ

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