Merge pull request #42 from jtanx/master
authorJeremy Tan <[email protected]>
Tue, 24 Sep 2013 04:46:58 +0000 (21:46 -0700)
committerJeremy Tan <[email protected]>
Tue, 24 Sep 2013 04:46:58 +0000 (21:46 -0700)
Update fastcgi bool type

16 files changed:
irc/log
server/Makefile
server/actuator.c
server/bbb_pin.c
server/bbb_pin.h
server/common.h
server/fastcgi.c
server/log.c
server/log.h
server/main.c
server/options.h
server/pin_test.c [new file with mode: 0644]
server/pin_test.h [new file with mode: 0644]
server/run.sh
server/sensor.c
web/gui.js

diff --git a/irc/log b/irc/log
index 1370d76..0819b75 100644 (file)
--- a/irc/log
+++ b/irc/log
 00:51 < sam_moore> Hell yes
 00:51 < sam_moore> PWM controlled through web browser
 00:51 < sam_moore> GPIO controlled through web browser
+01:19 < sam_moore> .... And ADC read through web browser
+01:19 < sam_moore> Blergh
+01:28 < sam_moore> I think I'll take the rest of today off from MCTX3420 :S
+08:21 -!- jtanx [[email protected]] has joined #mctxuwa_softdev
+09:32 -!- jtanx [[email protected]] has quit [Ping timeout]
+11:36 -!- jtanx [[email protected]] has joined #mctxuwa_softdev
+11:53 < sam_moore> I've analysed the crap out of sampling rates for this ADC
+11:53 < sam_moore> At least as much as I can just using the timestamps according to gettimeofday
+11:54 < sam_moore> Contrary to my first email, reading the ADC is actually really slow. And also probably the greatest source of variation in sampling rate.
+11:56 < jtanx> wow
+11:56 < jtanx> only 100Hz?
+11:56 < sam_moore> Well it looks more like 1KHz on the oscilloscope, but there's a lot of variation, it has trouble getting a trigger
+11:57 < jtanx> the cpu datasheet rates it at 200kSPS
+11:57 < sam_moore> Hmm
+11:58 < sam_moore> Well judging by the control it is something about the ADC reading that makes it really slow
+11:58 < jtanx> That's annoyng
+11:58 < sam_moore> Yeah
+11:58 < sam_moore> Also annoying is that the ADC file is generally in a different place each time they're enabled
+11:59 < sam_moore> I ended up modifying the program to take the path to the ADC file as an argument
+11:59 < sam_moore> And making run.sh do the initialisation
+11:59 < sam_moore> I figured that was better than calling system()
+11:59 < jtanx> that makes sense
+11:59 < sam_moore> Yep, we might want to set other options that run.sh can pass to it anyway
+12:00 < sam_moore> Ok, I have to stop now, I'm spending way to much time on this
+12:00 < jtanx> Haha
+12:00 < sam_moore> It's getting to the point where I'm considering writing an ADC kernel module that doesn't suck :S
+12:01 < jtanx> :S let's hope it doesn't get to that stage
+14:08 -!- jtanx [[email protected]] has quit [Connection reset by peer]
+14:25 -!- jtanx [[email protected]] has joined #mctxuwa_softdev
+14:37 -!- MctxBot [[email protected]] has quit [Ping timeout]
+15:21 -!- MctxBot [[email protected]] has joined #mctxuwa_softdev
+20:12 < jtanx> the pressure regulator has a 1-5vdc analogue output
+20:12 < jtanx> is this considered one of the pressure sensors?
+20:14 < jtanx> or maybe it's just not used
+21:50 -!- jtanx [[email protected]] has quit ["ChatZilla 0.9.90.1 [Firefox 24.0/20130910160258]"]
+--- Day changed Mon Sep 23 2013
+07:56 -!- jtanx [[email protected]] has joined #mctxuwa_softdev
+08:51 -!- jtanx [[email protected]] has quit ["ChatZilla 0.9.90.1 [Firefox 24.0/20130910160258]"]
+19:38 -!- jtanx [[email protected]] has joined #mctxuwa_softdev
+19:41 -!- MctxBot [[email protected]] has quit [Ping timeout]
+20:55 -!- jtanx [[email protected]] has quit ["ChatZilla 0.9.90.1 [Firefox 24.0/20130910160258]"]
+21:02 -!- MctxBot [[email protected]] has joined #mctxuwa_softdev
+22:33 -!- Irssi: #mctxuwa_softdev: Total of 2 nicks [0 ops, 0 halfops, 0 voices, 2 normal]
index 1302544..f3ce6b4 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 bbb_pin.o
+OBJ = log.o control.o data.o fastcgi.o main.o sensor.o actuator.o image.o bbb_pin.o pin_test.o
 RM = rm -f
 
 BIN = server
index f5d7cd6..40f9b46 100644 (file)
@@ -32,6 +32,7 @@ void Actuator_Init()
        // Initialise pins used
        GPIO_Export(GPIO1_16);
        PWM_Export(EHRPWM0A);
+       PWM_Export(EHRPWM0B);
        
 }
 
index f8ba011..4569578 100644 (file)
@@ -9,6 +9,8 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <ctype.h>
+#include "options.h"
 
 /**
  * Structure to represent a GPIO pin
@@ -26,7 +28,7 @@ typedef struct
  */
 typedef struct
 {
-       FILE * file_value;
+       int fd_value;
 } ADC_Pin;
 
 /**
@@ -59,7 +61,9 @@ static char g_buffer[BUFSIZ] = "";
 void GPIO_Export(int pin)
 {
        if (pin < 0 || pin > GPIO_NUM_PINS)
-               Fatal("Invalid pin number %d", pin);
+       {
+               Abort("Invalid pin number %d", pin);
+       }
 
        
 
@@ -67,7 +71,9 @@ void GPIO_Export(int 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));
+       {
+               Abort("Couldn't open %s to export GPIO pin %d - %s", g_buffer, pin, strerror(errno));
+       }
 
        fprintf(export, "%d", pin);     
        fclose(export);
@@ -76,14 +82,21 @@ void GPIO_Export(int pin)
        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));
+       {
+               Abort("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));
+       {
+               Abort("Couldn't open %s for GPIO pin %d - %s", g_buffer, pin, strerror(errno));
+       }
+
+       Log(LOGDEBUG, "Exported GPIO%d", pin);
+       //sleep(1);
 }
 
 /**
@@ -93,7 +106,9 @@ void GPIO_Unexport(int pin)
 {
 
        if (pin < 0 || pin > GPIO_NUM_PINS)
-               Fatal("Invalid pin number %d", pin);
+       {
+               Abort("Invalid pin number %d", pin);
+       }
 
        // Close file descriptors
        close(g_gpio[pin].fd_value);
@@ -105,7 +120,9 @@ void GPIO_Unexport(int pin)
                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));
+       {
+               Abort("Couldn't open %s to export GPIO pin %d - %s", g_buffer, pin, strerror(errno));
+       }
 
        fprintf(export, "%d", pin);     
        fclose(export);
@@ -121,37 +138,49 @@ void GPIO_Unexport(int pin)
 void PWM_Export(int pin)
 {
        if (pin < 0 || pin > PWM_NUM_PINS)
-               Fatal("Invalid pin number %d", pin);
+       {
+               Abort("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));
+       {
+               Abort("Couldn't open %s to export PWM pin %d - %s", g_buffer, pin, strerror(errno));
+       }
        
-       fprintf(export, "%d", 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)
-               Fatal("Couldn't open %s for PWM pin %d - %s", g_buffer, pin, strerror(errno));
+       {
+               Abort("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));
+       {
+               Abort("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));
+       {
+               Abort("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));
+       {
+               Abort("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);
@@ -167,7 +196,9 @@ void PWM_Export(int pin)
 void PWM_Unexport(int pin)
 {
        if (pin < 0 || pin > PWM_NUM_PINS)
-               Fatal("Invalid pin number %d", pin);
+       {
+               Abort("Invalid pin number %d", pin);
+       }
 
        // Close the file descriptors
        close(g_pwm[pin].fd_polarity);
@@ -179,7 +210,9 @@ void PWM_Unexport(int 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));
+       {
+               Abort("Couldn't open %s to unexport PWM pin %d - %s", g_buffer, pin, strerror(errno));  
+       }
        
        fprintf(export, "%d", pin);
        fclose(export);
@@ -194,22 +227,16 @@ void PWM_Unexport(int pin)
  */
 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));
+               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);
+               //setbuf(g_adc[i].file_value, NULL);
 
        }
 }
@@ -220,7 +247,7 @@ void ADC_Export()
 void ADC_Unexport()
 {
        for (int i = 0; i < ADC_NUM_PINS; ++i)
-               fclose(g_adc[i].file_value);
+               close(g_adc[i].fd_value);
 }
 
 /**
@@ -229,12 +256,16 @@ void ADC_Unexport()
  */
 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));
+       if (pwrite(g_gpio[pin].fd_direction, "out", 3, 0) != 3)
+       {
+               Abort("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));
+       if (pwrite(g_gpio[pin].fd_value, &c, 1, 0) != 1)
+       {
+               Abort("Couldn't read GPIO %d value - %s", pin, strerror(errno));
+       }
 
 }
 
@@ -244,11 +275,11 @@ void GPIO_Set(int pin, bool value)
  */
 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)); 
+       if (pwrite(g_gpio[pin].fd_direction, "in", 2, 0) != 2)
+               Log(LOGERR,"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));
+       if (pread(g_gpio[pin].fd_value, &c, 1, 0) != 1)
+               Log(LOGERR,"Couldn't read GPIO %d value - %s", pin, strerror(errno));
 
        return (c == '1');
 
@@ -264,25 +295,32 @@ bool GPIO_Read(int pin)
 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));
+       if (pwrite(g_pwm[pin].fd_run, "0", 1, 0) != 1)
+       {
+               Abort("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));
-
+       if (pwrite(g_pwm[pin].fd_polarity, &c, 1, 0) != 1)
+       {
+               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_duty, "%lu", duty) == 0)
-               Fatal("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 (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));
+       {
+               Abort("Couldn't set period for PWM %d - %s", pin, strerror(errno));
+       }
+       if (pwrite(g_pwm[pin].fd_run, "1", 1, 0) != 1)
+       {
+               Abort("Couldn't start PWM %d - %s", pin, strerror(errno));
+       }
 
 }
 
@@ -292,9 +330,10 @@ void PWM_Set(int pin, bool polarity, long period, long duty)
  */
 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));
-
+       if (pwrite(g_pwm[pin].fd_run, "0", 1, 0) != 1)
+       {
+               Abort("Couldn't stop PWM %d - %s", pin, strerror(errno));
+       }
 }
 
 /**
@@ -302,25 +341,28 @@ void PWM_Stop(int pin)
  * @param id - The ID of the ADC pin to read
  * @returns - The reading of the ADC channel
  */
-long ADC_Read(int id)
+int 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)
+       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)
        {
-               if (adc_val[i] == '\n')
-                       adc_val[i] = '\0';
+               if (read(g_adc[id].fd_value, adc_str+i, 1) != 1)
+                       break;
+               if (adc_str[i] == '\n')
+               {
+                       adc_str[i] = '\0';
+                       break;
+               }
        }
 
        char * end;
-       long val = strtol(adc_val, &end, 10);
+       int val = strtol(adc_str, &end, 10);
        if (*end != '\0')
        {
-               Log(LOGERR, "Reading ADC%d gives %s - invalid!", id, adc_val);
-       }
-       //Log(LOGDEBUG, "Returns %lu", val);
-       return val;
+               Log(LOGERR, "Read non integer from ADC %d - %s", id, adc_str);
+       }       
+       return val;     
 }
index 472a917..04c02b6 100644 (file)
@@ -24,7 +24,7 @@ extern void ADC_Unexport();
 extern bool GPIO_Read(int pin);
 extern void GPIO_Set(int pin, bool value);
 
-extern long ADC_Read(int pin);
+extern int 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);
index 97290d2..43bb8bd 100644 (file)
@@ -34,4 +34,6 @@
 #define TIMEVAL_DIFF(tv1, tv2) ((tv1).tv_sec - (tv2).tv_sec + 1e-6 * ((tv1).tv_usec - (tv2).tv_usec))
 
 
+
+
 #endif //_COMMON_H
index 89386f3..352efe1 100644 (file)
@@ -16,6 +16,7 @@
 #include "control.h"
 #include "options.h"
 #include "image.h"
+#include "pin_test.h"
 
 /**The time period (in seconds) before the control key expires */
 #define CONTROL_TIMEOUT 180
@@ -490,6 +491,8 @@ void * FCGI_RequestLoop (void *data)
                        module_handler = Actuator_Handler;
                } else if (!strcmp("image", module)) {
                        module_handler = Image_Handler;
+               } else if (!strcmp("pin", module)) { 
+                       module_handler = Pin_Handler; // *Debug only* pin test module
                }
 
                context.current_module = module;
index c23d158..bd210d8 100644 (file)
@@ -15,6 +15,7 @@
 
 static const char * unspecified_funct = "???";
 
+
 /**
  * Print a message to stderr and log it via syslog. The message must be
  * less than BUFSIZ characters long, or it will be truncated.
@@ -111,6 +112,7 @@ void FatalEx(const char * funct, const char * file, int line, ...)
                funct = unspecified_funct;
 
        syslog(LOG_CRIT, "FATAL: %s (%s:%d) - %s", funct, file, line, buffer);
+
        exit(EXIT_FAILURE);
 }
 
index fd98190..cc6a7e5 100644 (file)
@@ -10,6 +10,9 @@
 #define Log(level, ...) LogEx(level, __func__, __FILE__, __LINE__, __VA_ARGS__)
 #define Fatal(...) FatalEx(__func__, __FILE__, __LINE__, __VA_ARGS__)
 
+/*** Macro to abort function ***/
+#define Abort(...) LogEx(LOGERR, __func__, __FILE__, __LINE__, __VA_ARGS__); return
+
 // An enum to make the severity of log messages human readable in code
 enum {LOGERR=0, LOGWARN=1, LOGNOTE=2, LOGINFO=3,LOGDEBUG=4};
 
index c032eb1..aff5b83 100644 (file)
@@ -9,6 +9,7 @@
 #include "sensor.h"
 #include "actuator.h"
 #include "control.h"
+#include "bbb_pin_defines.h"
 
 // --- Standard headers --- //
 #include <syslog.h> // for system logging
@@ -26,10 +27,39 @@ Options g_options; // options passed to program through command line arguments
  */
 void ParseArguments(int argc, char ** argv)
 {
+       // horrible horrible hacks
+       g_options.argc = argc;
+       g_options.argv = argv;
+
        g_options.program = argv[0]; // program name
        g_options.verbosity = LOGDEBUG; // default log level
        gettimeofday(&(g_options.start_time), NULL); // Start time
+       g_options.adc_device_path = ADC_DEVICE_PATH;
        Log(LOGDEBUG, "Called as %s with %d arguments.", g_options.program, argc);
+
+       for (int i = 1; i < argc; ++i)
+       {
+               if (argv[i][0] != '-')
+                       Fatal("Unexpected argv[%d] - %s", i, argv[i]);
+
+               if (i+1 >= argc || argv[i+1][0] == '-')
+                       Fatal("No argument following switch %s", argv[i]);
+               
+               if (strlen(argv[i]) > 2)
+                       Fatal("Human readable switches are not supported.");
+
+               switch (argv[i][1])
+               {
+                       case 'a':
+                               g_options.adc_device_path = argv[i+1];
+                               Log(LOGINFO, "ADC Device Path: %s", argv[i+1]);
+                               ++i;
+                               break;
+                       default:
+                               Fatal("Unrecognised switch %s", argv[i]);
+                               break;
+               }
+       }       
 }
 
 /**
@@ -67,11 +97,14 @@ void Cleanup()
  */
 int main(int argc, char ** argv)
 {
+       // Open log before calling ParseArguments (since ParseArguments may call the Log functions)
+       openlog("mctxserv", LOG_PID | LOG_PERROR, LOG_USER);
+       Log(LOGINFO, "Server started");
+
        ParseArguments(argc, argv);
 
        //Open the system log
-       openlog("mctxserv", LOG_PID | LOG_PERROR, LOG_USER);
-       Log(LOGINFO, "Server started");
+
        // signal handler
        //TODO: Make this work
        /*
@@ -83,6 +116,7 @@ int main(int argc, char ** argv)
        */
        Sensor_Init();
        Actuator_Init();
+       Pin_Init();
        //Sensor_StartAll("test");
        //Actuator_StartAll("test");
        const char *ret;
@@ -97,6 +131,8 @@ int main(int argc, char ** argv)
        //Sensor_StopAll();
        //Actuator_StopAll();
 
+       Pin_Close();
+
        Cleanup();
        return 0;
 }
index a20e0e1..f702e01 100644 (file)
@@ -19,6 +19,14 @@ typedef struct
        /** Time at which program exits **/
        struct timeval end_time;
 
+       /** Path to ADC files **/
+       char * adc_device_path;
+
+       /*** Horrible horrible hack ***/
+       int argc;
+       /*** Horrible horrible hack ***/
+       char ** argv;
+
 } Options;
 
 /** The only instance of the Options struct **/
diff --git a/server/pin_test.c b/server/pin_test.c
new file mode 100644 (file)
index 0000000..cd8c307
--- /dev/null
@@ -0,0 +1,156 @@
+/**
+ * @file pin_test.c
+ * @purpose Implementations to allow direct control over pins through FastCGI
+ */
+
+#include "pin_test.h"
+
+#include "bbb_pin.h"
+
+/**
+ * Export *ALL* pins for control
+ */
+void Pin_Init()
+{
+       for (int i = 0; i < GPIO_NUM_PINS; ++i)
+               GPIO_Export(i);
+
+       for (int i = 0; i < ADC_NUM_PINS; ++i)
+               ADC_Export();
+
+       for (int i = 0; i < PWM_NUM_PINS; ++i)
+               PWM_Export(i);
+}
+
+/**
+ * Unexport all pins
+ */
+void Pin_Close()
+{
+       for (int i = 0; i < GPIO_NUM_PINS; ++i)
+               GPIO_Unexport(i);
+
+       for (int i = 0; i < ADC_NUM_PINS; ++i)
+               ADC_Unexport(i);
+
+       for (int i = 0; i < PWM_NUM_PINS; ++i)
+               PWM_Unexport(i);
+}
+
+/**
+ * Handle a request to the Pin test module
+ * @param context - The FastCGI context
+ * @param params - key/value pair parameters as a string
+ */
+void Pin_Handler(FCGIContext *context, char * params)
+{
+       
+       char * type = NULL;
+       int num = 0;
+       bool set = true;
+       bool pol = false;
+       double freq = 50;
+       double duty = 0.5;
+       
+
+       // key/value pairs
+       FCGIValue values[] = {
+               {"type", &type, FCGI_REQUIRED(FCGI_STRING_T)},
+               {"num", &num, FCGI_REQUIRED(FCGI_INT_T)}, 
+               {"set", &set, FCGI_INT_T},
+               {"pol", &pol, FCGI_INT_T},
+               {"freq", &freq, FCGI_DOUBLE_T},
+               {"duty", &duty, FCGI_DOUBLE_T}
+       };
+
+       // enum to avoid the use of magic numbers
+       typedef enum {
+               TYPE,
+               NUM,
+               SET,
+               FREQ,
+               DUTY
+       } SensorParams;
+       
+       // Fill values appropriately
+       if (!FCGI_ParseRequest(context, params, values, sizeof(values)/sizeof(FCGIValue)))
+       {
+               // Error occured; FCGI_RejectJSON already called
+               return;
+       }
+
+       Log(LOGDEBUG, "Params: type = %s, num = %d, set = %d, pol = %d, freq = %f, duty = %f", type, num, set, pol, freq, duty);
+
+       if (strcmp(type, "gpo") == 0)
+       {
+               if (num <= 0 || num > GPIO_NUM_PINS)
+               {
+                       FCGI_RejectJSON(context, "Invalid GPIO pin");
+                       return;
+               }
+
+               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);
+       }
+       else if (strcmp(type, "gpi") == 0)
+       {
+               if (num < 0 || num >= GPIO_NUM_PINS)
+               {
+                       FCGI_RejectJSON(context, "Invalid GPIO pin");
+                       return;
+               }
+               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));
+
+       }
+       else if (strcmp(type, "adc") == 0)
+       {
+               if (num < 0 || num >= ADC_NUM_PINS)
+               {
+                       FCGI_RejectJSON(context, "Invalid ADC pin");
+                       return;
+               }
+               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));
+       }
+       else if (strcmp(type, "pwm") == 0)
+       {
+               if (num < 0 || num >= PWM_NUM_PINS)
+               {
+                       FCGI_RejectJSON(context, "Invalid PWM pin");
+                       return;
+               }
+
+               FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
+               
+               if (set)
+               {
+                       Log(LOGDEBUG, "Setting PWM%d", num);
+                       long period_ns = (long)(1e9 / freq);
+                       long duty_ns = (long)(duty * period_ns);
+                       PWM_Set(num, pol, period_ns, duty_ns);
+                       FCGI_PrintRaw("PWM%d set to period_ns = %lu (%f Hz), duty_ns = %lu (%d), polarity = %d", num, period_ns, freq, duty_ns, duty*100, pol);
+               }
+               else
+               {
+                       Log(LOGDEBUG, "Stopping PWM%d",num);
+                       PWM_Stop(num);
+                       FCGI_PrintRaw("PWM%d stopped",num);
+               }               
+       }
+       else
+       {
+               Log(LOGDEBUG, "Invalid pin type %s", type);
+               FCGI_RejectJSON(context, "Invalid pin type");
+       }
+
+       
+
+}
+
+//EOF
diff --git a/server/pin_test.h b/server/pin_test.h
new file mode 100644 (file)
index 0000000..dd07fe1
--- /dev/null
@@ -0,0 +1,17 @@
+/**
+ * @file pin_test.h
+ * @purpose Declarations to allow direct control over pins through FastCGI
+ */
+
+#ifndef _PIN_MODULE_H
+#define _PIN_MODULE_H
+
+#include "common.h"
+
+extern void Pin_Init();
+extern void Pin_Close();
+extern void Pin_Handler(FCGIContext *context, char * params);
+
+#endif //_PIN_MODULE_H
+
+//EOF
index aafc5d1..d9cb343 100755 (executable)
@@ -3,4 +3,49 @@
 #spawn-fcgi -p9005 -n ./valgrind.sh
 # Use this to run the server normally
 #./stream &
-spawn-fcgi -p9005 -n ./server
+
+# Check running as root
+if [ "$(whoami)" != "root" ]; then
+       (echo "Run $0 as root.") 1>&2
+       exit 1
+fi
+
+# Check existence of program
+if [ ! -e "server" ]; then
+       (echo "Rebuild server.") 1>&2;
+       exit 1
+fi
+
+# Identify cape-manager slots
+slot=$(echo /sys/devices/bone_capemgr.*/slots | awk '{print $1}')
+
+# Load PWM module
+modprobe pwm_test
+(echo am33xx_pwm > $slot) 1>&2 >> /dev/null
+for port in P9_21 P9_22 P9_14 P9_16 P9_29 P9_31 P9_42 P8_13 P8_19 P8_34 P8_36 P8_45 P8_46; do
+       echo bone_pwm_$port > $slot
+done
+
+# Load ADCs
+(echo cape-bone-iio > $slot) 1>&2 >> /dev/null
+# Find adc_device_path
+# NOTE: This has to be passed as a parameter, because it is not always the same. For some unfathomable reason. Hooray.
+adc_device_path=$(dirname $(find /sys -name *AIN0))
+
+
+# Run the program with parameters
+# TODO: Can tell spawn-fcgi to run the program as an unprivelaged user?
+# But first will have to work out how to set PWM/GPIO as unprivelaged user
+fails=0
+while [ $fails -lt 10 ]; do
+       spawn-fcgi -p9005 -n -- ./server -a "$adc_device_path"
+       if [ "$?" == "0" ]; then
+               exit 0
+       fi
+       fails=$(( $fails + 1 ))
+       (echo "Restarting server after Fatal Error #$fails") 1>&2
+       
+done
+(echo "Server had too many Fatal Errors ($fails)") 1>&2
+exit $fails
+
index e429958..63e69d8 100644 (file)
@@ -46,12 +46,12 @@ void Sensor_Init()
        }
 
        // Get the ADCs
-       ADC_Export();
+       //ADC_Export();
 
        // GPIO1_28 used as a pulse for sampling
-       GPIO_Export(GPIO1_28);
+       //GPIO_Export(GPIO1_28);
        // GPIO0_30 toggled during sampling
-       GPIO_Export(GPIO0_30);
+       //GPIO_Export(GPIO0_30);
 }
 
 /**
@@ -144,13 +144,13 @@ void Sensor_CheckData(SensorId id, double value)
 {
        if( value > thresholds[id].max_error || value < thresholds[id].min_error)
        {
-               Log(LOGERR, "Sensor %s is above or below its safety value of %f or %f\n", g_sensor_names[id],thresholds[id].max_error, thresholds[id].min_error);
+               Log(LOGERR, "Sensor %s at %f is above or below its safety value of %f or %f\n", value, g_sensor_names[id],thresholds[id].max_error, thresholds[id].min_error);
                //new function that stops actuators?
                //Control_SetMode(CONTROL_EMERGENCY, NULL)
        }
        else if( value > thresholds[id].max_warn || value < thresholds[id].min_warn)
        {
-               Log(LOGWARN, "Sensor %s is above or below its warning value of %f or %f\n", g_sensor_names[id],thresholds[id].max_warn, thresholds[id].min_warn);       
+               Log(LOGWARN, "Sensor %s at %f is above or below its warning value of %f or %f\n", value, g_sensor_names[id],thresholds[id].max_warn, thresholds[id].min_warn);  
        }
 }
 
@@ -175,16 +175,18 @@ bool Sensor_Read(Sensor * s, DataPoint * d)
        // Read value based on Sensor Id
        switch (s->id)
        {
-               case ANALOG_REALTEST:
+               case 2:
                {
                        static bool set = false;
                        
-                       GPIO_Set(GPIO0_30, true);
+                       //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);
+                       //GPIO_Set(GPIO0_30, false);
                        set = !set;
-                       GPIO_Set(GPIO1_28, set);
+                       //GPIO_Set(GPIO1_28, set);
+
+                       usleep(100000);
                        
                        break;
                }
index 7d7a8fe..e49cf4d 100644 (file)
@@ -11,6 +11,24 @@ $(document).ready(function()
        g_numSensors = 1
        g_storeTime = []
        g_key = null
+       g_led = 1
+       
+       $.fn.ledFlash = function()
+       {
+               //alert("Flash LED");
+               if (g_led == 0)
+               {
+                       $.ajax({url : "api/actuators", data : {id : 0, set : 1}})
+                       g_led = 1
+                       $("#led").html("LED On");
+               }
+               else
+               {
+                       $.ajax({url : "api/actuators", data : {id : 0, set : 0}})
+                       g_led = 0
+                       $("#led").html("LED Off");
+               }
+       }
 
        $.fn.pruneSensorData = function(id)
        {
@@ -112,8 +130,7 @@ $(document).ready(function()
                $("#plots").html(plotsHTML)
 
                controlHTML = "<h2 id=control0>Controls</h2>\n"
-               controlHTML += "<p> Pressure: <input type=text id=control0_value value=\"100\"/>"
-               controlHTML += "<button id=actuator0 onclick=\"$(document).setPressure()\">SET</button> </p>"
+               controlHTML += "<button id=led onclick=\"$(document).ledFlash()\">LED On</button>"
                
                $("#controls").html(controlHTML)
 

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