hal_can.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. ////////////////////////////////////////////////////////////////////////////////
  2. /// @file hal_can.c
  3. /// @author AE TEAM
  4. /// @brief THIS FILE PROVIDES ALL THE CAN FIRMWARE FUNCTIONS.
  5. ////////////////////////////////////////////////////////////////////////////////
  6. /// @attention
  7. ///
  8. /// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE
  9. /// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE
  10. /// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
  11. /// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH
  12. /// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN
  13. /// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS.
  14. ///
  15. /// <H2><CENTER>&COPY; COPYRIGHT MINDMOTION </CENTER></H2>
  16. ////////////////////////////////////////////////////////////////////////////////
  17. // Define to prevent recursive inclusion
  18. #define __HAL_CAN_C
  19. // Files includes
  20. #include "hal_can.h"
  21. #include "hal_rcc.h"
  22. ////////////////////////////////////////////////////////////////////////////////
  23. /// @addtogroup MM32_Hardware_Abstract_Layer
  24. /// @{
  25. ////////////////////////////////////////////////////////////////////////////////
  26. /// @addtogroup CAN_HAL
  27. /// @{
  28. ////////////////////////////////////////////////////////////////////////////////
  29. /// @addtogroup CAN_Exported_Functions
  30. /// @{
  31. ////////////////////////////////////////////////////////////////////////////////
  32. /// @brief Deinitializes the CAN peripheral registers to their default reset
  33. /// values.
  34. /// @param can: select the CAN peripheral.
  35. /// @retval None.
  36. ////////////////////////////////////////////////////////////////////////////////
  37. void CAN_DeInit(CAN_TypeDef* can)
  38. {
  39. exRCC_APB1PeriphReset(RCC_APB1ENR_CAN);
  40. }
  41. ////////////////////////////////////////////////////////////////////////////////
  42. /// @brief Initializes the CAN peripheral according to the specified
  43. /// parameters in the CAN_InitStruct.
  44. /// @param can: select the CAN peripheral.
  45. /// @param CAN_InitStruct: pointer to a CAN_InitTypeDef structure that
  46. /// contains the configuration information for the CAN peripheral.
  47. /// @retval Constant indicates initialization succeed which will be
  48. /// CANINITFAILED or CANINITOK.
  49. ////////////////////////////////////////////////////////////////////////////////
  50. u8 CAN_Init(CAN_TypeDef* can, CAN_Basic_InitTypeDef* init_struct)
  51. {
  52. u8 InitStatus = CANINITFAILED;
  53. can->BTR0 = ((u32)(init_struct->SJW) << 6) | ((u32)(init_struct->BRP));
  54. can->BTR1 = ((u32)(init_struct->SAM) << 7) | ((u32)(init_struct->TESG2) << 4) | ((u32)(init_struct->TESG1));
  55. if (init_struct->GTS == ENABLE) {
  56. can->CMR |= (u32)CAN_SleepMode;
  57. InitStatus = CANINITFAILED;
  58. }
  59. else {
  60. can->CMR &= ~(u32)CAN_SleepMode;
  61. InitStatus = CANINITOK;
  62. }
  63. (init_struct->GTS == ENABLE) ? (can->CMR |= (u32)CAN_SleepMode) : (can->CMR &= ~(u32)CAN_SleepMode);
  64. can->CDR |=
  65. ((init_struct->CBP) << 6) | ((init_struct->RXINTEN) << 5) | ((init_struct->CLOSE_OPEN_CLK) << 3) | (init_struct->CDCLK);
  66. return InitStatus;
  67. }
  68. ////////////////////////////////////////////////////////////////////////////////
  69. /// @brief Configures the CAN_Basic reception filter according to the specified
  70. /// parameters in the basic_filter_init_struct.
  71. /// @param basic_filter_init_struct: pointer to a CAN_Basic_FilterInitTypeDef
  72. /// structure that contains the configuration information.
  73. /// @retval None.
  74. ////////////////////////////////////////////////////////////////////////////////
  75. void CAN_FilterInit(CAN_Basic_FilterInitTypeDef* basic_filter_init_struct)
  76. {
  77. // Filter Mode
  78. CAN1->ACR = basic_filter_init_struct->CAN_FilterId;
  79. CAN1->AMR = basic_filter_init_struct->CAN_FilterMaskId;
  80. }
  81. ////////////////////////////////////////////////////////////////////////////////
  82. /// @brief Fills each init_struct member with its default value.
  83. /// @param init_struct : pointer to a CAN_Basic_InitTypeDef structure which will be initialized.
  84. /// @retval None.
  85. ////////////////////////////////////////////////////////////////////////////////
  86. void CAN_StructInit(CAN_Basic_InitTypeDef* init_struct)
  87. {
  88. // Reset CAN_Basic init structure parameters values
  89. // initialize the BRP member(where can be set with (0..63))
  90. init_struct->BRP = 0x0;
  91. // initialize the SJW member(where can be set with (0..3))
  92. init_struct->SJW = 0x0;
  93. // Initialize the TESG1 member(where can be set with (0..15))
  94. init_struct->TESG1 = 0x0;
  95. // Initialize the TESG2 member(where can be set with(0..7))
  96. init_struct->TESG2 = 0x0;
  97. // Initialize the SAM member(where can be set (SET or RESET))
  98. init_struct->SAM = RESET;
  99. // Initialize the GTS member to Sleep Mode(where can be set (ENABLE or
  100. // DISABLE))
  101. init_struct->GTS = DISABLE;
  102. // Initialize the external pin CLKOUT frequence
  103. init_struct->CDCLK = 0x0;
  104. // Initialize the external clk is open or close
  105. init_struct->CLOSE_OPEN_CLK = 0x0;
  106. // Initialize the TX1 pin work as rx interrupt output
  107. init_struct->RXINTEN = 0x0;
  108. // Initialize the CBP of CDR register
  109. init_struct->CBP = 0x0;
  110. }
  111. ////////////////////////////////////////////////////////////////////////////////
  112. /// @brief Enables or disables the specified CAN interrupts.
  113. /// @param can: select the CAN peripheral.
  114. /// @param it: specifies the CAN interrupt sources to be enabled or
  115. /// disabled.
  116. /// This parameter can be: CAN_IT_OIE, CAN_IT_EIE, CAN_IT_TIE,
  117. /// CAN_IT_RIE.
  118. /// @param state: new state of the CAN interrupts.
  119. /// This parameter can be: ENABLE or DISABLE.
  120. /// @retval None.
  121. ////////////////////////////////////////////////////////////////////////////////
  122. void CAN_ITConfig(CAN_TypeDef* can, u32 it, FunctionalState state)
  123. {
  124. (state) ? (can->CR |= it) : (can->CR &= ~it);
  125. }
  126. ////////////////////////////////////////////////////////////////////////////////
  127. /// @brief Initiates and transmits a CAN frame message.
  128. /// @param can:select the CAN peripheral.
  129. /// @param TxMessage: pointer to a structure which contains CAN Id, CAN DLC and
  130. /// CAN data.
  131. /// @retval CANTXOK if the CAN driver transmits the message
  132. ////////////////////////////////////////////////////////////////////////////////
  133. u8 CAN_Transmit(CAN_TypeDef* can, CanBasicTxMsg* basic_transmit_message)
  134. {
  135. can->TXID0 = (basic_transmit_message->IDH);
  136. can->TXID1 = (basic_transmit_message->IDL << 5) | (basic_transmit_message->RTR << 4) | (basic_transmit_message->DLC);
  137. if ((FunctionalState)(basic_transmit_message->RTR) != ENABLE) {
  138. can->TXDR0 = basic_transmit_message->Data[0];
  139. can->TXDR1 = basic_transmit_message->Data[1];
  140. can->TXDR2 = basic_transmit_message->Data[2];
  141. can->TXDR3 = basic_transmit_message->Data[3];
  142. can->TXDR4 = basic_transmit_message->Data[4];
  143. can->TXDR5 = basic_transmit_message->Data[5];
  144. can->TXDR6 = basic_transmit_message->Data[6];
  145. can->TXDR7 = basic_transmit_message->Data[7];
  146. }
  147. can->CMR = CAN_CMR_TR;
  148. return (can->SR & 0x01);
  149. }
  150. ////////////////////////////////////////////////////////////////////////////////
  151. /// @brief Cancels a transmit request.
  152. /// @param can: select the CAN peripheral.
  153. /// @retval None.
  154. ////////////////////////////////////////////////////////////////////////////////
  155. void CAN_CancelTransmit(CAN_TypeDef* can)
  156. {
  157. // abort transmission
  158. can->CMR = CAN_AT;
  159. }
  160. ////////////////////////////////////////////////////////////////////////////////
  161. /// @brief Releases the specified receive FIFO.
  162. /// @param can: select the CAN peripheral.
  163. /// @retval None.
  164. ////////////////////////////////////////////////////////////////////////////////
  165. void CAN_FIFORelease(CAN_TypeDef* can)
  166. {
  167. // Release FIFO
  168. can->CMR |= (u32)CAN_RRB;
  169. }
  170. ////////////////////////////////////////////////////////////////////////////////
  171. /// @brief Receives a correct CAN frame.
  172. /// @param can: select the CAN peripheral.
  173. /// @param RxMessage: pointer to a structure receive frame which contains CAN
  174. /// Id,CAN DLC, CAN data and FMI number.
  175. /// @retval None.
  176. ////////////////////////////////////////////////////////////////////////////////
  177. void CAN_Receive(CAN_TypeDef* can, CanBasicRxMsg* basic_receive_message)
  178. {
  179. u16 tempid;
  180. basic_receive_message->RTR = (u8)((can->RXID1) >> 4) & 0x1;
  181. basic_receive_message->DLC = (u8)((can->RXID1) & 0xf);
  182. tempid = (u16)(((can->RXID1) & 0xe0) >> 5);
  183. tempid |= (u16)(can->RXID0 << 3);
  184. basic_receive_message->ID = tempid;
  185. basic_receive_message->Data[0] = CAN1->RXDR0;
  186. basic_receive_message->Data[1] = CAN1->RXDR1;
  187. basic_receive_message->Data[2] = CAN1->RXDR2;
  188. basic_receive_message->Data[3] = CAN1->RXDR3;
  189. basic_receive_message->Data[4] = CAN1->RXDR4;
  190. basic_receive_message->Data[5] = CAN1->RXDR5;
  191. basic_receive_message->Data[6] = CAN1->RXDR6;
  192. basic_receive_message->Data[7] = CAN1->RXDR7;
  193. CAN_FIFORelease(can);
  194. }
  195. ////////////////////////////////////////////////////////////////////////////////
  196. /// @brief Select the Sleep mode or not in Basic workmode
  197. /// @param state to go into the Sleep mode or go out
  198. /// @retval None.
  199. ////////////////////////////////////////////////////////////////////////////////
  200. u8 CAN_Sleep(CAN_TypeDef* can)
  201. {
  202. can->CMR |= CAN_SleepMode;
  203. // At this step, sleep mode status
  204. return (u8)((can->CMR & 0x10) == CAN_SleepMode) ? CANSLEEPOK : CANSLEEPFAILED;
  205. }
  206. ////////////////////////////////////////////////////////////////////////////////
  207. /// @brief Wakes the CAN up.
  208. /// @param can: where x can be 1 to select the CAN peripheral.
  209. /// @retval CANWAKEUPOK if sleep mode left, CANWAKEUPFAILED in an other case.
  210. ////////////////////////////////////////////////////////////////////////////////
  211. u8 CAN_WakeUp(CAN_TypeDef* can)
  212. {
  213. // Wake up request
  214. can->CMR &= ~CAN_SleepMode;
  215. return (u8)((can->CMR & 0x01) == 0) ? CANWAKEUPOK : CANWAKEUPFAILED;
  216. }
  217. ////////////////////////////////////////////////////////////////////////////////
  218. /// @brief Checks whether the specified CAN flag is set or not.
  219. /// @param can: select the CAN peripheral.
  220. /// @param flag: specifies the flag to check.
  221. /// This parameter can be one of the following values:
  222. /// @arg CAN_STATUS_RBS: Receive buffer status
  223. /// @arg CAN_STATUS_DOS: Data overflow status
  224. /// @arg CAN_STATUS_TBS: Transmit buffer status
  225. /// @arg CAN_STATUS_TCS: Transmit complete status
  226. /// @arg CAN_STATUS_RS: Receiving status
  227. /// @arg CAN_STATUS_TS: Transmiting status
  228. /// @arg CAN_STATUS_ES: Error status
  229. /// @arg CAN_STATUS_BS: bus status, close or open
  230. /// @retval The new state of CAN_FLAG (SET or RESET).
  231. ////////////////////////////////////////////////////////////////////////////////
  232. FlagStatus CAN_GetFlagStatus(CAN_TypeDef* can, u32 flag)
  233. {
  234. return (FlagStatus)(((can->SR & flag) == flag) ? SET : RESET);
  235. }
  236. ////////////////////////////////////////////////////////////////////////////////
  237. /// @brief Checks whether the specified CAN interrupt has occurred or not.
  238. /// @param can: where x can be 1 to select the CAN peripheral.
  239. /// @param it: specifies the CAN interrupt source to check.
  240. /// This parameter can be one of the following values:
  241. /// @arg CAN_IT_RI: Receive FIFO not empty Interrupt
  242. /// @arg CAN_IT_TI: Transmit Interrupt
  243. /// @arg CAN_IT_EI: ERROR Interrupt
  244. /// @arg CAN_IT_DOI: Data voerflow Interrupt
  245. /// @arg CAN_IT_WUI: Wakeup Interrupt
  246. /// @arg CAN_IT_ALL: use it can enble all Interrupt
  247. /// @retval The current state of it (SET or RESET).
  248. ////////////////////////////////////////////////////////////////////////////////
  249. ITStatus CAN_GetITStatus(CAN_TypeDef* can, u32 it)
  250. {
  251. return (ITStatus)((can->IR & it) != it) ? RESET : SET;
  252. }
  253. ////////////////////////////////////////////////////////////////////////////////
  254. /// @brief Select the can work as peli mode or basic mode
  255. /// @param can: where x can be 1 or 2 to to select the CAN peripheral.
  256. /// @param CAN_MODE: specifies the work mode:CAN_BASICMode,CAN_PELIMode
  257. /// @retval None.
  258. ////////////////////////////////////////////////////////////////////////////////
  259. void CAN_Mode_Cmd(CAN_TypeDef* can, u32 mode)
  260. {
  261. can->CDR |= mode;
  262. }
  263. ////////////////////////////////////////////////////////////////////////////////
  264. /// @brief Select the Reset mode or not
  265. /// @param can: where x can be 1 or 2 to to select the CAN peripheral.
  266. /// @param state to go into the Reset mode or go out
  267. /// @retval None.
  268. ////////////////////////////////////////////////////////////////////////////////
  269. void CAN_ResetMode_Cmd(CAN_TypeDef* can, FunctionalState state)
  270. {
  271. (state == ENABLE) ? (can->CR |= CAN_ResetMode) : (can->CR &= ~CAN_ResetMode);
  272. }
  273. ////////////////////////////////////////////////////////////////////////////////
  274. /// @brief Clear the data overflow.
  275. /// @param can: where x can be 1 or 2 to to select the CAN peripheral.
  276. /// @retval None.
  277. ////////////////////////////////////////////////////////////////////////////////
  278. void CAN_ClearDataOverflow(CAN_TypeDef* can)
  279. {
  280. can->CMR |= (u32)CAN_CDO;
  281. }
  282. ////////////////////////////////////////////////////////////////////////////////
  283. /// @brief Clears the CAN's IT pending.
  284. /// @param can: where x can be 1 or 2 to to select the CAN peripheral.
  285. /// @retval None.
  286. ////////////////////////////////////////////////////////////////////////////////
  287. void CAN_ClearITPendingBit(CAN_TypeDef* can)
  288. {
  289. u32 temp = 0;
  290. temp = temp;
  291. temp = can->IR; // read this register clear all interrupt
  292. }
  293. ////////////////////////////////////////////////////////////////////////////////
  294. /// @brief Select the Sleep mode or not in Peli workmode
  295. /// @param state to go into the Sleep mode or go out
  296. /// @retval None.
  297. ////////////////////////////////////////////////////////////////////////////////
  298. void CAN_Peli_SleepMode_Cmd(FunctionalState state)
  299. {
  300. (state == ENABLE) ? (CAN1_PELI->MOD |= CAN_SleepMode) : (CAN1_PELI->MOD &= ~CAN_SleepMode);
  301. }
  302. ////////////////////////////////////////////////////////////////////////////////
  303. /// @brief Fills each CAN1_PELI_InitStruct member with its default value.
  304. /// @param init_struct : pointer to a CAN_Peli_InitTypeDef structure
  305. /// which will be initialized.
  306. /// @retval None.
  307. ////////////////////////////////////////////////////////////////////////////////
  308. void CAN_Peli_StructInit(CAN_Peli_InitTypeDef* init_struct)
  309. {
  310. //--------------- Reset CAN_Peli init structure parameters values
  311. //---------------
  312. init_struct->BRP = 0x0; // initialize the BRP member(where can be set with (0..63))
  313. init_struct->SJW = 0x0; // initialize the SJW member(where can be set with (0..3))
  314. init_struct->TESG1 = 0x0; // Initialize the TESG1 member(where can be set with (0..15))
  315. init_struct->TESG2 = 0x0; // Initialize the TESG2 member(where can be set with(0..7))
  316. init_struct->SAM = RESET; // Initialize the SAM member(where can be set (SET or RESET))
  317. init_struct->LOM = DISABLE; // Initialize the LOM member
  318. init_struct->STM = DISABLE; // Initialize the STM member
  319. init_struct->SM = DISABLE; // Initialize the SM member
  320. init_struct->SRR = DISABLE;
  321. init_struct->EWLR = 0x96;
  322. }
  323. ////////////////////////////////////////////////////////////////////////////////
  324. /// @brief Initializes the CAN_Peli peripheral according to the specified
  325. /// parameters in the init_struct.
  326. /// @param init_struct: pointer to a CAN_Peli_InitTypeDef structure that
  327. /// contains the configuration information for the CAN peripheral in the peli workmode.
  328. /// @retval None.
  329. ////////////////////////////////////////////////////////////////////////////////
  330. void CAN_Peli_Init(CAN_Peli_InitTypeDef* init_struct)
  331. {
  332. CAN1_PELI->BTR0 = ((u32)init_struct->SJW << 6) | ((u32)init_struct->BRP);
  333. CAN1_PELI->BTR1 = ((u32)init_struct->SAM << 7) | ((u32)init_struct->TESG2 << 4) | ((u32)init_struct->TESG1);
  334. if (init_struct->LOM == ENABLE)
  335. CAN1_PELI->MOD |= (u32)CAN_ListenOnlyMode;
  336. else
  337. CAN1_PELI->MOD &= ~(u32)CAN_ListenOnlyMode;
  338. if (init_struct->STM == ENABLE)
  339. CAN1_PELI->MOD |= (u32)CAN_SeftTestMode;
  340. else
  341. CAN1_PELI->MOD &= ~(u32)CAN_SeftTestMode;
  342. if (init_struct->SM == ENABLE)
  343. CAN1_PELI->MOD |= (u32)CAN_SleepMode;
  344. else
  345. CAN1_PELI->MOD &= ~(u32)CAN_SleepMode;
  346. CAN1_PELI->EWLR = (u32)init_struct->EWLR;
  347. }
  348. ////////////////////////////////////////////////////////////////////////////////
  349. /// @brief Configures the CAN_Peli reception filter according to the specified
  350. /// parameters in the peli_filter_init_struct.
  351. /// @param peli_filter_init_struct: pointer to a CAN_Peli_FilterInitTypeDef
  352. /// structure that contains the configuration information.
  353. /// @retval None.
  354. ////////////////////////////////////////////////////////////////////////////////
  355. void CAN_Peli_FilterInit(CAN_Peli_FilterInitTypeDef* peli_filter_init_struct)
  356. {
  357. (peli_filter_init_struct->AFM == CAN_FilterMode_Singal) ? (CAN1_PELI->MOD |= (u32)CAN_FilterMode_Singal)
  358. : (CAN1_PELI->MOD &= (u32)CAN_FilterMode_Double);
  359. CAN1_PELI->FF = peli_filter_init_struct->CAN_FilterId0;
  360. CAN1_PELI->ID0 = peli_filter_init_struct->CAN_FilterId1;
  361. CAN1_PELI->ID1 = peli_filter_init_struct->CAN_FilterId2;
  362. CAN1_PELI->DATA0 = peli_filter_init_struct->CAN_FilterId3;
  363. CAN1_PELI->DATA1 = peli_filter_init_struct->CAN_FilterMaskId0;
  364. CAN1_PELI->DATA2 = peli_filter_init_struct->CAN_FilterMaskId1;
  365. CAN1_PELI->DATA3 = peli_filter_init_struct->CAN_FilterMaskId2;
  366. CAN1_PELI->DATA4 = peli_filter_init_struct->CAN_FilterMaskId3;
  367. }
  368. ////////////////////////////////////////////////////////////////////////////////
  369. /// @brief Fills each peli_filter_init_struct member with its default value.
  370. /// @param peli_filter_init_struct: pointer to a CAN_InitTypeDef structure
  371. /// which ill be initialized.
  372. /// @retval None.
  373. ////////////////////////////////////////////////////////////////////////////////
  374. void CAN_Peli_FilterStructInit(CAN_Peli_FilterInitTypeDef* peli_filter_init_struct)
  375. {
  376. peli_filter_init_struct->CAN_FilterId0 = 0;
  377. peli_filter_init_struct->CAN_FilterId1 = 0;
  378. peli_filter_init_struct->CAN_FilterId2 = 0;
  379. peli_filter_init_struct->CAN_FilterId3 = 0;
  380. peli_filter_init_struct->CAN_FilterMaskId0 = 0;
  381. peli_filter_init_struct->CAN_FilterMaskId1 = 0;
  382. peli_filter_init_struct->CAN_FilterMaskId2 = 0;
  383. peli_filter_init_struct->CAN_FilterMaskId3 = 0;
  384. }
  385. ////////////////////////////////////////////////////////////////////////////////
  386. /// @brief Initiates and transmits a CAN frame message.
  387. /// @param TxMessage: pointer to a structure which contains CAN Id, CAN DLC and
  388. /// CAN data.
  389. /// @retval None.
  390. ////////////////////////////////////////////////////////////////////////////////
  391. void CAN_Peli_Transmit(CanPeliTxMsg* peli_transmit_message)
  392. {
  393. CAN1_PELI->FF = (peli_transmit_message->FF << 7) | (peli_transmit_message->RTR << 6) | (peli_transmit_message->DLC);
  394. if (((FunctionalState)peli_transmit_message->FF) != ENABLE) {
  395. CAN1_PELI->ID0 = (peli_transmit_message->IDHH);
  396. CAN1_PELI->ID1 = (peli_transmit_message->IDHL & 0xE0);
  397. if ((FunctionalState)(peli_transmit_message->RTR) != ENABLE) {
  398. CAN1_PELI->DATA0 = peli_transmit_message->Data[0];
  399. CAN1_PELI->DATA1 = peli_transmit_message->Data[1];
  400. CAN1_PELI->DATA2 = peli_transmit_message->Data[2];
  401. CAN1_PELI->DATA3 = peli_transmit_message->Data[3];
  402. CAN1_PELI->DATA4 = peli_transmit_message->Data[4];
  403. CAN1_PELI->DATA5 = peli_transmit_message->Data[5];
  404. CAN1_PELI->DATA6 = peli_transmit_message->Data[6];
  405. CAN1_PELI->DATA7 = peli_transmit_message->Data[7];
  406. }
  407. }
  408. else {
  409. CAN1_PELI->ID0 = peli_transmit_message->IDHH;
  410. CAN1_PELI->ID1 = peli_transmit_message->IDHL;
  411. CAN1_PELI->DATA0 = peli_transmit_message->IDLH;
  412. CAN1_PELI->DATA1 = peli_transmit_message->IDLL;
  413. if ((FunctionalState)(peli_transmit_message->RTR) != ENABLE) {
  414. CAN1_PELI->DATA2 = peli_transmit_message->Data[0];
  415. CAN1_PELI->DATA3 = peli_transmit_message->Data[1];
  416. CAN1_PELI->DATA4 = peli_transmit_message->Data[2];
  417. CAN1_PELI->DATA5 = peli_transmit_message->Data[3];
  418. CAN1_PELI->DATA6 = peli_transmit_message->Data[4];
  419. CAN1_PELI->DATA7 = peli_transmit_message->Data[5];
  420. CAN1_PELI->DATA8 = peli_transmit_message->Data[6];
  421. CAN1_PELI->DATA9 = peli_transmit_message->Data[7];
  422. }
  423. }
  424. (CAN1_PELI->MOD & CAN_MOD_STM) ? (CAN1->CMR = CAN_CMR_GTS | CAN_CMR_AT) : (CAN1->CMR = CAN_CMR_TR | CAN_CMR_AT);
  425. }
  426. ////////////////////////////////////////////////////////////////////////////////
  427. /// @brief Initiates and transmits a CAN frame message.
  428. /// @param TxMessage: pointer to a structure which contains CAN Id, CAN DLC and
  429. /// CAN data.
  430. /// @retval None.
  431. ////////////////////////////////////////////////////////////////////////////////
  432. void CAN_Peli_TransmitRepeat(CanPeliTxMsg* peli_transmit_message)
  433. {
  434. CAN1_PELI->FF = (peli_transmit_message->FF << 7) | (peli_transmit_message->RTR << 6) | (peli_transmit_message->DLC);
  435. if (((FunctionalState)peli_transmit_message->FF) != ENABLE) {
  436. CAN1_PELI->ID0 = (peli_transmit_message->IDHH);
  437. CAN1_PELI->ID1 = (peli_transmit_message->IDHL & 0xE0);
  438. if ((FunctionalState)(peli_transmit_message->RTR) != ENABLE) {
  439. CAN1_PELI->DATA0 = peli_transmit_message->Data[0];
  440. CAN1_PELI->DATA1 = peli_transmit_message->Data[1];
  441. CAN1_PELI->DATA2 = peli_transmit_message->Data[2];
  442. CAN1_PELI->DATA3 = peli_transmit_message->Data[3];
  443. CAN1_PELI->DATA4 = peli_transmit_message->Data[4];
  444. CAN1_PELI->DATA5 = peli_transmit_message->Data[5];
  445. CAN1_PELI->DATA6 = peli_transmit_message->Data[6];
  446. CAN1_PELI->DATA7 = peli_transmit_message->Data[7];
  447. }
  448. }
  449. else {
  450. CAN1_PELI->ID0 = peli_transmit_message->IDHH;
  451. CAN1_PELI->ID1 = peli_transmit_message->IDHL;
  452. CAN1_PELI->DATA0 = peli_transmit_message->IDLH;
  453. CAN1_PELI->DATA1 = peli_transmit_message->IDLL;
  454. if ((FunctionalState)(peli_transmit_message->RTR) != ENABLE) {
  455. CAN1_PELI->DATA2 = peli_transmit_message->Data[0];
  456. CAN1_PELI->DATA3 = peli_transmit_message->Data[1];
  457. CAN1_PELI->DATA4 = peli_transmit_message->Data[2];
  458. CAN1_PELI->DATA5 = peli_transmit_message->Data[3];
  459. CAN1_PELI->DATA6 = peli_transmit_message->Data[4];
  460. CAN1_PELI->DATA7 = peli_transmit_message->Data[5];
  461. CAN1_PELI->DATA8 = peli_transmit_message->Data[6];
  462. CAN1_PELI->DATA9 = peli_transmit_message->Data[7];
  463. }
  464. }
  465. (CAN1_PELI->MOD & CAN_MOD_STM) ? (CAN1->CMR = CAN_CMR_GTS | CAN_CMR_AT) : (CAN1->CMR = CAN_CMR_TR);
  466. }
  467. ////////////////////////////////////////////////////////////////////////////////
  468. /// @brief Receives a correct CAN frame.
  469. /// @param RxMessage: pointer to a structure receive frame which contains CAN
  470. /// Id,CAN DLC, CAN data and FMI number.
  471. /// @retval None.
  472. ////////////////////////////////////////////////////////////////////////////////
  473. void CAN_Peli_Receive(CanPeliRxMsg* peli_receive_message)
  474. {
  475. u32 tempid;
  476. peli_receive_message->FF = (CAN1_PELI->FF) >> 7;
  477. peli_receive_message->RTR = ((CAN1_PELI->FF) >> 6) & 0x1;
  478. peli_receive_message->DLC = (CAN1_PELI->FF) & 0xf;
  479. if (((FunctionalState)peli_receive_message->FF) != ENABLE) {
  480. tempid = (u32)(CAN1_PELI->ID1 >> 5);
  481. tempid |= (u32)(CAN1_PELI->ID0 << 3);
  482. peli_receive_message->ID = tempid;
  483. peli_receive_message->Data[0] = CAN1_PELI->DATA0;
  484. peli_receive_message->Data[1] = CAN1_PELI->DATA1;
  485. peli_receive_message->Data[2] = CAN1_PELI->DATA2;
  486. peli_receive_message->Data[3] = CAN1_PELI->DATA3;
  487. peli_receive_message->Data[4] = CAN1_PELI->DATA4;
  488. peli_receive_message->Data[5] = CAN1_PELI->DATA5;
  489. peli_receive_message->Data[6] = CAN1_PELI->DATA6;
  490. peli_receive_message->Data[7] = CAN1_PELI->DATA7;
  491. }
  492. else {
  493. tempid = (u32)((CAN1_PELI->DATA1 & 0xf8) >> 3);
  494. tempid |= (u32)(CAN1_PELI->DATA0 << 5);
  495. tempid |= (u32)(CAN1_PELI->ID1 << 13);
  496. tempid |= (u32)(CAN1_PELI->ID0 << 21);
  497. peli_receive_message->ID = tempid;
  498. peli_receive_message->Data[0] = CAN1_PELI->DATA2;
  499. peli_receive_message->Data[1] = CAN1_PELI->DATA3;
  500. peli_receive_message->Data[2] = CAN1_PELI->DATA4;
  501. peli_receive_message->Data[3] = CAN1_PELI->DATA5;
  502. peli_receive_message->Data[4] = CAN1_PELI->DATA6;
  503. peli_receive_message->Data[5] = CAN1_PELI->DATA7;
  504. peli_receive_message->Data[6] = CAN1_PELI->DATA8;
  505. peli_receive_message->Data[7] = CAN1_PELI->DATA9;
  506. }
  507. CAN_FIFORelease(CAN1);
  508. }
  509. ////////////////////////////////////////////////////////////////////////////////
  510. /// @brief Get available current informatoin in receive FIFO only in Peli
  511. /// workmode.
  512. /// @retval The value in reg RMC
  513. ////////////////////////////////////////////////////////////////////////////////
  514. u32 CAN_Peli_GetRxFIFOInfo(void)
  515. {
  516. return CAN1_PELI->RMC;
  517. }
  518. ////////////////////////////////////////////////////////////////////////////////
  519. /// @brief Returns the CAN's last error code (LEC).
  520. /// @retval Error code:
  521. /// - CAN_ERRORCODE_NoErr: No Error
  522. /// - CAN_ERRORCODE_StuffErr: Stuff Error
  523. /// - CAN_ERRORCODE_FormErr: Form Error
  524. /// - CAN_ERRORCODE_ACKErr : Acknowledgment Error
  525. /// - CAN_ERRORCODE_BitRecessiveErr: Bit Recessive Error
  526. /// - CAN_ERRORCODE_BitDominantErr: Bit Dominant Error
  527. /// - CAN_ERRORCODE_CRCErr: CRC Error
  528. /// - CAN_ERRORCODE_SoftwareSetErr: Software Set Error
  529. ////////////////////////////////////////////////////////////////////////////////
  530. u8 CAN_Peli_GetLastErrorCode(void)
  531. {
  532. // Return the error code
  533. return (u8)CAN1_PELI->ECC;
  534. }
  535. ////////////////////////////////////////////////////////////////////////////////
  536. /// @brief Returns the CAN Receive Error Counter (REC).
  537. /// @note In case of an error during reception, this counter is incremented
  538. /// by 1 or by 8 depending on the error condition as defined by the CAN
  539. /// standard. After every successful reception, the counter is
  540. /// decremented by 1 or reset to 120 if its value was higher than 128.
  541. /// When the counter value exceeds 127, the CAN controller enters the
  542. /// error passive state.
  543. /// @retval CAN Receive Error Counter.
  544. ////////////////////////////////////////////////////////////////////////////////
  545. u8 CAN_Peli_GetReceiveErrorCounter(void)
  546. {
  547. // Return the Receive Error Counter
  548. return (u8)(CAN1_PELI->RXERR);
  549. }
  550. ////////////////////////////////////////////////////////////////////////////////
  551. /// @brief Returns the LSB of the 9-bit can Transmit Error Counter(TEC).
  552. /// @retval LSB of the 8-bit CAN Transmit Error Counter.
  553. ////////////////////////////////////////////////////////////////////////////////
  554. u8 CAN_Peli_GetLSBTransmitErrorCounter(void)
  555. {
  556. // Return the LSB of the 8-bit CAN Transmit Error Counter(TEC)
  557. return (u8)(CAN1_PELI->TXERR);
  558. }
  559. ////////////////////////////////////////////////////////////////////////////////
  560. /// @brief Enables or disables the specified CAN interrupts in peli workmode.
  561. /// @param it: specifies the CAN interrupt sources to be enabled or
  562. /// disabled.
  563. /// This parameter can be:
  564. /// @arg CAN_IT_RI: Receive FIFO not empty Interrupt
  565. /// @arg CAN_IT_TI: Transmit Interrupt
  566. /// @arg CAN_IT_EI: ERROR Interrupt
  567. /// @arg CAN_IT_DOI: Data voerflow Interrupt
  568. /// @arg CAN_IT_WUI: Wakeup Interrupt
  569. /// @arg CAN_IT_EPI(only Peli): passive error Interrupt
  570. /// @arg CAN_IT_ALI(only Peli): arbiter lose Interrupt
  571. /// @arg CAN_IT_BEI(only Peli): bus error Interrupt
  572. /// @arg CAN_IT_ALL: use it can enble all Interrupt
  573. /// @param state: new state of the CAN interrupts.
  574. /// This parameter can be: ENABLE or DISABLE.
  575. /// @retval None.
  576. ////////////////////////////////////////////////////////////////////////////////
  577. void CAN_Peli_ITConfig(u32 it, FunctionalState state)
  578. {
  579. (state) ? (CAN1_PELI->IER |= it) : (CAN1_PELI->IER &= ~it);
  580. }
  581. ////////////////////////////////////////////////////////////////////////////////
  582. /// @brief Checks whether the specified CAN interrupt has occurred or not.
  583. /// @param it: specifies the CAN interrupt source to check.
  584. /// This parameter can be one of the following values:
  585. /// @arg CAN_IT_RI: Receive FIFO not empty Interrupt
  586. /// @arg CAN_IT_TI: Transmit Interrupt
  587. /// @arg CAN_IT_EI: ERROR Interrupt
  588. /// @arg CAN_IT_DOI: Data voerflow Interrupt
  589. /// @arg CAN_IT_WUI: Wakeup Interrupt
  590. /// @arg CAN_IT_EPI(only Peli): passive error Interrupt
  591. /// @arg CAN_IT_ALI(only Peli): arbiter lose Interrupt
  592. /// @arg CAN_IT_BEI(only Peli): bus error Interrupt
  593. /// @arg CAN_IT_ALL: use it can enble all Interrupt
  594. /// @retval The current state of it (SET or RESET).
  595. ////////////////////////////////////////////////////////////////////////////////
  596. ITStatus CAN_Peli_GetITStatus(u32 it)
  597. {
  598. return (ITStatus)(((CAN1_PELI->IR & it) != it) ? RESET : SET);
  599. }
  600. ////////////////////////////////////////////////////////////////////////////////
  601. /// @brief Config CAN_Peli_InitTypeDef baud parameter.
  602. /// @param CAN_Peli_InitTypeDef: CAN struct.
  603. /// @param src_clk: CAN module clock.
  604. /// @param baud: specified baud.
  605. /// @retval The current state of it (SET or RESET).
  606. ////////////////////////////////////////////////////////////////////////////////
  607. void CAN_AutoCfg_BaudParam(CAN_Peli_InitTypeDef* init_struct, u32 src_clk, u32 baud)
  608. {
  609. u32 i, value = baud, record = 1;
  610. u32 remain = 0, sumPrescaler = 0;
  611. while ((baud == 0) || (src_clk == 0))
  612. ;
  613. sumPrescaler = src_clk / baud;
  614. sumPrescaler = sumPrescaler / 2;
  615. for (i = 25; i > 3; i--) {
  616. remain = sumPrescaler - ((sumPrescaler / i) * i);
  617. if (remain == 0) {
  618. record = i;
  619. break;
  620. }
  621. else {
  622. if (remain < value) {
  623. value = remain;
  624. record = i;
  625. }
  626. }
  627. }
  628. init_struct->SJW = 0;
  629. init_struct->BRP = (sumPrescaler / record) - 1;
  630. init_struct->TESG2 = (record - 3) / 3;
  631. init_struct->TESG1 = (record - 3) - init_struct->TESG2;
  632. }
  633. /// @}
  634. /// @}
  635. /// @}