firmata/ConfigurableFirmata

Support for RP2040 / Pico

Closed this issue · 3 comments

I believe this to be the board definition for a standard Raspberry Pi Pico device, it would be great if this could be incorporated:

 // Raspberry Pi Pico
 // https://datasheets.raspberrypi.org/pico/Pico-R3-A4-Pinout.pdf
 #elif defined(TARGET_RP2040) || defined(TARGET_RASPBERRY_PI_PICO)
 #define TOTAL_ANALOG_PINS       4
 #define TOTAL_PINS              30
 #define VERSION_BLINK_PIN       LED_BUILTIN
 #define IS_PIN_DIGITAL(p)       (((p) >= 0 && (p) < 23) || (p) == LED_BUILTIN)
 #define IS_PIN_ANALOG(p)        ((p) >= 26 && (p) < 26 + TOTAL_ANALOG_PINS)
 #define IS_PIN_PWM(p)           digitalPinHasPWM(p)
 #define IS_PIN_SERVO(p)         (IS_PIN_DIGITAL(p) && (p) != LED_BUILTIN)
 // From the data sheet I2C-0 defaults to GP 4 (SDA) & 5 (SCL) (physical pins 6 & 7)
 // However, v2.3.1 of mbed_rp2040 defines WIRE_HOWMANY to 1 and uses the non-default GPs 6 & 7:
 //#define WIRE_HOWMANY	(1)
 //#define PIN_WIRE_SDA            (6u)
 //#define PIN_WIRE_SCL            (7u)
 #define IS_PIN_I2C(p)           ((p) == PIN_WIRE_SDA || (p) == PIN_WIRE_SCL)
 // SPI-0 defaults to GP 16 (RX / MISO), 17 (CSn), 18 (SCK) & 19 (TX / MOSI) (physical pins 21, 22, 24, 25)
 #define IS_PIN_SPI(p)           ((p) == PIN_SPI_SCK || (p) == PIN_SPI_MOSI || (p) == PIN_SPI_MISO || (p) == PIN_SPI_SS)
 // UART-0 defaults to GP 0 (TX) & 1 (RX)
 #define IS_PIN_SERIAL(p)        ((p) == 0 || (p) == 1 || (p) == 4 || (p) == 5 || (p) == 8 || (p) == 9 || (p) == 12 || (p) == 13 || (p) == 16 || (p) == 17)
 #define PIN_TO_DIGITAL(p)       (p)
 #define PIN_TO_ANALOG(p)        ((p) - 26)
 #define PIN_TO_PWM(p)           (p)
 #define PIN_TO_SERVO(p)         (p)

I've done basic tests with the above using DIGITAL_INPUT, DIGITAL_OUTPUT and I2C.

@mattjlewis : Thanks for providing and testing this. I'll be looking forward to a PR. Did you use the Arduino IDE with https://github.com/earlephilhower/arduino-pico for programming the pico or some other way?

It's great to see new features being added to Firmata.
I installed support for "Arduino Mbed OS RP2040 Boards" using the Arduino Boards Manager in the Arduino IDE. Annoyingly I can't get ConfigurableFirmata to work (apologies, I thought that was the version that I'd used) - it works with StandardFirmata / StandardFirmataPlus. I'll do some further investigation.

/Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/ConfigurableFirmata.cpp: In member function 'void FirmataClass::sendStringf(FlashString*, int, ...)':
/Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/ConfigurableFirmata.cpp:500:5: error: 'va_start' was not declared in this scope
     va_start (va, sizeOfArgs);
     ^~~~~~~~
/Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/ConfigurableFirmata.cpp:500:5: note: suggested alternative: 'stat'
     va_start (va, sizeOfArgs);
     ^~~~~~~~
     stat
/Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/ConfigurableFirmata.cpp:520:5: error: 'va_end' was not declared in this scope
     va_end (va);
     ^~~~~~
/Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/ConfigurableFirmata.cpp:520:5: note: suggested alternative: 'rand'
     va_end (va);
     ^~~~~~
     rand
/Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/Frequency.cpp: In member function 'virtual boolean Frequency::handleSysex(byte, byte, byte*)':
/Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/Frequency.cpp:110:77: error: no matching function for call to 'attachInterrupt(byte&, void (&)(), int&)'
       attachInterrupt(digitalPinToInterrupt(pin), FrequencyIsr, internalMode);
                                                                             ^
In file included from /Users/xxx/Library/Arduino15/packages/arduino/hardware/mbed_rp2040/2.3.1/variants/RASPBERRY_PI_PICO/pinmode_arduino.h:30:0,
                 from /Users/xxx/Library/Arduino15/packages/arduino/hardware/mbed_rp2040/2.3.1/cores/arduino/Arduino.h:26,
                 from /Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/utility/Boards.h:23,
                 from /Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/ConfigurableFirmata.h:18,
                 from /Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/Frequency.cpp:19:
/Users/xxx/Library/Arduino15/packages/arduino/hardware/mbed_rp2040/2.3.1/cores/arduino/api/Common.h:111:6: note: candidate: void attachInterrupt(pin_size_t, voidFuncPtr, PinStatus) <near match>
 void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus mode);
      ^~~~~~~~~~~~~~~
/Users/xxx/Library/Arduino15/packages/arduino/hardware/mbed_rp2040/2.3.1/cores/arduino/api/Common.h:111:6: note:   conversion of argument 3 would be ill-formed:
/Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/Frequency.cpp:110:77: error: invalid conversion from 'int' to 'PinStatus' [-fpermissive]
       attachInterrupt(digitalPinToInterrupt(pin), FrequencyIsr, internalMode);
                                                                             ^
In file included from /Users/xxx/Library/Arduino15/packages/arduino/hardware/mbed_rp2040/2.3.1/cores/arduino/Arduino.h:114:0,
                 from /Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/utility/Boards.h:23,
                 from /Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/ConfigurableFirmata.h:18,
                 from /Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/Frequency.cpp:19:
/Users/xxx/Library/Arduino15/packages/arduino/hardware/mbed_rp2040/2.3.1/cores/arduino/overloads.h:35:6: note: candidate: void attachInterrupt(PinName, voidFuncPtr, PinStatus) <near match>
 void attachInterrupt(PinName interruptNumber, voidFuncPtr callback, PinStatus mode);
      ^~~~~~~~~~~~~~~
/Users/xxx/Library/Arduino15/packages/arduino/hardware/mbed_rp2040/2.3.1/cores/arduino/overloads.h:35:6: note:   conversion of argument 3 would be ill-formed:
/Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/Frequency.cpp:110:77: error: invalid conversion from 'int' to 'PinStatus' [-fpermissive]
       attachInterrupt(digitalPinToInterrupt(pin), FrequencyIsr, internalMode);
                                                                             ^
In file included from /Users/xxx/Library/Arduino15/packages/arduino/hardware/mbed_rp2040/2.3.1/cores/arduino/api/ArduinoAPI.h:29:0,
                 from /Users/xxx/Library/Arduino15/packages/arduino/hardware/mbed_rp2040/2.3.1/cores/arduino/Arduino.h:27,
                 from /Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/utility/Boards.h:23,
                 from /Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/ConfigurableFirmata.h:18,
                 from /Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/Frequency.cpp:19:
/Users/xxx/Library/Arduino15/packages/arduino/hardware/mbed_rp2040/2.3.1/cores/arduino/api/Interrupts.h:38:27: note: candidate: template<class T> void arduino::attachInterrupt(pin_size_t, arduino::voidTemplateFuncPtrParam<T*>, PinStatus, T*)
 template<typename T> void attachInterrupt(pin_size_t interruptNum, voidTemplateFuncPtrParam<T*> userFunc, PinStatus mode, T* param) {
                           ^~~~~~~~~~~~~~~
/Users/xxx/Library/Arduino15/packages/arduino/hardware/mbed_rp2040/2.3.1/cores/arduino/api/Interrupts.h:38:27: note:   template argument deduction/substitution failed:
/Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/Frequency.cpp:110:77: note:   candidate expects 1 argument, 0 provided
       attachInterrupt(digitalPinToInterrupt(pin), FrequencyIsr, internalMode);
                                                                             ^
In file included from /Users/xxx/Library/Arduino15/packages/arduino/hardware/mbed_rp2040/2.3.1/cores/arduino/api/ArduinoAPI.h:29:0,
                 from /Users/xxx/Library/Arduino15/packages/arduino/hardware/mbed_rp2040/2.3.1/cores/arduino/Arduino.h:27,
                 from /Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/utility/Boards.h:23,
                 from /Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/ConfigurableFirmata.h:18,
                 from /Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/Frequency.cpp:19:
/Users/xxx/Library/Arduino15/packages/arduino/hardware/mbed_rp2040/2.3.1/cores/arduino/api/Interrupts.h:21:27: note: candidate: template<class T> void arduino::attachInterrupt(pin_size_t, arduino::voidTemplateFuncPtrParam<T>, PinStatus, T&)
 template<typename T> void attachInterrupt(pin_size_t interruptNum, voidTemplateFuncPtrParam<T> userFunc, PinStatus mode, T& param) {
                           ^~~~~~~~~~~~~~~
/Users/xxx/Library/Arduino15/packages/arduino/hardware/mbed_rp2040/2.3.1/cores/arduino/api/Interrupts.h:21:27: note:   template argument deduction/substitution failed:
/Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata/src/Frequency.cpp:110:77: note:   candidate expects 1 argument, 0 provided
       attachInterrupt(digitalPinToInterrupt(pin), FrequencyIsr, internalMode);
                                                                             ^
Multiple libraries were found for "ConfigurableFirmata.h"
 Used: /Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata
 Not used: /Users/xxx/Documents/Arduino/libraries/FirmataWithDeviceFeature
 Not used: /Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata_2_10_1
 Not used: /Users/xxx/Documents/Arduino/libraries/ConfigurableFirmata.official
exit status 1
Error compiling for board Raspberry Pi Pico.

The first problem was fixed by adding #include <stdarg.h> within the Pico block in Boards.h. The attachInterrupt error is related to Frequency - temporarily removing Frequency.cpp and Frequency.h allowed me to upload ConfigurableFirmata to my Pico. The Pico defines attachInterrupt as follows which does match that expected by ConfigurableFirmata:

void attachInterrupt(PinName interruptNumber, voidFuncPtr callback, PinStatus mode);