gd32f10x_can.c 37 KB

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