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 
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