3 * @purpose Implementations to allow direct control over pins through FastCGI
11 * Export *ALL* pins for control
15 //Don't export anything; make the user do it.
16 /*for (int i = 0; i < GPIO_NUM_PINS; ++i)
17 GPIO_Export(g_index_to_gpio[i]);
19 for (int i = 0; i < ADC_NUM_PINS; ++i)
22 //Only export 'safe' PWM pins that don't interfere with one another
23 for (int i = 0; i < PWM_NUM_SAFE_PINS; ++i)
24 PWM_Export(g_pin_safe_pwm[i]);*/
32 for (int i = 0; i < GPIO_NUM_PINS; ++i)
33 GPIO_Unexport(g_pin_index_to_gpio[i]);
35 for (int i = 0; i < ADC_NUM_PINS; ++i)
38 for (int i = 0; i < PWM_NUM_PINS; ++i)
39 PWM_Unexport(g_pin_safe_pwm[i]);
43 * Handle a request to the Pin test module
44 * @param context - The FastCGI context
45 * @param params - key/value pair parameters as a string
47 void Pin_Handler(FCGIContext *context, char * params)
59 FCGIValue values[] = {
60 {"type", &type, FCGI_REQUIRED(FCGI_STRING_T)},
61 {"num", &num, FCGI_REQUIRED(FCGI_INT_T)},
62 {"set", &set, FCGI_BOOL_T},
63 {"pol", &pol, FCGI_BOOL_T},
64 {"freq", &freq, FCGI_DOUBLE_T},
65 {"duty", &duty, FCGI_DOUBLE_T}
68 // enum to avoid the use of magic numbers
78 // Fill values appropriately
79 if (!FCGI_ParseRequest(context, params, values, sizeof(values)/sizeof(FCGIValue)))
81 // Error occured; FCGI_RejectJSON already called
85 Log(LOGDEBUG, "Params: type = %s, num = %d, set = %d, pol = %d, freq = %f, duty = %f", type, num, set, pol, freq, duty);
87 if (strcmp(type, "gpo") == 0)
89 if (num <= 0 || num > GPIO_NUM_PINS)
91 FCGI_RejectJSON(context, "Invalid GPIO pin");
95 Log(LOGDEBUG, "Setting GPIO%d to %d", num, set);
98 FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
99 FCGI_PrintRaw("GPIO%d set to %d\n", num, set);
101 else if (strcmp(type, "gpi") == 0)
103 if (num < 0 || num >= GPIO_NUM_PINS)
105 FCGI_RejectJSON(context, "Invalid GPIO pin");
108 Log(LOGDEBUG, "Reading GPIO%d", num);
109 FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
111 if (!GPIO_Read(num, &ret))
112 FCGI_PrintRaw("GPIO%d read failed. Is it exported?", num);
114 FCGI_PrintRaw("GPIO%d reads %d\n", num, ret);
117 else if (strcmp(type, "adc") == 0)
119 if (num < 0 || num >= ADC_NUM_PINS)
121 FCGI_RejectJSON(context, "Invalid ADC pin");
124 Log(LOGDEBUG, "Reading ADC%d", num, set);
125 FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
127 if (!ADC_Read(num, &raw_adc))
129 FCGI_PrintRaw("ADC%d read failed. Is it initialised?", num);
133 FCGI_PrintRaw("ADC%d reads %d\n", num, raw_adc);
136 else if (strcmp(type, "pwm") == 0)
138 if (num < 0 || num >= PWM_NUM_SAFE_PINS)
140 FCGI_RejectJSON(context, "Invalid PWM pin");
144 FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
148 Log(LOGDEBUG, "Setting PWM%d", num);
149 duty = duty < 0 ? 0 : duty > 1 ? 1 : duty;
150 long period_ns = (long)(1e9 / freq);
151 long duty_ns = (long)(duty * period_ns);
152 PWM_Set(g_pin_safe_pwm[num], pol, period_ns, duty_ns);
153 FCGI_PrintRaw("PWM%d set to period_ns = %lu (%f Hz), duty_ns = %lu (%f), polarity = %d",
154 num, period_ns, freq, duty_ns, duty*100, (int)pol);
158 Log(LOGDEBUG, "Stopping PWM%d",num);
159 PWM_Stop(g_pin_safe_pwm[num]);
160 FCGI_PrintRaw("PWM%d stopped",num);
165 Log(LOGDEBUG, "Invalid pin type %s", type);
166 FCGI_RejectJSON(context, "Invalid pin type");