]> AND Private Git Repository - Cipher_code.git/blob - Arduino/libraries/Firmata/FirmataMarshaller.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
up
[Cipher_code.git] / Arduino / libraries / Firmata / FirmataMarshaller.cpp
1 /*
2   FirmataMarshaller.cpp
3   Copyright (c) 2006-2008 Hans-Christoph Steiner.  All rights reserved.
4   Copyright (C) 2009-2016 Jeff Hoefs.  All rights reserved.
5
6   This library is free software; you can redistribute it and/or
7   modify it under the terms of the GNU Lesser General Public
8   License as published by the Free Software Foundation; either
9   version 2.1 of the License, or (at your option) any later version.
10
11   See file LICENSE.txt for further informations on licensing terms.
12 */
13
14 //******************************************************************************
15 //* Includes
16 //******************************************************************************
17
18 #include "FirmataMarshaller.h"
19
20 #if defined(__cplusplus) && !defined(ARDUINO)
21   #include <cstring>
22 #else
23   #include <string.h>
24 #endif
25
26 #include "FirmataConstants.h"
27
28 using namespace firmata;
29
30 //******************************************************************************
31 //* Support Functions
32 //******************************************************************************
33
34 /**
35  * Request or halt a stream of analog readings from the Firmata host application. The range of pins is
36  * limited to [0..15] when using the REPORT_ANALOG. The maximum result of the REPORT_ANALOG is limited to 14 bits
37  * (16384). To increase the pin range or value, see the documentation for the EXTENDED_ANALOG
38  * message.
39  * @param pin The analog pin for which to request the value (limited to pins 0 - 15).
40  * @param stream_enable A zero value will disable the stream, a non-zero will enable the stream
41  * @note The maximum resulting value is 14-bits (16384).
42  */
43 void FirmataMarshaller::reportAnalog(uint8_t pin, bool stream_enable)
44 const
45 {
46   if ( (Stream *)NULL == FirmataStream ) { return; }
47   // pin can only be 0-15, so chop higher bits
48   FirmataStream->write(REPORT_ANALOG | (pin & 0xF));
49   FirmataStream->write(stream_enable);
50 }
51
52 /**
53  * Request or halt an 8-bit port stream from the Firmata host application (protocol v2 and later).
54  * Send 14-bits in a single digital message (protocol v1).
55  * @param portNumber The port number for which to request the value. Note that this is not the same as a "port" on the
56  * physical microcontroller. Ports are defined in order per every 8 pins in ascending order
57  * of the Arduino digital pin numbering scheme. Port 0 = pins D0 - D7, port 1 = pins D8 - D15, etc.
58  * @param stream_enable A zero value will disable the stream, a non-zero will enable the stream
59  */
60 void FirmataMarshaller::reportDigitalPort(uint8_t portNumber, bool stream_enable)
61 const
62 {
63   if ( (Stream *)NULL == FirmataStream ) { return; }
64   FirmataStream->write(REPORT_DIGITAL | (portNumber & 0xF));
65   FirmataStream->write(stream_enable);
66 }
67
68 /**
69  * An alternative to the normal analog message, this extended version allows addressing beyond
70  * pin 15 and supports sending analog values with any number of bits.
71  * @param pin The analog pin to which the value is sent.
72  * @param bytec The size of the storage for the analog value
73  * @param bytev The pointer to the location of the analog value
74  */
75 void FirmataMarshaller::sendExtendedAnalog(uint8_t pin, size_t bytec, uint8_t * bytev)
76 const
77 {
78   if ( (Stream *)NULL == FirmataStream ) { return; }
79   FirmataStream->write(START_SYSEX);
80   FirmataStream->write(EXTENDED_ANALOG);
81   FirmataStream->write(pin);
82   encodeByteStream(bytec, bytev, bytec);
83   FirmataStream->write(END_SYSEX);
84 }
85
86 /**
87  * Transform 8-bit stream into 7-bit message
88  * @param bytec The number of data bytes in the message.
89  * @param bytev A pointer to the array of data bytes to send in the message.
90  * @param max_bytes Force message to be n bytes, regardless of data bits.
91  */
92 void FirmataMarshaller::encodeByteStream (size_t bytec, uint8_t * bytev, size_t max_bytes)
93 const
94 {
95   static const size_t transmit_bits = 7;
96   static const uint8_t transmit_mask = ((1 << transmit_bits) - 1);
97
98   size_t bytes_sent = 0;
99   size_t outstanding_bits = 0;
100   uint8_t outstanding_bit_cache = *bytev;
101
102   if ( !max_bytes ) { max_bytes = static_cast<size_t>(-1); }
103   for (size_t i = 0 ; (i < bytec) && (bytes_sent < max_bytes) ; ++i) {
104     uint8_t transmit_byte = (outstanding_bit_cache|(bytev[i] << outstanding_bits));
105     FirmataStream->write(transmit_mask & transmit_byte);
106     ++bytes_sent;
107     outstanding_bit_cache = (bytev[i] >> (transmit_bits - outstanding_bits));
108     outstanding_bits = (outstanding_bits + (8 - transmit_bits));
109     for ( ; (outstanding_bits >= transmit_bits) && (bytes_sent < max_bytes) ; ) {
110       transmit_byte = outstanding_bit_cache;
111     FirmataStream->write(transmit_mask & transmit_byte);
112       ++bytes_sent;
113       outstanding_bit_cache >>= transmit_bits;
114       outstanding_bits -= transmit_bits;
115     }
116   }
117   if ( outstanding_bits && (bytes_sent < max_bytes) ) {
118     FirmataStream->write(static_cast<uint8_t>((1 << outstanding_bits) - 1) & outstanding_bit_cache);
119   }
120 }
121
122 //******************************************************************************
123 //* Constructors
124 //******************************************************************************
125
126 /**
127  * The FirmataMarshaller class.
128  */
129 FirmataMarshaller::FirmataMarshaller()
130 :
131   FirmataStream((Stream *)NULL)
132 {
133 }
134
135 //******************************************************************************
136 //* Public Methods
137 //******************************************************************************
138
139 /**
140  * Reassign the Firmata stream transport.
141  * @param s A reference to the Stream transport object. This can be any type of
142  * transport that implements the Stream interface. Some examples include Ethernet, WiFi
143  * and other UARTs on the board (Serial1, Serial2, etc).
144  */
145 void FirmataMarshaller::begin(Stream &s)
146 {
147   FirmataStream = &s;
148 }
149
150 /**
151  * Closes the FirmataMarshaller stream by setting its stream reference to `(Stream *)NULL`
152  */
153 void FirmataMarshaller::end(void)
154 {
155   FirmataStream = (Stream *)NULL;
156 }
157
158 //******************************************************************************
159 //* Output Stream Handling
160 //******************************************************************************
161
162 /**
163  * Query the target's firmware name and version
164  */
165 void FirmataMarshaller::queryFirmwareVersion(void)
166 const
167 {
168   if ( (Stream *)NULL == FirmataStream ) { return; }
169   FirmataStream->write(START_SYSEX);
170   FirmataStream->write(REPORT_FIRMWARE);
171   FirmataStream->write(END_SYSEX);
172 }
173
174 /**
175  * Query the target's Firmata protocol version
176  */
177 void FirmataMarshaller::queryVersion(void)
178 const
179 {
180   if ( (Stream *)NULL == FirmataStream ) { return; }
181   FirmataStream->write(REPORT_VERSION);
182 }
183
184 /**
185  * Halt the stream of analog readings from the Firmata host application. The range of pins is
186  * limited to [0..15] when using the REPORT_ANALOG. The maximum result of the REPORT_ANALOG is limited to 14 bits
187  * (16384). To increase the pin range or value, see the documentation for the EXTENDED_ANALOG
188  * message.
189  * @param pin The analog pin for which to request the value (limited to pins 0 - 15).
190  */
191 void FirmataMarshaller::reportAnalogDisable(uint8_t pin)
192 const
193 {
194   reportAnalog(pin, false);
195 }
196
197 /**
198  * Request a stream of analog readings from the Firmata host application. The range of pins is
199  * limited to [0..15] when using the REPORT_ANALOG. The maximum result of the REPORT_ANALOG is limited to 14 bits
200  * (16384). To increase the pin range or value, see the documentation for the EXTENDED_ANALOG
201  * message.
202  * @param pin The analog pin for which to request the value (limited to pins 0 - 15).
203  */
204 void FirmataMarshaller::reportAnalogEnable(uint8_t pin)
205 const
206 {
207   reportAnalog(pin, true);
208 }
209
210 /**
211  * Halt an 8-bit port stream from the Firmata host application (protocol v2 and later).
212  * Send 14-bits in a single digital message (protocol v1).
213  * @param portNumber The port number for which to request the value. Note that this is not the same as a "port" on the
214  * physical microcontroller. Ports are defined in order per every 8 pins in ascending order
215  * of the Arduino digital pin numbering scheme. Port 0 = pins D0 - D7, port 1 = pins D8 - D15, etc.
216  */
217 void FirmataMarshaller::reportDigitalPortDisable(uint8_t portNumber)
218 const
219 {
220   reportDigitalPort(portNumber, false);
221 }
222
223 /**
224  * Request an 8-bit port stream from the Firmata host application (protocol v2 and later).
225  * Send 14-bits in a single digital message (protocol v1).
226  * @param portNumber The port number for which to request the value. Note that this is not the same as a "port" on the
227  * physical microcontroller. Ports are defined in order per every 8 pins in ascending order
228  * of the Arduino digital pin numbering scheme. Port 0 = pins D0 - D7, port 1 = pins D8 - D15, etc.
229  */
230 void FirmataMarshaller::reportDigitalPortEnable(uint8_t portNumber)
231 const
232 {
233   reportDigitalPort(portNumber, true);
234 }
235
236 /**
237  * Send an analog message to the Firmata host application. The range of pins is limited to [0..15]
238  * when using the ANALOG_MESSAGE. The maximum value of the ANALOG_MESSAGE is limited to 14 bits
239  * (16384). To increase the pin range or value, see the documentation for the EXTENDED_ANALOG
240  * message.
241  * @param pin The analog pin to which the value is sent.
242  * @param value The value of the analog pin (0 - 1024 for 10-bit analog, 0 - 4096 for 12-bit, etc).
243  * @note The maximum value is 14-bits (16384).
244  */
245 void FirmataMarshaller::sendAnalog(uint8_t pin, uint16_t value)
246 const
247 {
248   if ( (Stream *)NULL == FirmataStream ) { return; }
249   if ( (0xF >= pin) && (0x3FFF >= value) ) {
250     FirmataStream->write(ANALOG_MESSAGE|pin);
251     encodeByteStream(sizeof(value), reinterpret_cast<uint8_t *>(&value), sizeof(value));
252   } else {
253     sendExtendedAnalog(pin, sizeof(value), reinterpret_cast<uint8_t *>(&value));
254   }
255 }
256
257 /**
258  * Send an analog mapping query to the Firmata host application. The resulting sysex message will
259  * have an ANALOG_MAPPING_RESPONSE command byte, followed by a list of pins [0-n]; where each
260  * pin will specify its corresponding analog pin number or 0x7F (127) if not applicable.
261  */
262 void FirmataMarshaller::sendAnalogMappingQuery(void)
263 const
264 {
265   sendSysex(ANALOG_MAPPING_QUERY, 0, NULL);
266 }
267
268 /**
269  * Send a capability query to the Firmata host application. The resulting sysex message will have
270  * a CAPABILITY_RESPONSE command byte, followed by a list of byte tuples (mode and mode resolution)
271  * for each pin; where each pin list is terminated by 0x7F (127).
272  */
273 void FirmataMarshaller::sendCapabilityQuery(void)
274 const
275 {
276   sendSysex(CAPABILITY_QUERY, 0, NULL);
277 }
278
279 /**
280  * Send a single digital pin value to the Firmata host application.
281  * @param pin The digital pin to send the value of.
282  * @param value The value of the pin.
283  */
284 void FirmataMarshaller::sendDigital(uint8_t pin, uint8_t value)
285 const
286 {
287   if ( (Stream *)NULL == FirmataStream ) { return; }
288   FirmataStream->write(SET_DIGITAL_PIN_VALUE);
289   FirmataStream->write(pin & 0x7F);
290   FirmataStream->write(value != 0);
291 }
292
293
294 /**
295  * Send an 8-bit port in a single digital message (protocol v2 and later).
296  * Send 14-bits in a single digital message (protocol v1).
297  * @param portNumber The port number to send. Note that this is not the same as a "port" on the
298  * physical microcontroller. Ports are defined in order per every 8 pins in ascending order
299  * of the Arduino digital pin numbering scheme. Port 0 = pins D0 - D7, port 1 = pins D8 - D15, etc.
300  * @param portData The value of the port. The value of each pin in the port is represented by a bit.
301  */
302 void FirmataMarshaller::sendDigitalPort(uint8_t portNumber, uint16_t portData)
303 const
304 {
305   if ( (Stream *)NULL == FirmataStream ) { return; }
306   FirmataStream->write(DIGITAL_MESSAGE | (portNumber & 0xF));
307   // Tx bits  0-6 (protocol v1 and higher)
308   // Tx bits 7-13 (bit 7 only for protocol v2 and higher)
309   encodeByteStream(sizeof(portData), reinterpret_cast<uint8_t *>(&portData), sizeof(portData));
310 }
311
312 /**
313  * Sends the firmware name and version to the Firmata host application.
314  * @param major The major verison number
315  * @param minor The minor version number
316  * @param bytec The length of the firmware name
317  * @param bytev The firmware name array
318  */
319 void FirmataMarshaller::sendFirmwareVersion(uint8_t major, uint8_t minor, size_t bytec, uint8_t *bytev)
320 const
321 {
322   if ( (Stream *)NULL == FirmataStream ) { return; }
323   size_t i;
324   FirmataStream->write(START_SYSEX);
325   FirmataStream->write(REPORT_FIRMWARE);
326   FirmataStream->write(major);
327   FirmataStream->write(minor);
328   for (i = 0; i < bytec; ++i) {
329     encodeByteStream(sizeof(bytev[i]), reinterpret_cast<uint8_t *>(&bytev[i]));
330   }
331   FirmataStream->write(END_SYSEX);
332 }
333
334 /**
335  * Send the Firmata protocol version to the Firmata host application.
336  * @param major The major verison number
337  * @param minor The minor version number
338  */
339 void FirmataMarshaller::sendVersion(uint8_t major, uint8_t minor)
340 const
341 {
342   if ( (Stream *)NULL == FirmataStream ) { return; }
343   FirmataStream->write(REPORT_VERSION);
344   FirmataStream->write(major);
345   FirmataStream->write(minor);
346 }
347
348 /**
349  * Send the pin mode/configuration. The pin configuration (or mode) in Firmata represents the
350  * current function of the pin. Examples are digital input or output, analog input, pwm, i2c,
351  * serial (uart), etc.
352  * @param pin The pin to configure.
353  * @param config The configuration value for the specified pin.
354  */
355 void FirmataMarshaller::sendPinMode(uint8_t pin, uint8_t config)
356 const
357 {
358   if ( (Stream *)NULL == FirmataStream ) { return; }
359   FirmataStream->write(SET_PIN_MODE);
360   FirmataStream->write(pin);
361   FirmataStream->write(config);
362 }
363
364 /**
365  * Send a pin state query to the Firmata host application. The resulting sysex message will have
366  * a PIN_STATE_RESPONSE command byte, followed by the pin number, the pin mode and a stream of
367  * bits to indicate any *data* written to the pin (pin state).
368  * @param pin The pin to query
369  * @note The pin state is any data written to the pin (i.e. pin state != pin value)
370  */
371 void FirmataMarshaller::sendPinStateQuery(uint8_t pin)
372 const
373 {
374   if ( (Stream *)NULL == FirmataStream ) { return; }
375   FirmataStream->write(START_SYSEX);
376   FirmataStream->write(PIN_STATE_QUERY);
377   FirmataStream->write(pin);
378   FirmataStream->write(END_SYSEX);
379 }
380
381 /**
382  * Send a sysex message where all values after the command byte are packet as 2 7-bit bytes
383  * (this is not always the case so this function is not always used to send sysex messages).
384  * @param command The sysex command byte.
385  * @param bytec The number of data bytes in the message (excludes start, command and end bytes).
386  * @param bytev A pointer to the array of data bytes to send in the message.
387  */
388 void FirmataMarshaller::sendSysex(uint8_t command, size_t bytec, uint8_t *bytev)
389 const
390 {
391   if ( (Stream *)NULL == FirmataStream ) { return; }
392   size_t i;
393   FirmataStream->write(START_SYSEX);
394   FirmataStream->write(command);
395   for (i = 0; i < bytec; ++i) {
396     encodeByteStream(sizeof(bytev[i]), reinterpret_cast<uint8_t *>(&bytev[i]));
397   }
398   FirmataStream->write(END_SYSEX);
399 }
400
401 /**
402  * Send a string to the Firmata host application.
403  * @param string A pointer to the char string
404  */
405 void FirmataMarshaller::sendString(const char *string)
406 const
407 {
408   sendSysex(STRING_DATA, strlen(string), reinterpret_cast<uint8_t *>(const_cast<char *>(string)));
409 }
410
411 /**
412  * The sampling interval sets how often analog data and i2c data is reported to the client.
413  * @param interval_ms The interval (in milliseconds) at which to sample
414  * @note The default sampling interval is 19ms
415  */
416 void FirmataMarshaller::setSamplingInterval(uint16_t interval_ms)
417 const
418 {
419   sendSysex(SAMPLING_INTERVAL, sizeof(interval_ms), reinterpret_cast<uint8_t *>(&interval_ms));
420 }
421
422 /**
423  * Perform a software reset on the target. For example, StandardFirmata.ino will initialize
424  * everything to a known state and reset the parsing buffer.
425  */
426 void FirmataMarshaller::systemReset(void)
427 const
428 {
429   if ( (Stream *)NULL == FirmataStream ) { return; }
430   FirmataStream->write(SYSTEM_RESET);
431 }