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