apm32f10x_can.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110
  1. /*!
  2. * @file apm32f10x_can.c
  3. *
  4. * @brief This file provides all the CAN firmware functions
  5. *
  6. * @version V1.0.1
  7. *
  8. * @date 2021-03-23
  9. *
  10. */
  11. #include "apm32f10x_can.h"
  12. #include "apm32f10x_rcm.h"
  13. /** @addtogroup Peripherals_Library Standard Peripheral Library
  14. @{
  15. */
  16. /** @addtogroup CAN_Driver CAN Driver
  17. @{
  18. */
  19. /** @addtogroup CAN_Fuctions Fuctions
  20. @{
  21. */
  22. /*!
  23. * @brief Reset CAN registers
  24. *
  25. * @param can: Select the CAN peripheral.
  26. *
  27. * @retval None
  28. *
  29. * @note CAN2 applies only to APM32F103xC device.
  30. */
  31. void CAN_Reset(CAN_T* can)
  32. {
  33. if (can == CAN1)
  34. {
  35. RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_CAN1);
  36. RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_CAN1);
  37. }
  38. else if (can == CAN2)
  39. {
  40. RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_CAN2);
  41. RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_CAN2);
  42. }
  43. }
  44. /*!
  45. * @brief Initialization parameter configuration
  46. *
  47. * @param can: Select the CAN peripheral which can be CAN1 or CAN2.
  48. *
  49. * @param canConfig: Point to a CAN_Config_T structure.
  50. *
  51. * @retval ERROR or SUCCEESS
  52. *
  53. * @note CAN2 applies only to APM32F103xC device.
  54. */
  55. uint8_t CAN_Config(CAN_T* can, CAN_Config_T* canConfig)
  56. {
  57. uint8_t initStatus = ERROR;
  58. uint32_t wait_ack = 0x00000000;
  59. /** Exit from sleep mode */
  60. can->MCTRL_B.SLEEPREQ = BIT_RESET;
  61. /** Request initialisation */
  62. can->MCTRL_B.INITREQ = BIT_SET;
  63. /** Wait the acknowledge */
  64. while(((can->MSTS_B.INITFLG) != BIT_SET) && (wait_ack != 0x0000FFFF))
  65. {
  66. wait_ack++;
  67. }
  68. /** Check acknowledge */
  69. if(((can->MSTS_B.INITFLG) != BIT_SET))
  70. {
  71. initStatus = ERROR;
  72. }
  73. else
  74. {
  75. if(canConfig->timeTrigComMode == ENABLE)
  76. {
  77. can->MCTRL_B.TTCM = BIT_SET;
  78. }
  79. else
  80. {
  81. can->MCTRL_B.TTCM = BIT_RESET;
  82. }
  83. if(canConfig->autoBusOffManage == ENABLE)
  84. {
  85. can->MCTRL_B.ALBOFFM = BIT_SET;
  86. }
  87. else
  88. {
  89. can->MCTRL_B.ALBOFFM = BIT_RESET;
  90. }
  91. if(canConfig->autoWakeUpMode == ENABLE)
  92. {
  93. can->MCTRL_B.AWUPCFG = BIT_SET;
  94. }
  95. else
  96. {
  97. can->MCTRL_B.AWUPCFG = BIT_RESET;
  98. }
  99. if(canConfig->nonAutoRetran == ENABLE)
  100. {
  101. can->MCTRL_B.ARTXMD = BIT_SET;
  102. }
  103. else
  104. {
  105. can->MCTRL_B.ARTXMD = BIT_RESET;
  106. }
  107. if(canConfig->rxFIFOLockMode == ENABLE)
  108. {
  109. can->MCTRL_B.RXFLOCK = BIT_SET;
  110. }
  111. else
  112. {
  113. can->MCTRL_B.RXFLOCK = BIT_RESET;
  114. }
  115. if(canConfig->txFIFOPriority == ENABLE)
  116. {
  117. can->MCTRL_B.TXFPCFG = BIT_SET;
  118. }
  119. else
  120. {
  121. can->MCTRL_B.TXFPCFG = BIT_RESET;
  122. }
  123. /** Set the bit timing register */
  124. can->BITTIM &= (uint32_t)0x3fffffff;
  125. can->BITTIM |= (uint32_t)canConfig->mode << 30;
  126. can->BITTIM_B.RSYNJW = canConfig->syncJumpWidth;
  127. can->BITTIM_B.TIMSEG1 = canConfig->timeSegment1;
  128. can->BITTIM_B.TIMSEG2 = canConfig->timeSegment2;
  129. can->BITTIM_B.BRPSC = canConfig->prescaler - 1;
  130. /** Request leave initialisation */
  131. can->MCTRL_B.INITREQ = BIT_RESET;
  132. wait_ack = 0;
  133. /** Wait the acknowledge */
  134. while(((can->MSTS_B.INITFLG) != BIT_RESET) && (wait_ack != 0x0000FFFF))
  135. {
  136. wait_ack++;
  137. }
  138. /** Check acknowledge */
  139. if(((can->MSTS_B.INITFLG) != BIT_RESET))
  140. {
  141. initStatus = ERROR;
  142. }
  143. else
  144. {
  145. initStatus = SUCCESS;
  146. }
  147. }
  148. return initStatus;
  149. }
  150. /*!
  151. * @brief Congig the CAN peripheral according to the specified parameters in the filterConfig.
  152. *
  153. * @param can: Select the CAN peripheral which can be CAN1 or CAN2.
  154. *
  155. * @param filterConfig :Point to a CAN_FILTER_CONFIG_T structure.
  156. *
  157. * @retval None
  158. *
  159. * @note CAN2 applies only to APM32F103xC device.
  160. */
  161. void CAN_ConfigFilter(CAN_T* can, CAN_FILTER_CONFIG_T* filterConfig)
  162. {
  163. can->FCTRL_B.FINITEN = BIT_SET;
  164. can->FACT &= ~(1 << filterConfig->filterNumber);
  165. /** Filter Scale */
  166. if(filterConfig->filterScale == CAN_FILTER_SCALE_16BIT)
  167. {
  168. /** 16-bit scale for the filter */
  169. can->FSCFG &= ~(1 << filterConfig->filterNumber);
  170. can->sFilterRegister[filterConfig->filterNumber].FBANK1 =
  171. ((0x0000FFFF & filterConfig->filterMaskIdLow) << 16) |
  172. (0x0000FFFF & filterConfig->filterIdLow);
  173. can->sFilterRegister[filterConfig->filterNumber].FBANK2 =
  174. ((0x0000FFFF & filterConfig->filterMaskIdHigh) << 16) |
  175. (0x0000FFFF & filterConfig->filterIdHigh);
  176. }
  177. if(filterConfig->filterScale == CAN_FILTER_SCALE_32BIT)
  178. {
  179. can->FSCFG |= (1 << filterConfig->filterNumber);
  180. can->sFilterRegister[filterConfig->filterNumber].FBANK1 =
  181. ((0x0000FFFF & filterConfig->filterIdHigh) << 16) |
  182. (0x0000FFFF & filterConfig->filterIdLow);
  183. can->sFilterRegister[filterConfig->filterNumber].FBANK2 =
  184. ((0x0000FFFF & filterConfig->filterMaskIdHigh) << 16) |
  185. (0x0000FFFF & filterConfig->filterMaskIdLow);
  186. }
  187. /** Filter Mode */
  188. if(filterConfig->filterMode == CAN_FILTER_MODE_IDMASK)
  189. {
  190. can->FMCFG &= ~(1 << filterConfig->filterNumber);
  191. }
  192. else
  193. {
  194. can->FMCFG |= (1 << filterConfig->filterNumber);
  195. }
  196. /** Filter FIFO assignment */
  197. if(filterConfig->filterFIFO == CAN_FILTER_FIFO_0)
  198. {
  199. can->FFASS &= ~(1 << filterConfig->filterNumber);
  200. }
  201. if(filterConfig->filterFIFO == CAN_FILTER_FIFO_1)
  202. {
  203. can->FFASS |= (1 << filterConfig->filterNumber);
  204. }
  205. /** Filter activation */
  206. if(filterConfig->filterActivation == ENABLE)
  207. {
  208. can->FACT |= (1 << filterConfig->filterNumber);
  209. }
  210. can->FCTRL_B.FINITEN = BIT_RESET;
  211. }
  212. /*!
  213. * @brief Initialize a CAN_Config_T structure with the initial value.
  214. *
  215. * @param canConfig :Point to a CAN_Config_T structure.
  216. *
  217. * @retval None
  218. *
  219. * @note CAN2 applies only to APM32F103xC device.
  220. */
  221. void CAN_ConfigStructInit(CAN_Config_T* canConfig)
  222. {
  223. canConfig->timeTrigComMode = DISABLE;
  224. canConfig->autoBusOffManage = DISABLE;
  225. canConfig->autoWakeUpMode = DISABLE;
  226. canConfig->nonAutoRetran = DISABLE;
  227. canConfig->rxFIFOLockMode = DISABLE;
  228. canConfig->txFIFOPriority = DISABLE;
  229. canConfig->mode = CAN_MODE_NORMAL;
  230. canConfig->syncJumpWidth = CAN_SJW_1;
  231. canConfig->timeSegment1 = CAN_TIME_SEGMENT1_4;
  232. canConfig->timeSegment2 = CAN_TIME_SEGMENT2_3;
  233. canConfig->prescaler = 1;
  234. }
  235. /*!
  236. * @brief Enables the DBG Freeze for CAN.
  237. *
  238. * @param can: Select the CAN peripheral.
  239. *
  240. * @retval None
  241. *
  242. * @note CAN2 applies only to APM32F103xC device.
  243. */
  244. void CAN_EnableDBGFreeze(CAN_T* can)
  245. {
  246. can->MCTRL_B.DBGFRZE = ENABLE;
  247. }
  248. /*!
  249. * @brief Disable the DBG Freeze for CAN.
  250. *
  251. * @param can: Select the CAN peripheral.
  252. *
  253. * @retval None
  254. *
  255. * @note CAN2 applies only to APM32F103xC device.
  256. */
  257. void CAN_DisableDBGFreeze(CAN_T* can)
  258. {
  259. can->MCTRL_B.DBGFRZE = DISABLE;
  260. }
  261. /*!
  262. * @brief Enables the CAN Time TriggerOperation communication mode.
  263. *
  264. * @param can: Select the CAN peripheral.
  265. *
  266. * @retval None
  267. *
  268. * @note CAN2 applies only to APM32F103xC device.
  269. */
  270. void CAN_EnableTTCComMode(CAN_T* can)
  271. {
  272. can->MCTRL_B.TTCM = ENABLE;
  273. can->sTxMailBox[0].TXDLEN_B.TXTS = BIT_SET;
  274. can->sTxMailBox[1].TXDLEN_B.TXTS = BIT_SET;
  275. can->sTxMailBox[2].TXDLEN_B.TXTS = BIT_SET;
  276. }
  277. /*!
  278. * @brief Disable the CAN Time TriggerOperation communication mode.
  279. *
  280. * @param can: Select the CAN peripheral.
  281. *
  282. * @retval None
  283. *
  284. * @note CAN2 applies only to APM32F103xC device.
  285. */
  286. void CAN_DisableTTCComMode(CAN_T* can)
  287. {
  288. can->MCTRL_B.TTCM = DISABLE;
  289. can->sTxMailBox[0].TXDLEN_B.TXTS = BIT_RESET;
  290. can->sTxMailBox[1].TXDLEN_B.TXTS = BIT_RESET;
  291. can->sTxMailBox[2].TXDLEN_B.TXTS = BIT_RESET;
  292. }
  293. /*!
  294. * @brief Initiates the transmission of a message.
  295. *
  296. * @param can: Select the CAN peripheral.
  297. *
  298. * @param TxMessage: pointer to a CAN_TX_MESSAGE_T structure.
  299. *
  300. * @retval The number of the mailbox which is used for transmission or 3 if No mailbox is empty.
  301. *
  302. * @note CAN2 applies only to APM32F103xC device.
  303. */
  304. uint8_t CAN_TxMessage(CAN_T* can, CAN_TX_MESSAGE_T* TxMessage)
  305. {
  306. uint8_t transmit_milbox = 0;
  307. /** Select one empty transmit mailbox */
  308. if((can->TXSTS & 0x04000000) == 0x04000000)
  309. {
  310. transmit_milbox = 0;
  311. }
  312. else if((can->TXSTS & 0x08000000) == 0x08000000)
  313. {
  314. transmit_milbox = 1;
  315. }
  316. else if((can->TXSTS & 0x10000000) == 0x10000000)
  317. {
  318. transmit_milbox = 2;
  319. } else
  320. {
  321. return 3; //!< No mailbox is empty
  322. }
  323. /** Set up the Id */
  324. can->sTxMailBox[transmit_milbox].TXMID &= 0x00000001;
  325. if(TxMessage->typeID == CAN_TYPEID_STD)
  326. {
  327. can->sTxMailBox[transmit_milbox].TXMID |= (TxMessage->stdID << 21) | (TxMessage->remoteTxReq);
  328. } else
  329. {
  330. can->sTxMailBox[transmit_milbox].TXMID |= (TxMessage->extID << 3) | (TxMessage->typeID) | (TxMessage->remoteTxReq);
  331. }
  332. /** Set up the TXDLEN */
  333. TxMessage->dataLengthCode &= 0x0F;
  334. can->sTxMailBox[transmit_milbox].TXDLEN &= (uint32_t)0xFFFFFFF0;
  335. can->sTxMailBox[transmit_milbox].TXDLEN |= TxMessage->dataLengthCode;
  336. /** Set up the data field */
  337. can->sTxMailBox[transmit_milbox].TXMDL = ((uint32_t)TxMessage->data[3] << 24) | ((uint32_t)TxMessage->data[2] << 16)
  338. | ((uint32_t)TxMessage->data[1] << 8) | ((uint32_t)TxMessage->data[0]);
  339. can->sTxMailBox[transmit_milbox].TXMDH = ((uint32_t)TxMessage->data[7] << 24) | ((uint32_t)TxMessage->data[6] << 16)
  340. | ((uint32_t)TxMessage->data[5] << 8) | ((uint32_t)TxMessage->data[4]);
  341. /** Request transmission */
  342. can->sTxMailBox[transmit_milbox].TXMID |= 0x00000001;
  343. return transmit_milbox;
  344. }
  345. /*!
  346. * @brief Checks the transmission of a message.
  347. *
  348. * @param can: Select the CAN peripheral.
  349. *
  350. * @param transmitMailbox: the number of the mailbox
  351. *
  352. * @retval state: 0: Status of transmission is Failed
  353. * 1: Status of transmission is Ok
  354. * 2: transmit pending
  355. *
  356. * @note CAN2 applies only to APM32F103xC device.
  357. */
  358. uint8_t CAN_TxMessageStatus(CAN_T* can, CAN_TX_MAILBIX_T TxMailbox)
  359. {
  360. uint32_t state = 0;
  361. switch (TxMailbox)
  362. {
  363. case (CAN_TX_MAILBIX_0):
  364. state = can->TXSTS & (0x00000001 | 0x00000002 | 0x04000000);
  365. break;
  366. case (CAN_TX_MAILBIX_1):
  367. state = can->TXSTS & (0x00000100 | 0x00000200 | 0x08000000);
  368. break;
  369. case (CAN_TX_MAILBIX_2):
  370. state = can->TXSTS & (0x00010000 | 0x00020000 | 0x10000000);
  371. break;
  372. default:
  373. state = 0;
  374. break;
  375. }
  376. switch (state)
  377. {
  378. /** transmit pending */
  379. case (0x0): state = 2;
  380. break;
  381. /* transmit failed */
  382. case (0x00000001 | 0x04000000): state = 0;
  383. break;
  384. case (0x00000100 | 0x08000000): state = 0;
  385. break;
  386. case (0x00010000 | 0x10000000): state = 0;
  387. break;
  388. /* transmit succeeded */
  389. case (0x00000001 | 0x00000002 | 0x04000000):state = 1;
  390. break;
  391. case (0x00000100 | 0x00000200 | 0x08000000):state = 1;
  392. break;
  393. case (0x00010000 | 0x00020000 | 0x10000000):state = 1;
  394. break;
  395. default: state = 0;
  396. break;
  397. }
  398. return (uint8_t) state;
  399. }
  400. /*!
  401. * @brief Cancels a transmit request.
  402. *
  403. * @param can: Select the CAN peripheral.
  404. *
  405. * @param mailBox: the number of the mailbox
  406. * This parameter can be one of the following values:
  407. * @arg CAN_TX_MAILBIX_0 : Tx mailbox 0
  408. * @arg CAN_TX_MAILBIX_1 : Tx mailbox 1
  409. * @arg CAN_TX_MAILBIX_2 : Tx mailbox 2
  410. *
  411. * @retval None
  412. *
  413. * @note CAN2 applies only to APM32F103xC device.
  414. */
  415. void CAN_CancelTxMailbox(CAN_T* can, CAN_TX_MAILBIX_T TxMailbox)
  416. {
  417. switch (TxMailbox)
  418. {
  419. case CAN_TX_MAILBIX_0:
  420. can->TXSTS_B.ABREQFLG0 = BIT_SET;
  421. break;
  422. case CAN_TX_MAILBIX_1:
  423. can->TXSTS_B.ABREQFLG1 = BIT_SET;
  424. break;
  425. case CAN_TX_MAILBIX_2:
  426. can->TXSTS_B.ABREQFLG2 = BIT_SET;
  427. break;
  428. default:
  429. break;
  430. }
  431. }
  432. /*!
  433. * @brief Receives a message and save to a CAN_RX_MESSAGE_T structure.
  434. *
  435. * @param can: Select the CAN peripheral.
  436. *
  437. * @param FIFONumber: Receive FIFO number.
  438. * This parameter can be one of the following values:
  439. * @arg CAN_RX_FIFO_0 : Receive FIFO 0
  440. * @arg CAN_RX_FIFO_1 : Receive FIFO 1
  441. *
  442. * @param RxMessage: pointer to a structure to receive the message.
  443. *
  444. * @retval None
  445. *
  446. * @note CAN2 applies only to APM32F103xC device.
  447. */
  448. void CAN_RxMessage(CAN_T* can, CAN_RX_FIFO_T FIFONumber, CAN_RX_MESSAGE_T* RxMessage)
  449. {
  450. /* Get the Id */
  451. RxMessage->typeID = ((uint8_t)0x04 & (can->sRxMailBox[FIFONumber].RXMID));
  452. if(RxMessage->typeID == CAN_TYPEID_STD)
  453. {
  454. RxMessage->stdID = (can->sRxMailBox[FIFONumber].RXMID >> 21) & 0x000007FF;
  455. }
  456. else
  457. {
  458. RxMessage->extID = (can->sRxMailBox[FIFONumber].RXMID >> 3) & 0x1FFFFFFF;
  459. }
  460. RxMessage->remoteTxReq = can->sRxMailBox[FIFONumber].RXMID_B.RFTXREQ;
  461. RxMessage->dataLengthCode = can->sRxMailBox[FIFONumber].RXDLEN_B.DLCODE;
  462. RxMessage->filterMatchIndex = can->sRxMailBox[FIFONumber].RXDLEN_B.FMIDX;
  463. /** Get the data field */
  464. RxMessage->data[0] = can->sRxMailBox[FIFONumber].RXMDL_B.DATABYTE1;
  465. RxMessage->data[1] = can->sRxMailBox[FIFONumber].RXMDL_B.DATABYTE2;
  466. RxMessage->data[2] = can->sRxMailBox[FIFONumber].RXMDL_B.DATABYTE3;
  467. RxMessage->data[3] = can->sRxMailBox[FIFONumber].RXMDL_B.DATABYTE4;
  468. RxMessage->data[4] = can->sRxMailBox[FIFONumber].RXMDH_B.DATABYTE5;
  469. RxMessage->data[5] = can->sRxMailBox[FIFONumber].RXMDH_B.DATABYTE6;
  470. RxMessage->data[6] = can->sRxMailBox[FIFONumber].RXMDH_B.DATABYTE7;
  471. RxMessage->data[7] = can->sRxMailBox[FIFONumber].RXMDH_B.DATABYTE8;
  472. if(FIFONumber == CAN_RX_FIFO_0)
  473. {
  474. can->RXF0_B.RFOM0 = BIT_SET;
  475. }
  476. else
  477. {
  478. can->RXF1_B.RFOM1 = BIT_SET;
  479. }
  480. }
  481. /*!
  482. * @brief Releases the specified FIFO.
  483. *
  484. * @param can: Select the CAN peripheral.
  485. *
  486. * @param FIFONumber: Receive FIFO number
  487. * This parameter can be one of the following values:
  488. * @arg CAN_RX_FIFO_0 : Receive FIFO 0
  489. * @arg CAN_RX_FIFO_1 : Receive FIFO 1
  490. *
  491. * @retval None
  492. *
  493. * @note CAN2 applies only to APM32F103xC device.
  494. */
  495. void CAN_ReleaseFIFO(CAN_T* can, CAN_RX_FIFO_T FIFONumber)
  496. {
  497. if(FIFONumber == CAN_RX_FIFO_0)
  498. {
  499. can->RXF0_B.RFOM0 = BIT_SET;
  500. }
  501. else
  502. {
  503. can->RXF1_B.RFOM1 = BIT_SET;
  504. }
  505. }
  506. /*!
  507. * @brief Returns the number of pending messages.
  508. *
  509. * @param can: Select the CAN peripheral.
  510. *
  511. * @param FIFONumber: Receive FIFO number
  512. * This parameter can be one of the following values:
  513. * @arg CAN_RX_FIFO_0 : Receive FIFO 0
  514. * @arg CAN_RX_FIFO_1 : Receive FIFO 1
  515. *
  516. * @retval The number of pending message.
  517. *
  518. * @note CAN2 applies only to APM32F103xC device.
  519. */
  520. uint8_t CAN_PendingMessage(CAN_T* can, CAN_RX_FIFO_T FIFONumber)
  521. {
  522. if(FIFONumber == CAN_RX_FIFO_0)
  523. {
  524. return can->RXF0 & 0x03;
  525. }
  526. else
  527. {
  528. return can->RXF1 & 0x03;
  529. }
  530. }
  531. /*!
  532. * @brief Select the CAN Operation mode
  533. *
  534. * @param can: Select the CAN peripheral.
  535. *
  536. * @param operatingMode: CAN Operating Mode
  537. * This parameter can be one of the following values:
  538. * @arg CAN_OPERATING_MODE_INIT : Initialization mode
  539. * @arg CAN_OPERATING_MODE_NORMAL: Normal mode
  540. * @arg CAN_OPERATING_MODE_SLEEP : sleep mode
  541. *
  542. * @retval modeState:status of the requested mode
  543. * 0:CAN failed entering the specific mode
  544. * 1:CAN Succeed entering the specific mode
  545. *
  546. * @note CAN2 applies only to APM32F103xC device.
  547. */
  548. uint8_t CAN_OperatingMode(CAN_T* can, CAN_OPERATING_MODE_T operatingMode)
  549. {
  550. uint8_t states = 0;
  551. uint32_t time_out = 0x0000FFFF;
  552. if(operatingMode == CAN_OPERATING_MODE_INIT)
  553. {
  554. can->MCTRL_B.SLEEPREQ = BIT_RESET;
  555. can->MCTRL_B.INITREQ = BIT_SET;
  556. while((can->MSTS_B.INITFLG != BIT_SET && can->MSTS_B.SLEEPFLG != BIT_RESET) && (time_out != 0))
  557. {
  558. time_out --;
  559. }
  560. if((can->MSTS_B.INITFLG == BIT_SET && can->MSTS_B.SLEEPFLG == BIT_RESET))
  561. {
  562. states = 1;
  563. }
  564. }
  565. else if(operatingMode == CAN_OPERATING_MODE_NORMAL)
  566. {
  567. can->MCTRL_B.SLEEPREQ = BIT_RESET;
  568. can->MCTRL_B.INITREQ = BIT_RESET;
  569. time_out = 0x0000FFFF;
  570. while((can->MSTS_B.INITFLG != BIT_RESET || can->MSTS_B.SLEEPFLG != BIT_RESET) && (time_out != 0))
  571. {
  572. time_out --;
  573. }
  574. if((can->MSTS_B.INITFLG == BIT_RESET || can->MSTS_B.SLEEPFLG == BIT_RESET))
  575. {
  576. states = 1;
  577. }
  578. }
  579. else if(operatingMode == CAN_OPERATING_MODE_SLEEP)
  580. {
  581. can->MCTRL_B.SLEEPREQ = BIT_SET;
  582. can->MCTRL_B.INITREQ = BIT_RESET;
  583. time_out = 0x0000FFFF;
  584. while((can->MSTS_B.INITFLG != BIT_RESET && can->MSTS_B.SLEEPFLG != BIT_SET) && (time_out != 0))
  585. {
  586. time_out --;
  587. }
  588. if((can->MSTS_B.INITFLG == BIT_RESET && can->MSTS_B.SLEEPFLG == BIT_SET))
  589. {
  590. states = 1;
  591. }
  592. }
  593. return states ;
  594. }
  595. /*!
  596. * @brief Into the low power mode.
  597. *
  598. * @param can: Select the CAN peripheral.
  599. *
  600. * @retval status: Status of entering sleep mode.
  601. * 0: Enter sleep fail
  602. * 1: Enter sleep success
  603. *
  604. * @note CAN2 applies only to APM32F103xC device.
  605. */
  606. uint8_t CAN_SleepMode(CAN_T* can)
  607. {
  608. can->MCTRL_B.SLEEPREQ = BIT_SET;
  609. can->MCTRL_B.INITREQ = BIT_RESET;
  610. if((can->MSTS_B.INITFLG == BIT_RESET && can->MSTS_B.SLEEPFLG == BIT_SET))
  611. {
  612. return 1;
  613. }
  614. return 0;
  615. }
  616. /*!
  617. * @brief Wakes the CAN up.
  618. *
  619. * @param can: Select the CAN peripheral.
  620. *
  621. * @retval status: Status of waking the CAN up
  622. * 0: WakeUp CAN fail,
  623. * 1: WakeUp CAN success
  624. *
  625. * @note CAN2 applies only to APM32F103xC device.
  626. */
  627. uint8_t CAN_WakeUpMode(CAN_T* can)
  628. {
  629. uint32_t time_out = 0x0000FFFF;
  630. can->MCTRL_B.SLEEPREQ = BIT_RESET;
  631. while((can->MSTS_B.SLEEPFLG != BIT_RESET) && (time_out != 0))
  632. {
  633. time_out --;
  634. }
  635. if(can->MSTS_B.SLEEPFLG == BIT_RESET)
  636. {
  637. return 1;
  638. }
  639. return 0;
  640. }
  641. /*!
  642. * @brief Read the can's last error code (LERRC)
  643. *
  644. * @param can: Select the CAN peripheral.
  645. *
  646. * @retval The Last Error Code.
  647. *
  648. * @note CAN2 applies only to APM32F103xC device.
  649. */
  650. uint8_t CAN_ReadLastErrorCode(CAN_T* can)
  651. {
  652. return can->ERRSTS_B.LERRC;
  653. }
  654. /*!
  655. * @brief Read the can Receive Error Counter(RXERRCNT)
  656. *
  657. * @param can: Select the CAN peripheral.
  658. *
  659. * @retval CAN Receive Error Counter.
  660. *
  661. * @note CAN2 applies only to APM32F103xC device.
  662. */
  663. uint8_t CAN_ReadRxErrorCounter(CAN_T* can)
  664. {
  665. return can->ERRSTS_B.RXERRCNT;
  666. }
  667. /*!
  668. * @brief Read the LSB of the 9-bit can Transmit Error Counter(TXERRCNT).
  669. *
  670. * @param can: Select the CAN peripheral.
  671. *
  672. * @retval Least Significant Byte Of The 9-Bit Transmit Error Counter.
  673. *
  674. * @note CAN2 applies only to APM32F103xC device.
  675. */
  676. uint8_t CAN_ReadLSBTxErrorCounter(CAN_T* can)
  677. {
  678. return can->ERRSTS_B.TXERRCNT;
  679. }
  680. /*!
  681. * @brief Enables the specified can interrupts.
  682. *
  683. * @param can: Select the CAN peripheral.
  684. *
  685. * @param interrupts: specifies the CAN interrupt sources
  686. * This parameter can be any combination of the following values:
  687. * @arg CAN_INT_TXME : Transmit mailbox empty Interrupt
  688. * @arg CAN_INT_F0MP : FIFO 0 message pending Interrupt
  689. * @arg CAN_INT_F0FULL : FIFO 0 full Interrupt
  690. * @arg CAN_INT_F0OVR : FIFO 0 overrun Interrupt
  691. * @arg CAN_INT_F1MP : FIFO 1 message pending Interrupt
  692. * @arg CAN_INT_F1FULL : FIFO 1 full Interrupt
  693. * @arg CAN_INT_F1OVR : FIFO 1 overrun Interrupt
  694. * @arg CAN_INT_ERRW : Error warning Interrupt
  695. * @arg CAN_INT_ERRP : Error passive Interrupt
  696. * @arg CAN_INT_BOF : Bus-off Interrupt
  697. * @arg CAN_INT_LEC : Last error record code Interrupt
  698. * @arg CAN_INT_ERR : Error Interrupt
  699. * @arg CAN_INT_WUP : Wake-up Interrupt
  700. * @arg CAN_INT_SLEEP : Sleep acknowledge Interrupt
  701. *
  702. * @retval None
  703. *
  704. * @note CAN2 applies only to APM32F103xC device.
  705. */
  706. void CAN_EnableInterrupt(CAN_T* can, uint32_t interrupts)
  707. {
  708. can->INTEN |= interrupts;
  709. }
  710. /*!
  711. * @brief Disable the specified can interrupts.
  712. *
  713. * @param can: Select the CAN peripheral.
  714. *
  715. * @param interrupts: specifies the CAN interrupt sources
  716. * This parameter can be any combination of the following values:
  717. * @arg CAN_INT_TXME : Transmit mailbox empty Interrupt
  718. * @arg CAN_INT_F0MP : FIFO 0 message pending Interrupt
  719. * @arg CAN_INT_F0FULL : FIFO 0 full Interrupt
  720. * @arg CAN_INT_F0OVR : FIFO 0 overrun Interrupt
  721. * @arg CAN_INT_F1MP : FIFO 1 message pending Interrupt
  722. * @arg CAN_INT_F1FULL : FIFO 1 full Interrupt
  723. * @arg CAN_INT_F1OVR : FIFO 1 overrun Interrupt
  724. * @arg CAN_INT_ERRW : Error warning Interrupt
  725. * @arg CAN_INT_ERRP : Error passive Interrupt
  726. * @arg CAN_INT_BOF : Bus-off Interrupt
  727. * @arg CAN_INT_LEC : Last error record code Interrupt
  728. * @arg CAN_INT_ERR : Error Interrupt
  729. * @arg CAN_INT_WUP : Wake-up Interrupt
  730. * @arg CAN_INT_SLEEP : Sleep acknowledge Interrupt
  731. *
  732. * @retval None
  733. *
  734. * @note CAN2 applies only to APM32F103xC device.
  735. */
  736. void CAN_DisableInterrupt(CAN_T* can, uint32_t interrupts)
  737. {
  738. can->INTEN &= ~interrupts;
  739. }
  740. /*!
  741. * @brief Read whether the specified CAN flag is set or not.
  742. *
  743. * @param can: Select the CAN peripheral.
  744. *
  745. * @param flag: specifies the CAN flag.
  746. * This parameter can be one of the following values:
  747. * @arg CAN_FLAG_ERRW : Error Warning Flag
  748. * @arg CAN_FLAG_ERRP : Error Passive Flag
  749. * @arg CAN_FLAG_BOF : Bus-Off Flag
  750. * @arg CAN_FLAG_LERRC : Last error record code Flag
  751. * @arg CAN_FLAG_WUPI : Wake up Flag
  752. * @arg CAN_FLAG_SLEEP : Sleep acknowledge Flag
  753. * @arg CAN_FLAG_F0MP : FIFO 0 Message Pending Flag
  754. * @arg CAN_FLAG_F0FULL : FIFO 0 Full Flag
  755. * @arg CAN_FLAG_F0OVR : FIFO 0 Overrun Flag
  756. * @arg CAN_FLAG_F1MP : FIFO 1 Message Pending Flag
  757. * @arg CAN_FLAG_F1FULL : FIFO 1 Full Flag
  758. * @arg CAN_FLAG_F1OVR : FIFO 1 Overrun Flag
  759. * @arg CAN_FLAG_REQC0 : Request MailBox0 Flag
  760. * @arg CAN_FLAG_REQC1 : Request MailBox1 Flag
  761. * @arg CAN_FLAG_REQC2 : Request MailBox2 Flag
  762. *
  763. * @retval flag staus: RESET or SET
  764. *
  765. * @note CAN2 applies only to APM32F103xC device.
  766. */
  767. uint8_t CAN_ReadStatusFlag(CAN_T* can, CAN_FLAG_T flag)
  768. {
  769. uint8_t status = 0;
  770. if((flag & 0x00F00000) != RESET )
  771. {
  772. if((can->ERRSTS & (flag & 0x000FFFFF)) != RESET)
  773. {
  774. status = SET;
  775. }
  776. else
  777. {
  778. status = RESET;
  779. }
  780. }
  781. else if((flag & 0x01000000) != RESET )
  782. {
  783. if((can->MSTS & (flag & 0x000FFFFF)) != RESET )
  784. {
  785. status = SET;
  786. }
  787. else
  788. {
  789. status = RESET ;
  790. }
  791. }
  792. else if((flag & 0x08000000) != RESET )
  793. {
  794. if((can->TXSTS & (flag & 0x000FFFFF)) != RESET )
  795. {
  796. status = SET;
  797. }
  798. else
  799. {
  800. status = RESET;
  801. }
  802. }
  803. else if((flag & 0x02000000) != RESET )
  804. {
  805. if((can->RXF0 & (flag & 0x000FFFFF)) != RESET )
  806. {
  807. status = SET;
  808. }
  809. else
  810. {
  811. status = RESET;
  812. }
  813. }
  814. else
  815. {
  816. if((can->RXF1 & (flag & 0x000FFFFF)) != RESET)
  817. {
  818. status = SET;
  819. }
  820. else
  821. {
  822. status = RESET;
  823. }
  824. }
  825. return status;
  826. }
  827. /*!
  828. * @brief Clears the CAN's pending flags.
  829. *
  830. * @param can: Select the CAN peripheral.
  831. *
  832. * @param flag: specifies the CAN flag.
  833. * This parameter can be one of the following values:
  834. * @arg CAN_FLAG_LERRC : Last error record code Flag
  835. * @arg CAN_FLAG_WUPI : Wake up Flag
  836. * @arg CAN_FLAG_SLEEP : Sleep acknowledge Flag
  837. * @arg CAN_FLAG_F0FULL: FIFO 0 Full Flag
  838. * @arg CAN_FLAG_F0OVR : FIFO 0 Overrun Flag
  839. * @arg CAN_FLAG_F1FULL: FIFO 1 Full Flag
  840. * @arg CAN_FLAG_F1OVR : FIFO 1 Overrun Flag
  841. * @arg CAN_FLAG_REQC0 : Request MailBox0 Flag
  842. * @arg CAN_FLAG_REQC1 : Request MailBox1 Flag
  843. * @arg CAN_FLAG_REQC2 : Request MailBox2 Flag
  844. *
  845. * @retval None
  846. *
  847. * @note CAN2 applies only to APM32F103xC device.
  848. */
  849. void CAN_ClearStatusFlag(CAN_T* can, CAN_FLAG_T flag)
  850. {
  851. uint32_t flagtmp = 0;
  852. /** ERRSTS register */
  853. if(flag == 0x30F00070)
  854. {
  855. can->ERRSTS = RESET;
  856. }
  857. else
  858. {
  859. flagtmp = flag & 0x000FFFFF;
  860. if((flag & 0x02000000) != RESET)
  861. {
  862. can->RXF0 = flagtmp;
  863. }
  864. else if((flag & 0x04000000) != RESET)
  865. {
  866. can->RXF1 = flagtmp;
  867. }
  868. else if((flag & 0x08000000) != RESET)
  869. {
  870. can->TXSTS = flagtmp;
  871. }
  872. else
  873. {
  874. can->MSTS = flagtmp;
  875. }
  876. }
  877. }
  878. /*!
  879. * @brief Read whether the specified can interrupt has occurred or not.
  880. *
  881. * @param can: Select the CAN peripheral.
  882. *
  883. * @param flag: specifies the CAN interrupt sources
  884. * This parameter can be one of the following values:
  885. * @arg CAN_INT_TXME : Transmit mailbox empty Interrupt
  886. * @arg CAN_INT_F0MP : FIFO 0 message pending Interrupt
  887. * @arg CAN_INT_F0FULL : FIFO 0 full Interrupt
  888. * @arg CAN_INT_F0OVR : FIFO 0 overrun Interrupt
  889. * @arg CAN_INT_F1MP : FIFO 1 message pending Interrupt
  890. * @arg CAN_INT_F1FULL : FIFO 1 full Interrupt
  891. * @arg CAN_INT_F1OVR : FIFO 1 overrun Interrupt
  892. * @arg CAN_INT_ERRW : Error warning Interrupt
  893. * @arg CAN_INT_ERRP : Error passive Interrupt
  894. * @arg CAN_INT_BOF : Bus-off Interrupt
  895. * @arg CAN_INT_LEC : Last error record code Interrupt
  896. * @arg CAN_INT_ERR : Error Interrupt
  897. * @arg CAN_INT_WUP : Wake-up Interrupt
  898. * @arg CAN_INT_SLEEP : Sleep acknowledge Interrupt
  899. *
  900. * @retval status : SET or RESET
  901. *
  902. * @note CAN2 applies only to APM32F103xC device.
  903. */
  904. uint8_t CAN_ReadIntFlag(CAN_T* can, CAN_INT_T flag)
  905. {
  906. uint8_t status = 0;
  907. if((can->INTEN & flag) != RESET)
  908. {
  909. switch (flag)
  910. {
  911. case CAN_INT_TXME:
  912. status = can->TXSTS_B.REQCFLG0 | can->TXSTS_B.REQCFLG1 | can->TXSTS_B.REQCFLG2;
  913. break;
  914. case CAN_INT_F0MP:
  915. status = can->RXF0_B.FMNUM0;
  916. break;
  917. case CAN_INT_F0FULL:
  918. status = can->RXF0_B.FFULLFLG0;
  919. break;
  920. case CAN_INT_F0OVR:
  921. status = can->RXF0_B.FOVRFLG0;
  922. break;
  923. case CAN_INT_F1MP:
  924. status = can->RXF1_B.FMNUM1;
  925. break;
  926. case CAN_INT_F1FULL:
  927. status = can->RXF1_B.FFULLFLG1;
  928. break;
  929. case CAN_INT_F1OVR:
  930. status = can->RXF1_B.FOVRFLG1;
  931. break;
  932. case CAN_INT_WUP:
  933. status = can->MSTS_B.WUPIFLG;
  934. break;
  935. case CAN_INT_SLEEP:
  936. status = can->MSTS_B.SLEEPIFLG;
  937. break;
  938. case CAN_INT_ERRW:
  939. status = can->ERRSTS_B.ERRWFLG;
  940. break;
  941. case CAN_INT_ERRP:
  942. status = can->ERRSTS_B.ERRPFLG;
  943. break;
  944. case CAN_INT_BOF:
  945. status = can->ERRSTS_B.BOFLG;
  946. break;
  947. case CAN_INT_LEC:
  948. status = can->ERRSTS_B.LERRC;
  949. break;
  950. case CAN_INT_ERR:
  951. status = can->MSTS_B.ERRIFLG;
  952. break;
  953. default:
  954. status = RESET;
  955. break;
  956. }
  957. }
  958. else
  959. {
  960. status = RESET;
  961. }
  962. return status;
  963. }
  964. /*!
  965. * @brief Clears the can's interrupt flag.
  966. *
  967. * @param can: Select the CAN peripheral.
  968. *
  969. * @param flag: Interrupt pending bit to clear
  970. * This parameter can be one of the following values:
  971. * @arg CAN_INT_TXME : Transmit mailbox empty Interrupt
  972. * @arg CAN_INT_F0FULL : FIFO 0 full Interrupt
  973. * @arg CAN_INT_F0OVR : FIFO 0 overrun Interrupt
  974. * @arg CAN_INT_F1FULL : FIFO 1 full Interrupt
  975. * @arg CAN_INT_F1OVR : FIFO 1 overrun Interrupt
  976. * @arg CAN_INT_ERRW : Error warning Interrupt
  977. * @arg CAN_INT_ERRP : Error passive Interrupt
  978. * @arg CAN_INT_BOF : Bus-off Interrupt
  979. * @arg CAN_INT_LEC : Last error record code Interrupt
  980. * @arg CAN_INT_ERR : Error Interrupt
  981. * @arg CAN_INT_WUP : Wake-up Interrupt
  982. * @arg CAN_INT_SLEEP : Sleep acknowledge Interrupt
  983. *
  984. * @retval None
  985. *
  986. * @note CAN2 applies only to APM32F103xC device.
  987. */
  988. void CAN_ClearIntFlag(CAN_T* can, CAN_INT_T flag)
  989. {
  990. switch (flag)
  991. {
  992. case CAN_INT_TXME:
  993. can->TXSTS_B.REQCFLG0 = BIT_SET;
  994. can->TXSTS_B.REQCFLG1 = BIT_SET;
  995. can->TXSTS_B.REQCFLG2 = BIT_SET;
  996. break;
  997. case CAN_INT_F0FULL:
  998. can->RXF0_B.FFULLFLG0 = BIT_SET;
  999. break;
  1000. case CAN_INT_F0OVR:
  1001. can->RXF0_B.FOVRFLG0 = BIT_SET;
  1002. break;
  1003. case CAN_INT_F1FULL:
  1004. can->RXF1_B.FFULLFLG1 = BIT_SET;
  1005. break;
  1006. case CAN_INT_F1OVR:
  1007. can->RXF1_B.FOVRFLG1 = BIT_SET;
  1008. break;
  1009. case CAN_INT_WUP:
  1010. can->MSTS_B.WUPIFLG = BIT_SET;
  1011. break;
  1012. case CAN_INT_SLEEP:
  1013. can->MSTS_B.SLEEPIFLG = BIT_SET;
  1014. break;
  1015. case CAN_INT_ERRW:
  1016. can->MSTS_B.ERRIFLG = BIT_SET;
  1017. break;
  1018. case CAN_INT_ERRP:
  1019. can->MSTS_B.ERRIFLG = BIT_SET;
  1020. break;
  1021. case CAN_INT_BOF:
  1022. can->MSTS_B.ERRIFLG = BIT_SET;
  1023. break;
  1024. case CAN_INT_LEC:
  1025. can->ERRSTS_B.LERRC = BIT_RESET;
  1026. can->MSTS_B.ERRIFLG = BIT_SET;
  1027. break;
  1028. case CAN_INT_ERR:
  1029. can->ERRSTS_B.LERRC = BIT_RESET;
  1030. can->MSTS_B.ERRIFLG = BIT_SET;
  1031. break;
  1032. default:
  1033. break;
  1034. }
  1035. }
  1036. /**@} end of group CAN_Fuctions*/
  1037. /**@} end of group CAN_Driver*/
  1038. /**@} end of group Peripherals_Library*/