at32f413_can.c 34 KB

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