]> granicus.if.org Git - esp-idf/commitdiff
can: Add support for lower bit rates
authorDarian <darian@espressif.com>
Thu, 17 Oct 2019 04:33:17 +0000 (12:33 +0800)
committerAngus Gratton <angus@espressif.com>
Thu, 17 Oct 2019 04:33:17 +0000 (12:33 +0800)
This commit adds support for lower bit rates in the CAN Driver for
ESP32 Rev 2 or later chips.

components/driver/can.c
components/driver/include/driver/can.h
components/soc/esp32/include/soc/can_struct.h
docs/en/api-reference/peripherals/can.rst

index 933994b0580e4387d329eda1f65a26cf21e62eee..34d4938b32f575109dc7aeec0e4c23d7ca3d6d57 100644 (file)
 #define CAN_RESET_FLAG(var, mask)   ((var) &= ~(mask))
 #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
 #define DRIVER_DEFAULT_EWL          96          //Default Error Warning Limit value
 #define DRIVER_DEFAULT_TEC          0           //TX 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_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
 
 //Command Bit Masks
@@ -198,7 +212,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
        - 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
-       - 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_1_reg_t timing_reg_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->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);
+#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;
     can_obj_t *p_can_obj_dummy;
@@ -684,8 +704,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
        will freeze REC. The desired mode will be set when can_start() is called. */
     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_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_acceptance_filter(f_config->acceptance_code, f_config->acceptance_mask, f_config->single_filter);
     can_config_clk_out(g_config->clkout_divider);
index 074ead3808566d4e4efccdc6e1d6a88ffffa2c7e..45b829c4044f2ae11f56d29b883a98e1ca27a2ee 100644 (file)
@@ -45,7 +45,13 @@ extern "C" {
  * The following initializer macros offer commonly found bit rates.
  *
  * @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_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}
@@ -153,7 +159,8 @@ typedef struct {
  * @note    Macro initializers are available for this structure
  */
 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_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) */
index 3a7912bd4ceea27b245f8ad63cd6d503e0d79f21..e19196454af2851a8f7a75d2a4b4c9fc78164343 100644 (file)
@@ -93,7 +93,7 @@ typedef union {
         uint32_t tx: 1;                                     /* IER.1 Transmit 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 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 arb_lost: 1;                               /* IER.6 Arbitration Lost Interrupt Enable */
         uint32_t bus_err: 1;                                /* IER.7 Bus Error Interrupt Enable */
index d24cbd7f6a41a15518f212d6bed9c1b245bcf17b..ce190de6adb72d4db1a7561050f1e84e1aa26366 100644 (file)
@@ -168,7 +168,7 @@ The operating bit rate of the CAN controller is configured using the :cpp:type:`
     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
 
-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 **any even number from 2 to 128**.
+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 **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
     :caption: Bit timing configuration for 500kbit/s given BRP = 8
@@ -183,6 +183,9 @@ The **Synchronization Jump Width** is used to determined the maximum number of t
 
 Bit timing **macro initializers** are also available for commonly used CAN bus bit rates. The following macro initializers 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_50KBITS()``
     - ``CAN_TIMING_CONFIG_100KBITS()``
@@ -192,6 +195,10 @@ Bit timing **macro initializers** are also available for commonly used CAN bus b
     - ``CAN_TIMING_CONFIG_800KBITS()``
     - ``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
 ^^^^^^^^^^^^^^^^^