/*
* $Id: ssvn_zrpi.c,v 1.3 2025/03/09 19:50:47 snw Exp $
* Support for Raspberry Pi single-board computers
*
*
* Author: Serena Willis <snw@coherent-logic.com>
* Copyright (C) 1998 MUG Deutschland
* Copyright (C) 2020, 2025 Coherent Logic Development LLC
*
*
* This file is part of FreeM.
*
* FreeM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FreeM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with FreeM. If not, see <https://www.gnu.org/licenses/>.
*
* $Log: ssvn_zrpi.c,v $
* Revision 1.3 2025/03/09 19:50:47 snw
* Second phase of REUSE compliance and header reformat
*
*
* SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC
* SPDX-License-Identifier: AGPL-3.0-or-later
**/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "mpsdef.h"
#include "mref.h"
#include "ssvn_zrpi.h"
#if defined(HAVE_WIRINGPI_H)
# include <wiringPi.h>
#endif
int rpi_pinmode[RPI_PINCOUNT];
void ssvn_zrpi_init (void)
{
register int i;
#if defined(HAVE_WIRINGPI_H)
wiringPiSetup ();
for (i = 0; i < RPI_PINCOUNT; i++) {
pinMode (i, INPUT);
rpi_pinmode[i] = INPUT;
}
#endif
}
void ssvn_zrpi (short action, char *key, char *data)
{
int pin;
freem_ref_t *ref = (freem_ref_t *) malloc (sizeof (freem_ref_t));
char *kbuf = (char *) malloc (STRLEN * sizeof (char));
char *verb = (char *) malloc (STRLEN * sizeof (char));
NULLPTRCHK(ref,"ssvn_zrpi");
NULLPTRCHK(kbuf,"ssvn_zrpi");
NULLPTRCHK(verb,"ssvn_zrpi");
#if !defined(HAVE_WIRINGPI_H)
/* not on a Raspberry Pi */
*data = EOL;
merr_raise (NORPI);
goto done;
#else
mref_init (ref, MREF_RT_SSVN, "");
internal_to_mref (ref, key);
stcpy (kbuf, key);
if (strcmp (ref->subscripts[0], "INITIALIZE") == 0) {
ssvn_zrpi_init ();
*data = EOL;
merr_raise (OK);
goto done;
}
if (strcmp (ref->subscripts[0], "GPIO") != 0) {
merr_raise (INVREF);
goto done;
}
if (ref->subscript_count < 3) {
merr_raise (INVREF);
goto done;
}
pin = atol (ref->subscripts[1]);
strncpy (verb, ref->subscripts[2], 255);
if (pin < 0 || pin > RPI_PINCOUNT) {
merr_raise (INVREF);
goto done;
}
switch (action) {
case get_sym:
if (strcmp (verb, "MODE") == 0) {
switch (rpi_pinmode[pin]) {
case INPUT:
sprintf (data, "INPUT\201");
break;
case OUTPUT:
sprintf (data, "OUTPUT\201");
break;
case PWM_OUTPUT:
sprintf (data, "PWM_OUTPUT\201");
break;
case GPIO_CLOCK:
sprintf (data, "GPIO_CLOCK\201");
break;
}
}
else if (strcmp (verb, "DIGITAL") == 0) {
sprintf (data, "%d\201", digitalRead (pin));
break;
}
else if (strcmp (verb, "ANALOG") == 0) {
sprintf (data, "%d\201", analogRead (pin));
break;
}
else {
merr_raise (INVREF);
goto done;
}
goto done;
case set_sym:
if (strcmp (verb, "MODE") == 0) {
if (stcmp (data, "INPUT\201") == 0) {
pinMode (pin, INPUT);
rpi_pinmode[pin] = INPUT;
}
else if (stcmp (data, "OUTPUT\201") == 0) {
pinMode (pin, OUTPUT);
rpi_pinmode[pin] = OUTPUT;
}
else if (stcmp (data, "PWM_OUTPUT\201") == 0) {
pinMode (pin, PWM_OUTPUT);
rpi_pinmode[pin] = PWM_OUTPUT;
}
else if (stcmp (data, "GPIO_CLOCK\201") == 0) {
pinMode (pin, GPIO_CLOCK);
rpi_pinmode[pin] = GPIO_CLOCK;
}
else {
merr_raise (INVREF);
goto done;
}
goto done;
}
else if (strcmp (verb, "DIGITAL") == 0) {
char dta[255];
int val;
stcpy (dta, data);
stcnv_m2c (dta);
val = atoi (dta);
switch (val) {
case 0:
digitalWrite (pin, LOW);
goto done;
case 1:
digitalWrite (pin, HIGH);
goto done;
default:
merr_raise (INVREF);
goto done;
}
goto done;
}
else if (strcmp (verb, "ANALOG") == 0) {
char dta[255];
int val;
stcpy (dta, data);
stcnv_m2c (dta);
val = atoi (dta);
if (val < 0 || val > 1024) {
merr_raise (INVREF);
goto done;
}
analogWrite (pin, val);
goto done;
}
else {
merr_raise (INVREF);
goto done;
}
goto done;
default:
merr_raise (INVREF);
goto done;
break;
}
#endif
done:
free (ref);
free (kbuf);
free (verb);
return;
}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>