Update Titlepage with links to individual sections
[matches/MCTX3420.git] / server / pin_test.c
1 /**
2  * @file pin_test.c
3  * @brief 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         
16 }
17
18 /**
19  * Unexport all pins
20  */
21 void Pin_Close()
22 {
23         for (int i = 0; i < GPIO_NUM_PINS; ++i)
24                 GPIO_Unexport(g_pin_index_to_gpio[i]);
25
26         for (int i = 0; i < ADC_NUM_PINS; ++i)
27                 ADC_Unexport(i);
28
29         for (int i = 0; i < PWM_NUM_PINS; ++i)
30                 PWM_Unexport(i);
31 }
32
33 bool Pin_Configure(const char *type, int pin_export, int num)
34 {
35         bool ret = true;
36
37         if (strcmp(type, "gpo") == 0 || strcmp(type, "gpi") == 0)
38         {
39                 //Don't allow unexport of gpio
40                 if (pin_export > 0)
41                         ret = GPIO_Export(num);
42         }
43         else if (strcmp(type, "pwm") == 0)
44         {
45                 if (pin_export < 0)
46                         PWM_Unexport(num);
47                 else
48                         ret = PWM_Export(num);          
49         }
50         else if (strcmp(type, "adc") == 0)
51         {
52                 //Don't allow unexport of adc
53                 if (pin_export > 0)
54                         ret = ADC_Export(num);
55         }
56         return ret;
57 }
58
59 /**
60  * Handle a request to the Pin test module
61  * @param context - The FastCGI context
62  * @param params - key/value pair parameters as a string
63  */
64 void Pin_Handler(FCGIContext *context, char * params)
65 {
66         
67         const char * type = NULL;
68         int num = 0;
69         int pin_export = 0;
70         bool set = false;
71         bool pol = false;
72         double freq = 50;
73         double duty = 0.5;
74         
75
76         // key/value pairs
77         FCGIValue values[] = {
78                 {"type", &type, FCGI_REQUIRED(FCGI_STRING_T)},
79                 {"num", &num, FCGI_REQUIRED(FCGI_INT_T)}, 
80                 {"export", &pin_export, FCGI_INT_T},
81                 {"set", &set, FCGI_BOOL_T},
82                 {"pol", &pol, FCGI_BOOL_T},
83                 {"freq", &freq, FCGI_DOUBLE_T},
84                 {"duty", &duty, FCGI_DOUBLE_T}
85         };
86
87         // enum to avoid the use of magic numbers
88         typedef enum {
89                 TYPE,
90                 NUM,
91                 EXPORT,
92                 SET,
93                 POL,
94                 FREQ,
95                 DUTY
96         } SensorParams;
97         
98         // Fill values appropriately
99         if (!FCGI_ParseRequest(context, params, values, sizeof(values)/sizeof(FCGIValue)))
100         {
101                 // Error occured; FCGI_RejectJSON already called
102                 return;
103         }
104
105         Log(LOGDEBUG, "Params: type = %s, num = %d, export = %d, set = %d, pol = %d, freq = %f, duty = %f", type, num, pin_export, set, pol, freq, duty);
106         if (pin_export != 0)
107         {
108                 if (!Pin_Configure(type, pin_export, num))
109                 {
110                         FCGI_RejectJSON(context, "Failed to (un)export the pin. Check that a valid number has been specified.");
111                         return;
112                 }
113                 FCGI_BeginJSON(context, STATUS_OK);
114                 FCGI_JSONPair("description", "Pin (un)export OK!");
115                 FCGI_EndJSON();
116                 return;
117         }
118
119         if (strcmp(type, "gpo") == 0)
120         {
121                 if (num <= 0 || num > GPIO_MAX_NUMBER)
122                 {
123                         FCGI_RejectJSON(context, "Invalid GPIO pin");
124                         return;
125                 }
126
127                 Log(LOGDEBUG, "Setting GPIO%d to %d", num, set);
128                 if (!GPIO_Set(num, set))
129                 {
130                         FCGI_RejectJSON(context, "Failed to set the GPIO pin. Check that it's exported.");
131                 }
132                 else
133                 {
134                         FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
135                         FCGI_PrintRaw("GPIO%d set to %d\n", num, set);
136                 }
137         }
138         else if (strcmp(type, "gpi") == 0)
139         {
140                 if (num < 0 || num > GPIO_MAX_NUMBER)
141                 {
142                         FCGI_RejectJSON(context, "Invalid GPIO pin");
143                         return;
144                 }
145                 Log(LOGDEBUG, "Reading GPIO%d", num);
146                 bool val;
147                 if (!GPIO_Read(num, &val))
148                 {
149                         FCGI_RejectJSON(context, "Failed to read from the GPIO pin. Check that it's exported.");
150                 }
151                 else
152                 {
153                         FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
154                         FCGI_PrintRaw("GPIO%d reads %d\n", num, val);
155                 }
156         }
157         else if (strcmp(type, "adc") == 0)
158         {
159                 if (num < 0 || num >= ADC_NUM_PINS)
160                 {
161                         FCGI_RejectJSON(context, "Invalid ADC pin");
162                         return;
163                 }
164                 Log(LOGDEBUG, "Reading ADC%d", num, set);
165                 int raw_adc;
166                 if (!ADC_Read(num, &raw_adc))
167                 {
168                         FCGI_RejectJSON(context, "ADC read failed. Check that it's exported.");
169                 }
170                 else
171                 {
172                         FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
173                         FCGI_PrintRaw("%d\n", raw_adc);
174                 }
175         }
176         else if (strcmp(type, "pwm") == 0)
177         {
178                 if (num < 0 || num >= PWM_NUM_PINS)
179                 {
180                         FCGI_RejectJSON(context, "Invalid PWM pin");
181                         return;
182                 }
183                 
184                 if (set)
185                 {
186                         Log(LOGDEBUG, "Setting PWM%d", num);
187                         duty = duty < 0 ? 0 : duty > 1 ? 1 : duty;
188                         long period_ns = (long)(1e9 / freq);
189                         long duty_ns = (long)(duty * period_ns);
190                         if (!PWM_Set(num, pol, period_ns, duty_ns))
191                         {
192                                 FCGI_RejectJSON(context, "PWM set failed. Check if it's exported, and that there's no channel conflict.");
193                         }
194                         else
195                         {
196                                 FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
197                                 FCGI_PrintRaw("PWM%d set to period_ns = %lu (%f Hz), duty_ns = %lu (%f), polarity = %d", 
198                                         num, period_ns, freq, duty_ns, duty*100, (int)pol);
199                         }
200                 }
201                 else
202                 {
203                         Log(LOGDEBUG, "Stopping PWM%d",num);
204                         PWM_Stop(num);
205                         FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
206                         FCGI_PrintRaw("PWM%d stopped",num);
207                 }               
208         }
209         else
210         {
211                 Log(LOGDEBUG, "Invalid pin type %s", type);
212                 FCGI_RejectJSON(context, "Invalid pin type");
213         }
214
215 }

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