1 /*
2  * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #include <stdint.h>
10 #include <stdbool.h>
11 #include "sdkconfig.h"
12 #include "soc/soc_caps.h"
13 #include "soc/clk_tree_defs.h"
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /**
20  * @brief   TWAI Constants
21  */
22 #define TWAI_EXTD_ID_MASK               0x1FFFFFFF  /**< Bit mask for 29 bit Extended Frame Format ID */
23 #define TWAI_STD_ID_MASK                0x7FF       /**< Bit mask for 11 bit Standard Frame Format ID */
24 #define TWAI_FRAME_MAX_DLC              8           /**< Max data bytes allowed in TWAI */
25 #define TWAI_FRAME_EXTD_ID_LEN_BYTES    4           /**< EFF ID requires 4 bytes (29bit) */
26 #define TWAI_FRAME_STD_ID_LEN_BYTES     2           /**< SFF ID requires 2 bytes (11bit) */
27 #define TWAI_ERR_PASS_THRESH            128         /**< Error counter threshold for error passive */
28 
29 /** @cond */    //Doxy command to hide preprocessor definitions from docs
30 /**
31  * @brief   TWAI Message flags
32  *
33  * The message flags are used to indicate the type of message transmitted/received.
34  * Some flags also specify the type of transmission.
35  */
36 #define TWAI_MSG_FLAG_NONE              0x00        /**< No message flags (Standard Frame Format) */
37 #define TWAI_MSG_FLAG_EXTD              0x01        /**< Extended Frame Format (29bit ID) */
38 #define TWAI_MSG_FLAG_RTR               0x02        /**< Message is a Remote Frame */
39 #define TWAI_MSG_FLAG_SS                0x04        /**< Transmit as a Single Shot Transmission. Unused for received. */
40 #define TWAI_MSG_FLAG_SELF              0x08        /**< Transmit as a Self Reception Request. Unused for received. */
41 #define TWAI_MSG_FLAG_DLC_NON_COMP      0x10        /**< Message's Data length code is larger than 8. This will break compliance with TWAI */
42 
43 #define TWAI_BRP_MAX    SOC_TWAI_BRP_MAX    /**< Maximum configurable BRP value */
44 #define TWAI_BRP_MIN    SOC_TWAI_BRP_MIN    /**< Minimum configurable BRP value */
45 
46 
47 /**
48  * @brief Initializer macros for timing configuration structure
49  *
50  * The following initializer macros offer commonly found bit rates. These macros
51  * place the sample point at 80% or 67% of a bit time.
52  *
53  * @note The available bit rates are dependent on the chip target and ECO version.
54  */
55 #if SOC_TWAI_BRP_MAX > 256
56 #define TWAI_TIMING_CONFIG_1KBITS()     {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 20000, .brp = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
57 #define TWAI_TIMING_CONFIG_5KBITS()     {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 100000, .brp = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
58 #define TWAI_TIMING_CONFIG_10KBITS()    {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 200000, .brp = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
59 #endif // SOC_TWAI_BRP_MAX > 256
60 
61 #if (SOC_TWAI_BRP_MAX > 128) || (CONFIG_ESP32_REV_MIN_FULL >= 200)
62 #define TWAI_TIMING_CONFIG_12_5KBITS()  {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 312500, .brp = 0, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false}
63 #define TWAI_TIMING_CONFIG_16KBITS()    {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 400000, .brp = 0, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false}
64 #define TWAI_TIMING_CONFIG_20KBITS()    {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 400000, .brp = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
65 #endif // (SOC_TWAI_BRP_MAX > 128) || (CONFIG_ESP32_REV_MIN_FULL >= 200)
66 
67 #if CONFIG_XTAL_FREQ == 32   // TWAI_CLK_SRC_XTAL = 32M
68 #define TWAI_TIMING_CONFIG_25KBITS()    {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 400000, .brp = 0, .tseg_1 = 11, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
69 #define TWAI_TIMING_CONFIG_50KBITS()    {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 1000000, .brp = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
70 #define TWAI_TIMING_CONFIG_100KBITS()   {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 2000000, .brp = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
71 #define TWAI_TIMING_CONFIG_125KBITS()   {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 4000000, .brp = 0, .tseg_1 = 23, .tseg_2 = 8, .sjw = 3, .triple_sampling = false}
72 #define TWAI_TIMING_CONFIG_250KBITS()   {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 4000000, .brp = 0, .tseg_1 = 11, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
73 #define TWAI_TIMING_CONFIG_500KBITS()   {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 8000000, .brp = 0, .tseg_1 = 11, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
74 #define TWAI_TIMING_CONFIG_800KBITS()   {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 16000000, .brp = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
75 #define TWAI_TIMING_CONFIG_1MBITS()     {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 16000000, .brp = 0, .tseg_1 = 11, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
76 
77 #elif CONFIG_XTAL_FREQ == 40   // TWAI_CLK_SRC_XTAL = 40M
78 #define TWAI_TIMING_CONFIG_25KBITS()    {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 625000, .brp = 0, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false}
79 #define TWAI_TIMING_CONFIG_50KBITS()    {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 1000000, .brp = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
80 #define TWAI_TIMING_CONFIG_100KBITS()   {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 2000000, .brp = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
81 #define TWAI_TIMING_CONFIG_125KBITS()   {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 2500000, .brp = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
82 #define TWAI_TIMING_CONFIG_250KBITS()   {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 5000000, .brp = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
83 #define TWAI_TIMING_CONFIG_500KBITS()   {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 10000000, .brp = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
84 #define TWAI_TIMING_CONFIG_800KBITS()   {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 20000000, .brp = 0, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false}
85 #define TWAI_TIMING_CONFIG_1MBITS()     {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 20000000, .brp = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}
86 #endif  //CONFIG_XTAL_FREQ
87 
88 /**
89  * @brief   Initializer macro for filter configuration to accept all IDs
90  */
91 #define TWAI_FILTER_CONFIG_ACCEPT_ALL() {.acceptance_code = 0, .acceptance_mask = 0xFFFFFFFF, .single_filter = true}
92 /** @endcond */
93 
94 /**
95  * @brief   TWAI Controller operating modes
96  */
97 typedef enum {
98     TWAI_MODE_NORMAL,               /**< Normal operating mode where TWAI controller can send/receive/acknowledge messages */
99     TWAI_MODE_NO_ACK,               /**< Transmission does not require acknowledgment. Use this mode for self testing */
100     TWAI_MODE_LISTEN_ONLY,          /**< The TWAI controller will not influence the bus (No transmissions or acknowledgments) but can receive messages */
101 } twai_mode_t;
102 
103 /**
104  * @brief   Structure to store a TWAI message
105  *
106  * @note    The flags member is deprecated
107  */
108 typedef struct {
109     union {
110         struct {
111             //The order of these bits must match deprecated message flags for compatibility reasons
112             uint32_t extd: 1;           /**< Extended Frame Format (29bit ID) */
113             uint32_t rtr: 1;            /**< Message is a Remote Frame */
114             uint32_t ss: 1;             /**< Transmit as a Single Shot Transmission. Unused for received. */
115             uint32_t self: 1;           /**< Transmit as a Self Reception Request. Unused for received. */
116             uint32_t dlc_non_comp: 1;   /**< Message's Data length code is larger than 8. This will break compliance with ISO 11898-1 */
117             uint32_t reserved: 27;      /**< Reserved bits */
118         };
119         //Todo: Deprecate flags
120         uint32_t flags;                 /**< Deprecated: Alternate way to set bits using message flags */
121     };
122     uint32_t identifier;                /**< 11 or 29 bit identifier */
123     uint8_t data_length_code;           /**< Data length code */
124     uint8_t data[TWAI_FRAME_MAX_DLC];    /**< Data bytes (not relevant in RTR frame) */
125 } twai_message_t;
126 
127 /**
128  * @brief RMT group clock source
129  * @note User should select the clock source based on the power and resolution requirement
130  */
131 #if SOC_TWAI_SUPPORTED
132 typedef soc_periph_twai_clk_src_t twai_clock_source_t;
133 #else
134 typedef int twai_clock_source_t;
135 #endif
136 
137 /**
138  * @brief   Structure for bit timing configuration of the TWAI driver
139  *
140  * @note    Macro initializers are available for this structure
141  */
142 typedef struct {
143     twai_clock_source_t clk_src;    /**< Clock source, set to 0 or TWAI_CLK_SRC_DEFAULT if you want a default clock source */
144     uint32_t quanta_resolution_hz;  /**< The resolution of one timing quanta, in Hz.
145                                          Note: the value of `brp` will reflected by this field if it's non-zero, otherwise, `brp` needs to be set manually */
146     uint32_t brp;                   /**< Baudrate prescale (i.e., clock divider). Any even number from 2 to 128 for ESP32, 2 to 32768 for non-ESP32 chip.
147                                          Note: For ESP32 ECO 2 or later, multiples of 4 from 132 to 256 are also supported */
148     uint8_t tseg_1;                 /**< Timing segment 1 (Number of time quanta, between 1 to 16) */
149     uint8_t tseg_2;                 /**< Timing segment 2 (Number of time quanta, 1 to 8) */
150     uint8_t sjw;                    /**< Synchronization Jump Width (Max time quanta jump for synchronize from 1 to 4) */
151     bool triple_sampling;           /**< Enables triple sampling when the TWAI controller samples a bit */
152 } twai_timing_config_t;
153 
154 /**
155  * @brief   Structure for acceptance filter configuration of the TWAI driver (see documentation)
156  *
157  * @note    Macro initializers are available for this structure
158  */
159 typedef struct {
160     uint32_t acceptance_code;       /**< 32-bit acceptance code */
161     uint32_t acceptance_mask;       /**< 32-bit acceptance mask */
162     bool single_filter;             /**< Use Single Filter Mode (see documentation) */
163 } twai_filter_config_t;
164 
165 #ifdef __cplusplus
166 }
167 #endif
168