1: /*
2: * $Id: ssvn_zrpi.c,v 1.4 2025/04/09 19:52:02 snw Exp $
3: * Support for Raspberry Pi single-board computers
4: *
5: *
6: * Author: Serena Willis <snw@coherent-logic.com>
7: * Copyright (C) 1998 MUG Deutschland
8: * Copyright (C) 2020, 2025 Coherent Logic Development LLC
9: *
10: *
11: * This file is part of FreeM.
12: *
13: * FreeM is free software: you can redistribute it and/or modify
14: * it under the terms of the GNU Affero General Public License as published by
15: * the Free Software Foundation, either version 3 of the License, or
16: * (at your option) any later version.
17: *
18: * FreeM is distributed in the hope that it will be useful,
19: * but WITHOUT ANY WARRANTY; without even the implied warranty of
20: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21: * GNU Affero General Public License for more details.
22: *
23: * You should have received a copy of the GNU Affero General Public License
24: * along with FreeM. If not, see <https://www.gnu.org/licenses/>.
25: *
26: * $Log: ssvn_zrpi.c,v $
27: * Revision 1.4 2025/04/09 19:52:02 snw
28: * Eliminate as many warnings as possible while building with -Wall
29: *
30: * Revision 1.3 2025/03/09 19:50:47 snw
31: * Second phase of REUSE compliance and header reformat
32: *
33: *
34: * SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC
35: * SPDX-License-Identifier: AGPL-3.0-or-later
36: **/
37:
38: #include <stdlib.h>
39: #include <stdio.h>
40: #include <string.h>
41:
42: #include "mpsdef.h"
43: #include "mref.h"
44: #include "ssvn_zrpi.h"
45:
46: #if defined(HAVE_WIRINGPI_H)
47: # include <wiringPi.h>
48: #endif
49:
50: int rpi_pinmode[RPI_PINCOUNT];
51:
52: void ssvn_zrpi_init (void)
53: {
54:
55: #if defined(HAVE_WIRINGPI_H)
56: register int i;
57:
58: wiringPiSetup ();
59:
60: for (i = 0; i < RPI_PINCOUNT; i++) {
61: pinMode (i, INPUT);
62: rpi_pinmode[i] = INPUT;
63: }
64:
65: #endif
66: return;
67: }
68:
69: void ssvn_zrpi (short action, char *key, char *data)
70: {
71: freem_ref_t *ref = (freem_ref_t *) malloc (sizeof (freem_ref_t));
72: char *kbuf = (char *) malloc (STRLEN * sizeof (char));
73: char *verb = (char *) malloc (STRLEN * sizeof (char));
74:
75: NULLPTRCHK(ref,"ssvn_zrpi");
76: NULLPTRCHK(kbuf,"ssvn_zrpi");
77: NULLPTRCHK(verb,"ssvn_zrpi");
78:
79: #if !defined(HAVE_WIRINGPI_H)
80:
81: /* not on a Raspberry Pi */
82:
83: *data = EOL;
84: merr_raise (NORPI);
85:
86: goto done;
87:
88: #else
89:
90: mref_init (ref, MREF_RT_SSVN, "");
91: internal_to_mref (ref, key);
92:
93: stcpy (kbuf, key);
94:
95:
96: if (strcmp (ref->subscripts[0], "INITIALIZE") == 0) {
97:
98: ssvn_zrpi_init ();
99:
100: *data = EOL;
101: merr_raise (OK);
102:
103: goto done;
104:
105: }
106:
107: if (strcmp (ref->subscripts[0], "GPIO") != 0) {
108: merr_raise (INVREF);
109: goto done;
110: }
111:
112: if (ref->subscript_count < 3) {
113: merr_raise (INVREF);
114: goto done;
115: }
116:
117: pin = atol (ref->subscripts[1]);
118: strncpy (verb, ref->subscripts[2], 255);
119:
120: if (pin < 0 || pin > RPI_PINCOUNT) {
121: merr_raise (INVREF);
122: goto done;
123: }
124:
125: switch (action) {
126:
127:
128: case get_sym:
129:
130: if (strcmp (verb, "MODE") == 0) {
131:
132: switch (rpi_pinmode[pin]) {
133:
134: case INPUT:
135: sprintf (data, "INPUT\201");
136: break;
137:
138: case OUTPUT:
139: sprintf (data, "OUTPUT\201");
140: break;
141:
142: case PWM_OUTPUT:
143: sprintf (data, "PWM_OUTPUT\201");
144: break;
145:
146: case GPIO_CLOCK:
147: sprintf (data, "GPIO_CLOCK\201");
148: break;
149: }
150:
151:
152: }
153: else if (strcmp (verb, "DIGITAL") == 0) {
154:
155: sprintf (data, "%d\201", digitalRead (pin));
156: break;
157:
158: }
159: else if (strcmp (verb, "ANALOG") == 0) {
160:
161: sprintf (data, "%d\201", analogRead (pin));
162: break;
163:
164: }
165: else {
166: merr_raise (INVREF);
167: goto done;
168: }
169:
170: goto done;
171:
172:
173: case set_sym:
174:
175:
176: if (strcmp (verb, "MODE") == 0) {
177:
178: if (stcmp (data, "INPUT\201") == 0) {
179: pinMode (pin, INPUT);
180: rpi_pinmode[pin] = INPUT;
181: }
182: else if (stcmp (data, "OUTPUT\201") == 0) {
183: pinMode (pin, OUTPUT);
184: rpi_pinmode[pin] = OUTPUT;
185: }
186: else if (stcmp (data, "PWM_OUTPUT\201") == 0) {
187: pinMode (pin, PWM_OUTPUT);
188: rpi_pinmode[pin] = PWM_OUTPUT;
189: }
190: else if (stcmp (data, "GPIO_CLOCK\201") == 0) {
191: pinMode (pin, GPIO_CLOCK);
192: rpi_pinmode[pin] = GPIO_CLOCK;
193: }
194: else {
195: merr_raise (INVREF);
196: goto done;
197: }
198:
199: goto done;
200:
201: }
202: else if (strcmp (verb, "DIGITAL") == 0) {
203:
204: char dta[255];
205: int val;
206:
207: stcpy (dta, data);
208: stcnv_m2c (dta);
209:
210: val = atoi (dta);
211:
212: switch (val) {
213:
214: case 0:
215: digitalWrite (pin, LOW);
216: goto done;
217:
218: case 1:
219: digitalWrite (pin, HIGH);
220: goto done;
221:
222: default:
223: merr_raise (INVREF);
224: goto done;
225:
226: }
227:
228: goto done;
229:
230: }
231: else if (strcmp (verb, "ANALOG") == 0) {
232:
233: char dta[255];
234: int val;
235:
236: stcpy (dta, data);
237: stcnv_m2c (dta);
238:
239: val = atoi (dta);
240:
241: if (val < 0 || val > 1024) {
242: merr_raise (INVREF);
243: goto done;
244: }
245:
246: analogWrite (pin, val);
247:
248: goto done;
249:
250: }
251: else {
252: merr_raise (INVREF);
253: goto done;
254: }
255:
256: goto done;
257:
258:
259: default:
260:
261: merr_raise (INVREF);
262: goto done;
263:
264: break;
265:
266: }
267:
268: #endif
269:
270:
271: done:
272:
273: free (ref);
274: free (kbuf);
275: free (verb);
276:
277: return;
278:
279: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>