can.c 44 KB

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