|
@@ -0,0 +1,201 @@
|
|
|
+/*
|
|
|
+ * drcSerial.c:
|
|
|
+ * Extend wiringPi with the DRC Serial protocol (e.g. to Arduino)
|
|
|
+ * Copyright (c) 2013 Gordon Henderson
|
|
|
+ ***********************************************************************
|
|
|
+ * This file is part of wiringPi:
|
|
|
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
|
|
|
+ *
|
|
|
+ * wiringPi is free software: you can redistribute it and/or modify
|
|
|
+ * it under the terms of the GNU Lesser General Public License as
|
|
|
+ * published by the Free Software Foundation, either version 3 of the
|
|
|
+ * License, or (at your option) any later version.
|
|
|
+ *
|
|
|
+ * wiringPi 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 Lesser General Public License for more details.
|
|
|
+ *
|
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
+ * License along with wiringPi.
|
|
|
+ * If not, see <http://www.gnu.org/licenses/>.
|
|
|
+ ***********************************************************************
|
|
|
+ */
|
|
|
+
|
|
|
+#include <stdio.h>
|
|
|
+#include <time.h>
|
|
|
+#include <string.h>
|
|
|
+#include <errno.h>
|
|
|
+
|
|
|
+#include "wiringPi.h"
|
|
|
+#include "wiringSerial.h"
|
|
|
+
|
|
|
+#include "drcSerial.h"
|
|
|
+
|
|
|
+#ifndef TRUE
|
|
|
+# define TRUE (1==1)
|
|
|
+# define FALSE (1==2)
|
|
|
+#endif
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ * myPinMode:
|
|
|
+ * Change the pin mode on the remote DRC device
|
|
|
+ *********************************************************************************
|
|
|
+ */
|
|
|
+
|
|
|
+static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
|
|
|
+{
|
|
|
+ /**/ if (mode == OUTPUT)
|
|
|
+ serialPutchar (node->fd, 'o') ; // Input
|
|
|
+ else if (mode == PWM_OUTPUT)
|
|
|
+ serialPutchar (node->fd, 'p') ; // PWM
|
|
|
+ else
|
|
|
+ serialPutchar (node->fd, 'i') ; // Default to input
|
|
|
+
|
|
|
+ serialPutchar (node->fd, pin - node->pinBase) ;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ * myPullUpDnControl:
|
|
|
+ * ATmegas only have pull-up's on of off. No pull-downs.
|
|
|
+ *********************************************************************************
|
|
|
+ */
|
|
|
+
|
|
|
+static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
|
|
|
+{
|
|
|
+
|
|
|
+// Force pin into input mode
|
|
|
+
|
|
|
+ serialPutchar (node->fd, 'i' ) ;
|
|
|
+ serialPutchar (node->fd, pin - node->pinBase) ;
|
|
|
+
|
|
|
+ /**/ if (mode == PUD_UP)
|
|
|
+ {
|
|
|
+ serialPutchar (node->fd, '1') ;
|
|
|
+ serialPutchar (node->fd, pin - node->pinBase) ;
|
|
|
+ }
|
|
|
+ else if (mode == PUD_OFF)
|
|
|
+ {
|
|
|
+ serialPutchar (node->fd, '0') ;
|
|
|
+ serialPutchar (node->fd, pin - node->pinBase) ;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ * myDigitalWrite:
|
|
|
+ *********************************************************************************
|
|
|
+ */
|
|
|
+
|
|
|
+static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
|
|
+{
|
|
|
+ serialPutchar (node->fd, value == 0 ? '0' : '1') ;
|
|
|
+ serialPutchar (node->fd, pin - node->pinBase) ;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ * myPwmWrite:
|
|
|
+ *********************************************************************************
|
|
|
+ */
|
|
|
+
|
|
|
+static void myPwmWrite (struct wiringPiNodeStruct *node, int pin, int value)
|
|
|
+{
|
|
|
+ serialPutchar (node->fd, 'v') ;
|
|
|
+ serialPutchar (node->fd, pin - node->pinBase) ;
|
|
|
+ serialPutchar (node->fd, value & 0xFF) ;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ * myAnalogRead:
|
|
|
+ *********************************************************************************
|
|
|
+ */
|
|
|
+
|
|
|
+static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
|
|
|
+{
|
|
|
+ int vHi, vLo ;
|
|
|
+
|
|
|
+ serialPutchar (node->fd, 'a') ;
|
|
|
+ serialPutchar (node->fd, pin - node->pinBase) ;
|
|
|
+ vHi = serialGetchar (node->fd) ;
|
|
|
+ vLo = serialGetchar (node->fd) ;
|
|
|
+
|
|
|
+ return (vHi << 8) | vLo ;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ * myDigitalRead:
|
|
|
+ *********************************************************************************
|
|
|
+ */
|
|
|
+
|
|
|
+static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
|
|
|
+{
|
|
|
+ serialPutchar (node->fd, 'r') ; // Send read command
|
|
|
+ serialPutchar (node->fd, pin - node->pinBase) ;
|
|
|
+ return (serialGetchar (node->fd) == '0') ? 0 : 1 ;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ * drcSetup:
|
|
|
+ * Create a new instance of an DRC GPIO interface.
|
|
|
+ * Could be a variable nunber of pins here - we might not know in advance
|
|
|
+ * if it's an ATmega with 14 pins, or something with less or more!
|
|
|
+ *********************************************************************************
|
|
|
+ */
|
|
|
+
|
|
|
+int drcSetupSerial (const int pinBase, const int numPins, const char *device, const int baud)
|
|
|
+{
|
|
|
+ int fd ;
|
|
|
+ int ok, tries ;
|
|
|
+ time_t then ;
|
|
|
+ struct wiringPiNodeStruct *node ;
|
|
|
+
|
|
|
+ if ((fd = serialOpen (device, baud)) < 0)
|
|
|
+ return wiringPiFailure (WPI_ALMOST, "Unable to open DRC device (%s): %s", device, strerror (errno)) ;
|
|
|
+
|
|
|
+ delay (10) ; // May need longer if it's an Uno that reboots on the open...
|
|
|
+
|
|
|
+// Flush any pending input
|
|
|
+
|
|
|
+ while (serialDataAvail (fd))
|
|
|
+ (void)serialGetchar (fd) ;
|
|
|
+
|
|
|
+ ok = FALSE ;
|
|
|
+ for (tries = 1 ; (tries < 5) && (!ok) ; ++tries)
|
|
|
+ {
|
|
|
+ serialPutchar (fd, '@') ; // Ping
|
|
|
+ then = time (NULL) + 2 ;
|
|
|
+ while (time (NULL) < then)
|
|
|
+ if (serialDataAvail (fd))
|
|
|
+ {
|
|
|
+ if (serialGetchar (fd) == '@')
|
|
|
+ {
|
|
|
+ ok = TRUE ;
|
|
|
+ break ;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!ok)
|
|
|
+ {
|
|
|
+ serialClose (fd) ;
|
|
|
+ return wiringPiFailure (WPI_FATAL, "Unable to communicate with DRC serial device") ;
|
|
|
+ }
|
|
|
+
|
|
|
+ node = wiringPiNewNode (pinBase, numPins) ;
|
|
|
+
|
|
|
+ node->fd = fd ;
|
|
|
+ node->pinMode = myPinMode ;
|
|
|
+ node->pullUpDnControl = myPullUpDnControl ;
|
|
|
+ node->analogRead = myAnalogRead ;
|
|
|
+ node->digitalRead = myDigitalRead ;
|
|
|
+ node->digitalWrite = myDigitalWrite ;
|
|
|
+ node->pwmWrite = myPwmWrite ;
|
|
|
+
|
|
|
+ return 0 ;
|
|
|
+}
|