(Almost done) pin refactoring
[matches/MCTX3420.git] / server / pin_test.c
1 /**
2  * @file pin_test.c
3  * @purpose Implementations to allow direct control over pins through FastCGI
4  */
5
6 #include "pin_test.h"
7
8 #include "bbb_pin.h"
9
10 /**
11  * Export *ALL* pins for control
12  */
13 void Pin_Init()
14 {
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]);
18
19         for (int i = 0; i < ADC_NUM_PINS; ++i)
20                 ADC_Export(i);
21
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]);*/
25 }
26
27 /**
28  * Unexport all pins
29  */
30 void Pin_Close()
31 {
32         for (int i = 0; i < GPIO_NUM_PINS; ++i)
33                 GPIO_Unexport(g_pin_index_to_gpio[i]);
34
35         for (int i = 0; i < ADC_NUM_PINS; ++i)
36                 ADC_Unexport(i);
37
38         for (int i = 0; i < PWM_NUM_PINS; ++i)
39                 PWM_Unexport(g_pin_safe_pwm[i]);
40 }
41
42 /**
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
46  */
47 void Pin_Handler(FCGIContext *context, char * params)
48 {
49         
50         char * type = NULL;
51         int num = 0;
52         bool set = true;
53         bool pol = false;
54         double freq = 50;
55         double duty = 0.5;
56         
57
58         // key/value pairs
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}
66         };
67
68         // enum to avoid the use of magic numbers
69         typedef enum {
70                 TYPE,
71                 NUM,
72                 SET,
73                 POL,
74                 FREQ,
75                 DUTY
76         } SensorParams;
77         
78         // Fill values appropriately
79         if (!FCGI_ParseRequest(context, params, values, sizeof(values)/sizeof(FCGIValue)))
80         {
81                 // Error occured; FCGI_RejectJSON already called
82                 return;
83         }
84
85         Log(LOGDEBUG, "Params: type = %s, num = %d, set = %d, pol = %d, freq = %f, duty = %f", type, num, set, pol, freq, duty);
86
87         if (strcmp(type, "gpo") == 0)
88         {
89                 if (num <= 0 || num > GPIO_NUM_PINS)
90                 {
91                         FCGI_RejectJSON(context, "Invalid GPIO pin");
92                         return;
93                 }
94
95                 Log(LOGDEBUG, "Setting GPIO%d to %d", num, set);
96                 GPIO_Set(num, set);
97
98                 FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
99                 FCGI_PrintRaw("GPIO%d set to %d\n", num, set);
100         }
101         else if (strcmp(type, "gpi") == 0)
102         {
103                 if (num < 0 || num >= GPIO_NUM_PINS)
104                 {
105                         FCGI_RejectJSON(context, "Invalid GPIO pin");
106                         return;
107                 }
108                 Log(LOGDEBUG, "Reading GPIO%d", num);
109                 FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
110                 bool ret;
111                 if (!GPIO_Read(num, &ret))
112                         FCGI_PrintRaw("GPIO%d read failed. Is it exported?", num);
113                 else
114                         FCGI_PrintRaw("GPIO%d reads %d\n", num, ret);
115
116         }
117         else if (strcmp(type, "adc") == 0)
118         {
119                 if (num < 0 || num >= ADC_NUM_PINS)
120                 {
121                         FCGI_RejectJSON(context, "Invalid ADC pin");
122                         return;
123                 }
124                 Log(LOGDEBUG, "Reading ADC%d", num, set);
125                 FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
126                 int raw_adc;
127                 if (!ADC_Read(num, &raw_adc))
128                 {
129                         FCGI_PrintRaw("ADC%d read failed. Is it initialised?", num);
130                 }
131                 else
132                 {
133                         FCGI_PrintRaw("ADC%d reads %d\n", num, raw_adc);
134                 }
135         }
136         else if (strcmp(type, "pwm") == 0)
137         {
138                 if (num < 0 || num >= PWM_NUM_SAFE_PINS)
139                 {
140                         FCGI_RejectJSON(context, "Invalid PWM pin");
141                         return;
142                 }
143
144                 FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
145                 
146                 if (set)
147                 {
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);
155                 }
156                 else
157                 {
158                         Log(LOGDEBUG, "Stopping PWM%d",num);
159                         PWM_Stop(g_pin_safe_pwm[num]);
160                         FCGI_PrintRaw("PWM%d stopped",num);
161                 }               
162         }
163         else
164         {
165                 Log(LOGDEBUG, "Invalid pin type %s", type);
166                 FCGI_RejectJSON(context, "Invalid pin type");
167         }
168
169 }

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