Skip to content

Commit

Permalink
Add support for the Arduino Nano ESP32 on 3.x branch (#8909)
Browse files Browse the repository at this point in the history
* [pin_remap 1/3] platform: define ARDUINO_CORE_BUILD when building core files

* [pin_remap 2/3] core,libs: add pin remap hooks

* platform: remove previous build options if file is missing

"touch" would create the file if not present, but not delete its
contents if a previous run left the file in the build dir.

* platform: make debug_custom.json file customizable by board

* platform: fix default debug prefix

"debug.toolchain.prefix" must end with a dash, since only the tool name is
appended to this string.

The reason this is not a major issue is that the "debug_custom.json" file
(copied in the sketch directory when debugging is enabled) forces its own
prefix. And to make things more interesting, the "toolchainPrefix" entry
in that file should _not_ end with a dash.

* [pin_remap 3/3]: add Arduino Nano ESP32 board

* fix: periman: include it by default, add include guard

* fix: io_pin_remap: adjust for new perimap APIs

* fix: libraries: manually handled pin remapping files

Previously all libraries invoked either high-level APIs (transparently
remapped, like the user sketch) or low-level ESP-IDF calls (where the
remap to GPIO numbers had to be added manually).

Since 3.x, some of these are mixed (for example, periman* APIs are
remapped, while soc* are not). This must be handled by disabling the
automatic API remapping and making sure all calls use GPIO numbers.

* feat: show remapped pins in chip debug reports

---------

Co-authored-by: Jan Procházka <[email protected]>
Co-authored-by: Me No Dev <[email protected]>
  • Loading branch information
3 people authored Nov 29, 2023
1 parent 595dc01 commit 7d26b07
Show file tree
Hide file tree
Showing 28 changed files with 1,014 additions and 45 deletions.
71 changes: 70 additions & 1 deletion boards.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ menu.MemoryType=Memory Type
menu.EraseFlash=Erase All Flash Before Sketch Upload
menu.JTAGAdapter=JTAG Adapter
menu.ZigbeeMode=Zigbee Mode
menu.PinNumbers=Pin Numbering

# Custom options
menu.Revision=Board Revision
Expand Down Expand Up @@ -29688,4 +29689,72 @@ sensebox_mcu_esp32s2.menu.EraseFlash.none.upload.erase_cmd=
sensebox_mcu_esp32s2.menu.EraseFlash.all=Enabled
sensebox_mcu_esp32s2.menu.EraseFlash.all.upload.erase_cmd=-e

##############################################################
##############################################################

nano_nora.name=Arduino Nano ESP32
nano_nora.vid.0=0x2341
nano_nora.pid.0=0x0070
nano_nora.upload_port.0.vid=0x2341
nano_nora.upload_port.0.pid=0x0070

nano_nora.bootloader.tool=esptool_py
nano_nora.bootloader.tool.default=esptool_py

nano_nora.upload.tool=dfu-util
nano_nora.upload.tool.default=dfu-util
nano_nora.upload.tool.network=esp_ota
nano_nora.upload.protocol=serial
nano_nora.upload.maximum_size=3145728
nano_nora.upload.maximum_data_size=327680
nano_nora.upload.use_1200bps_touch=false
nano_nora.upload.wait_for_upload_port=false

nano_nora.serial.disableDTR=false
nano_nora.serial.disableRTS=false

nano_nora.build.tarch=xtensa
nano_nora.build.bootloader_addr=0x0
nano_nora.build.target=esp32s3
nano_nora.build.mcu=esp32s3
nano_nora.build.core=esp32
nano_nora.build.variant=arduino_nano_nora
nano_nora.build.board=NANO_ESP32
nano_nora.build.code_debug=0

nano_nora.build.usb_mode=0
nano_nora.build.cdc_on_boot=1
nano_nora.build.msc_on_boot=0
nano_nora.build.dfu_on_boot=1
nano_nora.build.f_cpu=240000000L
nano_nora.build.flash_size=16MB
nano_nora.build.flash_freq=80m
nano_nora.build.flash_mode=dio
nano_nora.build.boot=qio
nano_nora.build.boot_freq=80m
nano_nora.build.partitions=app3M_fat9M_fact512k_16MB
nano_nora.build.defines=-DBOARD_HAS_PIN_REMAP {build.disable_pin_remap} -DBOARD_HAS_PSRAM '-DUSB_MANUFACTURER="Arduino"' '-DUSB_PRODUCT="Nano ESP32"'
nano_nora.build.loop_core=-DARDUINO_RUNNING_CORE=1
nano_nora.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=1
nano_nora.build.psram_type=opi
nano_nora.build.memory_type={build.boot}_{build.psram_type}
nano_nora.build.disable_pin_remap=

nano_nora.tools.esptool_py.program.pattern_args=--chip {build.mcu} --port "{serial.port}" --before default_reset --after hard_reset write_flash -z --flash_mode {build.flash_mode} --flash_freq {build.flash_freq} --flash_size {build.flash_size} {build.bootloader_addr} "{build.path}/{build.project_name}.bootloader.bin" 0x8000 "{build.path}/{build.project_name}.partitions.bin" 0xe000 "{runtime.platform.path}/tools/partitions/boot_app0.bin" 0xf70000 "{build.variant.path}/extra/nora_recovery/nora_recovery.ino.bin" 0x10000 "{build.path}/{build.project_name}.bin"
nano_nora.tools.esptool_py.erase.pattern_args=--chip {build.mcu} --port "{serial.port}" --before default_reset --after hard_reset erase_flash

nano_nora.menu.PartitionScheme.default=With FAT partition (default)
nano_nora.menu.PartitionScheme.spiffs=With SPIFFS partition (advanced)
nano_nora.menu.PartitionScheme.spiffs.build.partitions=app3M_spiffs9M_fact512k_16MB

nano_nora.menu.PinNumbers.default=By Arduino pin (default)
nano_nora.menu.PinNumbers.byGPIONumber=By GPIO number (legacy)
nano_nora.menu.PinNumbers.byGPIONumber.build.disable_pin_remap=-DBOARD_USES_HW_GPIO_NUMBERS

nano_nora.menu.USBMode.default=Normal mode (TinyUSB)
nano_nora.menu.USBMode.hwcdc=Debug mode (Hardware CDC)
nano_nora.menu.USBMode.hwcdc.build.usb_mode=1
nano_nora.menu.USBMode.hwcdc.build.copy_jtag_files=1
nano_nora.menu.USBMode.hwcdc.build.openocdscript=esp32s3-builtin.cfg
nano_nora.menu.USBMode.hwcdc.build.debugconfig=esp32s3-arduino.json

##############################################################
11 changes: 6 additions & 5 deletions cores/esp32/Arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,13 @@
#define analogInPinToBit(P) (P)
#if SOC_GPIO_PIN_COUNT <= 32
#define digitalPinToPort(pin) (0)
#define digitalPinToBitMask(pin) (1UL << (pin))
#define digitalPinToBitMask(pin) (1UL << digitalPinToGPIONumber(pin))
#define portOutputRegister(port) ((volatile uint32_t*)GPIO_OUT_REG)
#define portInputRegister(port) ((volatile uint32_t*)GPIO_IN_REG)
#define portModeRegister(port) ((volatile uint32_t*)GPIO_ENABLE_REG)
#elif SOC_GPIO_PIN_COUNT <= 64
#define digitalPinToPort(pin) (((pin)>31)?1:0)
#define digitalPinToBitMask(pin) (1UL << (((pin)>31)?((pin)-32):(pin)))
#define digitalPinToPort(pin) ((digitalPinToGPIONumber(pin)>31)?1:0)
#define digitalPinToBitMask(pin) (1UL << (digitalPinToGPIONumber(pin)&31))
#define portOutputRegister(port) ((volatile uint32_t*)((port)?GPIO_OUT1_REG:GPIO_OUT_REG))
#define portInputRegister(port) ((volatile uint32_t*)((port)?GPIO_IN1_REG:GPIO_IN_REG))
#define portModeRegister(port) ((volatile uint32_t*)((port)?GPIO_ENABLE1_REG:GPIO_ENABLE_REG))
Expand All @@ -139,8 +139,8 @@
#endif
#define EXTERNAL_NUM_INTERRUPTS NUM_DIGITAL_PINS // All GPIOs
#define analogInputToDigitalPin(p) (((p)<NUM_ANALOG_INPUTS)?(analogChannelToDigitalPin(p)):-1)
#define digitalPinToInterrupt(p) (((p)<NUM_DIGITAL_PINS)?(p):NOT_AN_INTERRUPT)
#define digitalPinHasPWM(p) ((p)<NUM_DIGITAL_PINS)
#define digitalPinToInterrupt(p) ((((uint8_t)digitalPinToGPIONumber(p))<NUM_DIGITAL_PINS)?digitalPinToGPIONumber(p):NOT_AN_INTERRUPT)
#define digitalPinHasPWM(p) (((uint8_t)digitalPinToGPIONumber(p))<NUM_DIGITAL_PINS)

typedef bool boolean;
typedef uint8_t byte;
Expand Down Expand Up @@ -236,5 +236,6 @@ void noTone(uint8_t _pin);
#endif /* __cplusplus */

#include "pins_arduino.h"
#include "io_pin_remap.h"

#endif /* _ESP32_CORE_ARDUINO_H_ */
7 changes: 4 additions & 3 deletions cores/esp32/FunctionalInterrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
#include <stdint.h>

struct InterruptArgStructure {
std::function<void(void)> interruptFunction;
std::function<void(void)> interruptFunction;
};

void attachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode);

// The extra set of parentheses here prevents macros defined
// in io_pin_remap.h from applying to this declaration.
void (attachInterrupt)(uint8_t pin, std::function<void(void)> intRoutine, int mode);

#endif /* CORE_CORE_FUNCTIONALINTERRUPT_H_ */
11 changes: 11 additions & 0 deletions cores/esp32/HardwareSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <ctime>

#include "pins_arduino.h"
#include "io_pin_remap.h"
#include "HardwareSerial.h"
#include "soc/soc_caps.h"
#include "driver/uart.h"
Expand Down Expand Up @@ -325,6 +326,10 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
}
}

// map logical pins to GPIO numbers
rxPin = digitalPinToGPIONumber(rxPin);
txPin = digitalPinToGPIONumber(txPin);

if(_uart) {
// in this case it is a begin() over a previous begin() - maybe to change baud rate
// thus do not disable debug output
Expand Down Expand Up @@ -500,6 +505,12 @@ void HardwareSerial::setRxInvert(bool invert)
// can be called after or before begin()
bool HardwareSerial::setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin)
{
// map logical pins to GPIO numbers
rxPin = digitalPinToGPIONumber(rxPin);
txPin = digitalPinToGPIONumber(txPin);
ctsPin = digitalPinToGPIONumber(ctsPin);
rtsPin = digitalPinToGPIONumber(rtsPin);

// uartSetPins() checks if pins are valid and, if necessary, detaches the previous ones
return uartSetPins(_uart_nr, rxPin, txPin, ctsPin, rtsPin);
}
Expand Down
13 changes: 11 additions & 2 deletions cores/esp32/USB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@
#define USB_WEBUSB_URL "https://espressif.github.io/arduino-esp32/webusb.html"
#endif

#if CFG_TUD_DFU_RUNTIME
#if CFG_TUD_DFU
__attribute__((weak)) uint16_t load_dfu_ota_descriptor(uint8_t * dst, uint8_t * itf) {
return 0;
}
#elif CFG_TUD_DFU_RUNTIME
static uint16_t load_dfu_descriptor(uint8_t * dst, uint8_t * itf)
{
#define DFU_ATTRS (DFU_ATTR_CAN_DOWNLOAD | DFU_ATTR_CAN_UPLOAD | DFU_ATTR_MANIFESTATION_TOLERANT)
Expand All @@ -65,6 +69,9 @@ static uint16_t load_dfu_descriptor(uint8_t * dst, uint8_t * itf)
memcpy(dst, descriptor, TUD_DFU_RT_DESC_LEN);
return TUD_DFU_RT_DESC_LEN;
}
#endif /* CFG_TUD_DFU_RUNTIME */

#if CFG_TUD_DFU_RUNTIME
// Invoked on DFU_DETACH request to reboot to the bootloader
void tud_dfu_runtime_reboot_to_dfu_cb(void)
{
Expand Down Expand Up @@ -207,7 +214,9 @@ ESPUSB::operator bool() const
}

bool ESPUSB::enableDFU(){
#if CFG_TUD_DFU_RUNTIME
#if CFG_TUD_DFU
return tinyusb_enable_interface(USB_INTERFACE_DFU, TUD_DFU_DESC_LEN(1), load_dfu_ota_descriptor) == ESP_OK;
#elif CFG_TUD_DFU_RUNTIME
return tinyusb_enable_interface(USB_INTERFACE_DFU, TUD_DFU_RT_DESC_LEN, load_dfu_descriptor) == ESP_OK;
#endif /* CFG_TUD_DFU_RUNTIME */
return false;
Expand Down
15 changes: 14 additions & 1 deletion cores/esp32/chip-debug-report.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,11 @@ static void printBoardInfo(void){
static void printPerimanInfo(void){
chip_report_printf("GPIO Info:\n");
chip_report_printf("------------------------------------------\n");
#if defined(BOARD_HAS_PIN_REMAP)
chip_report_printf(" DPIN|GPIO : BUS_TYPE[bus/unit][chan]\n");
#else
chip_report_printf(" GPIO : BUS_TYPE[bus/unit][chan]\n");
#endif
chip_report_printf(" -------------------------------------- \n");
for(uint8_t i = 0; i < SOC_GPIO_PIN_COUNT; i++){
if(!perimanPinIsValid(i)){
Expand All @@ -252,8 +256,17 @@ static void printPerimanInfo(void){
if(type == ESP32_BUS_TYPE_INIT){
continue;//unused pin
}
const char* extra_type = perimanGetPinBusExtraType(i);
#if defined(BOARD_HAS_PIN_REMAP)
int dpin = gpioNumberToDigitalPin(i);
if (dpin < 0) {
continue;//pin is not exported
} else {
chip_report_printf(" D%-3d|%4u : ", dpin, i);
}
#else
chip_report_printf(" %4u : ", i);
#endif
const char* extra_type = perimanGetPinBusExtraType(i);
if(extra_type){
chip_report_printf("%s", extra_type);
}
Expand Down
2 changes: 2 additions & 0 deletions cores/esp32/esp32-hal-periman.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#ifdef __cplusplus
extern "C"
{
Expand Down
1 change: 1 addition & 0 deletions cores/esp32/esp32-hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ void yield(void);
#include "esp32-hal-psram.h"
#include "esp32-hal-rgb-led.h"
#include "esp32-hal-cpu.h"
#include "esp32-hal-periman.h"

void analogWrite(uint8_t pin, int value);
void analogWriteFrequency(uint8_t pin, uint32_t freq);
Expand Down
Loading

0 comments on commit 7d26b07

Please sign in to comment.