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);