gd32f30x_can.c 45 KB

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