gd32vf103_can.c 37 KB

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