circuitpython/ports/esp32s2
Jeff Epler 726dcdb60a Add some NORETURN attributes
I have a function where it should be impossible to reach the end, so I put in a safe-mode reset at the bottom:
```
int find_unused_slot(void) {
    // precondition: you already verified that a slot was available
    for (int i=0; i<NUM_SLOTS; i++) {
        if( slot_free(i)) {
            return i;
        }
    }
    safe_mode_reset(MICROPY_FATAL_ERROR);
}
```
However, the compiler still gave a diagnostic, because safe_mode_reset was not declared NORETURN.

So I started by teaching the compiler that reset_into_safe_mode never returned.  This leads at least one level deeper due to reset_cpu needing to be a NORETURN function.  Each port is a little different in this area.  I also marked reset_to_bootloader as NORETURN.
Additional notes:

 * stm32's reset_to_bootloader was not implemented, but now does a bare reset.  Most stm32s are not fitted with uf2 bootloaders anyway.
 * ditto cxd56
 * esp32s2 did not implement reset_cpu at all.  I used esp_restart().  (not tested)
 * litex did not implement reset_cpu at all.  I used reboot_ctrl_write.  But notably this is what reset_to_bootloader already did, so one or the other must be incorrect (not tested).  reboot_ctrl_write cannot be declared NORETURN, as it returns unless the special value 0xac is written), so a new unreachable forever-loop is added.
 * cxd56's reset is via a boardctl() call which can't generically be declared NORETURN, so a new unreacahble "for(;;)" forever-loop is added.
 * In several places, NVIC_SystemReset is redeclared with NORETURN applied.  This is accepted just fine by gcc.  I chose this as preferable to editing the multiple copies of CMSIS headers where it is normally declared.
 * the stub safe_mode reset simply aborts.  This is used in mpy-cross.
2020-09-28 18:55:56 -05:00
..
bindings/espidf Fix espidf.MemoryError print 2020-08-25 16:14:31 -07:00
boards Update microS2 config files 2020-09-21 14:39:31 +05:30
common-hal Move missing pin warning to shared-bindings 2020-09-23 11:39:39 -04:00
esp-idf@de733cdab5 Fix esp-idf requirements 2020-08-27 11:45:51 -07:00
modules Switch SPI to polling DMA and enable displayio 2020-06-24 13:10:08 -07:00
peripherals Style changes, reposition runtime errors 2020-08-18 11:42:06 -04:00
supervisor Add some NORETURN attributes 2020-09-28 18:55:56 -05:00
tools Spill registers before scanning the stack. 2020-05-28 18:34:14 -07:00
.gitignore Initial ESP32S2 port. 2020-05-15 15:36:16 -07:00
background.c Add PulseIn 2020-08-14 15:30:48 -04:00
background.h supervisor: factor supervisor_background_tasks from sundry ports 2020-07-15 11:49:44 -05:00
CMakeLists.txt HTTP works with my adafruit_requests 2020-08-19 14:23:18 -07:00
esp32s2_peripherals_config.h Initial ESP32S2 port. 2020-05-15 15:36:16 -07:00
fatfs_port.c Add license to some obvious files. 2020-07-06 19:16:25 +01:00
Makefile Add partition layouts for 8 and 16 MB as well. 2020-09-15 18:12:06 -07:00
mpconfigport.h Turn on json and enable socket.close 2020-08-19 14:23:28 -07:00
mpconfigport.mk RTC is pickd up automatically 2020-09-16 10:13:07 -07:00
mphalport.c Add pull up testing, proper us delay and stop supporting 45 and 46 for I2C 2020-06-24 12:47:58 -07:00
mphalport.h Initial ESP32S2 port. 2020-05-15 15:36:16 -07:00
partitions-4MB.csv Add partition layouts for 8 and 16 MB as well. 2020-09-15 18:12:06 -07:00
partitions-8MB.csv Add partition layouts for 8 and 16 MB as well. 2020-09-15 18:12:06 -07:00
partitions-16MB.csv Add partition layouts for 8 and 16 MB as well. 2020-09-15 18:12:06 -07:00
qstrdefsport.h Initial ESP32S2 port. 2020-05-15 15:36:16 -07:00
README.md Clarify location of port root 2020-09-16 10:51:08 -04:00
sdkconfig-4MB.defaults Add partition layouts for 8 and 16 MB as well. 2020-09-15 18:12:06 -07:00
sdkconfig-8MB.defaults Add partition layouts for 8 and 16 MB as well. 2020-09-15 18:12:06 -07:00
sdkconfig-16MB.defaults Add partition layouts for 8 and 16 MB as well. 2020-09-15 18:12:06 -07:00
sdkconfig.defaults Add partition layouts for 8 and 16 MB as well. 2020-09-15 18:12:06 -07:00

Circuitpython on ESP32-S2

This port adds the ESP32-S2 line of modules from Espressif to Circuitpython. ESP32-S2 modules are low power, single-core Wi-Fi microcontroller SoCs designed for IoT applications.

How this port is organized:

  • bindings/ contains some required bindings to the ESP-IDF for exceptions and memory.
  • boards/ contains the configuration files for each development board and breakout available on the port.
  • common-hal/ contains the port-specific module implementations, used by shared-module and shared-bindings.
  • esp-idf/ contains the Espressif IoT development framework installation, includign all the drivers for the port.
  • modules/ contains information specific to certain ESP32-S2 hardware modules, such as the pins used for flash and RAM on the WROVER and WROOM.
  • peripherals/ contains peripheral setup files and peripheral mapping information, sorted by family and sub-variant. Most files in this directory can be generated with the python scripts in tools/.
  • supervisor/ contains port-specific implementations of internal flash, serial and USB, as well as the port.c file, which initializes the port at startup.
  • tools/ includes useful python scripts for debugging and other purposes.

At the root level, refer to mpconfigboard.h and mpconfigport.mk for port specific settings and a list of enabled circuitpython modules.

Connecting to the ESP32-S2

The USB port built into ESP32-S2 boards such as the Saola is not the native USB of the board, but a debugging and programming interface. The actual ESP32-S2 native USB which exposes the Circuitpython drive and CDC connection is located on IO pins 19 and 20:

GPIO USB
20 D+ (green)
19 D- (white)
GND GND (black)
5V +5V (red)

Connect these pins using a USB adapter or breakout cable to access the Circuitpython drive.

Building and flashing

Before building or flashing the ESP32-S2, you must install the esp-idf. This must be re-done ever time the esp-idf is updated, but not every time you build. Run cd ports/esp32s2 from circuitpython/ to move to the esp32s2 port root, and run:

./esp-idf/install.sh

Additionally, any time you open a new bash environment for building or flashing, you must add the esp-idf tools to your path:

. esp-idf/export.sh

Building boards such as the Saola is typically done through make flash. The default port is tty.SLAB_USBtoUART, which will only work on certain Mac setups. On most machines, both Mac and Linux, you will need to set the port yourself by running ls /dev/tty.usb* and selecting the one that only appears when your development board is plugged in. An example make command with the port setting is as follows:

make BOARD=espressif_saola_1_wrover flash PORT=/dev/tty.usbserial-1421120

Debugging

The ESP32-S2 supports JTAG debugging over OpenOCD using a JLink or other probe hardware. The official tutorials can be found on the Espressif website here, but they are mostly for the ESP32-S2 Kaluga, which has built-in debugging.

OpenOCD is automatically installed and added to your bash environment during the esp-idf installation and setup process. You can double check that it is installed by using openocd --version, as per the tutorial. Attach the JTAG probe pins according to the instructions for JTAG debugging on boards that do not contain an integrated debugger.

Once the debugger is connected physically, you must run OpenOCD with attached configuration files specifying the interface (your debugger probe) and either a target or a board (targets are for SoCs only, and can be used when a full board configuration file doesn't exist). You can find the path location of these files by checking the OPENOCD_SCRIPTS environmental variable by running echo $OPENOCD_SCRIPTS in bash. Interfaces will be in the interface/ directory, and targets and boards in the target/ and board/ directories, respectively.

Note: Unfortunately, there are no board files for the esp32-s2 other than the Kaluga, and the included target/esp32s2.cfg target file will not work by default on the Jlink for boards like the Saola 1, as the default speed is incorrect. In addition, these files are covered under the GPL and cannot be included in Circuitpython. Thus, you must make a copy of the esp32s2.cfg file yourself and add the following line manually, under transport select jtag at the start of the file:

adapter_khz 1000

Once this is complete, your final OpenOCD command may look something like this:

openocd -f interface/jlink.cfg -f SOMEPATH/copied-esp32s2-saola-1.cfg

Where SOMEPATH is the location of your copied configuration file (this can be placed in the port/boards director with a prefix to ignore it with .gitignore, for instance). Interface, target and board config files sourced from espressif only need their paths from the $OPENOCD_SCRIPTS location, you don't need to include their full path. Once OpenOCD is running, connect to GDB with:

xtensa-esp32s2-elf-gdb build-espressif_saola_1_wrover/firmware.elf

And follow the Espressif GDB tutorial instructions for connecting, or add them to your gdbinit:

target remote :3333
set remote hardware-watchpoint-limit 2
mon reset halt
flushregs
thb app_main
c