Skip to content

Commit 526fa5f

Browse files
Merge pull request firmata#227 from firmata/zero-support
Add support for Arduino Zero
2 parents eb90640 + 8ab43c3 commit 526fa5f

File tree

7 files changed

+185
-53
lines changed

7 files changed

+185
-53
lines changed

Boards.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,29 @@ writePort(port, value, bitmask): Write an 8 bit port.
242242
#define PIN_TO_SERVO(p) ((p) - 2)
243243

244244

245+
// Arduino Zero
246+
// Note this will work with an Arduino Zero Pro, but not with an Arduino M0 Pro
247+
// Arduino M0 Pro does not properly map pins to the board labeled pin numbers
248+
#elif defined(_VARIANT_ARDUINO_ZERO_)
249+
#define TOTAL_ANALOG_PINS 6
250+
#define TOTAL_PINS 25 // 14 digital + 6 analog + 2 i2c + 3 spi
251+
#define TOTAL_PORTS 3 // set when TOTAL_PINS > num digitial I/O pins
252+
#define VERSION_BLINK_PIN LED_BUILTIN
253+
#define PIN_SERIAL1_RX 0
254+
#define PIN_SERIAL1_TX 1
255+
#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 19)
256+
#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS)
257+
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
258+
#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4
259+
#define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) // SDA = 20, SCL = 21
260+
#define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) // SS = A2
261+
#define IS_PIN_SERIAL(p) ((p) == 0 || (p) == 1)
262+
#define PIN_TO_DIGITAL(p) (p)
263+
#define PIN_TO_ANALOG(p) ((p) - 14)
264+
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
265+
#define PIN_TO_SERVO(p) (p) // deprecated since v2.4
266+
267+
245268
// Teensy 1.0
246269
#elif defined(__AVR_AT90USB162__)
247270
#define TOTAL_ANALOG_PINS 0
@@ -618,6 +641,7 @@ writePort(port, value, bitmask): Write an 8 bit port.
618641
#define IS_PIN_SERIAL(p) 0
619642
#endif
620643

644+
621645
/*==============================================================================
622646
* readPort() - Read an 8 bit port
623647
*============================================================================*/

examples/StandardFirmata/StandardFirmata.ino

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
2121
See file LICENSE.txt for further informations on licensing terms.
2222
23-
Last updated by Jeff Hoefs: August 9th, 2015
23+
Last updated by Jeff Hoefs: October 24th, 2015
2424
*/
2525

2626
#include <Servo.h>
@@ -255,15 +255,21 @@ void setPinModeCallback(byte pin, int mode)
255255
if (IS_PIN_ANALOG(pin)) {
256256
if (IS_PIN_DIGITAL(pin)) {
257257
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
258+
#if ARDUINO <= 100
259+
// deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.5
258260
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
261+
#endif
259262
}
260263
pinConfig[pin] = ANALOG;
261264
}
262265
break;
263266
case INPUT:
264267
if (IS_PIN_DIGITAL(pin)) {
265268
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
269+
#if ARDUINO <= 100
270+
// deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.5
266271
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
272+
#endif
267273
pinConfig[pin] = INPUT;
268274
}
269275
break;
@@ -305,13 +311,15 @@ void setPinModeCallback(byte pin, int mode)
305311
}
306312

307313
/*
308-
* Sets the value of an individual pin.
309-
* Useful if you want to set a pin value but are not tracking the digital port state.
314+
* Sets the value of an individual pin. Useful if you want to set a pin value but
315+
* are not tracking the digital port state.
316+
* Can only be used on pins configured as OUTPUT.
317+
* Cannot be used to enable pull-ups on Digital INPUT pins.
310318
*/
311319
void setPinValueCallback(byte pin, int value)
312320
{
313321
if (pin < TOTAL_PINS && IS_PIN_DIGITAL(pin)) {
314-
if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) {
322+
if (pinConfig[pin] == OUTPUT) {
315323
pinState[pin] = value;
316324
digitalWrite(PIN_TO_DIGITAL(pin), value);
317325
}
@@ -338,7 +346,7 @@ void analogWriteCallback(byte pin, int value)
338346

339347
void digitalWriteCallback(byte port, int value)
340348
{
341-
byte pin, lastPin, mask = 1, pinWriteMask = 0;
349+
byte pin, lastPin, pinValue, mask = 1, pinWriteMask = 0;
342350

343351
if (port < TOTAL_PORTS) {
344352
// create a mask of the pins on this port that are writable.
@@ -347,11 +355,21 @@ void digitalWriteCallback(byte port, int value)
347355
for (pin = port * 8; pin < lastPin; pin++) {
348356
// do not disturb non-digital pins (eg, Rx & Tx)
349357
if (IS_PIN_DIGITAL(pin)) {
350-
// only write to OUTPUT and INPUT (enables pullup)
351358
// do not touch pins in PWM, ANALOG, SERVO or other modes
352359
if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) {
353-
pinWriteMask |= mask;
354-
pinState[pin] = ((byte)value & mask) ? 1 : 0;
360+
pinValue = ((byte)value & mask) ? 1 : 0;
361+
if (pinConfig[pin] == OUTPUT) {
362+
pinWriteMask |= mask;
363+
} else if (pinConfig[pin] == INPUT && pinValue == 1 && pinState[pin] != 1) {
364+
// only handle INPUT here for backwards compatibility
365+
#if ARDUINO > 100
366+
pinMode(pin, INPUT_PULLUP);
367+
#else
368+
// only write to the INPUT pin to enable pullups if Arduino v1.0.0 or earlier
369+
pinWriteMask |= mask;
370+
#endif
371+
}
372+
pinState[pin] = pinValue;
355373
}
356374
}
357375
mask = mask << 1;
@@ -654,7 +672,7 @@ void systemResetCallback()
654672
if (IS_PIN_ANALOG(i)) {
655673
// turns off pullup, configures everything
656674
setPinModeCallback(i, ANALOG);
657-
} else {
675+
} else if (IS_PIN_DIGITAL(i)) {
658676
// sets the output to 0, configures portConfigInputs
659677
setPinModeCallback(i, OUTPUT);
660678
}

examples/StandardFirmataChipKIT/StandardFirmataChipKIT.ino

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
2222
See file LICENSE.txt for further informations on licensing terms.
2323
24-
Last updated by Brian Schmalz: August 9th, 2015
24+
Last updated by Jeff Hoefs: October 24th, 2015
2525
*/
2626

2727
#include <SoftPWMServo.h> // Gives us PWM and Servo on every pin
@@ -266,15 +266,21 @@ void setPinModeCallback(byte pin, int mode)
266266
if (IS_PIN_ANALOG(pin)) {
267267
if (IS_PIN_DIGITAL(pin)) {
268268
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
269+
#if ARDUINO <= 100
270+
// deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.5
269271
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
272+
#endif
270273
}
271274
pinConfig[pin] = ANALOG;
272275
}
273276
break;
274277
case INPUT:
275278
if (IS_PIN_DIGITAL(pin)) {
276279
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
280+
#if ARDUINO <= 100
281+
// deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.5
277282
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
283+
#endif
278284
pinConfig[pin] = INPUT;
279285
}
280286
break;
@@ -316,13 +322,15 @@ void setPinModeCallback(byte pin, int mode)
316322
}
317323

318324
/*
319-
* Sets the value of an individual pin.
320-
* Useful if you want to set a pin value but are not tracking the digital port state.
325+
* Sets the value of an individual pin. Useful if you want to set a pin value but
326+
* are not tracking the digital port state.
327+
* Can only be used on pins configured as OUTPUT.
328+
* Cannot be used to enable pull-ups on Digital INPUT pins.
321329
*/
322330
void setPinValueCallback(byte pin, int value)
323331
{
324332
if (pin < TOTAL_PINS && IS_PIN_DIGITAL(pin)) {
325-
if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) {
333+
if (pinConfig[pin] == OUTPUT) {
326334
pinState[pin] = value;
327335
digitalWrite(PIN_TO_DIGITAL(pin), value);
328336
}
@@ -349,7 +357,7 @@ void analogWriteCallback(byte pin, int value)
349357

350358
void digitalWriteCallback(byte port, int value)
351359
{
352-
byte pin, lastPin, mask = 1, pinWriteMask = 0;
360+
byte pin, lastPin, pinValue, mask = 1, pinWriteMask = 0;
353361

354362
if (port < TOTAL_PORTS) {
355363
// create a mask of the pins on this port that are writable.
@@ -358,11 +366,21 @@ void digitalWriteCallback(byte port, int value)
358366
for (pin = port * 8; pin < lastPin; pin++) {
359367
// do not disturb non-digital pins (eg, Rx & Tx)
360368
if (IS_PIN_DIGITAL(pin)) {
361-
// only write to OUTPUT and INPUT (enables pullup)
362369
// do not touch pins in PWM, ANALOG, SERVO or other modes
363370
if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) {
364-
pinWriteMask |= mask;
365-
pinState[pin] = ((byte)value & mask) ? 1 : 0;
371+
pinValue = ((byte)value & mask) ? 1 : 0;
372+
if (pinConfig[pin] == OUTPUT) {
373+
pinWriteMask |= mask;
374+
} else if (pinConfig[pin] == INPUT && pinValue == 1 && pinState[pin] != 1) {
375+
// only handle INPUT here for backwards compatibility
376+
#if ARDUINO > 100
377+
pinMode(pin, INPUT_PULLUP);
378+
#else
379+
// only write to the INPUT pin to enable pullups if Arduino v1.0.0 or earlier
380+
pinWriteMask |= mask;
381+
#endif
382+
}
383+
pinState[pin] = pinValue;
366384
}
367385
}
368386
mask = mask << 1;
@@ -663,7 +681,7 @@ void systemResetCallback()
663681
if (IS_PIN_ANALOG(i)) {
664682
// turns off pullup, configures everything
665683
setPinModeCallback(i, ANALOG);
666-
} else {
684+
} else if (IS_PIN_DIGITAL(i)) {
667685
// sets the output to 0, configures portConfigInputs
668686
setPinModeCallback(i, OUTPUT);
669687
}

examples/StandardFirmataEthernet/StandardFirmataEthernet.ino

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
2121
See file LICENSE.txt for further informations on licensing terms.
2222
23-
Last updated by Jeff Hoefs: August 9th, 2015
23+
Last updated by Jeff Hoefs: October 24th, 2015
2424
*/
2525

2626
/*
@@ -371,15 +371,21 @@ void setPinModeCallback(byte pin, int mode)
371371
if (IS_PIN_ANALOG(pin)) {
372372
if (IS_PIN_DIGITAL(pin)) {
373373
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
374+
#if ARDUINO <= 100
375+
// deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.5
374376
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
377+
#endif
375378
}
376379
pinConfig[pin] = ANALOG;
377380
}
378381
break;
379382
case INPUT:
380383
if (IS_PIN_DIGITAL(pin)) {
381384
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
385+
#if ARDUINO <= 100
386+
// deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.5
382387
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
388+
#endif
383389
pinConfig[pin] = INPUT;
384390
}
385391
break;
@@ -421,13 +427,15 @@ void setPinModeCallback(byte pin, int mode)
421427
}
422428

423429
/*
424-
* Sets the value of an individual pin.
425-
* Useful if you want to set a pin value but are not tracking the digital port state.
430+
* Sets the value of an individual pin. Useful if you want to set a pin value but
431+
* are not tracking the digital port state.
432+
* Can only be used on pins configured as OUTPUT.
433+
* Cannot be used to enable pull-ups on Digital INPUT pins.
426434
*/
427435
void setPinValueCallback(byte pin, int value)
428436
{
429437
if (pin < TOTAL_PINS && IS_PIN_DIGITAL(pin)) {
430-
if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) {
438+
if (pinConfig[pin] == OUTPUT) {
431439
pinState[pin] = value;
432440
digitalWrite(PIN_TO_DIGITAL(pin), value);
433441
}
@@ -454,7 +462,7 @@ void analogWriteCallback(byte pin, int value)
454462

455463
void digitalWriteCallback(byte port, int value)
456464
{
457-
byte pin, lastPin, mask = 1, pinWriteMask = 0;
465+
byte pin, lastPin, pinValue, mask = 1, pinWriteMask = 0;
458466

459467
if (port < TOTAL_PORTS) {
460468
// create a mask of the pins on this port that are writable.
@@ -463,11 +471,21 @@ void digitalWriteCallback(byte port, int value)
463471
for (pin = port * 8; pin < lastPin; pin++) {
464472
// do not disturb non-digital pins (eg, Rx & Tx)
465473
if (IS_PIN_DIGITAL(pin)) {
466-
// only write to OUTPUT and INPUT (enables pullup)
467474
// do not touch pins in PWM, ANALOG, SERVO or other modes
468475
if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) {
469-
pinWriteMask |= mask;
470-
pinState[pin] = ((byte)value & mask) ? 1 : 0;
476+
pinValue = ((byte)value & mask) ? 1 : 0;
477+
if (pinConfig[pin] == OUTPUT) {
478+
pinWriteMask |= mask;
479+
} else if (pinConfig[pin] == INPUT && pinValue == 1 && pinState[pin] != 1) {
480+
// only handle INPUT here for backwards compatibility
481+
#if ARDUINO > 100
482+
pinMode(pin, INPUT_PULLUP);
483+
#else
484+
// only write to the INPUT pin to enable pullups if Arduino v1.0.0 or earlier
485+
pinWriteMask |= mask;
486+
#endif
487+
}
488+
pinState[pin] = pinValue;
471489
}
472490
}
473491
mask = mask << 1;
@@ -770,7 +788,7 @@ void systemResetCallback()
770788
if (IS_PIN_ANALOG(i)) {
771789
// turns off pullup, configures everything
772790
setPinModeCallback(i, ANALOG);
773-
} else {
791+
} else if (IS_PIN_DIGITAL(i)) {
774792
// sets the output to 0, configures portConfigInputs
775793
setPinModeCallback(i, OUTPUT);
776794
}

0 commit comments

Comments
 (0)