1+ // clang-format off
2+ #include "fdcan.h"
3+ #include <stdint.h>
4+ #include <string.h>
5+
6+ /* Initializes CAN */
7+ HAL_StatusTypeDef can_init (can_t * can )
8+ {
9+
10+ /* Init these guys to 0 */
11+ can -> standard_filter_index = 0 ;
12+ can -> extended_filter_index = 0 ;
13+
14+ /* Config interrupts */
15+ HAL_StatusTypeDef status = HAL_FDCAN_ConfigInterruptLines (can -> hcan , FDCAN_IT_RX_FIFO0_NEW_MESSAGE , FDCAN_INTERRUPT_LINE0 );
16+ if (status != HAL_OK )
17+ {
18+ printf ("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ConfigInterruptLines() (Status: %d).\n" , status );
19+ return status ;
20+ }
21+
22+ /* Activate interrupt notifications */
23+ status = HAL_FDCAN_ActivateNotification (can -> hcan , FDCAN_IT_RX_FIFO0_NEW_MESSAGE , 0 );
24+ if (status != HAL_OK )
25+ {
26+ printf ("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ActivateNotification() (Status: %d).\n" , status );
27+ return status ;
28+ }
29+
30+ /* Start FDCAN */
31+ status = HAL_FDCAN_Start (can -> hcan );
32+ if (status != HAL_OK )
33+ {
34+ printf ("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_Start() (Status: %d).\n" , status );
35+ return status ;
36+ }
37+
38+ return status ;
39+ }
40+
41+ /* Adds Standard CAN ID(s) to the CAN filter. */
42+ HAL_StatusTypeDef can_add_filter_standard (can_t * can , uint16_t can_ids [2 ])
43+ {
44+ FDCAN_FilterTypeDef filter ;
45+
46+ /* Config the filter */
47+ filter .IdType = FDCAN_STANDARD_ID ;
48+ filter .FilterIndex = can -> standard_filter_index ;
49+ filter .FilterType = FDCAN_FILTER_DUAL ;
50+ filter .FilterConfig = FDCAN_FILTER_TO_RXFIFO0 ;
51+ filter .FilterID1 = can_ids [0 ];
52+ filter .FilterID2 = can_ids [1 ];
53+
54+ /* Send HAL the config, and check if it was sucessful */
55+ HAL_StatusTypeDef status = HAL_FDCAN_ConfigFilter (can -> hcan , & filter );
56+ if (status != HAL_OK )
57+ {
58+ printf ("[fdcan.c/can_add_filter_standard()] ERROR: Failed to config standard FDCAN filter (Status: %d, Filter Index: %d).\n" , status , filter .FilterIndex );
59+ return status ;
60+ }
61+
62+ /* If successful, increment the standard filter index */
63+ can -> standard_filter_index ++ ;
64+ return status ;
65+ }
66+
67+ /* Adds Extended CAN ID(s) to the CAN filter. */
68+ HAL_StatusTypeDef can_add_filter_extended (can_t * can , uint32_t can_ids [2 ])
69+ {
70+ FDCAN_FilterTypeDef filter ;
71+
72+ /* Config the filter */
73+ filter .IdType = FDCAN_EXTENDED_ID ;
74+ filter .FilterIndex = can -> extended_filter_index ;
75+ filter .FilterType = FDCAN_FILTER_DUAL ;
76+ filter .FilterConfig = FDCAN_FILTER_TO_RXFIFO0 ;
77+ filter .FilterID1 = can_ids [0 ];
78+ filter .FilterID2 = can_ids [1 ];
79+
80+ /* Send HAL the config, and check if it was sucessful */
81+ HAL_StatusTypeDef status = HAL_FDCAN_ConfigFilter (can -> hcan , & filter );
82+ if (status != HAL_OK )
83+ {
84+ printf ("[fdcan.c/can_add_filter_extended()] ERROR: Failed to config extended FDCAN filter (Status: %d, Filter Index: %d). \n" , status , filter .FilterIndex );
85+ return status ;
86+ }
87+
88+ /* If successful, increment the extended filter index */
89+ can -> extended_filter_index ++ ;
90+ return status ;
91+ }
92+
93+ /* Sends a CAN message. */
94+ HAL_StatusTypeDef can_send_msg (can_t * can , can_msg_t * msg )
95+ {
96+ /* Validate message length */
97+ if (msg -> len > 8 )
98+ {
99+ printf ("[fdcan.c/can_send_msg()] ERROR: FDCAN message length exceeds 8 bytes (Length: %d, Message ID: %d).\n" , msg -> len , msg -> id );
100+ return HAL_ERROR ;
101+ }
102+
103+ FDCAN_TxHeaderTypeDef tx_header ;
104+ tx_header .Identifier = msg -> id ;
105+ tx_header .DataLength = msg -> len ;
106+ tx_header .TxFrameType = FDCAN_DATA_FRAME ;
107+ tx_header .ErrorStateIndicator = FDCAN_ESI_ACTIVE ;
108+ tx_header .BitRateSwitch = FDCAN_BRS_OFF ;
109+ tx_header .FDFormat = FDCAN_CLASSIC_CAN ;
110+
111+ /* Check if extended or not extended */
112+ if (msg -> id_is_extended )
113+ tx_header .IdType = FDCAN_EXTENDED_ID ;
114+ else
115+ tx_header .IdType = FDCAN_STANDARD_ID ;
116+
117+ if (HAL_FDCAN_GetTxFifoFreeLevel (can -> hcan ) == 0 )
118+ return HAL_BUSY ;
119+
120+ HAL_StatusTypeDef status = HAL_FDCAN_AddMessageToTxFifoQ (can -> hcan , & tx_header , msg -> data );
121+ if (status != HAL_OK ) {
122+ printf ("[fdcan.c/can_send_msg()] ERROR: HAL_FDCAN_AddMessageToTxFifoQ() failed (Status: %d, Message ID: %d).\n" , status , msg -> id );
123+ return status ;
124+ }
125+
126+ return status ;
127+ }
0 commit comments