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