gd32f4xx_can.c 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027
  1. /*!
  2. \file gd32f4xx_can.c
  3. \brief CAN driver
  4. \version 2016-08-15, V1.0.0, firmware for GD32F4xx
  5. \version 2018-12-12, V2.0.0, firmware for GD32F4xx
  6. \version 2019-11-27, V2.0.1, firmware for GD32F4xx
  7. \version 2020-07-14, V2.0.2, firmware for GD32F4xx
  8. \version 2020-09-30, V2.1.0, firmware for GD32F4xx
  9. */
  10. /*
  11. Copyright (c) 2020, GigaDevice Semiconductor Inc.
  12. Redistribution and use in source and binary forms, with or without modification,
  13. are permitted provided that the following conditions are met:
  14. 1. Redistributions of source code must retain the above copyright notice, this
  15. list of conditions and the following disclaimer.
  16. 2. Redistributions in binary form must reproduce the above copyright notice,
  17. this list of conditions and the following disclaimer in the documentation
  18. and/or other materials provided with the distribution.
  19. 3. Neither the name of the copyright holder nor the names of its contributors
  20. may be used to endorse or promote products derived from this software without
  21. specific prior written permission.
  22. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  25. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  26. INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  27. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  28. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  29. WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  30. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  31. OF SUCH DAMAGE.
  32. */
  33. #include "gd32f4xx_can.h"
  34. #define CAN_ERROR_HANDLE(s) do{}while(1)
  35. /*!
  36. \brief deinitialize CAN
  37. \param[in] can_periph
  38. \arg CANx(x=0,1)
  39. \param[out] none
  40. \retval none
  41. */
  42. void can_deinit(uint32_t can_periph)
  43. {
  44. if(CAN0 == can_periph){
  45. rcu_periph_reset_enable(RCU_CAN0RST);
  46. rcu_periph_reset_disable(RCU_CAN0RST);
  47. }else{
  48. rcu_periph_reset_enable(RCU_CAN1RST);
  49. rcu_periph_reset_disable(RCU_CAN1RST);
  50. }
  51. }
  52. /*!
  53. \brief initialize CAN parameter struct with a default value
  54. \param[in] type: the type of CAN parameter struct
  55. only one parameter can be selected which is shown as below:
  56. \arg CAN_INIT_STRUCT: the CAN initial struct
  57. \arg CAN_FILTER_STRUCT: the CAN filter struct
  58. \arg CAN_TX_MESSAGE_STRUCT: the CAN TX message struct
  59. \arg CAN_RX_MESSAGE_STRUCT: the CAN RX message struct
  60. \param[in] p_struct: the pointer of the specific struct
  61. \param[out] none
  62. \retval none
  63. */
  64. void can_struct_para_init(can_struct_type_enum type, void* p_struct)
  65. {
  66. uint8_t i;
  67. /* get type of the struct */
  68. switch(type){
  69. /* used for can_init() */
  70. case CAN_INIT_STRUCT:
  71. ((can_parameter_struct*)p_struct)->auto_bus_off_recovery = DISABLE;
  72. ((can_parameter_struct*)p_struct)->no_auto_retrans = DISABLE;
  73. ((can_parameter_struct*)p_struct)->auto_wake_up = DISABLE;
  74. ((can_parameter_struct*)p_struct)->prescaler = 0x03FFU;
  75. ((can_parameter_struct*)p_struct)->rec_fifo_overwrite = DISABLE;
  76. ((can_parameter_struct*)p_struct)->resync_jump_width = CAN_BT_SJW_1TQ;
  77. ((can_parameter_struct*)p_struct)->time_segment_1 = CAN_BT_BS1_3TQ;
  78. ((can_parameter_struct*)p_struct)->time_segment_2 = CAN_BT_BS2_1TQ;
  79. ((can_parameter_struct*)p_struct)->time_triggered = DISABLE;
  80. ((can_parameter_struct*)p_struct)->trans_fifo_order = DISABLE;
  81. ((can_parameter_struct*)p_struct)->working_mode = CAN_NORMAL_MODE;
  82. break;
  83. /* used for can_filter_init() */
  84. case CAN_FILTER_STRUCT:
  85. ((can_filter_parameter_struct*)p_struct)->filter_bits = CAN_FILTERBITS_32BIT;
  86. ((can_filter_parameter_struct*)p_struct)->filter_enable = DISABLE;
  87. ((can_filter_parameter_struct*)p_struct)->filter_fifo_number = CAN_FIFO0;
  88. ((can_filter_parameter_struct*)p_struct)->filter_list_high = 0x0000U;
  89. ((can_filter_parameter_struct*)p_struct)->filter_list_low = 0x0000U;
  90. ((can_filter_parameter_struct*)p_struct)->filter_mask_high = 0x0000U;
  91. ((can_filter_parameter_struct*)p_struct)->filter_mask_low = 0x0000U;
  92. ((can_filter_parameter_struct*)p_struct)->filter_mode = CAN_FILTERMODE_MASK;
  93. ((can_filter_parameter_struct*)p_struct)->filter_number = 0U;
  94. break;
  95. /* used for can_message_transmit() */
  96. case CAN_TX_MESSAGE_STRUCT:
  97. for(i = 0U; i < 8U; i++){
  98. ((can_trasnmit_message_struct*)p_struct)->tx_data[i] = 0U;
  99. }
  100. ((can_trasnmit_message_struct*)p_struct)->tx_dlen = 0u;
  101. ((can_trasnmit_message_struct*)p_struct)->tx_efid = 0U;
  102. ((can_trasnmit_message_struct*)p_struct)->tx_ff = (uint8_t)CAN_FF_STANDARD;
  103. ((can_trasnmit_message_struct*)p_struct)->tx_ft = (uint8_t)CAN_FT_DATA;
  104. ((can_trasnmit_message_struct*)p_struct)->tx_sfid = 0U;
  105. break;
  106. /* used for can_message_receive() */
  107. case CAN_RX_MESSAGE_STRUCT:
  108. for(i = 0U; i < 8U; i++){
  109. ((can_receive_message_struct*)p_struct)->rx_data[i] = 0U;
  110. }
  111. ((can_receive_message_struct*)p_struct)->rx_dlen = 0U;
  112. ((can_receive_message_struct*)p_struct)->rx_efid = 0U;
  113. ((can_receive_message_struct*)p_struct)->rx_ff = (uint8_t)CAN_FF_STANDARD;
  114. ((can_receive_message_struct*)p_struct)->rx_fi = 0U;
  115. ((can_receive_message_struct*)p_struct)->rx_ft = (uint8_t)CAN_FT_DATA;
  116. ((can_receive_message_struct*)p_struct)->rx_sfid = 0U;
  117. break;
  118. default:
  119. CAN_ERROR_HANDLE("parameter is invalid \r\n");
  120. }
  121. }
  122. /*!
  123. \brief initialize CAN
  124. \param[in] can_periph
  125. \arg CANx(x=0,1)
  126. \param[in] can_parameter_init: parameters for CAN initializtion
  127. \arg working_mode: CAN_NORMAL_MODE, CAN_LOOPBACK_MODE, CAN_SILENT_MODE, CAN_SILENT_LOOPBACK_MODE
  128. \arg resync_jump_width: CAN_BT_SJW_xTQ(x=1, 2, 3, 4)
  129. \arg time_segment_1: CAN_BT_BS1_xTQ(1..16)
  130. \arg time_segment_2: CAN_BT_BS2_xTQ(1..8)
  131. \arg time_triggered: ENABLE or DISABLE
  132. \arg auto_bus_off_recovery: ENABLE or DISABLE
  133. \arg auto_wake_up: ENABLE or DISABLE
  134. \arg no_auto_retrans: ENABLE or DISABLE
  135. \arg rec_fifo_overwrite: ENABLE or DISABLE
  136. \arg trans_fifo_order: ENABLE or DISABLE
  137. \arg prescaler: 0x0001 - 0x0400
  138. \param[out] none
  139. \retval ErrStatus: SUCCESS or ERROR
  140. */
  141. ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init)
  142. {
  143. uint32_t timeout = CAN_TIMEOUT;
  144. ErrStatus flag = ERROR;
  145. /* disable sleep mode */
  146. CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
  147. /* enable initialize mode */
  148. CAN_CTL(can_periph) |= CAN_CTL_IWMOD;
  149. /* wait ACK */
  150. while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){
  151. timeout--;
  152. }
  153. /* check initialize working success */
  154. if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){
  155. flag = ERROR;
  156. }else{
  157. /* set the bit timing register */
  158. CAN_BT(can_periph) = (BT_MODE((uint32_t)can_parameter_init->working_mode) | \
  159. BT_SJW((uint32_t)can_parameter_init->resync_jump_width) | \
  160. BT_BS1((uint32_t)can_parameter_init->time_segment_1) | \
  161. BT_BS2((uint32_t)can_parameter_init->time_segment_2) | \
  162. BT_BAUDPSC(((uint32_t)(can_parameter_init->prescaler) - 1U)));
  163. /* time trigger communication mode */
  164. if(ENABLE == can_parameter_init->time_triggered){
  165. CAN_CTL(can_periph) |= CAN_CTL_TTC;
  166. }else{
  167. CAN_CTL(can_periph) &= ~CAN_CTL_TTC;
  168. }
  169. /* automatic bus-off managment */
  170. if(ENABLE == can_parameter_init->auto_bus_off_recovery){
  171. CAN_CTL(can_periph) |= CAN_CTL_ABOR;
  172. }else{
  173. CAN_CTL(can_periph) &= ~CAN_CTL_ABOR;
  174. }
  175. /* automatic wakeup mode */
  176. if(ENABLE == can_parameter_init->auto_wake_up){
  177. CAN_CTL(can_periph) |= CAN_CTL_AWU;
  178. }else{
  179. CAN_CTL(can_periph) &= ~CAN_CTL_AWU;
  180. }
  181. /* automatic retransmission mode disable*/
  182. if(ENABLE == can_parameter_init->no_auto_retrans){
  183. CAN_CTL(can_periph) |= CAN_CTL_ARD;
  184. }else{
  185. CAN_CTL(can_periph) &= ~CAN_CTL_ARD;
  186. }
  187. /* receive fifo overwrite mode */
  188. if(ENABLE == can_parameter_init->rec_fifo_overwrite){
  189. CAN_CTL(can_periph) |= CAN_CTL_RFOD;
  190. }else{
  191. CAN_CTL(can_periph) &= ~CAN_CTL_RFOD;
  192. }
  193. /* transmit fifo order */
  194. if(ENABLE == can_parameter_init->trans_fifo_order){
  195. CAN_CTL(can_periph) |= CAN_CTL_TFO;
  196. }else{
  197. CAN_CTL(can_periph) &= ~CAN_CTL_TFO;
  198. }
  199. /* disable initialize mode */
  200. CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD;
  201. timeout = CAN_TIMEOUT;
  202. /* wait the ACK */
  203. while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){
  204. timeout--;
  205. }
  206. /* check exit initialize mode */
  207. if(CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)){
  208. flag = SUCCESS;
  209. }
  210. }
  211. return flag;
  212. }
  213. /*!
  214. \brief initialize CAN filter
  215. \param[in] can_filter_parameter_init: struct for CAN filter initialization
  216. \arg filter_list_high: 0x0000 - 0xFFFF
  217. \arg filter_list_low: 0x0000 - 0xFFFF
  218. \arg filter_mask_high: 0x0000 - 0xFFFF
  219. \arg filter_mask_low: 0x0000 - 0xFFFF
  220. \arg filter_fifo_number: CAN_FIFO0, CAN_FIFO1
  221. \arg filter_number: 0 - 27
  222. \arg filter_mode: CAN_FILTERMODE_MASK, CAN_FILTERMODE_LIST
  223. \arg filter_bits: CAN_FILTERBITS_32BIT, CAN_FILTERBITS_16BIT
  224. \arg filter_enable: ENABLE or DISABLE
  225. \param[out] none
  226. \retval none
  227. */
  228. void can_filter_init(can_filter_parameter_struct* can_filter_parameter_init)
  229. {
  230. uint32_t val = 0U;
  231. val = ((uint32_t)1) << (can_filter_parameter_init->filter_number);
  232. /* filter lock disable */
  233. CAN_FCTL(CAN0) |= CAN_FCTL_FLD;
  234. /* disable filter */
  235. CAN_FW(CAN0) &= ~(uint32_t)val;
  236. /* filter 16 bits */
  237. if(CAN_FILTERBITS_16BIT == can_filter_parameter_init->filter_bits){
  238. /* set filter 16 bits */
  239. CAN_FSCFG(CAN0) &= ~(uint32_t)val;
  240. /* first 16 bits list and first 16 bits mask or first 16 bits list and second 16 bits list */
  241. CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \
  242. FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS) | \
  243. FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS);
  244. /* second 16 bits list and second 16 bits mask or third 16 bits list and fourth 16 bits list */
  245. CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \
  246. FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | \
  247. FDATA_MASK_LOW((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS);
  248. }
  249. /* filter 32 bits */
  250. if(CAN_FILTERBITS_32BIT == can_filter_parameter_init->filter_bits){
  251. /* set filter 32 bits */
  252. CAN_FSCFG(CAN0) |= (uint32_t)val;
  253. /* 32 bits list or first 32 bits list */
  254. CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \
  255. FDATA_MASK_HIGH((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS) |
  256. FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS);
  257. /* 32 bits mask or second 32 bits list */
  258. CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \
  259. FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) |
  260. FDATA_MASK_LOW((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS);
  261. }
  262. /* filter mode */
  263. if(CAN_FILTERMODE_MASK == can_filter_parameter_init->filter_mode){
  264. /* mask mode */
  265. CAN_FMCFG(CAN0) &= ~(uint32_t)val;
  266. }else{
  267. /* list mode */
  268. CAN_FMCFG(CAN0) |= (uint32_t)val;
  269. }
  270. /* filter FIFO */
  271. if(CAN_FIFO0 == (can_filter_parameter_init->filter_fifo_number)){
  272. /* FIFO0 */
  273. CAN_FAFIFO(CAN0) &= ~(uint32_t)val;
  274. }
  275. if(CAN_FIFO1 == can_filter_parameter_init->filter_fifo_number){
  276. /* FIFO1 */
  277. CAN_FAFIFO(CAN0) |= (uint32_t)val;
  278. }
  279. /* filter working */
  280. if(ENABLE == can_filter_parameter_init->filter_enable){
  281. CAN_FW(CAN0) |= (uint32_t)val;
  282. }
  283. /* filter lock enable */
  284. CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD;
  285. }
  286. /*!
  287. \brief set CAN1 fliter start bank number
  288. \param[in] can1_start_bank_number
  289. \arg (1..27)
  290. \param[out] none
  291. \retval none
  292. */
  293. void can1_filter_start_bank(uint8_t start_bank)
  294. {
  295. /* filter lock disable */
  296. CAN_FCTL(CAN0) |= CAN_FCTL_FLD;
  297. /* set CAN1 filter start number */
  298. CAN_FCTL(CAN0) &= ~(uint32_t)CAN_FCTL_HBC1F;
  299. CAN_FCTL(CAN0) |= FCTL_HBC1F(start_bank);
  300. /* filter lock enaable */
  301. CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD;
  302. }
  303. /*!
  304. \brief enable CAN debug freeze
  305. \param[in] can_periph
  306. \arg CANx(x=0,1)
  307. \param[out] none
  308. \retval none
  309. */
  310. void can_debug_freeze_enable(uint32_t can_periph)
  311. {
  312. CAN_CTL(can_periph) |= CAN_CTL_DFZ;
  313. if(CAN0 == can_periph){
  314. dbg_periph_enable(DBG_CAN0_HOLD);
  315. }else{
  316. dbg_periph_enable(DBG_CAN1_HOLD);
  317. }
  318. }
  319. /*!
  320. \brief disable CAN debug freeze
  321. \param[in] can_periph
  322. \arg CANx(x=0,1)
  323. \param[out] none
  324. \retval none
  325. */
  326. void can_debug_freeze_disable(uint32_t can_periph)
  327. {
  328. CAN_CTL(can_periph) &= ~CAN_CTL_DFZ;
  329. if(CAN0 == can_periph){
  330. dbg_periph_disable(DBG_CAN0_HOLD);
  331. }else{
  332. dbg_periph_disable(DBG_CAN0_HOLD);
  333. }
  334. }
  335. /*!
  336. \brief enable CAN time trigger mode
  337. \param[in] can_periph
  338. \arg CANx(x=0,1)
  339. \param[out] none
  340. \retval none
  341. */
  342. void can_time_trigger_mode_enable(uint32_t can_periph)
  343. {
  344. uint8_t mailbox_number;
  345. /* enable the tcc mode */
  346. CAN_CTL(can_periph) |= CAN_CTL_TTC;
  347. /* enable time stamp */
  348. for(mailbox_number = 0U; mailbox_number < 3U; mailbox_number++){
  349. CAN_TMP(can_periph, mailbox_number) |= CAN_TMP_TSEN;
  350. }
  351. }
  352. /*!
  353. \brief disable CAN time trigger mode
  354. \param[in] can_periph
  355. \arg CANx(x=0,1)
  356. \param[out] none
  357. \retval none
  358. */
  359. void can_time_trigger_mode_disable(uint32_t can_periph)
  360. {
  361. uint8_t mailbox_number;
  362. /* disable the TCC mode */
  363. CAN_CTL(can_periph) &= ~CAN_CTL_TTC;
  364. /* reset TSEN bits */
  365. for(mailbox_number = 0U; mailbox_number < 3U; mailbox_number++){
  366. CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_TSEN;
  367. }
  368. }
  369. /*!
  370. \brief transmit CAN message
  371. \param[in] can_periph
  372. \arg CANx(x=0,1)
  373. \param[in] transmit_message: struct for CAN transmit message
  374. \arg tx_sfid: 0x00000000 - 0x000007FF
  375. \arg tx_efid: 0x00000000 - 0x1FFFFFFF
  376. \arg tx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
  377. \arg tx_ft: CAN_FT_DATA, CAN_FT_REMOTE
  378. \arg tx_dlen: 0 - 8
  379. \arg tx_data[]: 0x00 - 0xFF
  380. \param[out] none
  381. \retval mailbox_number
  382. */
  383. uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* transmit_message)
  384. {
  385. uint8_t mailbox_number = CAN_MAILBOX0;
  386. /* select one empty mailbox */
  387. if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)){
  388. mailbox_number = CAN_MAILBOX0;
  389. }else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)){
  390. mailbox_number = CAN_MAILBOX1;
  391. }else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)){
  392. mailbox_number = CAN_MAILBOX2;
  393. }else{
  394. mailbox_number = CAN_NOMAILBOX;
  395. }
  396. /* return no mailbox empty */
  397. if(CAN_NOMAILBOX == mailbox_number){
  398. return CAN_NOMAILBOX;
  399. }
  400. CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN;
  401. if(CAN_FF_STANDARD == transmit_message->tx_ff){
  402. /* set transmit mailbox standard identifier */
  403. CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | \
  404. transmit_message->tx_ft);
  405. }else{
  406. /* set transmit mailbox extended identifier */
  407. CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | \
  408. transmit_message->tx_ff | \
  409. transmit_message->tx_ft);
  410. }
  411. /* set the data length */
  412. transmit_message->tx_dlen &= (uint8_t)(CAN_TMP_DLENC);
  413. CAN_TMP(can_periph, mailbox_number) &= ((uint32_t)~CAN_TMP_DLENC);
  414. CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen;
  415. /* set the data */
  416. CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \
  417. TMDATA0_DB2(transmit_message->tx_data[2]) | \
  418. TMDATA0_DB1(transmit_message->tx_data[1]) | \
  419. TMDATA0_DB0(transmit_message->tx_data[0]);
  420. CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \
  421. TMDATA1_DB6(transmit_message->tx_data[6]) | \
  422. TMDATA1_DB5(transmit_message->tx_data[5]) | \
  423. TMDATA1_DB4(transmit_message->tx_data[4]);
  424. /* enable transmission */
  425. CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN;
  426. return mailbox_number;
  427. }
  428. /*!
  429. \brief get CAN transmit state
  430. \param[in] can_periph
  431. \arg CANx(x=0,1)
  432. \param[in] mailbox_number
  433. only one parameter can be selected which is shown as below:
  434. \arg CAN_MAILBOX(x=0,1,2)
  435. \param[out] none
  436. \retval can_transmit_state_enum
  437. */
  438. can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number)
  439. {
  440. can_transmit_state_enum state = CAN_TRANSMIT_FAILED;
  441. uint32_t val = 0U;
  442. /* check selected mailbox state */
  443. switch(mailbox_number){
  444. /* mailbox0 */
  445. case CAN_MAILBOX0:
  446. val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0);
  447. break;
  448. /* mailbox1 */
  449. case CAN_MAILBOX1:
  450. val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1);
  451. break;
  452. /* mailbox2 */
  453. case CAN_MAILBOX2:
  454. val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2);
  455. break;
  456. default:
  457. val = CAN_TRANSMIT_FAILED;
  458. break;
  459. }
  460. switch(val){
  461. /* transmit pending */
  462. case (CAN_STATE_PENDING):
  463. state = CAN_TRANSMIT_PENDING;
  464. break;
  465. /* transmit failed */
  466. case (CAN_TSTAT_MTF0 | CAN_TSTAT_TME0):
  467. state = CAN_TRANSMIT_FAILED;
  468. break;
  469. case (CAN_TSTAT_MTF1 | CAN_TSTAT_TME1):
  470. state = CAN_TRANSMIT_FAILED;
  471. break;
  472. case (CAN_TSTAT_MTF2 | CAN_TSTAT_TME2):
  473. state = CAN_TRANSMIT_FAILED;
  474. break;
  475. /* transmit succeeded */
  476. case (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0):
  477. state = CAN_TRANSMIT_OK;
  478. break;
  479. /* mailbox1 transmit succeeded */
  480. case (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1):
  481. state = CAN_TRANSMIT_OK;
  482. break;
  483. /* mailbox2 transmit succeeded */
  484. case (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2):
  485. state = CAN_TRANSMIT_OK;
  486. break;
  487. /* transmit failed */
  488. default:
  489. state = CAN_TRANSMIT_FAILED;
  490. break;
  491. }
  492. return state;
  493. }
  494. /*!
  495. \brief stop CAN transmission
  496. \param[in] can_periph
  497. \arg CANx(x=0,1)
  498. \param[in] mailbox_number
  499. only one parameter can be selected which is shown as below:
  500. \arg CAN_MAILBOXx(x=0,1,2)
  501. \param[out] none
  502. \retval none
  503. */
  504. void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number)
  505. {
  506. if(CAN_MAILBOX0 == mailbox_number){
  507. CAN_TSTAT(can_periph) |= CAN_TSTAT_MST0;
  508. while(CAN_TSTAT_MST0 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST0)){
  509. }
  510. }else if(CAN_MAILBOX1 == mailbox_number){
  511. CAN_TSTAT(can_periph) |= CAN_TSTAT_MST1;
  512. while(CAN_TSTAT_MST1 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST1)){
  513. }
  514. }else if(CAN_MAILBOX2 == mailbox_number){
  515. CAN_TSTAT(can_periph) |= CAN_TSTAT_MST2;
  516. while(CAN_TSTAT_MST2 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST2)){
  517. }
  518. }else{
  519. /* illegal parameters */
  520. }
  521. }
  522. /*!
  523. \brief CAN receive message
  524. \param[in] can_periph
  525. \arg CANx(x=0,1)
  526. \param[in] fifo_number
  527. \arg CAN_FIFOx(x=0,1)
  528. \param[out] receive_message: struct for CAN receive message
  529. \arg rx_sfid: 0x00000000 - 0x000007FF
  530. \arg rx_efid: 0x00000000 - 0x1FFFFFFF
  531. \arg rx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
  532. \arg rx_ft: CAN_FT_DATA, CAN_FT_REMOTE
  533. \arg rx_dlen: 0 - 8
  534. \arg rx_data[]: 0x00 - 0xFF
  535. \arg rx_fi: 0 - 27
  536. \retval none
  537. */
  538. void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct* receive_message)
  539. {
  540. /* get the frame format */
  541. receive_message->rx_ff = (uint8_t)(CAN_RFIFOMI_FF & CAN_RFIFOMI(can_periph, fifo_number));
  542. if(CAN_FF_STANDARD == receive_message->rx_ff){
  543. /* get standard identifier */
  544. receive_message->rx_sfid = (uint32_t)(GET_RFIFOMI_SFID(CAN_RFIFOMI(can_periph, fifo_number)));
  545. }else{
  546. /* get extended identifier */
  547. receive_message->rx_efid = (uint32_t)(GET_RFIFOMI_EFID(CAN_RFIFOMI(can_periph, fifo_number)));
  548. }
  549. /* get frame type */
  550. receive_message->rx_ft = (uint8_t)(CAN_RFIFOMI_FT & CAN_RFIFOMI(can_periph, fifo_number));
  551. /* filtering index */
  552. receive_message->rx_fi = (uint8_t)(GET_RFIFOMP_FI(CAN_RFIFOMP(can_periph, fifo_number)));
  553. /* get recevie data length */
  554. receive_message->rx_dlen = (uint8_t)(GET_RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number)));
  555. /* receive data */
  556. receive_message -> rx_data[0] = (uint8_t)(GET_RFIFOMDATA0_DB0(CAN_RFIFOMDATA0(can_periph, fifo_number)));
  557. receive_message -> rx_data[1] = (uint8_t)(GET_RFIFOMDATA0_DB1(CAN_RFIFOMDATA0(can_periph, fifo_number)));
  558. receive_message -> rx_data[2] = (uint8_t)(GET_RFIFOMDATA0_DB2(CAN_RFIFOMDATA0(can_periph, fifo_number)));
  559. receive_message -> rx_data[3] = (uint8_t)(GET_RFIFOMDATA0_DB3(CAN_RFIFOMDATA0(can_periph, fifo_number)));
  560. receive_message -> rx_data[4] = (uint8_t)(GET_RFIFOMDATA1_DB4(CAN_RFIFOMDATA1(can_periph, fifo_number)));
  561. receive_message -> rx_data[5] = (uint8_t)(GET_RFIFOMDATA1_DB5(CAN_RFIFOMDATA1(can_periph, fifo_number)));
  562. receive_message -> rx_data[6] = (uint8_t)(GET_RFIFOMDATA1_DB6(CAN_RFIFOMDATA1(can_periph, fifo_number)));
  563. receive_message -> rx_data[7] = (uint8_t)(GET_RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number)));
  564. /* release FIFO */
  565. if(CAN_FIFO0 == fifo_number){
  566. CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0;
  567. }else{
  568. CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1;
  569. }
  570. }
  571. /*!
  572. \brief release FIFO0
  573. \param[in] can_periph
  574. \arg CANx(x=0,1)
  575. \param[in] fifo_number
  576. only one parameter can be selected which is shown as below:
  577. \arg CAN_FIFOx(x=0,1)
  578. \param[out] none
  579. \retval none
  580. */
  581. void can_fifo_release(uint32_t can_periph, uint8_t fifo_number)
  582. {
  583. if(CAN_FIFO0 == fifo_number){
  584. CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0;
  585. }else if(CAN_FIFO1 == fifo_number){
  586. CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1;
  587. }else{
  588. /* illegal parameters */
  589. CAN_ERROR_HANDLE("CAN FIFO NUM is invalid \r\n");
  590. }
  591. }
  592. /*!
  593. \brief CAN receive message length
  594. \param[in] can_periph
  595. \arg CANx(x=0,1)
  596. \param[in] fifo_number
  597. only one parameter can be selected which is shown as below:
  598. \arg CAN_FIFOx(x=0,1)
  599. \param[out] none
  600. \retval message length
  601. */
  602. uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number)
  603. {
  604. uint8_t val = 0U;
  605. if(CAN_FIFO0 == fifo_number){
  606. /* FIFO0 */
  607. val = (uint8_t)(CAN_RFIFO0(can_periph) & CAN_RFIF_RFL_MASK);
  608. }else if(CAN_FIFO1 == fifo_number){
  609. /* FIFO1 */
  610. val = (uint8_t)(CAN_RFIFO1(can_periph) & CAN_RFIF_RFL_MASK);
  611. }else{
  612. /* illegal parameters */
  613. }
  614. return val;
  615. }
  616. /*!
  617. \brief set CAN working mode
  618. \param[in] can_periph
  619. \arg CANx(x=0,1)
  620. \param[in] can_working_mode
  621. only one parameter can be selected which is shown as below:
  622. \arg CAN_MODE_INITIALIZE
  623. \arg CAN_MODE_NORMAL
  624. \arg CAN_MODE_SLEEP
  625. \param[out] none
  626. \retval ErrStatus: SUCCESS or ERROR
  627. */
  628. ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode)
  629. {
  630. ErrStatus flag = ERROR;
  631. /* timeout for IWS or also for SLPWS bits */
  632. uint32_t timeout = CAN_TIMEOUT;
  633. if(CAN_MODE_INITIALIZE == working_mode){
  634. /* disable sleep mode */
  635. CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_SLPWMOD);
  636. /* set initialize mode */
  637. CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_IWMOD;
  638. /* wait the acknowledge */
  639. while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){
  640. timeout--;
  641. }
  642. if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){
  643. flag = ERROR;
  644. }else{
  645. flag = SUCCESS;
  646. }
  647. }else if(CAN_MODE_NORMAL == working_mode){
  648. /* enter normal mode */
  649. CAN_CTL(can_periph) &= ~(uint32_t)(CAN_CTL_SLPWMOD | CAN_CTL_IWMOD);
  650. /* wait the acknowledge */
  651. while((0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) && (0U != timeout)){
  652. timeout--;
  653. }
  654. if(0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))){
  655. flag = ERROR;
  656. }else{
  657. flag = SUCCESS;
  658. }
  659. }else if(CAN_MODE_SLEEP == working_mode){
  660. /* disable initialize mode */
  661. CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_IWMOD);
  662. /* set sleep mode */
  663. CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_SLPWMOD;
  664. /* wait the acknowledge */
  665. while((CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0U != timeout)){
  666. timeout--;
  667. }
  668. if(CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){
  669. flag = ERROR;
  670. }else{
  671. flag = SUCCESS;
  672. }
  673. }else{
  674. flag = ERROR;
  675. }
  676. return flag;
  677. }
  678. /*!
  679. \brief wake up CAN
  680. \param[in] can_periph
  681. \arg CANx(x=0,1)
  682. \param[out] none
  683. \retval ErrStatus: SUCCESS or ERROR
  684. */
  685. ErrStatus can_wakeup(uint32_t can_periph)
  686. {
  687. ErrStatus flag = ERROR;
  688. uint32_t timeout = CAN_TIMEOUT;
  689. /* wakeup */
  690. CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
  691. while((0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0x00U != timeout)){
  692. timeout--;
  693. }
  694. /* check state */
  695. if(0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){
  696. flag = ERROR;
  697. }else{
  698. flag = SUCCESS;
  699. }
  700. return flag;
  701. }
  702. /*!
  703. \brief get CAN error type
  704. \param[in] can_periph
  705. \arg CANx(x=0,1)
  706. \param[out] none
  707. \retval can_error_enum
  708. \arg CAN_ERROR_NONE: no error
  709. \arg CAN_ERROR_FILL: fill error
  710. \arg CAN_ERROR_FORMATE: format error
  711. \arg CAN_ERROR_ACK: ACK error
  712. \arg CAN_ERROR_BITRECESSIVE: bit recessive
  713. \arg CAN_ERROR_BITDOMINANTER: bit dominant error
  714. \arg CAN_ERROR_CRC: CRC error
  715. \arg CAN_ERROR_SOFTWARECFG: software configure
  716. */
  717. can_error_enum can_error_get(uint32_t can_periph)
  718. {
  719. can_error_enum error;
  720. error = CAN_ERROR_NONE;
  721. /* get error type */
  722. error = (can_error_enum)(GET_ERR_ERRN(CAN_ERR(can_periph)));
  723. return error;
  724. }
  725. /*!
  726. \brief get CAN receive error number
  727. \param[in] can_periph
  728. \arg CANx(x=0,1)
  729. \param[out] none
  730. \retval error number
  731. */
  732. uint8_t can_receive_error_number_get(uint32_t can_periph)
  733. {
  734. uint8_t val;
  735. /* get error count */
  736. val = (uint8_t)(GET_ERR_RECNT(CAN_ERR(can_periph)));
  737. return val;
  738. }
  739. /*!
  740. \brief get CAN transmit error number
  741. \param[in] can_periph
  742. \arg CANx(x=0,1)
  743. \param[out] none
  744. \retval error number
  745. */
  746. uint8_t can_transmit_error_number_get(uint32_t can_periph)
  747. {
  748. uint8_t val;
  749. val = (uint8_t)(GET_ERR_TECNT(CAN_ERR(can_periph)));
  750. return val;
  751. }
  752. /*!
  753. \brief enable CAN interrupt
  754. \param[in] can_periph
  755. \arg CANx(x=0,1)
  756. \param[in] interrupt
  757. one or more parameters can be selected which are shown as below:
  758. \arg CAN_INT_TME: transmit mailbox empty interrupt enable
  759. \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable
  760. \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable
  761. \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable
  762. \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable
  763. \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable
  764. \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable
  765. \arg CAN_INT_WERR: warning error interrupt enable
  766. \arg CAN_INT_PERR: passive error interrupt enable
  767. \arg CAN_INT_BO: bus-off interrupt enable
  768. \arg CAN_INT_ERRN: error number interrupt enable
  769. \arg CAN_INT_ERR: error interrupt enable
  770. \arg CAN_INT_WU: wakeup interrupt enable
  771. \arg CAN_INT_SLPW: sleep working interrupt enable
  772. \param[out] none
  773. \retval none
  774. */
  775. void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt)
  776. {
  777. CAN_INTEN(can_periph) |= interrupt;
  778. }
  779. /*!
  780. \brief disable CAN interrupt
  781. \param[in] can_periph
  782. \arg CANx(x=0,1)
  783. \param[in] interrupt
  784. one or more parameters can be selected which are shown as below:
  785. \arg CAN_INT_TME: transmit mailbox empty interrupt enable
  786. \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable
  787. \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable
  788. \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable
  789. \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable
  790. \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable
  791. \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable
  792. \arg CAN_INT_WERR: warning error interrupt enable
  793. \arg CAN_INT_PERR: passive error interrupt enable
  794. \arg CAN_INT_BO: bus-off interrupt enable
  795. \arg CAN_INT_ERRN: error number interrupt enable
  796. \arg CAN_INT_ERR: error interrupt enable
  797. \arg CAN_INT_WU: wakeup interrupt enable
  798. \arg CAN_INT_SLPW: sleep working interrupt enable
  799. \param[out] none
  800. \retval none
  801. */
  802. void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt)
  803. {
  804. CAN_INTEN(can_periph) &= ~interrupt;
  805. }
  806. /*!
  807. \brief get CAN flag state
  808. \param[in] can_periph
  809. \arg CANx(x=0,1)
  810. \param[in] flag: CAN flags, refer to can_flag_enum
  811. only one parameter can be selected which is shown as below:
  812. \arg CAN_FLAG_RXL: RX level
  813. \arg CAN_FLAG_LASTRX: last sample value of RX pin
  814. \arg CAN_FLAG_RS: receiving state
  815. \arg CAN_FLAG_TS: transmitting state
  816. \arg CAN_FLAG_SLPIF: status change flag of entering sleep working mode
  817. \arg CAN_FLAG_WUIF: status change flag of wakeup from sleep working mode
  818. \arg CAN_FLAG_ERRIF: error flag
  819. \arg CAN_FLAG_SLPWS: sleep working state
  820. \arg CAN_FLAG_IWS: initial working state
  821. \arg CAN_FLAG_TMLS2: transmit mailbox 2 last sending in Tx FIFO
  822. \arg CAN_FLAG_TMLS1: transmit mailbox 1 last sending in Tx FIFO
  823. \arg CAN_FLAG_TMLS0: transmit mailbox 0 last sending in Tx FIFO
  824. \arg CAN_FLAG_TME2: transmit mailbox 2 empty
  825. \arg CAN_FLAG_TME1: transmit mailbox 1 empty
  826. \arg CAN_FLAG_TME0: transmit mailbox 0 empty
  827. \arg CAN_FLAG_MTE2: mailbox 2 transmit error
  828. \arg CAN_FLAG_MTE1: mailbox 1 transmit error
  829. \arg CAN_FLAG_MTE0: mailbox 0 transmit error
  830. \arg CAN_FLAG_MAL2: mailbox 2 arbitration lost
  831. \arg CAN_FLAG_MAL1: mailbox 1 arbitration lost
  832. \arg CAN_FLAG_MAL0: mailbox 0 arbitration lost
  833. \arg CAN_FLAG_MTFNERR2: mailbox 2 transmit finished with no error
  834. \arg CAN_FLAG_MTFNERR1: mailbox 1 transmit finished with no error
  835. \arg CAN_FLAG_MTFNERR0: mailbox 0 transmit finished with no error
  836. \arg CAN_FLAG_MTF2: mailbox 2 transmit finished
  837. \arg CAN_FLAG_MTF1: mailbox 1 transmit finished
  838. \arg CAN_FLAG_MTF0: mailbox 0 transmit finished
  839. \arg CAN_FLAG_RFO0: receive FIFO0 overfull
  840. \arg CAN_FLAG_RFF0: receive FIFO0 full
  841. \arg CAN_FLAG_RFO1: receive FIFO1 overfull
  842. \arg CAN_FLAG_RFF1: receive FIFO1 full
  843. \arg CAN_FLAG_BOERR: bus-off error
  844. \arg CAN_FLAG_PERR: passive error
  845. \arg CAN_FLAG_WERR: warning error
  846. \param[out] none
  847. \retval FlagStatus: SET or RESET
  848. */
  849. FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag)
  850. {
  851. /* get flag and interrupt enable state */
  852. if(RESET != (CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)))){
  853. return SET;
  854. }else{
  855. return RESET;
  856. }
  857. }
  858. /*!
  859. \brief clear CAN flag state
  860. \param[in] can_periph
  861. \arg CANx(x=0,1)
  862. \param[in] flag: CAN flags, refer to can_flag_enum
  863. only one parameter can be selected which is shown as below:
  864. \arg CAN_FLAG_SLPIF: status change flag of entering sleep working mode
  865. \arg CAN_FLAG_WUIF: status change flag of wakeup from sleep working mode
  866. \arg CAN_FLAG_ERRIF: error flag
  867. \arg CAN_FLAG_MTE2: mailbox 2 transmit error
  868. \arg CAN_FLAG_MTE1: mailbox 1 transmit error
  869. \arg CAN_FLAG_MTE0: mailbox 0 transmit error
  870. \arg CAN_FLAG_MAL2: mailbox 2 arbitration lost
  871. \arg CAN_FLAG_MAL1: mailbox 1 arbitration lost
  872. \arg CAN_FLAG_MAL0: mailbox 0 arbitration lost
  873. \arg CAN_FLAG_MTFNERR2: mailbox 2 transmit finished with no error
  874. \arg CAN_FLAG_MTFNERR1: mailbox 1 transmit finished with no error
  875. \arg CAN_FLAG_MTFNERR0: mailbox 0 transmit finished with no error
  876. \arg CAN_FLAG_MTF2: mailbox 2 transmit finished
  877. \arg CAN_FLAG_MTF1: mailbox 1 transmit finished
  878. \arg CAN_FLAG_MTF0: mailbox 0 transmit finished
  879. \arg CAN_FLAG_RFO0: receive FIFO0 overfull
  880. \arg CAN_FLAG_RFF0: receive FIFO0 full
  881. \arg CAN_FLAG_RFO1: receive FIFO1 overfull
  882. \arg CAN_FLAG_RFF1: receive FIFO1 full
  883. \param[out] none
  884. \retval none
  885. */
  886. void can_flag_clear(uint32_t can_periph, can_flag_enum flag)
  887. {
  888. CAN_REG_VAL(can_periph, flag) = BIT(CAN_BIT_POS(flag));
  889. }
  890. /*!
  891. \brief get CAN interrupt flag state
  892. \param[in] can_periph
  893. \arg CANx(x=0,1)
  894. \param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum
  895. only one parameter can be selected which is shown as below:
  896. \arg CAN_INT_FLAG_SLPIF: status change interrupt flag of sleep working mode entering
  897. \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode
  898. \arg CAN_INT_FLAG_ERRIF: error interrupt flag
  899. \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag
  900. \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag
  901. \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag
  902. \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag
  903. \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag
  904. \arg CAN_INT_FLAG_RFL0: receive FIFO0 not empty interrupt flag
  905. \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag
  906. \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag
  907. \arg CAN_INT_FLAG_RFL1: receive FIFO1 not empty interrupt flag
  908. \arg CAN_INT_FLAG_ERRN: error number interrupt flag
  909. \arg CAN_INT_FLAG_BOERR: bus-off error interrupt flag
  910. \arg CAN_INT_FLAG_PERR: passive error interrupt flag
  911. \arg CAN_INT_FLAG_WERR: warning error interrupt flag
  912. \param[out] none
  913. \retval FlagStatus: SET or RESET
  914. */
  915. FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag)
  916. {
  917. uint32_t ret1 = RESET;
  918. uint32_t ret2 = RESET;
  919. /* get the staus of interrupt flag */
  920. if (flag == CAN_INT_FLAG_RFF0) {
  921. ret1 = can_receive_message_length_get(can_periph, CAN_FIFO0);
  922. } else if (flag == CAN_INT_FLAG_RFF1) {
  923. ret1 = can_receive_message_length_get(can_periph, CAN_FIFO1);
  924. } else if (flag == CAN_INT_FLAG_ERRN) {
  925. ret1 = can_error_get(can_periph);
  926. } else {
  927. ret1 = CAN_REG_VALS(can_periph, flag) & BIT(CAN_BIT_POS0(flag));
  928. }
  929. /* get the staus of interrupt enale bit */
  930. ret2 = CAN_INTEN(can_periph) & BIT(CAN_BIT_POS1(flag));
  931. if(ret1 && ret2){
  932. return SET;
  933. }else{
  934. return RESET;
  935. }
  936. }
  937. /*!
  938. \brief clear CAN interrupt flag state
  939. \param[in] can_periph
  940. \arg CANx(x=0,1)
  941. \param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum
  942. only one parameter can be selected which is shown as below:
  943. \arg CAN_INT_FLAG_SLPIF: status change interrupt flag of sleep working mode entering
  944. \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode
  945. \arg CAN_INT_FLAG_ERRIF: error interrupt flag
  946. \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag
  947. \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag
  948. \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag
  949. \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag
  950. \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag
  951. \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag
  952. \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag
  953. \param[out] none
  954. \retval none
  955. */
  956. void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag)
  957. {
  958. CAN_REG_VALS(can_periph, flag) = BIT(CAN_BIT_POS0(flag));
  959. }