twai.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #pragma once
  7. #ifdef __cplusplus
  8. extern "C" {
  9. #endif
  10. #include "soc/soc_caps.h"
  11. #if SOC_TWAI_SUPPORTED
  12. #include "freertos/FreeRTOS.h"
  13. #include "esp_types.h"
  14. #include "esp_intr_alloc.h"
  15. #include "esp_err.h"
  16. #include "gpio.h"
  17. #include "hal/twai_types.h"
  18. /* -------------------- Default initializers and flags ---------------------- */
  19. /** @cond */ //Doxy command to hide preprocessor definitions from docs
  20. /**
  21. * @brief Initializer macro for general configuration structure.
  22. *
  23. * This initializer macros allows the TX GPIO, RX GPIO, and operating mode to be
  24. * configured. The other members of the general configuration structure are
  25. * assigned default values.
  26. */
  27. #define TWAI_GENERAL_CONFIG_DEFAULT(tx_io_num, rx_io_num, op_mode) {.mode = op_mode, .tx_io = tx_io_num, .rx_io = rx_io_num, \
  28. .clkout_io = TWAI_IO_UNUSED, .bus_off_io = TWAI_IO_UNUSED, \
  29. .tx_queue_len = 5, .rx_queue_len = 5, \
  30. .alerts_enabled = TWAI_ALERT_NONE, .clkout_divider = 0, \
  31. .intr_flags = ESP_INTR_FLAG_LEVEL1}
  32. /**
  33. * @brief Alert flags
  34. *
  35. * The following flags represents the various kind of alerts available in
  36. * the TWAI driver. These flags can be used when configuring/reconfiguring
  37. * alerts, or when calling twai_read_alerts().
  38. *
  39. * @note The TWAI_ALERT_AND_LOG flag is not an actual alert, but will configure
  40. * the TWAI driver to log to UART when an enabled alert occurs.
  41. */
  42. #define TWAI_ALERT_TX_IDLE 0x00000001 /**< Alert(1): No more messages to transmit */
  43. #define TWAI_ALERT_TX_SUCCESS 0x00000002 /**< Alert(2): The previous transmission was successful */
  44. #define TWAI_ALERT_BELOW_ERR_WARN 0x00000004 /**< Alert(4): Both error counters have dropped below error warning limit */
  45. #define TWAI_ALERT_ERR_ACTIVE 0x00000008 /**< Alert(8): TWAI controller has become error active */
  46. #define TWAI_ALERT_RECOVERY_IN_PROGRESS 0x00000010 /**< Alert(16): TWAI controller is undergoing bus recovery */
  47. #define TWAI_ALERT_BUS_RECOVERED 0x00000020 /**< Alert(32): TWAI controller has successfully completed bus recovery */
  48. #define TWAI_ALERT_ARB_LOST 0x00000040 /**< Alert(64): The previous transmission lost arbitration */
  49. #define TWAI_ALERT_ABOVE_ERR_WARN 0x00000080 /**< Alert(128): One of the error counters have exceeded the error warning limit */
  50. #define TWAI_ALERT_BUS_ERROR 0x00000100 /**< Alert(256): A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus */
  51. #define TWAI_ALERT_TX_FAILED 0x00000200 /**< Alert(512): The previous transmission has failed (for single shot transmission) */
  52. #define TWAI_ALERT_RX_QUEUE_FULL 0x00000400 /**< Alert(1024): The RX queue is full causing a frame to be lost */
  53. #define TWAI_ALERT_ERR_PASS 0x00000800 /**< Alert(2048): TWAI controller has become error passive */
  54. #define TWAI_ALERT_BUS_OFF 0x00001000 /**< Alert(4096): Bus-off condition occurred. TWAI controller can no longer influence bus */
  55. #define TWAI_ALERT_RX_FIFO_OVERRUN 0x00002000 /**< Alert(8192): An RX FIFO overrun has occurred */
  56. #define TWAI_ALERT_TX_RETRIED 0x00004000 /**< Alert(16384): An message transmission was cancelled and retried due to an errata workaround */
  57. #define TWAI_ALERT_PERIPH_RESET 0x00008000 /**< Alert(32768): The TWAI controller was reset */
  58. #define TWAI_ALERT_ALL 0x0000FFFF /**< Bit mask to enable all alerts during configuration */
  59. #define TWAI_ALERT_NONE 0x00000000 /**< Bit mask to disable all alerts during configuration */
  60. #define TWAI_ALERT_AND_LOG 0x00010000 /**< Bit mask to enable alerts to also be logged when they occur. Note that logging from the ISR is disabled if CONFIG_TWAI_ISR_IN_IRAM is enabled (see docs). */
  61. /** @endcond */
  62. #define TWAI_IO_UNUSED ((gpio_num_t) -1) /**< Marks GPIO as unused in TWAI configuration */
  63. /* ----------------------- Enum and Struct Definitions ---------------------- */
  64. /**
  65. * @brief TWAI driver states
  66. */
  67. typedef enum {
  68. TWAI_STATE_STOPPED, /**< Stopped state. The TWAI controller will not participate in any TWAI bus activities */
  69. TWAI_STATE_RUNNING, /**< Running state. The TWAI controller can transmit and receive messages */
  70. TWAI_STATE_BUS_OFF, /**< Bus-off state. The TWAI controller cannot participate in bus activities until it has recovered */
  71. TWAI_STATE_RECOVERING, /**< Recovering state. The TWAI controller is undergoing bus recovery */
  72. } twai_state_t;
  73. /**
  74. * @brief Structure for general configuration of the TWAI driver
  75. *
  76. * @note Macro initializers are available for this structure
  77. */
  78. typedef struct {
  79. twai_mode_t mode; /**< Mode of TWAI controller */
  80. gpio_num_t tx_io; /**< Transmit GPIO number */
  81. gpio_num_t rx_io; /**< Receive GPIO number */
  82. gpio_num_t clkout_io; /**< CLKOUT GPIO number (optional, set to -1 if unused) */
  83. gpio_num_t bus_off_io; /**< Bus off indicator GPIO number (optional, set to -1 if unused) */
  84. uint32_t tx_queue_len; /**< Number of messages TX queue can hold (set to 0 to disable TX Queue) */
  85. uint32_t rx_queue_len; /**< Number of messages RX queue can hold */
  86. uint32_t alerts_enabled; /**< Bit field of alerts to enable (see documentation) */
  87. uint32_t clkout_divider; /**< CLKOUT divider. Can be 1 or any even number from 2 to 14 (optional, set to 0 if unused) */
  88. int intr_flags; /**< Interrupt flags to set the priority of the driver's ISR. Note that to use the ESP_INTR_FLAG_IRAM, the CONFIG_TWAI_ISR_IN_IRAM option should be enabled first. */
  89. } twai_general_config_t;
  90. /**
  91. * @brief Structure to store status information of TWAI driver
  92. */
  93. typedef struct {
  94. twai_state_t state; /**< Current state of TWAI controller (Stopped/Running/Bus-Off/Recovery) */
  95. uint32_t msgs_to_tx; /**< Number of messages queued for transmission or awaiting transmission completion */
  96. uint32_t msgs_to_rx; /**< Number of messages in RX queue waiting to be read */
  97. uint32_t tx_error_counter; /**< Current value of Transmit Error Counter */
  98. uint32_t rx_error_counter; /**< Current value of Receive Error Counter */
  99. uint32_t tx_failed_count; /**< Number of messages that failed transmissions */
  100. uint32_t rx_missed_count; /**< Number of messages that were lost due to a full RX queue (or errata workaround if enabled) */
  101. uint32_t rx_overrun_count; /**< Number of messages that were lost due to a RX FIFO overrun */
  102. uint32_t arb_lost_count; /**< Number of instances arbitration was lost */
  103. uint32_t bus_error_count; /**< Number of instances a bus error has occurred */
  104. } twai_status_info_t;
  105. /* ------------------------------ Public API -------------------------------- */
  106. /**
  107. * @brief Install TWAI driver
  108. *
  109. * This function installs the TWAI driver using three configuration structures.
  110. * The required memory is allocated and the TWAI driver is placed in the stopped
  111. * state after running this function.
  112. *
  113. * @param[in] g_config General configuration structure
  114. * @param[in] t_config Timing configuration structure
  115. * @param[in] f_config Filter configuration structure
  116. *
  117. * @note Macro initializers are available for the configuration structures (see documentation)
  118. *
  119. * @note To reinstall the TWAI driver, call twai_driver_uninstall() first
  120. *
  121. * @return
  122. * - ESP_OK: Successfully installed TWAI driver
  123. * - ESP_ERR_INVALID_ARG: Arguments are invalid
  124. * - ESP_ERR_NO_MEM: Insufficient memory
  125. * - ESP_ERR_INVALID_STATE: Driver is already installed
  126. */
  127. esp_err_t twai_driver_install(const twai_general_config_t *g_config, const twai_timing_config_t *t_config, const twai_filter_config_t *f_config);
  128. /**
  129. * @brief Uninstall the TWAI driver
  130. *
  131. * This function uninstalls the TWAI driver, freeing the memory utilized by the
  132. * driver. This function can only be called when the driver is in the stopped
  133. * state or the bus-off state.
  134. *
  135. * @warning The application must ensure that no tasks are blocked on TX/RX
  136. * queues or alerts when this function is called.
  137. *
  138. * @return
  139. * - ESP_OK: Successfully uninstalled TWAI driver
  140. * - ESP_ERR_INVALID_STATE: Driver is not in stopped/bus-off state, or is not installed
  141. */
  142. esp_err_t twai_driver_uninstall(void);
  143. /**
  144. * @brief Start the TWAI driver
  145. *
  146. * This function starts the TWAI driver, putting the TWAI driver into the running
  147. * state. This allows the TWAI driver to participate in TWAI bus activities such
  148. * as transmitting/receiving messages. The TX and RX queue are reset in this function,
  149. * clearing any messages that are unread or pending transmission. This function
  150. * can only be called when the TWAI driver is in the stopped state.
  151. *
  152. * @return
  153. * - ESP_OK: TWAI driver is now running
  154. * - ESP_ERR_INVALID_STATE: Driver is not in stopped state, or is not installed
  155. */
  156. esp_err_t twai_start(void);
  157. /**
  158. * @brief Stop the TWAI driver
  159. *
  160. * This function stops the TWAI driver, preventing any further message from being
  161. * transmitted or received until twai_start() is called. Any messages in the TX
  162. * queue are cleared. Any messages in the RX queue should be read by the
  163. * application after this function is called. This function can only be called
  164. * when the TWAI driver is in the running state.
  165. *
  166. * @warning A message currently being transmitted/received on the TWAI bus will
  167. * be ceased immediately. This may lead to other TWAI nodes interpreting
  168. * the unfinished message as an error.
  169. *
  170. * @return
  171. * - ESP_OK: TWAI driver is now Stopped
  172. * - ESP_ERR_INVALID_STATE: Driver is not in running state, or is not installed
  173. */
  174. esp_err_t twai_stop(void);
  175. /**
  176. * @brief Transmit a TWAI message
  177. *
  178. * This function queues a TWAI message for transmission. Transmission will start
  179. * immediately if no other messages are queued for transmission. If the TX queue
  180. * is full, this function will block until more space becomes available or until
  181. * it times out. If the TX queue is disabled (TX queue length = 0 in configuration),
  182. * this function will return immediately if another message is undergoing
  183. * transmission. This function can only be called when the TWAI driver is in the
  184. * running state and cannot be called under Listen Only Mode.
  185. *
  186. * @param[in] message Message to transmit
  187. * @param[in] ticks_to_wait Number of FreeRTOS ticks to block on the TX queue
  188. *
  189. * @note This function does not guarantee that the transmission is successful.
  190. * The TX_SUCCESS/TX_FAILED alert can be enabled to alert the application
  191. * upon the success/failure of a transmission.
  192. *
  193. * @note The TX_IDLE alert can be used to alert the application when no other
  194. * messages are awaiting transmission.
  195. *
  196. * @return
  197. * - ESP_OK: Transmission successfully queued/initiated
  198. * - ESP_ERR_INVALID_ARG: Arguments are invalid
  199. * - ESP_ERR_TIMEOUT: Timed out waiting for space on TX queue
  200. * - ESP_FAIL: TX queue is disabled and another message is currently transmitting
  201. * - ESP_ERR_INVALID_STATE: TWAI driver is not in running state, or is not installed
  202. * - ESP_ERR_NOT_SUPPORTED: Listen Only Mode does not support transmissions
  203. */
  204. esp_err_t twai_transmit(const twai_message_t *message, TickType_t ticks_to_wait);
  205. /**
  206. * @brief Receive a TWAI message
  207. *
  208. * This function receives a message from the RX queue. The flags field of the
  209. * message structure will indicate the type of message received. This function
  210. * will block if there are no messages in the RX queue
  211. *
  212. * @param[out] message Received message
  213. * @param[in] ticks_to_wait Number of FreeRTOS ticks to block on RX queue
  214. *
  215. * @warning The flags field of the received message should be checked to determine
  216. * if the received message contains any data bytes.
  217. *
  218. * @return
  219. * - ESP_OK: Message successfully received from RX queue
  220. * - ESP_ERR_TIMEOUT: Timed out waiting for message
  221. * - ESP_ERR_INVALID_ARG: Arguments are invalid
  222. * - ESP_ERR_INVALID_STATE: TWAI driver is not installed
  223. */
  224. esp_err_t twai_receive(twai_message_t *message, TickType_t ticks_to_wait);
  225. /**
  226. * @brief Read TWAI driver alerts
  227. *
  228. * This function will read the alerts raised by the TWAI driver. If no alert has
  229. * been issued when this function is called, this function will block until an alert
  230. * occurs or until it timeouts.
  231. *
  232. * @param[out] alerts Bit field of raised alerts (see documentation for alert flags)
  233. * @param[in] ticks_to_wait Number of FreeRTOS ticks to block for alert
  234. *
  235. * @note Multiple alerts can be raised simultaneously. The application should
  236. * check for all alerts that have been enabled.
  237. *
  238. * @return
  239. * - ESP_OK: Alerts read
  240. * - ESP_ERR_TIMEOUT: Timed out waiting for alerts
  241. * - ESP_ERR_INVALID_ARG: Arguments are invalid
  242. * - ESP_ERR_INVALID_STATE: TWAI driver is not installed
  243. */
  244. esp_err_t twai_read_alerts(uint32_t *alerts, TickType_t ticks_to_wait);
  245. /**
  246. * @brief Reconfigure which alerts are enabled
  247. *
  248. * This function reconfigures which alerts are enabled. If there are alerts
  249. * which have not been read whilst reconfiguring, this function can read those
  250. * alerts.
  251. *
  252. * @param[in] alerts_enabled Bit field of alerts to enable (see documentation for alert flags)
  253. * @param[out] current_alerts Bit field of currently raised alerts. Set to NULL if unused
  254. *
  255. * @return
  256. * - ESP_OK: Alerts reconfigured
  257. * - ESP_ERR_INVALID_STATE: TWAI driver is not installed
  258. */
  259. esp_err_t twai_reconfigure_alerts(uint32_t alerts_enabled, uint32_t *current_alerts);
  260. /**
  261. * @brief Start the bus recovery process
  262. *
  263. * This function initiates the bus recovery process when the TWAI driver is in
  264. * the bus-off state. Once initiated, the TWAI driver will enter the recovering
  265. * state and wait for 128 occurrences of the bus-free signal on the TWAI bus
  266. * before returning to the stopped state. This function will reset the TX queue,
  267. * clearing any messages pending transmission.
  268. *
  269. * @note The BUS_RECOVERED alert can be enabled to alert the application when
  270. * the bus recovery process completes.
  271. *
  272. * @return
  273. * - ESP_OK: Bus recovery started
  274. * - ESP_ERR_INVALID_STATE: TWAI driver is not in the bus-off state, or is not installed
  275. */
  276. esp_err_t twai_initiate_recovery(void);
  277. /**
  278. * @brief Get current status information of the TWAI driver
  279. *
  280. * @param[out] status_info Status information
  281. *
  282. * @return
  283. * - ESP_OK: Status information retrieved
  284. * - ESP_ERR_INVALID_ARG: Arguments are invalid
  285. * - ESP_ERR_INVALID_STATE: TWAI driver is not installed
  286. */
  287. esp_err_t twai_get_status_info(twai_status_info_t *status_info);
  288. /**
  289. * @brief Clear the transmit queue
  290. *
  291. * This function will clear the transmit queue of all messages.
  292. *
  293. * @note The transmit queue is automatically cleared when twai_stop() or
  294. * twai_initiate_recovery() is called.
  295. *
  296. * @return
  297. * - ESP_OK: Transmit queue cleared
  298. * - ESP_ERR_INVALID_STATE: TWAI driver is not installed or TX queue is disabled
  299. */
  300. esp_err_t twai_clear_transmit_queue(void);
  301. /**
  302. * @brief Clear the receive queue
  303. *
  304. * This function will clear the receive queue of all messages.
  305. *
  306. * @note The receive queue is automatically cleared when twai_start() is
  307. * called.
  308. *
  309. * @return
  310. * - ESP_OK: Transmit queue cleared
  311. * - ESP_ERR_INVALID_STATE: TWAI driver is not installed
  312. */
  313. esp_err_t twai_clear_receive_queue(void);
  314. #ifdef __cplusplus
  315. }
  316. #endif
  317. #endif //SOC_TWAI_SUPPORTED