esp32: Add initial support for ESP32C3 SoCs.

Supported features for this SoC are:
- UART REPL, filesystem
- Pin, ADC, PWM, SoftI2C, SoftSPI, Timer, RTC
- OneWire, DHT, NeoPixel
- RMT
- WiFi, Bluetooth

Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Damien George 2021-07-18 12:11:21 +10:00
parent 59dbbe9be7
commit 6823514845
13 changed files with 136 additions and 10 deletions

View File

@ -13,14 +13,17 @@ void IRAM_ATTR esp_neopixel_write(uint8_t pin, uint8_t *pixels, uint32_t numByte
uint8_t *p, *end, pix, mask;
uint32_t t, time0, time1, period, c, startTime, pinMask, gpio_reg_set, gpio_reg_clear;
if (pin < 32) {
pinMask = 1 << pin;
gpio_reg_set = GPIO_OUT_W1TS_REG;
gpio_reg_clear = GPIO_OUT_W1TC_REG;
} else {
#if !CONFIG_IDF_TARGET_ESP32C3
if (pin >= 32) {
pinMask = 1 << (pin - 32);
gpio_reg_set = GPIO_OUT1_W1TS_REG;
gpio_reg_clear = GPIO_OUT1_W1TC_REG;
} else
#endif
{
pinMask = 1 << pin;
gpio_reg_set = GPIO_OUT_W1TS_REG;
gpio_reg_clear = GPIO_OUT_W1TC_REG;
}
p = pixels;
end = p + numBytes;

View File

@ -35,8 +35,10 @@
#include "py/mpthread.h"
#include "gccollect.h"
#include "soc/cpu.h"
#include "xtensa/hal.h"
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#include "xtensa/hal.h"
static void gc_collect_inner(int level) {
if (level < XCHAL_NUM_AREGS / 8) {
@ -64,3 +66,18 @@ void gc_collect(void) {
gc_collect_inner(0);
gc_collect_end();
}
#elif CONFIG_IDF_TARGET_ESP32C3
#include "shared/runtime/gchelper.h"
void gc_collect(void) {
gc_collect_start();
gc_helper_collect_regs_and_stack();
#if MICROPY_PY_THREAD
mp_thread_gc_others();
#endif
gc_collect_end();
}
#endif

View File

@ -52,6 +52,12 @@ STATIC const madc_obj_t madc_obj[] = {
{{&machine_adc_type}, GPIO_NUM_33, ADC1_CHANNEL_5},
{{&machine_adc_type}, GPIO_NUM_34, ADC1_CHANNEL_6},
{{&machine_adc_type}, GPIO_NUM_35, ADC1_CHANNEL_7},
#elif CONFIG_IDF_TARGET_ESP32C3
{{&machine_adc_type}, GPIO_NUM_0, ADC1_CHANNEL_0},
{{&machine_adc_type}, GPIO_NUM_1, ADC1_CHANNEL_1},
{{&machine_adc_type}, GPIO_NUM_2, ADC1_CHANNEL_2},
{{&machine_adc_type}, GPIO_NUM_3, ADC1_CHANNEL_3},
{{&machine_adc_type}, GPIO_NUM_4, ADC1_CHANNEL_4},
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
{{&machine_adc_type}, GPIO_NUM_1, ADC1_CHANNEL_0},
{{&machine_adc_type}, GPIO_NUM_2, ADC1_CHANNEL_1},

View File

@ -53,6 +53,10 @@
#define MP_HW_SPI_MAX_XFER_BYTES (4092)
#define MP_HW_SPI_MAX_XFER_BITS (MP_HW_SPI_MAX_XFER_BYTES * 8) // Has to be an even multiple of 8
#if CONFIG_IDF_TARGET_ESP32C3
#define HSPI_HOST SPI2_HOST
#endif
typedef struct _machine_hw_spi_default_pins_t {
int8_t sck;
int8_t mosi;

View File

@ -40,6 +40,10 @@
#include "machine_rtc.h"
#include "modesp32.h"
#if CONFIG_IDF_TARGET_ESP32C3
#include "hal/gpio_ll.h"
#endif
// Used to implement a range of pull capabilities
#define GPIO_PULL_DOWN (1)
#define GPIO_PULL_UP (2)
@ -99,6 +103,31 @@ STATIC const machine_pin_obj_t machine_pin_obj[] = {
{{&machine_pin_type}, GPIO_NUM_38},
{{&machine_pin_type}, GPIO_NUM_39},
#elif CONFIG_IDF_TARGET_ESP32C3
{{&machine_pin_type}, GPIO_NUM_0},
{{&machine_pin_type}, GPIO_NUM_1},
{{&machine_pin_type}, GPIO_NUM_2},
{{&machine_pin_type}, GPIO_NUM_3},
{{&machine_pin_type}, GPIO_NUM_4},
{{&machine_pin_type}, GPIO_NUM_5},
{{&machine_pin_type}, GPIO_NUM_6},
{{&machine_pin_type}, GPIO_NUM_7},
{{&machine_pin_type}, GPIO_NUM_8},
{{&machine_pin_type}, GPIO_NUM_9},
{{&machine_pin_type}, GPIO_NUM_10},
{{&machine_pin_type}, GPIO_NUM_11},
{{&machine_pin_type}, GPIO_NUM_12},
{{&machine_pin_type}, GPIO_NUM_13},
{{&machine_pin_type}, GPIO_NUM_14},
{{&machine_pin_type}, GPIO_NUM_15},
{{&machine_pin_type}, GPIO_NUM_16},
{{&machine_pin_type}, GPIO_NUM_17},
{{&machine_pin_type}, GPIO_NUM_18},
{{&machine_pin_type}, GPIO_NUM_19},
{{&machine_pin_type}, GPIO_NUM_20},
{{&machine_pin_type}, GPIO_NUM_21},
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
{{&machine_pin_type}, GPIO_NUM_0},
@ -213,10 +242,18 @@ 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(self->id)) {
#if !CONFIG_IDF_TARGET_ESP32C3
rtc_gpio_deinit(self->id);
#endif
}
}
#if CONFIG_IDF_TARGET_ESP32C3
if (self->id == 18 || self->id == 19) {
CLEAR_PERI_REG_MASK(USB_DEVICE_CONF0_REG, USB_DEVICE_USB_PAD_ENABLE);
}
#endif
// configure the pin for gpio
gpio_pad_select_gpio(self->id);
@ -494,6 +531,31 @@ STATIC const machine_pin_irq_obj_t machine_pin_irq_object[] = {
{{&machine_pin_irq_type}, GPIO_NUM_38},
{{&machine_pin_irq_type}, GPIO_NUM_39},
#elif CONFIG_IDF_TARGET_ESP32C3
{{&machine_pin_irq_type}, GPIO_NUM_0},
{{&machine_pin_irq_type}, GPIO_NUM_1},
{{&machine_pin_irq_type}, GPIO_NUM_2},
{{&machine_pin_irq_type}, GPIO_NUM_3},
{{&machine_pin_irq_type}, GPIO_NUM_4},
{{&machine_pin_irq_type}, GPIO_NUM_5},
{{&machine_pin_irq_type}, GPIO_NUM_6},
{{&machine_pin_irq_type}, GPIO_NUM_7},
{{&machine_pin_irq_type}, GPIO_NUM_8},
{{&machine_pin_irq_type}, GPIO_NUM_9},
{{&machine_pin_irq_type}, GPIO_NUM_10},
{{&machine_pin_irq_type}, GPIO_NUM_11},
{{&machine_pin_irq_type}, GPIO_NUM_12},
{{&machine_pin_irq_type}, GPIO_NUM_13},
{{&machine_pin_irq_type}, GPIO_NUM_14},
{{&machine_pin_irq_type}, GPIO_NUM_15},
{{&machine_pin_irq_type}, GPIO_NUM_16},
{{&machine_pin_irq_type}, GPIO_NUM_17},
{{&machine_pin_irq_type}, GPIO_NUM_18},
{{&machine_pin_irq_type}, GPIO_NUM_19},
{{&machine_pin_irq_type}, GPIO_NUM_20},
{{&machine_pin_irq_type}, GPIO_NUM_21},
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
{{&machine_pin_irq_type}, GPIO_NUM_0},

View File

@ -70,6 +70,13 @@
#define MP_TASK_PRIORITY (ESP_TASK_PRIO_MIN + 1)
#define MP_TASK_STACK_SIZE (16 * 1024)
// Set the margin for detecting stack overflow, depending on the CPU architecture.
#if CONFIG_IDF_TARGET_ESP32C3
#define MP_TASK_STACK_LIMIT_MARGIN (2048)
#else
#define MP_TASK_STACK_LIMIT_MARGIN (1024)
#endif
int vprintf_null(const char *format, va_list ap) {
// do nothing: this is used as a log target during raw repl mode
return 0;
@ -127,7 +134,7 @@ void mp_task(void *pvParameter) {
soft_reset:
// initialise the stack pointer for the main thread
mp_stack_set_top((void *)sp);
mp_stack_set_limit(MP_TASK_STACK_SIZE - 1024);
mp_stack_set_limit(MP_TASK_STACK_SIZE - MP_TASK_STACK_LIMIT_MARGIN);
gc_init(mp_task_heap, mp_task_heap + mp_task_heap_size);
mp_init();
mp_obj_list_init(mp_sys_path, 0);

View File

@ -34,6 +34,9 @@ set(MICROPY_SOURCE_LIB
${MICROPY_DIR}/lib/oofatfs/ff.c
${MICROPY_DIR}/lib/oofatfs/ffunicode.c
)
if(IDF_TARGET STREQUAL "esp32c3")
list(APPEND MICROPY_SOURCE_LIB ${MICROPY_DIR}/shared/runtime/gchelper_generic.c)
endif()
set(MICROPY_SOURCE_DRIVERS
${MICROPY_DIR}/drivers/bus/softspi.c
@ -133,6 +136,9 @@ endif()
if(IDF_TARGET STREQUAL "esp32")
list(APPEND IDF_COMPONENTS esp32)
elseif(IDF_TARGET STREQUAL "esp32c3")
list(APPEND IDF_COMPONENTS esp32c3)
list(APPEND IDF_COMPONENTS riscv)
elseif(IDF_TARGET STREQUAL "esp32s2")
list(APPEND IDF_COMPONENTS esp32s2)
list(APPEND IDF_COMPONENTS tinyusb)

View File

@ -30,7 +30,6 @@
#include <time.h>
#include <sys/time.h>
#include "soc/rtc_cntl_reg.h"
#include "soc/sens_reg.h"
#include "driver/gpio.h"
#include "driver/adc.h"
#include "esp_heap_caps.h"
@ -134,6 +133,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp32_wake_on_ext1_obj, 0, esp32_wake_on_ext1)
#if CONFIG_IDF_TARGET_ESP32
#include "soc/sens_reg.h"
STATIC mp_obj_t esp32_raw_temperature(void) {
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 3, SENS_FORCE_XPD_SAR_S);
SET_PERI_REG_BITS(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_CLK_DIV, 10, SENS_TSENS_CLK_DIV_S);

View File

@ -34,7 +34,6 @@
#include "freertos/task.h"
#include "esp_sleep.h"
#include "esp_pm.h"
#include "driver/touch_pad.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/rtc.h"
@ -70,6 +69,10 @@ typedef enum {
STATIC bool is_soft_reset = 0;
#if CONFIG_IDF_TARGET_ESP32C3
int esp_clk_cpu_freq(void);
#endif
STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
if (n_args == 0) {
// get
@ -82,6 +85,8 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
}
#if CONFIG_IDF_TARGET_ESP32
esp_pm_config_esp32_t pm;
#elif CONFIG_IDF_TARGET_ESP32C3
esp_pm_config_esp32c3_t pm;
#elif CONFIG_IDF_TARGET_ESP32S2
esp_pm_config_esp32s2_t pm;
#endif
@ -117,6 +122,8 @@ STATIC mp_obj_t machine_sleep_helper(wake_type_t wake_type, size_t n_args, const
esp_sleep_enable_timer_wakeup(((uint64_t)expiry) * 1000);
}
#if !CONFIG_IDF_TARGET_ESP32C3
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);
}
@ -133,6 +140,8 @@ STATIC mp_obj_t machine_sleep_helper(wake_type_t wake_type, size_t n_args, const
}
}
#endif
switch (wake_type) {
case MACHINE_WAKE_SLEEP:
esp_light_sleep_start();

View File

@ -11,13 +11,18 @@
// object representation and NLR handling
#define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_A)
#define MICROPY_NLR_SETJMP (1)
#if CONFIG_IDF_TARGET_ESP32C3
#define MICROPY_GCREGS_SETJMP (1)
#endif
// memory allocation policies
#define MICROPY_ALLOC_PATH_MAX (128)
// emitters
#define MICROPY_PERSISTENT_CODE_LOAD (1)
#if !CONFIG_IDF_TARGET_ESP32C3
#define MICROPY_EMIT_XTENSAWIN (1)
#endif
// compiler configuration
#define MICROPY_COMP_MODULE_CONST (1)

View File

@ -35,6 +35,8 @@
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/uart.h"
#elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/uart.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/uart.h"
#elif CONFIG_IDF_TARGET_ESP32S3

View File

@ -51,7 +51,11 @@ void check_esp_err(esp_err_t code);
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
__asm__ __volatile__ ("csrr %0, 0x7E2" : "=r" (ccount)); // Machine Performance Counter Value
#else
__asm__ __volatile__ ("rsr %0,ccount" : "=a" (ccount));
#endif
return ccount;
}

View File

@ -51,7 +51,7 @@ STATIC void IRAM_ATTR uart_irq_handler(void *arg) {
while (uart->status.rxfifo_cnt) {
#if CONFIG_IDF_TARGET_ESP32
uint8_t c = uart->fifo.rw_byte;
#elif CONFIG_IDF_TARGET_ESP32S2
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2
uint8_t c = READ_PERI_REG(UART_FIFO_AHB_REG(0)); // UART0
#endif
if (c == mp_interrupt_char) {