gd32f4xx_can.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863
  1. /*!
  2. \file gd32f4xx_can.c
  3. \brief CAN driver
  4. */
  5. /*
  6. Copyright (C) 2016 GigaDevice
  7. 2016-08-15, V1.0.0, firmware for GD32F4xx
  8. */
  9. #include "gd32f4xx_can.h"
  10. /*!
  11. \brief deinitialize CAN
  12. \param[in] can_periph
  13. \arg CANx(x=0,1)
  14. \param[out] none
  15. \retval none
  16. */
  17. void can_deinit(uint32_t can_periph)
  18. {
  19. if(CAN0 == can_periph){
  20. rcu_periph_reset_enable(RCU_CAN0RST);
  21. rcu_periph_reset_disable(RCU_CAN0RST);
  22. }else{
  23. rcu_periph_reset_enable(RCU_CAN1RST);
  24. rcu_periph_reset_disable(RCU_CAN1RST);
  25. }
  26. }
  27. /*!
  28. \brief initialize CAN
  29. \param[in] can_periph
  30. \arg CANx(x=0,1)
  31. \param[in] can_parameter_struct: parameters for CAN initializtion
  32. can_mode: CAN_NORMAL_MODE, CAN_LOOPBACK_MODE, CAN_SILENT_MODE, CAN_SILENT_LOOPBACK_MODE
  33. can_sjw: CAN_BT_SJW_xTQ(x=1, 2, 3, 4)
  34. can_bs1: CAN_BT_BS1_xTQ(1..16)
  35. can_bs2: CAN_BT_BS2_xTQ(1..8)
  36. can_ttc: ENABLE or DISABLE
  37. can_abor: ENABLE or DISABLE
  38. can_awu: ENABLE or DISABLE
  39. can_ard: ENABLE or DISABLE
  40. can_rfod: ENABLE or DISABLE
  41. can_tfo: ENABLE or DISABLE
  42. can_psc: 0x0001 - 0x03FF
  43. \param[out] none
  44. \retval ErrStatus: SUCCESS or ERROR
  45. */
  46. ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init)
  47. {
  48. uint32_t timeout = CAN_TIMEOUT;
  49. ErrStatus flag = ERROR;
  50. /* disable sleep mode */
  51. CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
  52. /* enable initialize mode */
  53. CAN_CTL(can_periph) |= CAN_CTL_IWMOD;
  54. /* wait ACK */
  55. while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (timeout)){
  56. timeout--;
  57. }
  58. /* check initialize working success */
  59. if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){
  60. flag = ERROR;
  61. } else {
  62. /* set the bit timing register */
  63. CAN_BT(can_periph) = (BT_MODE((uint32_t)can_parameter_init->working_mode) | \
  64. BT_SJW((uint32_t)can_parameter_init->resync_jump_width) | \
  65. BT_BS1((uint32_t)can_parameter_init->time_segment_1) | \
  66. BT_BS2((uint32_t)can_parameter_init->time_segment_2) | \
  67. BT_BAUDPSC(((uint32_t)(can_parameter_init->prescaler) - 1U)));
  68. /* time trigger communication mode */
  69. if(ENABLE == can_parameter_init->time_triggered){
  70. CAN_CTL(can_periph) |= CAN_CTL_TTC;
  71. }else{
  72. CAN_CTL(can_periph) &= ~CAN_CTL_TTC;
  73. }
  74. /* automatic bus-off managment */
  75. if(ENABLE == can_parameter_init->auto_bus_off_recovery){
  76. CAN_CTL(can_periph) |= CAN_CTL_ABOR;
  77. }else{
  78. CAN_CTL(can_periph) &= ~CAN_CTL_ABOR;
  79. }
  80. /* automatic wakeup mode */
  81. if(ENABLE == can_parameter_init->auto_wake_up){
  82. CAN_CTL(can_periph) |= CAN_CTL_AWU;
  83. }else{
  84. CAN_CTL(can_periph) &= ~CAN_CTL_AWU;
  85. }
  86. /* automatic retransmission mode */
  87. if(ENABLE == can_parameter_init->auto_retrans){
  88. CAN_CTL(can_periph) |= CAN_CTL_ARD;
  89. }else{
  90. CAN_CTL(can_periph) &= ~CAN_CTL_ARD;
  91. }
  92. /* receive fifo overwrite mode */
  93. if(ENABLE == can_parameter_init->rec_fifo_overwrite){
  94. CAN_CTL(can_periph) |= CAN_CTL_RFOD;
  95. }else{
  96. CAN_CTL(can_periph) &= ~CAN_CTL_RFOD;
  97. }
  98. /* transmit fifo order */
  99. if(ENABLE == can_parameter_init->trans_fifo_order){
  100. CAN_CTL(can_periph) |= CAN_CTL_TFO;
  101. }else{
  102. CAN_CTL(can_periph) &= ~CAN_CTL_TFO;
  103. }
  104. /* disable initialize mode */
  105. CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD;
  106. timeout = CAN_TIMEOUT;
  107. /* wait the ACK */
  108. while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (timeout)){
  109. timeout--;
  110. }
  111. /* check exit initialize mode */
  112. if(CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)){
  113. flag = SUCCESS;
  114. }
  115. }
  116. return flag;
  117. }
  118. /*!
  119. \brief initialize CAN filter
  120. \param[in] can_filter_parameter_struct: struct for CAN filter initialization
  121. can_filter_list_high: 0x0000 - 0xFFFF
  122. can_filter_list_low: 0x0000 - 0xFFFF
  123. can_filter_mask_high: 0x0000 - 0xFFFF
  124. can_filter_mask_low: 0x0000 - 0xFFFF
  125. can_filter_fifo_number: CAN_FIFO0, CAN_FIFO1
  126. can_filter_number: 0 - 27
  127. can_filter_mode: CAN_FILTERMODE_MASK, CAN_FILTERMODE_LIST
  128. can_filter_bits: CAN_FILTERBITS_32BIT, CAN_FILTERBITS_16BIT
  129. can_filter_enable: ENABLE or DISABLE
  130. \param[out] none
  131. \retval none
  132. */
  133. void can_filter_init(can_filter_parameter_struct* can_filter_parameter_init)
  134. {
  135. uint32_t val = 0U;
  136. val = ((uint32_t)1) << (can_filter_parameter_init->filter_number);
  137. /* filter lock disable */
  138. CAN_FCTL(CAN0) |= CAN_FCTL_FLD;
  139. /* disable filter */
  140. CAN_FW(CAN0) &= ~(uint32_t)val;
  141. /* filter 16 bits */
  142. if(CAN_FILTERBITS_16BIT == can_filter_parameter_init->filter_bits){
  143. /* set filter 16 bits */
  144. CAN_FSCFG(CAN0) &= ~(uint32_t)val;
  145. /* first 16 bits list and first 16 bits mask or first 16 bits list and second 16 bits list */
  146. CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \
  147. FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS) | \
  148. FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS);
  149. /* second 16 bits list and second 16 bits mask or third 16 bits list and fourth 16 bits list */
  150. CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \
  151. FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | \
  152. FDATA_MASK_LOW((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS);
  153. }
  154. /* filter 32 bits */
  155. if(CAN_FILTERBITS_32BIT == can_filter_parameter_init->filter_bits){
  156. /* set filter 32 bits */
  157. CAN_FSCFG(CAN0) |= (uint32_t)val;
  158. /* 32 bits list or first 32 bits list */
  159. CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \
  160. FDATA_MASK_HIGH((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS) |
  161. FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS);
  162. /* 32 bits mask or second 32 bits list */
  163. CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \
  164. FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) |
  165. FDATA_MASK_LOW((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS);
  166. }
  167. /* filter mode */
  168. if(CAN_FILTERMODE_MASK == can_filter_parameter_init->filter_mode){
  169. /* mask mode */
  170. CAN_FMCFG(CAN0) &= ~(uint32_t)val;
  171. }else{
  172. /* list mode */
  173. CAN_FMCFG(CAN0) |= (uint32_t)val;
  174. }
  175. /* filter FIFO */
  176. if(CAN_FIFO0 == (can_filter_parameter_init->filter_fifo_number)){
  177. /* FIFO0 */
  178. CAN_FAFIFO(CAN0) &= ~(uint32_t)val;
  179. }
  180. if(CAN_FIFO1 == can_filter_parameter_init->filter_fifo_number){
  181. /* FIFO1 */
  182. CAN_FAFIFO(CAN0) |= (uint32_t)val;
  183. }
  184. /* filter working */
  185. if(ENABLE == can_filter_parameter_init->filter_enable){
  186. CAN_FW(CAN0) |= (uint32_t)val;
  187. }
  188. /* filter lock enable */
  189. CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD;
  190. }
  191. /*!
  192. \brief set CAN1 fliter start bank number
  193. \param[in] can1_start_bank_number
  194. \arg (1..27)
  195. \param[out] none
  196. \retval none
  197. */
  198. void can1_filter_start_bank(uint8_t start_bank)
  199. {
  200. /* filter lock disable */
  201. CAN_FCTL(CAN0) |= CAN_FCTL_FLD;
  202. /* set CAN1 filter start number */
  203. CAN_FCTL(CAN0) &= ~(uint32_t)CAN_FCTL_HBC1F;
  204. CAN_FCTL(CAN0) |= FCTL_HBC1F(start_bank);
  205. /* filter lock enaable */
  206. CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD;
  207. }
  208. /*!
  209. \brief enable CAN debug freeze
  210. \param[in] can_periph
  211. \arg CANx(x=0,1)
  212. \param[out] none
  213. \retval none
  214. */
  215. void can_debug_freeze_enable(uint32_t can_periph)
  216. {
  217. CAN_CTL(can_periph) |= CAN_CTL_DFZ;
  218. if(CAN0 == can_periph){
  219. dbg_periph_enable(DBG_CAN0_HOLD);
  220. }else{
  221. dbg_periph_enable(DBG_CAN1_HOLD);
  222. }
  223. }
  224. /*!
  225. \brief disable CAN debug freeze
  226. \param[in] can_periph
  227. \arg CANx(x=0,1)
  228. \param[out] none
  229. \retval none
  230. */
  231. void can_debug_freeze_disable(uint32_t can_periph)
  232. {
  233. CAN_CTL(can_periph) &= ~CAN_CTL_DFZ;
  234. if(CAN0 == can_periph){
  235. dbg_periph_disable(DBG_CAN0_HOLD);
  236. }else{
  237. dbg_periph_disable(DBG_CAN0_HOLD);
  238. }
  239. }
  240. /*!
  241. \brief enable CAN time trigger mode
  242. \param[in] can_periph
  243. \arg CANx(x=0,1)
  244. \param[out] none
  245. \retval none
  246. */
  247. void can_time_trigger_mode_enable(uint32_t can_periph)
  248. {
  249. uint8_t mailbox_number;
  250. /* enable the tcc mode */
  251. CAN_CTL(can_periph) |= CAN_CTL_TTC;
  252. /* enable time stamp */
  253. for(mailbox_number=0U; mailbox_number<3U; mailbox_number++){
  254. CAN_TMP(can_periph, mailbox_number) |= CAN_TMP_TSEN;
  255. }
  256. }
  257. /*!
  258. \brief disable CAN time trigger mode
  259. \param[in] can_periph
  260. \arg CANx(x=0,1)
  261. \param[out] none
  262. \retval none
  263. */
  264. void can_time_trigger_mode_disable(uint32_t can_periph)
  265. {
  266. uint8_t mailbox_number;
  267. /* disable the TCC mode */
  268. CAN_CTL(can_periph) &= ~CAN_CTL_TTC;
  269. /* reset TSEN bits */
  270. for(mailbox_number=0U; mailbox_number<3U; mailbox_number++){
  271. CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_TSEN;
  272. }
  273. }
  274. /*!
  275. \brief CAN transmit message
  276. \param[in] can_periph
  277. \arg CANx(x=0,1)
  278. \param[in] can_trasnmit_message_struct: struct for CAN transmit message
  279. can_rx_sfid: 0x00000000 - 0x000007FF
  280. can_rx_efid: 0x00000000 - 0x1FFFFFFF
  281. can_rx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
  282. can_rx_ft: CAN_FT_DATA, CAN_FT_REMOTE
  283. can_rx_dlenc: 1 - 7
  284. can_rx_data[]: 0x00 - 0xFF
  285. \param[out] none
  286. \retval none
  287. */
  288. uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* transmit_message)
  289. {
  290. uint8_t mailbox_number = CAN_MAILBOX0;
  291. /* select one empty mailbox */
  292. if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)){
  293. mailbox_number = CAN_MAILBOX0;
  294. }else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)){
  295. mailbox_number = CAN_MAILBOX1;
  296. }else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)){
  297. mailbox_number = CAN_MAILBOX2;
  298. }else{
  299. mailbox_number = CAN_NOMAILBOX;
  300. }
  301. if(CAN_NOMAILBOX == mailbox_number){
  302. return CAN_NOMAILBOX;
  303. }
  304. CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN;
  305. if(CAN_FF_STANDARD == transmit_message->tx_ff){
  306. /* set transmit mailbox standard identifier */
  307. CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | \
  308. transmit_message->tx_ft);
  309. }else{
  310. /* set transmit mailbox extended identifier */
  311. CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | \
  312. transmit_message->tx_ff | \
  313. transmit_message->tx_ft);
  314. }
  315. /* set the data length */
  316. transmit_message->tx_dlen &= (uint8_t)(CAN_TMP_DLENC);
  317. CAN_TMP(can_periph, mailbox_number) &= ((uint32_t)~CAN_TMP_DLENC);
  318. CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen;
  319. /* set the data */
  320. CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \
  321. TMDATA0_DB2(transmit_message->tx_data[2]) | \
  322. TMDATA0_DB1(transmit_message->tx_data[1]) | \
  323. TMDATA0_DB0(transmit_message->tx_data[0]);
  324. CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \
  325. TMDATA1_DB6(transmit_message->tx_data[6]) | \
  326. TMDATA1_DB5(transmit_message->tx_data[5]) | \
  327. TMDATA1_DB4(transmit_message->tx_data[4]);
  328. /* enable transmission */
  329. CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN;
  330. return mailbox_number;
  331. }
  332. /*!
  333. \brief CAN transmit state
  334. \param[in] can_periph
  335. \arg CANx(x=0,1)
  336. \param[in] mailbox_number
  337. \arg CAN_MAILBOX(x=0,1,2)
  338. \param[out] none
  339. \retval can_transmit_state_enum
  340. */
  341. can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number)
  342. {
  343. can_transmit_state_enum state = CAN_TRANSMIT_FAILED;
  344. uint32_t val = 0U;
  345. switch(mailbox_number){
  346. case CAN_MAILBOX0:
  347. val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0);
  348. break;
  349. case CAN_MAILBOX1:
  350. val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1);
  351. break;
  352. case CAN_MAILBOX2:
  353. val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2);
  354. break;
  355. default:
  356. val = CAN_TRANSMIT_FAILED;
  357. break;
  358. }
  359. switch(val){
  360. /* transmit pending */
  361. case (CAN_STATE_PENDING):
  362. state = CAN_TRANSMIT_PENDING;
  363. break;
  364. /* transmit failed */
  365. case (CAN_TSTAT_MTF0 | CAN_TSTAT_TME0):
  366. state = CAN_TRANSMIT_FAILED;
  367. break;
  368. case (CAN_TSTAT_MTF1 | CAN_TSTAT_TME1):
  369. state = CAN_TRANSMIT_FAILED;
  370. break;
  371. case (CAN_TSTAT_MTF2 | CAN_TSTAT_TME2):
  372. state = CAN_TRANSMIT_FAILED;
  373. break;
  374. /* transmit succeeded */
  375. case (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0):
  376. state = CAN_TRANSMIT_OK;
  377. break;
  378. case (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1):
  379. state = CAN_TRANSMIT_OK;
  380. break;
  381. case (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2):
  382. state = CAN_TRANSMIT_OK;
  383. break;
  384. default:
  385. state = CAN_TRANSMIT_FAILED;
  386. break;
  387. }
  388. return state;
  389. }
  390. /*!
  391. \brief CAN stop transmission
  392. \param[in] can_periph
  393. \arg CANx(x=0,1)
  394. \param[in] mailbox_number
  395. \arg CAN_MAILBOXx(x=0,1,2)
  396. \param[out] none
  397. \retval none
  398. */
  399. void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number)
  400. {
  401. if(CAN_MAILBOX0 == mailbox_number){
  402. CAN_TSTAT(can_periph) |= CAN_TSTAT_MST0;
  403. }else if(CAN_MAILBOX1 == mailbox_number){
  404. CAN_TSTAT(can_periph) |= CAN_TSTAT_MST1;
  405. }else if(CAN_MAILBOX2 == mailbox_number){
  406. CAN_TSTAT(can_periph) |= CAN_TSTAT_MST2;
  407. }else{
  408. /* illegal parameter*/
  409. }
  410. }
  411. /*!
  412. \brief CAN receive message
  413. \param[in] can_periph
  414. \arg CANx(x=0,1)
  415. \param[in] fifo_number
  416. \arg CAN_FIFO0x(x=0,1)
  417. \param[out] can_receive_message_struct: struct for CAN receive message
  418. can_rx_sfid: 0x00000000 - 0x000007FF
  419. can_rx_efid: 0x00000000 - 0x1FFFFFFF
  420. can_rx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
  421. can_rx_ft: CAN_FT_DATA, CAN_FT_REMOTE
  422. can_rx_dlenc: 1 - 7
  423. can_rx_data[]: 0x00 - 0xFF
  424. can_rx_fi: 0 - 27
  425. \retval none
  426. */
  427. void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct* receive_message)
  428. {
  429. /* get the frame format */
  430. receive_message->rx_ff = (uint8_t)(CAN_RFIFOMI_FF & CAN_RFIFOMI(can_periph, fifo_number));
  431. if(CAN_FF_STANDARD == receive_message->rx_ff){
  432. /* get standard identifier */
  433. receive_message -> rx_sfid = (uint32_t)(RFIFOMI_SFID(CAN_RFIFOMI(can_periph, fifo_number)));
  434. }else{
  435. /* get extended identifier */
  436. receive_message -> rx_efid = (uint32_t)(RFIFOMI_EFID(CAN_RFIFOMI(can_periph, fifo_number)));
  437. }
  438. /* get frame type */
  439. receive_message -> rx_ft = (uint8_t)(CAN_RFIFOMI_FT & CAN_RFIFOMI(can_periph, fifo_number));
  440. /* get recevie data length */
  441. receive_message -> rx_dlen = (uint8_t)(RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number)));
  442. /* filtering index */
  443. receive_message -> rx_fi = (uint8_t)(RFIFOMP_FI(CAN_RFIFOMP(can_periph, fifo_number)));
  444. /* receive data */
  445. receive_message -> rx_data[0] = (uint8_t)(RFIFOMDATA0_DB0(CAN_RFIFOMDATA0(can_periph, fifo_number)));
  446. receive_message -> rx_data[1] = (uint8_t)(RFIFOMDATA0_DB1(CAN_RFIFOMDATA0(can_periph, fifo_number)));
  447. receive_message -> rx_data[2] = (uint8_t)(RFIFOMDATA0_DB2(CAN_RFIFOMDATA0(can_periph, fifo_number)));
  448. receive_message -> rx_data[3] = (uint8_t)(RFIFOMDATA0_DB3(CAN_RFIFOMDATA0(can_periph, fifo_number)));
  449. receive_message -> rx_data[4] = (uint8_t)(RFIFOMDATA1_DB4(CAN_RFIFOMDATA1(can_periph, fifo_number)));
  450. receive_message -> rx_data[5] = (uint8_t)(RFIFOMDATA1_DB5(CAN_RFIFOMDATA1(can_periph, fifo_number)));
  451. receive_message -> rx_data[6] = (uint8_t)(RFIFOMDATA1_DB6(CAN_RFIFOMDATA1(can_periph, fifo_number)));
  452. receive_message -> rx_data[7] = (uint8_t)(RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number)));
  453. /* release FIFO */
  454. if(CAN_FIFO0 == fifo_number){
  455. CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0;
  456. }else{
  457. CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1;
  458. }
  459. }
  460. /*!
  461. \brief release FIFO0
  462. \param[in] can_periph
  463. \arg CANx(x=0,1)
  464. \arg CAN_FIFO0x(x=0,1)
  465. \param[out] none
  466. \retval none
  467. */
  468. void can_fifo_release(uint32_t can_periph, uint8_t fifo_number)
  469. {
  470. if(CAN_FIFO0 == fifo_number){
  471. CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0;
  472. }else if(CAN_FIFO1 == fifo_number){
  473. CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1;
  474. }else{
  475. /* illegal parameter */
  476. }
  477. }
  478. /*!
  479. \brief CAN receive message length
  480. \param[in] can_periph
  481. \arg CANx(x=0,1)
  482. \arg CAN_FIFO0x(x=0,1)
  483. \param[out] none
  484. \retval message length
  485. */
  486. uint8_t can_receive_message_length(uint32_t can_periph, uint8_t fifo_number)
  487. {
  488. uint8_t val = 0U;
  489. if(CAN_FIFO0 == fifo_number){
  490. val = (uint8_t)(CAN_RFIFO0(can_periph) & CAN_RFIFO_RFL0_MASK);
  491. }else if(CAN_FIFO0 == fifo_number){
  492. val = (uint8_t)(CAN_RFIFO1(can_periph) & CAN_RFIFO_RFL0_MASK);
  493. }else{
  494. /* illegal parameter */
  495. }
  496. return val;
  497. }
  498. /*!
  499. \brief set CAN working mode
  500. \param[in] can_periph
  501. \arg CANx(x=0,1)
  502. \param[in] can_working_mode
  503. \arg CAN_INITIALIZE_MODE
  504. \arg CAN_NORMAL_MODE
  505. \arg CAN_SLEEP_MODE
  506. \param[out] none
  507. \retval ErrStatus: SUCCESS or ERROR
  508. */
  509. ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode)
  510. {
  511. ErrStatus flag = ERROR;
  512. /* timeout for IWS or also for SLPWS bits*/
  513. uint32_t timeout = CAN_TIMEOUT;
  514. if(CAN_MODE_INITIALIZE == working_mode){
  515. /* disable sleep mode */
  516. CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_SLPWMOD);
  517. /* set initialize mode */
  518. CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_IWMOD;
  519. /* wait the acknowledge */
  520. while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (timeout != 0U)){
  521. timeout--;
  522. }
  523. if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){
  524. flag = ERROR;
  525. }else{
  526. flag = SUCCESS;
  527. }
  528. }else if(CAN_MODE_NORMAL == working_mode){
  529. /* enter normal mode */
  530. CAN_CTL(can_periph) &= ~(uint32_t)(CAN_CTL_SLPWMOD | CAN_CTL_IWMOD);
  531. /* wait the acknowledge */
  532. while((0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) && (timeout != 0U)){
  533. timeout--;
  534. }
  535. if(0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))){
  536. flag = ERROR;
  537. }else{
  538. flag = SUCCESS;
  539. }
  540. }else if(CAN_MODE_SLEEP == working_mode){
  541. /* disable initialize mode */
  542. CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_IWMOD);
  543. /* set sleep mode */
  544. CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_SLPWMOD;
  545. /* wait the acknowledge */
  546. while((CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (timeout != 0U)){
  547. timeout--;
  548. }
  549. if (CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){
  550. flag = ERROR;
  551. }else{
  552. flag = SUCCESS;
  553. }
  554. }else{
  555. flag = ERROR;
  556. }
  557. return flag;
  558. }
  559. /*!
  560. \brief wake up CAN
  561. \param[in] can_periph
  562. \arg CANx(x=0,1)
  563. \param[out] none
  564. \retval ErrStatus: SUCCESS or ERROR
  565. */
  566. ErrStatus can_wakeup(uint32_t can_periph)
  567. {
  568. ErrStatus flag = ERROR;
  569. uint32_t timeout = CAN_TIMEOUT;
  570. /* wakeup */
  571. CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
  572. while((0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (timeout != 0x00U)){
  573. timeout--;
  574. }
  575. if(0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){
  576. flag = ERROR;
  577. }else{
  578. flag = SUCCESS;
  579. }
  580. return flag;
  581. }
  582. /*!
  583. \brief get CAN error type
  584. \param[in] can_periph
  585. \arg CANx(x=0,1)
  586. \param[out] none
  587. \retval can_error_enum
  588. */
  589. can_error_enum can_error_get(uint32_t can_periph)
  590. {
  591. can_error_enum error;
  592. error = CAN_ERROR_NONE;
  593. /* get error type */
  594. error = (can_error_enum)((CAN_ERR(can_periph) & CAN_ERR_ERRN) >> 4U);
  595. return error;
  596. }
  597. /*!
  598. \brief CAN receive error number
  599. \param[in] can_periph
  600. \arg CANx(x=0,1)
  601. \param[out] none
  602. \retval error number
  603. */
  604. uint8_t can_receive_error_number(uint32_t can_periph)
  605. {
  606. uint8_t val;
  607. val = (uint8_t)((CAN_ERR(can_periph) & CAN_ERR_RECNT) >> 24U);
  608. return val;
  609. }
  610. /*!
  611. \brief CAN transmit error number
  612. \param[in] can_periph
  613. \arg CANx(x=0,1)
  614. \param[out] none
  615. \retval error number
  616. */
  617. uint8_t can_transmit_error_number(uint32_t can_periph)
  618. {
  619. uint8_t val;
  620. val = (uint8_t)((CAN_ERR(can_periph) & CAN_ERR_TECNT) >> 16U);
  621. return val;
  622. }
  623. /*!
  624. \brief enable CAN interrupt
  625. \param[in] can_periph
  626. \arg CANx(x=0,1)
  627. \param[in] interrupt
  628. \arg CAN_INTEN_TMEIE
  629. \arg CAN_INTEN_RFNEIE0
  630. \arg CAN_INTEN_RFFIE0
  631. \arg CAN_INTEN_RFOIE0
  632. \arg CAN_INTEN_RFNEIE1
  633. \arg CAN_INTEN_RFFIE1
  634. \arg CAN_INTEN_RFOIE1
  635. \arg CAN_INTEN_WERRIE
  636. \arg CAN_INTEN_PERRIE
  637. \arg CAN_INTEN_BOIE
  638. \arg CAN_INTEN_ERRNIE
  639. \arg CAN_INTEN_ERRIE
  640. \arg CAN_INTEN_WUIE
  641. \arg CAN_INTEN_SLPWIE
  642. \param[out] none
  643. \retval none
  644. */
  645. void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt)
  646. {
  647. CAN_INTEN(can_periph) |= interrupt;
  648. }
  649. /*!
  650. \brief disable CAN interrupt
  651. \param[in] can_periph
  652. \arg CANx(x=0,1)
  653. \param[in] interrupt
  654. \arg CAN_INTEN_TMEIE
  655. \arg CAN_INTEN_RFNEIE0
  656. \arg CAN_INTEN_RFFIE0
  657. \arg CAN_INTEN_RFOIE0
  658. \arg CAN_INTEN_RFNEIE1
  659. \arg CAN_INTEN_RFFIE1
  660. \arg CAN_INTEN_RFOIE1
  661. \arg CAN_INTEN_WERRIE
  662. \arg CAN_INTEN_PERRIE
  663. \arg CAN_INTEN_BOIE
  664. \arg CAN_INTEN_ERRNIE
  665. \arg CAN_INTEN_ERRIE
  666. \arg CAN_INTEN_WUIE
  667. \arg CAN_INTEN_SLPWIE
  668. \param[out] none
  669. \retval none
  670. */
  671. void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt)
  672. {
  673. CAN_INTEN(can_periph) &= ~interrupt;
  674. }
  675. /*!
  676. \brief get CAN flag state
  677. \param[in] can_periph
  678. \arg CANx(x=0,1)
  679. \param[in] flag: CAN flags, refer to can_flag_enum
  680. only one parameter can be selected which is shown as below:
  681. \arg CAN_FLAG_MTE2
  682. \arg CAN_FLAG_MTE1
  683. \arg CAN_FLAG_MTE0
  684. \arg CAN_FLAG_MTF2
  685. \arg CAN_FLAG_MTF1
  686. \arg CAN_FLAG_MTF0
  687. \arg CAN_FLAG_RFO0
  688. \arg CAN_FLAG_RFF0
  689. \arg CAN_FLAG_RFO1
  690. \arg CAN_FLAG_RFF1
  691. \arg CAN_FLAG_BOERR
  692. \arg CAN_FLAG_PERR
  693. \arg CAN_FLAG_WERR
  694. \param[out] none
  695. \retval FlagStatus: SET or RESET
  696. */
  697. FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag)
  698. {
  699. if(RESET != (CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)))){
  700. return SET;
  701. }else{
  702. return RESET;
  703. }
  704. }
  705. /*!
  706. \brief clear CAN flag state
  707. \param[in] can_periph
  708. \arg CANx(x=0,1)
  709. \param[in] flag: CAN flags, refer to can_flag_enum
  710. only one parameter can be selected which is shown as below:
  711. \arg CAN_FLAG_MTE2
  712. \arg CAN_FLAG_MTE1
  713. \arg CAN_FLAG_MTE0
  714. \arg CAN_FLAG_MTF2
  715. \arg CAN_FLAG_MTF1
  716. \arg CAN_FLAG_MTF0
  717. \arg CAN_FLAG_RFO0
  718. \arg CAN_FLAG_RFF0
  719. \arg CAN_FLAG_RFO1
  720. \arg CAN_FLAG_RFF1
  721. \param[out] none
  722. \retval none
  723. */
  724. void can_flag_clear(uint32_t can_periph, can_flag_enum flag)
  725. {
  726. CAN_REG_VAL(can_periph, flag) |= BIT(CAN_BIT_POS(flag));
  727. }
  728. /*!
  729. \brief get CAN interrupt flag state
  730. \param[in] can_periph
  731. \arg CANx(x=0,1)
  732. \param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum
  733. only one parameter can be selected which is shown as below:
  734. \arg CAN_INT_SLPIF
  735. \arg CAN_INT_WUIF
  736. \arg CAN_INT_ERRIF
  737. \param[out] none
  738. \retval FlagStatus: SET or RESET
  739. */
  740. FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag)
  741. {
  742. FlagStatus inten = RESET;
  743. FlagStatus temp = RESET;
  744. FlagStatus status1 = RESET;
  745. FlagStatus status2 = RESET;
  746. switch(flag){
  747. /* get the status of sleep working interrupt enable bit */
  748. case CAN_INT_SLPIF:
  749. inten = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_SLPWIE);
  750. break;
  751. /* get the status of wakeup interrupt enable bit */
  752. case CAN_INT_WUIF:
  753. inten = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_WUIE);
  754. break;
  755. /* get the status of error falgs and its enable bit */
  756. case CAN_INT_ERRIF:
  757. /* check if the BOERR bit in CAN_ERR register and BOIE bit in CAN_INTEN register are set */
  758. status1 = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_BOIE);
  759. status2 = (FlagStatus)(CAN_ERR(can_periph) & CAN_ERR_BOERR);
  760. if((RESET != status1) && (RESET != status2)){
  761. inten = SET;
  762. }
  763. /* check if the WERR bit in CAN_ERR register and WERRIE bit in CAN_INTEN register are set */
  764. status1 = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_WERRIE);
  765. status2 = (FlagStatus)(CAN_ERR(can_periph) & CAN_ERR_WERR);
  766. if((RESET != status1) && (RESET != status2)){
  767. inten = SET;
  768. }
  769. /* check if the PERR bit in CAN_ERR register and PERRIE bit in CAN_INTEN register are set */
  770. status1 = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_PERRIE);
  771. status2 = (FlagStatus)(CAN_ERR(can_periph) & CAN_ERR_PERR);
  772. if((RESET != status1) && (RESET != status2)){
  773. inten = SET;
  774. }
  775. /* check if the ERRN bit in CAN_ERR register and ERRNIE bit in CAN_INTEN register are set */
  776. status1 = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_ERRNIE);
  777. status2 = (FlagStatus)(CAN_ERR(can_periph) & CAN_ERR_ERRN);
  778. if((RESET != status1) && (RESET != status2)){
  779. inten = SET;
  780. }
  781. break;
  782. default:
  783. break;
  784. }
  785. /* get the interrupt flag */
  786. temp = (FlagStatus)(CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)));
  787. /* check the interrupt enable bit and corresponding flag bit are set */
  788. if((RESET != inten) && (RESET != temp)){
  789. return SET;
  790. }else{
  791. return RESET;
  792. }
  793. }
  794. /*!
  795. \brief clear CAN interrupt flag state
  796. \param[in] can_periph
  797. \arg CANx(x=0,1)
  798. \param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum
  799. only one parameter can be selected which is shown as below:
  800. \arg CAN_INT_SLPIF
  801. \arg CAN_INT_WUIF
  802. \arg CAN_INT_ERRIF
  803. \param[out] none
  804. \retval none
  805. */
  806. void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag)
  807. {
  808. CAN_REG_VAL(can_periph, flag) |= BIT(CAN_BIT_POS(flag));
  809. }