Skip to content

Commit 3120222

Browse files
add HW pin constants and serial pin config
1 parent 5b8bff7 commit 3120222

File tree

3 files changed

+126
-14
lines changed

3 files changed

+126
-14
lines changed

Boards.h

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,19 @@ writePort(port, value, bitmask): Write an 8 bit port.
200200
#define TOTAL_ANALOG_PINS 16
201201
#define TOTAL_PINS 70 // 54 digital + 16 analog
202202
#define VERSION_BLINK_PIN 13
203+
#define PIN_SERIAL1_RX 19
204+
#define PIN_SERIAL1_TX 18
205+
#define PIN_SERIAL2_RX 17
206+
#define PIN_SERIAL2_TX 16
207+
#define PIN_SERIAL3_RX 15
208+
#define PIN_SERIAL3_TX 14
203209
#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
204210
#define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
205211
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
206212
#define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
207213
#define IS_PIN_I2C(p) ((p) == 20 || (p) == 21)
208214
#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
215+
#define IS_PIN_SERIAL(p) ((p) > 13 && (p) < 20)
209216
#define PIN_TO_DIGITAL(p) (p)
210217
#define PIN_TO_ANALOG(p) ((p) - 54)
211218
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
@@ -217,11 +224,18 @@ writePort(port, value, bitmask): Write an 8 bit port.
217224
#define TOTAL_ANALOG_PINS 12
218225
#define TOTAL_PINS 66 // 54 digital + 12 analog
219226
#define VERSION_BLINK_PIN 13
227+
#define PIN_SERIAL1_RX 19
228+
#define PIN_SERIAL1_TX 18
229+
#define PIN_SERIAL2_RX 17
230+
#define PIN_SERIAL2_TX 16
231+
#define PIN_SERIAL3_RX 15
232+
#define PIN_SERIAL3_TX 14
220233
#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
221234
#define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
222235
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
223236
#define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
224237
#define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) // 70 71
238+
#define IS_PIN_SERIAL(p) ((p) > 13 && (p) < 20)
225239
#define PIN_TO_DIGITAL(p) (p)
226240
#define PIN_TO_ANALOG(p) ((p) - 54)
227241
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
@@ -233,12 +247,15 @@ writePort(port, value, bitmask): Write an 8 bit port.
233247
#define TOTAL_ANALOG_PINS 0
234248
#define TOTAL_PINS 21 // 21 digital + no analog
235249
#define VERSION_BLINK_PIN 6
250+
#define PIN_SERIAL1_RX 2
251+
#define PIN_SERIAL1_TX 3
236252
#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
237253
#define IS_PIN_ANALOG(p) (0)
238254
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
239255
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
240256
#define IS_PIN_I2C(p) (0)
241257
#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
258+
#define IS_PIN_SERIAL(p) ((p) == 2 || (p) == 3)
242259
#define PIN_TO_DIGITAL(p) (p)
243260
#define PIN_TO_ANALOG(p) (0)
244261
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
@@ -250,12 +267,15 @@ writePort(port, value, bitmask): Write an 8 bit port.
250267
#define TOTAL_ANALOG_PINS 12
251268
#define TOTAL_PINS 25 // 11 digital + 12 analog
252269
#define VERSION_BLINK_PIN 11
270+
#define PIN_SERIAL1_RX 7
271+
#define PIN_SERIAL1_TX 8
253272
#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
254273
#define IS_PIN_ANALOG(p) ((p) >= 11 && (p) <= 22)
255274
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
256275
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
257276
#define IS_PIN_I2C(p) ((p) == 5 || (p) == 6)
258277
#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
278+
#define IS_PIN_SERIAL(p) ((p) == 7 || (p) == 8)
259279
#define PIN_TO_DIGITAL(p) (p)
260280
#define PIN_TO_ANALOG(p) (((p)<22)?21-(p):11)
261281
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
@@ -267,11 +287,18 @@ writePort(port, value, bitmask): Write an 8 bit port.
267287
#define TOTAL_ANALOG_PINS 14
268288
#define TOTAL_PINS 38 // 24 digital + 10 analog-digital + 4 analog
269289
#define VERSION_BLINK_PIN 13
290+
#define PIN_SERIAL1_RX 0
291+
#define PIN_SERIAL1_TX 1
292+
#define PIN_SERIAL2_RX 9
293+
#define PIN_SERIAL2_TX 10
294+
#define PIN_SERIAL3_RX 7
295+
#define PIN_SERIAL3_TX 8
270296
#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 34)
271297
#define IS_PIN_ANALOG(p) (((p) >= 14 && (p) <= 23) || ((p) >= 34 && (p) <= 38))
272298
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
273299
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
274300
#define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
301+
#define IS_PIN_SERIAL(p) (((p) > 6 && (p) < 11) || ((p) == 0 || (p) == 1))
275302
#define PIN_TO_DIGITAL(p) (p)
276303
#define PIN_TO_ANALOG(p) (((p)<=23)?(p)-14:(p)-24)
277304
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
@@ -283,12 +310,15 @@ writePort(port, value, bitmask): Write an 8 bit port.
283310
#define TOTAL_ANALOG_PINS 8
284311
#define TOTAL_PINS 46 // 38 digital + 8 analog
285312
#define VERSION_BLINK_PIN 6
313+
#define PIN_SERIAL1_RX 2
314+
#define PIN_SERIAL1_TX 3
286315
#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
287316
#define IS_PIN_ANALOG(p) ((p) >= 38 && (p) < TOTAL_PINS)
288317
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
289318
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
290319
#define IS_PIN_I2C(p) ((p) == 0 || (p) == 1)
291320
#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
321+
#define IS_PIN_SERIAL(p) ((p) == 2 || (p) == 3)
292322
#define PIN_TO_DIGITAL(p) (p)
293323
#define PIN_TO_ANALOG(p) ((p) - 38)
294324
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
@@ -300,28 +330,35 @@ writePort(port, value, bitmask): Write an 8 bit port.
300330
#define TOTAL_ANALOG_PINS 12
301331
#define TOTAL_PINS 30 // 14 digital + 12 analog + 4 SPI (D14-D17 on ISP header)
302332
#define VERSION_BLINK_PIN 13
333+
#define PIN_SERIAL1_RX 0
334+
#define PIN_SERIAL1_TX 1
303335
#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
304336
#define IS_PIN_ANALOG(p) ((p) >= 18 && (p) < TOTAL_PINS)
305337
#define IS_PIN_PWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11 || (p) == 13)
306338
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
307339
#define IS_PIN_I2C(p) ((p) == 2 || (p) == 3)
308340
#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
341+
#define IS_PIN_SERIAL(p) ((p) == 0 || (p) == 1)
309342
#define PIN_TO_DIGITAL(p) (p)
310343
#define PIN_TO_ANALOG(p) (p) - 18
311344
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
312345
#define PIN_TO_SERVO(p) (p)
313346

347+
314348
// Intel Galileo Board
315349
#elif defined(ARDUINO_LINUX)
316350
#define TOTAL_ANALOG_PINS 6
317351
#define TOTAL_PINS 20 // 14 digital + 6 analog
318352
#define VERSION_BLINK_PIN 13
353+
#define PIN_SERIAL1_RX 0
354+
#define PIN_SERIAL1_TX 1
319355
#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19)
320356
#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 19)
321357
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
322358
#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
323359
#define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
324360
#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK)
361+
#define IS_PIN_SERIAL(p) ((p) == 0 || (p) == 1)
325362
#define PIN_TO_DIGITAL(p) (p)
326363
#define PIN_TO_ANALOG(p) ((p) - 14)
327364
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
@@ -490,7 +527,7 @@ writePort(port, value, bitmask): Write an 8 bit port.
490527
// Pic32 chipKIT MAX32
491528
#elif defined(_BOARD_MEGA_) && defined(__PIC32) // NOTE: no _BOARD_MAX32_ to use
492529
#define TOTAL_ANALOG_PINS NUM_ANALOG_PINS // 16
493-
#define TOTAL_PINS NUM_DIGITAL_PINS // 87
530+
#define TOTAL_PINS NUM_DIGITAL_PINS // 87
494531
#define MAX_SERVOS NUM_DIGITAL_PINS
495532
#define VERSION_BLINK_PIN PIN_LED1
496533
#define IS_PIN_DIGITAL(p) ((p) >= 2)
@@ -534,6 +571,10 @@ writePort(port, value, bitmask): Write an 8 bit port.
534571
#define IS_PIN_SPI(p) 0
535572
#endif
536573

574+
#ifndef IS_PIN_SERIAL
575+
#define IS_PIN_SERIAL(p) 0
576+
#endif
577+
537578
/*==============================================================================
538579
* readPort() - Read an 8 bit port
539580
*============================================================================*/

Firmata.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
// extended command set using sysex (0-127/0x00-0x7F)
4343
/* 0x00-0x0F reserved for user-defined commands */
44+
#define SERIAL_MESSAGE 0x60 // communicate with serial devices, including other boards
4445
#define ENCODER_DATA 0x61 // reply with encoders current positions
4546
#define SERVO_CONFIG 0x70 // set max angle, minPulse, maxPulse, freq
4647
#define STRING_DATA 0x71 // a string message with 14-bits per char
@@ -79,8 +80,9 @@
7980
#define ONEWIRE 0x07 // pin configured for 1-wire
8081
#define STEPPER 0x08 // pin configured for stepper motor
8182
#define ENCODER 0x09 // pin configured for rotary encoders
83+
#define MODE_SERIAL 0x0A // pin configured for serial communication
8284
#define IGNORE 0x7F // pin configured to be ignored by digitalWrite and capabilityResponse
83-
#define TOTAL_PIN_MODES 11
85+
#define TOTAL_PIN_MODES 12
8486

8587
extern "C" {
8688
// callback function types

examples/StandardFirmata/StandardFirmata.ino

Lines changed: 81 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,14 @@
4242
#define SW_SERIAL2 0x0A
4343
#define SW_SERIAL3 0x0B
4444

45-
#define SERIAL_MESSAGE 0x60
45+
// map configuration query response resolution value to serial pin type
46+
#define CONFIG_RX1 0x02
47+
#define CONFIG_TX1 0x03
48+
#define CONFIG_RX2 0x04
49+
#define CONFIG_TX2 0x05
50+
#define CONFIG_RX3 0x06
51+
#define CONFIG_TX3 0x07
52+
4653
#define SERIAL_CONFIG 0x10
4754
#define SERIAL_WRITE 0x20
4855
#define SERIAL_READ 0x30
@@ -67,7 +74,7 @@
6774
#define I2C_REGISTER_NOT_SPECIFIED -1
6875

6976
// the minimum interval for sampling analog input
70-
#define MINIMUM_SAMPLING_INTERVAL 10
77+
#define MINIMUM_SAMPLING_INTERVAL 10
7178

7279

7380
/*==============================================================================
@@ -160,19 +167,19 @@ Stream* getPortFromId(byte portId)
160167
// block use of Serial (typically pins 0 and 1) until ability to reclaim Serial is implemented
161168
//return &Serial;
162169
return NULL;
163-
#if defined(UBRR1H) || defined(USBCON)
170+
#if defined(PIN_SERIAL1_RX)
164171
case HW_SERIAL1:
165172
return &Serial1;
166173
#endif
167-
#if defined(UBRR2H) || defined(SERIAL_PORT_HARDWARE2)
174+
#if defined(PIN_SERIAL2_RX)
168175
case HW_SERIAL2:
169176
return &Serial2;
170177
#endif
171-
#if defined(UBRR3H) || defined(SERIAL_PORT_HARDWARE3)
178+
#if defined(PIN_SERIAL3_RX)
172179
case HW_SERIAL3:
173180
return &Serial3;
174181
#endif
175-
#if defined(ARDUINO_ARCH_AVR)
182+
#if defined(SoftwareSerial_h)
176183
case SW_SERIAL0:
177184
if (swSerial0 != NULL) {
178185
// instances of SoftwareSerial are already pointers so simply return the instance
@@ -218,7 +225,7 @@ void checkSerial()
218225
if (serialPort == NULL) {
219226
continue;
220227
}
221-
#if defined(ARDUINO_ARCH_AVR)
228+
#if defined(SoftwareSerial_h)
222229
// only the SoftwareSerial port that is "listening" can read data
223230
if (portId > 7 && !((SoftwareSerial*)serialPort)->isListening()) {
224231
continue;
@@ -249,6 +256,57 @@ void checkSerial()
249256
}
250257
}
251258

259+
/*
260+
* Return the serial serial pin type (RX1, TX1, RX2, TX2, etc) for the specified pin
261+
*/
262+
byte getSerialPinType(byte pin) {
263+
#if defined(PIN_SERIAL1_RX)
264+
if (pin == PIN_SERIAL1_RX) return CONFIG_RX1;
265+
if (pin == PIN_SERIAL1_TX) return CONFIG_TX1;
266+
#endif
267+
#if defined(PIN_SERIAL2_RX)
268+
if (pin == PIN_SERIAL2_RX) return CONFIG_RX2;
269+
if (pin == PIN_SERIAL2_TX) return CONFIG_TX2;
270+
#endif
271+
#if defined(PIN_SERIAL3_RX)
272+
if (pin == PIN_SERIAL3_RX) return CONFIG_RX3;
273+
if (pin == PIN_SERIAL3_TX) return CONFIG_TX3;
274+
#endif
275+
return 0;
276+
}
277+
278+
byte configHWSerialPins(byte portId) {
279+
byte rxPin, txPin;
280+
switch (portId) {
281+
#if defined(PIN_SERIAL1_RX)
282+
case HW_SERIAL1:
283+
rxPin = PIN_SERIAL1_RX;
284+
txPin = PIN_SERIAL1_TX;
285+
break;
286+
#endif
287+
#if defined(PIN_SERIAL2_RX)
288+
case HW_SERIAL2:
289+
rxPin = PIN_SERIAL2_RX;
290+
txPin = PIN_SERIAL2_TX;
291+
break;
292+
#endif
293+
#if defined(PIN_SERIAL3_RX)
294+
case HW_SERIAL3:
295+
rxPin = PIN_SERIAL3_RX;
296+
txPin = PIN_SERIAL3_TX;
297+
break;
298+
#endif
299+
default:
300+
return 0;
301+
}
302+
setPinModeCallback(rxPin, MODE_SERIAL);
303+
setPinModeCallback(txPin, MODE_SERIAL);
304+
305+
// Fixes an issue where some serial devices would not work properly with Arduino Due
306+
// because all Arduino pins are set to OUTPUT by default in StandardFirmata.
307+
pinMode(rxPin, INPUT);
308+
}
309+
252310
void attachServo(byte pin, int minPulse, int maxPulse)
253311
{
254312
if (servoCount < MAX_SERVOS) {
@@ -439,6 +497,10 @@ void setPinModeCallback(byte pin, int mode)
439497
pinConfig[pin] = I2C;
440498
}
441499
break;
500+
case MODE_SERIAL:
501+
// used for both HW and SW serial
502+
pinConfig[pin] = MODE_SERIAL;
503+
break;
442504
default:
443505
Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM
444506
}
@@ -700,6 +762,10 @@ void sysexCallback(byte command, byte argc, byte *argv)
700762
Firmata.write(I2C);
701763
Firmata.write(1); // TODO: could assign a number to map to SCL or SDA
702764
}
765+
if (IS_PIN_SERIAL(pin)) {
766+
Firmata.write(MODE_SERIAL);
767+
Firmata.write(getSerialPinType(pin));
768+
}
703769
Firmata.write(127);
704770
}
705771
Firmata.write(END_SYSEX);
@@ -749,10 +815,11 @@ void sysexCallback(byte command, byte argc, byte *argv)
749815
if (portId < 8) {
750816
serialPort = getPortFromId(portId);
751817
if (serialPort != NULL) {
818+
configHWSerialPins(portId);
752819
((HardwareSerial*)serialPort)->begin(baud);
753820
}
754821
} else {
755-
#if defined(ARDUINO_ARCH_AVR)
822+
#if defined(SoftwareSerial_h)
756823
switch (portId) {
757824
case SW_SERIAL0:
758825
if (swSerial0 == NULL) {
@@ -777,6 +844,8 @@ void sysexCallback(byte command, byte argc, byte *argv)
777844
}
778845
serialPort = getPortFromId(portId);
779846
if (serialPort != NULL) {
847+
setPinModeCallback(rxPin, MODE_SERIAL);
848+
setPinModeCallback(txPin, MODE_SERIAL);
780849
((SoftwareSerial*)serialPort)->begin(baud);
781850
}
782851
#endif
@@ -830,7 +899,7 @@ void sysexCallback(byte command, byte argc, byte *argv)
830899
if (portId < 8) {
831900
((HardwareSerial*)serialPort)->end();
832901
} else {
833-
#if defined(ARDUINO_ARCH_AVR)
902+
#if defined(SoftwareSerial_h)
834903
((SoftwareSerial*)serialPort)->end();
835904
if (serialPort != NULL) {
836905
free(serialPort);
@@ -846,7 +915,7 @@ void sysexCallback(byte command, byte argc, byte *argv)
846915
getPortFromId(portId)->flush();
847916
}
848917
break;
849-
#if defined(ARDUINO_ARCH_AVR)
918+
#if defined(SoftwareSerial_h)
850919
case SERIAL_LISTEN:
851920
// can only call listen() on software serial ports
852921
if (portId > 7) {
@@ -902,7 +971,7 @@ void systemResetCallback()
902971
disableI2CPins();
903972
}
904973

905-
#if defined(ARDUINO_ARCH_AVR)
974+
#if defined(SoftwareSerial_h)
906975
// free memory allocated for SoftwareSerial ports
907976
for (byte i = SW_SERIAL0; i < SW_SERIAL3 + 1; i++) {
908977
serialPort = getPortFromId(i);
@@ -967,7 +1036,7 @@ void setup()
9671036
// Call begin(baud) on the alternate serial port and pass it to Firmata to begin like this:
9681037
// Serial1.begin(57600);
9691038
// Firmata.begin(Serial1);
970-
// then comment out or remove lines 701 - 704 below
1039+
// However do not do this if you are using SERIAL_MESSAGE
9711040

9721041
Firmata.begin(57600);
9731042
while (!Serial) {

0 commit comments

Comments
 (0)