|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- /*
- * 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 ;
- }
|