at32f413_can.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150
  1. /**
  2. **************************************************************************
  3. * @file at32f413_can.c
  4. * @brief contains all the functions for the can firmware library
  5. **************************************************************************
  6. * Copyright notice & Disclaimer
  7. *
  8. * The software Board Support Package (BSP) that is made available to
  9. * download from Artery official website is the copyrighted work of Artery.
  10. * Artery authorizes customers to use, copy, and distribute the BSP
  11. * software and its related documentation for the purpose of design and
  12. * development in conjunction with Artery microcontrollers. Use of the
  13. * software is governed by this copyright notice and the following disclaimer.
  14. *
  15. * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
  16. * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
  17. * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
  18. * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
  19. * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
  21. *
  22. **************************************************************************
  23. */
  24. #include "at32f413_conf.h"
  25. /** @addtogroup AT32F413_periph_driver
  26. * @{
  27. */
  28. /** @defgroup CAN
  29. * @brief CAN driver modules
  30. * @{
  31. */
  32. #ifdef CAN_MODULE_ENABLED
  33. /** @defgroup CAN_private_functions
  34. * @{
  35. */
  36. /**
  37. * @brief deinitialize the can peripheral registers to their default reset values.
  38. * @param can_x: select the can peripheral.
  39. * this parameter can be one of the following values:
  40. * CAN1,CAN2.
  41. * @retval none.
  42. */
  43. void can_reset(can_type* can_x)
  44. {
  45. if(can_x == CAN1)
  46. {
  47. crm_periph_reset(CRM_CAN1_PERIPH_RESET, TRUE);
  48. crm_periph_reset(CRM_CAN1_PERIPH_RESET, FALSE);
  49. }
  50. #if defined (AT32F413TBU7) || defined (AT32F413Rx) || defined (AT32F413Cx) || \
  51. defined (AT32F413Kx)
  52. else if(can_x == CAN2)
  53. {
  54. crm_periph_reset(CRM_CAN2_PERIPH_RESET, TRUE);
  55. crm_periph_reset(CRM_CAN2_PERIPH_RESET, FALSE);
  56. }
  57. #endif
  58. }
  59. /**
  60. * @brief fill each can_baudrate_struct member with its default value.
  61. * @param can_baudrate_struct: pointer to a can_baudrate_type structure which will be initialized.
  62. * @retval none.
  63. */
  64. void can_baudrate_default_para_init(can_baudrate_type* can_baudrate_struct)
  65. {
  66. /* reset can baudrate structure parameters values */
  67. /* baud rate division */
  68. can_baudrate_struct->baudrate_div = 1;
  69. /* resynchronization adjust width */
  70. can_baudrate_struct->rsaw_size = CAN_RSAW_2TQ;
  71. /* bit time segment 1 */
  72. can_baudrate_struct->bts1_size = CAN_BTS1_4TQ;
  73. /* bit time segment 2 */
  74. can_baudrate_struct->bts2_size = CAN_BTS2_3TQ;
  75. }
  76. /**
  77. * @brief set the baudrate of the can peripheral
  78. * @param can_x: select the can peripheral.
  79. * this parameter can be one of the following values:
  80. * CAN1,CAN2.
  81. * @param can_baudrate_struct: pointer to a can_baudrate_type structure which will be set.
  82. * @note baudrate calculate method is:
  83. * baudrate = fpclk/(baudrate_div *(3 + bts1_size + bts2_size))
  84. * @retval the result of baudrate set
  85. * this parameter can be one of the following values:
  86. * SUCCESS or ERROR
  87. */
  88. error_status can_baudrate_set(can_type* can_x, can_baudrate_type* can_baudrate_struct)
  89. {
  90. error_status status_index = ERROR;
  91. uint32_t wait_ack_index = 0x00000000;
  92. /* exit from doze mode */
  93. can_x->mctrl_bit.dzen = FALSE;
  94. /* request freeze mode */
  95. can_x->mctrl_bit.fzen = TRUE;
  96. /* wait the acknowledge */
  97. while((!can_x->msts_bit.fzc) && (wait_ack_index != FZC_TIMEOUT))
  98. {
  99. wait_ack_index++;
  100. }
  101. /* check acknowledge */
  102. if(can_x->msts_bit.fzc)
  103. {
  104. can_x->btmg_bit.brdiv = can_baudrate_struct->baudrate_div - 1;
  105. can_x->btmg_bit.rsaw = can_baudrate_struct->rsaw_size;
  106. can_x->btmg_bit.bts1 = can_baudrate_struct->bts1_size;
  107. can_x->btmg_bit.bts2 = can_baudrate_struct->bts2_size;
  108. /* request leave freeze mode */
  109. can_x->mctrl_bit.fzen = FALSE;
  110. /* wait the acknowledge */
  111. wait_ack_index = 0;
  112. while((can_x->msts_bit.fzc) && (wait_ack_index != FZC_TIMEOUT))
  113. {
  114. wait_ack_index++;
  115. }
  116. /* check acknowledged */
  117. if(can_x->msts_bit.fzc)
  118. {
  119. status_index = ERROR;
  120. }
  121. else
  122. {
  123. status_index = SUCCESS ;
  124. }
  125. }
  126. else
  127. {
  128. status_index = ERROR;
  129. }
  130. /* return the status of baudrate set */
  131. return status_index;
  132. }
  133. /**
  134. * @brief fill each can_init_struct member with its default value.
  135. * @param can_base_struct: pointer to a can_base_type structure which will be initialized.
  136. * @retval none.
  137. */
  138. void can_default_para_init(can_base_type* can_base_struct)
  139. {
  140. /* reset can init structure parameters values */
  141. /* initialize the time triggered communication mode */
  142. can_base_struct->ttc_enable = FALSE;
  143. /* initialize the automatic exit bus-off management */
  144. can_base_struct->aebo_enable = FALSE;
  145. /* initialize the automatic exit doze mode */
  146. can_base_struct->aed_enable = FALSE;
  147. /* initialize the prohibit retransmission when sending fails */
  148. can_base_struct->prsf_enable = FALSE;
  149. /* initialize the message discarding rule select when overflow */
  150. can_base_struct->mdrsel_selection = CAN_DISCARDING_FIRST_RECEIVED;
  151. /* initialize the multiple message sending sequence rule */
  152. can_base_struct->mmssr_selection = CAN_SENDING_BY_ID;
  153. /* initialize the can_mode */
  154. can_base_struct->mode_selection = CAN_MODE_COMMUNICATE;
  155. }
  156. /**
  157. * @brief initialize the can peripheral according to the specified
  158. * parameters in the can_init_struct.
  159. * @param can_x: select the can peripheral.
  160. * this parameter can be one of the following values:
  161. * CAN1,CAN2.
  162. * @param can_base_struct: pointer to a can_base_struct structure that contains the configuration information for the can peripheral.
  163. * @retval the status of initialization
  164. * this parameter can be one of the following values:
  165. * SUCCESS or ERROR
  166. */
  167. error_status can_base_init(can_type* can_x, can_base_type* can_base_struct)
  168. {
  169. error_status init_status_index = ERROR;
  170. uint32_t wait_ack_index = 0x00000000;
  171. /* exit from doze mode */
  172. can_x->mctrl_bit.dzen = FALSE;
  173. /* request freeze mode */
  174. can_x->mctrl_bit.fzen = TRUE;
  175. /* wait the acknowledge */
  176. while((!can_x->msts_bit.fzc) && (wait_ack_index != FZC_TIMEOUT))
  177. {
  178. wait_ack_index++;
  179. }
  180. /* check acknowledge */
  181. if(can_x->msts_bit.fzc)
  182. {
  183. /* set the time triggered communication mode */
  184. can_x->mctrl_bit.ttcen = can_base_struct->ttc_enable;
  185. /* set the automatic exit bus-off management */
  186. can_x->mctrl_bit.aeboen = can_base_struct->aebo_enable;
  187. /* set the automatic automatic exit doze mode */
  188. can_x->mctrl_bit.aeden = can_base_struct->aed_enable;
  189. /* set the prohibit retransmission when sending fails */
  190. can_x->mctrl_bit.prsfen = can_base_struct->prsf_enable;
  191. /* set the message discarding rule select when overflow */
  192. can_x->mctrl_bit.mdrsel = can_base_struct->mdrsel_selection;
  193. /* set the multiple message sending sequence rule */
  194. can_x->mctrl_bit.mmssr = can_base_struct->mmssr_selection;
  195. /* set the test mode */
  196. can_x->btmg_bit.lben = can_base_struct->mode_selection & 0x01;
  197. can_x->btmg_bit.loen = (can_base_struct->mode_selection >> 1) & 0x01;
  198. /* request leave freeze mode */
  199. can_x->mctrl_bit.fzen = FALSE;
  200. /* wait the acknowledge */
  201. wait_ack_index = 0;
  202. while((can_x->msts_bit.fzc) && (wait_ack_index != FZC_TIMEOUT))
  203. {
  204. wait_ack_index++;
  205. }
  206. /* check acknowledged */
  207. if(can_x->msts_bit.fzc)
  208. {
  209. init_status_index = ERROR;
  210. }
  211. else
  212. {
  213. init_status_index = SUCCESS ;
  214. }
  215. }
  216. else
  217. {
  218. init_status_index = ERROR;
  219. }
  220. /* return the status of initialization */
  221. return init_status_index;
  222. }
  223. /**
  224. * @brief fill each can_filter_init_struct member with its default value.
  225. * @param can_filter_init_struct: pointer to a can_filter_init_type structure which will be initialized.
  226. * @retval none.
  227. */
  228. void can_filter_default_para_init(can_filter_init_type* can_filter_init_struct)
  229. {
  230. /* reset can filter init structure parameters values */
  231. /* initialize the filter activate state */
  232. can_filter_init_struct->filter_activate_enable = FALSE;
  233. /* filter mode */
  234. can_filter_init_struct->filter_mode = CAN_FILTER_MODE_ID_MASK;
  235. /* filter relation fifo select */
  236. can_filter_init_struct->filter_fifo = CAN_FILTER_FIFO0;
  237. /* filter number select */
  238. can_filter_init_struct->filter_number = 0;
  239. /* initialize the filter bit width */
  240. can_filter_init_struct->filter_bit = CAN_FILTER_16BIT;
  241. /* initialize the filters filter data bit */
  242. can_filter_init_struct->filter_id_high = 0;
  243. can_filter_init_struct->filter_id_low = 0;
  244. can_filter_init_struct->filter_mask_high = 0;
  245. can_filter_init_struct->filter_mask_low = 0;
  246. }
  247. /**
  248. * @brief initialize the can peripheral according to the specified
  249. * parameters in the can_filter_init_struct.
  250. * @param can_x: select the can peripheral.
  251. * this parameter can be one of the following values:
  252. * CAN1,CAN2.
  253. * @param can_filter_init_struct: pointer to a can_filter_init_type structure that contains the configuration information.
  254. * @retval none.
  255. */
  256. void can_filter_init(can_type* can_x, can_filter_init_type* can_filter_init_struct)
  257. {
  258. uint32_t filter_number_bit_pos = 0;
  259. filter_number_bit_pos = ((uint32_t)1) << can_filter_init_struct->filter_number;
  260. /* set the filter turn into configuration condition */
  261. can_x->fctrl_bit.fcs = TRUE;
  262. /* filter activate disable */
  263. can_x->facfg &= ~(uint32_t)filter_number_bit_pos;
  264. /* filter bit width */
  265. switch(can_filter_init_struct->filter_bit)
  266. {
  267. case CAN_FILTER_16BIT:
  268. can_x->fbwcfg &= ~(uint32_t)filter_number_bit_pos;
  269. /* first 16-bit identifier and first 16-bit mask or first 16-bit identifier and second 16-bit identifier */
  270. can_x->ffb[can_filter_init_struct->filter_number].ffdb1 = ((0x0000FFFF & (uint32_t)can_filter_init_struct->filter_mask_low) << 16);
  271. can_x->ffb[can_filter_init_struct->filter_number].ffdb1 |= (0x0000FFFF & (uint32_t)can_filter_init_struct->filter_id_low);
  272. /* second 16-bit identifier and second 16-bit mask or third 16-bit identifier and fourth 16-bit identifier */
  273. can_x->ffb[can_filter_init_struct->filter_number].ffdb2 = ((0x0000FFFF & (uint32_t)can_filter_init_struct->filter_mask_high) << 16);
  274. can_x->ffb[can_filter_init_struct->filter_number].ffdb2 |= (0x0000FFFF & (uint32_t)can_filter_init_struct->filter_id_high);
  275. break;
  276. case CAN_FILTER_32BIT:
  277. can_x->fbwcfg |= filter_number_bit_pos;
  278. /* 32-bit identifier or first 32-bit identifier */
  279. can_x->ffb[can_filter_init_struct->filter_number].ffdb1 = ((0x0000FFFF & (uint32_t)can_filter_init_struct->filter_id_high) << 16);
  280. can_x->ffb[can_filter_init_struct->filter_number].ffdb1 |= (0x0000FFFF & (uint32_t)can_filter_init_struct->filter_id_low);
  281. /* 32-bit mask or second 32-bit identifier */
  282. can_x->ffb[can_filter_init_struct->filter_number].ffdb2 = ((0x0000FFFF & (uint32_t)can_filter_init_struct->filter_mask_high) << 16);
  283. can_x->ffb[can_filter_init_struct->filter_number].ffdb2 |= (0x0000FFFF & (uint32_t)can_filter_init_struct->filter_mask_low);
  284. break;
  285. default:
  286. break;
  287. }
  288. /* filter mode */
  289. switch(can_filter_init_struct->filter_mode)
  290. {
  291. case CAN_FILTER_MODE_ID_MASK:
  292. can_x->fmcfg &= ~(uint32_t)filter_number_bit_pos;
  293. break;
  294. case CAN_FILTER_MODE_ID_LIST:
  295. can_x->fmcfg |= (uint32_t)filter_number_bit_pos;
  296. break;
  297. default:
  298. break;
  299. }
  300. /* filter relation fifo select */
  301. switch(can_filter_init_struct->filter_fifo)
  302. {
  303. case CAN_FILTER_FIFO0:
  304. can_x->frf &= ~(uint32_t)filter_number_bit_pos;
  305. break;
  306. case CAN_FILTER_FIFO1:
  307. can_x->frf |= (uint32_t)filter_number_bit_pos;
  308. break;
  309. default:
  310. break;
  311. }
  312. /* filter activate enable */
  313. switch(can_filter_init_struct->filter_activate_enable)
  314. {
  315. case TRUE:
  316. can_x->facfg |= (uint32_t)filter_number_bit_pos;
  317. break;
  318. case FALSE:
  319. can_x->facfg &= ~(uint32_t)filter_number_bit_pos;
  320. break;
  321. default:
  322. break;
  323. }
  324. /* set the filter turn into working condition */
  325. can_x->fctrl_bit.fcs = FALSE;
  326. }
  327. /**
  328. * @brief enable or disable the debug transmission prohibit of the specified can peripheral.
  329. * @param can_x: select the can peripheral.
  330. * this parameter can be one of the following values:
  331. * CAN1,CAN2.
  332. * @param new_state: new state of debug transmission prohibit.
  333. * this parameter can be: TRUE or FALSE.
  334. * @retval none.
  335. */
  336. void can_debug_transmission_prohibit(can_type* can_x, confirm_state new_state)
  337. {
  338. can_x->mctrl_bit.ptd = new_state;
  339. }
  340. /**
  341. * @brief enable or disable time trigger operation communication mode of the specified can peripheral.
  342. * @param can_x: select the can peripheral.
  343. * this parameter can be one of the following values:
  344. * CAN1 or CAN2.
  345. * @param new_state : new state of time trigger operation communication mode.
  346. * this parameter can be: TRUE or FALSE.
  347. * @note
  348. * note1:
  349. * when enabled, transmit mailbox time stamp(tmts[15:0]) value is sent in the last two data bytes of
  350. * the 8-byte message: tmts[7:0] in data byte 6 and tmts[15:8] in data byte 7
  351. * @note
  352. * note2:
  353. * tmdtbl must be programmed as 8 in order time stamp (2 bytes) to be sent over the can bus.
  354. * @retval none
  355. */
  356. void can_ttc_mode_enable(can_type* can_x, confirm_state new_state)
  357. {
  358. /* config the ttc mode new_state */
  359. can_x->mctrl_bit.ttcen = new_state;
  360. /* config tmtsten bits new_state */
  361. can_x->tx_mailbox[0].tmc_bit.tmtsten = new_state;
  362. can_x->tx_mailbox[1].tmc_bit.tmtsten = new_state;
  363. can_x->tx_mailbox[2].tmc_bit.tmtsten = new_state;
  364. }
  365. /**
  366. * @brief fill the transmission message and transmit of the specified can peripheral.
  367. * @param can_x: select the can peripheral.
  368. * this parameter can be one of the following values:
  369. * CAN1,CAN2.
  370. * @param tx_message_struct: pointer to a structure which contains the message to be trans.
  371. * @retval the number of the mailbox that is used for transmission:
  372. * this parameter can be one of the following values:
  373. * - CAN_TX_MAILBOX0
  374. * - CAN_TX_MAILBOX1
  375. * - CAN_TX_MAILBOX2
  376. * - CAN_TX_STATUS_NO_EMPTY <meanings there is no empty mailbox, message cannot be filled>
  377. */
  378. uint8_t can_message_transmit(can_type* can_x, can_tx_message_type* tx_message_struct)
  379. {
  380. uint8_t transmit_mailbox = CAN_TX_STATUS_NO_EMPTY;
  381. /* select one empty transmit mailbox */
  382. if(can_x->tsts_bit.tm0ef)
  383. {
  384. transmit_mailbox = CAN_TX_MAILBOX0;
  385. }
  386. else if(can_x->tsts_bit.tm1ef)
  387. {
  388. transmit_mailbox = CAN_TX_MAILBOX1;
  389. }
  390. else if(can_x->tsts_bit.tm2ef)
  391. {
  392. transmit_mailbox = CAN_TX_MAILBOX2;
  393. }
  394. else
  395. {
  396. transmit_mailbox = CAN_TX_STATUS_NO_EMPTY;
  397. }
  398. if(transmit_mailbox != CAN_TX_STATUS_NO_EMPTY)
  399. {
  400. /* set up the id */
  401. can_x->tx_mailbox[transmit_mailbox].tmi &= 0x00000001;
  402. can_x->tx_mailbox[transmit_mailbox].tmi_bit.tmidsel = tx_message_struct->id_type;
  403. switch(tx_message_struct->id_type)
  404. {
  405. case CAN_ID_STANDARD:
  406. can_x->tx_mailbox[transmit_mailbox].tmi_bit.tmsid = tx_message_struct->standard_id;
  407. break;
  408. case CAN_ID_EXTENDED:
  409. can_x->tx_mailbox[transmit_mailbox].tmi |= (tx_message_struct->extended_id << 3);
  410. break;
  411. default:
  412. break;
  413. }
  414. can_x->tx_mailbox[transmit_mailbox].tmi_bit.tmfrsel = tx_message_struct->frame_type;
  415. /* set up the dlc */
  416. can_x->tx_mailbox[transmit_mailbox].tmc_bit.tmdtbl = (tx_message_struct->dlc & ((uint8_t)0x0F));
  417. /* set up the data field */
  418. can_x->tx_mailbox[transmit_mailbox].tmdtl = (((uint32_t)tx_message_struct->data[3] << 24) |
  419. ((uint32_t)tx_message_struct->data[2] << 16) |
  420. ((uint32_t)tx_message_struct->data[1] << 8) |
  421. ((uint32_t)tx_message_struct->data[0]));
  422. can_x->tx_mailbox[transmit_mailbox].tmdth = (((uint32_t)tx_message_struct->data[7] << 24) |
  423. ((uint32_t)tx_message_struct->data[6] << 16) |
  424. ((uint32_t)tx_message_struct->data[5] << 8) |
  425. ((uint32_t)tx_message_struct->data[4]));
  426. /* request transmission */
  427. can_x->tx_mailbox[transmit_mailbox].tmi_bit.tmsr = TRUE;
  428. }
  429. return transmit_mailbox;
  430. }
  431. /**
  432. * @brief check the transmission state of the specified can peripheral.
  433. * @param can_x: select the can peripheral.
  434. * this parameter can be one of the following values:
  435. * CAN1 or CAN2.
  436. * @param transmit_mailbox: the number of the mailbox that is used for transmission.
  437. * this parameter can be one of the following values:
  438. * - CAN_TX_MAILBOX0
  439. * - CAN_TX_MAILBOX1
  440. * - CAN_TX_MAILBOX2
  441. * @retval can transmit status
  442. * this parameter can be one of the following values:
  443. * - CAN_TX_STATUS_SUCCESSFUL
  444. * - CAN_TX_STATUS_FAILED
  445. * - CAN_TX_STATUS_PENDING
  446. */
  447. can_transmit_status_type can_transmit_status_get(can_type* can_x, can_tx_mailbox_num_type transmit_mailbox)
  448. {
  449. can_transmit_status_type state_index = CAN_TX_STATUS_FAILED;
  450. switch(transmit_mailbox)
  451. {
  452. case CAN_TX_MAILBOX0:
  453. if(can_x->tsts_bit.tm0tcf != RESET)
  454. {
  455. if(can_x->tsts_bit.tm0tsf != RESET)
  456. {
  457. state_index = CAN_TX_STATUS_SUCCESSFUL;
  458. }
  459. else
  460. {
  461. state_index = CAN_TX_STATUS_FAILED;
  462. }
  463. }
  464. else
  465. {
  466. state_index = CAN_TX_STATUS_PENDING;
  467. }
  468. break;
  469. case CAN_TX_MAILBOX1:
  470. if(can_x->tsts_bit.tm1tcf != RESET)
  471. {
  472. if(can_x->tsts_bit.tm1tsf != RESET)
  473. {
  474. state_index = CAN_TX_STATUS_SUCCESSFUL;
  475. }
  476. else
  477. {
  478. state_index = CAN_TX_STATUS_FAILED;
  479. }
  480. }
  481. else
  482. {
  483. state_index = CAN_TX_STATUS_PENDING;
  484. }
  485. break;
  486. case CAN_TX_MAILBOX2:
  487. if(can_x->tsts_bit.tm2tcf != RESET)
  488. {
  489. if(can_x->tsts_bit.tm2tsf != RESET)
  490. {
  491. state_index = CAN_TX_STATUS_SUCCESSFUL;
  492. }
  493. else
  494. {
  495. state_index = CAN_TX_STATUS_FAILED;
  496. }
  497. }
  498. else
  499. {
  500. state_index = CAN_TX_STATUS_PENDING;
  501. }
  502. break;
  503. default:
  504. state_index = CAN_TX_STATUS_FAILED;
  505. break;
  506. }
  507. return state_index;
  508. }
  509. /**
  510. * @brief cancel a transmit request of the specified can peripheral.
  511. * @param can_x: select the can peripheral.
  512. * this parameter can be one of the following values:
  513. * CAN1 or CAN2.
  514. * @param mailbox: mailbox number.
  515. * this parameter can be one of the following values:
  516. * - CAN_TX_MAILBOX0
  517. * - CAN_TX_MAILBOX1
  518. * - CAN_TX_MAILBOX2
  519. * @retval none.
  520. */
  521. void can_transmit_cancel(can_type* can_x, can_tx_mailbox_num_type transmit_mailbox)
  522. {
  523. switch (transmit_mailbox)
  524. {
  525. case CAN_TX_MAILBOX0:
  526. can_x->tsts = CAN_TSTS_TM0CT_VAL;
  527. break;
  528. case CAN_TX_MAILBOX1:
  529. can_x->tsts = CAN_TSTS_TM1CT_VAL;
  530. break;
  531. case CAN_TX_MAILBOX2:
  532. can_x->tsts = CAN_TSTS_TM2CT_VAL;
  533. break;
  534. default:
  535. break;
  536. }
  537. }
  538. /**
  539. * @brief receive message of the specified can peripheral.
  540. * @param can_x: select the can peripheral.
  541. * this parameter can be one of the following values:
  542. * CAN1,CAN2.
  543. * @param fifo_number: receive fifo number.
  544. * this parameter can be one of the following values:
  545. * - CAN_RX_FIFO0
  546. * - CAN_RX_FIFO1
  547. * @param rx_message_struct: pointer to a structure which store the receive message.
  548. * @retval none.
  549. */
  550. void can_message_receive(can_type* can_x, can_rx_fifo_num_type fifo_number, can_rx_message_type* rx_message_struct)
  551. {
  552. /* get the id type */
  553. rx_message_struct->id_type = (can_identifier_type)can_x->fifo_mailbox[fifo_number].rfi_bit.rfidi;
  554. switch (rx_message_struct->id_type)
  555. {
  556. case CAN_ID_STANDARD:
  557. rx_message_struct->standard_id = can_x->fifo_mailbox[fifo_number].rfi_bit.rfsid;
  558. break;
  559. case CAN_ID_EXTENDED:
  560. rx_message_struct->extended_id = 0x1FFFFFFF & (can_x->fifo_mailbox[fifo_number].rfi >> 3);
  561. break;
  562. default:
  563. break;
  564. }
  565. rx_message_struct->frame_type = (can_trans_frame_type)can_x->fifo_mailbox[fifo_number].rfi_bit.rffri;
  566. /* get the dlc */
  567. rx_message_struct->dlc = can_x->fifo_mailbox[fifo_number].rfc_bit.rfdtl;
  568. /* get the filter match number */
  569. rx_message_struct->filter_index = can_x->fifo_mailbox[fifo_number].rfc_bit.rffmn;
  570. /* get the data field */
  571. rx_message_struct->data[0] = can_x->fifo_mailbox[fifo_number].rfdtl_bit.rfdt0;
  572. rx_message_struct->data[1] = can_x->fifo_mailbox[fifo_number].rfdtl_bit.rfdt1;
  573. rx_message_struct->data[2] = can_x->fifo_mailbox[fifo_number].rfdtl_bit.rfdt2;
  574. rx_message_struct->data[3] = can_x->fifo_mailbox[fifo_number].rfdtl_bit.rfdt3;
  575. rx_message_struct->data[4] = can_x->fifo_mailbox[fifo_number].rfdth_bit.rfdt4;
  576. rx_message_struct->data[5] = can_x->fifo_mailbox[fifo_number].rfdth_bit.rfdt5;
  577. rx_message_struct->data[6] = can_x->fifo_mailbox[fifo_number].rfdth_bit.rfdt6;
  578. rx_message_struct->data[7] = can_x->fifo_mailbox[fifo_number].rfdth_bit.rfdt7;
  579. /* release the fifo */
  580. can_receive_fifo_release(can_x, fifo_number);
  581. }
  582. /**
  583. * @brief release the specified fifo of the specified can peripheral.
  584. * @param can_x: select the can peripheral.
  585. * this parameter can be one of the following values:
  586. * CAN1,CAN2.
  587. * @param fifo_number: fifo to be release.
  588. * this parameter can be one of the following values:
  589. * - CAN_RX_FIFO0
  590. * - CAN_RX_FIFO1
  591. * @retval none.
  592. */
  593. void can_receive_fifo_release(can_type* can_x, can_rx_fifo_num_type fifo_number)
  594. {
  595. switch (fifo_number)
  596. {
  597. case CAN_RX_FIFO0:
  598. can_x->rf0 = CAN_RF0_RF0R_VAL;
  599. break;
  600. case CAN_RX_FIFO1:
  601. can_x->rf1 = CAN_RF1_RF1R_VAL;
  602. break;
  603. default:
  604. break;
  605. }
  606. }
  607. /**
  608. * @brief return the number of pending messages of the specified can peripheral.
  609. * @param can_x: select the can peripheral.
  610. * this parameter can be one of the following values:
  611. * CAN1,CAN2.
  612. * @param fifo_number: receive fifo number.
  613. * this parameter can be one of the following values:
  614. * - CAN_RX_FIFO0
  615. * - CAN_RX_FIFO1
  616. * @retval the number of message pending in the receive fifo.
  617. */
  618. uint8_t can_receive_message_pending_get(can_type* can_x, can_rx_fifo_num_type fifo_number)
  619. {
  620. uint8_t message_pending = 0;
  621. switch (fifo_number)
  622. {
  623. case CAN_RX_FIFO0:
  624. message_pending = can_x->rf0_bit.rf0mn;
  625. break;
  626. case CAN_RX_FIFO1:
  627. message_pending = can_x->rf1_bit.rf1mn;
  628. break;
  629. default:
  630. break;
  631. }
  632. return message_pending;
  633. }
  634. /**
  635. * @brief set the operation mode of the specified can peripheral.
  636. * @param can_x: select the can peripheral.
  637. * this parameter can be one of the following values:
  638. * CAN1,CAN2.
  639. * @param can_operating_mode: can operating mode.
  640. * this parameter can be one of the following values:
  641. * - CAN_OPERATINGMODE_FREEZE
  642. * - CAN_OPERATINGMODE_DOZE
  643. * - CAN_OPERATINGMODE_COMMUNICATE
  644. * @retval status of operation mode set
  645. * this parameter can be one of the following values:
  646. * SUCCESS or ERROR
  647. */
  648. error_status can_operating_mode_set(can_type* can_x, can_operating_mode_type can_operating_mode)
  649. {
  650. error_status status = ERROR;
  651. uint32_t time_out_index = FZC_TIMEOUT;
  652. if (can_operating_mode == CAN_OPERATINGMODE_FREEZE)
  653. {
  654. /* request enter freeze mode */
  655. can_x->mctrl_bit.dzen = FALSE;
  656. can_x->mctrl_bit.fzen = TRUE;
  657. while(((can_x->msts_bit.dzc) || (!can_x->msts_bit.fzc)) && (time_out_index != 0))
  658. {
  659. time_out_index--;
  660. }
  661. if((can_x->msts_bit.dzc) || (!can_x->msts_bit.fzc))
  662. {
  663. status = ERROR;
  664. }
  665. else
  666. {
  667. status = SUCCESS;
  668. }
  669. }
  670. else if(can_operating_mode == CAN_OPERATINGMODE_DOZE)
  671. {
  672. /* request enter doze mode */
  673. can_x->mctrl_bit.dzen = TRUE;
  674. can_x->mctrl_bit.fzen = FALSE;
  675. while(((!can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) && (time_out_index != 0))
  676. {
  677. time_out_index--;
  678. }
  679. if((!can_x->msts_bit.dzc) || (can_x->msts_bit.fzc))
  680. {
  681. status = ERROR;
  682. }
  683. else
  684. {
  685. status = SUCCESS;
  686. }
  687. }
  688. else if(can_operating_mode == CAN_OPERATINGMODE_COMMUNICATE)
  689. {
  690. /* request enter normal mode */
  691. can_x->mctrl_bit.dzen = FALSE;
  692. can_x->mctrl_bit.fzen = FALSE;
  693. while(((can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) && (time_out_index != 0))
  694. {
  695. time_out_index--;
  696. }
  697. if((can_x->msts_bit.dzc) || (can_x->msts_bit.fzc))
  698. {
  699. status = ERROR;
  700. }
  701. else
  702. {
  703. status = SUCCESS;
  704. }
  705. }
  706. else
  707. {
  708. status = ERROR;
  709. }
  710. return status;
  711. }
  712. /**
  713. * @brief enter the low power mode of the specified can peripheral.
  714. * @param can_x: select the can peripheral.
  715. * this parameter can be one of the following values:
  716. * CAN1,CAN2.
  717. * @retval status of doze mode enter, the returned value can be:
  718. * - CAN_ENTER_DOZE_SUCCESSFUL <it meaning enter the doze mode succeed>
  719. * - CAN_ENTER_DOZE_FAILED <it meaning enter the doze mode failed>
  720. */
  721. can_enter_doze_status_type can_doze_mode_enter(can_type* can_x)
  722. {
  723. can_enter_doze_status_type status = CAN_ENTER_DOZE_FAILED;
  724. uint32_t time_out_index = FZC_TIMEOUT;
  725. can_x->mctrl_bit.fzen = FALSE;
  726. can_x->mctrl_bit.dzen = TRUE;
  727. while(((!can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) && (time_out_index != 0))
  728. {
  729. time_out_index--;
  730. }
  731. if((!can_x->msts_bit.dzc) || (can_x->msts_bit.fzc))
  732. {
  733. status = CAN_ENTER_DOZE_FAILED;
  734. }
  735. else
  736. {
  737. status = CAN_ENTER_DOZE_SUCCESSFUL;
  738. }
  739. return status;
  740. }
  741. /**
  742. * @brief exit the doze mode of the specified can peripheral.
  743. * @param can_x: select the can peripheral.
  744. * this parameter can be one of the following values:
  745. * CAN1,CAN2.
  746. * @retval status of doze mode enter, the returned value can be:
  747. * - CAN_QUIT_DOZE_SUCCESSFUL <it meaning exit the doze mode succeed>
  748. * - CAN_QUIT_DOZE_FAILED <it meaning exit the doze mode failed>
  749. */
  750. can_quit_doze_status_type can_doze_mode_exit(can_type* can_x)
  751. {
  752. can_quit_doze_status_type status = CAN_QUIT_DOZE_FAILED;
  753. uint32_t time_out_index = DZC_TIMEOUT;
  754. can_x->mctrl_bit.dzen = FALSE;
  755. while((can_x->msts_bit.dzc) && (time_out_index != 0))
  756. {
  757. time_out_index--;
  758. }
  759. if(!can_x->msts_bit.dzc)
  760. {
  761. status = CAN_QUIT_DOZE_SUCCESSFUL;
  762. }
  763. return status;
  764. }
  765. /**
  766. * @brief return the error type record (etr) of the specified can peripheral.
  767. * @param can_x: select the can peripheral.
  768. * this parameter can be one of the following values:
  769. * CAN1,CAN2.
  770. * @retval the value of the error code
  771. * the return can be one of the follow values:
  772. * - CAN_ERRORRECORD_NOERR
  773. * - CAN_ERRORRECORD_STUFFERR,
  774. * - CAN_ERRORRECORD_FORMERR,
  775. * - CAN_ERRORRECORD_ACKERR,
  776. * - CAN_ERRORRECORD_BITRECESSIVEERR,
  777. * - CAN_ERRORRECORD_BITDOMINANTERR,
  778. * - CAN_ERRORRECORD_CRCERR,
  779. * - CAN_ERRORRECORD_SOFTWARESETERR
  780. */
  781. can_error_record_type can_error_type_record_get(can_type* can_x)
  782. {
  783. can_error_record_type error_code = CAN_ERRORRECORD_NOERR;
  784. error_code = (can_error_record_type)can_x->ests_bit.etr;
  785. return error_code;
  786. }
  787. /**
  788. * @brief return the receive error counter (rec) of the specified can peripheral.
  789. * @param can_x: select the can peripheral.
  790. * this parameter can be one of the following values:
  791. * CAN1,CAN2.
  792. * @retval the value of receive error counter.
  793. */
  794. uint8_t can_receive_error_counter_get(can_type* can_x)
  795. {
  796. uint8_t counter = 0;
  797. counter = can_x->ests_bit.rec;
  798. return counter;
  799. }
  800. /**
  801. * @brief return the transmit error counter of the specified can peripheral.
  802. * @param can_x: select the can peripheral.
  803. * this parameter can be one of the following values:
  804. * CAN1,CAN2.
  805. * @retval the value of transmit error counter.
  806. */
  807. uint8_t can_transmit_error_counter_get(can_type* can_x)
  808. {
  809. uint8_t counter = 0;
  810. counter = can_x->ests_bit.tec;
  811. return counter;
  812. }
  813. /**
  814. * @brief enable or disable the interrupt of the specified can peripheral.
  815. * @param can_x: select the can peripheral.
  816. * this parameter can be one of the following values:
  817. * CAN1,CAN2.
  818. * @param can_int: specifies the can interrupt sources to be enabled or disabled.
  819. * this parameter can be one of the following values:
  820. * - CAN_TCIEN_INT
  821. * - CAN_RF0MIEN_INT
  822. * - CAN_RF0FIEN_INT
  823. * - CAN_RF0OIEN_INT
  824. * - CAN_RF1MIEN_INT
  825. * - CAN_RF1FIEN_INT
  826. * - CAN_RF1OIEN_INT
  827. * - CAN_EAIEN_INT
  828. * - CAN_EPIEN_INT
  829. * - CAN_BOIEN_INT
  830. * - CAN_ETRIEN_INT
  831. * - CAN_EOIEN_INT
  832. * - CAN_QDZIEN_INT
  833. * - CAN_EDZIEN_INT
  834. * @param new_state: new state of the can interrupts.
  835. * this parameter can be: TRUE or FALSE.
  836. * @retval none.
  837. */
  838. void can_interrupt_enable(can_type* can_x, uint32_t can_int, confirm_state new_state)
  839. {
  840. if (new_state != FALSE)
  841. {
  842. can_x->inten |= can_int;
  843. }
  844. else
  845. {
  846. can_x->inten &= ~can_int;
  847. }
  848. }
  849. /**
  850. * @brief get flag of the specified can peripheral.
  851. * @param can_x: select the can peripheral.
  852. * this parameter can be one of the following values:
  853. * CAN1,CAN2.
  854. * @param can_flag: select the flag.
  855. * this parameter can be one of the following flags:
  856. * - CAN_EAF_FLAG
  857. * - CAN_EPF_FLAG
  858. * - CAN_BOF_FLAG
  859. * - CAN_ETR_FLAG
  860. * - CAN_EOIF_FLAG
  861. * - CAN_TM0TCF_FLAG
  862. * - CAN_TM1TCF_FLAG
  863. * - CAN_TM2TCF_FLAG
  864. * - CAN_RF0MN_FLAG
  865. * - CAN_RF0FF_FLAG
  866. * - CAN_RF0OF_FLAG
  867. * - CAN_RF1MN_FLAG
  868. * - CAN_RF1FF_FLAG
  869. * - CAN_RF1OF_FLAG
  870. * - CAN_QDZIF_FLAG
  871. * - CAN_EDZC_FLAG
  872. * - CAN_TMEF_FLAG
  873. * note:the state of CAN_EDZC_FLAG need to check dzc and edzif bit
  874. * note:the state of CAN_TMEF_FLAG need to check rqc0,rqc1 and rqc2 bit
  875. * @retval status of can_flag, the returned value can be:SET or RESET.
  876. */
  877. flag_status can_flag_get(can_type* can_x, uint32_t can_flag)
  878. {
  879. flag_status bit_status = RESET;
  880. switch(can_flag)
  881. {
  882. case CAN_EAF_FLAG:
  883. bit_status = (flag_status)can_x->ests_bit.eaf;
  884. break;
  885. case CAN_EPF_FLAG:
  886. bit_status = (flag_status)can_x->ests_bit.epf;
  887. break;
  888. case CAN_BOF_FLAG:
  889. bit_status = (flag_status)can_x->ests_bit.bof;
  890. break;
  891. case CAN_ETR_FLAG:
  892. if(can_x->ests_bit.etr != 0)
  893. {
  894. bit_status = SET;
  895. }
  896. else
  897. {
  898. bit_status = RESET;
  899. }
  900. break;
  901. case CAN_EOIF_FLAG:
  902. bit_status = (flag_status)can_x->msts_bit.eoif;
  903. break;
  904. case CAN_TM0TCF_FLAG:
  905. bit_status = (flag_status)can_x->tsts_bit.tm0tcf;
  906. break;
  907. case CAN_TM1TCF_FLAG:
  908. bit_status = (flag_status)can_x->tsts_bit.tm1tcf;
  909. break;
  910. case CAN_TM2TCF_FLAG:
  911. bit_status = (flag_status)can_x->tsts_bit.tm2tcf;
  912. break;
  913. case CAN_RF0MN_FLAG:
  914. if(can_x->rf0_bit.rf0mn != 0)
  915. {
  916. bit_status = SET;
  917. }
  918. else
  919. {
  920. bit_status = RESET;
  921. }
  922. break;
  923. case CAN_RF0FF_FLAG:
  924. bit_status = (flag_status)can_x->rf0_bit.rf0ff;
  925. break;
  926. case CAN_RF0OF_FLAG:
  927. bit_status = (flag_status)can_x->rf0_bit.rf0of;
  928. break;
  929. case CAN_RF1MN_FLAG:
  930. if(can_x->rf1_bit.rf1mn != 0)
  931. {
  932. bit_status = SET;
  933. }
  934. else
  935. {
  936. bit_status = RESET;
  937. }
  938. break;
  939. case CAN_RF1FF_FLAG:
  940. bit_status = (flag_status)can_x->rf1_bit.rf1ff;
  941. break;
  942. case CAN_RF1OF_FLAG:
  943. bit_status = (flag_status)can_x->rf1_bit.rf1of;
  944. break;
  945. case CAN_QDZIF_FLAG:
  946. bit_status = (flag_status)can_x->msts_bit.qdzif;
  947. break;
  948. case CAN_EDZC_FLAG:
  949. if((can_x->msts_bit.dzc != RESET) ||(can_x->msts_bit.edzif != RESET))
  950. {
  951. bit_status = SET;
  952. }
  953. else
  954. {
  955. bit_status = RESET;
  956. }
  957. break;
  958. case CAN_TMEF_FLAG:
  959. if((can_x->tsts_bit.tm0ef != RESET) || (can_x->tsts_bit.tm1ef != RESET) || (can_x->tsts_bit.tm2ef != RESET))
  960. {
  961. bit_status = SET;
  962. }
  963. else
  964. {
  965. bit_status = RESET;
  966. }
  967. break;
  968. default:
  969. bit_status = RESET;
  970. break;
  971. }
  972. return bit_status;
  973. }
  974. /**
  975. * @brief clear flag of the specified can peripheral.
  976. * @param can_x: select the can peripheral.
  977. * this parameter can be one of the following values:
  978. * CAN1,CAN2.
  979. * @param can_flag: select the flag.
  980. * this parameter can be one of the following flags:
  981. * - CAN_EAF_FLAG
  982. * - CAN_EPF_FLAG
  983. * - CAN_BOF_FLAG
  984. * - CAN_ETR_FLAG
  985. * - CAN_EOIF_FLAG
  986. * - CAN_TM0TCF_FLAG
  987. * - CAN_TM1TCF_FLAG
  988. * - CAN_TM2TCF_FLAG
  989. * - CAN_RF0FF_FLAG
  990. * - CAN_RF0OF_FLAG
  991. * - CAN_RF1FF_FLAG
  992. * - CAN_RF1OF_FLAG
  993. * - CAN_QDZIF_FLAG
  994. * - CAN_EDZC_FLAG
  995. * - CAN_TMEF_FLAG
  996. * - CAN_ETR_SOFTWARE_FLAG
  997. * note:CAN_RF0MN_FLAG and CAN_RF1MN_FLAG can not clear by this function
  998. * @retval none.
  999. */
  1000. void can_flag_clear(can_type* can_x, uint32_t can_flag)
  1001. {
  1002. switch(can_flag)
  1003. {
  1004. case CAN_EAF_FLAG:
  1005. case CAN_EPF_FLAG:
  1006. case CAN_BOF_FLAG:
  1007. case CAN_EOIF_FLAG:
  1008. can_x->msts = CAN_MSTS_EOIF_VAL;
  1009. break;
  1010. case CAN_ETR_FLAG:
  1011. can_x->msts = CAN_MSTS_EOIF_VAL;
  1012. can_x->ests = 0;
  1013. break;
  1014. case CAN_TM0TCF_FLAG:
  1015. can_x->tsts = CAN_TSTS_TM0TCF_VAL;
  1016. break;
  1017. case CAN_TM1TCF_FLAG:
  1018. can_x->tsts = CAN_TSTS_TM1TCF_VAL;
  1019. break;
  1020. case CAN_TM2TCF_FLAG:
  1021. can_x->tsts = CAN_TSTS_TM2TCF_VAL;
  1022. break;
  1023. case CAN_RF0FF_FLAG:
  1024. can_x->rf0 = CAN_RF0_RF0FF_VAL;
  1025. break;
  1026. case CAN_RF0OF_FLAG:
  1027. can_x->rf0 = CAN_RF0_RF0OF_VAL;
  1028. break;
  1029. case CAN_RF1FF_FLAG:
  1030. can_x->rf1 = CAN_RF1_RF1FF_VAL;
  1031. break;
  1032. case CAN_RF1OF_FLAG:
  1033. can_x->rf1 = CAN_RF1_RF1OF_VAL;
  1034. break;
  1035. case CAN_QDZIF_FLAG:
  1036. can_x->msts = CAN_MSTS_QDZIF_VAL;
  1037. break;
  1038. case CAN_EDZC_FLAG:
  1039. can_x->msts = CAN_MSTS_EDZIF_VAL;
  1040. break;
  1041. case CAN_TMEF_FLAG:
  1042. can_x->tsts = CAN_TSTS_TM0TCF_VAL | CAN_TSTS_TM1TCF_VAL | CAN_TSTS_TM2TCF_VAL;
  1043. break;
  1044. default:
  1045. break;
  1046. }
  1047. }
  1048. /**
  1049. * @}
  1050. */
  1051. #endif
  1052. /**
  1053. * @}
  1054. */
  1055. /**
  1056. * @}
  1057. */