Skip to content

Commit 8d4af8d

Browse files
Added FDCAN support for STM32H563 (#302)
1 parent 1bffad7 commit 8d4af8d

3 files changed

Lines changed: 176 additions & 0 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#ifndef FDCAN_H
2+
#define FDCAN_H
3+
4+
// clang-format off
5+
#include <stdbool.h>
6+
#include <stddef.h>
7+
#include <stdint.h>
8+
9+
#include "stm32xx_hal.h"
10+
11+
typedef struct
12+
{
13+
uint32_t id;
14+
uint8_t data[8]; // technically can go to 64 bytes but i cant count that high
15+
bool id_is_extended;
16+
uint8_t len;
17+
} can_msg_t;
18+
19+
typedef struct
20+
{
21+
FDCAN_HandleTypeDef *hcan;
22+
23+
uint32_t standard_filter_index;
24+
uint32_t extended_filter_index;
25+
} can_t;
26+
27+
HAL_StatusTypeDef can_init(can_t *can);
28+
HAL_StatusTypeDef can_send_msg(can_t *can, can_msg_t *msg);
29+
HAL_StatusTypeDef can_add_filter_standard(can_t *can, uint16_t can_ids[2]);
30+
HAL_StatusTypeDef can_add_filter_extended(can_t *can, uint32_t can_ids[2]);
31+
32+
// clang-format on
33+
#endif // FDCAN_H
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef STM32XX_HAL_H
2+
#define STM32XX_HAL_H
3+
4+
#ifdef STM32H745xx
5+
#include "stm32h7xx_hal.h"
6+
#endif
7+
8+
#ifdef STM32G431xx
9+
#include "stm32g4xx_hal.h"
10+
#endif
11+
12+
#ifdef STM32H563xx
13+
#include "stm32h5xx_hal.h"
14+
#endif
15+
16+
#endif /* STM32XX_HAL_H*/

platforms/stm32h563/src/fdcan.c

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
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

Comments
 (0)