Gordons Projects

--> Projects Top-Level GIT

Updating for various stuff and bugs. CM3+ and PiA3+
[wiringPi] / wiringPi / drcSerial.c
1 /*
2  * drcSerial.c:
3  *      Extend wiringPi with the DRC Serial protocol (e.g. to Arduino)
4  *      Copyright (c) 2013-2016 Gordon Henderson
5  ***********************************************************************
6  * This file is part of wiringPi:
7  *      https://projects.drogon.net/raspberry-pi/wiringpi/
8  *
9  *    wiringPi is free software: you can redistribute it and/or modify
10  *    it under the terms of the GNU Lesser General Public License as
11  *    published by the Free Software Foundation, either version 3 of the
12  *    License, or (at your option) any later version.
13  *
14  *    wiringPi is distributed in the hope that it will be useful,
15  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *    GNU Lesser General Public License for more details.
18  *
19  *    You should have received a copy of the GNU Lesser General Public
20  *    License along with wiringPi.
21  *    If not, see <http://www.gnu.org/licenses/>.
22  ***********************************************************************
23  */
24
25 #include <stdio.h>
26 #include <time.h>
27 #include <string.h>
28 #include <errno.h>
29
30 #include "wiringPi.h"
31 #include "wiringSerial.h"
32
33 #include "drcSerial.h"
34
35
36 /*
37  * myPinMode:
38  *      Change the pin mode on the remote DRC device
39  *********************************************************************************
40  */
41
42 static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
43 {
44   /**/ if (mode == OUTPUT)
45     serialPutchar (node->fd, 'o') ;       // Input
46   else if (mode == PWM_OUTPUT)
47     serialPutchar (node->fd, 'p') ;       // PWM
48   else
49     serialPutchar (node->fd, 'i') ;       // Default to input
50
51   serialPutchar (node->fd, pin - node->pinBase) ;
52 }
53
54
55 /*
56  * myPullUpDnControl:
57  *      ATmegas only have pull-up's on of off. No pull-downs.
58  *********************************************************************************
59  */
60
61 static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
62 {
63
64 // Force pin into input mode
65
66   serialPutchar (node->fd, 'i' ) ;
67   serialPutchar (node->fd, pin - node->pinBase) ;
68
69   /**/ if (mode == PUD_UP)
70   {
71     serialPutchar (node->fd, '1') ;
72     serialPutchar (node->fd, pin - node->pinBase) ;
73   }
74   else if (mode == PUD_OFF)
75   {
76     serialPutchar (node->fd, '0') ;
77     serialPutchar (node->fd, pin - node->pinBase) ;
78   }
79 }
80
81
82 /*
83  * myDigitalWrite:
84  *********************************************************************************
85  */
86
87 static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
88 {
89   serialPutchar (node->fd, value == 0 ? '0' : '1') ;
90   serialPutchar (node->fd, pin - node->pinBase) ;
91 }
92
93
94 /*
95  * myPwmWrite:
96  *********************************************************************************
97  */
98
99 static void myPwmWrite (struct wiringPiNodeStruct *node, int pin, int value)
100 {
101   serialPutchar (node->fd, 'v') ;
102   serialPutchar (node->fd, pin - node->pinBase) ;
103   serialPutchar (node->fd, value & 0xFF) ;
104 }
105
106
107 /*
108  * myAnalogRead:
109  *********************************************************************************
110  */
111
112 static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
113 {
114   int vHi, vLo ;
115
116   serialPutchar (node->fd, 'a') ;
117   serialPutchar (node->fd, pin - node->pinBase) ;
118   vHi = serialGetchar (node->fd) ;
119   vLo = serialGetchar (node->fd) ;
120
121   return (vHi << 8) | vLo ;
122 }
123
124
125 /*
126  * myDigitalRead:
127  *********************************************************************************
128  */
129
130 static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
131 {
132   serialPutchar (node->fd, 'r') ; // Send read command
133   serialPutchar (node->fd, pin - node->pinBase) ;
134   return (serialGetchar (node->fd) == '0') ? 0 : 1 ;
135 }
136
137
138 /*
139  * drcSetup:
140  *      Create a new instance of an DRC GPIO interface.
141  *      Could be a variable nunber of pins here - we might not know in advance
142  *      if it's an ATmega with 14 pins, or something with less or more!
143  *********************************************************************************
144  */
145
146 int drcSetupSerial (const int pinBase, const int numPins, const char *device, const int baud)
147 {
148   int fd ;
149   int ok, tries ;
150   time_t then ;
151   struct wiringPiNodeStruct *node ;
152
153   if ((fd = serialOpen (device, baud)) < 0)
154     return FALSE ;
155
156   delay (10) ;  // May need longer if it's an Uno that reboots on the open...
157
158 // Flush any pending input
159
160   while (serialDataAvail (fd))
161     (void)serialGetchar (fd) ;
162
163   ok = FALSE ;
164   for (tries = 1 ; (tries < 5) && (!ok) ; ++tries)
165   {
166     serialPutchar (fd, '@') ;           // Ping
167     then = time (NULL) + 2 ;
168     while (time (NULL) < then)
169       if (serialDataAvail (fd))
170       {
171         if (serialGetchar (fd) == '@')
172         {
173           ok = TRUE ;
174           break ;
175         }
176       }
177   }
178
179   if (!ok)
180   {
181     serialClose (fd) ;
182     return FALSE ;
183   }
184
185   node = wiringPiNewNode (pinBase, numPins) ;
186
187   node->fd              = fd ;
188   node->pinMode         = myPinMode ;
189   node->pullUpDnControl = myPullUpDnControl ;
190   node->analogRead      = myAnalogRead ;
191   node->digitalRead     = myDigitalRead ;
192   node->digitalWrite    = myDigitalWrite ;
193   node->pwmWrite        = myPwmWrite ;
194
195   return TRUE ;
196 }