can.c 40 KB

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