can: Add support for lower bit rates
This commit adds support for lower bit rates in the CAN Driver for ESP32 Rev 2 or later chips.
This commit is contained in:
parent
ef4c513834
commit
09ae962c33
4 changed files with 47 additions and 5 deletions
|
@ -44,12 +44,26 @@
|
||||||
#define CAN_RESET_FLAG(var, mask) ((var) &= ~(mask))
|
#define CAN_RESET_FLAG(var, mask) ((var) &= ~(mask))
|
||||||
#define CAN_TAG "CAN"
|
#define CAN_TAG "CAN"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Baud Rate Prescaler Divider config/values. The BRP_DIV bit is located in the
|
||||||
|
* CAN interrupt enable register, and is only available in ESP32 Revision 2 or
|
||||||
|
* later. Setting this bit will cause the APB clock to be prescaled (divided) by
|
||||||
|
* a factor 2, before having the BRP applied. This will allow for lower bit rates
|
||||||
|
* to be achieved.
|
||||||
|
*/
|
||||||
|
#define BRP_DIV_EN_THRESH 128 //A BRP config value large this this will need to enable brp_div
|
||||||
|
#define BRP_DIV_EN_BIT 0x10 //Bit mask for brp_div in the interrupt register
|
||||||
|
//When brp_div is enabled, the BRP config value must be any multiple of 4 between 132 and 256
|
||||||
|
#define BRP_CHECK_WITH_DIV(brp) ((brp) >= 132 && (brp) <= 256 && ((brp) & 0x3) == 0)
|
||||||
|
//When brp_div is disabled, the BRP config value must be any even number between 2 to 128
|
||||||
|
#define BRP_CHECK_NO_DIV(brp) ((brp) >= 2 && (brp) <= 128 && ((brp) & 0x1) == 0)
|
||||||
|
|
||||||
//Driver default config/values
|
//Driver default config/values
|
||||||
#define DRIVER_DEFAULT_EWL 96 //Default Error Warning Limit value
|
#define DRIVER_DEFAULT_EWL 96 //Default Error Warning Limit value
|
||||||
#define DRIVER_DEFAULT_TEC 0 //TX Error Counter starting value
|
#define DRIVER_DEFAULT_TEC 0 //TX Error Counter starting value
|
||||||
#define DRIVER_DEFAULT_REC 0 //RX Error Counter starting value
|
#define DRIVER_DEFAULT_REC 0 //RX Error Counter starting value
|
||||||
#define DRIVER_DEFAULT_CLKOUT_DIV 14 //APB CLK divided by two
|
#define DRIVER_DEFAULT_CLKOUT_DIV 14 //APB CLK divided by two
|
||||||
#define DRIVER_DEFAULT_INTERRUPTS 0xE7 //Exclude data overrun
|
#define DRIVER_DEFAULT_INTERRUPTS 0xE7 //Exclude data overrun (bit[3]) and brp_div (bit[4])
|
||||||
#define DRIVER_DEFAULT_ERR_PASS_CNT 128 //Error counter threshold for error passive
|
#define DRIVER_DEFAULT_ERR_PASS_CNT 128 //Error counter threshold for error passive
|
||||||
|
|
||||||
//Command Bit Masks
|
//Command Bit Masks
|
||||||
|
@ -199,7 +213,7 @@ static inline void can_config_bus_timing(uint32_t brp, uint32_t sjw, uint32_t ts
|
||||||
- SJW (1 to 4) is number of T_scl to shorten/lengthen for bit synchronization
|
- SJW (1 to 4) is number of T_scl to shorten/lengthen for bit synchronization
|
||||||
- TSEG_1 (1 to 16) is number of T_scl in a bit time before sample point
|
- TSEG_1 (1 to 16) is number of T_scl in a bit time before sample point
|
||||||
- TSEG_2 (1 to 8) is number of T_scl in a bit time after sample point
|
- TSEG_2 (1 to 8) is number of T_scl in a bit time after sample point
|
||||||
- triple_sampling will cause each bit time to be sampled 3 times*/
|
- triple_sampling will cause each bit time to be sampled 3 times */
|
||||||
can_bus_tim_0_reg_t timing_reg_0;
|
can_bus_tim_0_reg_t timing_reg_0;
|
||||||
can_bus_tim_1_reg_t timing_reg_1;
|
can_bus_tim_1_reg_t timing_reg_1;
|
||||||
timing_reg_0.baud_rate_prescaler = (brp / 2) - 1;
|
timing_reg_0.baud_rate_prescaler = (brp / 2) - 1;
|
||||||
|
@ -629,6 +643,12 @@ esp_err_t can_driver_install(const can_general_config_t *g_config, const can_tim
|
||||||
CAN_CHECK(g_config->rx_queue_len > 0, ESP_ERR_INVALID_ARG);
|
CAN_CHECK(g_config->rx_queue_len > 0, ESP_ERR_INVALID_ARG);
|
||||||
CAN_CHECK(g_config->tx_io >= 0 && g_config->tx_io < GPIO_NUM_MAX, ESP_ERR_INVALID_ARG);
|
CAN_CHECK(g_config->tx_io >= 0 && g_config->tx_io < GPIO_NUM_MAX, ESP_ERR_INVALID_ARG);
|
||||||
CAN_CHECK(g_config->rx_io >= 0 && g_config->rx_io < GPIO_NUM_MAX, ESP_ERR_INVALID_ARG);
|
CAN_CHECK(g_config->rx_io >= 0 && g_config->rx_io < GPIO_NUM_MAX, ESP_ERR_INVALID_ARG);
|
||||||
|
#if (CONFIG_ESP32_REV_MIN >= 2)
|
||||||
|
//ESP32 revision 2 or later chips have a brp_div bit. Check that the BRP config value is valid when brp_div is enabled or disabled
|
||||||
|
CAN_CHECK(BRP_CHECK_WITH_DIV(t_config->brp) || BRP_CHECK_NO_DIV(t_config->brp), ESP_ERR_INVALID_ARG);
|
||||||
|
#else
|
||||||
|
CAN_CHECK(BRP_CHECK_NO_DIV(t_config->brp), ESP_ERR_INVALID_ARG);
|
||||||
|
#endif
|
||||||
|
|
||||||
esp_err_t ret;
|
esp_err_t ret;
|
||||||
can_obj_t *p_can_obj_dummy;
|
can_obj_t *p_can_obj_dummy;
|
||||||
|
@ -685,8 +705,14 @@ esp_err_t can_driver_install(const can_general_config_t *g_config, const can_tim
|
||||||
/* Note: REC is allowed to increase even in reset mode. Listen only mode
|
/* Note: REC is allowed to increase even in reset mode. Listen only mode
|
||||||
will freeze REC. The desired mode will be set when can_start() is called. */
|
will freeze REC. The desired mode will be set when can_start() is called. */
|
||||||
can_config_mode(CAN_MODE_LISTEN_ONLY);
|
can_config_mode(CAN_MODE_LISTEN_ONLY);
|
||||||
|
#if (CONFIG_ESP32_REV_MIN >= 2)
|
||||||
|
//If the BRP config value is large enough, the brp_div bit must be enabled to achieve the same effective baud rate prescaler
|
||||||
|
can_config_interrupts((t_config->brp > BRP_DIV_EN_THRESH) ? DRIVER_DEFAULT_INTERRUPTS | BRP_DIV_EN_BIT : DRIVER_DEFAULT_INTERRUPTS);
|
||||||
|
can_config_bus_timing((t_config->brp > BRP_DIV_EN_THRESH) ? t_config->brp/2 : t_config->brp, t_config->sjw, t_config->tseg_1, t_config->tseg_2, t_config->triple_sampling);
|
||||||
|
#else
|
||||||
can_config_interrupts(DRIVER_DEFAULT_INTERRUPTS);
|
can_config_interrupts(DRIVER_DEFAULT_INTERRUPTS);
|
||||||
can_config_bus_timing(t_config->brp, t_config->sjw, t_config->tseg_1, t_config->tseg_2, t_config->triple_sampling);
|
can_config_bus_timing(t_config->brp, t_config->sjw, t_config->tseg_1, t_config->tseg_2, t_config->triple_sampling);
|
||||||
|
#endif
|
||||||
can_config_error(DRIVER_DEFAULT_EWL, DRIVER_DEFAULT_REC, DRIVER_DEFAULT_TEC);
|
can_config_error(DRIVER_DEFAULT_EWL, DRIVER_DEFAULT_REC, DRIVER_DEFAULT_TEC);
|
||||||
can_config_acceptance_filter(f_config->acceptance_code, f_config->acceptance_mask, f_config->single_filter);
|
can_config_acceptance_filter(f_config->acceptance_code, f_config->acceptance_mask, f_config->single_filter);
|
||||||
can_config_clk_out(g_config->clkout_divider);
|
can_config_clk_out(g_config->clkout_divider);
|
||||||
|
|
|
@ -44,7 +44,13 @@ extern "C" {
|
||||||
* The following initializer macros offer commonly found bit rates.
|
* The following initializer macros offer commonly found bit rates.
|
||||||
*
|
*
|
||||||
* @note These timing values are based on the assumption APB clock is at 80MHz
|
* @note These timing values are based on the assumption APB clock is at 80MHz
|
||||||
|
* @note The 20K, 16K and 12.5K bit rates are only available from ESP32 Revision 2 onwards
|
||||||
*/
|
*/
|
||||||
|
#if (CONFIG_ESP32_REV_MIN >= 2)
|
||||||
|
#define CAN_TIMING_CONFIG_12_5KBITS() {.brp = 256, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false}
|
||||||
|
#define CAN_TIMING_CONFIG_16KBITS() {.brp = 200, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false}
|
||||||
|
#define CAN_TIMING_CONFIG_20KBITS() {.brp = 200, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
||||||
|
#endif
|
||||||
#define CAN_TIMING_CONFIG_25KBITS() {.brp = 128, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false}
|
#define CAN_TIMING_CONFIG_25KBITS() {.brp = 128, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false}
|
||||||
#define CAN_TIMING_CONFIG_50KBITS() {.brp = 80, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
#define CAN_TIMING_CONFIG_50KBITS() {.brp = 80, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
||||||
#define CAN_TIMING_CONFIG_100KBITS() {.brp = 40, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
#define CAN_TIMING_CONFIG_100KBITS() {.brp = 40, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
|
||||||
|
@ -152,7 +158,8 @@ typedef struct {
|
||||||
* @note Macro initializers are available for this structure
|
* @note Macro initializers are available for this structure
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t brp; /**< Baudrate prescaler (APB clock divider, even number from 2 to 128) */
|
uint32_t brp; /**< Baudrate prescaler (i.e., APB clock divider) can be any even number from 2 to 128.
|
||||||
|
For ESP32 Rev 2 or later, multiples of 4 from 132 to 256 are also supported */
|
||||||
uint8_t tseg_1; /**< Timing segment 1 (Number of time quanta, between 1 to 16) */
|
uint8_t tseg_1; /**< Timing segment 1 (Number of time quanta, between 1 to 16) */
|
||||||
uint8_t tseg_2; /**< Timing segment 2 (Number of time quanta, 1 to 8) */
|
uint8_t tseg_2; /**< Timing segment 2 (Number of time quanta, 1 to 8) */
|
||||||
uint8_t sjw; /**< Synchronization Jump Width (Max time quanta jump for synchronize from 1 to 4) */
|
uint8_t sjw; /**< Synchronization Jump Width (Max time quanta jump for synchronize from 1 to 4) */
|
||||||
|
|
|
@ -91,7 +91,7 @@ typedef union {
|
||||||
uint32_t tx: 1; /* IER.1 Transmit Interrupt Enable */
|
uint32_t tx: 1; /* IER.1 Transmit Interrupt Enable */
|
||||||
uint32_t err_warn: 1; /* IER.2 Error Interrupt Enable */
|
uint32_t err_warn: 1; /* IER.2 Error Interrupt Enable */
|
||||||
uint32_t data_overrun: 1; /* IER.3 Data Overrun Interrupt Enable */
|
uint32_t data_overrun: 1; /* IER.3 Data Overrun Interrupt Enable */
|
||||||
uint32_t reserved1: 1; /* Internal Reserved (Wake-up not supported) */
|
uint32_t brp_div: 1; /* THIS IS NOT AN INTERRUPT. brp_div will prescale BRP by 2. Only available on ESP32 Revision 2 or later. Reserved otherwise */
|
||||||
uint32_t err_passive: 1; /* IER.5 Error Passive Interrupt Enable */
|
uint32_t err_passive: 1; /* IER.5 Error Passive Interrupt Enable */
|
||||||
uint32_t arb_lost: 1; /* IER.6 Arbitration Lost Interrupt Enable */
|
uint32_t arb_lost: 1; /* IER.6 Arbitration Lost Interrupt Enable */
|
||||||
uint32_t bus_err: 1; /* IER.7 Bus Error Interrupt Enable */
|
uint32_t bus_err: 1; /* IER.7 Bus Error Interrupt Enable */
|
||||||
|
|
|
@ -226,7 +226,9 @@ following segments in the following order:
|
||||||
|
|
||||||
The **Baudrate Prescaler** is used to determine the period of each time quanta by
|
The **Baudrate Prescaler** is used to determine the period of each time quanta by
|
||||||
dividing the CAN controller's source clock (80 MHz APB clock). The ``brp`` can be
|
dividing the CAN controller's source clock (80 MHz APB clock). The ``brp`` can be
|
||||||
**any even number from 2 to 128**.
|
**any even number from 2 to 128**. If the ESP32 is a revision 2 or later chip, the
|
||||||
|
``brp`` will also support **any multiple of 4 from 132 to 256**, and can be enabled
|
||||||
|
by setting the :ref:`CONFIG_ESP32_REV_MIN` to revision 2 or higher.
|
||||||
|
|
||||||
.. packetdiag:: ../../../_static/diagrams/can/can_bit_timing.diag
|
.. packetdiag:: ../../../_static/diagrams/can/can_bit_timing.diag
|
||||||
:caption: Bit timing configuration for 500kbit/s given BRP = 8
|
:caption: Bit timing configuration for 500kbit/s given BRP = 8
|
||||||
|
@ -249,6 +251,9 @@ purposes. ``sjw`` can **range from 1 to 4**.
|
||||||
Bit timing **macro initializers** are also available for commonly used CAN bus bit rates.
|
Bit timing **macro initializers** are also available for commonly used CAN bus bit rates.
|
||||||
The following macro initiliazers are provided by the CAN driver.
|
The following macro initiliazers are provided by the CAN driver.
|
||||||
|
|
||||||
|
- ``CAN_TIMING_CONFIG_12_5KBITS()``
|
||||||
|
- ``CAN_TIMING_CONFIG_16KBITS()``
|
||||||
|
- ``CAN_TIMING_CONFIG_20KBITS()``
|
||||||
- ``CAN_TIMING_CONFIG_25KBITS()``
|
- ``CAN_TIMING_CONFIG_25KBITS()``
|
||||||
- ``CAN_TIMING_CONFIG_50KBITS()``
|
- ``CAN_TIMING_CONFIG_50KBITS()``
|
||||||
- ``CAN_TIMING_CONFIG_100KBITS()``
|
- ``CAN_TIMING_CONFIG_100KBITS()``
|
||||||
|
@ -258,6 +263,10 @@ The following macro initiliazers are provided by the CAN driver.
|
||||||
- ``CAN_TIMING_CONFIG_800KBITS()``
|
- ``CAN_TIMING_CONFIG_800KBITS()``
|
||||||
- ``CAN_TIMING_CONFIG_1MBITS()``
|
- ``CAN_TIMING_CONFIG_1MBITS()``
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
The macro initializers for 12.5K, 16K, and 20K bit rates are only available
|
||||||
|
for ESP32 revision 2 or later.
|
||||||
|
|
||||||
Acceptance Filter
|
Acceptance Filter
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue