diff --git a/README.md b/README.md index f5bc6d78f0..600cf04c41 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ track of the code size of the core runtime and VM. In addition, the following ports are provided in this repository: - [cc3200](ports/cc3200) -- Texas Instruments CC3200 (including PyCom WiPy). - - [esp32](ports/esp32) -- Espressif ESP32 SoC (including ESP32S2, ESP32S3, ESP32C3). + - [esp32](ports/esp32) -- Espressif ESP32 SoC (including ESP32S2, ESP32S3, ESP32C3, ESP32C6). - [esp8266](ports/esp8266) -- Espressif ESP8266 SoC. - [mimxrt](ports/mimxrt) -- NXP m.iMX RT (including Teensy 4.x). - [nrf](ports/nrf) -- Nordic Semiconductor nRF51 and nRF52. diff --git a/ports/esp32/boards/deploy_c6.md b/ports/esp32/boards/deploy_c6.md new file mode 100644 index 0000000000..d8e567a1cd --- /dev/null +++ b/ports/esp32/boards/deploy_c6.md @@ -0,0 +1,14 @@ +Program your board using the esptool.py program, found [here](https://github.com/espressif/esptool). + +If you are putting MicroPython on your board for the first time then you should +first erase the entire flash using: + +```bash +esptool.py --chip esp32c6 --port /dev/ttyUSB0 erase_flash +``` + +From then on program the firmware starting at address 0x0: + +```bash +esptool.py --chip esp32c6 --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x0 esp32c6-20220117-v1.18.bin +``` diff --git a/ports/esp32/boards/sdkconfig.ble b/ports/esp32/boards/sdkconfig.ble index af2d4b133e..02247f8610 100644 --- a/ports/esp32/boards/sdkconfig.ble +++ b/ports/esp32/boards/sdkconfig.ble @@ -7,6 +7,9 @@ CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="MPY ESP32" CONFIG_BT_NIMBLE_MAX_CONNECTIONS=4 +# Needed to enable esp_nimble_hci on ESP32C6 +#CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y + # Put NimBLE on core 1, and for synchronisation # with the ringbuffer and scheduler MP needs to be on the same core. # MP on core 1 prevents interference with WiFi for time sensitive operations. diff --git a/ports/esp32/esp32_common.cmake b/ports/esp32/esp32_common.cmake index 89e46f9cfb..c91b3b1841 100644 --- a/ports/esp32/esp32_common.cmake +++ b/ports/esp32/esp32_common.cmake @@ -161,7 +161,7 @@ idf_component_register( set(MICROPY_TARGET ${COMPONENT_TARGET}) # Define mpy-cross flags, for use with frozen code. -if(NOT IDF_TARGET STREQUAL "esp32c3") +if(NOT IDF_TARGET MATCHES "^esp32c[36]$") set(MICROPY_CROSS_FLAGS -march=xtensawin) endif() @@ -200,6 +200,10 @@ foreach(comp ${__COMPONENT_NAMES_RESOLVED}) micropy_gather_target_properties(${comp}) endforeach() + +list(APPEND MICROPY_CPP_INC_EXTRA ${IDF_PATH}/components/riscv/include) +list(APPEND MICROPY_CPP_INC_EXTRA ${IDF_PATH}/components/soc/soc/include) + # Include the main MicroPython cmake rules. include(${MICROPY_DIR}/py/mkrules.cmake) diff --git a/ports/esp32/gccollect.c b/ports/esp32/gccollect.c index 4b6dd8ab61..74d354471f 100644 --- a/ports/esp32/gccollect.c +++ b/ports/esp32/gccollect.c @@ -61,7 +61,7 @@ void gc_collect(void) { gc_collect_end(); } -#elif CONFIG_IDF_TARGET_ESP32C3 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 #include "shared/runtime/gchelper.h" diff --git a/ports/esp32/machine_adc.c b/ports/esp32/machine_adc.c index 0ac9f5d266..2f276836fe 100644 --- a/ports/esp32/machine_adc.c +++ b/ports/esp32/machine_adc.c @@ -44,7 +44,7 @@ #define MICROPY_PY_MACHINE_ADC_CLASS_CONSTANTS_WIDTH_9_10_11 #endif -#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32S3 #define MICROPY_PY_MACHINE_ADC_CLASS_CONSTANTS_WIDTH_12 \ { MP_ROM_QSTR(MP_QSTR_WIDTH_12BIT), MP_ROM_INT(12) }, #else @@ -87,7 +87,7 @@ static const machine_adc_obj_t madc_obj[] = { {{&machine_adc_type}, ADCBLOCK2, ADC_CHANNEL_7, GPIO_NUM_27}, {{&machine_adc_type}, ADCBLOCK2, ADC_CHANNEL_8, GPIO_NUM_25}, {{&machine_adc_type}, ADCBLOCK2, ADC_CHANNEL_9, GPIO_NUM_26}, - #elif CONFIG_IDF_TARGET_ESP32C3 + #elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 {{&machine_adc_type}, ADCBLOCK1, ADC_CHANNEL_0, GPIO_NUM_0}, {{&machine_adc_type}, ADCBLOCK1, ADC_CHANNEL_1, GPIO_NUM_1}, {{&machine_adc_type}, ADCBLOCK1, ADC_CHANNEL_2, GPIO_NUM_2}, diff --git a/ports/esp32/machine_adc_block.c b/ports/esp32/machine_adc_block.c index c610233900..6afdd6f87f 100644 --- a/ports/esp32/machine_adc_block.c +++ b/ports/esp32/machine_adc_block.c @@ -35,7 +35,7 @@ machine_adc_block_obj_t madcblock_obj[] = { #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 {{&machine_adc_block_type}, ADC_UNIT_1, 12, -1, {0}}, {{&machine_adc_block_type}, ADC_UNIT_2, 12, -1, {0}}, - #elif CONFIG_IDF_TARGET_ESP32S2 + #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C6 {{&machine_adc_block_type}, ADC_UNIT_1, 13, -1, {0}}, {{&machine_adc_block_type}, ADC_UNIT_2, 13, -1, {0}}, #endif diff --git a/ports/esp32/machine_bitstream.c b/ports/esp32/machine_bitstream.c index ceb1e6ad14..b4e58c51f4 100644 --- a/ports/esp32/machine_bitstream.c +++ b/ports/esp32/machine_bitstream.c @@ -42,7 +42,7 @@ // This is a translation of the cycle counter implementation in ports/stm32/machine_bitstream.c. static void IRAM_ATTR machine_bitstream_high_low_bitbang(mp_hal_pin_obj_t pin, uint32_t *timing_ns, const uint8_t *buf, size_t len) { uint32_t pin_mask, gpio_reg_set, gpio_reg_clear; - #if !CONFIG_IDF_TARGET_ESP32C3 + #if !CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 if (pin >= 32) { pin_mask = 1 << (pin - 32); gpio_reg_set = GPIO_OUT1_W1TS_REG; diff --git a/ports/esp32/machine_hw_spi.c b/ports/esp32/machine_hw_spi.c index a0531b95f8..c4a1da5e43 100644 --- a/ports/esp32/machine_hw_spi.c +++ b/ports/esp32/machine_hw_spi.c @@ -38,10 +38,10 @@ #include "soc/spi_pins.h" // SPI mappings by device, naming used by IDF old/new -// upython | ESP32 | ESP32S2 | ESP32S3 | ESP32C3 -// ----------+-----------+-----------+---------+--------- -// SPI(id=1) | HSPI/SPI2 | FSPI/SPI2 | SPI2 | SPI2 -// SPI(id=2) | VSPI/SPI3 | HSPI/SPI3 | SPI3 | err +// upython | ESP32 | ESP32S2 | ESP32S3 | ESP32C3 | ESP32C6 +// ----------+-----------+-----------+---------+---------+--------- +// SPI(id=1) | HSPI/SPI2 | FSPI/SPI2 | SPI2 | SPI2 | SPI2 +// SPI(id=2) | VSPI/SPI3 | HSPI/SPI3 | SPI3 | err | err // Number of available hardware SPI peripherals. #if SOC_SPI_PERIPH_NUM > 2 @@ -251,7 +251,7 @@ static void machine_hw_spi_init_internal(machine_hw_spi_obj_t *self, mp_arg_val_ // Select DMA channel based on the hardware SPI host int dma_chan = 0; - #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 + #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 dma_chan = SPI_DMA_CH_AUTO; #else if (self->host == SPI2_HOST) { diff --git a/ports/esp32/machine_i2c.c b/ports/esp32/machine_i2c.c index fe42d2e8c2..94273d7d24 100755 --- a/ports/esp32/machine_i2c.c +++ b/ports/esp32/machine_i2c.c @@ -49,7 +49,7 @@ #endif #endif -#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 #define I2C_SCLK_FREQ XTAL_CLK_FREQ #elif CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 #define I2C_SCLK_FREQ APB_CLK_FREQ diff --git a/ports/esp32/machine_pin.c b/ports/esp32/machine_pin.c index 1e7b86baeb..5985714aee 100644 --- a/ports/esp32/machine_pin.c +++ b/ports/esp32/machine_pin.c @@ -44,7 +44,7 @@ #include "modesp32.h" #include "genhdr/pins.h" -#if CONFIG_IDF_TARGET_ESP32C3 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 #include "soc/usb_serial_jtag_reg.h" #endif @@ -153,13 +153,13 @@ static mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_ // reset the pin to digital if this is a mode-setting init (grab it back from ADC) if (args[ARG_mode].u_obj != mp_const_none) { if (rtc_gpio_is_valid_gpio(index)) { - #if !CONFIG_IDF_TARGET_ESP32C3 + #if !(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6) rtc_gpio_deinit(index); #endif } } - #if CONFIG_IDF_TARGET_ESP32C3 + #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 if (index == 18 || index == 19) { CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE); } diff --git a/ports/esp32/machine_pin.h b/ports/esp32/machine_pin.h index 53f9c6bdad..46c294b95b 100644 --- a/ports/esp32/machine_pin.h +++ b/ports/esp32/machine_pin.h @@ -71,7 +71,7 @@ #define MICROPY_HW_ENABLE_GPIO38 (1) #define MICROPY_HW_ENABLE_GPIO39 (1) -#elif CONFIG_IDF_TARGET_ESP32C3 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 #define MICROPY_HW_ENABLE_GPIO0 (1) #define MICROPY_HW_ENABLE_GPIO1 (1) diff --git a/ports/esp32/machine_pwm.c b/ports/esp32/machine_pwm.c index e5d8986c8a..b823e3f08f 100644 --- a/ports/esp32/machine_pwm.c +++ b/ports/esp32/machine_pwm.c @@ -241,7 +241,12 @@ static void set_freq(machine_pwm_obj_t *self, unsigned int freq, ledc_timer_conf // Configure the new resolution and frequency timer->duty_resolution = res; timer->freq_hz = freq; + #if CONFIG_IDF_TARGET_ESP32C6 + // TODO don't know if this is appropriate, compiler error suggested it + timer->clk_cfg = LEDC_USE_XTAL_CLK; + #else timer->clk_cfg = LEDC_USE_APB_CLK; + #endif #if SOC_LEDC_SUPPORT_REF_TICK if (freq < EMPIRIC_FREQ) { timer->clk_cfg = LEDC_USE_REF_TICK; diff --git a/ports/esp32/main.c b/ports/esp32/main.c index 62dd7ae3cc..c8705093a7 100644 --- a/ports/esp32/main.c +++ b/ports/esp32/main.c @@ -72,7 +72,7 @@ #define MP_TASK_PRIORITY (ESP_TASK_PRIO_MIN + 1) // Set the margin for detecting stack overflow, depending on the CPU architecture. -#if CONFIG_IDF_TARGET_ESP32C3 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 #define MP_TASK_STACK_LIMIT_MARGIN (2048) #else #define MP_TASK_STACK_LIMIT_MARGIN (1024) diff --git a/ports/esp32/main_esp32c6/CMakeLists.txt b/ports/esp32/main_esp32c6/CMakeLists.txt new file mode 100644 index 0000000000..307c0f3218 --- /dev/null +++ b/ports/esp32/main_esp32c6/CMakeLists.txt @@ -0,0 +1,14 @@ +# Set location of base MicroPython directory. +if(NOT MICROPY_DIR) + get_filename_component(MICROPY_DIR ${CMAKE_CURRENT_LIST_DIR}/../../.. ABSOLUTE) +endif() + +# Set location of the ESP32 port directory. +if(NOT MICROPY_PORT_DIR) + get_filename_component(MICROPY_PORT_DIR ${MICROPY_DIR}/ports/esp32 ABSOLUTE) +endif() + +list(APPEND MICROPY_SOURCE_LIB ${MICROPY_DIR}/shared/runtime/gchelper_generic.c) +list(APPEND IDF_COMPONENTS riscv) + +include(${MICROPY_PORT_DIR}/esp32_common.cmake) diff --git a/ports/esp32/main_esp32c6/idf_component.yml b/ports/esp32/main_esp32c6/idf_component.yml new file mode 100644 index 0000000000..5bbab6d8c3 --- /dev/null +++ b/ports/esp32/main_esp32c6/idf_component.yml @@ -0,0 +1,5 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/mdns: "~1.1.0" + idf: + version: ">=5.1.0" diff --git a/ports/esp32/main_esp32c6/linker.lf b/ports/esp32/main_esp32c6/linker.lf new file mode 100644 index 0000000000..31c5b4563c --- /dev/null +++ b/ports/esp32/main_esp32c6/linker.lf @@ -0,0 +1 @@ +# Empty linker fragment (no workaround required for C3, see main_esp32/linker.lf). diff --git a/ports/esp32/modesp32.c b/ports/esp32/modesp32.c index f363939483..32fc65dd70 100644 --- a/ports/esp32/modesp32.c +++ b/ports/esp32/modesp32.c @@ -29,7 +29,7 @@ #include #include -#include "soc/rtc_cntl_reg.h" +// #include "soc/rtc_cntl_reg.h" #include "driver/gpio.h" #include "driver/adc.h" #include "esp_heap_caps.h" diff --git a/ports/esp32/modmachine.c b/ports/esp32/modmachine.c index 759455a59a..5f94a77f22 100644 --- a/ports/esp32/modmachine.c +++ b/ports/esp32/modmachine.c @@ -90,7 +90,7 @@ typedef enum { static bool is_soft_reset = 0; -#if CONFIG_IDF_TARGET_ESP32C3 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 int esp_clk_cpu_freq(void); #endif @@ -101,11 +101,11 @@ static mp_obj_t mp_machine_get_freq(void) { static void mp_machine_set_freq(size_t n_args, const mp_obj_t *args) { mp_int_t freq = mp_obj_get_int(args[0]) / 1000000; if (freq != 20 && freq != 40 && freq != 80 && freq != 160 - #if !CONFIG_IDF_TARGET_ESP32C3 + #if !(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6) && freq != 240 #endif ) { - #if CONFIG_IDF_TARGET_ESP32C3 + #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 mp_raise_ValueError(MP_ERROR_TEXT("frequency must be 20MHz, 40MHz, 80Mhz or 160MHz")); #else mp_raise_ValueError(MP_ERROR_TEXT("frequency must be 20MHz, 40MHz, 80Mhz, 160MHz or 240MHz")); @@ -118,6 +118,8 @@ static void mp_machine_set_freq(size_t n_args, const mp_obj_t *args) { esp_pm_config_esp32_t pm; #elif CONFIG_IDF_TARGET_ESP32C3 esp_pm_config_esp32c3_t pm; + #elif CONFIG_IDF_TARGET_ESP32C6 + esp_pm_config_esp32c6_t pm; #elif CONFIG_IDF_TARGET_ESP32S2 esp_pm_config_esp32s2_t pm; #elif CONFIG_IDF_TARGET_ESP32S3 @@ -146,7 +148,7 @@ static void machine_sleep_helper(wake_type_t wake_type, size_t n_args, const mp_ esp_sleep_enable_timer_wakeup(((uint64_t)expiry) * 1000); } - #if !CONFIG_IDF_TARGET_ESP32C3 + #if !(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6) if (machine_rtc_config.ext0_pin != -1 && (machine_rtc_config.ext0_wake_types & wake_type)) { esp_sleep_enable_ext0_wakeup(machine_rtc_config.ext0_pin, machine_rtc_config.ext0_level ? 1 : 0); diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index 0afb12f85c..df1ed5dde2 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -19,7 +19,7 @@ // object representation and NLR handling #define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_A) #define MICROPY_NLR_SETJMP (1) -#if CONFIG_IDF_TARGET_ESP32C3 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 #define MICROPY_GCREGS_SETJMP (1) #endif @@ -42,7 +42,7 @@ // emitters #define MICROPY_PERSISTENT_CODE_LOAD (1) -#if !CONFIG_IDF_TARGET_ESP32C3 +#if !(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6) #define MICROPY_EMIT_XTENSAWIN (1) #endif @@ -164,6 +164,8 @@ #define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "mpy-esp32s3" #elif CONFIG_IDF_TARGET_ESP32C3 #define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "mpy-esp32c3" +#elif CONFIG_IDF_TARGET_ESP32C6 +#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "mpy-esp32c6" #endif #endif #define MICROPY_PY_NETWORK_INCLUDEFILE "ports/esp32/modnetwork.h" @@ -299,7 +301,7 @@ void boardctrl_startup(void); #if MICROPY_PY_NETWORK_LAN && CONFIG_ETH_USE_SPI_ETHERNET #ifndef MICROPY_PY_NETWORK_LAN_SPI_CLOCK_SPEED_MZ -#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 #define MICROPY_PY_NETWORK_LAN_SPI_CLOCK_SPEED_MZ (12) #else #define MICROPY_PY_NETWORK_LAN_SPI_CLOCK_SPEED_MZ (36) diff --git a/ports/esp32/mphalport.h b/ports/esp32/mphalport.h index 9a7c39487d..e5e9549109 100644 --- a/ports/esp32/mphalport.h +++ b/ports/esp32/mphalport.h @@ -73,7 +73,7 @@ void check_esp_err_(esp_err_t code, const char *func, const int line, const char uint32_t mp_hal_ticks_us(void); __attribute__((always_inline)) static inline uint32_t mp_hal_ticks_cpu(void) { uint32_t ccount; - #if CONFIG_IDF_TARGET_ESP32C3 + #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 __asm__ __volatile__ ("csrr %0, 0x7E2" : "=r" (ccount)); // Machine Performance Counter Value #else __asm__ __volatile__ ("rsr %0,ccount" : "=a" (ccount)); diff --git a/ports/esp32/mpnimbleport.c b/ports/esp32/mpnimbleport.c index 669aeb746a..4e6eff9189 100644 --- a/ports/esp32/mpnimbleport.c +++ b/ports/esp32/mpnimbleport.c @@ -32,7 +32,9 @@ #define DEBUG_printf(...) // printf("nimble (esp32): " __VA_ARGS__) +#if !CONFIG_IDF_TARGET_ESP32C6 #include "esp_nimble_hci.h" +#endif #include "nimble/nimble_port.h" #include "nimble/nimble_port_freertos.h" @@ -46,13 +48,16 @@ static void ble_host_task(void *param) { void mp_bluetooth_nimble_port_hci_init(void) { DEBUG_printf("mp_bluetooth_nimble_port_hci_init\n"); + #if !CONFIG_IDF_TARGET_ESP32C6 esp_nimble_hci_init(); + #endif } void mp_bluetooth_nimble_port_hci_deinit(void) { DEBUG_printf("mp_bluetooth_nimble_port_hci_deinit\n"); - + #if !CONFIG_IDF_TARGET_ESP32C6 esp_nimble_hci_deinit(); + #endif } void mp_bluetooth_nimble_port_start(void) {