Added module for direct control over pins
[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         for (int i = 0; i < GPIO_NUM_PINS; ++i)
16                 GPIO_Export(i);
17
18         for (int i = 0; i < ADC_NUM_PINS; ++i)
19                 ADC_Export();
20
21         for (int i = 0; i < PWM_NUM_PINS; ++i)
22                 PWM_Export(i);
23 }
24
25 /**
26  * Unexport all pins
27  */
28 void Pin_Close()
29 {
30         for (int i = 0; i < GPIO_NUM_PINS; ++i)
31                 GPIO_Unexport(i);
32
33         for (int i = 0; i < ADC_NUM_PINS; ++i)
34                 ADC_Unexport(i);
35
36         for (int i = 0; i < PWM_NUM_PINS; ++i)
37                 PWM_Unexport(i);
38 }
39
40 /**
41  * Handle a request to the Pin test module
42  * @param context - The FastCGI context
43  * @param params - key/value pair parameters as a string
44  */
45 void Pin_Handler(FCGIContext *context, char * params)
46 {
47         
48         char * type = NULL;
49         int num = 0;
50         bool set = true;
51         bool pol = false;
52         double freq = 50;
53         double duty = 0.5;
54         
55
56         // key/value pairs
57         FCGIValue values[] = {
58                 {"type", &type, FCGI_REQUIRED(FCGI_STRING_T)},
59                 {"num", &num, FCGI_REQUIRED(FCGI_INT_T)}, 
60                 {"set", &set, FCGI_INT_T},
61                 {"pol", &pol, FCGI_INT_T},
62                 {"freq", &freq, FCGI_DOUBLE_T},
63                 {"duty", &duty, FCGI_DOUBLE_T}
64         };
65
66         // enum to avoid the use of magic numbers
67         typedef enum {
68                 TYPE,
69                 NUM,
70                 SET,
71                 FREQ,
72                 DUTY
73         } SensorParams;
74         
75         // Fill values appropriately
76         if (!FCGI_ParseRequest(context, params, values, sizeof(values)/sizeof(FCGIValue)))
77         {
78                 // Error occured; FCGI_RejectJSON already called
79                 return;
80         }
81
82         Log(LOGDEBUG, "Params: type = %s, num = %d, set = %d, pol = %d, freq = %f, duty = %f", type, num, set, pol, freq, duty);
83
84         if (strcmp(type, "gpo") == 0)
85         {
86                 if (num <= 0 || num > GPIO_NUM_PINS)
87                 {
88                         FCGI_RejectJSON(context, "Invalid GPIO pin");
89                         return;
90                 }
91
92                 Log(LOGDEBUG, "Setting GPIO%d to %d", num, set);
93                 GPIO_Set(num, set);
94
95                 FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
96                 FCGI_PrintRaw("GPIO%d set to %d\n", num, set);
97         }
98         else if (strcmp(type, "gpi") == 0)
99         {
100                 if (num < 0 || num >= GPIO_NUM_PINS)
101                 {
102                         FCGI_RejectJSON(context, "Invalid GPIO pin");
103                         return;
104                 }
105                 Log(LOGDEBUG, "Reading GPIO%d", num);
106                 FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
107                 FCGI_PrintRaw("GPIO%d reads %d\n", num, GPIO_Read(num));
108
109         }
110         else if (strcmp(type, "adc") == 0)
111         {
112                 if (num < 0 || num >= ADC_NUM_PINS)
113                 {
114                         FCGI_RejectJSON(context, "Invalid ADC pin");
115                         return;
116                 }
117                 Log(LOGDEBUG, "Reading ADC%d", num, set);
118                 FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
119                 FCGI_PrintRaw("ADC%d reads %d\n", num, ADC_Read(num));
120         }
121         else if (strcmp(type, "pwm") == 0)
122         {
123                 if (num < 0 || num >= PWM_NUM_PINS)
124                 {
125                         FCGI_RejectJSON(context, "Invalid PWM pin");
126                         return;
127                 }
128
129                 FCGI_PrintRaw("Content-type: text/plain\r\n\r\n");
130                 
131                 if (set)
132                 {
133                         Log(LOGDEBUG, "Setting PWM%d", num);
134                         long period_ns = (long)(1e9 / freq);
135                         long duty_ns = (long)(duty * period_ns);
136                         PWM_Set(num, pol, period_ns, duty_ns);
137                         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);
138                 }
139                 else
140                 {
141                         Log(LOGDEBUG, "Stopping PWM%d",num);
142                         PWM_Stop(num);
143                         FCGI_PrintRaw("PWM%d stopped",num);
144                 }               
145         }
146         else
147         {
148                 Log(LOGDEBUG, "Invalid pin type %s", type);
149                 FCGI_RejectJSON(context, "Invalid pin type");
150         }
151
152         
153
154 }
155
156 //EOF

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