mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
twai: h2 support twai driver
This commit is contained in:
parent
76989b504a
commit
fdeeced62c
@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# Enable Socket CAN Device with bitrate 250Kbps
|
||||
|
||||
|
@ -12,6 +12,7 @@ from pytest_embedded import Dut
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.esp32h2
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.generic
|
||||
@ -39,6 +40,7 @@ def fixture_create_socket_can() -> Bus:
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.esp32h2
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.skip(reason='Runner not set up yet')
|
||||
@ -70,6 +72,7 @@ def test_twai_listen_only(dut: Dut, socket_can: Bus) -> None:
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.esp32h2
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.skip(reason='Runner not set up yet')
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include "esp_pm.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "clk_tree.h"
|
||||
#include "clk_ctrl_os.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_private/esp_clk.h"
|
||||
@ -426,24 +428,7 @@ esp_err_t twai_driver_install(const twai_general_config_t *g_config, const twai_
|
||||
if (clk_src == 0) {
|
||||
clk_src = TWAI_CLK_SRC_DEFAULT;
|
||||
}
|
||||
|
||||
switch (clk_src) {
|
||||
#if SOC_TWAI_CLK_SUPPORT_APB
|
||||
case TWAI_CLK_SRC_APB:
|
||||
clock_source_hz = esp_clk_apb_freq();
|
||||
break;
|
||||
#endif //SOC_TWAI_CLK_SUPPORT_APB
|
||||
|
||||
#if SOC_TWAI_CLK_SUPPORT_XTAL
|
||||
case TWAI_CLK_SRC_XTAL:
|
||||
clock_source_hz = esp_clk_xtal_freq();
|
||||
break;
|
||||
#endif //SOC_TWAI_CLK_SUPPORT_XTAL
|
||||
|
||||
default:
|
||||
//Invalid clock source
|
||||
TWAI_CHECK(false, ESP_ERR_INVALID_ARG);
|
||||
}
|
||||
clk_tree_src_get_freq_hz(clk_src, CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clock_source_hz);
|
||||
|
||||
//Check brp validation
|
||||
uint32_t brp = t_config->brp;
|
||||
@ -469,8 +454,9 @@ esp_err_t twai_driver_install(const twai_general_config_t *g_config, const twai_
|
||||
p_twai_obj_dummy->alerts_enabled = g_config->alerts_enabled;
|
||||
p_twai_obj_dummy->module = twai_controller_periph_signals.controllers[controller_id].module;
|
||||
|
||||
|
||||
#if CONFIG_PM_ENABLE && SOC_TWAI_CLK_SUPPORT_APB
|
||||
#if CONFIG_PM_ENABLE
|
||||
#if SOC_TWAI_CLK_SUPPORT_APB
|
||||
// DFS can change APB frequency. So add lock to prevent sleep and APB freq from changing
|
||||
if (clk_src == TWAI_CLK_SRC_APB) {
|
||||
// TODO: pm_lock name should also reflect the controller ID
|
||||
ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "twai", &(p_twai_obj_dummy->pm_lock));
|
||||
@ -478,7 +464,14 @@ esp_err_t twai_driver_install(const twai_general_config_t *g_config, const twai_
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#endif //CONFIG_PM_ENABLE && SOC_TWAI_CLK_SUPPORT_APB
|
||||
#else // XTAL
|
||||
// XTAL freq can be closed in light sleep, so we need to create a lock to prevent light sleep
|
||||
ret = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "twai", &(p_twai_obj_dummy->pm_lock));
|
||||
if (ret != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
#endif //SOC_TWAI_CLK_SUPPORT_APB
|
||||
#endif //CONFIG_PM_ENABLE
|
||||
|
||||
//Initialize TWAI peripheral registers, and allocate interrupt
|
||||
TWAI_ENTER_CRITICAL();
|
||||
|
@ -24,8 +24,9 @@
|
||||
#include "hal/twai_types.h"
|
||||
#include "soc/twai_periph.h"
|
||||
#include "soc/twai_struct.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
|
||||
#define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI) : NULL)
|
||||
#define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI0) : NULL)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -96,7 +97,7 @@ ESP_STATIC_ASSERT(sizeof(twai_ll_frame_buffer_t) == 13, "TX/RX buffer type shoul
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en)
|
||||
{
|
||||
(void)hw;
|
||||
PCR.twai0_func_clk_conf.twai0_func_clk_en = en;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,8 +109,13 @@ static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en)
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t clk_src)
|
||||
{
|
||||
(void)hw;
|
||||
HAL_ASSERT(clk_src == TWAI_CLK_SRC_APB);
|
||||
switch (clk_src) {
|
||||
case TWAI_CLK_SRC_DEFAULT:
|
||||
PCR.twai0_func_clk_conf.twai0_func_clk_sel = 0;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------- Mode Register ------------------------------- */
|
||||
@ -128,7 +134,7 @@ static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_enter_reset_mode(twai_dev_t *hw)
|
||||
{
|
||||
hw->mode_reg.rm = 1;
|
||||
hw->mode.reset_mode = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,7 +151,7 @@ static inline void twai_ll_enter_reset_mode(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_exit_reset_mode(twai_dev_t *hw)
|
||||
{
|
||||
hw->mode_reg.rm = 0;
|
||||
hw->mode.reset_mode = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -156,7 +162,7 @@ static inline void twai_ll_exit_reset_mode(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline bool twai_ll_is_in_reset_mode(twai_dev_t *hw)
|
||||
{
|
||||
return hw->mode_reg.rm;
|
||||
return hw->mode.reset_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -170,15 +176,15 @@ static inline bool twai_ll_is_in_reset_mode(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_set_mode(twai_dev_t *hw, twai_mode_t mode)
|
||||
{
|
||||
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;
|
||||
if (mode == TWAI_MODE_NORMAL) { //Normal Operating mode
|
||||
hw->mode.listen_only_mode = 0;
|
||||
hw->mode.self_test_mode = 0;
|
||||
} else if (mode == TWAI_MODE_NO_ACK) { //Self Test Mode (No Ack)
|
||||
hw->mode.listen_only_mode = 0;
|
||||
hw->mode.self_test_mode = 1;
|
||||
} else if (mode == TWAI_MODE_LISTEN_ONLY) { //Listen Only Mode
|
||||
hw->mode.listen_only_mode = 1;
|
||||
hw->mode.self_test_mode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,7 +206,7 @@ static inline void twai_ll_set_mode(twai_dev_t *hw, twai_mode_t mode)
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_set_cmd_tx(twai_dev_t *hw)
|
||||
{
|
||||
hw->command_reg.tr = 1;
|
||||
hw->cmd.tx_request = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -218,7 +224,7 @@ static inline void twai_ll_set_cmd_tx(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_set_cmd_tx_single_shot(twai_dev_t *hw)
|
||||
{
|
||||
hw->command_reg.val = 0x03; //Set command_reg.tr and command_reg.at simultaneously for single shot transmittion request
|
||||
hw->cmd.val = 0x03; //Set cmd.tx_request and cmd.abort_tx simultaneously for single shot transmitting request
|
||||
}
|
||||
|
||||
/**
|
||||
@ -238,7 +244,7 @@ static inline void twai_ll_set_cmd_tx_single_shot(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_set_cmd_abort_tx(twai_dev_t *hw)
|
||||
{
|
||||
hw->command_reg.at = 1;
|
||||
hw->cmd.abort_tx = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -251,7 +257,7 @@ static inline void twai_ll_set_cmd_abort_tx(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_set_cmd_release_rx_buffer(twai_dev_t *hw)
|
||||
{
|
||||
hw->command_reg.rrb = 1;
|
||||
hw->cmd.release_buffer = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -264,7 +270,7 @@ static inline void twai_ll_set_cmd_release_rx_buffer(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_set_cmd_clear_data_overrun(twai_dev_t *hw)
|
||||
{
|
||||
hw->command_reg.cdo = 1;
|
||||
hw->cmd.clear_data_overrun = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -284,7 +290,7 @@ static inline void twai_ll_set_cmd_clear_data_overrun(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_set_cmd_self_rx_request(twai_dev_t *hw)
|
||||
{
|
||||
hw->command_reg.srr = 1;
|
||||
hw->cmd.self_rx_request = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -303,7 +309,7 @@ static inline void twai_ll_set_cmd_self_rx_request(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_set_cmd_self_rx_single_shot(twai_dev_t *hw)
|
||||
{
|
||||
hw->command_reg.val = 0x12; //Set command_reg.srr and command_reg.at simultaneously for single shot self reception request
|
||||
hw->cmd.val = 0x12; //Set cmd.self_rx_request and cmd.abort_tx simultaneously for single shot self reception request
|
||||
}
|
||||
|
||||
/* --------------------------- Status Register ------------------------------ */
|
||||
@ -317,7 +323,7 @@ static inline void twai_ll_set_cmd_self_rx_single_shot(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t twai_ll_get_status(twai_dev_t *hw)
|
||||
{
|
||||
return hw->status_reg.val;
|
||||
return hw->status.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -329,7 +335,7 @@ static inline uint32_t twai_ll_get_status(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline bool twai_ll_is_fifo_overrun(twai_dev_t *hw)
|
||||
{
|
||||
return hw->status_reg.dos;
|
||||
return hw->status.status_overrun;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -341,7 +347,7 @@ static inline bool twai_ll_is_fifo_overrun(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline bool twai_ll_is_last_tx_successful(twai_dev_t *hw)
|
||||
{
|
||||
return hw->status_reg.tcs;
|
||||
return hw->status.status_transmission_complete;
|
||||
}
|
||||
|
||||
/* -------------------------- Interrupt Register ---------------------------- */
|
||||
@ -358,7 +364,7 @@ static inline bool twai_ll_is_last_tx_successful(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t twai_ll_get_and_clear_intrs(twai_dev_t *hw)
|
||||
{
|
||||
return hw->interrupt_reg.val;
|
||||
return hw->interrupt.val;
|
||||
}
|
||||
|
||||
/* ----------------------- Interrupt Enable Register ------------------------ */
|
||||
@ -374,7 +380,7 @@ static inline uint32_t twai_ll_get_and_clear_intrs(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_set_enabled_intrs(twai_dev_t *hw, uint32_t intr_mask)
|
||||
{
|
||||
hw->interrupt_enable_reg.val = intr_mask;
|
||||
hw->interrupt_enable.val = intr_mask;
|
||||
}
|
||||
|
||||
/* ------------------------ Bus Timing Registers --------------------------- */
|
||||
@ -405,16 +411,16 @@ static inline bool twai_ll_check_brp_validation(uint32_t brp)
|
||||
* @param triple_sampling Triple Sampling enable/disable
|
||||
*
|
||||
* @note Must be called in reset mode
|
||||
* @note ESP32H4 brp can be any even number between 2 to 32768
|
||||
* @note ESP32H2 brp can be any even number between 2 to 32768
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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)
|
||||
{
|
||||
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;
|
||||
hw->bus_timing_1_reg.tseg2 = tseg2 - 1;
|
||||
hw->bus_timing_1_reg.sam = triple_sampling;
|
||||
hw->bus_timing_0.baud_presc = (brp / 2) - 1;
|
||||
hw->bus_timing_0.sync_jump_width = sjw - 1;
|
||||
hw->bus_timing_1.time_segment1 = tseg1 - 1;
|
||||
hw->bus_timing_1.time_segment2 = tseg2 - 1;
|
||||
hw->bus_timing_1.time_sampling = triple_sampling;
|
||||
}
|
||||
|
||||
/* ----------------------------- ALC Register ------------------------------- */
|
||||
@ -429,7 +435,7 @@ static inline void twai_ll_set_bus_timing(twai_dev_t *hw, uint32_t brp, uint32_t
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_clear_arb_lost_cap(twai_dev_t *hw)
|
||||
{
|
||||
(void)hw->arbitration_lost_captue_reg.val;
|
||||
(void)hw->arb_lost_cap.val;
|
||||
}
|
||||
|
||||
/* ----------------------------- ECC Register ------------------------------- */
|
||||
@ -444,7 +450,7 @@ static inline void twai_ll_clear_arb_lost_cap(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_clear_err_code_cap(twai_dev_t *hw)
|
||||
{
|
||||
(void)hw->error_code_capture_reg.val;
|
||||
(void)hw->err_code_cap.val;
|
||||
}
|
||||
|
||||
/* ----------------------------- EWL Register ------------------------------- */
|
||||
@ -460,7 +466,7 @@ static inline void twai_ll_clear_err_code_cap(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_set_err_warn_lim(twai_dev_t *hw, uint32_t ewl)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->error_warning_limit_reg, ewl, ewl);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->err_warning_limit, err_warning_limit, ewl);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -472,7 +478,7 @@ static inline void twai_ll_set_err_warn_lim(twai_dev_t *hw, uint32_t ewl)
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t twai_ll_get_err_warn_lim(twai_dev_t *hw)
|
||||
{
|
||||
return hw->error_warning_limit_reg.val;
|
||||
return hw->err_warning_limit.val;
|
||||
}
|
||||
|
||||
/* ------------------------ RX Error Count Register ------------------------- */
|
||||
@ -489,7 +495,7 @@ static inline uint32_t twai_ll_get_err_warn_lim(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t twai_ll_get_rec(twai_dev_t *hw)
|
||||
{
|
||||
return hw->rx_error_counter_reg.val;
|
||||
return hw->rx_err_cnt.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -503,7 +509,7 @@ static inline uint32_t twai_ll_get_rec(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_set_rec(twai_dev_t *hw, uint32_t rec)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->rx_error_counter_reg, rxerr, rec);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->rx_err_cnt, rx_err_cnt, rec);
|
||||
}
|
||||
|
||||
/* ------------------------ TX Error Count Register ------------------------- */
|
||||
@ -519,7 +525,7 @@ static inline void twai_ll_set_rec(twai_dev_t *hw, uint32_t rec)
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t twai_ll_get_tec(twai_dev_t *hw)
|
||||
{
|
||||
return hw->tx_error_counter_reg.val;
|
||||
return hw->tx_err_cnt.val;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -533,7 +539,7 @@ static inline uint32_t twai_ll_get_tec(twai_dev_t *hw)
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_set_tec(twai_dev_t *hw, uint32_t tec)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->tx_error_counter_reg, txerr, tec);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->tx_err_cnt, tx_err_cnt, tec);
|
||||
}
|
||||
|
||||
/* ---------------------- Acceptance Filter Registers ----------------------- */
|
||||
@ -548,15 +554,15 @@ static inline void twai_ll_set_tec(twai_dev_t *hw, uint32_t tec)
|
||||
* @note Must be called in reset mode
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void twai_ll_set_acc_filter(twai_dev_t* hw, uint32_t code, uint32_t mask, bool single_filter)
|
||||
static inline void twai_ll_set_acc_filter(twai_dev_t *hw, uint32_t code, uint32_t mask, bool single_filter)
|
||||
{
|
||||
uint32_t code_swapped = __builtin_bswap32(code);
|
||||
uint32_t mask_swapped = __builtin_bswap32(mask);
|
||||
uint32_t code_swapped = HAL_SWAP32(code);
|
||||
uint32_t mask_swapped = HAL_SWAP32(mask);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->acceptance_filter.acr[i], byte, ((code_swapped >> (i * 8)) & 0xFF));
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->acceptance_filter.amr[i], byte, ((mask_swapped >> (i * 8)) & 0xFF));
|
||||
}
|
||||
hw->mode_reg.afm = single_filter;
|
||||
hw->mode.acceptance_filter_mode = single_filter;
|
||||
}
|
||||
|
||||
/* ------------------------- TX/RX Buffer Registers ------------------------- */
|
||||
@ -591,7 +597,7 @@ static inline void twai_ll_get_rx_buffer(twai_dev_t *hw, twai_ll_frame_buffer_t
|
||||
{
|
||||
//Copy RX buffer registers into frame
|
||||
for (int i = 0; i < 13; i++) {
|
||||
rx_frame->bytes[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->tx_rx_buffer[i], byte);
|
||||
rx_frame->bytes[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->tx_rx_buffer[i], byte);
|
||||
}
|
||||
}
|
||||
|
||||
@ -612,7 +618,7 @@ static inline void twai_ll_get_rx_buffer(twai_dev_t *hw, twai_ll_frame_buffer_t
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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)
|
||||
uint32_t flags, twai_ll_frame_buffer_t *tx_frame)
|
||||
{
|
||||
bool is_extd = flags & TWAI_MSG_FLAG_EXTD;
|
||||
bool is_rtr = flags & TWAI_MSG_FLAG_RTR;
|
||||
@ -626,12 +632,12 @@ static inline void twai_ll_format_frame_buffer(uint32_t id, uint8_t dlc, const u
|
||||
|
||||
//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))
|
||||
uint32_t id_temp = HAL_SWAP32((id & TWAI_EXTD_ID_MASK) << 3); //((id << 3) >> 8*(3-i))
|
||||
for (int i = 0; i < 4; i++) {
|
||||
tx_frame->extended.id[i] = (id_temp >> (8 * i)) & 0xFF;
|
||||
}
|
||||
} else {
|
||||
uint32_t id_temp = __builtin_bswap16((id & TWAI_STD_ID_MASK) << 5); //((id << 5) >> 8*(1-i))
|
||||
uint32_t id_temp = HAL_SWAP16((id & TWAI_STD_ID_MASK) << 5); //((id << 5) >> 8*(1-i))
|
||||
for (int i = 0; i < 2; i++) {
|
||||
tx_frame->standard.id[i] = (id_temp >> (8 * i)) & 0xFF;
|
||||
}
|
||||
@ -656,7 +662,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 *flags)
|
||||
{
|
||||
//Copy frame information
|
||||
*dlc = rx_frame->dlc;
|
||||
@ -672,14 +678,14 @@ static inline void twai_ll_parse_frame_buffer(twai_ll_frame_buffer_t *rx_frame,
|
||||
for (int i = 0; i < 4; i++) {
|
||||
id_temp |= rx_frame->extended.id[i] << (8 * i);
|
||||
}
|
||||
id_temp = __builtin_bswap32(id_temp) >> 3; //((byte[i] << 8*(3-i)) >> 3)
|
||||
id_temp = HAL_SWAP32(id_temp) >> 3; //((byte[i] << 8*(3-i)) >> 3)
|
||||
*id = id_temp & TWAI_EXTD_ID_MASK;
|
||||
} else {
|
||||
uint32_t id_temp = 0;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
id_temp |= rx_frame->standard.id[i] << (8 * i);
|
||||
}
|
||||
id_temp = __builtin_bswap16(id_temp) >> 5; //((byte[i] << 8*(1-i)) >> 5)
|
||||
id_temp = HAL_SWAP16(id_temp) >> 5; //((byte[i] << 8*(1-i)) >> 5)
|
||||
*id = id_temp & TWAI_STD_ID_MASK;
|
||||
}
|
||||
|
||||
@ -706,7 +712,7 @@ static inline void twai_ll_parse_frame_buffer(twai_ll_frame_buffer_t *rx_frame,
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t twai_ll_get_rx_msg_count(twai_dev_t *hw)
|
||||
{
|
||||
return hw->rx_message_counter_reg.val;
|
||||
return hw->rx_message_counter.val;
|
||||
}
|
||||
|
||||
/* ------------------------- Clock Divider Register ------------------------- */
|
||||
@ -714,7 +720,7 @@ 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
|
||||
* Configure CLKOUT. CLKOUT is a pre-scaled version of peripheral source clock. 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
|
||||
@ -724,15 +730,16 @@ __attribute__((always_inline))
|
||||
static inline void twai_ll_set_clkout(twai_dev_t *hw, uint32_t divider)
|
||||
{
|
||||
if (divider >= 2 && divider <= 490) {
|
||||
hw->clock_divider_reg.co = 0;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider_reg, cd, (divider / 2) - 1);
|
||||
hw->clock_divider.clock_off = 0;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider, cd, (divider / 2) - 1);
|
||||
} else if (divider == 1) {
|
||||
//Setting the divider reg to max value (255) means a divider of 1
|
||||
hw->clock_divider_reg.co = 0;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider_reg, cd, 255);
|
||||
hw->clock_divider.clock_off = 0;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider, cd, 255);
|
||||
} else {
|
||||
hw->clock_divider_reg.co = 1;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider_reg, cd, 0);
|
||||
hw->clock_divider.clock_off = 1;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider, cd, 0);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,17 @@ extern "C" {
|
||||
#define TWAI_TIMING_CONFIG_20KBITS() {.quanta_resolution_hz = 400000, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
||||
#endif // (SOC_TWAI_BRP_MAX > 128) || (CONFIG_ESP32_REV_MIN_FULL >= 200)
|
||||
|
||||
#if CONFIG_XTAL_FREQ == 32 // TWAI_CLK_SRC_XTAL = 32M
|
||||
#define TWAI_TIMING_CONFIG_25KBITS() {.quanta_resolution_hz = 400000, .tseg_1 = 11, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
||||
#define TWAI_TIMING_CONFIG_50KBITS() {.quanta_resolution_hz = 1000000, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
||||
#define TWAI_TIMING_CONFIG_100KBITS() {.quanta_resolution_hz = 2000000, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
||||
#define TWAI_TIMING_CONFIG_125KBITS() {.quanta_resolution_hz = 4000000, .tseg_1 = 23, .tseg_2 = 8, .sjw = 3, .triple_sampling = false}
|
||||
#define TWAI_TIMING_CONFIG_250KBITS() {.quanta_resolution_hz = 4000000, .tseg_1 = 11, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
||||
#define TWAI_TIMING_CONFIG_500KBITS() {.quanta_resolution_hz = 8000000, .tseg_1 = 11, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
||||
#define TWAI_TIMING_CONFIG_800KBITS() {.quanta_resolution_hz = 16000000, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
||||
#define TWAI_TIMING_CONFIG_1MBITS() {.quanta_resolution_hz = 16000000, .tseg_1 = 11, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
||||
|
||||
#elif CONFIG_XTAL_FREQ == 40 // TWAI_CLK_SRC_XTAL = 40M
|
||||
#define TWAI_TIMING_CONFIG_25KBITS() {.quanta_resolution_hz = 625000, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false}
|
||||
#define TWAI_TIMING_CONFIG_50KBITS() {.quanta_resolution_hz = 1000000, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
||||
#define TWAI_TIMING_CONFIG_100KBITS() {.quanta_resolution_hz = 2000000, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
||||
@ -72,6 +83,7 @@ extern "C" {
|
||||
#define TWAI_TIMING_CONFIG_500KBITS() {.quanta_resolution_hz = 10000000, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
||||
#define TWAI_TIMING_CONFIG_800KBITS() {.quanta_resolution_hz = 20000000, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false}
|
||||
#define TWAI_TIMING_CONFIG_1MBITS() {.quanta_resolution_hz = 20000000, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
||||
#endif //CONFIG_XTAL_FREQ
|
||||
|
||||
/**
|
||||
* @brief Initializer macro for filter configuration to accept all IDs
|
||||
|
@ -27,6 +27,10 @@ config SOC_MCPWM_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TWAI_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_GPTIMER_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
@ -389,8 +389,8 @@ typedef enum {
|
||||
* @brief TWAI clock source
|
||||
*/
|
||||
typedef enum {
|
||||
TWAI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
|
||||
TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */
|
||||
TWAI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
|
||||
TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */
|
||||
} soc_periph_twai_clk_src_t;
|
||||
|
||||
//////////////////////////////////////////////////ADC///////////////////////////////////////////////////////////////////
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -135,14 +135,14 @@
|
||||
#define RMT_SIG_IN1_IDX 72
|
||||
#define RMT_SIG_OUT1_IDX 72
|
||||
#define MODEM_DIAG9_IDX 72
|
||||
#define CAN0_RX_IDX 73
|
||||
#define CAN0_TX_IDX 73
|
||||
#define TWAI_RX_IDX 73
|
||||
#define TWAI_TX_IDX 73
|
||||
#define MODEM_DIAG10_IDX 73
|
||||
#define CAN0_BUS_OFF_ON_IDX 74
|
||||
#define TWAI_BUS_OFF_ON_IDX 74
|
||||
#define MODEM_DIAG11_IDX 74
|
||||
#define CAN0_CLKOUT_IDX 75
|
||||
#define TWAI_CLKOUT_IDX 75
|
||||
#define MODEM_DIAG12_IDX 75
|
||||
#define CAN0_STANDBY_IDX 76
|
||||
#define TWAI_STANDBY_IDX 76
|
||||
#define MODEM_DIAG13_IDX 76
|
||||
#define CTE_ANT6_IDX 77
|
||||
#define CTE_ANT7_IDX 78
|
||||
|
@ -32,7 +32,7 @@
|
||||
#define SOC_ASYNC_MEMCPY_SUPPORTED 1
|
||||
#define SOC_PCNT_SUPPORTED 1
|
||||
#define SOC_MCPWM_SUPPORTED 1
|
||||
// #define SOC_TWAI_SUPPORTED 1 // TODO: IDF-6217
|
||||
#define SOC_TWAI_SUPPORTED 1
|
||||
// #define SOC_BT_SUPPORTED 1 // TODO: IDF-6416
|
||||
// #define SOC_IEEE802154_SUPPORTED 1 // TODO: IDF-6577
|
||||
#define SOC_GPTIMER_SUPPORTED 1
|
||||
@ -359,7 +359,6 @@
|
||||
#define SOC_TIMER_GROUP_TOTAL_TIMERS (2)
|
||||
#define SOC_TIMER_SUPPORT_ETM (1)
|
||||
|
||||
// TODO: IDF-6217 (Copy from esp32c6, need check)
|
||||
/*-------------------------- TWAI CAPS ---------------------------------------*/
|
||||
#define SOC_TWAI_CONTROLLER_NUM 1
|
||||
#define SOC_TWAI_CLK_SUPPORT_XTAL 1
|
||||
|
22
components/soc/esp32h2/twai_periph.c
Normal file
22
components/soc/esp32h2/twai_periph.c
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "soc/twai_periph.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
|
||||
const twai_controller_signal_conn_t twai_controller_periph_signals = {
|
||||
.controllers = {
|
||||
[0] = {
|
||||
.module = PERIPH_TWAI0_MODULE,
|
||||
.irq_id = ETS_TWAI0_INTR_SOURCE,
|
||||
.tx_sig = TWAI_TX_IDX,
|
||||
.rx_sig = TWAI_RX_IDX,
|
||||
.bus_off_sig = TWAI_BUS_OFF_ON_IDX,
|
||||
.clk_out_sig = TWAI_CLKOUT_IDX,
|
||||
.stand_by_sig = TWAI_STANDBY_IDX,
|
||||
}
|
||||
}
|
||||
};
|
@ -296,21 +296,6 @@ typedef enum {
|
||||
GLITCH_FILTER_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB clock as the default clock choice */
|
||||
} soc_periph_glitch_filter_clk_src_t;
|
||||
|
||||
//////////////////////////////////////////////////TWAI/////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Array initializer for all supported clock sources of TWAI
|
||||
*/
|
||||
#define SOC_TWAI_CLKS {SOC_MOD_CLK_APB}
|
||||
|
||||
/**
|
||||
* @brief TWAI clock source
|
||||
*/
|
||||
typedef enum {
|
||||
TWAI_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
|
||||
TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
|
||||
} soc_periph_twai_clk_src_t;
|
||||
|
||||
//////////////////////////////////////////////////ADC///////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
|
@ -1,209 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* ---------------------------- Register Layout ------------------------------ */
|
||||
|
||||
/* The TWAI peripheral's registers are 8bits, however the ESP32-H4 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 reserved4: 28; /* Internal Reserved. MOD.4 Sleep Mode not supported */
|
||||
};
|
||||
uint32_t val;
|
||||
} mode_reg; /* Address 0x0000 */
|
||||
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 reserved5: 27; /* Internal Reserved */
|
||||
};
|
||||
uint32_t val;
|
||||
} command_reg; /* Address 0x0004 */
|
||||
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 reserved9: 23; /* Internal Reserved */
|
||||
};
|
||||
uint32_t val;
|
||||
} status_reg; /* Address 0x0008 */
|
||||
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 doi: 1; /* IR.3 Data Overrun Interrupt */
|
||||
uint32_t reserved4: 1; /* Internal Reserved (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 reserved8: 24; /* Internal Reserved */
|
||||
};
|
||||
uint32_t val;
|
||||
} interrupt_reg; /* Address 0x000C */
|
||||
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 doie: 1; /* IER.3 Data Overrun Interrupt Enable */
|
||||
uint32_t reserved4: 1; /* Internal Reserved (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 reserved8: 24; /* Internal Reserved */
|
||||
};
|
||||
uint32_t val;
|
||||
} interrupt_enable_reg; /* Address 0x0010 */
|
||||
uint32_t reserved_14;
|
||||
union {
|
||||
struct {
|
||||
uint32_t brp: 13; /* BTR0[12:0] Baud Rate Prescaler */
|
||||
uint32_t reserved13: 1; /* Internal Reserved */
|
||||
uint32_t sjw: 2; /* BTR0[15:14] Synchronization Jump Width*/
|
||||
uint32_t reserved16: 16; /* Internal Reserved */
|
||||
};
|
||||
uint32_t val;
|
||||
} bus_timing_0_reg; /* Address 0x0018 */
|
||||
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 reserved8: 24; /* Internal Reserved */
|
||||
};
|
||||
uint32_t val;
|
||||
} bus_timing_1_reg; /* Address 0x001C */
|
||||
uint32_t reserved_20; /* Address 0x0020 (Output control not supported) */
|
||||
uint32_t reserved_24; /* Address 0x0024 (Test Register not supported) */
|
||||
uint32_t reserved_28; /* Address 0x0028 */
|
||||
|
||||
//Capture and Counter Registers
|
||||
union {
|
||||
struct {
|
||||
uint32_t alc: 5; /* ALC[4:0] Arbitration lost capture */
|
||||
uint32_t reserved5: 27; /* Internal Reserved */
|
||||
};
|
||||
uint32_t val;
|
||||
} arbitration_lost_captue_reg; /* Address 0x002C */
|
||||
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 reserved8: 24; /* Internal Reserved */
|
||||
};
|
||||
uint32_t val;
|
||||
} error_code_capture_reg; /* Address 0x0030 */
|
||||
union {
|
||||
struct {
|
||||
uint32_t ewl: 8; /* EWL[7:0] Error Warning Limit */
|
||||
uint32_t reserved8: 24; /* Internal Reserved */
|
||||
};
|
||||
uint32_t val;
|
||||
} error_warning_limit_reg; /* Address 0x0034 */
|
||||
union {
|
||||
struct {
|
||||
uint32_t rxerr: 8; /* RXERR[7:0] Receive Error Counter */
|
||||
uint32_t reserved8: 24; /* Internal Reserved */
|
||||
};
|
||||
uint32_t val;
|
||||
} rx_error_counter_reg; /* Address 0x0038 */
|
||||
union {
|
||||
struct {
|
||||
uint32_t txerr: 8; /* TXERR[7:0] Receive Error Counter */
|
||||
uint32_t reserved8: 24; /* Internal Reserved */
|
||||
};
|
||||
uint32_t val;
|
||||
} tx_error_counter_reg; /* Address 0x003C */
|
||||
|
||||
//Shared Registers (TX Buff/RX Buff/Acc Filter)
|
||||
union {
|
||||
struct {
|
||||
union {
|
||||
struct {
|
||||
uint32_t byte: 8; /* ACRx[7:0] Acceptance Code */
|
||||
uint32_t reserved8: 24; /* Internal Reserved */
|
||||
};
|
||||
uint32_t val;
|
||||
} acr[4];
|
||||
union {
|
||||
struct {
|
||||
uint32_t byte: 8; /* AMRx[7:0] Acceptance Mask */
|
||||
uint32_t reserved8: 24; /* Internal Reserved */
|
||||
};
|
||||
uint32_t val;
|
||||
} amr[4];
|
||||
uint32_t reserved_60;
|
||||
uint32_t reserved_64;
|
||||
uint32_t reserved_68;
|
||||
uint32_t reserved_6c;
|
||||
uint32_t reserved_70;
|
||||
} acceptance_filter;
|
||||
union {
|
||||
struct {
|
||||
uint32_t byte: 8; /* TX/RX Byte X [7:0] */
|
||||
uint32_t reserved24: 24; /* Internal Reserved */
|
||||
};
|
||||
uint32_t val;
|
||||
} tx_rx_buffer[13];
|
||||
}; /* Address 0x0040 - 0x0070 */
|
||||
|
||||
//Misc Registers
|
||||
union {
|
||||
struct {
|
||||
uint32_t rmc: 7; /* RMC[6:0] RX Message Counter */
|
||||
uint32_t reserved7: 25; /* Internal Reserved */
|
||||
};
|
||||
uint32_t val;
|
||||
} rx_message_counter_reg; /* Address 0x0074 */
|
||||
uint32_t reserved_78; /* Address 0x0078 (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 reserved9: 23; /* Internal Reserved */
|
||||
};
|
||||
uint32_t val;
|
||||
} clock_divider_reg; /* Address 0x007C */
|
||||
} twai_dev_t;
|
||||
|
||||
#ifndef __cplusplus
|
||||
_Static_assert(sizeof(twai_dev_t) == 128, "TWAI registers should be 32 * 4 bytes");
|
||||
#endif
|
||||
|
||||
extern twai_dev_t TWAI;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -51,7 +51,6 @@ api-reference/peripherals/sdspi_share
|
||||
api-reference/peripherals/adc_continuous
|
||||
api-reference/peripherals/adc_oneshot
|
||||
api-reference/peripherals/usb_host
|
||||
api-reference/peripherals/twai
|
||||
api-reference/peripherals/usb_device
|
||||
api-reference/peripherals/sdspi_host
|
||||
api-reference/peripherals/i2s
|
||||
|
@ -159,7 +159,7 @@ The operating bit rate of the TWAI driver is configured using the :cpp:type:`twa
|
||||
2. **Timing Segment 1** consists of 1 to 16 time quanta before sample point
|
||||
3. **Timing Segment 2** consists of 1 to 8 time quanta after sample point
|
||||
|
||||
{IDF_TARGET_MAX_BRP:default="128", esp32="128", esp32s2="32768", esp32c3="16384", esp32c6="16384"}
|
||||
{IDF_TARGET_MAX_BRP:default="128", esp32="128", esp32s2="32768", esp32s3="16384", esp32c3="16384", esp32c6="32768", esp32h2="32768"}
|
||||
|
||||
The **Baudrate Prescaler** is used to determine the period of each time quantum by dividing the TWAI controller's source clock. On the {IDF_TARGET_NAME}, the ``brp`` can be **any even number from 2 to {IDF_TARGET_MAX_BRP}**. Alternatively, you can decide the resolution of each quantum, by setting :cpp:member:`twai_timing_config_t::quanta_resolution_hz` to a non-zero value. In this way, the driver can calculate the underlying ``brp`` value for you. It's useful when you set different clock sources but want the bitrate to keep the same.
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# TWAI Alert and Recovery Example
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# TWAI Network Example
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# TWAI Self Test Example
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user