Get BBB pin control working
authorSam Moore <[email protected]>
Sat, 21 Sep 2013 17:25:22 +0000 (01:25 +0800)
committerSam Moore <[email protected]>
Sat, 21 Sep 2013 17:25:22 +0000 (01:25 +0800)
Thank god it finally works.

12 files changed:
server/Makefile
server/actuator.c
server/bbb_pin.c [new file with mode: 0644]
server/bbb_pin.h [new file with mode: 0644]
server/bbb_pin_defines.h [new file with mode: 0644]
server/fastcgi.c
server/gpio.c [deleted file]
server/gpio.h [deleted file]
server/pwm.c [deleted file]
server/pwm.h [deleted file]
server/sensor.c
web/gui.js

index fd4d7ec..1302544 100644 (file)
@@ -2,7 +2,7 @@
 CXX = gcc
 FLAGS = -std=c99 -Wall -pedantic -g -I/usr/include/opencv -I/usr/include/opencv2/highgui -L/usr/lib
 LIB = -lfcgi -lssl -lcrypto -lpthread -lm -lopencv_highgui -lopencv_core -lopencv_ml -lopencv_imgproc
-OBJ = log.o control.o data.o fastcgi.o main.o sensor.o actuator.o image.o gpio.o
+OBJ = log.o control.o data.o fastcgi.o main.o sensor.o actuator.o image.o bbb_pin.o
 RM = rm -f
 
 BIN = server
@@ -10,12 +10,6 @@ BIN = server
 
 all : $(BIN) $(BIN2)
 
-stream : stream.c
-       $(CXX) $(FLAGS) -o stream stream.c $(LIB)
-
-intertest : interferometer.c
-       $(CXX) $(FLAGS) -o intertest interferometer.c $(LIB)
-
 
 $(BIN) : $(OBJ)
        $(CXX) $(FLAGS) -o $(BIN) $(OBJ) $(LIB)
index 4df06bc..50a27de 100644 (file)
@@ -6,7 +6,7 @@
 #include "actuator.h"
 #include "options.h"
 // Files containing GPIO and PWM definitions
-#include "gpio.h"
+#include "bbb_pin.h"
 
 
 /** Array of Actuators (global to this file) initialised by Actuator_Init **/
@@ -14,7 +14,7 @@ static Actuator g_actuators[NUMACTUATORS];
 
 /** Human readable names for the Actuators **/
 const char * g_actuator_names[NUMACTUATORS] = {        
-       "actuator_test0", "actuator_test1", "actuator_test2"
+       "actuator_test0", "gpio1_16", "EHRPWM0A_duty@60Hz"
 };
 
 /**
@@ -28,6 +28,11 @@ void Actuator_Init()
                Data_Init(&(g_actuators[i].data_file));
                pthread_mutex_init(&(g_actuators[i].mutex), NULL);
        }
+
+       // Initialise pins used
+       GPIO_Export(GPIO1_16);
+       PWM_Export(EHRPWM0A);
+       
 }
 
 /**
@@ -192,35 +197,15 @@ void Actuator_SetValue(Actuator * a, double value)
                        }
                        break;
                case ACTUATOR_TEST1:
-                       // GPIO pin digital actuator
-                       {
-                               // Quick actuator function for testing pins
-                               // GPIOPin can be passed as argument, but is just defined here for testing purposes
-                               // Modify this to only export on first run, only unexport on shutdown
-                               pinExport(60);
-                               pinDirection(60, 1);
-                               pinSet(value, 60);
-                               pinUnexport(60);
-                       }
+                       GPIO_Set(GPIO1_16, (bool)(value));
                        break;
                case ACTUATOR_TEST2:
+               {
                        // PWM analogue actuator (currently generates one PWM signal with first PWM module)
-                       /*
-                       {
-                               if (pwminit == 0) {                                             // If inactive, start the pwm module
-                                       pwm_init();
-                               }
-                               if (pwmstart == 0) {
-                                       pwm_start();
-                                       pwm_set_period(FREQ);                           // Frequency is 50Hz defined in pwm header file
-                               }
-                               if(value >= 0 && value <= 1000) {
-                                       double duty = value/1000 * 100;         // Convert pressure to duty percentage
-                                       pwm_set_duty((int)duty);                        // Set duty percentage for actuator (0-100%)
-                               }
-                       }
-                       */
+                       static long freq = 16666666; // This is 60Hz
+                       PWM_Set(EHRPWM0A, true, freq, value * freq); // Set the duty cycle
                        break;
+               }
        }
 
        Log(LOGDEBUG, "Actuator %s set to %f", g_actuator_names[a->id], value);
@@ -243,6 +228,7 @@ void Actuator_BeginResponse(FCGIContext * context, ActuatorId id, DataFormat for
                case JSON:
                        FCGI_BeginJSON(context, STATUS_OK);
                        FCGI_JSONLong("id", id);
+                       FCGI_JSONPair("name", g_actuator_names[id]);
                        break;
                default:
                        FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
diff --git a/server/bbb_pin.c b/server/bbb_pin.c
new file mode 100644 (file)
index 0000000..f8ba011
--- /dev/null
@@ -0,0 +1,326 @@
+/**
+ * @file bbb_pin.c
+ * @purpose Implementation of BBB pin control functions and structures
+ * THIS CODE IS NOT THREADSAFE
+ */
+
+#include "bbb_pin.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/**
+ * Structure to represent a GPIO pin
+ * Note: Only accessable to this file; to use the functions pass a GPIOId
+ */
+typedef struct
+{
+       int fd_value;
+       int fd_direction;
+} GPIO_Pin;
+
+/**
+ * Structure to represent an ADC pin
+ * Note: Only accessable to this file; to use the functions pass a ADCId
+ */
+typedef struct
+{
+       FILE * file_value;
+} ADC_Pin;
+
+/**
+ * Structure to represent a PWM pin
+ * Note: Only accessable to this file; to use the functions pass a PWMId
+ */
+typedef struct
+{
+       int fd_run;
+       FILE * file_duty;
+       FILE * file_period;
+       int fd_polarity;
+} PWM_Pin;
+
+/** Array of GPIO pins **/
+static GPIO_Pin g_gpio[GPIO_NUM_PINS] = {{0}};
+/** Array of ADC pins **/
+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] = "";
+
+
+
+
+/**
+ * Export a GPIO pin and open the file descriptors
+ */
+void GPIO_Export(int pin)
+{
+       if (pin < 0 || pin > GPIO_NUM_PINS)
+               Fatal("Invalid pin number %d", pin);
+
+       
+
+       // Export the pin
+       sprintf(g_buffer, "%s/export", GPIO_DEVICE_PATH);
+       FILE * export = fopen(g_buffer, "w");
+       if (export == NULL)
+               Fatal("Couldn't open %s to export GPIO pin %d - %s", g_buffer, pin, strerror(errno));
+
+       fprintf(export, "%d", pin);     
+       fclose(export);
+       
+       // Setup direction file descriptor
+       sprintf(g_buffer, "%s/gpio%d/direction", GPIO_DEVICE_PATH, pin);
+       g_gpio[pin].fd_direction = open(g_buffer, O_RDWR);
+       if (g_gpio[pin].fd_direction < 0)
+               Fatal("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);
+       g_gpio[pin].fd_value = open(g_buffer, O_RDWR);
+       if (g_gpio[pin].fd_value < 0)
+               Fatal("Couldn't open %s for GPIO pin %d - %s", g_buffer, pin, strerror(errno));
+}
+
+/**
+ * Unexport a GPIO pin and close its' file descriptors
+ */
+void GPIO_Unexport(int pin)
+{
+
+       if (pin < 0 || pin > GPIO_NUM_PINS)
+               Fatal("Invalid pin number %d", pin);
+
+       // Close file descriptors
+       close(g_gpio[pin].fd_value);
+       close(g_gpio[pin].fd_direction);
+
+       // 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)
+               Fatal("Couldn't open %s to export GPIO pin %d - %s", g_buffer, pin, strerror(errno));
+
+       fprintf(export, "%d", pin);     
+       fclose(export);
+}
+
+
+
+
+/**
+ * Export all PWM pins and open file descriptors
+ * @param pin - The pin number
+ */
+void PWM_Export(int pin)
+{
+       if (pin < 0 || pin > PWM_NUM_PINS)
+               Fatal("Invalid pin number %d", pin);
+       
+       // Export the pin
+       sprintf(g_buffer, "%s/export", PWM_DEVICE_PATH);
+       FILE * export = fopen(g_buffer, "w");
+       if (export == NULL)
+               Fatal("Couldn't open %s to export PWM pin %d - %s", g_buffer, pin, strerror(errno));
+       
+       fprintf(export, "%d", 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)
+               Fatal("Couldn't open %s for PWM pin %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)
+               Fatal("Couldn't open %s for PWM pin %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)
+               Fatal("Couldn't open %s for PWM pin %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)
+               Fatal("Couldn't open %s for PWM pin %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);
+
+       
+}
+
+/**
+ * Unexport a PWM pin and close its file descriptors
+ * @param pin - The pin number
+ */
+void PWM_Unexport(int pin)
+{
+       if (pin < 0 || pin > PWM_NUM_PINS)
+               Fatal("Invalid pin number %d", 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)
+               Fatal("Couldn't open %s to unexport PWM pin %d - %s", g_buffer, pin, strerror(errno));
+       
+       fprintf(export, "%d", pin);
+       fclose(export);
+
+
+}
+
+/**
+ * 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
+ */
+void ADC_Export()
+{
+       
+       FILE * export = fopen(ADC_EXPORT_PATH, "w");
+       if (export == NULL)
+               Fatal("Couldn't open %s to export ADCs - %s", ADC_EXPORT_PATH, strerror(errno));
+
+       fprintf(export, "cape-bone-iio");
+       fclose(export);
+
+       for (int i = 0; i < ADC_NUM_PINS; ++i)
+       {
+               sprintf(g_buffer, "%s/AIN%d", ADC_DEVICE_PATH, i);
+               g_adc[i].file_value = fopen(g_buffer, "r");
+               if (g_adc[i].file_value == NULL)
+                       Fatal("Couldn't open ADC %d device file %s - %s", i, g_buffer, strerror(errno));
+
+               setbuf(g_adc[i].file_value, NULL);
+
+       }
+}
+
+/**
+ * Unexport ADC pins
+ */
+void ADC_Unexport()
+{
+       for (int i = 0; i < ADC_NUM_PINS; ++i)
+               fclose(g_adc[i].file_value);
+}
+
+/**
+ * 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)
+{
+       if (pwrite(g_gpio[pin].fd_direction, "out", 3*sizeof(char), 0) != 3)
+               Fatal("Couldn't set GPIO %d direction - %s", pin, strerror(errno));
+
+       char c = '0' + (value);
+       if (pwrite(g_gpio[pin].fd_value, &c, 1*sizeof(char), 0) != 1)
+               Fatal("Couldn't read GPIO %d value - %s", pin, strerror(errno));
+
+}
+
+/** 
+ * Read from a GPIO Pin
+ * @param pin - The pin to read
+ */
+bool GPIO_Read(int pin)
+{
+       if (pwrite(g_gpio[pin].fd_direction, "in", 2*sizeof(char), 0) != 2)
+               Fatal("Couldn't set GPIO %d direction - %s", pin, strerror(errno)); 
+       char c = '0';
+       if (pread(g_gpio[pin].fd_value, &c, 1*sizeof(char), 0) != 1)
+               Fatal("Couldn't read GPIO %d value - %s", pin, strerror(errno));
+
+       return (c == '1');
+
+}
+
+/**
+ * Activate a PWM pin
+ * @param pin - The pin to activate
+ * @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
+ */
+void PWM_Set(int pin, bool polarity, long period, long duty)
+{
+       // Have to stop PWM before changing it
+       if (pwrite(g_pwm[pin].fd_run, "0", 1*sizeof(char), 0) != 1)
+               Fatal("Couldn't stop PWM %d - %s", pin, strerror(errno));
+
+       char c = '0' + polarity;
+       if (pwrite(g_pwm[pin].fd_polarity, &c, 1*sizeof(char), 0) != 1)
+               Fatal("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_duty, "%lu", duty) == 0)
+               Fatal("Couldn't set duty cycle for PWM %d - %s", pin, strerror(errno));
+
+       if (fprintf(g_pwm[pin].file_period, "%lu", period) == 0)
+               Fatal("Couldn't set period for PWM %d - %s", pin, strerror(errno));
+       
+       if (pwrite(g_pwm[pin].fd_run, "1", 1*sizeof(char), 0) != 1)
+               Fatal("Couldn't start PWM %d - %s", pin, strerror(errno));
+
+}
+
+/**
+ * Deactivate a PWM pin
+ * @param pin - The pin to turn off
+ */
+void PWM_Stop(int pin)
+{
+       if (pwrite(g_pwm[pin].fd_run, "0", 1*sizeof(char), 0) != 1)
+               Fatal("Couldn't stop PWM %d - %s", pin, strerror(errno));
+
+}
+
+/**
+ * Read an ADC value
+ * @param id - The ID of the ADC pin to read
+ * @returns - The reading of the ADC channel
+ */
+long ADC_Read(int id)
+{
+
+       //Log(LOGDEBUG, "Called for pin %d", id);
+       char adc_val[ADC_DIGITS] = "";
+       rewind(g_adc[id].file_value);
+       fgets(adc_val, sizeof(adc_val)/sizeof(char), g_adc[id].file_value);
+       for(int i = ADC_DIGITS-1; i > 0; --i)
+       {
+               if (adc_val[i] == '\n')
+                       adc_val[i] = '\0';
+       }
+
+       char * end;
+       long val = strtol(adc_val, &end, 10);
+       if (*end != '\0')
+       {
+               Log(LOGERR, "Reading ADC%d gives %s - invalid!", id, adc_val);
+       }
+       //Log(LOGDEBUG, "Returns %lu", val);
+       return val;
+}
diff --git a/server/bbb_pin.h b/server/bbb_pin.h
new file mode 100644 (file)
index 0000000..472a917
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * @file bbb_pin.h
+ * @brief Definition of functions for controlling pins on the Beaglebone Black
+ */
+
+#ifndef _BBB_PIN_H
+#define _BBB_PIN_H
+
+#include "common.h"
+
+#include "bbb_pin_defines.h"
+
+// Initialise / Deinitialise functions
+extern void GPIO_Export(int pin);
+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();
+
+// Pin reading/setting functions
+extern bool GPIO_Read(int pin);
+extern void GPIO_Set(int pin, bool value);
+
+extern long ADC_Read(int pin);
+
+extern void PWM_Set(int pin, bool polarity, long period, long duty); // period and duty are in ns
+extern void PWM_Stop(int pin);
+
+
+
+#endif //_BBB_PIN_H
+
+//EOF
diff --git a/server/bbb_pin_defines.h b/server/bbb_pin_defines.h
new file mode 100644 (file)
index 0000000..dba2d5c
--- /dev/null
@@ -0,0 +1,154 @@
+/**
+ * @file bbb_pin_defines.h
+ * @brief Defines pins on Beaglebone Black
+ */
+
+#ifndef _BBB_PIN_DEFINES_H
+#define _BBB_PIN_DEFINES_H
+
+/** GPIO0 defines **/
+
+#define GPIO0_1 1
+#define GPIO0_2 2
+//#define GPIO0_3 3 // Used for PWM
+//#define GPIO0_4 4 // Used for PWM
+#define GPIO0_5 5
+#define GPIO0_6 6
+#define GPIO0_7 7
+#define GPIO0_8 8
+#define GPIO0_9 9
+#define GPIO0_10 10
+#define GPIO0_11 11
+#define GPIO0_12 12
+#define GPIO0_13 13
+#define GPIO0_14 14
+#define GPIO0_15 15
+#define GPIO0_16 16
+#define GPIO0_17 17
+#define GPIO0_18 18
+#define GPIO0_19 19
+#define GPIO0_20 20
+#define GPIO0_21 21
+#define GPIO0_22 22
+#define GPIO0_23 23
+#define GPIO0_24 24
+#define GPIO0_25 25
+#define GPIO0_26 26
+#define GPIO0_27 27
+#define GPIO0_28 28
+#define GPIO0_29 29
+#define GPIO0_30 30
+#define GPIO0_31 31
+#define GPIO0_32 32
+
+/** GPIO1 defines **/
+
+#define GPIO1_1 33
+#define GPIO1_2 34
+#define GPIO1_3 35
+#define GPIO1_4 36
+#define GPIO1_5 37
+#define GPIO1_6 38
+#define GPIO1_7 39
+#define GPIO1_8 40
+#define GPIO1_9 41
+#define GPIO1_10 42
+#define GPIO1_11 43
+#define GPIO1_12 44
+#define GPIO1_13 45
+#define GPIO1_14 46
+#define GPIO1_15 47
+#define GPIO1_16 48
+#define GPIO1_17 49
+#define GPIO1_18 50
+#define GPIO1_19 51
+#define GPIO1_20 52
+#define GPIO1_21 53
+#define GPIO1_22 54
+#define GPIO1_23 55
+#define GPIO1_24 56
+#define GPIO1_25 57
+#define GPIO1_26 58
+#define GPIO1_27 59
+#define GPIO1_28 60
+#define GPIO1_29 61
+#define GPIO1_30 62
+#define GPIO1_31 63
+#define GPIO1_32 64
+
+/** GPIO2 defines **/
+
+#define GPIO2_1 65
+#define GPIO2_2 66
+#define GPIO2_3 67
+#define GPIO2_4 68
+#define GPIO2_5 69
+#define GPIO2_6 70
+#define GPIO2_7 71
+#define GPIO2_8 72
+#define GPIO2_9 73
+#define GPIO2_10 74
+#define GPIO2_11 75
+#define GPIO2_12 76
+#define GPIO2_13 77
+#define GPIO2_14 78
+#define GPIO2_15 79
+#define GPIO2_16 80
+#define GPIO2_17 81
+#define GPIO2_18 82
+#define GPIO2_19 83
+#define GPIO2_20 84
+#define GPIO2_21 85
+#define GPIO2_22 86
+#define GPIO2_23 87
+#define GPIO2_24 88
+#define GPIO2_25 89
+#define GPIO2_26 90
+#define GPIO2_27 91
+#define GPIO2_28 92
+#define GPIO2_29 93
+#define GPIO2_30 94
+#define GPIO2_31 95
+#define GPIO2_32 96
+
+/** Number of GPIO pins **/
+#define GPIO_NUM_PINS 97
+
+/** Export path **/
+#define GPIO_DEVICE_PATH "/sys/class/gpio"
+
+#define ADC_BITS 12
+#define ADC_DIGITS 5
+#define ADC0 0
+#define ADC1 1
+#define ADC2 2
+#define ADC3 3
+#define ADC4 4
+#define ADC5 5
+#define ADC6 6
+#define ADC7 7
+
+/** 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!
+
+/** Number of PWM pins **/
+#define PWM_NUM_PINS 2
+
+/** Path to PWM sysfs **/
+#define PWM_DEVICE_PATH "/sys/class/pwm"
+
+
+
+#endif //_BBB_PIN_DEFINES_H
+
+
index b7a3e6b..e391fcd 100644 (file)
@@ -446,15 +446,17 @@ void * FCGI_RequestLoop (void *data)
 {
        FCGIContext context = {0};
        
-       Log(LOGDEBUG, "First request...");
+       Log(LOGDEBUG, "Start loop");
        while (FCGI_Accept() >= 0) {
-               Log(LOGDEBUG, "Got request #%d", context.response_number);
+               
                ModuleHandler module_handler = NULL;
                char module[BUFSIZ], params[BUFSIZ];
                
                //strncpy doesn't zero-truncate properly
                snprintf(module, BUFSIZ, "%s", getenv("DOCUMENT_URI_LOCAL"));
                snprintf(params, BUFSIZ, "%s", getenv("QUERY_STRING"));
+
+               Log(LOGDEBUG, "Got request #%d - Module %s, params %s", context.response_number, module, params);
                
                //Remove trailing slashes (if present) from module query
                size_t lastchar = strlen(module) - 1;
@@ -488,7 +490,7 @@ void * FCGI_RequestLoop (void *data)
                }
                context.response_number++;
 
-               Log(LOGDEBUG, "Waiting for request #%d", context.response_number);
+               
        }
 
        Log(LOGDEBUG, "Thread exiting.");
diff --git a/server/gpio.c b/server/gpio.c
deleted file mode 100644 (file)
index 6370df6..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-#include "gpio.h"
-
-void pinExport(int GPIOPin) {
-       
-       char GPIOString[4];
-       char setValue[4];
-       sprintf(GPIOString, "%d", GPIOPin);
-
-       FILE * myOutputHandle = fopen(exportPath, "ab");
-       if (myOutputHandle == NULL)
-       {
-               Log(LOGERR, "Unable to export GPIO pin %f\n", GPIOPin);
-       }
-       strcpy(setValue, GPIOString);
-       fwrite(&setValue, sizeof(char), 2, myOutputHandle);
-       fclose(myOutputHandle);
-}
-
-void pinDirection(int GPIOPin, int io) {
-       char setValue[4];
-       char GPIODirection[64];
-       FILE *myOutputHandle = NULL;
-       snprintf(GPIODirection, sizeof(GPIODirection), "%s%d%s", directionPath, GPIOPin, "/direction");
-       if ((myOutputHandle = fopen(GPIODirection, "rb+")) == NULL){
-               Log(LOGERR, "Unable to open direction handle for pin %f\n", GPIOPin);
-       }
-       if (io == 1) 
-       {
-               strcpy(setValue,"out");
-               fwrite(&setValue, sizeof(char), 3, myOutputHandle);
-       }
-       else if (io == 0) 
-       {
-               strcpy(setValue,"in");
-               fwrite(&setValue, sizeof(char), 2, myOutputHandle);
-       }
-       else Log(LOGERR, "GPIO direction must be 1 or 0\n");
-       fclose(myOutputHandle);
-}
-
-void pinSet(double value, int GPIOPin) {
-       int val = (int)value;
-       char GPIOValue[64];
-       char setValue[4];
-       FILE *myOutputHandle = NULL;
-       snprintf(GPIOValue, sizeof(GPIOValue), "%s%d%s", valuePath, GPIOPin, "/value");
-       if (val == 1) {
-               if ((myOutputHandle = fopen(GPIOValue, "rb+")) == NULL){
-                       Log(LOGERR, "Unable to open value handle for pin %f\n", GPIOPin);
-               }
-               strcpy(setValue, "1"); // Set value high
-               fwrite(&setValue, sizeof(char), 1, myOutputHandle);
-       }
-       else if (val == 0){
-               if ((myOutputHandle = fopen(GPIOValue, "rb+")) == NULL){
-                       Log(LOGERR, "Unable to open value handle for pin %f\n", GPIOPin);
-               }
-               strcpy(setValue, "0"); // Set value low
-               fwrite(&setValue, sizeof(char), 1, myOutputHandle);
-       }
-       else Log(LOGERR, "GPIO value must be 1 or 0\n");
-       fclose(myOutputHandle);
-}
-
-/** Open an ADC and return the voltage value from it
-*      @param adc_num - ADC number, ranges from 0 to 7 on the Beaglebone
-       @return the converted voltage value if successful
-*/
-
-//TODO: create a function to lookup the ADC or pin number instead of manually
-//             specifying it here (so we can keep all the numbers in one place)
-
-int ADCRead(int adc_num)
-{
-       char adc_path[64];
-       snprintf(adc_path, sizeof(adc_path), "%s%d", ADCPath, adc_num);         // Construct ADC path
-       int sensor = open(adc_path, O_RDONLY);                                                          
-       char buffer[64];                                                                                                        // I think ADCs are only 12 bits (0-4096), buffer can probably be smaller
-       int r = read(sensor, buffer, sizeof(buffer));
-       if (r != -1) {
-               buffer[r] = '\0';
-               int value = atoi(buffer);
-               double convert = (value/4096) * 1000;                                                   // Random conversion factor, will be different for each sensor (get from datasheets)
-               // lseek(sensor, 0, 0); (I think this is uneeded as we are reopening the file on each sensor read; if sensor is read continously we'll need this
-               close(sensor);
-               return convert;
-       }
-       else {
-               Log(LOGERR, "Failed to get value from ADC %f\n", adc_num);
-               close(sensor);
-               return -1;
-       }
-}
-
-/** Open a digital pin and return the value from it
-*      @param pin_num - pin number, specified by electronics team
-       @return 1 or 0 if reading was successful
-*/
-
-int pinRead(int GPIOPin)
-{
-       char GPIOValue[64];
-       snprintf(GPIOValue, sizeof(GPIOValue), "%s%d%s", valuePath, GPIOPin, "/value"); //construct pin path
-       int pin = open(GPIOValue, O_RDONLY);
-       char ch;
-       lseek(pin, 0, SEEK_SET);
-       int r = read(pin, &ch, sizeof(ch));
-       if (r != -1) 
-       {
-               if (ch != '0') {
-                       close(pin);
-                       return 1;
-               }
-               else {
-                       close(pin);
-                       return 0;
-               }
-       }
-       else 
-       {
-               Log(LOGERR, "Failed to get value from pin %f\n", GPIOPin);
-               close(pin);
-               return -1;
-       }
-}
-
-void pinUnexport(int GPIOPin) {
-       char setValue[4];
-       char GPIOString[4];
-       sprintf(GPIOString, "%d", GPIOPin);
-       FILE *myOutputHandle = NULL;
-       if ((myOutputHandle = fopen(unexportPath, "ab")) == NULL) {
-               Log(LOGERR, "Couldn't unexport GPIO pin %f\n", GPIOPin);
-       }
-       strcpy(setValue, GPIOString);
-       fwrite(&setValue, sizeof(char), 2, myOutputHandle);
-       fclose(myOutputHandle);
-}
diff --git a/server/gpio.h b/server/gpio.h
deleted file mode 100644 (file)
index b4ded0c..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <sys/wait.h>
-#include <sched.h>
-#include <stdint.h>
-
-#include "common.h"
-
-#define exportPath             "/sys/class/gpio/export"
-#define unexportPath   "/sys/class/gpio/unexport"
-#define valuePath              "/sys/class/gpio/gpio"
-#define directionPath  "/sys/class/gpio/gpio"
-#define ADCPath                "/sys/devices/platform/tsc/ain"
-
-void pinExport(int GPIOPin);
-void pinDirection(int GPIOPin, int io);
-void pinSet(double value, int GPIOPin);
-void pinUnexport(int GPIOPin);
-int pinRead(int GPIOPin);
-int ADCRead(int adc_num);
diff --git a/server/pwm.c b/server/pwm.c
deleted file mode 100644 (file)
index b86b07e..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-#include "pwm.h"
-
-/* Initialize PWM : 
-1/ mmap /dev/mem to have write access to system clock 
-2/ enable system clock (0x0 = disabled, 0x02 = enabled)
-3/ set correct pin MUX 
-
-can modify pwm variables through virtual filesystem:
-"/sys/class/pwm/ehrpwm.1:0/..."
-
-pwm drivers reference:
-http://processors.wiki.ti.com/index.php/AM335x_PWM_Driver%27s_Guide */
-
-static int pwminit = 0;
-static int pwmstart = 0;
-
-void pwm_init(void) {
-    FILE *pwm_mux;
-    int i;
-    volatile uint32_t *epwmss1;
-    
-    int fd = open("/dev/mem", O_RDWR);
-    
-    if(fd < 0)
-        {
-        printf("Can't open /dev/mem\n");
-        exit(1);
-        }
-
-    epwmss1 = (volatile uint32_t *) mmap(NULL, LENGTH, PROT_READ|PROT_WRITE, MAP_SHARED, fd, START);
-    if(epwmss1 == NULL)
-        {
-        printf("Can't mmap\n");
-        exit(1);
-        }
-    else
-       {
-               epwmss1[OFFSET_1 / sizeof(uint32_t)] = 0x2;
-               }
-    close(fd);
-    pwminit = 1;
-    pwm_mux = fopen(PWMMuxPath, "w");
-    fprintf(pwm_mux, "6");                                                      // pwm is mux mode 6
-    fclose(pwm_mux);
-}
-
-//can change filepath of pwm module "/ehrpwm.%d:0/" by passing %d as argument
-//depends how many pwm modules we have to run
-//TODO:
-
-void pwm_start(void) {
-    FILE *pwm_run;
-    pwm_run = fopen(PWMRunPath, "w");
-    fprintf(pwm_run, "1");
-    fclose(pwm_run);
-       pwmstart = 1;
-}
-
-void pwm_stop(void) {
-    FILE *pwm_run;
-    pwm_run = fopen(PWMRunPath, "w");
-    fprintf(pwm_run, "0");
-    fclose(pwm_run);
-       pwmstart = 0;
-}
-
-//duty_percent is just a regular percentage (i.e. 50 = 50%)
-
-void pwm_set_duty(int duty_percent) {
-    FILE *pwm_duty;
-    pwm_duty = fopen(PWMDutyPath, "w"); 
-    fprintf(pwm_duty, "%d", duty_percent);
-    fclose(pwm_duty);
-}
-
-//freq is just normal frequency (i.e. 100 = 100Hz)
-
-void pwm_set_period(int freq) {
-    FILE *pwm_period;
-    pwm_period = fopen(PWMFreqPath, "w");
-    fprintf(pwm_period, "%d", freq);
-    fclose(pwm_period);
-}
\ No newline at end of file
diff --git a/server/pwm.h b/server/pwm.h
deleted file mode 100644 (file)
index 2c9411b..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <sys/wait.h>
-#include <sched.h>
-#include <stdint.h>
-
-#define START          0x44e00000    // see datasheet of AM335x
-#define LENGTH         1024
-#define OFFSET_1       0xcc          // offset of PWM1 clock (see datasheet of AM335x p.1018)
-#define FREQ           50                         //50Hz pwm frequency for pressure regulator
-#define PWMMuxPath     "/sys/kernel/debug/omap_mux/gpmc_a2"
-#define PWMRunPath     "/sys/class/pwm/ehrpwm.1:0/run"
-#define PWMDutyPath    "/sys/class/pwm/ehrpwm.1:0/duty_percent"
-#define PWMFreqPath    "/sys/class/pwm/ehrpwm.1:0/period_freq"
-
-void pwm_init(void);
-void pwm_start(void);
-void pwm_stop(void);
-void pwm_set_duty(int duty_percent);
-void pwm_set_period(int freq);
\ No newline at end of file
index a3580b7..9d0b33c 100644 (file)
@@ -7,7 +7,7 @@
 #include "common.h"
 #include "sensor.h"
 #include "options.h"
-#include "gpio.h"
+#include "bbb_pin.h"
 #include <math.h>
 
 /** Array of sensors, initialised by Sensor_Init **/
@@ -18,8 +18,8 @@ const SensorThreshold thresholds[NUMSENSORS]= {
        //Max Safety, Min safety, Max warning, Min warning
        {1,-1,1,-1},            // ANALOG_TEST0
        {500,0,499,0},          // ANALOG_TEST1
+       {5000,0,5000,0},                // ANALOG_REALTEST
        {5,-5,4,-4},            // ANALOG_FAIL0
-       {500,0,499,0},          // ANALOG_REALTEST
        {1,0,1,0},                      // DIGITAL_TEST0
        {1,0,1,0},                      // DIGITAL_TEST1
        {1,0,1,0},                      // DIGITAL_REALTEST
@@ -45,6 +45,14 @@ void Sensor_Init()
                Data_Init(&(g_sensors[i].data_file));
                g_sensors[i].record_data = false;       
        }
+
+       // Get the ADCs
+       ADC_Export();
+
+       // GPIO1_28 used as a pulse for sampling
+       GPIO_Export(GPIO1_28);
+       // GPIO0_30 toggled during sampling
+       GPIO_Export(GPIO0_30);
 }
 
 /**
@@ -154,9 +162,32 @@ bool Sensor_Read(Sensor * s, DataPoint * d)
        gettimeofday(&t, NULL);
        d->time_stamp = TIMEVAL_DIFF(t, *Control_GetStartTime());
 
+       static bool result = true;
+       
+       
        // Read value based on Sensor Id
        switch (s->id)
        {
+               case ANALOG_REALTEST:
+               {
+                       static bool set = false;
+                       
+                       GPIO_Set(GPIO0_30, true);
+                       d->value = (double)ADC_Read(ADC0);      //ADC #0 on the Beaglebone
+                       //Log(LOGDEBUG, "Got value %f from ADC0", d->value);
+                       GPIO_Set(GPIO0_30, false);
+                       set = !set;
+                       GPIO_Set(GPIO1_28, set);
+                       
+                       break;
+               }
+               
+               default:
+                       d->value = rand() % 2;
+                       usleep(1000000);
+                       break;
+               
+
                case ANALOG_TEST0:
                {
                        d->value = (double)(rand() % 100) / 100;
@@ -169,18 +200,15 @@ bool Sensor_Read(Sensor * s, DataPoint * d)
                        d->value = count++;
                        break;
                }
-               case ANALOG_REALTEST:
-               {
-                       //d->value = ADCRead(0);        //ADC #0 on the Beaglebone
-                       break;
-               }
+
                case ANALOG_FAIL0:
-                       d->value = 250;
+                       d->value = 0;
                        //d->value = (double)(rand() % 6) * -( rand() % 2) / ( rand() % 100 + 1);
                        //Gives a value between -5 and 5
                        break;
                case DIGITAL_TEST0:
                        d->value = t.tv_sec % 2;
+
                        break;
                case DIGITAL_TEST1:
                        d->value = (t.tv_sec+1)%2;
@@ -198,17 +226,17 @@ bool Sensor_Read(Sensor * s, DataPoint * d)
                        d->value = rand() % 2; 
                        //Gives 0 or 1 or a 2 every 1/100 times
                        break;
-               default:
-                       Fatal("Unknown sensor id: %d", s->id);
-                       break;
+               //default:
+               //      Fatal("Unknown sensor id: %d", s->id);
+               //      break;
        }       
-       usleep(100000); // simulate delay in sensor polling
+       
 
        // Perform sanity check based on Sensor's ID and the DataPoint
        Sensor_CheckData(s->id, d->value);
 
        // Update latest DataPoint if necessary
-       bool result = (d->value != s->newest_data.value);
+       
        if (result)
        {
                s->newest_data.time_stamp = d->time_stamp;
@@ -290,6 +318,7 @@ void Sensor_BeginResponse(FCGIContext * context, SensorId id, DataFormat format)
                case JSON:
                        FCGI_BeginJSON(context, STATUS_OK);
                        FCGI_JSONLong("id", id);
+                       FCGI_JSONPair("name", g_sensor_names[id]);
                        break;
                default:
                        FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
index da4e0d0..7d7a8fe 100644 (file)
@@ -8,7 +8,7 @@ $(document).ready(function()
 {
 
        g_sensors = []
-       g_numSensors = 2
+       g_numSensors = 1
        g_storeTime = []
        g_key = null
 
@@ -44,7 +44,7 @@ $(document).ready(function()
        $.fn.updateSensor = function(json)
        {
                //console.log(json.data)
-               var sensor = g_sensors[json.id]
+               var sensor = g_sensors[0]
                var most_recent = null
                if (sensor.length > 0)
                        most_recent = sensor[sensor.length-1][0]
@@ -62,7 +62,7 @@ $(document).ready(function()
                
                //console.log("Plot:")
                //console.log(g_sensors[json.id])
-               $.plot("#sensor"+String(json.id)+"_plot", [g_sensors[json.id]])
+               $.plot("#sensor"+String(0)+"_plot", [g_sensors[0]])
                $.ajax({url : "/api/sensors", data : {id : json.id}, success : function(data) {$(this).updateSensor(data);}});
                
                //
@@ -127,7 +127,7 @@ $(document).ready(function()
 
        for (var i = 0; i < g_numSensors; ++i)
        {
-       //      $.ajax({url : "/api/sensors", data : {id : i}, success : function(data) {$(this).updateSensor(data);}})
+         $.ajax({url : "/api/sensors", data : {id : 2}, success : function(data) {$(this).updateSensor(data);}})
 
        }
 });

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