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

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