Files
esp-idf/components/esp_driver_twai/include/esp_twai_onchip.h

97 lines
4.6 KiB
C

/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_err.h"
#include "esp_twai_types.h"
#include "hal/gpio_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief TWAI on-chip node initialization configuration structure
*/
typedef struct {
struct {
gpio_num_t tx; /**< GPIO pin for twai TX */
gpio_num_t rx; /**< GPIO pin for twai RX */
gpio_num_t quanta_clk_out; /**< GPIO pin for quanta clock output, Set -1 to not use */
gpio_num_t bus_off_indicator; /**< GPIO pin for bus-off indicator, Set -1 to not use */
} io_cfg; /**< I/O configuration */
twai_clock_source_t clk_src; /**< Optional, clock source, remain 0 to using TWAI_CLK_SRC_DEFAULT by default */
twai_timing_basic_config_t bit_timing; /**< Timing configuration for classic twai and FD arbitration stage */
twai_timing_basic_config_t data_timing; /**< Optional, timing configuration for FD data stage */
int8_t fail_retry_cnt; /**< Hardware retry limit if failed, range [-1:15], -1 for re-trans forever */
uint32_t tx_queue_depth; /**< Depth of the transmit queue */
int intr_priority; /**< Interrupt priority, [0:3] */
struct {
uint32_t enable_self_test: 1; /**< Transmission does not require acknowledgment. Use this mode for self testing */
uint32_t enable_loopback: 1; /**< The TWAI controller receive back frames what it send out */
uint32_t enable_listen_only: 1; /**< The TWAI controller will not influence the bus (No transmissions or acknowledgments) but can receive messages */
uint32_t no_receive_rtr: 1; /**< Don't receive remote frames */
} flags; /**< Misc configuration flags */
} twai_onchip_node_config_t;
/**
* @brief Allocate a TWAI hardware node by specific init config structure
* To delete/free the TWAI, call `twai_node_delete()`
*
* @param[in] node_config Init config structure
* @param[out] node_ret Return driver handle
*
* @return ESP_OK Allocate success
* ESP_ERR_NO_MEM No enough free memory
* ESP_ERR_NOT_FOUND No free hardware controller
* ESP_ERR_INVALID_ARG Config argument not available
* ESP_ERR_INVALID_STATE State error, including hardware state error and driver state error
* ESP_FAIL Other reasons
*/
esp_err_t twai_new_node_onchip(const twai_onchip_node_config_t *node_config, twai_node_handle_t *node_ret);
/**
* @brief Helper function to configure a dual 16-bit acceptance filter.
* @note For 29bits Extended IDs, ONLY high 16bits id/mask is used for eache filter.
*
* @param id1 First ID to filter.
* @param mask1 Mask for first ID.
* @param id2 Second ID to filter.
* @param mask2 Mask for second ID.
* @param is_ext True if using Extended (29-bit) IDs, false for Standard (11-bit) IDs.
* @return twai_mask_filter_config_t A filled filter configuration structure for dual filtering.
*/
static inline twai_mask_filter_config_t twai_make_dual_filter(uint16_t id1, uint16_t mask1, uint16_t id2, uint16_t mask2, bool is_ext)
{
/**
* Dual filter is a special mode in hardware,
* which allow split general 32bits filter register to 2 unit of 16 bits id/mask pairs then using as 2 filter
* below code do bit shifting to reach hardware requirement in this mode, for detail please refer to `Dual Filter Mode` of TRM
*
* 31 16 15 0
* ▼ ▼ ▼ ▼
* xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
* ◄─11 bits─► ◄─11 bits─►
* std filter 2 std filter 1
* ─────────────────────────────────
* ◄───16─bits────► ◄───16─bits────►
* ext filter 2 etx filter 1
*/
twai_mask_filter_config_t dual_cfg = {
.id = is_ext ? (((id1 & TWAI_EXT_ID_MASK) >> 13) << 16) | ((id2 & TWAI_EXT_ID_MASK) >> 13) : \
((id1 & TWAI_STD_ID_MASK) << 21) | ((id2 & TWAI_STD_ID_MASK) << 5),
.mask = is_ext ? (((mask1 & TWAI_EXT_ID_MASK) >> 13) << 16) | ((mask2 & TWAI_EXT_ID_MASK) >> 13) : \
((mask1 & TWAI_STD_ID_MASK) << 21) | ((mask2 & TWAI_STD_ID_MASK) << 5),
.is_ext = is_ext,
.dual_filter = true,
};
return dual_cfg;
}
#ifdef __cplusplus
}
#endif