void GPIO_Export(int pin)
{
if (pin < 0 || pin > GPIO_NUM_PINS)
- Fatal("Invalid pin number %d", pin);
+ {
+ Abort("Invalid pin number %d", 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);
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);
}
/**
{
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);
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);
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\n", pin);
fclose(export);
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);
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);
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);
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)
- Fatal("Couldn't open ADC %d device file %s - %s", i, g_buffer, strerror(errno));
+ {
+ Abort("Couldn't open ADC %d device file %s - %s", i, g_buffer, strerror(errno));
+ }
//setbuf(g_adc[i].file_value, NULL);
void GPIO_Set(int pin, bool value)
{
if (pwrite(g_gpio[pin].fd_direction, "out", 3, 0) != 3)
- Fatal("Couldn't set GPIO %d direction - %s", pin, strerror(errno));
+ {
+ Abort("Couldn't set GPIO %d direction - %s", pin, strerror(errno));
+ }
char c = '0' + (value);
if (pwrite(g_gpio[pin].fd_value, &c, 1, 0) != 1)
- Fatal("Couldn't read GPIO %d value - %s", pin, strerror(errno));
+ {
+ Abort("Couldn't read GPIO %d value - %s", pin, strerror(errno));
+ }
}
bool GPIO_Read(int pin)
{
if (pwrite(g_gpio[pin].fd_direction, "in", 2, 0) != 2)
- Fatal("Couldn't set GPIO %d direction - %s", pin, strerror(errno));
+ Log(LOGERR,"Couldn't set GPIO %d direction - %s", pin, strerror(errno));
char c = '0';
if (pread(g_gpio[pin].fd_value, &c, 1, 0) != 1)
- Fatal("Couldn't read GPIO %d value - %s", pin, strerror(errno));
+ Log(LOGERR,"Couldn't read GPIO %d value - %s", pin, strerror(errno));
return (c == '1');
{
// Have to stop PWM before changing it
if (pwrite(g_pwm[pin].fd_run, "0", 1, 0) != 1)
- Fatal("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)
- Fatal("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_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));
-
+ {
+ Abort("Couldn't set period for PWM %d - %s", pin, strerror(errno));
+ }
if (pwrite(g_pwm[pin].fd_run, "1", 1, 0) != 1)
- Fatal("Couldn't start PWM %d - %s", pin, strerror(errno));
+ {
+ Abort("Couldn't start PWM %d - %s", pin, strerror(errno));
+ }
}
void PWM_Stop(int pin)
{
if (pwrite(g_pwm[pin].fd_run, "0", 1, 0) != 1)
- Fatal("Couldn't stop PWM %d - %s", pin, strerror(errno));
-
+ {
+ Abort("Couldn't stop PWM %d - %s", pin, strerror(errno));
+ }
}
/**
--- /dev/null
+/**
+ * @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