feat(driver_twai): support legacy targets in new driver

This commit is contained in:
wanckl
2025-04-27 15:57:46 +08:00
parent f7398c5bc2
commit 8a60934c4f
53 changed files with 1931 additions and 1197 deletions

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -32,6 +32,13 @@ extern "C" {
#endif
/* ------------------------- Defines and Typedefs --------------------------- */
#define TWAI_LL_BRP_MIN 2
#define TWAI_LL_BRP_MAX 16384
#define TWAI_LL_TSEG1_MIN 1
#define TWAI_LL_TSEG2_MIN 1
#define TWAI_LL_TSEG1_MAX 16 //the max register value
#define TWAI_LL_TSEG2_MAX 8
#define TWAI_LL_SJW_MAX 4
#define TWAI_LL_STATUS_RBS (0x1 << 0) //Receive Buffer Status
#define TWAI_LL_STATUS_DOS (0x1 << 1) //Data Overrun Status
@@ -51,6 +58,51 @@ extern "C" {
#define TWAI_LL_INTR_ALI (0x1 << 6) //Arbitration Lost Interrupt
#define TWAI_LL_INTR_BEI (0x1 << 7) //Bus Error Interrupt
#define TWAI_LL_DRIVER_INTERRUPTS (TWAI_LL_INTR_RI | TWAI_LL_INTR_TI | TWAI_LL_INTR_EI | \
TWAI_LL_INTR_EPI | TWAI_LL_INTR_ALI | TWAI_LL_INTR_BEI)
typedef enum {
TWAI_LL_ERR_BIT = 0,
TWAI_LL_ERR_FORM,
TWAI_LL_ERR_STUFF,
TWAI_LL_ERR_OTHER,
TWAI_LL_ERR_MAX,
} twai_ll_err_type_t;
typedef enum {
TWAI_LL_ERR_DIR_TX = 0,
TWAI_LL_ERR_DIR_RX,
TWAI_LL_ERR_DIR_MAX,
} twai_ll_err_dir_t;
typedef enum {
TWAI_LL_ERR_SEG_SOF = 3,
TWAI_LL_ERR_SEG_ID_28_21 = 2,
TWAI_LL_ERR_SEG_SRTR = 4,
TWAI_LL_ERR_SEG_IDE = 5,
TWAI_LL_ERR_SEG_ID_20_18 = 6,
TWAI_LL_ERR_SEG_ID_17_13 = 7,
TWAI_LL_ERR_SEG_CRC_SEQ = 8,
TWAI_LL_ERR_SEG_R0 = 9,
TWAI_LL_ERR_SEG_DATA = 10,
TWAI_LL_ERR_SEG_DLC = 11,
TWAI_LL_ERR_SEG_RTR = 12,
TWAI_LL_ERR_SEG_R1 = 13,
TWAI_LL_ERR_SEG_ID_4_0 = 14,
TWAI_LL_ERR_SEG_ID_12_5 = 15,
TWAI_LL_ERR_SEG_ACT_FLAG = 17,
TWAI_LL_ERR_SEG_INTER = 18,
TWAI_LL_ERR_SEG_SUPERPOS = 19,
TWAI_LL_ERR_SEG_PASS_FLAG = 22,
TWAI_LL_ERR_SEG_ERR_DELIM = 23,
TWAI_LL_ERR_SEG_CRC_DELIM = 24,
TWAI_LL_ERR_SEG_ACK_SLOT = 25,
TWAI_LL_ERR_SEG_EOF = 26,
TWAI_LL_ERR_SEG_ACK_DELIM = 27,
TWAI_LL_ERR_SEG_OVRLD_FLAG = 28,
TWAI_LL_ERR_SEG_MAX = 29,
} twai_ll_err_seg_t;
/*
* The following frame structure has an NEARLY identical bit field layout to
* each byte of the TX buffer. This allows for formatting and parsing frames to
@@ -59,7 +111,7 @@ extern "C" {
* TX buffer are used in the frame structure to store the self_reception and
* single_shot flags which in turn indicate the type of transmission to execute.
*/
typedef union {
typedef union twai_ll_frame_buffer_t {
struct {
struct {
uint8_t dlc: 4; //Data length code (0 to 8) of the frame
@@ -202,18 +254,10 @@ static inline bool twai_ll_is_in_reset_mode(twai_dev_t *hw)
* @note Must be called in reset mode
*/
__attribute__((always_inline))
static inline void twai_ll_set_mode(twai_dev_t *hw, twai_mode_t mode)
static inline void twai_ll_set_mode(twai_dev_t *hw, bool listen_only, bool no_ack, bool loopback)
{
if (mode == TWAI_MODE_NORMAL) { //Normal Operating mode
hw->mode_reg.lom = 0;
hw->mode_reg.stm = 0;
} else if (mode == TWAI_MODE_NO_ACK) { //Self Test Mode (No Ack)
hw->mode_reg.lom = 0;
hw->mode_reg.stm = 1;
} else if (mode == TWAI_MODE_LISTEN_ONLY) { //Listen Only Mode
hw->mode_reg.lom = 1;
hw->mode_reg.stm = 0;
}
hw->mode_reg.lom = listen_only;
hw->mode_reg.stm = no_ack;
}
/* --------------------------- Command Register ----------------------------- */
@@ -354,30 +398,6 @@ static inline uint32_t twai_ll_get_status(twai_dev_t *hw)
return hw->status_reg.val;
}
/**
* @brief Check if RX FIFO overrun status bit is set
*
* @param hw Start address of the TWAI registers
* @return Overrun status bit
*/
__attribute__((always_inline))
static inline bool twai_ll_is_fifo_overrun(twai_dev_t *hw)
{
return hw->status_reg.dos;
}
/**
* @brief Check if previously TX was successful
*
* @param hw Start address of the TWAI registers
* @return Whether previous TX was successful
*/
__attribute__((always_inline))
static inline bool twai_ll_is_last_tx_successful(twai_dev_t *hw)
{
return hw->status_reg.tcs;
}
/* -------------------------- Interrupt Register ---------------------------- */
/**
@@ -422,7 +442,7 @@ static inline void twai_ll_set_enabled_intrs(twai_dev_t *hw, uint32_t intr_mask)
__attribute__((always_inline))
static inline bool twai_ll_check_brp_validation(uint32_t brp)
{
bool valid = (brp >= SOC_TWAI_BRP_MIN) && (brp <= SOC_TWAI_BRP_MAX);
bool valid = (brp >= TWAI_LL_BRP_MIN) && (brp <= TWAI_LL_BRP_MAX);
// should be an even number
valid = valid && !(brp & 0x01);
return valid;
@@ -469,16 +489,19 @@ static inline void twai_ll_clear_arb_lost_cap(twai_dev_t *hw)
/* ----------------------------- ECC Register ------------------------------- */
/**
* @brief Clear Error Code Capture register
* @brief Parse Error Code Capture register
*
* Reading the ECC register rearms the Bus Error Interrupt
*
* @param hw Start address of the TWAI registers
*/
__attribute__((always_inline))
static inline void twai_ll_clear_err_code_cap(twai_dev_t *hw)
static inline void twai_ll_parse_err_code_cap(twai_dev_t *hw, twai_ll_err_type_t *type, twai_ll_err_dir_t *dir, twai_ll_err_seg_t *seg)
{
(void)hw->error_code_capture_reg.val;
uint32_t ecc = hw->error_code_capture_reg.val;
*type = (twai_ll_err_type_t) ((ecc >> 6) & 0x3);
*dir = (twai_ll_err_dir_t) ((ecc >> 5) & 0x1);
*seg = (twai_ll_err_seg_t) (ecc & 0x1F);
}
/* ----------------------------- EWL Register ------------------------------- */
@@ -679,6 +702,18 @@ static inline void twai_ll_format_frame_buffer(uint32_t id, uint8_t dlc, const u
}
}
/**
* @brief Check if the message in twai_ll_frame_buffer is extend id format or not
*
* @param rx_frame The rx_frame in twai_ll_frame_buffer_t type
* @return true if the message is extend id format, false if not
*/
__attribute__((always_inline))
static inline bool twai_ll_frame_is_ext_format(twai_ll_frame_buffer_t *rx_frame)
{
return rx_frame->frame_format;
}
/**
* @brief Parse formatted TWAI frame (RX Buffer Layout) into its constituent contents
*
@@ -690,7 +725,7 @@ static inline void twai_ll_format_frame_buffer(uint32_t id, uint8_t dlc, const u
*/
__attribute__((always_inline))
static inline void twai_ll_parse_frame_buffer(twai_ll_frame_buffer_t *rx_frame, uint32_t *id, uint8_t *dlc,
uint8_t *data, uint32_t *flags)
uint8_t *data, uint32_t buf_sz, uint32_t *flags)
{
//Copy frame information
*dlc = rx_frame->dlc;
@@ -720,13 +755,10 @@ static inline void twai_ll_parse_frame_buffer(twai_ll_frame_buffer_t *rx_frame,
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);
data_length = (data_length < buf_sz) ? data_length : buf_sz;
for (int i = 0; i < data_length; i++) {
data[i] = data_buffer[i];
}
//Set remaining bytes of data to 0
for (int i = data_length; i < TWAI_FRAME_MAX_DLC; i++) {
data[i] = 0;
}
}
/* ----------------------- RX Message Count Register ------------------------ */