From 0713e93b8fb555a4c3346268caaef2c73a3a57f1 Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Thu, 14 Jan 2021 10:44:59 +0800 Subject: [PATCH] TWAI: bringup for S3 and C3 --- components/driver/CMakeLists.txt | 4 +- components/esp32c3/ld/esp32c3.peripherals.ld | 1 + components/esp32s3/ld/esp32s3.peripherals.ld | 1 + components/hal/CMakeLists.txt | 10 +- components/hal/esp32c3/include/hal/twai_ll.h | 127 ++++------- components/hal/esp32s3/include/hal/twai_ll.h | 88 +++----- components/soc/esp32c3/include/soc/soc_caps.h | 9 +- .../soc/esp32c3/include/soc/twai_struct.h | 208 ++++++++++++++++++ .../soc/esp32s2/include/soc/twai_struct.h | 2 +- .../soc/esp32s3/include/soc/twai_struct.h | 4 +- .../twai/twai_alert_and_recovery/README.md | 4 +- .../main/Kconfig.projbuild | 6 +- .../peripherals/twai/twai_network/README.md | 38 ++-- .../main/Kconfig.projbuild | 6 +- .../main/Kconfig.projbuild | 6 +- .../twai_network_slave/main/Kconfig.projbuild | 6 +- .../peripherals/twai/twai_self_test/README.md | 6 +- .../twai_self_test/main/Kconfig.projbuild | 6 +- 18 files changed, 341 insertions(+), 191 deletions(-) create mode 100644 components/soc/esp32c3/include/soc/twai_struct.h diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index d81b1e2f90..b833b50a6e 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -19,6 +19,7 @@ set(srcs "spi_slave.c" "spi_bus_lock.c" "timer.c" + "twai.c" "uart.c") set(includes "include" "${target}/include") @@ -32,7 +33,6 @@ if(${target} STREQUAL "esp32") "sdmmc_host.c" "sdmmc_transaction.c" "touch_sensor_common.c" - "twai.c" "esp32/touch_sensor.c" "esp32/adc.c" "esp32/dac.c") @@ -45,7 +45,6 @@ if(IDF_TARGET STREQUAL "esp32s2") "dedic_gpio.c" "spi_slave_hd.c" "touch_sensor_common.c" - "twai.c" "esp32s2/rtc_tempsensor.c" "esp32s2/touch_sensor.c" "esp32s2/adc.c" @@ -61,7 +60,6 @@ if(${target} STREQUAL "esp32s3") "gdma.c" "spi_slave_hd.c" "touch_sensor_common.c" - "twai.c" ) endif() diff --git a/components/esp32c3/ld/esp32c3.peripherals.ld b/components/esp32c3/ld/esp32c3.peripherals.ld index 728d1b7199..4b6eaa39cc 100644 --- a/components/esp32c3/ld/esp32c3.peripherals.ld +++ b/components/esp32c3/ld/esp32c3.peripherals.ld @@ -24,6 +24,7 @@ PROVIDE ( TIMERG1 = 0x60020000 ); PROVIDE ( GPSPI2 = 0x60024000 ); PROVIDE ( GPSPI3 = 0x60025000 ); PROVIDE ( SYSCON = 0x60026000 ); +PROVIDE ( TWAI = 0x6002B000 ); PROVIDE ( GPSPI4 = 0x60037000 ); PROVIDE ( APB_SARADC = 0x60040000 ); PROVIDE ( GDMA = 0x6003F000 ); diff --git a/components/esp32s3/ld/esp32s3.peripherals.ld b/components/esp32s3/ld/esp32s3.peripherals.ld index 8f31656ca4..71eaf1a23e 100644 --- a/components/esp32s3/ld/esp32s3.peripherals.ld +++ b/components/esp32s3/ld/esp32s3.peripherals.ld @@ -26,6 +26,7 @@ PROVIDE ( GPSPI2 = 0x60024000 ); PROVIDE ( GPSPI3 = 0x60025000 ); PROVIDE ( SYSCON = 0x60026000 ); PROVIDE ( I2C1 = 0x60027000 ); +PROVIDE ( TWAI = 0x6002B000 ); PROVIDE ( GPSPI4 = 0x60037000 ); PROVIDE ( GDMA = 0x6003F000 ); PROVIDE ( UART2 = 0x60010000 ); diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index f80329dd5c..90cd9bda25 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -28,7 +28,9 @@ if(NOT BOOTLOADER_BUILD) "soc_hal.c" "interrupt_controller_hal.c" "sha_hal.c" - "aes_hal.c") + "aes_hal.c" + "twai_hal.c" + "twai_hal_iram.c") if(${target} STREQUAL "esp32") list(APPEND srcs @@ -38,8 +40,6 @@ if(NOT BOOTLOADER_BUILD) "pcnt_hal.c" "sdio_slave_hal.c" "touch_sensor_hal.c" - "twai_hal.c" - "twai_hal_iram.c" "esp32/adc_hal.c" "esp32/brownout_hal.c" "esp32/interrupt_descriptor_table.c" @@ -57,8 +57,6 @@ if(NOT BOOTLOADER_BUILD) "spi_flash_hal_gpspi.c" "spi_slave_hd_hal.c" "touch_sensor_hal.c" - "twai_hal.c" - "twai_hal_iram.c" "esp32s2/adc_hal.c" "esp32s2/brownout_hal.c" "esp32s2/cp_dma_hal.c" @@ -78,8 +76,6 @@ if(NOT BOOTLOADER_BUILD) "spi_flash_hal_gpspi.c" "spi_slave_hd_hal.c" "touch_sensor_hal.c" - "twai_hal.c" - "twai_hal_iram.c" "esp32s3/brownout_hal.c" "esp32s3/interrupt_descriptor_table.c" "esp32s3/systimer_hal.c" diff --git a/components/hal/esp32c3/include/hal/twai_ll.h b/components/hal/esp32c3/include/hal/twai_ll.h index fc22ddf55a..522a397b68 100644 --- a/components/hal/esp32c3/include/hal/twai_ll.h +++ b/components/hal/esp32c3/include/hal/twai_ll.h @@ -1,4 +1,4 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ /******************************************************************************* * NOTICE * The ll is not public api, don't use in application code. - * See readme.md in soc/include/hal/readme.md + * See readme.md in hal/include/hal/readme.md ******************************************************************************/ // The Lowlevel layer for TWAI @@ -33,22 +33,22 @@ extern "C" { /* ------------------------- Defines and Typedefs --------------------------- */ -#define TWAI_LL_STATUS_RBS (0x1 << 0) -#define TWAI_LL_STATUS_DOS (0x1 << 1) -#define TWAI_LL_STATUS_TBS (0x1 << 2) -#define TWAI_LL_STATUS_TCS (0x1 << 3) -#define TWAI_LL_STATUS_RS (0x1 << 4) -#define TWAI_LL_STATUS_TS (0x1 << 5) -#define TWAI_LL_STATUS_ES (0x1 << 6) -#define TWAI_LL_STATUS_BS (0x1 << 7) +#define TWAI_LL_STATUS_RBS (0x1 << 0) //Receive Buffer Status +#define TWAI_LL_STATUS_DOS (0x1 << 1) //Data Overrun Status +#define TWAI_LL_STATUS_TBS (0x1 << 2) //Transmit Buffer Status +#define TWAI_LL_STATUS_TCS (0x1 << 3) //Transmission Complete Status +#define TWAI_LL_STATUS_RS (0x1 << 4) //Receive Status +#define TWAI_LL_STATUS_TS (0x1 << 5) //Transmit Status +#define TWAI_LL_STATUS_ES (0x1 << 6) //Error Status +#define TWAI_LL_STATUS_BS (0x1 << 7) //Bus Status -#define TWAI_LL_INTR_RI (0x1 << 0) -#define TWAI_LL_INTR_TI (0x1 << 1) -#define TWAI_LL_INTR_EI (0x1 << 2) +#define TWAI_LL_INTR_RI (0x1 << 0) //Receive Interrupt +#define TWAI_LL_INTR_TI (0x1 << 1) //Transmit Interrupt +#define TWAI_LL_INTR_EI (0x1 << 2) //Error Interrupt //Data overrun interrupt not supported in SW due to HW peculiarities -#define TWAI_LL_INTR_EPI (0x1 << 5) -#define TWAI_LL_INTR_ALI (0x1 << 6) -#define TWAI_LL_INTR_BEI (0x1 << 7) +#define TWAI_LL_INTR_EPI (0x1 << 5) //Error Passive Interrupt +#define TWAI_LL_INTR_ALI (0x1 << 6) //Arbitration Lost Interrupt +#define TWAI_LL_INTR_BEI (0x1 << 7) //Bus Error Interrupt /* * The following frame structure has an NEARLY identical bit field layout to @@ -82,6 +82,8 @@ typedef union { uint8_t bytes[13]; } __attribute__((packed)) twai_ll_frame_buffer_t; +_Static_assert(sizeof(twai_ll_frame_buffer_t) == 13, "TX/RX buffer type should be 13 bytes"); + /* ---------------------------- Mode Register ------------------------------- */ /** @@ -92,14 +94,12 @@ typedef union { * in order to write the majority of configuration registers. * * @param hw Start address of the TWAI registers - * @return true if reset mode was entered successfully * * @note Reset mode is automatically entered on BUS OFF condition */ -static inline bool twai_ll_enter_reset_mode(twai_dev_t *hw) +static inline void twai_ll_enter_reset_mode(twai_dev_t *hw) { hw->mode_reg.rm = 1; - return hw->mode_reg.rm; } /** @@ -110,14 +110,12 @@ static inline bool twai_ll_enter_reset_mode(twai_dev_t *hw) * operating mode. * * @param hw Start address of the TWAI registers - * @return true if reset mode was exit successfully * * @note Reset mode must be exit to initiate BUS OFF recovery */ -static inline bool twai_ll_exit_reset_mode(twai_dev_t *hw) +static inline void twai_ll_exit_reset_mode(twai_dev_t *hw) { hw->mode_reg.rm = 0; - return !(hw->mode_reg.rm); } /** @@ -186,7 +184,7 @@ static inline void twai_ll_set_cmd_tx(twai_dev_t *hw) */ static inline void twai_ll_set_cmd_tx_single_shot(twai_dev_t *hw) { - hw->command_reg.val = 0x03; //Writing to TR and AT simultaneously + hw->command_reg.val = 0x03; //Set command_reg.tr and command_reg.at simultaneously for single shot transmittion request } /** @@ -266,7 +264,7 @@ static inline void twai_ll_set_cmd_self_rx_request(twai_dev_t *hw) */ static inline void twai_ll_set_cmd_self_rx_single_shot(twai_dev_t *hw) { - hw->command_reg.val = 0x12; + hw->command_reg.val = 0x12; //Set command_reg.srr and command_reg.at simultaneously for single shot self reception request } /* --------------------------- Status Register ------------------------------ */ @@ -304,8 +302,6 @@ static inline bool twai_ll_is_last_tx_successful(twai_dev_t *hw) return hw->status_reg.tcs; } -//Todo: Add stand alone status bit check functions when necessary - /* -------------------------- Interrupt Register ---------------------------- */ /** @@ -334,12 +330,7 @@ static inline uint32_t twai_ll_get_and_clear_intrs(twai_dev_t *hw) */ static inline void twai_ll_set_enabled_intrs(twai_dev_t *hw, uint32_t intr_mask) { -#ifdef TWAI_BRP_DIV_SUPPORTED - //ESP32 Rev 2 has brp div. Need to mask when setting - hw->interrupt_enable_reg.val = (hw->interrupt_enable_reg.val & 0x10) | intr_mask; -#else hw->interrupt_enable_reg.val = intr_mask; -#endif } /* ------------------------ Bus Timing Registers --------------------------- */ @@ -355,18 +346,10 @@ static inline void twai_ll_set_enabled_intrs(twai_dev_t *hw, uint32_t intr_mask) * @param triple_sampling Triple Sampling enable/disable * * @note Must be called in reset mode - * @note ESP32 rev 2 or later can support a x2 brp by setting a brp_div bit, - * allowing the brp to go from a maximum of 128 to 256. + * @note ESP32C3 brp can be any even number between 2 to 32768 */ static inline void twai_ll_set_bus_timing(twai_dev_t *hw, uint32_t brp, uint32_t sjw, uint32_t tseg1, uint32_t tseg2, bool triple_sampling) { -#ifdef TWAI_BRP_DIV_SUPPORTED - if (brp > TWAI_BRP_DIV_THRESH) { - //Need to set brp_div bit - hw->interrupt_enable_reg.brp_div = 1; - brp /= 2; - } -#endif hw->bus_timing_0_reg.brp = (brp / 2) - 1; hw->bus_timing_0_reg.sjw = sjw - 1; hw->bus_timing_1_reg.tseg1 = tseg1 - 1; @@ -386,7 +369,6 @@ static inline void twai_ll_set_bus_timing(twai_dev_t *hw, uint32_t brp, uint32_t static inline void twai_ll_clear_arb_lost_cap(twai_dev_t *hw) { (void)hw->arbitration_lost_captue_reg.val; - //Todo: Decode ALC register } /* ----------------------------- ECC Register ------------------------------- */ @@ -401,7 +383,6 @@ static inline void twai_ll_clear_arb_lost_cap(twai_dev_t *hw) static inline void twai_ll_clear_err_code_cap(twai_dev_t *hw) { (void)hw->error_code_capture_reg.val; - //Todo: Decode error code capture } /* ----------------------------- EWL Register ------------------------------- */ @@ -546,7 +527,11 @@ static inline void twai_ll_get_rx_buffer(twai_dev_t *hw, twai_ll_frame_buffer_t /** * @brief Format contents of a TWAI frame into layout of TX Buffer * - * @param[in] id 11 or 29bit ID + * This function encodes a message into a frame structure. The frame structure + * has an identical layout to the TX buffer, allowing the frame structure to be + * directly copied into TX buffer. + * + * @param[in] 11bit or 29bit ID * @param[in] dlc Data length code * @param[in] data Pointer to an 8 byte array containing data. NULL if no data * @param[in] format Type of TWAI frame @@ -557,9 +542,6 @@ static inline void twai_ll_get_rx_buffer(twai_dev_t *hw, twai_ll_frame_buffer_t static inline void twai_ll_format_frame_buffer(uint32_t id, uint8_t dlc, const uint8_t *data, uint32_t flags, twai_ll_frame_buffer_t *tx_frame) { - /* This function encodes a message into a frame structure. The frame structure has - an identical layout to the TX buffer, allowing the frame structure to be directly - copied into TX buffer. */ bool is_extd = flags & TWAI_MSG_FLAG_EXTD; bool is_rtr = flags & TWAI_MSG_FLAG_RTR; @@ -570,7 +552,7 @@ static inline void twai_ll_format_frame_buffer(uint32_t id, uint8_t dlc, const u tx_frame->self_reception = (flags & TWAI_MSG_FLAG_SELF) ? 1 : 0; tx_frame->single_shot = (flags & TWAI_MSG_FLAG_SS) ? 1 : 0; - //Set ID + //Set ID. The ID registers are big endian and left aligned, therefore a bswap will be required if (is_extd) { uint32_t id_temp = __builtin_bswap32((id & TWAI_EXTD_ID_MASK) << 3); //((id << 3) >> 8*(3-i)) for (int i = 0; i < 4; i++) { @@ -583,9 +565,8 @@ static inline void twai_ll_format_frame_buffer(uint32_t id, uint8_t dlc, const u } } - //Set Data uint8_t *data_buffer = (is_extd) ? tx_frame->extended.data : tx_frame->standard.data; - if (!is_rtr) { + if (!is_rtr) { //Only copy data if the frame is a data frame (i.e not a remote frame) for (int i = 0; (i < dlc) && (i < TWAI_FRAME_MAX_DLC); i++) { data_buffer[i] = data[i]; } @@ -593,7 +574,7 @@ static inline void twai_ll_format_frame_buffer(uint32_t id, uint8_t dlc, const u } /** - * @brief Parse formatted TWAI frame (RX Buffer Layout) into its contents + * @brief Parse formatted TWAI frame (RX Buffer Layout) into its constituent contents * * @param[in] rx_frame Pointer to formatted frame * @param[out] id 11 or 29bit ID @@ -604,8 +585,6 @@ static inline void twai_ll_format_frame_buffer(uint32_t id, uint8_t dlc, const u static inline void twai_ll_prase_frame_buffer(twai_ll_frame_buffer_t *rx_frame, uint32_t *id, uint8_t *dlc, uint8_t *data, uint32_t *flags) { - //This function decodes a frame structure into it's constituent components. - //Copy frame information *dlc = rx_frame->dlc; uint32_t flags_temp = 0; @@ -614,7 +593,7 @@ static inline void twai_ll_prase_frame_buffer(twai_ll_frame_buffer_t *rx_frame, flags_temp |= (rx_frame->dlc > TWAI_FRAME_MAX_DLC) ? TWAI_MSG_FLAG_DLC_NON_COMP : 0; *flags = flags_temp; - //Copy ID + //Copy ID. The ID registers are big endian and left aligned, therefore a bswap will be required if (rx_frame->frame_format) { uint32_t id_temp = 0; for (int i = 0; i < 4; i++) { @@ -631,8 +610,8 @@ static inline void twai_ll_prase_frame_buffer(twai_ll_frame_buffer_t *rx_frame, *id = id_temp & TWAI_STD_ID_MASK; } - //Copy data uint8_t *data_buffer = (rx_frame->frame_format) ? rx_frame->extended.data : rx_frame->standard.data; + //Only copy data if the frame is a data frame (i.e. not a remote frame) int data_length = (rx_frame->rtr) ? 0 : ((rx_frame->dlc > TWAI_FRAME_MAX_DLC) ? TWAI_FRAME_MAX_DLC : rx_frame->dlc); for (int i = 0; i < data_length; i++) { data[i] = data_buffer[i]; @@ -661,43 +640,27 @@ static inline uint32_t twai_ll_get_rx_msg_count(twai_dev_t *hw) /** * @brief Set CLKOUT Divider and enable/disable * + * Configure CLKOUT. CLKOUT is a pre-scaled version of APB CLK. Divider can be + * 1, or any even number from 2 to 490. Set the divider to 0 to disable CLKOUT. + * * @param hw Start address of the TWAI registers - * @param divider Divider for CLKOUT. Set to 0 to disable CLKOUT + * @param divider Divider for CLKOUT (any even number from 2 to 490). Set to 0 to disable CLKOUT */ static inline void twai_ll_set_clkout(twai_dev_t *hw, uint32_t divider) { - /* Configure CLKOUT. CLKOUT is a pre-scaled version of APB CLK. Divider can be - 1, or any even number from 2 to 14. Set to out of range value (0) to disable - CLKOUT. */ - - if (divider >= 2 && divider <= 14) { - TWAI.clock_divider_reg.co = 0; - TWAI.clock_divider_reg.cd = (divider / 2) - 1; + if (divider >= 2 && divider <= 490) { + hw->clock_divider_reg.co = 0; + hw->clock_divider_reg.cd = (divider / 2) - 1; } else if (divider == 1) { - TWAI.clock_divider_reg.co = 0; - TWAI.clock_divider_reg.cd = 7; + //Setting the divider reg to max value (255) means a divider of 1 + hw->clock_divider_reg.co = 0; + hw->clock_divider_reg.cd = 255; } else { - TWAI.clock_divider_reg.co = 1; - TWAI.clock_divider_reg.cd = 0; + hw->clock_divider_reg.co = 1; + hw->clock_divider_reg.cd = 0; } } -/** - * @brief Set register address mapping to extended mode - * - * Extended mode register address mapping consists of more registers and extra - * features. - * - * @param hw Start address of the TWAI registers - * - * @note Must be called before setting any configuration - * @note Must be called in reset mode - */ -static inline void twai_ll_enable_extended_reg_layout(twai_dev_t *hw) -{ - hw->clock_divider_reg.cm = 1; -} - #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s3/include/hal/twai_ll.h b/components/hal/esp32s3/include/hal/twai_ll.h index a124341526..843d0e85ae 100644 --- a/components/hal/esp32s3/include/hal/twai_ll.h +++ b/components/hal/esp32s3/include/hal/twai_ll.h @@ -30,26 +30,25 @@ extern "C" { #include #include "hal/twai_types.h" #include "soc/twai_periph.h" -#include "soc/soc_caps.h" /* ------------------------- Defines and Typedefs --------------------------- */ -#define TWAI_LL_STATUS_RBS (0x1 << 0) -#define TWAI_LL_STATUS_DOS (0x1 << 1) -#define TWAI_LL_STATUS_TBS (0x1 << 2) -#define TWAI_LL_STATUS_TCS (0x1 << 3) -#define TWAI_LL_STATUS_RS (0x1 << 4) -#define TWAI_LL_STATUS_TS (0x1 << 5) -#define TWAI_LL_STATUS_ES (0x1 << 6) -#define TWAI_LL_STATUS_BS (0x1 << 7) +#define TWAI_LL_STATUS_RBS (0x1 << 0) //Receive Buffer Status +#define TWAI_LL_STATUS_DOS (0x1 << 1) //Data Overrun Status +#define TWAI_LL_STATUS_TBS (0x1 << 2) //Transmit Buffer Status +#define TWAI_LL_STATUS_TCS (0x1 << 3) //Transmission Complete Status +#define TWAI_LL_STATUS_RS (0x1 << 4) //Receive Status +#define TWAI_LL_STATUS_TS (0x1 << 5) //Transmit Status +#define TWAI_LL_STATUS_ES (0x1 << 6) //Error Status +#define TWAI_LL_STATUS_BS (0x1 << 7) //Bus Status -#define TWAI_LL_INTR_RI (0x1 << 0) -#define TWAI_LL_INTR_TI (0x1 << 1) -#define TWAI_LL_INTR_EI (0x1 << 2) +#define TWAI_LL_INTR_RI (0x1 << 0) //Receive Interrupt +#define TWAI_LL_INTR_TI (0x1 << 1) //Transmit Interrupt +#define TWAI_LL_INTR_EI (0x1 << 2) //Error Interrupt //Data overrun interrupt not supported in SW due to HW peculiarities -#define TWAI_LL_INTR_EPI (0x1 << 5) -#define TWAI_LL_INTR_ALI (0x1 << 6) -#define TWAI_LL_INTR_BEI (0x1 << 7) +#define TWAI_LL_INTR_EPI (0x1 << 5) //Error Passive Interrupt +#define TWAI_LL_INTR_ALI (0x1 << 6) //Arbitration Lost Interrupt +#define TWAI_LL_INTR_BEI (0x1 << 7) //Bus Error Interrupt /* * The following frame structure has an NEARLY identical bit field layout to @@ -95,14 +94,12 @@ _Static_assert(sizeof(twai_ll_frame_buffer_t) == 13, "TX/RX buffer type should b * in order to write the majority of configuration registers. * * @param hw Start address of the TWAI registers - * @return true if reset mode was entered successfully * * @note Reset mode is automatically entered on BUS OFF condition */ -static inline bool twai_ll_enter_reset_mode(twai_dev_t *hw) +static inline void twai_ll_enter_reset_mode(twai_dev_t *hw) { hw->mode_reg.rm = 1; - return hw->mode_reg.rm; } /** @@ -113,14 +110,12 @@ static inline bool twai_ll_enter_reset_mode(twai_dev_t *hw) * operating mode. * * @param hw Start address of the TWAI registers - * @return true if reset mode was exit successfully * * @note Reset mode must be exit to initiate BUS OFF recovery */ -static inline bool twai_ll_exit_reset_mode(twai_dev_t *hw) +static inline void twai_ll_exit_reset_mode(twai_dev_t *hw) { hw->mode_reg.rm = 0; - return !(hw->mode_reg.rm); } /** @@ -189,7 +184,7 @@ static inline void twai_ll_set_cmd_tx(twai_dev_t *hw) */ static inline void twai_ll_set_cmd_tx_single_shot(twai_dev_t *hw) { - hw->command_reg.val = 0x03; //Writing to TR and AT simultaneously + hw->command_reg.val = 0x03; //Set command_reg.tr and command_reg.at simultaneously for single shot transmittion request } /** @@ -269,7 +264,7 @@ static inline void twai_ll_set_cmd_self_rx_request(twai_dev_t *hw) */ static inline void twai_ll_set_cmd_self_rx_single_shot(twai_dev_t *hw) { - hw->command_reg.val = 0x12; + hw->command_reg.val = 0x12; //Set command_reg.srr and command_reg.at simultaneously for single shot self reception request } /* --------------------------- Status Register ------------------------------ */ @@ -307,8 +302,6 @@ static inline bool twai_ll_is_last_tx_successful(twai_dev_t *hw) return hw->status_reg.tcs; } -//Todo: Add stand alone status bit check functions when necessary - /* -------------------------- Interrupt Register ---------------------------- */ /** @@ -337,12 +330,7 @@ static inline uint32_t twai_ll_get_and_clear_intrs(twai_dev_t *hw) */ static inline void twai_ll_set_enabled_intrs(twai_dev_t *hw, uint32_t intr_mask) { -#ifdef TWAI_BRP_DIV_SUPPORTED - //ESP32 Rev 2 has brp div. Need to mask when setting - hw->interrupt_enable_reg.val = (hw->interrupt_enable_reg.val & 0x10) | intr_mask; -#else hw->interrupt_enable_reg.val = intr_mask; -#endif } /* ------------------------ Bus Timing Registers --------------------------- */ @@ -358,18 +346,10 @@ static inline void twai_ll_set_enabled_intrs(twai_dev_t *hw, uint32_t intr_mask) * @param triple_sampling Triple Sampling enable/disable * * @note Must be called in reset mode - * @note ESP32 rev 2 or later can support a x2 brp by setting a brp_div bit, - * allowing the brp to go from a maximum of 128 to 256. + * @note ESP32S3 brp can be any even number between 2 to 32768 */ static inline void twai_ll_set_bus_timing(twai_dev_t *hw, uint32_t brp, uint32_t sjw, uint32_t tseg1, uint32_t tseg2, bool triple_sampling) { -#ifdef TWAI_BRP_DIV_SUPPORTED - if (brp > SOC_TWAI_BRP_DIV_THRESH) { - //Need to set brp_div bit - hw->interrupt_enable_reg.brp_div = 1; - brp /= 2; - } -#endif hw->bus_timing_0_reg.brp = (brp / 2) - 1; hw->bus_timing_0_reg.sjw = sjw - 1; hw->bus_timing_1_reg.tseg1 = tseg1 - 1; @@ -389,7 +369,6 @@ static inline void twai_ll_set_bus_timing(twai_dev_t *hw, uint32_t brp, uint32_t static inline void twai_ll_clear_arb_lost_cap(twai_dev_t *hw) { (void)hw->arbitration_lost_captue_reg.val; - //Todo: Decode ALC register } /* ----------------------------- ECC Register ------------------------------- */ @@ -404,7 +383,6 @@ static inline void twai_ll_clear_arb_lost_cap(twai_dev_t *hw) static inline void twai_ll_clear_err_code_cap(twai_dev_t *hw) { (void)hw->error_code_capture_reg.val; - //Todo: Decode error code capture } /* ----------------------------- EWL Register ------------------------------- */ @@ -588,7 +566,7 @@ static inline void twai_ll_format_frame_buffer(uint32_t id, uint8_t dlc, const u } uint8_t *data_buffer = (is_extd) ? tx_frame->extended.data : tx_frame->standard.data; - if (!is_rtr) { //Only copy data if the frame is a data frame (i.e not RTR) + if (!is_rtr) { //Only copy data if the frame is a data frame (i.e not a remote frame) for (int i = 0; (i < dlc) && (i < TWAI_FRAME_MAX_DLC); i++) { data_buffer[i] = data[i]; } @@ -663,42 +641,26 @@ static inline uint32_t twai_ll_get_rx_msg_count(twai_dev_t *hw) * @brief Set CLKOUT Divider and enable/disable * * Configure CLKOUT. CLKOUT is a pre-scaled version of APB CLK. Divider can be - * 1, or any even number from 2 to 14. Set the divider to 0 to disable CLKOUT. + * 1, or any even number from 2 to 490. Set the divider to 0 to disable CLKOUT. * * @param hw Start address of the TWAI registers - * @param divider Divider for CLKOUT. Set to 0 to disable CLKOUT + * @param divider Divider for CLKOUT (any even number from 2 to 490). Set to 0 to disable CLKOUT */ static inline void twai_ll_set_clkout(twai_dev_t *hw, uint32_t divider) { - if (divider >= 2 && divider <= 14) { + if (divider >= 2 && divider <= 490) { hw->clock_divider_reg.co = 0; hw->clock_divider_reg.cd = (divider / 2) - 1; } else if (divider == 1) { - //Setting the divider reg to max value (7) means a divider of 1 + //Setting the divider reg to max value (255) means a divider of 1 hw->clock_divider_reg.co = 0; - hw->clock_divider_reg.cd = 7; + hw->clock_divider_reg.cd = 255; } else { hw->clock_divider_reg.co = 1; hw->clock_divider_reg.cd = 0; } } -/** - * @brief Set register address mapping to extended mode - * - * Extended mode register address mapping consists of more registers and extra - * features. - * - * @param hw Start address of the TWAI registers - * - * @note Must be called before setting any configuration - * @note Must be called in reset mode - */ -static inline void twai_ll_enable_extended_reg_layout(twai_dev_t *hw) -{ - hw->clock_divider_reg.cd = 1; -} - #ifdef __cplusplus } #endif diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 29b8d53f57..8d3295bf46 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -5,8 +5,10 @@ #pragma once -#define SOC_CPU_CORES_NUM 1 -#define SOC_GDMA_SUPPORTED 1 +#define SOC_CPU_CORES_NUM 1 +#define SOC_GDMA_SUPPORTED 1 +#define SOC_TWAI_SUPPORTED 1 + // There are 3 DMA channels on ESP32-C3 // Attention: These fixed DMA channels are temporarily workaround before we have a centralized DMA controller API to help alloc the channel dynamically @@ -46,6 +48,9 @@ /*-------------------------- TOUCH SENSOR CAPS -------------------------------*/ #define SOC_TOUCH_SENSOR_NUM (0) /*! No touch sensors on ESP32-C3 */ +/*-------------------------- TWAI CAPS ---------------------------------------*/ +#define SOC_TWAI_BRP_MIN 2 +#define SOC_TWAI_BRP_MAX 32768 #define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) ((PERIPH_NUM==0)? 5 : 1) #define SOC_ADC_MAX_CHANNEL_NUM (10) diff --git a/components/soc/esp32c3/include/soc/twai_struct.h b/components/soc/esp32c3/include/soc/twai_struct.h new file mode 100644 index 0000000000..30d419376c --- /dev/null +++ b/components/soc/esp32c3/include/soc/twai_struct.h @@ -0,0 +1,208 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* ---------------------------- Register Layout ------------------------------ */ + +/* The TWAI peripheral's registers are 8bits, however the ESP32-C3 can only access + * peripheral registers every 32bits. Therefore each TWAI register is mapped to + * the least significant byte of every 32bits. + */ + +typedef volatile struct twai_dev_s { + //Configuration and Control Registers + union { + struct { + uint32_t rm: 1; /* MOD.0 Reset Mode */ + uint32_t lom: 1; /* MOD.1 Listen Only Mode */ + uint32_t stm: 1; /* MOD.2 Self Test Mode */ + uint32_t afm: 1; /* MOD.3 Acceptance Filter Mode */ + uint32_t reserved28: 28; /* Internal Reserved. MOD.4 Sleep Mode not supported */ + }; + uint32_t val; + } mode_reg; /* Address 0 */ + union { + struct { + uint32_t tr: 1; /* CMR.0 Transmission Request */ + uint32_t at: 1; /* CMR.1 Abort Transmission */ + uint32_t rrb: 1; /* CMR.2 Release Receive Buffer */ + uint32_t cdo: 1; /* CMR.3 Clear Data Overrun */ + uint32_t srr: 1; /* CMR.4 Self Reception Request */ + uint32_t reserved27: 27; /* Internal Reserved */ + }; + uint32_t val; + } command_reg; /* Address 1 */ + union { + struct { + uint32_t rbs: 1; /* SR.0 Receive Buffer Status */ + uint32_t dos: 1; /* SR.1 Data Overrun Status */ + uint32_t tbs: 1; /* SR.2 Transmit Buffer Status */ + uint32_t tcs: 1; /* SR.3 Transmission Complete Status */ + uint32_t rs: 1; /* SR.4 Receive Status */ + uint32_t ts: 1; /* SR.5 Transmit Status */ + uint32_t es: 1; /* SR.6 Error Status */ + uint32_t bs: 1; /* SR.7 Bus Status */ + uint32_t ms: 1; /* SR.8 Miss Status */ + uint32_t reserved23: 23; /* Internal Reserved */ + }; + uint32_t val; + } status_reg; /* Address 2 */ + union { + struct { + uint32_t ri: 1; /* IR.0 Receive Interrupt */ + uint32_t ti: 1; /* IR.1 Transmit Interrupt */ + uint32_t ei: 1; /* IR.2 Error Interrupt */ + uint32_t reserved2: 2; /* Internal Reserved (Data Overrun interrupt and Wake-up not supported) */ + uint32_t epi: 1; /* IR.5 Error Passive Interrupt */ + uint32_t ali: 1; /* IR.6 Arbitration Lost Interrupt */ + uint32_t bei: 1; /* IR.7 Bus Error Interrupt */ + uint32_t reserved24: 24; /* Internal Reserved */ + }; + uint32_t val; + } interrupt_reg; /* Address 3 */ + union { + struct { + uint32_t rie: 1; /* IER.0 Receive Interrupt Enable */ + uint32_t tie: 1; /* IER.1 Transmit Interrupt Enable */ + uint32_t eie: 1; /* IER.2 Error Interrupt Enable */ + uint32_t reserved2: 2; /* Internal Reserved (Data Overrun interrupt and Wake-up not supported) */ + uint32_t epie: 1; /* IER.5 Error Passive Interrupt Enable */ + uint32_t alie: 1; /* IER.6 Arbitration Lost Interrupt Enable */ + uint32_t beie: 1; /* IER.7 Bus Error Interrupt Enable */ + uint32_t reserved24: 24; /* Internal Reserved */ + }; + uint32_t val; + } interrupt_enable_reg; /* Address 4 */ + uint32_t reserved_05; /* Address 5 */ + union { + struct { + uint32_t brp: 14; /* BTR0[13:0] Baud Rate Prescaler */ + uint32_t sjw: 2; /* BTR0[15:14] Synchronization Jump Width*/ + uint32_t reserved16: 16; /* Internal Reserved */ + }; + uint32_t val; + } bus_timing_0_reg; /* Address 6 */ + union { + struct { + uint32_t tseg1: 4; /* BTR1[3:0] Timing Segment 1 */ + uint32_t tseg2: 3; /* BTR1[6:4] Timing Segment 2 */ + uint32_t sam: 1; /* BTR1.7 Sampling*/ + uint32_t reserved24: 24; /* Internal Reserved */ + }; + uint32_t val; + } bus_timing_1_reg; /* Address 7 */ + uint32_t reserved_08; /* Address 8 (Output control not supported) */ + uint32_t reserved_09; /* Address 9 (Test Register not supported) */ + uint32_t reserved_10; /* Address 10 */ + + //Capture and Counter Registers + union { + struct { + uint32_t alc: 5; /* ALC[4:0] Arbitration lost capture */ + uint32_t reserved27: 27; /* Internal Reserved */ + }; + uint32_t val; + } arbitration_lost_captue_reg; /* Address 11 */ + union { + struct { + uint32_t seg: 5; /* ECC[4:0] Error Code Segment 0 to 5 */ + uint32_t dir: 1; /* ECC.5 Error Direction (TX/RX) */ + uint32_t errc: 2; /* ECC[7:6] Error Code */ + uint32_t reserved24: 24; /* Internal Reserved */ + }; + uint32_t val; + } error_code_capture_reg; /* Address 12 */ + union { + struct { + uint32_t ewl: 8; /* EWL[7:0] Error Warning Limit */ + uint32_t reserved24: 24; /* Internal Reserved */ + }; + uint32_t val; + } error_warning_limit_reg; /* EWLR[7:0] Error Warning Limit: Address 13 */ + union { + struct { + uint32_t rxerr: 8; /* RXERR[7:0] Receive Error Counter */ + uint32_t reserved24: 24; /* Internal Reserved */ + }; + uint32_t val; + } rx_error_counter_reg; /* Address 12 */ + union { + struct { + uint32_t txerr: 8; /* TXERR[7:0] Receive Error Counter */ + uint32_t reserved24: 24; /* Internal Reserved */ + }; + uint32_t val; + } tx_error_counter_reg; /* Address 15 */ + + //Shared Registers (TX Buff/RX Buff/Acc Filter) + union { + struct { + union { + struct { + uint32_t byte: 8; /* ACRx[7:0] Acceptance Code */ + uint32_t reserved24: 24; /* Internal Reserved */ + }; + uint32_t val; + } acr[4]; + union { + struct { + uint32_t byte: 8; /* AMRx[7:0] Acceptance Mask */ + uint32_t reserved24: 24; /* Internal Reserved */ + }; + uint32_t val; + } amr[4]; + uint32_t reserved32[5]; + } acceptance_filter; + union { + struct { + uint32_t byte: 8; + uint32_t reserved24: 24; + }; + uint32_t val; + } tx_rx_buffer[13]; + }; /* Address 16-28 TX/RX Buffer and Acc Filter*/; + + //Misc Registers + union { + struct { + uint32_t rmc: 7; /* RMC[6:0] RX Message Counter */ + uint32_t reserved25: 25; /* Internal Reserved */ + }; + uint32_t val; + } rx_message_counter_reg; /* Address 29 */ + uint32_t reserved_30; /* Address 30 (RX Buffer Start Address not supported) */ + union { + struct { + uint32_t cd: 8; /* CDR[7:0] CLKOUT frequency selector based of fOSC */ + uint32_t co: 1; /* CDR.8 CLKOUT enable/disable */ + uint32_t reserved24: 23; /* Internal Reserved */ + }; + uint32_t val; + } clock_divider_reg; /* Address 31 */ +} twai_dev_t; + +_Static_assert(sizeof(twai_dev_t) == 128, "TWAI registers should be 32 * 4 bytes"); + +extern twai_dev_t TWAI; + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32s2/include/soc/twai_struct.h b/components/soc/esp32s2/include/soc/twai_struct.h index a9cdcbf039..5cba4d409a 100644 --- a/components/soc/esp32s2/include/soc/twai_struct.h +++ b/components/soc/esp32s2/include/soc/twai_struct.h @@ -22,7 +22,7 @@ extern "C" { /* ---------------------------- Register Layout ------------------------------ */ -/* The TWAI peripheral's registers are 8bits, however the ESP32 can only access +/* The TWAI peripheral's registers are 8bits, however the ESP32-S2 can only access * peripheral registers every 32bits. Therefore each TWAI register is mapped to * the least significant byte of every 32bits. */ diff --git a/components/soc/esp32s3/include/soc/twai_struct.h b/components/soc/esp32s3/include/soc/twai_struct.h index 77debe0c43..58bdc6d1ab 100644 --- a/components/soc/esp32s3/include/soc/twai_struct.h +++ b/components/soc/esp32s3/include/soc/twai_struct.h @@ -22,7 +22,7 @@ extern "C" { /* ---------------------------- Register Layout ------------------------------ */ -/* The TWAI peripheral's registers are 8bits, however the ESP32 can only access +/* The TWAI peripheral's registers are 8bits, however the ESP32-S3 can only access * peripheral registers every 32bits. Therefore each TWAI register is mapped to * the least significant byte of every 32bits. */ @@ -61,7 +61,7 @@ typedef volatile struct twai_dev_s { uint32_t es: 1; /* SR.6 Error Status */ uint32_t bs: 1; /* SR.7 Bus Status */ uint32_t ms: 1; /* SR.8 Miss Status */ - uint32_t reserved24: 23; /* Internal Reserved */ + uint32_t reserved23: 23; /* Internal Reserved */ }; uint32_t val; } status_reg; /* Address 2 */ diff --git a/examples/peripherals/twai/twai_alert_and_recovery/README.md b/examples/peripherals/twai/twai_alert_and_recovery/README.md index 3304c630a5..b6eba62367 100644 --- a/examples/peripherals/twai/twai_alert_and_recovery/README.md +++ b/examples/peripherals/twai/twai_alert_and_recovery/README.md @@ -14,7 +14,7 @@ Note: If you don't have an external transceiver, this example can still be run b ### Configure the project -* Set the target of the build (where `{IDF_TARGET}` stands for the target chip such as `eszp32` or `esp32s2`). +* Set the target of the build (where `{IDF_TARGET}` stands for the target chip such as `esp32`, `esp32s2`, `esp32s2` or `esp32c3`). * Then run `menuconfig` to configure the example. ``` @@ -25,6 +25,8 @@ idf.py menuconfig * Under `Example Configuration`, configure the pin assignments using the options `TX GPIO Number` and `RX GPIO Number` according to how the target was connected to the transceiver. By default, `TX GPIO Number` and `RX GPIO Number` are set to the following values: * On the ESP32, `TX GPIO Number` and `RX GPIO Number` default to `21` and `22` respectively * On the ESP32-S2, `TX GPIO Number` and `RX GPIO Number` default to `20` and `21` respectively + * On the ESP32-S3, `TX GPIO Number` and `RX GPIO Number` default to `20` and `21` respectively + * On the ESP32-C3, `TX GPIO Number` and `RX GPIO Number` default to `2` and `3` respectively ### Build and Flash diff --git a/examples/peripherals/twai/twai_alert_and_recovery/main/Kconfig.projbuild b/examples/peripherals/twai/twai_alert_and_recovery/main/Kconfig.projbuild index 125931f169..ed23df09cd 100644 --- a/examples/peripherals/twai/twai_alert_and_recovery/main/Kconfig.projbuild +++ b/examples/peripherals/twai/twai_alert_and_recovery/main/Kconfig.projbuild @@ -2,7 +2,8 @@ menu "Example Configuration" config EXAMPLE_TX_GPIO_NUM int "TX GPIO number" - default 20 if IDF_TARGET_ESP32S2 + default 2 if IDF_TARGET_ESP32C3 + default 20 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 default 21 if IDF_TARGET_ESP32 help This option selects the GPIO pin used for the TX signal. Connect the @@ -10,7 +11,8 @@ menu "Example Configuration" config EXAMPLE_RX_GPIO_NUM int "RX GPIO number" - default 21 if IDF_TARGET_ESP32S2 + default 3 if IDF_TARGET_ESP32C3 + default 21 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 default 22 if IDF_TARGET_ESP32 help This option selects the GPIO pin used for the RX signal. Connect the diff --git a/examples/peripherals/twai/twai_network/README.md b/examples/peripherals/twai/twai_network/README.md index be74f1c0d0..01c2876661 100644 --- a/examples/peripherals/twai/twai_network/README.md +++ b/examples/peripherals/twai/twai_network/README.md @@ -2,7 +2,7 @@ (See the README.md file in the upper level 'examples' directory for more information about examples.) -This example demonstrates how to use the TWAI driver to program a target (ESP32 or ESP32-S2) as a TWAI node, and have the two nodes (Network Master and Network Slave) communicate on a TWAI network. The Listen Only node is optional and acts as a network monitor meaning that it only receives messages and does not influence the bus in any way (i.e. doesn't not acknowledge or send error frames). +This example demonstrates how to use the TWAI driver to program a target (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) as a TWAI node, and have the two nodes (Network Master and Network Slave) communicate on a TWAI network. The Listen Only node is optional and acts as a network monitor meaning that it only receives messages and does not influence the bus in any way (i.e. doesn't not acknowledge or send error frames). Note that concept of master/slave in this example refers to which node initiates and stops the transfer of a stream of data messages. @@ -16,22 +16,22 @@ This example requires at least two targets (e.g., an ESP32 or ESP32-S2) to act a The following diagram illustrates an example network: ``` - ---------- ---------- -------------- - | Master | | Slave | | Listen Only | - | | | | | | - | TX RX | | TX RX | | TX RX | - ---------- ---------- -------------- - | | | | | | - | | | | | | - ---------- ---------- ---------- - | D R | | D R | | D R | - | | | | | | - | VP230 | | VP230 | | VP230 | - | | | | | | - | H L | | H L | | H L | - ---------- ---------- ---------- - | | | | | | - | | | | | | + ---------- ---------- -------------- + | Master | | Slave | | Listen Only | + | | | | | | + | TX RX | | TX RX | | TX RX | + ---------- ---------- -------------- + | | | | | | + | | | | | | + ---------- ---------- ---------- + | D R | | D R | | D R | + | | | | | | + | VP230 | | VP230 | | VP230 | + | | | | | | + | H L | | H L | | H L | + ---------- ---------- ---------- + | | | | | | + | | | | | | |--x------|-----x------|-----x------|--| H | | | |---------x------------x------------x--| L @@ -55,6 +55,8 @@ idf.py menuconfig * Under `Example Configuration`, configure the pin assignments using the options `TX GPIO Number` and `RX GPIO Number` according to how the target was connected to the transceiver. By default, `TX GPIO Number` and `RX GPIO Number` are set to the following values: * On the ESP32, `TX GPIO Number` and `RX GPIO Number` default to `21` and `22` respectively * On the ESP32-S2, `TX GPIO Number` and `RX GPIO Number` default to `20` and `21` respectively + * On the ESP32-S3, `TX GPIO Number` and `RX GPIO Number` default to `20` and `21` respectively + * On the ESP32-C3, `TX GPIO Number` and `RX GPIO Number` default to `2` and `3` respectively ### Build and Flash @@ -181,4 +183,4 @@ The communication between the Network Master and Network Slave execute the follo 2. The master repeatedly sends **PING** messages until it receives a **PING_RESP** (ping response message) from the slave. The slave will only send a **PING_RESP** message when it receives a **PING** message from the master. 3. Once the master has received the **PING_RESP** from the slave, it will send a **START_CMD** message to the slave. 4. Upon receiving the **START_CMD** message, the slave will start transmitting **DATA** messages until the master sends a **STOP_CMD**. The master will send the **STOP_CMD** after receiving N **DATA** messages from the slave (N = 50 by default). -5. When the slave receives the **STOP_CMD**, it will confirm that it has stopped by sending a **STOP_RESP** message to the master. +5. When the slave receives the **STOP_CMD**, it will confirm that it has stopped by sending a **STOP_RESP** message to the master. diff --git a/examples/peripherals/twai/twai_network/twai_network_listen_only/main/Kconfig.projbuild b/examples/peripherals/twai/twai_network/twai_network_listen_only/main/Kconfig.projbuild index 125931f169..ed23df09cd 100644 --- a/examples/peripherals/twai/twai_network/twai_network_listen_only/main/Kconfig.projbuild +++ b/examples/peripherals/twai/twai_network/twai_network_listen_only/main/Kconfig.projbuild @@ -2,7 +2,8 @@ menu "Example Configuration" config EXAMPLE_TX_GPIO_NUM int "TX GPIO number" - default 20 if IDF_TARGET_ESP32S2 + default 2 if IDF_TARGET_ESP32C3 + default 20 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 default 21 if IDF_TARGET_ESP32 help This option selects the GPIO pin used for the TX signal. Connect the @@ -10,7 +11,8 @@ menu "Example Configuration" config EXAMPLE_RX_GPIO_NUM int "RX GPIO number" - default 21 if IDF_TARGET_ESP32S2 + default 3 if IDF_TARGET_ESP32C3 + default 21 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 default 22 if IDF_TARGET_ESP32 help This option selects the GPIO pin used for the RX signal. Connect the diff --git a/examples/peripherals/twai/twai_network/twai_network_master/main/Kconfig.projbuild b/examples/peripherals/twai/twai_network/twai_network_master/main/Kconfig.projbuild index 125931f169..ed23df09cd 100644 --- a/examples/peripherals/twai/twai_network/twai_network_master/main/Kconfig.projbuild +++ b/examples/peripherals/twai/twai_network/twai_network_master/main/Kconfig.projbuild @@ -2,7 +2,8 @@ menu "Example Configuration" config EXAMPLE_TX_GPIO_NUM int "TX GPIO number" - default 20 if IDF_TARGET_ESP32S2 + default 2 if IDF_TARGET_ESP32C3 + default 20 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 default 21 if IDF_TARGET_ESP32 help This option selects the GPIO pin used for the TX signal. Connect the @@ -10,7 +11,8 @@ menu "Example Configuration" config EXAMPLE_RX_GPIO_NUM int "RX GPIO number" - default 21 if IDF_TARGET_ESP32S2 + default 3 if IDF_TARGET_ESP32C3 + default 21 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 default 22 if IDF_TARGET_ESP32 help This option selects the GPIO pin used for the RX signal. Connect the diff --git a/examples/peripherals/twai/twai_network/twai_network_slave/main/Kconfig.projbuild b/examples/peripherals/twai/twai_network/twai_network_slave/main/Kconfig.projbuild index 125931f169..ed23df09cd 100644 --- a/examples/peripherals/twai/twai_network/twai_network_slave/main/Kconfig.projbuild +++ b/examples/peripherals/twai/twai_network/twai_network_slave/main/Kconfig.projbuild @@ -2,7 +2,8 @@ menu "Example Configuration" config EXAMPLE_TX_GPIO_NUM int "TX GPIO number" - default 20 if IDF_TARGET_ESP32S2 + default 2 if IDF_TARGET_ESP32C3 + default 20 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 default 21 if IDF_TARGET_ESP32 help This option selects the GPIO pin used for the TX signal. Connect the @@ -10,7 +11,8 @@ menu "Example Configuration" config EXAMPLE_RX_GPIO_NUM int "RX GPIO number" - default 21 if IDF_TARGET_ESP32S2 + default 3 if IDF_TARGET_ESP32C3 + default 21 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 default 22 if IDF_TARGET_ESP32 help This option selects the GPIO pin used for the RX signal. Connect the diff --git a/examples/peripherals/twai/twai_self_test/README.md b/examples/peripherals/twai/twai_self_test/README.md index 86237312ed..46f1a60f2a 100644 --- a/examples/peripherals/twai/twai_self_test/README.md +++ b/examples/peripherals/twai/twai_self_test/README.md @@ -2,7 +2,7 @@ (See the README.md file in the upper level 'examples' directory for more information about examples.) -The TWAI Self Test Example demonstrates how a node can transmit TWAI messages to itself using the TWAI driver's "No Acknowledgement" mode and Self Reception Requests. The Self Test Example can be run as a simple test to determine whether a target (ESP32 or ESP32-S2) is properly connected to a working external transceiver. +The TWAI Self Test Example demonstrates how a node can transmit TWAI messages to itself using the TWAI driver's "No Acknowledgement" mode and Self Reception Requests. The Self Test Example can be run as a simple test to determine whether a target (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) is properly connected to a working external transceiver. ## How to use example @@ -25,6 +25,8 @@ idf.py menuconfig * Under `Example Configuration`, configure the pin assignments using the options `TX GPIO Number` and `RX GPIO Number` according to how the target was connected to the transceiver. By default, `TX GPIO Number` and `RX GPIO Number` are set to the following values: * On the ESP32, `TX GPIO Number` and `RX GPIO Number` default to `21` and `22` respectively * On the ESP32-S2, `TX GPIO Number` and `RX GPIO Number` default to `20` and `21` respectively + * On the ESP32-S3, `TX GPIO Number` and `RX GPIO Number` default to `20` and `21` respectively + * On the ESP32-C3, `TX GPIO Number` and `RX GPIO Number` default to `2` and `3` respectively ### Build and Flash @@ -77,7 +79,7 @@ The TWAI Self Test Example will do multiple iterations of the following steps: 1. Install the TWAI driver 2. Start the TWAI driver -3. Simultaneously transmit and receive multiple messages using the self reception request. +3. Simultaneously transmit and receive multiple messages using the self reception request. 4. Stop the TWAI driver 5. Repeat steps 2 to 4 for multiple iterations 6. Uninstall the TWAI driver diff --git a/examples/peripherals/twai/twai_self_test/main/Kconfig.projbuild b/examples/peripherals/twai/twai_self_test/main/Kconfig.projbuild index 125931f169..ed23df09cd 100644 --- a/examples/peripherals/twai/twai_self_test/main/Kconfig.projbuild +++ b/examples/peripherals/twai/twai_self_test/main/Kconfig.projbuild @@ -2,7 +2,8 @@ menu "Example Configuration" config EXAMPLE_TX_GPIO_NUM int "TX GPIO number" - default 20 if IDF_TARGET_ESP32S2 + default 2 if IDF_TARGET_ESP32C3 + default 20 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 default 21 if IDF_TARGET_ESP32 help This option selects the GPIO pin used for the TX signal. Connect the @@ -10,7 +11,8 @@ menu "Example Configuration" config EXAMPLE_RX_GPIO_NUM int "RX GPIO number" - default 21 if IDF_TARGET_ESP32S2 + default 3 if IDF_TARGET_ESP32C3 + default 21 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 default 22 if IDF_TARGET_ESP32 help This option selects the GPIO pin used for the RX signal. Connect the