can.c 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116
  1. // Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. #include "freertos/FreeRTOS.h"
  14. #include "freertos/portmacro.h"
  15. #include "freertos/task.h"
  16. #include "freertos/queue.h"
  17. #include "freertos/semphr.h"
  18. #include "esp_types.h"
  19. #include "esp_log.h"
  20. #include "esp_intr_alloc.h"
  21. #include "esp_pm.h"
  22. #include "esp_attr.h"
  23. #include "esp_heap_caps.h"
  24. #include "soc/can_periph.h"
  25. #include "driver/gpio.h"
  26. #include "driver/periph_ctrl.h"
  27. #include "driver/can.h"
  28. /* ---------------------------- Definitions --------------------------------- */
  29. //Internal Macros
  30. #define CAN_CHECK(cond, ret_val) ({ \
  31. if (!(cond)) { \
  32. return (ret_val); \
  33. } \
  34. })
  35. #define CAN_CHECK_FROM_CRIT(cond, ret_val) ({ \
  36. if (!(cond)) { \
  37. CAN_EXIT_CRITICAL(); \
  38. return ret_val; \
  39. } \
  40. })
  41. #define CAN_SET_FLAG(var, mask) ((var) |= (mask))
  42. #define CAN_RESET_FLAG(var, mask) ((var) &= ~(mask))
  43. #ifdef CONFIG_CAN_ISR_IN_IRAM
  44. #define CAN_INLINE_ATTR __attribute__((always_inline))
  45. #define CAN_ISR_ATTR IRAM_ATTR
  46. #define CAN_MALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
  47. #else
  48. #define CAN_INLINE_ATTR
  49. #define CAN_TAG "CAN"
  50. #define CAN_ISR_ATTR
  51. #define CAN_MALLOC_CAPS MALLOC_CAP_DEFAULT
  52. #endif
  53. /*
  54. * Baud Rate Prescaler Divider config/values. The BRP_DIV bit is located in the
  55. * CAN interrupt enable register, and is only available in ESP32 Revision 2 or
  56. * later. Setting this bit will cause the APB clock to be prescaled (divided) by
  57. * a factor 2, before having the BRP applied. This will allow for lower bit rates
  58. * to be achieved.
  59. */
  60. #define BRP_DIV_EN_THRESH 128 //A BRP config value large this this will need to enable brp_div
  61. #define BRP_DIV_EN_BIT 0x10 //Bit mask for brp_div in the interrupt register
  62. //When brp_div is enabled, the BRP config value must be any multiple of 4 between 132 and 256
  63. #define BRP_CHECK_WITH_DIV(brp) ((brp) >= 132 && (brp) <= 256 && ((brp) & 0x3) == 0)
  64. //When brp_div is disabled, the BRP config value must be any even number between 2 to 128
  65. #define BRP_CHECK_NO_DIV(brp) ((brp) >= 2 && (brp) <= 128 && ((brp) & 0x1) == 0)
  66. //Driver default config/values
  67. #define DRIVER_DEFAULT_EWL 96 //Default Error Warning Limit value
  68. #define DRIVER_DEFAULT_TEC 0 //TX Error Counter starting value
  69. #define DRIVER_DEFAULT_REC 0 //RX Error Counter starting value
  70. #define DRIVER_DEFAULT_CLKOUT_DIV 14 //APB CLK divided by two
  71. #define DRIVER_DEFAULT_INTERRUPTS 0xE7 //Exclude data overrun (bit[3]) and brp_div (bit[4])
  72. #define DRIVER_DEFAULT_ERR_PASS_CNT 128 //Error counter threshold for error passive
  73. //Command Bit Masks
  74. #define CMD_TX_REQ 0x01 //Transmission Request
  75. #define CMD_ABORT_TX 0x02 //Abort Transmission
  76. #define CMD_RELEASE_RX_BUFF 0x04 //Release Receive Buffer
  77. #define CMD_CLR_DATA_OVRN 0x08 //Clear Data Overrun
  78. #define CMD_SELF_RX_REQ 0x10 //Self Reception Request
  79. #define CMD_TX_SINGLE_SHOT 0x03 //Single Shot Transmission
  80. #define CMD_SELF_RX_SINGLE_SHOT 0x12 //Single Shot Self Reception
  81. //Control flags
  82. #define CTRL_FLAG_STOPPED 0x001 //CAN peripheral in stopped state
  83. #define CTRL_FLAG_RECOVERING 0x002 //Bus is undergoing bus recovery
  84. #define CTRL_FLAG_ERR_WARN 0x004 //TEC or REC is >= error warning limit
  85. #define CTRL_FLAG_ERR_PASSIVE 0x008 //TEC or REC is >= 128
  86. #define CTRL_FLAG_BUS_OFF 0x010 //Bus-off due to TEC >= 256
  87. #define CTRL_FLAG_TX_BUFF_OCCUPIED 0x020 //Transmit buffer is occupied
  88. #define CTRL_FLAG_SELF_TEST 0x040 //Configured to Self Test Mode
  89. #define CTRL_FLAG_LISTEN_ONLY 0x080 //Configured to Listen Only Mode
  90. //Constants use for frame formatting and parsing
  91. #define FRAME_MAX_LEN 13 //EFF with 8 bytes of data
  92. #define FRAME_MAX_DATA_LEN 8 //Max data bytes allowed in CAN2.0
  93. #define FRAME_EXTD_ID_LEN 4 //EFF ID requires 4 bytes (29bit)
  94. #define FRAME_STD_ID_LEN 2 //SFF ID requires 2 bytes (11bit)
  95. #define FRAME_INFO_LEN 1 //Frame info requires 1 byte
  96. #define ALERT_LOG_LEVEL_WARNING CAN_ALERT_ARB_LOST //Alerts above and including this level use ESP_LOGW
  97. #define ALERT_LOG_LEVEL_ERROR CAN_ALERT_TX_FAILED //Alerts above and including this level use ESP_LOGE
  98. /* ------------------ Typedefs, structures, and variables ------------------- */
  99. /* Formatted frame structure has identical layout as TX/RX buffer registers.
  100. This allows for direct copy to/from TX/RX buffer. The two reserved bits in TX
  101. buffer are used in the frame structure to store the self_reception and
  102. single_shot flags. */
  103. typedef union {
  104. struct {
  105. struct {
  106. uint8_t dlc: 4; //Data length code (0 to 8) of the frame
  107. uint8_t self_reception: 1; //This frame should be transmitted using self reception command
  108. uint8_t single_shot: 1; //This frame should be transmitted using single shot command
  109. uint8_t rtr: 1; //This frame is a remote transmission request
  110. uint8_t frame_format: 1; //Format of the frame (1 = extended, 0 = standard)
  111. };
  112. union {
  113. struct {
  114. uint8_t id[FRAME_STD_ID_LEN]; //11 bit standard frame identifier
  115. uint8_t data[FRAME_MAX_DATA_LEN]; //Data bytes (0 to 8)
  116. uint8_t reserved8[2];
  117. } standard;
  118. struct {
  119. uint8_t id[FRAME_EXTD_ID_LEN]; //29 bit extended frame identifier
  120. uint8_t data[FRAME_MAX_DATA_LEN]; //Data bytes (0 to 8)
  121. } extended;
  122. };
  123. };
  124. uint8_t bytes[FRAME_MAX_LEN];
  125. } can_frame_t;
  126. //Control structure for CAN driver
  127. typedef struct {
  128. //Control and status members
  129. uint32_t control_flags;
  130. uint32_t rx_missed_count;
  131. uint32_t tx_failed_count;
  132. uint32_t arb_lost_count;
  133. uint32_t bus_error_count;
  134. intr_handle_t isr_handle;
  135. //TX and RX
  136. #ifdef CONFIG_CAN_ISR_IN_IRAM
  137. void *tx_queue_buff;
  138. void *tx_queue_struct;
  139. void *rx_queue_buff;
  140. void *rx_queue_struct;
  141. void *semphr_struct;
  142. #endif
  143. QueueHandle_t tx_queue;
  144. QueueHandle_t rx_queue;
  145. int tx_msg_count;
  146. int rx_msg_count;
  147. //Alerts
  148. SemaphoreHandle_t alert_semphr;
  149. uint32_t alerts_enabled;
  150. uint32_t alerts_triggered;
  151. #ifdef CONFIG_PM_ENABLE
  152. //Power Management
  153. esp_pm_lock_handle_t pm_lock;
  154. #endif
  155. } can_obj_t;
  156. static can_obj_t *p_can_obj = NULL;
  157. static portMUX_TYPE can_spinlock = portMUX_INITIALIZER_UNLOCKED;
  158. #define CAN_ENTER_CRITICAL_ISR() portENTER_CRITICAL_ISR(&can_spinlock)
  159. #define CAN_EXIT_CRITICAL_ISR() portEXIT_CRITICAL_ISR(&can_spinlock)
  160. #define CAN_ENTER_CRITICAL() portENTER_CRITICAL(&can_spinlock)
  161. #define CAN_EXIT_CRITICAL() portEXIT_CRITICAL(&can_spinlock)
  162. /* ------------------- Configuration Register Functions---------------------- */
  163. static inline CAN_INLINE_ATTR esp_err_t can_enter_reset_mode()
  164. {
  165. /* Enter reset mode (required to write to configuration registers). Reset mode
  166. also prevents all CAN activity on the current module and is automatically
  167. set upon entering a BUS-OFF condition. */
  168. CAN.mode_reg.reset = 1; //Set reset mode bit
  169. CAN_CHECK(CAN.mode_reg.reset == 1, ESP_ERR_INVALID_STATE); //Check bit was set
  170. return ESP_OK;
  171. }
  172. static inline esp_err_t can_exit_reset_mode()
  173. {
  174. /* Exiting reset mode will return the CAN module to operating mode. Reset mode
  175. must also be exited in order to trigger BUS-OFF recovery sequence. */
  176. CAN.mode_reg.reset = 0; //Exit reset mode
  177. CAN_CHECK(CAN.mode_reg.reset == 0, ESP_ERR_INVALID_STATE); //Check bit was reset
  178. return ESP_OK;
  179. }
  180. static inline void can_config_pelican()
  181. {
  182. //Use PeliCAN address layout. Exposes extra registers
  183. CAN.clock_divider_reg.can_mode = 1;
  184. }
  185. static CAN_ISR_ATTR void can_config_mode(can_mode_t mode)
  186. {
  187. //Configure CAN mode of operation
  188. can_mode_reg_t mode_reg;
  189. mode_reg.val = CAN.mode_reg.val; //Get current value of mode register
  190. if (mode == CAN_MODE_NO_ACK) {
  191. mode_reg.self_test = 1;
  192. mode_reg.listen_only = 0;
  193. } else if (mode == CAN_MODE_LISTEN_ONLY) {
  194. mode_reg.self_test = 0;
  195. mode_reg.listen_only = 1;
  196. } else {
  197. //Default to normal operating mode
  198. mode_reg.self_test = 0;
  199. mode_reg.listen_only = 0;
  200. }
  201. CAN.mode_reg.val = mode_reg.val; //Write back modified value to register
  202. }
  203. static inline void can_config_interrupts(uint32_t interrupts)
  204. {
  205. //Enable interrupt sources
  206. CAN.interrupt_enable_reg.val = interrupts;
  207. }
  208. static inline void can_config_bus_timing(uint32_t brp, uint32_t sjw, uint32_t tseg_1, uint32_t tseg_2, bool triple_sampling)
  209. {
  210. /* Configure bus/bit timing of CAN peripheral.
  211. - BRP (even from 2 to 128) divide APB to CAN system clock (T_scl)
  212. - SJW (1 to 4) is number of T_scl to shorten/lengthen for bit synchronization
  213. - TSEG_1 (1 to 16) is number of T_scl in a bit time before sample point
  214. - TSEG_2 (1 to 8) is number of T_scl in a bit time after sample point
  215. - triple_sampling will cause each bit time to be sampled 3 times */
  216. can_bus_tim_0_reg_t timing_reg_0;
  217. can_bus_tim_1_reg_t timing_reg_1;
  218. timing_reg_0.baud_rate_prescaler = (brp / 2) - 1;
  219. timing_reg_0.sync_jump_width = sjw - 1;
  220. timing_reg_1.time_seg_1 = tseg_1 - 1;
  221. timing_reg_1.time_seg_2 = tseg_2 - 1;
  222. timing_reg_1.sampling = triple_sampling;
  223. CAN.bus_timing_0_reg.val = timing_reg_0.val;
  224. CAN.bus_timing_1_reg.val = timing_reg_1.val;
  225. }
  226. static inline void can_config_error(int err_warn_lim, int rx_err_cnt, int tx_err_cnt)
  227. {
  228. /* Set error warning limit, RX error counter, and TX error counter. Note that
  229. forcibly setting RX/TX error counters will incur the expected status changes
  230. and interrupts as soon as reset mode exits. */
  231. if (err_warn_lim >= 0 && err_warn_lim <= UINT8_MAX) {
  232. //Defaults to 96 after hardware reset.
  233. CAN.error_warning_limit_reg.byte = err_warn_lim;
  234. }
  235. if (rx_err_cnt >= 0 && rx_err_cnt <= UINT8_MAX) {
  236. //Defaults to 0 after hardware reset.
  237. CAN.rx_error_counter_reg.byte = rx_err_cnt;
  238. }
  239. if (tx_err_cnt >= 0 && tx_err_cnt <= UINT8_MAX) {
  240. //Defaults to 0 after hardware reset, and 127 after BUS-OFF event
  241. CAN.tx_error_counter_reg.byte = tx_err_cnt;
  242. }
  243. }
  244. static inline void can_config_acceptance_filter(uint32_t code, uint32_t mask, bool single_filter)
  245. {
  246. //Set filter mode
  247. CAN.mode_reg.acceptance_filter = (single_filter) ? 1 : 0;
  248. //Swap code and mask to match big endian registers
  249. uint32_t code_swapped = __builtin_bswap32(code);
  250. uint32_t mask_swapped = __builtin_bswap32(mask);
  251. for (int i = 0; i < 4; i++) {
  252. CAN.acceptance_filter.code_reg[i].byte = ((code_swapped >> (i * 8)) & 0xFF);
  253. CAN.acceptance_filter.mask_reg[i].byte = ((mask_swapped >> (i * 8)) & 0xFF);
  254. }
  255. }
  256. static inline void can_config_clk_out(uint32_t divider)
  257. {
  258. /* Configure CLKOUT. CLKOUT is a pre-scaled version of APB CLK. Divider can be
  259. 1, or any even number from 2 to 14. Set to out of range value (0) to disable
  260. CLKOUT. */
  261. can_clk_div_reg_t clock_divider_reg;
  262. clock_divider_reg.val = CAN.clock_divider_reg.val;
  263. if (divider >= 2 && divider <= 14) {
  264. clock_divider_reg.clock_off = 0;
  265. clock_divider_reg.clock_divider = (divider / 2) - 1;
  266. } else if (divider == 1) {
  267. clock_divider_reg.clock_off = 0;
  268. clock_divider_reg.clock_divider = 7;
  269. } else {
  270. clock_divider_reg.clock_off = 1;
  271. clock_divider_reg.clock_divider = 0;
  272. }
  273. CAN.clock_divider_reg.val = clock_divider_reg.val;
  274. }
  275. /* ---------------------- Runtime Register Functions------------------------- */
  276. static inline CAN_INLINE_ATTR void can_set_command(uint8_t commands)
  277. {
  278. CAN.command_reg.val = commands;
  279. }
  280. static CAN_ISR_ATTR void can_set_tx_buffer_and_transmit(can_frame_t *frame)
  281. {
  282. //Copy frame structure into TX buffer registers
  283. for (int i = 0; i < FRAME_MAX_LEN; i++) {
  284. CAN.tx_rx_buffer[i].val = frame->bytes[i];
  285. }
  286. //Set correct transmit command
  287. uint8_t command;
  288. if (frame->self_reception) {
  289. command = (frame->single_shot) ? CMD_SELF_RX_SINGLE_SHOT : CMD_SELF_RX_REQ;
  290. } else {
  291. command = (frame->single_shot) ? CMD_TX_SINGLE_SHOT : CMD_TX_REQ;
  292. }
  293. can_set_command(command);
  294. }
  295. static inline CAN_INLINE_ATTR uint32_t can_get_status()
  296. {
  297. return CAN.status_reg.val;
  298. }
  299. static inline CAN_INLINE_ATTR uint32_t can_get_interrupt_reason()
  300. {
  301. return CAN.interrupt_reg.val;
  302. }
  303. static inline CAN_INLINE_ATTR uint32_t can_get_arbitration_lost_capture()
  304. {
  305. return CAN.arbitration_lost_captue_reg.val;
  306. //Todo: ALC read only to re-arm arb lost interrupt. Add function to decode ALC
  307. }
  308. static inline CAN_INLINE_ATTR uint32_t can_get_error_code_capture()
  309. {
  310. return CAN.error_code_capture_reg.val;
  311. //Todo: ECC read only to re-arm bus error interrupt. Add function to decode ECC
  312. }
  313. static inline CAN_INLINE_ATTR void can_get_error_counters(uint32_t *tx_error_cnt, uint32_t *rx_error_cnt)
  314. {
  315. if (tx_error_cnt != NULL) {
  316. *tx_error_cnt = CAN.tx_error_counter_reg.byte;
  317. }
  318. if (rx_error_cnt != NULL) {
  319. *rx_error_cnt = CAN.rx_error_counter_reg.byte;
  320. }
  321. }
  322. static CAN_ISR_ATTR void can_get_rx_buffer_and_clear(can_frame_t *frame)
  323. {
  324. //Copy RX buffer registers into frame structure
  325. for (int i = 0; i < FRAME_MAX_LEN; i++) {
  326. frame->bytes[i] = CAN.tx_rx_buffer[i].val;
  327. }
  328. //Clear RX buffer
  329. can_set_command(CMD_RELEASE_RX_BUFF);
  330. }
  331. static inline CAN_INLINE_ATTR uint32_t can_get_rx_message_counter()
  332. {
  333. return CAN.rx_message_counter_reg.val;
  334. }
  335. /* -------------------- Interrupt and Alert Handlers ------------------------ */
  336. static CAN_ISR_ATTR void can_alert_handler(uint32_t alert_code, int *alert_req)
  337. {
  338. if (p_can_obj->alerts_enabled & alert_code) {
  339. //Signify alert has occurred
  340. CAN_SET_FLAG(p_can_obj->alerts_triggered, alert_code);
  341. *alert_req = 1;
  342. #ifndef CONFIG_CAN_ISR_IN_IRAM //Only log if ISR is not in IRAM
  343. if (p_can_obj->alerts_enabled & CAN_ALERT_AND_LOG) {
  344. if (alert_code >= ALERT_LOG_LEVEL_ERROR) {
  345. ESP_EARLY_LOGE(CAN_TAG, "Alert %d", alert_code);
  346. } else if (alert_code >= ALERT_LOG_LEVEL_WARNING) {
  347. ESP_EARLY_LOGW(CAN_TAG, "Alert %d", alert_code);
  348. } else {
  349. ESP_EARLY_LOGI(CAN_TAG, "Alert %d", alert_code);
  350. }
  351. }
  352. #endif
  353. }
  354. }
  355. static CAN_ISR_ATTR void can_intr_handler_err_warn(can_status_reg_t *status, int *alert_req)
  356. {
  357. if (status->bus) {
  358. if (status->error) {
  359. //Bus-Off condition. TEC should set and held at 127, REC should be 0, reset mode entered
  360. CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_BUS_OFF);
  361. /* Note: REC is still allowed to increase during bus-off. REC > err_warn
  362. can prevent "bus recovery complete" interrupt from occurring. Set to
  363. listen only mode to freeze REC. */
  364. can_config_mode(CAN_MODE_LISTEN_ONLY);
  365. can_alert_handler(CAN_ALERT_BUS_OFF, alert_req);
  366. } else {
  367. //Bus-recovery in progress. TEC has dropped below error warning limit
  368. can_alert_handler(CAN_ALERT_RECOVERY_IN_PROGRESS, alert_req);
  369. }
  370. } else {
  371. if (status->error) {
  372. //TEC or REC surpassed error warning limit
  373. CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_ERR_WARN);
  374. can_alert_handler(CAN_ALERT_ABOVE_ERR_WARN, alert_req);
  375. } else if (p_can_obj->control_flags & CTRL_FLAG_RECOVERING) {
  376. //Bus recovery complete.
  377. esp_err_t err = can_enter_reset_mode();
  378. assert(err == ESP_OK);
  379. //Reset and set flags to the equivalent of the stopped state
  380. CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_RECOVERING | CTRL_FLAG_ERR_WARN |
  381. CTRL_FLAG_ERR_PASSIVE | CTRL_FLAG_BUS_OFF |
  382. CTRL_FLAG_TX_BUFF_OCCUPIED);
  383. CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_STOPPED);
  384. can_alert_handler(CAN_ALERT_BUS_RECOVERED, alert_req);
  385. } else {
  386. //TEC and REC are both below error warning
  387. CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_ERR_WARN);
  388. can_alert_handler(CAN_ALERT_BELOW_ERR_WARN, alert_req);
  389. }
  390. }
  391. }
  392. static inline CAN_INLINE_ATTR void can_intr_handler_err_passive(int *alert_req)
  393. {
  394. uint32_t tec, rec;
  395. can_get_error_counters(&tec, &rec);
  396. if (tec >= DRIVER_DEFAULT_ERR_PASS_CNT || rec >= DRIVER_DEFAULT_ERR_PASS_CNT) {
  397. //Entered error passive
  398. CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_ERR_PASSIVE);
  399. can_alert_handler(CAN_ALERT_ERR_PASS, alert_req);
  400. } else {
  401. //Returned to error active
  402. CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_ERR_PASSIVE);
  403. can_alert_handler(CAN_ALERT_ERR_ACTIVE, alert_req);
  404. }
  405. }
  406. static inline CAN_INLINE_ATTR void can_intr_handler_bus_err(int *alert_req)
  407. {
  408. // ECC register is read to re-arm bus error interrupt. ECC is not used
  409. (void) can_get_error_code_capture();
  410. p_can_obj->bus_error_count++;
  411. can_alert_handler(CAN_ALERT_BUS_ERROR, alert_req);
  412. }
  413. static inline CAN_INLINE_ATTR void can_intr_handler_arb_lost(int *alert_req)
  414. {
  415. //ALC register is read to re-arm arb lost interrupt. ALC is not used
  416. (void) can_get_arbitration_lost_capture();
  417. p_can_obj->arb_lost_count++;
  418. can_alert_handler(CAN_ALERT_ARB_LOST, alert_req);
  419. }
  420. static inline CAN_INLINE_ATTR CAN_ISR_ATTR void can_intr_handler_rx(BaseType_t *task_woken, int *alert_req)
  421. {
  422. can_rx_msg_cnt_reg_t msg_count_reg;
  423. msg_count_reg.val = can_get_rx_message_counter();
  424. for (int i = 0; i < msg_count_reg.rx_message_counter; i++) {
  425. can_frame_t frame;
  426. can_get_rx_buffer_and_clear(&frame);
  427. //Copy frame into RX Queue
  428. if (xQueueSendFromISR(p_can_obj->rx_queue, &frame, task_woken) == pdTRUE) {
  429. p_can_obj->rx_msg_count++;
  430. } else {
  431. p_can_obj->rx_missed_count++;
  432. can_alert_handler(CAN_ALERT_RX_QUEUE_FULL, alert_req);
  433. }
  434. }
  435. //Todo: Add Software Filters
  436. //Todo: Check for data overrun of RX FIFO, then trigger alert
  437. }
  438. static CAN_ISR_ATTR void can_intr_handler_tx(can_status_reg_t *status, int *alert_req)
  439. {
  440. //Handle previously transmitted frame
  441. if (status->tx_complete) {
  442. can_alert_handler(CAN_ALERT_TX_SUCCESS, alert_req);
  443. } else {
  444. p_can_obj->tx_failed_count++;
  445. can_alert_handler(CAN_ALERT_TX_FAILED, alert_req);
  446. }
  447. //Update TX message count
  448. p_can_obj->tx_msg_count--;
  449. assert(p_can_obj->tx_msg_count >= 0); //Sanity check
  450. //Check if there are more frames to transmit
  451. if (p_can_obj->tx_msg_count > 0 && p_can_obj->tx_queue != NULL) {
  452. can_frame_t frame;
  453. int res = xQueueReceiveFromISR(p_can_obj->tx_queue, &frame, NULL);
  454. if (res == pdTRUE) {
  455. can_set_tx_buffer_and_transmit(&frame);
  456. } else {
  457. assert(false && "failed to get a frame from TX queue");
  458. }
  459. } else {
  460. //No more frames to transmit
  461. CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_TX_BUFF_OCCUPIED);
  462. can_alert_handler(CAN_ALERT_TX_IDLE, alert_req);
  463. }
  464. }
  465. static CAN_ISR_ATTR void can_intr_handler_main(void *arg)
  466. {
  467. BaseType_t task_woken = pdFALSE;
  468. int alert_req = 0;
  469. can_status_reg_t status;
  470. can_intr_reg_t intr_reason;
  471. CAN_ENTER_CRITICAL_ISR();
  472. status.val = can_get_status();
  473. intr_reason.val = (p_can_obj != NULL) ? can_get_interrupt_reason() : 0; //Incase intr occurs whilst driver is being uninstalled
  474. #ifdef __clang_analyzer__
  475. if (intr_reason.val == 0) { // Teach clang-tidy that all bitfields are zero if a register is zero; othewise it warns about p_can_obj null dereference
  476. intr_reason.err_warn = intr_reason.err_passive = intr_reason.bus_err = intr_reason.arb_lost = intr_reason.rx = intr_reason.tx = 0;
  477. }
  478. #endif
  479. //Handle error counter related interrupts
  480. if (intr_reason.err_warn) {
  481. //Triggers when Bus-Status or Error-status bits change
  482. can_intr_handler_err_warn(&status, &alert_req);
  483. }
  484. if (intr_reason.err_passive) {
  485. //Triggers when entering/returning error passive/active state
  486. can_intr_handler_err_passive(&alert_req);
  487. }
  488. //Handle other error interrupts
  489. if (intr_reason.bus_err) {
  490. //Triggers when an error (Bit, Stuff, CRC, Form, ACK) occurs on the CAN bus
  491. can_intr_handler_bus_err(&alert_req);
  492. }
  493. if (intr_reason.arb_lost) {
  494. //Triggers when arbitration is lost
  495. can_intr_handler_arb_lost(&alert_req);
  496. }
  497. //Handle TX/RX interrupts
  498. if (intr_reason.rx) {
  499. //Triggers when RX buffer has one or more frames. Disabled if RX Queue length = 0
  500. can_intr_handler_rx(&task_woken, &alert_req);
  501. }
  502. if (intr_reason.tx) {
  503. //Triggers when TX buffer becomes free after a transmission
  504. can_intr_handler_tx(&status, &alert_req);
  505. }
  506. /* Todo: Check possible bug where transmitting self reception request then
  507. clearing rx buffer will cancel the transmission. */
  508. CAN_EXIT_CRITICAL_ISR();
  509. if (p_can_obj->alert_semphr != NULL && alert_req) {
  510. //Give semaphore if alerts were triggered
  511. xSemaphoreGiveFromISR(p_can_obj->alert_semphr, &task_woken);
  512. }
  513. if (task_woken == pdTRUE) {
  514. portYIELD_FROM_ISR();
  515. }
  516. }
  517. /* -------------------------- Helper functions ----------------------------- */
  518. static void can_format_frame(uint32_t id, uint8_t dlc, const uint8_t *data, uint32_t flags, can_frame_t *tx_frame)
  519. {
  520. /* This function encodes a message into a frame structure. The frame structure has
  521. an identical layout to the TX buffer, allowing the frame structure to be directly
  522. copied into TX buffer. */
  523. //Set frame information
  524. tx_frame->dlc = dlc;
  525. tx_frame->rtr = (flags & CAN_MSG_FLAG_RTR) ? 1 : 0;
  526. tx_frame->frame_format = (flags & CAN_MSG_FLAG_EXTD) ? 1 : 0;
  527. tx_frame->self_reception = (flags & CAN_MSG_FLAG_SELF) ? 1 : 0;
  528. tx_frame->single_shot = (flags & CAN_MSG_FLAG_SS) ? 1 : 0;
  529. //Set ID
  530. int id_len = (flags & CAN_MSG_FLAG_EXTD) ? FRAME_EXTD_ID_LEN : FRAME_STD_ID_LEN;
  531. uint8_t *id_buffer = (flags & CAN_MSG_FLAG_EXTD) ? tx_frame->extended.id : tx_frame->standard.id;
  532. //Split ID into 4 or 2 bytes, and turn into big-endian with left alignment (<< 3 or 5)
  533. uint32_t id_temp = (flags & CAN_MSG_FLAG_EXTD) ? __builtin_bswap32((id & CAN_EXTD_ID_MASK) << 3) : //((id << 3) >> 8*(3-i))
  534. __builtin_bswap16((id & CAN_STD_ID_MASK) << 5); //((id << 5) >> 8*(1-i))
  535. for (int i = 0; i < id_len; i++) {
  536. id_buffer[i] = (id_temp >> (8 * i)) & 0xFF; //Copy big-endian ID byte by byte
  537. }
  538. //Set Data.
  539. uint8_t *data_buffer = (flags & CAN_MSG_FLAG_EXTD) ? tx_frame->extended.data : tx_frame->standard.data;
  540. for (int i = 0; (i < dlc) && (i < FRAME_MAX_DATA_LEN); i++) { //Handle case where dlc is > 8
  541. data_buffer[i] = data[i];
  542. }
  543. }
  544. static void can_parse_frame(can_frame_t *rx_frame, uint32_t *id, uint8_t *dlc, uint8_t *data, uint32_t *flags)
  545. {
  546. //This function decodes a frame structure into it's constituent components.
  547. //Copy frame information
  548. *dlc = rx_frame->dlc;
  549. *flags = 0;
  550. *flags |= (rx_frame->dlc > FRAME_MAX_DATA_LEN) ? CAN_MSG_FLAG_DLC_NON_COMP : 0;
  551. *flags |= (rx_frame->rtr) ? CAN_MSG_FLAG_RTR : 0;
  552. *flags |= (rx_frame->frame_format) ? CAN_MSG_FLAG_EXTD : 0;
  553. //Copy ID
  554. int id_len = (rx_frame->frame_format) ? FRAME_EXTD_ID_LEN : FRAME_STD_ID_LEN;
  555. uint8_t *id_buffer = (rx_frame->frame_format) ? rx_frame->extended.id : rx_frame->standard.id;
  556. uint32_t id_temp = 0;
  557. for (int i = 0; i < id_len; i++) {
  558. id_temp |= id_buffer[i] << (8 * i); //Copy big-endian ID byte by byte
  559. }
  560. //Revert endianness of 4 or 2 byte ID, and shift into 29 or 11 bit ID
  561. id_temp = (rx_frame->frame_format) ? (__builtin_bswap32(id_temp) >> 3) : //((byte[i] << 8*(3-i)) >> 3)
  562. (__builtin_bswap16(id_temp) >> 5); //((byte[i] << 8*(1-i)) >> 5)
  563. *id = id_temp & ((rx_frame->frame_format) ? CAN_EXTD_ID_MASK : CAN_STD_ID_MASK);
  564. //Copy data
  565. uint8_t *data_buffer = (rx_frame->frame_format) ? rx_frame->extended.data : rx_frame->standard.data;
  566. for (int i = 0; (i < rx_frame->dlc) && (i < FRAME_MAX_DATA_LEN); i++) {
  567. data[i] = data_buffer[i];
  568. }
  569. //Set remaining bytes of data to 0
  570. for (int i = rx_frame->dlc; i < FRAME_MAX_DATA_LEN; i++) {
  571. data[i] = 0;
  572. }
  573. }
  574. static void can_configure_gpio(gpio_num_t tx, gpio_num_t rx, gpio_num_t clkout, gpio_num_t bus_status)
  575. {
  576. //Set TX pin
  577. gpio_set_pull_mode(tx, GPIO_FLOATING);
  578. gpio_matrix_out(tx, CAN_TX_IDX, false, false);
  579. gpio_pad_select_gpio(tx);
  580. //Set RX pin
  581. gpio_set_pull_mode(rx, GPIO_FLOATING);
  582. gpio_matrix_in(rx, CAN_RX_IDX, false);
  583. gpio_pad_select_gpio(rx);
  584. gpio_set_direction(rx, GPIO_MODE_INPUT);
  585. //Configure output clock pin (Optional)
  586. if (clkout >= 0 && clkout < GPIO_NUM_MAX) {
  587. gpio_set_pull_mode(clkout, GPIO_FLOATING);
  588. gpio_matrix_out(clkout, CAN_CLKOUT_IDX, false, false);
  589. gpio_pad_select_gpio(clkout);
  590. }
  591. //Configure bus status pin (Optional)
  592. if (bus_status >= 0 && bus_status < GPIO_NUM_MAX) {
  593. gpio_set_pull_mode(bus_status, GPIO_FLOATING);
  594. gpio_matrix_out(bus_status, CAN_BUS_OFF_ON_IDX, false, false);
  595. gpio_pad_select_gpio(bus_status);
  596. }
  597. }
  598. static void can_free_driver_obj(can_obj_t *p_obj)
  599. {
  600. //Free driver object and any dependent SW resources it uses (queues, semaphores etc)
  601. #ifdef CONFIG_PM_ENABLE
  602. if (p_obj->pm_lock != NULL) {
  603. ESP_ERROR_CHECK(esp_pm_lock_delete(p_obj->pm_lock));
  604. }
  605. #endif
  606. //Delete queues and semaphores
  607. if (p_obj->tx_queue != NULL) {
  608. vQueueDelete(p_obj->tx_queue);
  609. }
  610. if (p_obj->rx_queue != NULL) {
  611. vQueueDelete(p_obj->rx_queue);
  612. }
  613. if (p_obj->alert_semphr != NULL) {
  614. vSemaphoreDelete(p_obj->alert_semphr);
  615. }
  616. #ifdef CONFIG_CAN_ISR_IN_IRAM
  617. //Free memory used by static queues and semaphores. free() allows freeing NULL pointers
  618. free(p_obj->tx_queue_buff);
  619. free(p_obj->tx_queue_struct);
  620. free(p_obj->rx_queue_buff);
  621. free(p_obj->rx_queue_struct);
  622. free(p_obj->semphr_struct);
  623. #endif //CONFIG_CAN_ISR_IN_IRAM
  624. free(p_obj);
  625. }
  626. static can_obj_t *can_alloc_driver_obj(uint32_t tx_queue_len, uint32_t rx_queue_len)
  627. {
  628. can_obj_t *p_obj = heap_caps_calloc(1, sizeof(can_obj_t), CAN_MALLOC_CAPS);
  629. if (p_obj == NULL) {
  630. return NULL;
  631. }
  632. #ifdef CONFIG_CAN_ISR_IN_IRAM
  633. //Allocate memory for queues and semaphores in DRAM
  634. if (tx_queue_len > 0) {
  635. p_obj->tx_queue_buff = heap_caps_calloc(tx_queue_len, sizeof(can_frame_t), CAN_MALLOC_CAPS);
  636. p_obj->tx_queue_struct = heap_caps_calloc(1, sizeof(StaticQueue_t), CAN_MALLOC_CAPS);
  637. if (p_obj->tx_queue_buff == NULL || p_obj->tx_queue_struct == NULL) {
  638. goto cleanup;
  639. }
  640. }
  641. p_obj->rx_queue_buff = heap_caps_calloc(rx_queue_len, sizeof(can_frame_t), CAN_MALLOC_CAPS);
  642. p_obj->rx_queue_struct = heap_caps_calloc(1, sizeof(StaticQueue_t), CAN_MALLOC_CAPS);
  643. p_obj->semphr_struct = heap_caps_calloc(1, sizeof(StaticSemaphore_t), CAN_MALLOC_CAPS);
  644. if (p_obj->rx_queue_buff == NULL || p_obj->rx_queue_struct == NULL || p_obj->semphr_struct == NULL) {
  645. goto cleanup;
  646. }
  647. //Create static queues and semaphores
  648. if (tx_queue_len > 0) {
  649. p_obj->tx_queue = xQueueCreateStatic(tx_queue_len, sizeof(can_frame_t), p_obj->tx_queue_buff, p_obj->tx_queue_struct);
  650. if (p_obj->tx_queue == NULL) {
  651. goto cleanup;
  652. }
  653. }
  654. p_obj->rx_queue = xQueueCreateStatic(rx_queue_len, sizeof(can_frame_t), p_obj->rx_queue_buff, p_obj->rx_queue_struct);
  655. p_obj->alert_semphr = xSemaphoreCreateBinaryStatic(p_obj->semphr_struct);
  656. if (p_obj->rx_queue == NULL || p_obj->alert_semphr == NULL) {
  657. goto cleanup;
  658. }
  659. #else //CONFIG_CAN_ISR_IN_IRAM
  660. if (tx_queue_len > 0) {
  661. p_obj->tx_queue = xQueueCreate(tx_queue_len, sizeof(can_frame_t));
  662. }
  663. p_obj->rx_queue = xQueueCreate(rx_queue_len, sizeof(can_frame_t));
  664. p_obj->alert_semphr = xSemaphoreCreateBinary();
  665. if ((tx_queue_len > 0 && p_obj->tx_queue == NULL) || p_obj->rx_queue == NULL || p_obj->alert_semphr == NULL) {
  666. goto cleanup;
  667. }
  668. #endif //CONFIG_CAN_ISR_IN_IRAM
  669. #ifdef CONFIG_PM_ENABLE
  670. esp_err_t pm_err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "can", &(p_obj->pm_lock));
  671. if (pm_err != ESP_OK ) {
  672. goto cleanup;
  673. }
  674. #endif
  675. return p_obj;
  676. cleanup:
  677. can_free_driver_obj(p_obj);
  678. return NULL;
  679. }
  680. /* ---------------------------- Public Functions ---------------------------- */
  681. esp_err_t can_driver_install(const can_general_config_t *g_config, const can_timing_config_t *t_config, const can_filter_config_t *f_config)
  682. {
  683. //Check arguments
  684. CAN_CHECK(g_config != NULL, ESP_ERR_INVALID_ARG);
  685. CAN_CHECK(t_config != NULL, ESP_ERR_INVALID_ARG);
  686. CAN_CHECK(f_config != NULL, ESP_ERR_INVALID_ARG);
  687. CAN_CHECK(g_config->rx_queue_len > 0, ESP_ERR_INVALID_ARG);
  688. CAN_CHECK(g_config->tx_io >= 0 && g_config->tx_io < GPIO_NUM_MAX, ESP_ERR_INVALID_ARG);
  689. CAN_CHECK(g_config->rx_io >= 0 && g_config->rx_io < GPIO_NUM_MAX, ESP_ERR_INVALID_ARG);
  690. #if (CONFIG_ESP32_REV_MIN >= 2)
  691. //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
  692. CAN_CHECK(BRP_CHECK_WITH_DIV(t_config->brp) || BRP_CHECK_NO_DIV(t_config->brp), ESP_ERR_INVALID_ARG);
  693. #else
  694. CAN_CHECK(BRP_CHECK_NO_DIV(t_config->brp), ESP_ERR_INVALID_ARG);
  695. #endif
  696. #ifndef CONFIG_CAN_ISR_IN_IRAM
  697. CAN_CHECK(!(g_config->intr_flags & ESP_INTR_FLAG_IRAM), ESP_ERR_INVALID_ARG);
  698. #endif
  699. CAN_ENTER_CRITICAL();
  700. CAN_CHECK_FROM_CRIT(p_can_obj == NULL, ESP_ERR_INVALID_STATE);
  701. CAN_EXIT_CRITICAL();
  702. esp_err_t ret;
  703. can_obj_t *p_can_obj_dummy;
  704. //Create a CAN object (including queues and semaphores)
  705. p_can_obj_dummy = can_alloc_driver_obj(g_config->tx_queue_len, g_config->rx_queue_len);
  706. CAN_CHECK(p_can_obj_dummy != NULL, ESP_ERR_NO_MEM);
  707. //Initialize flags and variables. All other members are already set to zero by can_alloc_driver_obj()
  708. p_can_obj_dummy->control_flags = CTRL_FLAG_STOPPED;
  709. p_can_obj_dummy->control_flags |= (g_config->mode == CAN_MODE_NO_ACK) ? CTRL_FLAG_SELF_TEST : 0;
  710. p_can_obj_dummy->control_flags |= (g_config->mode == CAN_MODE_LISTEN_ONLY) ? CTRL_FLAG_LISTEN_ONLY : 0;
  711. p_can_obj_dummy->alerts_enabled = g_config->alerts_enabled;
  712. //Initialize CAN peripheral registers, and allocate interrupt
  713. CAN_ENTER_CRITICAL();
  714. if (p_can_obj == NULL) {
  715. p_can_obj = p_can_obj_dummy;
  716. } else {
  717. //Check if driver is already installed
  718. CAN_EXIT_CRITICAL();
  719. ret = ESP_ERR_INVALID_STATE;
  720. goto err;
  721. }
  722. periph_module_reset(PERIPH_CAN_MODULE);
  723. periph_module_enable(PERIPH_CAN_MODULE); //Enable APB CLK to CAN peripheral
  724. esp_err_t err = can_enter_reset_mode(); //Must enter reset mode to write to config registers
  725. assert(err == ESP_OK);
  726. can_config_pelican(); //Use PeliCAN addresses
  727. /* Note: REC is allowed to increase even in reset mode. Listen only mode
  728. will freeze REC. The desired mode will be set when can_start() is called. */
  729. can_config_mode(CAN_MODE_LISTEN_ONLY);
  730. #if (CONFIG_ESP32_REV_MIN >= 2)
  731. //If the BRP config value is large enough, the brp_div bit must be enabled to achieve the same effective baud rate prescaler
  732. can_config_interrupts((t_config->brp > BRP_DIV_EN_THRESH) ? DRIVER_DEFAULT_INTERRUPTS | BRP_DIV_EN_BIT : DRIVER_DEFAULT_INTERRUPTS);
  733. 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);
  734. #else
  735. can_config_interrupts(DRIVER_DEFAULT_INTERRUPTS);
  736. can_config_bus_timing(t_config->brp, t_config->sjw, t_config->tseg_1, t_config->tseg_2, t_config->triple_sampling);
  737. #endif
  738. can_config_error(DRIVER_DEFAULT_EWL, DRIVER_DEFAULT_REC, DRIVER_DEFAULT_TEC);
  739. can_config_acceptance_filter(f_config->acceptance_code, f_config->acceptance_mask, f_config->single_filter);
  740. can_config_clk_out(g_config->clkout_divider);
  741. (void) can_get_interrupt_reason(); //Read interrupt reg to clear it before allocating ISR
  742. //Todo: Allow interrupt to be registered to specified CPU
  743. CAN_EXIT_CRITICAL();
  744. //Allocate GPIO and Interrupts
  745. can_configure_gpio(g_config->tx_io, g_config->rx_io, g_config->clkout_io, g_config->bus_off_io);
  746. ESP_ERROR_CHECK(esp_intr_alloc(ETS_CAN_INTR_SOURCE, g_config->intr_flags, can_intr_handler_main, NULL, &p_can_obj->isr_handle));
  747. #ifdef CONFIG_PM_ENABLE
  748. ESP_ERROR_CHECK(esp_pm_lock_acquire(p_can_obj->pm_lock)); //Acquire pm_lock to keep APB clock at 80MHz
  749. #endif
  750. return ESP_OK; //CAN module is still in reset mode, users need to call can_start() afterwards
  751. err:
  752. can_free_driver_obj(p_can_obj_dummy);
  753. return ret;
  754. }
  755. esp_err_t can_driver_uninstall()
  756. {
  757. can_obj_t *p_can_obj_dummy;
  758. CAN_ENTER_CRITICAL();
  759. //Check state
  760. CAN_CHECK_FROM_CRIT(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
  761. CAN_CHECK_FROM_CRIT(p_can_obj->control_flags & (CTRL_FLAG_STOPPED | CTRL_FLAG_BUS_OFF), ESP_ERR_INVALID_STATE);
  762. esp_err_t err = can_enter_reset_mode(); //Enter reset mode to stop any CAN bus activity
  763. assert(err == ESP_OK);
  764. //Clear registers by reading
  765. (void) can_get_interrupt_reason();
  766. (void) can_get_arbitration_lost_capture();
  767. (void) can_get_error_code_capture();
  768. periph_module_disable(PERIPH_CAN_MODULE); //Disable CAN peripheral
  769. p_can_obj_dummy = p_can_obj; //Use dummy to shorten critical section
  770. p_can_obj = NULL;
  771. CAN_EXIT_CRITICAL();
  772. ESP_ERROR_CHECK(esp_intr_free(p_can_obj_dummy->isr_handle)); //Free interrupt
  773. #ifdef CONFIG_PM_ENABLE
  774. //Release and delete power management lock
  775. ESP_ERROR_CHECK(esp_pm_lock_release(p_can_obj_dummy->pm_lock));
  776. #endif
  777. can_free_driver_obj(p_can_obj_dummy);
  778. return ESP_OK;
  779. }
  780. esp_err_t can_start()
  781. {
  782. //Check state
  783. CAN_ENTER_CRITICAL();
  784. CAN_CHECK_FROM_CRIT(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
  785. CAN_CHECK_FROM_CRIT(p_can_obj->control_flags & CTRL_FLAG_STOPPED, ESP_ERR_INVALID_STATE);
  786. //Reset RX queue, and RX message count
  787. xQueueReset(p_can_obj->rx_queue);
  788. p_can_obj->rx_msg_count = 0;
  789. esp_err_t err = can_enter_reset_mode(); //Should already be in bus-off mode, set again to make sure
  790. assert(err == ESP_OK);
  791. //Currently in listen only mode, need to set to mode specified by configuration
  792. can_mode_t mode;
  793. if (p_can_obj->control_flags & CTRL_FLAG_SELF_TEST) {
  794. mode = CAN_MODE_NO_ACK;
  795. } else if (p_can_obj->control_flags & CTRL_FLAG_LISTEN_ONLY) {
  796. mode = CAN_MODE_LISTEN_ONLY;
  797. } else {
  798. mode = CAN_MODE_NORMAL;
  799. }
  800. can_config_mode(mode); //Set mode
  801. (void) can_get_interrupt_reason(); //Clear interrupt register
  802. err = can_exit_reset_mode();
  803. assert(err == ESP_OK);
  804. CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_STOPPED);
  805. CAN_EXIT_CRITICAL();
  806. return ESP_OK;
  807. }
  808. esp_err_t can_stop()
  809. {
  810. //Check state
  811. CAN_ENTER_CRITICAL();
  812. CAN_CHECK_FROM_CRIT(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
  813. CAN_CHECK_FROM_CRIT(!(p_can_obj->control_flags & (CTRL_FLAG_STOPPED | CTRL_FLAG_BUS_OFF)), ESP_ERR_INVALID_STATE);
  814. //Clear interrupts and reset flags
  815. esp_err_t err = can_enter_reset_mode();
  816. assert(err == ESP_OK);
  817. (void) can_get_interrupt_reason(); //Read interrupt register to clear interrupts
  818. can_config_mode(CAN_MODE_LISTEN_ONLY); //Set to listen only mode to freeze REC
  819. CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_TX_BUFF_OCCUPIED);
  820. CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_STOPPED);
  821. //Reset TX Queue and message count
  822. if (p_can_obj->tx_queue != NULL) {
  823. xQueueReset(p_can_obj->tx_queue);
  824. }
  825. p_can_obj->tx_msg_count = 0;
  826. CAN_EXIT_CRITICAL();
  827. return ESP_OK;
  828. }
  829. esp_err_t can_transmit(const can_message_t *message, TickType_t ticks_to_wait)
  830. {
  831. //Check arguments
  832. CAN_CHECK(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
  833. CAN_CHECK(message != NULL, ESP_ERR_INVALID_ARG);
  834. CAN_CHECK((message->data_length_code <= FRAME_MAX_DATA_LEN) || (message->flags & CAN_MSG_FLAG_DLC_NON_COMP), ESP_ERR_INVALID_ARG);
  835. CAN_ENTER_CRITICAL();
  836. //Check State
  837. CAN_CHECK_FROM_CRIT(!(p_can_obj->control_flags & CTRL_FLAG_LISTEN_ONLY), ESP_ERR_NOT_SUPPORTED);
  838. CAN_CHECK_FROM_CRIT(!(p_can_obj->control_flags & (CTRL_FLAG_STOPPED | CTRL_FLAG_BUS_OFF)), ESP_ERR_INVALID_STATE);
  839. //Format frame
  840. esp_err_t ret = ESP_FAIL;
  841. can_frame_t tx_frame;
  842. can_format_frame(message->identifier, message->data_length_code, message->data, message->flags, &tx_frame);
  843. //Check if frame can be sent immediately
  844. if ((p_can_obj->tx_msg_count == 0) && !(p_can_obj->control_flags & CTRL_FLAG_TX_BUFF_OCCUPIED)) {
  845. //No other frames waiting to transmit. Bypass queue and transmit immediately
  846. can_set_tx_buffer_and_transmit(&tx_frame);
  847. p_can_obj->tx_msg_count++;
  848. CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_TX_BUFF_OCCUPIED);
  849. ret = ESP_OK;
  850. }
  851. CAN_EXIT_CRITICAL();
  852. if (ret != ESP_OK) {
  853. if (p_can_obj->tx_queue == NULL) {
  854. //TX Queue is disabled and TX buffer is occupied, message was not sent
  855. ret = ESP_FAIL;
  856. } else if (xQueueSend(p_can_obj->tx_queue, &tx_frame, ticks_to_wait) == pdTRUE) {
  857. //Copied to TX Queue
  858. CAN_ENTER_CRITICAL();
  859. if (p_can_obj->control_flags & (CTRL_FLAG_STOPPED | CTRL_FLAG_BUS_OFF)) {
  860. //TX queue was reset (due to stop/bus_off), remove copied frame from queue to prevent transmission
  861. int res = xQueueReceive(p_can_obj->tx_queue, &tx_frame, 0);
  862. assert(res == pdTRUE);
  863. ret = ESP_ERR_INVALID_STATE;
  864. } else if ((p_can_obj->tx_msg_count == 0) && !(p_can_obj->control_flags & CTRL_FLAG_TX_BUFF_OCCUPIED)) {
  865. //TX buffer was freed during copy, manually trigger transmission
  866. int res = xQueueReceive(p_can_obj->tx_queue, &tx_frame, 0);
  867. assert(res == pdTRUE);
  868. can_set_tx_buffer_and_transmit(&tx_frame);
  869. p_can_obj->tx_msg_count++;
  870. CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_TX_BUFF_OCCUPIED);
  871. ret = ESP_OK;
  872. } else {
  873. //Frame was copied to queue, waiting to be transmitted
  874. p_can_obj->tx_msg_count++;
  875. ret = ESP_OK;
  876. }
  877. CAN_EXIT_CRITICAL();
  878. } else {
  879. //Timed out waiting for free space on TX queue
  880. ret = ESP_ERR_TIMEOUT;
  881. }
  882. }
  883. return ret;
  884. }
  885. esp_err_t can_receive(can_message_t *message, TickType_t ticks_to_wait)
  886. {
  887. //Check arguments and state
  888. CAN_CHECK(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
  889. CAN_CHECK(message != NULL, ESP_ERR_INVALID_ARG);
  890. //Get frame from RX Queue or RX Buffer
  891. can_frame_t rx_frame;
  892. if (xQueueReceive(p_can_obj->rx_queue, &rx_frame, ticks_to_wait) != pdTRUE) {
  893. return ESP_ERR_TIMEOUT;
  894. }
  895. CAN_ENTER_CRITICAL();
  896. p_can_obj->rx_msg_count--;
  897. CAN_EXIT_CRITICAL();
  898. //Decode frame
  899. can_parse_frame(&rx_frame, &(message->identifier), &(message->data_length_code), message->data, &(message->flags));
  900. return ESP_OK;
  901. }
  902. esp_err_t can_read_alerts(uint32_t *alerts, TickType_t ticks_to_wait)
  903. {
  904. //Check arguments and state
  905. CAN_CHECK(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
  906. CAN_CHECK(alerts != NULL, ESP_ERR_INVALID_ARG);
  907. //Wait for an alert to occur
  908. if (xSemaphoreTake(p_can_obj->alert_semphr, ticks_to_wait) == pdTRUE) {
  909. CAN_ENTER_CRITICAL();
  910. *alerts = p_can_obj->alerts_triggered;
  911. p_can_obj->alerts_triggered = 0; //Clear triggered alerts
  912. CAN_EXIT_CRITICAL();
  913. return ESP_OK;
  914. } else {
  915. *alerts = 0;
  916. return ESP_ERR_TIMEOUT;
  917. }
  918. }
  919. esp_err_t can_reconfigure_alerts(uint32_t alerts_enabled, uint32_t *current_alerts)
  920. {
  921. CAN_CHECK(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
  922. CAN_ENTER_CRITICAL();
  923. //Clear any unhandled alerts
  924. if (current_alerts != NULL) {
  925. *current_alerts = p_can_obj->alerts_triggered;;
  926. }
  927. p_can_obj->alerts_triggered = 0;
  928. p_can_obj->alerts_enabled = alerts_enabled; //Update enabled alerts
  929. CAN_EXIT_CRITICAL();
  930. return ESP_OK;
  931. }
  932. esp_err_t can_initiate_recovery()
  933. {
  934. CAN_ENTER_CRITICAL();
  935. //Check state
  936. CAN_CHECK_FROM_CRIT(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
  937. CAN_CHECK_FROM_CRIT(p_can_obj->control_flags & CTRL_FLAG_BUS_OFF, ESP_ERR_INVALID_STATE);
  938. CAN_CHECK_FROM_CRIT(!(p_can_obj->control_flags & CTRL_FLAG_RECOVERING), ESP_ERR_INVALID_STATE);
  939. //Reset TX Queue/Counters
  940. if (p_can_obj->tx_queue != NULL) {
  941. xQueueReset(p_can_obj->tx_queue);
  942. }
  943. p_can_obj->tx_msg_count = 0;
  944. CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_TX_BUFF_OCCUPIED);
  945. CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_RECOVERING);
  946. //Trigger start of recovery process
  947. esp_err_t err = can_exit_reset_mode();
  948. assert(err == ESP_OK);
  949. CAN_EXIT_CRITICAL();
  950. return ESP_OK;
  951. }
  952. esp_err_t can_get_status_info(can_status_info_t *status_info)
  953. {
  954. //Check parameters and state
  955. CAN_CHECK(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
  956. CAN_CHECK(status_info != NULL, ESP_ERR_INVALID_ARG);
  957. CAN_ENTER_CRITICAL();
  958. uint32_t tec, rec;
  959. can_get_error_counters(&tec, &rec);
  960. status_info->tx_error_counter = tec;
  961. status_info->rx_error_counter = rec;
  962. status_info->msgs_to_tx = p_can_obj->tx_msg_count;
  963. status_info->msgs_to_rx = p_can_obj->rx_msg_count;
  964. status_info->tx_failed_count = p_can_obj->tx_failed_count;
  965. status_info->rx_missed_count = p_can_obj->rx_missed_count;
  966. status_info->arb_lost_count = p_can_obj->arb_lost_count;
  967. status_info->bus_error_count = p_can_obj->bus_error_count;
  968. if (p_can_obj->control_flags & CTRL_FLAG_RECOVERING) {
  969. status_info->state = CAN_STATE_RECOVERING;
  970. } else if (p_can_obj->control_flags & CTRL_FLAG_BUS_OFF) {
  971. status_info->state = CAN_STATE_BUS_OFF;
  972. } else if (p_can_obj->control_flags & CTRL_FLAG_STOPPED) {
  973. status_info->state = CAN_STATE_STOPPED;
  974. } else {
  975. status_info->state = CAN_STATE_RUNNING;
  976. }
  977. CAN_EXIT_CRITICAL();
  978. return ESP_OK;
  979. }
  980. esp_err_t can_clear_transmit_queue()
  981. {
  982. //Check State
  983. CAN_CHECK(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
  984. CAN_CHECK(p_can_obj->tx_queue != NULL, ESP_ERR_NOT_SUPPORTED);
  985. CAN_ENTER_CRITICAL();
  986. //If a message is currently undergoing transmission, the tx interrupt handler will decrement tx_msg_count
  987. p_can_obj->tx_msg_count = (p_can_obj->control_flags & CTRL_FLAG_TX_BUFF_OCCUPIED) ? 1 : 0;
  988. xQueueReset(p_can_obj->tx_queue);
  989. CAN_EXIT_CRITICAL();
  990. return ESP_OK;
  991. }
  992. esp_err_t can_clear_receive_queue()
  993. {
  994. //Check State
  995. CAN_CHECK(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
  996. CAN_ENTER_CRITICAL();
  997. p_can_obj->rx_msg_count = 0;
  998. xQueueReset(p_can_obj->rx_queue);
  999. CAN_EXIT_CRITICAL();
  1000. return ESP_OK;
  1001. }