can_api.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. /* mbed Microcontroller Library
  2. * Copyright (c) 2006-2017 ARM Limited
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "can_api.h"
  17. #if DEVICE_CAN
  18. #include "cmsis.h"
  19. #include "pinmap.h"
  20. #include "PeripheralPins.h"
  21. #include "mbed_error.h"
  22. #include "can_device.h" // Specific to STM32 serie
  23. #include <math.h>
  24. #include <string.h>
  25. static uint32_t can_irq_ids[CAN_NUM] = {0};
  26. static can_irq_handler irq_handler;
  27. static void can_registers_init(can_t *obj)
  28. {
  29. if (HAL_CAN_Init(&obj->CanHandle) != HAL_OK) {
  30. error("Cannot initialize CAN");
  31. }
  32. // Set initial CAN frequency to specified frequency
  33. if (can_frequency(obj, obj->hz) != 1) {
  34. error("Can frequency could not be set\n");
  35. }
  36. }
  37. void can_init(can_t *obj, PinName rd, PinName td)
  38. {
  39. can_init_freq(obj, rd, td, 100000);
  40. }
  41. void can_init_freq(can_t *obj, PinName rd, PinName td, int hz)
  42. {
  43. CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD);
  44. CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD);
  45. CANName can = (CANName)pinmap_merge(can_rd, can_td);
  46. MBED_ASSERT((int)can != NC);
  47. if (can == CAN_1) {
  48. __HAL_RCC_CAN1_CLK_ENABLE();
  49. obj->index = 0;
  50. }
  51. #if defined(CAN2_BASE) && (CAN_NUM > 1)
  52. else if (can == CAN_2) {
  53. __HAL_RCC_CAN1_CLK_ENABLE(); // needed to set filters
  54. __HAL_RCC_CAN2_CLK_ENABLE();
  55. obj->index = 1;
  56. }
  57. #endif
  58. #if defined(CAN3_BASE) && (CAN_NUM > 2)
  59. else if (can == CAN_3) {
  60. __HAL_RCC_CAN3_CLK_ENABLE();
  61. obj->index = 2;
  62. }
  63. #endif
  64. else {
  65. return;
  66. }
  67. // Configure the CAN pins
  68. pinmap_pinout(rd, PinMap_CAN_RD);
  69. pinmap_pinout(td, PinMap_CAN_TD);
  70. if (rd != NC) {
  71. pin_mode(rd, PullUp);
  72. }
  73. if (td != NC) {
  74. pin_mode(td, PullUp);
  75. }
  76. /* Use default values for rist init */
  77. obj->CanHandle.Instance = (CAN_TypeDef *)can;
  78. obj->CanHandle.Init.TTCM = DISABLE;
  79. obj->CanHandle.Init.ABOM = DISABLE;
  80. obj->CanHandle.Init.AWUM = DISABLE;
  81. obj->CanHandle.Init.NART = DISABLE;
  82. obj->CanHandle.Init.RFLM = DISABLE;
  83. obj->CanHandle.Init.TXFP = DISABLE;
  84. obj->CanHandle.Init.Mode = CAN_MODE_NORMAL;
  85. obj->CanHandle.Init.SJW = CAN_SJW_1TQ;
  86. obj->CanHandle.Init.BS1 = CAN_BS1_6TQ;
  87. obj->CanHandle.Init.BS2 = CAN_BS2_8TQ;
  88. obj->CanHandle.Init.Prescaler = 2;
  89. /* Store frequency to be restored in case of reset */
  90. obj->hz = hz;
  91. can_registers_init(obj);
  92. /* Bits 27:14 are available for dual CAN configuration and are reserved for
  93. single CAN configuration: */
  94. #if defined(CAN3_BASE) && (CAN_NUM > 2)
  95. uint32_t filter_number = (can == CAN_1 || can == CAN_3) ? 0 : 14;
  96. #else
  97. uint32_t filter_number = (can == CAN_1) ? 0 : 14;
  98. #endif
  99. can_filter(obj, 0, 0, CANStandard, filter_number);
  100. }
  101. void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
  102. {
  103. irq_handler = handler;
  104. can_irq_ids[obj->index] = id;
  105. }
  106. void can_irq_free(can_t *obj)
  107. {
  108. CAN_TypeDef *can = obj->CanHandle.Instance;
  109. can->IER &= ~(CAN_IT_FMP0 | CAN_IT_FMP1 | CAN_IT_TME | \
  110. CAN_IT_ERR | CAN_IT_EPV | CAN_IT_BOF);
  111. can_irq_ids[obj->index] = 0;
  112. }
  113. void can_free(can_t *obj)
  114. {
  115. CANName can = (CANName) obj->CanHandle.Instance;
  116. // Reset CAN and disable clock
  117. if (can == CAN_1) {
  118. __HAL_RCC_CAN1_FORCE_RESET();
  119. __HAL_RCC_CAN1_RELEASE_RESET();
  120. __HAL_RCC_CAN1_CLK_DISABLE();
  121. }
  122. #if defined(CAN2_BASE) && (CAN_NUM > 1)
  123. if (can == CAN_2) {
  124. __HAL_RCC_CAN2_FORCE_RESET();
  125. __HAL_RCC_CAN2_RELEASE_RESET();
  126. __HAL_RCC_CAN2_CLK_DISABLE();
  127. }
  128. #endif
  129. #if defined(CAN3_BASE) && (CAN_NUM > 2)
  130. if (can == CAN_3) {
  131. __HAL_RCC_CAN3_FORCE_RESET();
  132. __HAL_RCC_CAN3_RELEASE_RESET();
  133. __HAL_RCC_CAN3_CLK_DISABLE();
  134. }
  135. #endif
  136. }
  137. // The following table is used to program bit_timing. It is an adjustment of the sample
  138. // point by synchronizing on the start-bit edge and resynchronizing on the following edges.
  139. // This table has the sampling points as close to 75% as possible (most commonly used).
  140. // The first value is TSEG1, the second TSEG2.
  141. static const int timing_pts[23][2] = {
  142. {0x0, 0x0}, // 2, 50%
  143. {0x1, 0x0}, // 3, 67%
  144. {0x2, 0x0}, // 4, 75%
  145. {0x3, 0x0}, // 5, 80%
  146. {0x3, 0x1}, // 6, 67%
  147. {0x4, 0x1}, // 7, 71%
  148. {0x5, 0x1}, // 8, 75%
  149. {0x6, 0x1}, // 9, 78%
  150. {0x6, 0x2}, // 10, 70%
  151. {0x7, 0x2}, // 11, 73%
  152. {0x8, 0x2}, // 12, 75%
  153. {0x9, 0x2}, // 13, 77%
  154. {0x9, 0x3}, // 14, 71%
  155. {0xA, 0x3}, // 15, 73%
  156. {0xB, 0x3}, // 16, 75%
  157. {0xC, 0x3}, // 17, 76%
  158. {0xD, 0x3}, // 18, 78%
  159. {0xD, 0x4}, // 19, 74%
  160. {0xE, 0x4}, // 20, 75%
  161. {0xF, 0x4}, // 21, 76%
  162. {0xF, 0x5}, // 22, 73%
  163. {0xF, 0x6}, // 23, 70%
  164. {0xF, 0x7}, // 24, 67%
  165. };
  166. static unsigned int can_speed(unsigned int pclk, unsigned int cclk, unsigned char psjw)
  167. {
  168. uint32_t btr;
  169. uint16_t brp = 0;
  170. uint32_t calcbit;
  171. uint32_t bitwidth;
  172. int hit = 0;
  173. int bits;
  174. bitwidth = (pclk / cclk);
  175. brp = bitwidth / 0x18;
  176. while ((!hit) && (brp < bitwidth / 4)) {
  177. brp++;
  178. for (bits = 22; bits > 0; bits--) {
  179. calcbit = (bits + 3) * (brp + 1);
  180. if (calcbit == bitwidth) {
  181. hit = 1;
  182. break;
  183. }
  184. }
  185. }
  186. if (hit) {
  187. btr = ((timing_pts[bits][1] << CAN_BTR_TS2_Pos) & CAN_BTR_TS2) |
  188. ((timing_pts[bits][0] << CAN_BTR_TS1_Pos) & CAN_BTR_TS1) |
  189. ((psjw << CAN_BTR_SJW_Pos) & CAN_BTR_SJW) |
  190. ((brp << CAN_BTR_BRP_Pos) & CAN_BTR_BRP);
  191. } else {
  192. btr = 0xFFFFFFFF;
  193. }
  194. return btr;
  195. }
  196. int can_frequency(can_t *obj, int f)
  197. {
  198. int pclk = HAL_RCC_GetPCLK1Freq();
  199. int btr = can_speed(pclk, (unsigned int)f, 1);
  200. CAN_TypeDef *can = obj->CanHandle.Instance;
  201. uint32_t tickstart = 0;
  202. int status = 1;
  203. if (btr > 0) {
  204. can->MCR |= CAN_MCR_INRQ ;
  205. /* Get tick */
  206. tickstart = HAL_GetTick();
  207. while ((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) {
  208. if ((HAL_GetTick() - tickstart) > 2) {
  209. status = 0;
  210. break;
  211. }
  212. }
  213. if (status != 0) {
  214. /* Do not erase all BTR registers (e.g. silent mode), only the
  215. * ones calculated in can_speed */
  216. can->BTR &= ~(CAN_BTR_TS2 | CAN_BTR_TS1 | CAN_BTR_SJW | CAN_BTR_BRP);
  217. can->BTR |= btr;
  218. can->MCR &= ~(uint32_t)CAN_MCR_INRQ;
  219. /* Get tick */
  220. tickstart = HAL_GetTick();
  221. while ((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) {
  222. if ((HAL_GetTick() - tickstart) > 2) {
  223. status = 0;
  224. break;
  225. }
  226. }
  227. if (status == 0) {
  228. error("can ESR 0x%04x.%04x + timeout status %d", (can->ESR & 0xFFFF0000) >> 16, (can->ESR & 0xFFFF), status);
  229. }
  230. } else {
  231. error("can init request timeout\n");
  232. }
  233. } else {
  234. status = 0;
  235. }
  236. return status;
  237. }
  238. int can_write(can_t *obj, CAN_Message msg, int cc)
  239. {
  240. uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  241. CAN_TypeDef *can = obj->CanHandle.Instance;
  242. /* Select one empty transmit mailbox */
  243. if ((can->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) {
  244. transmitmailbox = 0;
  245. } else if ((can->TSR & CAN_TSR_TME1) == CAN_TSR_TME1) {
  246. transmitmailbox = 1;
  247. } else if ((can->TSR & CAN_TSR_TME2) == CAN_TSR_TME2) {
  248. transmitmailbox = 2;
  249. } else {
  250. return 0;
  251. }
  252. can->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
  253. if (!(msg.format)) {
  254. can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 21) | (msg.type << 1));
  255. } else {
  256. can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 3) | CAN_ID_EXT | (msg.type << 1));
  257. }
  258. /* Set up the DLC */
  259. can->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
  260. can->sTxMailBox[transmitmailbox].TDTR |= (msg.len & (uint8_t)0x0000000F);
  261. /* Set up the data field */
  262. can->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)msg.data[3] << 24) |
  263. ((uint32_t)msg.data[2] << 16) |
  264. ((uint32_t)msg.data[1] << 8) |
  265. ((uint32_t)msg.data[0]));
  266. can->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)msg.data[7] << 24) |
  267. ((uint32_t)msg.data[6] << 16) |
  268. ((uint32_t)msg.data[5] << 8) |
  269. ((uint32_t)msg.data[4]));
  270. /* Request transmission */
  271. can->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
  272. return 1;
  273. }
  274. int can_read(can_t *obj, CAN_Message *msg, int handle)
  275. {
  276. //handle is the FIFO number
  277. CAN_TypeDef *can = obj->CanHandle.Instance;
  278. // check FPM0 which holds the pending message count in FIFO 0
  279. // if no message is pending, return 0
  280. if ((can->RF0R & CAN_RF0R_FMP0) == 0) {
  281. return 0;
  282. }
  283. /* Get the Id */
  284. msg->format = (CANFormat)(((uint8_t)0x04 & can->sFIFOMailBox[handle].RIR) >> 2);
  285. if (!msg->format) {
  286. msg->id = (uint32_t)0x000007FF & (can->sFIFOMailBox[handle].RIR >> 21);
  287. } else {
  288. msg->id = (uint32_t)0x1FFFFFFF & (can->sFIFOMailBox[handle].RIR >> 3);
  289. }
  290. msg->type = (CANType)(((uint8_t)0x02 & can->sFIFOMailBox[handle].RIR) >> 1);
  291. /* Get the DLC */
  292. msg->len = (uint8_t)0x0F & can->sFIFOMailBox[handle].RDTR;
  293. /* Get the FMI */
  294. // msg->FMI = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDTR >> 8);
  295. /* Get the data field */
  296. msg->data[0] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDLR;
  297. msg->data[1] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 8);
  298. msg->data[2] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 16);
  299. msg->data[3] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 24);
  300. msg->data[4] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDHR;
  301. msg->data[5] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 8);
  302. msg->data[6] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 16);
  303. msg->data[7] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 24);
  304. /* Release the FIFO */
  305. if (handle == CAN_FIFO0) {
  306. /* Release FIFO0 */
  307. can->RF0R |= CAN_RF0R_RFOM0;
  308. } else { /* FIFONumber == CAN_FIFO1 */
  309. /* Release FIFO1 */
  310. can->RF1R |= CAN_RF1R_RFOM1;
  311. }
  312. return 1;
  313. }
  314. void can_reset(can_t *obj)
  315. {
  316. CAN_TypeDef *can = obj->CanHandle.Instance;
  317. /* Reset IP and delete errors */
  318. can->MCR |= CAN_MCR_RESET;
  319. can->ESR = 0x0;
  320. /* restore registers state as saved in obj context */
  321. can_registers_init(obj);
  322. }
  323. unsigned char can_rderror(can_t *obj)
  324. {
  325. CAN_TypeDef *can = obj->CanHandle.Instance;
  326. return (can->ESR >> 24) & 0xFF;
  327. }
  328. unsigned char can_tderror(can_t *obj)
  329. {
  330. CAN_TypeDef *can = obj->CanHandle.Instance;
  331. return (can->ESR >> 16) & 0xFF;
  332. }
  333. void can_monitor(can_t *obj, int silent)
  334. {
  335. CanMode mode = MODE_NORMAL;
  336. /* Update current state w/ or w/o silent */
  337. if (silent) {
  338. switch (obj->CanHandle.Init.Mode) {
  339. case CAN_MODE_LOOPBACK:
  340. case CAN_MODE_SILENT_LOOPBACK:
  341. mode = MODE_TEST_SILENT;
  342. break;
  343. default:
  344. mode = MODE_SILENT;
  345. break;
  346. }
  347. } else {
  348. switch (obj->CanHandle.Init.Mode) {
  349. case CAN_MODE_LOOPBACK:
  350. case CAN_MODE_SILENT_LOOPBACK:
  351. mode = MODE_TEST_LOCAL;
  352. break;
  353. default:
  354. mode = MODE_NORMAL;
  355. break;
  356. }
  357. }
  358. can_mode(obj, mode);
  359. }
  360. int can_mode(can_t *obj, CanMode mode)
  361. {
  362. int success = 0;
  363. CAN_TypeDef *can = obj->CanHandle.Instance;
  364. can->MCR |= CAN_MCR_INRQ ;
  365. while ((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) {
  366. }
  367. switch (mode) {
  368. case MODE_NORMAL:
  369. obj->CanHandle.Init.Mode = CAN_MODE_NORMAL;
  370. can->BTR &= ~(CAN_BTR_SILM | CAN_BTR_LBKM);
  371. success = 1;
  372. break;
  373. case MODE_SILENT:
  374. obj->CanHandle.Init.Mode = CAN_MODE_SILENT;
  375. can->BTR |= CAN_BTR_SILM;
  376. can->BTR &= ~CAN_BTR_LBKM;
  377. success = 1;
  378. break;
  379. case MODE_TEST_GLOBAL:
  380. case MODE_TEST_LOCAL:
  381. obj->CanHandle.Init.Mode = CAN_MODE_LOOPBACK;
  382. can->BTR |= CAN_BTR_LBKM;
  383. can->BTR &= ~CAN_BTR_SILM;
  384. success = 1;
  385. break;
  386. case MODE_TEST_SILENT:
  387. obj->CanHandle.Init.Mode = CAN_MODE_SILENT_LOOPBACK;
  388. can->BTR |= (CAN_BTR_SILM | CAN_BTR_LBKM);
  389. success = 1;
  390. break;
  391. default:
  392. success = 0;
  393. break;
  394. }
  395. can->MCR &= ~(uint32_t)CAN_MCR_INRQ;
  396. while ((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) {
  397. }
  398. return success;
  399. }
  400. int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle)
  401. {
  402. int retval = 0;
  403. // filter for CANAny format cannot be configured for STM32
  404. if ((format == CANStandard) || (format == CANExtended)) {
  405. CAN_FilterConfTypeDef sFilterConfig;
  406. sFilterConfig.FilterNumber = handle;
  407. sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  408. sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  409. if (format == CANStandard) {
  410. sFilterConfig.FilterIdHigh = id << 5;
  411. sFilterConfig.FilterIdLow = 0x0;
  412. sFilterConfig.FilterMaskIdHigh = mask << 5;
  413. sFilterConfig.FilterMaskIdLow = 0x0; // allows both remote and data frames
  414. } else { // format == CANExtended
  415. sFilterConfig.FilterIdHigh = id >> 13; // EXTID[28:13]
  416. sFilterConfig.FilterIdLow = (0xFFFF & (id << 3)) | (1 << 2); // EXTID[12:0] + IDE
  417. sFilterConfig.FilterMaskIdHigh = mask >> 13;
  418. sFilterConfig.FilterMaskIdLow = (0xFFFF & (mask << 3)) | (1 << 2);
  419. }
  420. sFilterConfig.FilterFIFOAssignment = 0;
  421. sFilterConfig.FilterActivation = ENABLE;
  422. sFilterConfig.BankNumber = 14 + handle;
  423. HAL_CAN_ConfigFilter(&obj->CanHandle, &sFilterConfig);
  424. retval = handle;
  425. }
  426. return retval;
  427. }
  428. static void can_irq(CANName name, int id)
  429. {
  430. uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0;
  431. CAN_HandleTypeDef CanHandle;
  432. CanHandle.Instance = (CAN_TypeDef *)name;
  433. if (__HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_TME)) {
  434. tmp1 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_0);
  435. tmp2 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_1);
  436. tmp3 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_2);
  437. if (tmp1) {
  438. __HAL_CAN_CLEAR_FLAG(&CanHandle, CAN_FLAG_RQCP0);
  439. }
  440. if (tmp2) {
  441. __HAL_CAN_CLEAR_FLAG(&CanHandle, CAN_FLAG_RQCP1);
  442. }
  443. if (tmp3) {
  444. __HAL_CAN_CLEAR_FLAG(&CanHandle, CAN_FLAG_RQCP2);
  445. }
  446. if (tmp1 || tmp2 || tmp3) {
  447. irq_handler(can_irq_ids[id], IRQ_TX);
  448. }
  449. }
  450. tmp1 = __HAL_CAN_MSG_PENDING(&CanHandle, CAN_FIFO0);
  451. tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_FMP0);
  452. if ((tmp1 != 0) && tmp2) {
  453. irq_handler(can_irq_ids[id], IRQ_RX);
  454. }
  455. tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_EPV);
  456. tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_EPV);
  457. tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR);
  458. if (tmp1 && tmp2 && tmp3) {
  459. irq_handler(can_irq_ids[id], IRQ_PASSIVE);
  460. }
  461. tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_BOF);
  462. tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_BOF);
  463. tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR);
  464. if (tmp1 && tmp2 && tmp3) {
  465. irq_handler(can_irq_ids[id], IRQ_BUS);
  466. }
  467. tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR);
  468. if (tmp1 && tmp2 && tmp3) {
  469. irq_handler(can_irq_ids[id], IRQ_ERROR);
  470. }
  471. }
  472. #if defined(TARGET_STM32F0)
  473. void CAN_IRQHandler(void)
  474. {
  475. can_irq(CAN_1, 0);
  476. }
  477. #elif defined(TARGET_STM32F3)
  478. void CAN_RX0_IRQHandler(void)
  479. {
  480. can_irq(CAN_1, 0);
  481. }
  482. void CAN_TX_IRQHandler(void)
  483. {
  484. can_irq(CAN_1, 0);
  485. }
  486. void CAN_SCE_IRQHandler(void)
  487. {
  488. can_irq(CAN_1, 0);
  489. }
  490. #else
  491. void CAN1_RX0_IRQHandler(void)
  492. {
  493. can_irq(CAN_1, 0);
  494. }
  495. void CAN1_TX_IRQHandler(void)
  496. {
  497. can_irq(CAN_1, 0);
  498. }
  499. void CAN1_SCE_IRQHandler(void)
  500. {
  501. can_irq(CAN_1, 0);
  502. }
  503. #if defined(CAN2_BASE) && (CAN_NUM > 1)
  504. void CAN2_RX0_IRQHandler(void)
  505. {
  506. can_irq(CAN_2, 1);
  507. }
  508. void CAN2_TX_IRQHandler(void)
  509. {
  510. can_irq(CAN_2, 1);
  511. }
  512. void CAN2_SCE_IRQHandler(void)
  513. {
  514. can_irq(CAN_2, 1);
  515. }
  516. #endif
  517. #if defined(CAN3_BASE) && (CAN_NUM > 2)
  518. void CAN3_RX0_IRQHandler(void)
  519. {
  520. can_irq(CAN_3, 2);
  521. }
  522. void CAN3_TX_IRQHandler(void)
  523. {
  524. can_irq(CAN_3, 2);
  525. }
  526. void CAN3_SCE_IRQHandler(void)
  527. {
  528. can_irq(CAN_3, 2);
  529. }
  530. #endif
  531. #endif // else
  532. void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
  533. {
  534. CAN_TypeDef *can = obj->CanHandle.Instance;
  535. IRQn_Type irq_n = (IRQn_Type)0;
  536. uint32_t vector = 0;
  537. uint32_t ier;
  538. if ((CANName) can == CAN_1) {
  539. switch (type) {
  540. case IRQ_RX:
  541. ier = CAN_IT_FMP0;
  542. irq_n = CAN1_IRQ_RX_IRQN;
  543. vector = (uint32_t)&CAN1_IRQ_RX_VECT;
  544. break;
  545. case IRQ_TX:
  546. ier = CAN_IT_TME;
  547. irq_n = CAN1_IRQ_TX_IRQN;
  548. vector = (uint32_t)&CAN1_IRQ_TX_VECT;
  549. break;
  550. case IRQ_ERROR:
  551. ier = CAN_IT_ERR;
  552. irq_n = CAN1_IRQ_ERROR_IRQN;
  553. vector = (uint32_t)&CAN1_IRQ_ERROR_VECT;
  554. break;
  555. case IRQ_PASSIVE:
  556. ier = CAN_IT_EPV;
  557. irq_n = CAN1_IRQ_PASSIVE_IRQN;
  558. vector = (uint32_t)&CAN1_IRQ_PASSIVE_VECT;
  559. break;
  560. case IRQ_BUS:
  561. ier = CAN_IT_BOF;
  562. irq_n = CAN1_IRQ_BUS_IRQN;
  563. vector = (uint32_t)&CAN1_IRQ_BUS_VECT;
  564. break;
  565. default:
  566. return;
  567. }
  568. }
  569. #if defined(CAN2_BASE) && (CAN_NUM > 1)
  570. else if ((CANName) can == CAN_2) {
  571. switch (type) {
  572. case IRQ_RX:
  573. ier = CAN_IT_FMP0;
  574. irq_n = CAN2_IRQ_RX_IRQN;
  575. vector = (uint32_t)&CAN2_IRQ_RX_VECT;
  576. break;
  577. case IRQ_TX:
  578. ier = CAN_IT_TME;
  579. irq_n = CAN2_IRQ_TX_IRQN;
  580. vector = (uint32_t)&CAN2_IRQ_TX_VECT;
  581. break;
  582. case IRQ_ERROR:
  583. ier = CAN_IT_ERR;
  584. irq_n = CAN2_IRQ_ERROR_IRQN;
  585. vector = (uint32_t)&CAN2_IRQ_ERROR_VECT;
  586. break;
  587. case IRQ_PASSIVE:
  588. ier = CAN_IT_EPV;
  589. irq_n = CAN2_IRQ_PASSIVE_IRQN;
  590. vector = (uint32_t)&CAN2_IRQ_PASSIVE_VECT;
  591. break;
  592. case IRQ_BUS:
  593. ier = CAN_IT_BOF;
  594. irq_n = CAN2_IRQ_BUS_IRQN;
  595. vector = (uint32_t)&CAN2_IRQ_BUS_VECT;
  596. break;
  597. default:
  598. return;
  599. }
  600. }
  601. #endif
  602. #if defined(CAN3_BASE) && (CAN_NUM > 2)
  603. else if ((CANName) can == CAN_3) {
  604. switch (type) {
  605. case IRQ_RX:
  606. ier = CAN_IT_FMP0;
  607. irq_n = CAN3_IRQ_RX_IRQN;
  608. vector = (uint32_t)&CAN3_IRQ_RX_VECT;
  609. break;
  610. case IRQ_TX:
  611. ier = CAN_IT_TME;
  612. irq_n = CAN3_IRQ_TX_IRQN;
  613. vector = (uint32_t)&CAN3_IRQ_TX_VECT;
  614. break;
  615. case IRQ_ERROR:
  616. ier = CAN_IT_ERR;
  617. irq_n = CAN3_IRQ_ERROR_IRQN;
  618. vector = (uint32_t)&CAN3_IRQ_ERROR_VECT;
  619. break;
  620. case IRQ_PASSIVE:
  621. ier = CAN_IT_EPV;
  622. irq_n = CAN3_IRQ_PASSIVE_IRQN;
  623. vector = (uint32_t)&CAN3_IRQ_PASSIVE_VECT;
  624. break;
  625. case IRQ_BUS:
  626. ier = CAN_IT_BOF;
  627. irq_n = CAN3_IRQ_BUS_IRQN;
  628. vector = (uint32_t)&CAN3_IRQ_BUS_VECT;
  629. break;
  630. default:
  631. return;
  632. }
  633. }
  634. #endif
  635. else {
  636. return;
  637. }
  638. if (enable) {
  639. can->IER |= ier;
  640. } else {
  641. can->IER &= ~ier;
  642. }
  643. NVIC_SetVector(irq_n, vector);
  644. NVIC_EnableIRQ(irq_n);
  645. }
  646. #endif // DEVICE_CAN