1 /*
2   ******************************************************************************
3   * @file    HAL_Can.c
4   * @version V1.0.0
5   * @date    2020
6   * @brief   CAN HAL module driver.
7   *          This file provides firmware functions to manage the following
8   *          functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (CAN).
9   *           @ Initialization and de-initialization functions
10   *           @ IO operation functions
11   *           @ Peripheral Control functions
12   ******************************************************************************
13 */
14 #include "ACM32Fxx_HAL.h"
15 
16 /*********************************************************************************
17 * Function    : HAL_CAN_OperatingModeRequest
18 * Description : Select the CAN Operation mode.
19 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
20 *                      the configuration information for CAN module
21 * Input       : CAN_OperatingMode:CAN Operating Mode. This parameter can be one  of @ref CAN_OperatingMode enumeration.
22 * Output      : HAL status
23 * Author      : CWT                         Data : 2020
24 **********************************************************************************/
HAL_CAN_OperatingModeRequest(CAN_HandleTypeDef * hcan,uint8_t CAN_OperatingMode)25 HAL_StatusTypeDef HAL_CAN_OperatingModeRequest(CAN_HandleTypeDef *hcan, uint8_t CAN_OperatingMode)
26 {
27     uint8_t status = HAL_ERROR;
28     /* Check the parameters */
29     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return HAL_ERROR;
30     if(!IS_CAN_OPERATING_MODE(CAN_OperatingMode)) return HAL_ERROR;
31     if (CAN_OperatingMode == CAN_OperatingMode_Initialization)
32     {
33         hcan->Instance->MOD |= CAN_OperatingMode_Initialization;  // enter Initialization
34         if ((hcan->Instance->MOD & CAN_MOD_RM) != CAN_OperatingMode_Initialization)
35         {
36             status = HAL_ERROR;
37         }
38         else
39         {
40             status = HAL_OK;
41         }
42     }
43     else if(CAN_OperatingMode == CAN_OperatingMode_Normal)
44     {
45         hcan->Instance->MOD &=~ CAN_OperatingMode_Initialization;   //1-->0 enter Normal
46         if ((hcan->Instance->MOD & CAN_MOD_RM) != CAN_OperatingMode_Normal)
47         {
48             status = HAL_ERROR;
49         }
50         else
51         {
52             status = HAL_OK;
53         }
54     }
55     else if (CAN_OperatingMode == CAN_OperatingMode_Sleep)
56     {
57         hcan->Instance->MOD |= CAN_OperatingMode_Sleep;  // enter Normal
58         if ((hcan->Instance->MOD & CAN_MOD_SM) != CAN_OperatingMode_Sleep)
59         {
60             status = HAL_ERROR;
61         }
62         else
63         {
64             status = HAL_OK;
65         }
66     }
67     else if(CAN_OperatingMode == CAN_OperatingMode_Listen)
68     {
69         hcan->Instance->MOD |= CAN_OperatingMode_Listen;  // enter Normal
70         if((hcan->Instance->MOD & CAN_MOD_LOM) != CAN_OperatingMode_Listen)
71         {
72             status = HAL_ERROR;
73         }
74         else
75         {
76             status = HAL_OK;
77         }
78     }
79     else
80     {
81         status = HAL_ERROR;
82     }
83     return  (uint8_t) status;
84 }
85 
86 
87 /*********************************************************************************
88 * Function    : HAL_CAN_MspInit
89 * Description : Initialize the CAN MSP.
90 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
91 *                      the configuration information for CAN module
92 * Output      :
93 * Author      : CWT                         Data : 2020
94 **********************************************************************************/
95 
HAL_CAN_MspInit(CAN_HandleTypeDef * hcan)96 __weak void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan)
97 {
98     /* NOTE : This function should not be modified, when the callback is needed,
99                 the HAL_UART_MspInit can be implemented in the user file
100     */
101     /* For Example */
102     GPIO_InitTypeDef   GPIO_InitStruct;
103     if(hcan->Instance==CAN1)
104     {
105         /* Enable CAN clock */
106         System_Module_Enable(EN_CAN1);
107         GPIO_InitTypeDef GPIO_InitStructure;
108         /* Initialization GPIO */
109         /* PA11:Rx */  /* PA12:Tx */
110         GPIO_InitStructure.Pin = GPIO_PIN_11|GPIO_PIN_12;
111         GPIO_InitStructure.Alternate=GPIO_FUNCTION_5;
112         GPIO_InitStructure.Pull=GPIO_PULLUP;
113         GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
114         HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
115 
116     }
117     else if(hcan->Instance==CAN2)
118     {
119         /* Enable CAN clock */
120         System_Module_Enable(EN_CAN2);
121         GPIO_InitTypeDef GPIO_InitStructure;
122         /* Initialization GPIO */
123         /* PB5:Rx */  /* PB6:Tx */
124         GPIO_InitStructure.Pin = GPIO_PIN_5|GPIO_PIN_6;
125         GPIO_InitStructure.Alternate=GPIO_FUNCTION_5;
126         GPIO_InitStructure.Pull=GPIO_PULLUP;
127         GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
128         HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
129 
130         /* Enable the CAN Receive interrupt */
131         hcan->Instance->IER |= CAN_IER_RIE;
132         NVIC_ClearPendingIRQ(CAN2_IRQn);
133         NVIC_SetPriority(CAN2_IRQn, 5);
134         NVIC_EnableIRQ(CAN2_IRQn);
135     }
136 
137 }
138 /*********************************************************************************
139 * Function    : HAL_CAN_MspDeInit
140 * Description :	CAN MSP De-Initialization
141 *               This function frees the hardware resources used in this example:
142 *              - Disable the Peripheral's clock
143 *              - Revert GPIO configuration to their default state
144 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
145 *                      the configuration information for CAN module
146 * Output      :
147 * Author      : CWT                         Data : 2020
148 **********************************************************************************/
HAL_CAN_MspDeInit(CAN_HandleTypeDef * hcan)149 void HAL_CAN_MspDeInit(CAN_HandleTypeDef *hcan)
150 {
151     if(hcan->Instance==CAN1)
152     {
153         /* Reset CAN clock */
154         System_Module_Disable(EN_CAN1);
155         GPIO_InitTypeDef GPIO_InitStructure;
156         /* Initialization GPIO */
157         /* PA11:Rx */  /* PA12:Tx */
158         HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11);
159         HAL_GPIO_DeInit(GPIOA, GPIO_PIN_12);
160         }
161         else if(hcan->Instance==CAN2)
162         {
163         /* Reset CAN clock */
164         System_Module_Disable(EN_CAN2);
165         GPIO_InitTypeDef GPIO_InitStructure;
166         /* Initialization GPIO */
167         /* PB5:Rx */  /* PB6:Tx */
168         HAL_GPIO_DeInit(GPIOB, GPIO_PIN_5);
169         HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6);
170     }
171 }
172 /*********************************************************************************
173 * Function    : HAL_CAN_Init
174 * Description :	Initializes the CAN peripheral according to the specified  parameters in the CAN_HandleTypeDef..
175 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
176 *                      the configuration information for CAN module
177 * Output      : HAL status
178 * Author      : CWT                         Data : 2020
179 **********************************************************************************/
HAL_CAN_Init(CAN_HandleTypeDef * hcan)180 HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef *hcan)
181 {
182     uint8_t InitStatus = HAL_ERROR;
183     /* Check the parameters */
184     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return HAL_ERROR;
185     if(!IS_CAN_MODE(hcan->Init.CAN_Mode)) return HAL_ERROR;
186     if(!IS_CAN_SJW(hcan->Init.CAN_SJW)) return HAL_ERROR;
187     if(!IS_CAN_TSEG1(hcan->Init.CAN_TSEG1)) return HAL_ERROR;
188     if(!IS_CAN_TSEG2(hcan->Init.CAN_TSEG2)) return HAL_ERROR;
189     if(!IS_CAN_BRP(hcan->Init.CAN_BRP)) return HAL_ERROR;
190     if(!IS_CAN_SAM(hcan->Init.CAN_SAM)) return HAL_ERROR;
191     /* Reset the CANx */
192     if(hcan->Instance==CAN1)
193     {
194         System_Module_Reset(RST_CAN1);
195     }
196     else
197     {
198         System_Module_Reset(RST_CAN2);
199     }
200     HAL_CAN_MspInit(hcan);
201     HAL_CAN_OperatingModeRequest(hcan,CAN_OperatingMode_Initialization);//enter CAN_OperatingMode_Initialization
202     hcan->Instance->BTR0=0xff;
203     hcan->Instance->BTR0=(hcan->Init.CAN_SJW<<6)|(hcan->Init.CAN_BRP);
204     hcan->Instance->BTR1=(hcan->Init.CAN_SAM<<7)|(hcan->Init.CAN_TSEG2<<4)|(hcan->Init.CAN_TSEG1);
205     HAL_CAN_OperatingModeRequest(hcan,CAN_OperatingMode_Normal);//enter CAN_OperatingMode_Normal
206     return HAL_OK;
207 }
208 
209 
210 /*********************************************************************************
211 * Function    : HAL_CAN_DeInit
212 * Description :	Deinitializes the CAN peripheral registers to their default
213 *               reset values.
214 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
215 *                      the configuration information for CAN module
216 * Output      : HAL status
217 * Author      : CWT                         Data : 2020
218 **********************************************************************************/
HAL_CAN_DeInit(CAN_HandleTypeDef * hcan)219 HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef *hcan)
220 {
221     /* Check CAN handle */
222     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return HAL_ERROR;
223 
224     HAL_CAN_MspDeInit(hcan);
225 
226     /* Reset the CAN peripheral */
227     SET_BIT(hcan->Instance->MOD, CAN_MOD_RM);
228 
229     /* Return function status */
230     return HAL_OK;
231 }
232 /*********************************************************************************
233 * Function    : HAL_CAN_Transmit
234 * Description :	Initiates the transmission of a message.
235 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
236 *                      the configuration information for CAN module
237 * Input       : TxMessage : ppointer to a structure which contains CAN Id, CAN
238   *                         DLC and CAN data.
239 * Output      :
240 * Author      : CWT                         Data : 2020
241 **********************************************************************************/
HAL_CAN_Transmit(CAN_HandleTypeDef * hcan,CanTxRxMsg * TxMessage)242 HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef *hcan, CanTxRxMsg* TxMessage)
243 {
244     uint8_t i = 0;
245     uint8_t can_id[4];
246     uint32_t frame_header;
247     /* Check the parameters */
248     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return HAL_ERROR ;
249     if(!IS_CAN_IDTYPE(TxMessage->IDE)) return HAL_ERROR;
250     if(!IS_CAN_RTR(TxMessage->RTR)) return HAL_ERROR;
251     if(!IS_CAN_DLC(TxMessage->DLC)) return HAL_ERROR;
252     /* Set up the DLC */
253     frame_header =TxMessage->DLC & 0x0F;  // standard data frame
254     /* Set up the Id */
255     if(TxMessage->IDE==CAN_Id_Standard)//Standard ID
256     {
257         can_id[0] = TxMessage->StdId >>3;
258         can_id[1] = (TxMessage->StdId&0x07)<<5;
259         for(i=0;i<2;i++)
260         {
261             hcan->Instance->DF.DATABUF[1+i] = can_id[i];
262         }
263     }
264     else//Id_Extended
265     {
266         can_id[0] = TxMessage->ExtId>>21;
267         can_id[1] = (TxMessage->ExtId&0x1FE000)>>13;
268         can_id[2] = (TxMessage->ExtId&0x1FE0)>>5;
269         can_id[3] = (TxMessage->ExtId&0x1F)<<3;
270         frame_header |= (CAN_Id_Extended<<7);  // extended data frame
271         for(i=0;i<4;i++)
272         {
273             hcan->Instance->DF.DATABUF[1+i] = can_id[i];
274         }
275     }
276     if(TxMessage->RTR==CAN_RTR_Data)//CAN_RTR_Data
277     {
278         frame_header&=~(CAN_RTR_Remote<<6);
279         for(i=0; i<TxMessage->DLC; i++)
280         {
281             hcan->Instance->DF.DATABUF[3+(TxMessage->IDE*2)+i] = TxMessage->Data[i];
282         }
283     }
284     else//CAN_RTR_Remote
285     {
286         frame_header|=(CAN_RTR_Remote<<6);
287     }
288     hcan->Instance->DF.DATABUF[0]=frame_header;
289     hcan->Instance->CMR = CAN_CMR_TR;  // transfer request
290     while((hcan->Instance->SR & CAN_SR_TCS)==0x00); //wait for send ok
291     return HAL_OK;
292 }
293 
294 /*********************************************************************************
295 * Function    : HAL_CAN_CancelTransmit
296 * Description :	Cancels a transmit request.
297 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
298 *                      the configuration information for CAN module
299 * Output      :
300 * Author      : CWT                         Data : 2020
301 **********************************************************************************/
HAL_CAN_CancelTransmit(CAN_HandleTypeDef * hcan)302 void HAL_CAN_CancelTransmit(CAN_HandleTypeDef *hcan)
303 {
304     /* Check the parameters */
305     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return ;
306     /* abort transmission */
307     hcan->Instance->CMR |= CAN_CMR_AT; //Abort Transmission
308 }
309 
310 /*********************************************************************************
311 * Function    : HAL_CAN_Receive
312 * Description :	Receives a message.
313 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
314 *                      the configuration information for CAN module
315 * Input       : RxMessage : pointer to a structure receive message which contains
316 *                           CAN Id, CAN DLC, CAN datas  .
317 * Output      :
318 * Author      : CWT                         Data : 2020
319 **********************************************************************************/
HAL_CAN_Receive_IT(CAN_HandleTypeDef * hcan,CanTxRxMsg * RxMessage)320 HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef *hcan, CanTxRxMsg* RxMessage)
321 {
322     /* Check the parameters */
323     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return HAL_ERROR ;
324 
325     hcan->RxMessage=RxMessage;
326 
327     /* Enable the CAN Receive interrupt */
328     hcan->Instance->IER |= CAN_IER_RIE;
329     NVIC_ClearPendingIRQ(CAN1_IRQn);
330     NVIC_SetPriority(CAN1_IRQn, 5);
331     NVIC_EnableIRQ(CAN1_IRQn);
332 
333     return HAL_OK;
334 }
335 
336 
337 /*********************************************************************************
338 * Function    : HAL_CAN_Receive
339 * Description :	Receives a message.
340 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
341 *                      the configuration information for CAN module
342 * Input       : RxMessage : pointer to a structure receive message which contains
343 *                           CAN Id, CAN DLC, CAN datas  .
344 * Output      :
345 * Author      : CWT                         Data : 2020
346 **********************************************************************************/
HAL_CAN_Receive(CAN_HandleTypeDef * hcan,CanTxRxMsg * RxMessage)347 HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef *hcan, CanTxRxMsg* RxMessage)
348 {
349     /* Check the parameters */
350     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return HAL_ERROR ;
351     while(!(hcan->Instance->SR & CAN_SR_RBS));
352     HAL_CAN_GetRxMessage(hcan, RxMessage);
353     return HAL_OK;
354 }
355 
HAL_CAN_GetRxMessage(CAN_HandleTypeDef * hcan,CanTxRxMsg * RxMessage)356 void HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, CanTxRxMsg* RxMessage)
357 {
358     uint8_t i=0;
359     /* Check the parameters */
360     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return ;
361     if(0 == (hcan->Instance->SR & CAN_SR_RBS) ) return;  // receive fifo not empty
362     /* Get the IDE */
363     RxMessage->IDE = (uint8_t)(0x80 & hcan->Instance->DF.DATABUF[0])>>7;
364     /* Get the RTR */
365     RxMessage->RTR = (uint8_t)(0x40 & hcan->Instance->DF.DATABUF[0])>>6;
366     /* Get the DLC */
367     RxMessage->DLC = (uint8_t)0x0F & hcan->Instance->DF.DATABUF[0];
368     if (RxMessage->IDE == CAN_Id_Standard)
369     {
370         RxMessage->StdId = (uint32_t)(( hcan->Instance->DF.DATABUF[1]<<8) |  hcan->Instance->DF.DATABUF[2])>>5;;
371         for(i=0; i<RxMessage->DLC; i++)
372         {
373             RxMessage->Data[i] = hcan->Instance->DF.DATABUF[3+i];
374         }
375     }
376     else
377     {
378         RxMessage->ExtId = (uint32_t)(( hcan->Instance->DF.DATABUF[1]<<24) | ( hcan->Instance->DF.DATABUF[2]<<16) | ( hcan->Instance->DF.DATABUF[3]<<8) | (hcan->Instance->DF.DATABUF[4] ))>>3;;
379         for(i=0; i<RxMessage->DLC; i++)
380         {
381             RxMessage->Data[i] = hcan->Instance->DF.DATABUF[5+i];
382         }
383     }
384     /* Release the FIFO */
385     hcan->Instance->CMR |= CAN_CMR_RRB; //Release Receive Buffer
386 }
387 
388 /**
389   * @brief  Initializes the CAN peripheral according to the specified
390   *         parameters in the CAN_FilterInitStruct.
391   * @param  CANx:   where x can be 1 or 2 to to select the CAN peripheral.
392             CAN_FilterInitStruct: pointer to a CAN_FilterInitTypeDef
393   *                               structure that contains the configuration
394   *                               information.
395   * @retval None.
396   */
397 
398 /*********************************************************************************
399 * Function    : HAL_CAN_ConfigFilter
400 * Description :	Initializes the CAN peripheral according to the specified  parameters in the CAN_FilterInitStruct.
401 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
402 *                      the configuration information for CAN module
403 * Input       : CAN_FilterInitStruct : pointer to a CAN_FilterInitTypeDef structure that contains the configuration
404 *                                       information.
405 * Output      :
406 * Author      : CWT                         Data : 2020
407 **********************************************************************************/
HAL_CAN_ConfigFilter(CAN_HandleTypeDef * hcan,CAN_FilterInitTypeDef * CAN_FilterInitStruct)408 void HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan,CAN_FilterInitTypeDef* CAN_FilterInitStruct)
409 {
410     HAL_CAN_OperatingModeRequest(hcan,CAN_OperatingMode_Initialization);//enter CAN_OperatingMode_Initialization
411     /* Filter Mode */
412     if (CAN_FilterInitStruct->CAN_FilterMode ==CAN_FilterMode_Dual) /*Dual mode*/
413     {
414         hcan->Instance->MOD &= ~CAN_MOD_AFM;
415         /*Dual mode ACR set*/
416         hcan->Instance->DF.FILTER.ACR[0] = (CAN_FilterInitStruct->CAN_FilterId1&0x1FE00000)>>21;	/*Dual mode ACR0=ID28...ID21 of ID1*/
417         hcan->Instance->DF.FILTER.ACR[1] = (CAN_FilterInitStruct->CAN_FilterId1&0x1FE000)>>13; 		/*Dual mode ACR0=ID20...ID13 of ID1*/
418         hcan->Instance->DF.FILTER.ACR[2] = (CAN_FilterInitStruct->CAN_FilterId2&0x1FE00000)>>21;  /*Dual mode ACR0=ID28...ID21 of ID2*/
419         hcan->Instance->DF.FILTER.ACR[3] = (CAN_FilterInitStruct->CAN_FilterId2&0x1FE000)>>13;     /*Dual mode ACR0=ID20...ID13 of ID2*/
420         /*Dual mode AMR set*/
421         hcan->Instance->DF.FILTER.AMR[0] = (CAN_FilterInitStruct->CAN_FilterMaskId1)>>24;
422         hcan->Instance->DF.FILTER.AMR[1] = (CAN_FilterInitStruct->CAN_FilterMaskId1&0xFF0000)>>16;
423         hcan->Instance->DF.FILTER.AMR[2] = (CAN_FilterInitStruct->CAN_FilterMaskId2)>>24;
424         hcan->Instance->DF.FILTER.AMR[3] = (CAN_FilterInitStruct->CAN_FilterMaskId2&0xFF0000)>>16;
425     }
426     else /*Single mode*/
427     {
428         hcan->Instance->MOD |= CAN_MOD_AFM;
429         /*Single mode ACR set*/
430         hcan->Instance->DF.FILTER.ACR[0] = (CAN_FilterInitStruct->CAN_FilterId1&0x1FE00000)>>21;	/*Single mode ACR0=ID28...ID21*/
431         hcan->Instance->DF.FILTER.ACR[1] = (CAN_FilterInitStruct->CAN_FilterId1&0x1FE000)>>13; 		/*Single mode ACR1=ID20...ID13*/
432         hcan->Instance->DF.FILTER.ACR[2] = (CAN_FilterInitStruct->CAN_FilterId1&0x1FE0)>>5; 			/*Single mode ACR2=ID12...ID5*/
433         hcan->Instance->DF.FILTER.ACR[3] = (CAN_FilterInitStruct->CAN_FilterId1&0x1F)<<3;  				/*Single mode ACR3=ID4...ID0*/
434         /*Single mode AMR set*/
435         hcan->Instance->DF.FILTER.AMR[0] = (CAN_FilterInitStruct->CAN_FilterMaskId1)>>24;
436         hcan->Instance->DF.FILTER.AMR[1] = (CAN_FilterInitStruct->CAN_FilterMaskId1&0xFF0000)>>16;
437         hcan->Instance->DF.FILTER.AMR[2] = (CAN_FilterInitStruct->CAN_FilterMaskId1&0xFF00)>>8;
438         hcan->Instance->DF.FILTER.AMR[3] = (CAN_FilterInitStruct->CAN_FilterMaskId1&0xFF);
439     }
440 
441     HAL_CAN_OperatingModeRequest(hcan,CAN_OperatingMode_Normal);//enter CAN_OperatingMode_Initialization
442 }
443 
444 
445 /*********************************************************************************
446 * Function    : HAL_CAN_Sleep
447 * Description :	Enters the sleep mode.
448 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
449 *                      the configuration information for CAN module
450 * Output      :
451 * Author      : CWT                         Data : 2020
452 **********************************************************************************/
HAL_CAN_Sleep(CAN_HandleTypeDef * hcan)453 HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef *hcan)
454 {
455     HAL_StatusTypeDef status;
456     /* Check the parameters */
457     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return HAL_ERROR;
458     /* Request Sleep mode */
459     hcan->Instance->MOD |= CAN_MOD_SM; //Enter Sleep Mode
460 
461     /* Sleep mode status */
462     if ((hcan->Instance->MOD & CAN_MOD_SM) == CAN_MOD_SM)
463     {
464     /* Sleep mode entered */
465         status= HAL_OK;
466     }else
467     {
468         status=HAL_ERROR;
469     }
470     /* return sleep mode status */
471     return status;
472 }
473 
474 /*********************************************************************************
475 * Function    : HAL_CAN_WakeUp
476 * Description :	Wakes the CAN up.
477 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
478 *                      the configuration information for CAN module
479 * Output      :
480 * Author      : CWT                         Data : 2020
481 **********************************************************************************/
HAL_CAN_WakeUp(CAN_HandleTypeDef * hcan)482 HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan)
483 {
484     HAL_StatusTypeDef status;
485     /* Check the parameters */
486     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return HAL_ERROR;
487     /* sleep wake mode */
488     hcan->Instance->MOD &=~ CAN_MOD_SM; //Enter Sleep Mode
489 
490     /* sleep wake status */
491     if ((hcan->Instance->MOD & CAN_MOD_SM)== CAN_MOD_SM)
492     {
493         /* sleep wake not entered */
494         status= HAL_ERROR;
495     }else
496     {
497         status=HAL_OK;
498     }
499     /* return sleep mode status */
500     return status;
501 }
502 
503 /*********************************************************************************
504 * Function    : HAL_CAN_GetTransmitErrorCounter
505 * Description :	Returns the CANx Transmit Error Counter(TXERR).
506 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
507 *                      the configuration information for CAN module
508 * Output      :
509 * Author      : CWT                         Data : 2020
510 **********************************************************************************/
HAL_CAN_GetTransmitErrorCounter(CAN_HandleTypeDef * hcan)511 int8_t HAL_CAN_GetTransmitErrorCounter(CAN_HandleTypeDef *hcan)
512 {
513     uint8_t counter=0;
514     /* Check the parameters */
515     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return -1;
516     /* Get the  CANx Transmit Error Counter(TXERR) */
517     counter = (uint8_t)(hcan->Instance->TXERR);
518     /* Return the CANx Transmit Error Counter(TXERR) */
519     return counter;
520 }
521 
522 
523 /*********************************************************************************
524 * Function    : HAL_CAN_GetReceiveErrorCounter
525 * Description :	Returns the  CANx Receive Error Counter(RXERR).
526 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
527 *                      the configuration information for CAN module
528 * Output      :
529 * Author      : CWT                         Data : 2020
530 **********************************************************************************/
HAL_CAN_GetReceiveErrorCounter(CAN_HandleTypeDef * hcan)531 int8_t HAL_CAN_GetReceiveErrorCounter(CAN_HandleTypeDef *hcan)
532 {
533     uint8_t counter=0;
534     /* Check the parameters */
535     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return -1;
536     /* Get the  CANx Receive Error Counter(RXERR) */
537     counter = (uint8_t)(hcan->Instance->RXERR);
538     /* Return the CANx Receive Error Counter(RXERR) */
539     return counter;
540 }
541 
542 
543 /*********************************************************************************
544 * Function    : HAL_CAN_GetErrorCode
545 * Description :	Returns the CANx's  error code (ECC).
546 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
547 *                      the configuration information for CAN module
548 * Input       : Error_Type:This parameter can be one of the following flags:
549 *														CAN_ErrorType_SegCode
550 *														CAN_ErrorType_Direction
551 *														CAN_ErrorType_ErrCode
552 * Output      :
553 * Author      : CWT                         Data : 2020
554 **********************************************************************************/
HAL_CAN_GetErrorCode(CAN_HandleTypeDef * hcan,uint32_t Error_Type)555 int8_t HAL_CAN_GetErrorCode(CAN_HandleTypeDef *hcan,uint32_t Error_Type)
556 {
557     uint8_t ErrorCode=0;
558     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return -1;
559     if(!IS_CAN_ErrorType(Error_Type)) return -1;
560     /* Get the CANx  Error SegCode */
561     if(Error_Type==CAN_ErrorType_SegCode)
562     {
563         ErrorCode= (uint8_t)(hcan->Instance->ECC & CAN_ErrorType_SegCode);
564     }
565     /* Get the CANx  Error Direction */
566     else if(Error_Type==CAN_ErrorType_Direction)
567     {
568         ErrorCode= (uint8_t)((hcan->Instance->ECC & CAN_ErrorType_Direction)>>5);
569     }
570     /* Get the CANx  Error ErrCode */
571     else
572     {
573         ErrorCode= (uint8_t)((hcan->Instance->ECC & CAN_ErrorType_ErrCode)>>6);
574     }
575     return ErrorCode;
576 }
577 
578 /*********************************************************************************
579 * Function    : HAL_CAN_GetErrorAlarmCounter
580 * Description :	Returns the  CANx Error  Alarm Counter(EWLR).
581 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
582 *                      the configuration information for CAN module
583 * Output      :
584 * Author      : CWT                         Data : 2020
585 **********************************************************************************/
HAL_CAN_GetErrorAlarmCounter(CAN_HandleTypeDef * hcan)586 int8_t HAL_CAN_GetErrorAlarmCounter(CAN_HandleTypeDef *hcan)
587 {
588     uint8_t counter=0;
589     /* Check the parameters */
590     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return -1;
591     /* Get the  CANx Error Alarm Counter(EWLR) */
592     counter = (uint8_t)(hcan->Instance->EWLR);
593     /* Return the CANx Error Alarm Counter(EWLR) */
594     return counter;
595 }
596 
597 /*********************************************************************************
598 * Function    : HAL_CAN_GetArbitrationErrorPosition
599 * Description :	Returns the  CANx Arbitration Error Position(ALC).
600 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
601 *                      the configuration information for CAN module
602 * Output      :
603 * Author      : CWT                         Data : 2020
604 **********************************************************************************/
HAL_CAN_GetArbitrationErrorPosition(CAN_HandleTypeDef * hcan)605 int8_t HAL_CAN_GetArbitrationErrorPosition(CAN_HandleTypeDef *hcan)
606 {
607     uint8_t position=0;
608     /* Check the parameters */
609     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return -1;
610     /* Get the  CANx Arbitration Error Counter(ALC) */
611     position = (uint8_t)((hcan->Instance->ALC)+1);
612     /* Return the CANx Arbitration Error Counter(ALC) */
613     return position;
614 }
615 
616 
617 /*********************************************************************************
618 * Function    : HAL_CAN_GetReceiveFiFoCounter
619 * Description :	Returns the  CANx Receive FiFo Counter(RMC).
620 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
621 *                      the configuration information for CAN module
622 * Output      :
623 * Author      : CWT                         Data : 2020
624 **********************************************************************************/
HAL_CAN_GetReceiveFiFoCounter(CAN_HandleTypeDef * hcan)625 int8_t HAL_CAN_GetReceiveFiFoCounter(CAN_HandleTypeDef *hcan)
626 {
627     uint8_t counter=0;
628     /* Check the parameters */
629     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return -1;
630     /* Get the  CANx Receive FiFo Counter(RMC) */
631     counter = (uint8_t)(hcan->Instance->RMC);
632     /* Return the CANx Receive FiFo Counter(RMC) */
633     return counter;
634 }
635 
636 
637 /*********************************************************************************
638 * Function    : HAL_CAN_GetReceiveFiFoAddr
639 * Description :	 Returns the  CANx Receive FiFo start address(RBSA).
640 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
641 *                      the configuration information for CAN module
642 * Output      :
643 * Author      : CWT                         Data : 2020
644 **********************************************************************************/
HAL_CAN_GetReceiveFiFoAddr(CAN_HandleTypeDef * hcan)645 int8_t HAL_CAN_GetReceiveFiFoAddr(CAN_HandleTypeDef *hcan)
646 {
647     uint8_t addr=0;
648     /* Check the parameters */
649     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return -1;
650     /* Get the  CANx Receive FiFo start address(RBSA) */
651     addr = (uint8_t)(hcan->Instance->RBSA);
652     /* Return the CANx Receive FiFo start address(RBSA) */
653     return addr;
654 }
655 
656 
657 /*********************************************************************************
658 * Function    : HAL_CAN_ReleaseReceiveFIFO
659 * Description :	Releases the Receive FIFO.
660 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
661 *                      the configuration information for CAN module
662 * Output      :
663 * Author      : CWT                         Data : 2020
664 **********************************************************************************/
HAL_CAN_ReleaseReceiveFIFO(CAN_HandleTypeDef * hcan)665 void HAL_CAN_ReleaseReceiveFIFO(CAN_HandleTypeDef *hcan)
666 {
667     /* Check the parameters */
668     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return;
669     /* Releases the Receive FIFO. */
670     hcan->Instance->CMR|=CAN_CMR_RRB;
671 }
672 
673 
674 /*********************************************************************************
675 * Function    : HAL_CAN_ClearOverload
676 * Description : Clear Overload
677 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
678 *                      the configuration information for CAN module
679 * Output      :
680 * Author      : CWT                         Data : 2020
681 **********************************************************************************/
HAL_CAN_ClearOverload(CAN_HandleTypeDef * hcan)682 void HAL_CAN_ClearOverload(CAN_HandleTypeDef *hcan)
683 {
684     /* Check the parameters */
685     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return;
686     /* Clear Overload. */
687     hcan->Instance->CMR|=CAN_CMR_CDO;
688 }
689 
690 
691 /*********************************************************************************
692 * Function    : HAL_CAN_SlefReceive
693 * Description : Slef Receive
694 * Input       : hcan : pointer to a CAN_HandleTypeDef structure that contains
695 *                      the configuration information for CAN module
696 * Output      :
697 * Author      : CWT                         Data : 2020
698 **********************************************************************************/
HAL_CAN_SelfReceive(CAN_HandleTypeDef * hcan)699 void HAL_CAN_SelfReceive(CAN_HandleTypeDef *hcan)
700 {
701     /* Check the parameters */
702     if(!IS_CAN_ALL_PERIPH(hcan->Instance)) return;
703     /* Slef Receive. */
704     hcan->Instance->CMR|=CAN_CMR_SRR;
705     while((hcan->Instance->SR & CAN_SR_TCS)==0x00); //wait for send ok
706 }
707 
708 /*********************************************************************************
709 * Function    : HAL_CAN_IRQHandler
710 * Description : This function handles CAN interrupt request.
711 * Input       : hdma : pointer to a CAN_HandleTypeDef structure that contains
712 *                      the configuration information for CAN module
713 * Outpu       :
714 * Author      : Chris_Kyle                         Data : 2020
715 **********************************************************************************/
HAL_CAN_IRQHandler(CAN_HandleTypeDef * hcan)716 void HAL_CAN_IRQHandler(CAN_HandleTypeDef *hcan)
717 {
718     volatile uint32_t lu32_IR;
719     lu32_IR = hcan->Instance->IR;//read clear
720 
721     if(lu32_IR & CAN_IR_RI) //RI
722     {
723         /* CAN ReceiveIT complete callback */
724         HAL_CAN_GetRxMessage(hcan, hcan->RxMessage);
725         hcan->CAN_ReceiveIT_Callback(hcan);
726     }
727     if(lu32_IR & CAN_IR_TI) //TI
728     {
729         /* CAN TransmitIT complete callback */
730         hcan->CAN_TransmitIT_Callback(hcan);
731     }
732 }