Просмотр исходного кода

Merge branch 'feature/c3_twai_bringup' into 'master'

TWAI: bringup for S3 & C3

Closes IDF-2109 and IDF-1770

See merge request espressif/esp-idf!11984
Michael (XIAO Xufeng) 5 лет назад
Родитель
Сommit
b94c99a033

+ 1 - 3
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()
 

+ 1 - 0
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 );

+ 1 - 0
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 );

+ 3 - 7
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"

+ 46 - 83
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_INTR_RI          (0x1 << 0)
-#define TWAI_LL_INTR_TI          (0x1 << 1)
-#define TWAI_LL_INTR_EI          (0x1 << 2)
+#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)      //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

+ 26 - 64
components/hal/esp32s3/include/hal/twai_ll.h

@@ -30,26 +30,25 @@ extern "C" {
 #include <stdbool.h>
 #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_INTR_RI         (0x1 << 0)
-#define TWAI_LL_INTR_TI         (0x1 << 1)
-#define TWAI_LL_INTR_EI         (0x1 << 2)
+#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)      //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

+ 7 - 2
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)

+ 208 - 0
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 <stdint.h>
+
+/* ---------------------------- 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

+ 1 - 1
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.
  */

+ 2 - 2
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 */

+ 3 - 1
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
 

+ 4 - 2
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

+ 20 - 18
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.

+ 4 - 2
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

+ 4 - 2
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

+ 4 - 2
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

+ 4 - 2
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

+ 4 - 2
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