Skip to content

Commit ce9c654

Browse files
committed
[stm32] Add FDCAN support for H7 series
The H7 series supports a user-configured message RAM layout, rather than the static layout of past STM32 CAN IPs. The new message RAM is identical in structure and configurability to the ATSAM FDCAN IP. This commit merges the STM32 FDCAN and ATSAM FDCAN message RAM implementations. For H7 it also introduces lbuild parameters so the user can choose the amount of space available for each RX queue, each TX queue, and filters. This is independent for each FDCAN IP instance, although they share the same 10k RAM.
1 parent 5ae26dd commit ce9c654

File tree

20 files changed

+610
-513
lines changed

20 files changed

+610
-513
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
166166
<td align="center">✅</td>
167167
<td align="center">✅</td>
168168
<td align="center">✅</td>
169-
<td align="center"></td>
169+
<td align="center"></td>
170170
<td align="center">✕</td>
171171
<td align="center">✕</td>
172172
<td align="center">✅</td>

examples/nucleo_h723zg/can/main.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Copyright (c) 2020, Raphael Lehmann
3+
*
4+
* This file is part of the modm project.
5+
*
6+
* This Source Code Form is subject to the terms of the Mozilla Public
7+
* License, v. 2.0. If a copy of the MPL was not distributed with this
8+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
11+
#include <modm/board.hpp>
12+
#include <modm/debug/logger.hpp>
13+
#include <modm/board.hpp>
14+
15+
using namespace modm::literals;
16+
17+
// Set the log level
18+
#undef MODM_LOG_LEVEL
19+
#define MODM_LOG_LEVEL modm::log::INFO
20+
21+
int
22+
main()
23+
{
24+
Board::initialize();
25+
26+
MODM_LOG_INFO << "CAN Test Program" << modm::endl;
27+
28+
MODM_LOG_INFO << "Initializing Fdcan1..." << modm::endl;
29+
// Initialize Fdcan1
30+
Fdcan1::connect<GpioA11::Rx, GpioA12::Tx>(Gpio::InputType::PullUp);
31+
Fdcan1::initialize<Board::SystemClock, 125_kbps, 1_pct, 500_kbps>(9);
32+
33+
MODM_LOG_INFO << "Setting up Filter for Fdcan1..." << modm::endl;
34+
// Receive every extended id message
35+
Fdcan1::setExtendedFilter(0, Fdcan1::FilterConfig::Fifo0,
36+
modm::can::ExtendedIdentifier(0),
37+
modm::can::ExtendedMask(0));
38+
39+
MODM_LOG_INFO << "Initializing Fdcan2..." << modm::endl;
40+
// Initialize Fdcan2
41+
Fdcan2::connect<GpioB5::Rx, GpioB6::Tx>(Gpio::InputType::PullUp);
42+
Fdcan2::initialize<Board::SystemClock, 125_kbps, 1_pct, 500_kbps>(12);
43+
44+
MODM_LOG_INFO << "Setting up Filter for Fdcan2..." << modm::endl;
45+
// Receive every message
46+
Fdcan2::setExtendedFilter(0, Fdcan2::FilterConfig::Fifo0,
47+
modm::can::ExtendedIdentifier(0),
48+
modm::can::ExtendedMask(0));
49+
50+
// Send a message
51+
MODM_LOG_INFO << "Sending message on Fdcan1..." << modm::endl;
52+
modm::can::Message msg1(1, 1);
53+
msg1.setExtended(true);
54+
msg1.data[0] = 0x11;
55+
Fdcan1::sendMessage(msg1);
56+
57+
// Send a message
58+
MODM_LOG_INFO << "Sending message on Fdcan2..." << modm::endl;
59+
msg1.data[0] = 0x22;
60+
Fdcan2::sendMessage(msg1);
61+
62+
63+
while (true)
64+
{
65+
if (Fdcan1::isMessageAvailable())
66+
{
67+
MODM_LOG_INFO << "Fdcan1: Message is available..." << modm::endl;
68+
modm::can::Message message;
69+
Fdcan1::getMessage(message);
70+
MODM_LOG_INFO << message << modm::endl;
71+
}
72+
if (Fdcan2::isMessageAvailable())
73+
{
74+
MODM_LOG_INFO << "Fdcan2: Message is available..." << modm::endl;
75+
modm::can::Message message;
76+
Fdcan2::getMessage(message);
77+
MODM_LOG_INFO << message << modm::endl;
78+
}
79+
}
80+
81+
return 0;
82+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<library>
2+
<extends>modm:nucleo-h723zg</extends>
3+
<options>
4+
<option name="modm:build:build.path">../../../build/nucleo_h723zg/can</option>
5+
</options>
6+
<modules>
7+
<module>modm:debug</module>
8+
<module>modm:platform:can:1</module>
9+
<module>modm:platform:can:2</module>
10+
<module>modm:platform:can:3</module>
11+
<module>modm:build:scons</module>
12+
</modules>
13+
</library>

src/modm/board/nucleo_h723zg/board.hpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@ using namespace modm::literals;
3030
/// STM32H723ZG running at 550MHz from PLL clock generated from 8 MHz HSE
3131
struct SystemClock
3232
{
33+
static constexpr uint32_t Hse = 8_MHz;
34+
3335
// Max 550MHz
3436
static constexpr uint32_t SysClk = 550_MHz;
3537
static constexpr uint32_t Pll1Q = SysClk / 4;
38+
static constexpr uint32_t Pll2Q = 120_MHz;
3639
// Max 550MHz
3740
static constexpr uint32_t Hclk = SysClk / 1; // D1CPRE
3841
static constexpr uint32_t Frequency = Hclk;
@@ -74,8 +77,9 @@ struct SystemClock
7477

7578
static constexpr uint32_t LpUart1 = Apb4;
7679

77-
static constexpr uint32_t Can1 = Apb1;
78-
static constexpr uint32_t Can2 = Apb1;
80+
static constexpr uint32_t Fdcan1 = Pll2Q;
81+
static constexpr uint32_t Fdcan2 = Pll2Q;
82+
static constexpr uint32_t Fdcan3 = Pll2Q;
7983

8084
static constexpr uint32_t I2c1 = Apb1;
8185
static constexpr uint32_t I2c2 = Apb1;
@@ -122,6 +126,19 @@ struct SystemClock
122126
.pllR = 2, // 550 MHz / 2 = 275 MHz
123127
};
124128
Rcc::enablePll1(Rcc::PllSource::Hse, pllFactors1);
129+
130+
// Use PLL2 for FDCAN 120MHz
131+
const Rcc::PllFactors pllFactors2{
132+
.range = Rcc::PllInputRange::MHz1_2,
133+
.pllM = 4, // 8MHz / M= 2MHz
134+
.pllN = 120, // 2MHz * N= 240MHz
135+
.pllP = 2, // 240MHz / P= 120MHz
136+
.pllQ = 2, // 240MHz / Q= 120MHz
137+
.pllR = 2, // 240MHz / R= 120MHz
138+
};
139+
Rcc::enablePll2(Rcc::PllSource::ExternalClock, pllFactors2);
140+
Rcc::setCanClockSource(Rcc::CanClockSource::Pll2Q);
141+
125142
// Use PLL3 for USB 48MHz
126143
const Rcc::PllFactors pllFactors3{
127144
.range = Rcc::PllInputRange::MHz4_8,

src/modm/board/nucleo_h743zi/board.hpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ using namespace modm::literals;
2929
/// STM32H743 running at 400MHz from the external 8MHz HSE
3030
struct SystemClock
3131
{
32+
static constexpr uint32_t Hse = 8_MHz;
33+
3234
// NOTE: revision Y at 400MHz, only revision V runs at 480Mhz!!!
3335
static constexpr uint32_t SysClk = 400_MHz;
36+
static constexpr uint32_t Pll2Q = 120_MHz;
3437
// Max 400MHz or 480MHz
3538
static constexpr uint32_t Hclk = SysClk / 1; // D1CPRE
3639
static constexpr uint32_t Frequency = Hclk;
@@ -70,8 +73,8 @@ struct SystemClock
7073

7174
static constexpr uint32_t LpUart1 = Apb4;
7275

73-
static constexpr uint32_t Can1 = Apb1;
74-
static constexpr uint32_t Can2 = Apb1;
76+
static constexpr uint32_t Fdcan1 = Pll2Q;
77+
static constexpr uint32_t Fdcan2 = Pll2Q;
7578

7679
static constexpr uint32_t I2c1 = Apb1;
7780
static constexpr uint32_t I2c2 = Apb1;
@@ -112,6 +115,19 @@ struct SystemClock
112115
.pllR = 10, // 400MHz / R= 40MHz
113116
};
114117
Rcc::enablePll1(Rcc::PllSource::ExternalClock, pllFactors1);
118+
119+
// Use PLL2 for FDCAN 120MHz
120+
const Rcc::PllFactors pllFactors2{
121+
.range = Rcc::PllInputRange::MHz1_2,
122+
.pllM = 4, // 8MHz / M= 2MHz
123+
.pllN = 120, // 2MHz * N= 240MHz
124+
.pllP = 2, // 240MHz / P= 120MHz
125+
.pllQ = 2, // 240MHz / Q= 120MHz
126+
.pllR = 2, // 240MHz / R= 120MHz
127+
};
128+
Rcc::enablePll2(Rcc::PllSource::ExternalClock, pllFactors2);
129+
Rcc::setCanClockSource(Rcc::CanClockSource::Pll2Q);
130+
115131
// Use PLL3 for USB 48MHz
116132
const Rcc::PllFactors pllFactors3{
117133
.range = Rcc::PllInputRange::MHz4_8,

0 commit comments

Comments
 (0)