Skip to content

Commit 32f426a

Browse files
committed
[dma] Adapt STM32 implementation for F4 and F7 series
1 parent 47a97dc commit 32f426a

File tree

8 files changed

+261
-87
lines changed

8 files changed

+261
-87
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,8 @@ Please [discover modm's peripheral drivers for your specific device][discover].
208208
<td align="center">✅</td>
209209
<td align="center">○</td>
210210
<td align="center">✅</td>
211-
<td align="center"></td>
212-
<td align="center"></td>
211+
<td align="center"></td>
212+
<td align="center"></td>
213213
<td align="center">✅</td>
214214
<td align="center">✅</td>
215215
<td align="center">○</td>

examples/nucleo_g474re/dac_dma/main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ void setupDac4()
7979
});
8080

8181
Dma1::Channel1::enableInterruptVector();
82-
Dma1::Channel1::enableInterrupt(Dma1::Interrupt::TransferComplete | Dma1::Interrupt::Error);
82+
Dma1::Channel1::enableInterrupt(Dma1::InterruptEnable::TransferComplete |
83+
Dma1::InterruptEnable::TransferError);
8384

8485
// DAC4 channel 1 output via opamp 4 in follower mode connected to output B12
8586
GpioOutputB12::setAnalogInput();

src/modm/platform/dma/stm32/dma.hpp.in

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,10 @@ public:
143143
static void
144144
start()
145145
{
146-
ControlHal::clearInterruptFlags(uint32_t(Interrupt::Global) << (uint32_t(ChannelID) * 4));
146+
ControlHal::clearInterruptFlags(InterruptFlags::All, ChannelID);
147147
ChannelHal::start();
148148
}
149+
149150
/**
150151
* Stop a DMA channel transfer
151152
*/
@@ -271,6 +272,9 @@ public:
271272

272273
auto* channel = DMAMUX1_Channel0 + muxChannel;
273274
channel->CCR = (channel->CCR & DMAMUX_CxCR_DMAREQ_ID) | uint32_t(dmaRequest);
275+
%% elif dmaType in ["stm32-stream-channel"]
276+
DMA_Channel_TypeDef *Channel = reinterpret_cast<DMA_Channel_TypeDef*>(CHANNEL_BASE);
277+
Channel->CR = (Channel->CR & ~DMA_SxCR_CHSEL_Msk) | uint32_t(dmaRequest);
274278
%% else
275279
// Nothing to see here. This controller has no request mux, instead
276280
// all requests are or-ed together.
@@ -286,12 +290,22 @@ public:
286290
static void
287291
interruptHandler()
288292
{
293+
%% if dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]
289294
static const uint32_t TC_Flag {
290-
uint32_t(Interrupt::TransferComplete) << (uint32_t(ChannelID) * 4)
295+
uint32_t(InterruptFlags::TransferComplete) << (uint32_t(ChannelID) * 4)
291296
};
292297
static const uint32_t TE_Flag {
293-
uint32_t(Interrupt::Error) << (uint32_t(ChannelID) * 4)
298+
uint32_t(InterruptFlags::Error) << (uint32_t(ChannelID) * 4)
299+
};
300+
%% elif dmaType in ["stm32-stream-channel"]
301+
constexpr uint8_t offsetLut[8] = {0, 6, 16, 22, 0+32, 6+32, 16+32, 22+32};
302+
static const uint64_t TC_Flag {
303+
uint64_t(InterruptFlags::TransferComplete) << offsetLut[uint32_t(ChannelID)]
294304
};
305+
static const uint64_t TE_Flag {
306+
uint64_t(InterruptFlags::Error) << offsetLut[uint32_t(ChannelID)]
307+
};
308+
%% endif
295309

296310
auto isr { ControlHal::getInterruptFlags() };
297311
if (isr & TE_Flag) {
@@ -302,7 +316,7 @@ public:
302316
if ((isr & TC_Flag) and transferComplete)
303317
transferComplete();
304318

305-
ControlHal::clearInterruptFlags(uint32_t(Interrupt::Global) << (uint32_t(ChannelID) * 4));
319+
ControlHal::clearInterruptFlags(InterruptFlags::Global, ChannelID);
306320
}
307321

308322
/**
@@ -329,15 +343,15 @@ public:
329343
* Enable the specified interrupt of the channel
330344
*/
331345
static void
332-
enableInterrupt(Interrupt_t irq)
346+
enableInterrupt(InterruptEnable_t irq)
333347
{
334348
ChannelHal::enableInterrupt(irq);
335349
}
336350
/**
337351
* Disable the specified interrupt of the channel
338352
*/
339353
static void
340-
disableInterrupt(Interrupt_t irq)
354+
disableInterrupt(InterruptEnable_t irq)
341355
{
342356
ChannelHal::disableInterrupt(irq);
343357
}
@@ -391,7 +405,7 @@ public:
391405
};
392406

393407
%% endfor
394-
%% else
408+
%% elif dmaType in ["stm32-channel-request", "stm32-channel"]
395409
%% for channels in dma["channels"]
396410
class Dma{{ channels.instance }}: public DmaController<{{ channels.instance }}>
397411
{
@@ -401,6 +415,16 @@ public:
401415
%% endfor
402416
};
403417
%% endfor
418+
%% elif dmaType in ["stm32-stream-channel"]
419+
%% for streams in dma["streams"]
420+
class Dma{{ streams.instance }}: public DmaController<{{ streams.instance }}>
421+
{
422+
public:
423+
%% for stream in streams.stream
424+
using Channel{{ stream.position }} = DmaController<{{ streams.instance }}>::Channel<DmaBase::Channel::Channel{{ stream.position }}>;
425+
%% endfor
426+
};
427+
%% endfor
404428
%% endif
405429

406430
/*
@@ -477,7 +501,7 @@ namespace dma
477501
%% endfor
478502

479503
}
480-
%% else
504+
%% elif dmaType in ["stm32-channel"]
481505
%% for channels in dma["channels"]
482506
%% for channel in channels.channel
483507
%% for signal in channel.signal
@@ -502,6 +526,29 @@ struct DmaController<{{ channels.instance }}>::Channel<DmaBase::Channel::Channel
502526
%% endfor
503527
%% endfor
504528

529+
%% elif dmaType in ["stm32-stream-channel"]
530+
%% for channels in dma["streams"]
531+
%% for channel in channels.stream
532+
%% for request in channel.channel
533+
%% for signal in request.signal
534+
%% set peripheral = signal.driver.capitalize()
535+
%% if signal.instance is defined and peripheral not in ["Dac"]
536+
%% set peripheral = peripheral ~ signal.instance
537+
%% endif
538+
template <>
539+
template <>
540+
template <>
541+
struct DmaController<{{ channels.instance }}>::Channel<DmaBase::Channel::Channel{{ channel.position }}>::RequestMapping<Peripheral::{{ peripheral }}{% if signal.name is defined %}, DmaBase::Signal::{{ signal.name.capitalize() }}{% endif %}>
542+
{
543+
using Channel = DmaController<{{ channels.instance }}>::Channel<DmaBase::Channel::Channel{{ channel.position }}>;
544+
static constexpr DmaBase::Request Request = DmaBase::Request::Channel{{ request.position }};
545+
};
546+
547+
%% endfor
548+
%% endfor
549+
%% endfor
550+
%% endfor
551+
505552
%%endif
506553
} // namespace platform
507554

src/modm/platform/dma/stm32/dma_base.hpp.in

Lines changed: 82 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include <modm/architecture/interface/interrupt.hpp>
2626
#include <modm/architecture/interface/register.hpp>
2727

28-
%% if target["family"] == "f4"
28+
%% if dmaType in ["stm32-stream-channel"]
2929
%% set reg_prefix = "DMA_SxCR"
3030
%% elif dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]
3131
%% set reg_prefix = "DMA_CCR"
@@ -47,44 +47,47 @@ class DmaBase
4747
{
4848
public:
4949
// Enums
50-
%% if target["family"] == "f4"
50+
%% if dmaType in ["stm32-stream-channel"]
5151
enum class
52-
Channel : uint32_t
52+
Channel
5353
{
54-
Channel0 = 0,
55-
Channel1 = DMA_SxCR_CHSEL_0,
56-
Channel2 = DMA_SxCR_CHSEL_1,
57-
Channel3 = DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_0,
58-
Channel4 = DMA_SxCR_CHSEL_2,
59-
Channel5 = DMA_SxCR_CHSEL_2 | DMA_SxCR_CHSEL_0,
60-
Channel6 = DMA_SxCR_CHSEL_2 | DMA_SxCR_CHSEL_1,
61-
Channel7 = DMA_SxCR_CHSEL_2 | DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_0,
54+
Stream0 = 0,
55+
Stream1,
56+
Stream2,
57+
Stream3,
58+
Stream4,
59+
Stream5,
60+
Stream6,
61+
Stream7,
62+
Channel0 = Stream0,
63+
Channel1 = Stream1,
64+
Channel2 = Stream2,
65+
Channel3 = Stream3,
66+
Channel4 = Stream4,
67+
Channel5 = Stream5,
68+
Channel6 = Stream6,
69+
Channel7 = Stream7,
6270
};
6371

64-
enum class
65-
MemoryBurstTransfer : uint32_t
66-
{
67-
Single = 0,
68-
Increment4 = DMA_SxCR_MBURST_0,
69-
Increment8 = DMA_SxCR_MBURST_1,
70-
Increment16 = DMA_SxCR_MBURST_1 | DMA_SxCR_MBURST_0,
71-
};
72+
%% set request_count = namespace(max_requests = 0)
73+
%% for streams in dma["channels"]
74+
%% for stream in streams.stream
75+
%% for channel in stream.channel
76+
%% if request_count.max_requests < channel.position | int
77+
%% set request_count.max_requests = channel.position | int
78+
%% endif
79+
%% endfor
80+
%% endfor
81+
%% endfor
7282

7383
enum class
74-
PeripheralBurstTransfer : uint32_t
84+
Request : uint32_t
7585
{
76-
Single = 0,
77-
Increment4 = DMA_SxCR_PBURST_0,
78-
Increment8 = DMA_SxCR_PBURST_1,
79-
Increment16 = DMA_SxCR_PBURST_1 | DMA_SxCR_PBURST_0,
86+
%% for i in range(0, request_count.max_requests + 1)
87+
Channel{{ i }} = ({{ i }} << DMA_SxCR_CHSEL_Pos),
88+
%% endfor
8089
};
8190

82-
enum class
83-
FlowControl : uint32_t
84-
{
85-
Dma = 0,
86-
Peripheral = DMA_SxCR_PFCTRL, ///< the peripheral is the flow controller
87-
};
8891
%% elif dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]
8992
enum class
9093
Channel
@@ -189,7 +192,7 @@ public:
189192
enum class
190193
DataTransferDirection : uint32_t
191194
{
192-
%% if target["family"] == "f4"
195+
%% if dmaType in ["stm32-stream-channel"]
193196
/// Source: DMA_SxPAR; Sink: DMA_SxM0AR
194197
PeripheralToMemory = 0,
195198
/// Source: DMA_SxM0AR; Sink: DMA_SxPAR
@@ -217,34 +220,62 @@ public:
217220
%% endfor
218221
};
219222

220-
enum class Interrupt {
221-
Global = 0x01,
222-
TransferComplete = 0x02,
223-
HalfTransferComplete = 0x04,
224-
Error = 0x08,
225-
All = 0x0f,
223+
%% if dmaType in ["stm32-stream-channel"]
224+
enum class InterruptEnable {
225+
DirectModeError = DMA_SxCR_DMEIE,
226+
TransferError = DMA_SxCR_TEIE,
227+
HalfTransfer = DMA_SxCR_HTIE,
228+
TransferComplete = DMA_SxCR_TCIE,
229+
};
230+
MODM_FLAGS32(InterruptEnable);
231+
232+
enum class InterruptFlags {
233+
FifoError = 0b00'0001,
234+
DirectModeError = 0b00'0100,
235+
Error = 0b00'1000,
236+
HalfTransferComplete = 0b01'0000,
237+
TransferComplete = 0b10'0000,
238+
All = 0b11'1101,
239+
Global = All,
226240
};
227-
MODM_FLAGS32(Interrupt);
241+
MODM_FLAGS32(InterruptFlags);
242+
%% elif dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]
243+
enum class InterruptEnable {
244+
TransferComplete = DMA_CCR_TCIE,
245+
HalfTransfer = DMA_CCR_HTIE,
246+
TransferError = DMA_CCR_TEIE,
247+
};
248+
MODM_FLAGS32(InterruptEnable);
249+
250+
enum class InterruptFlags {
251+
Global = 0b0001,
252+
TransferComplete = 0b0010,
253+
HalfTransferComplete = 0b0100,
254+
Error = 0b1000,
255+
All = 0b1111,
256+
};
257+
MODM_FLAGS32(InterruptFlags);
258+
%% endif
228259

229260
using IrqHandler = void (*)(void);
230261

231262
protected:
232-
%% if target["family"] == "f4"
263+
%% if dmaType in ["stm32-stream-channel"]
233264
static constexpr uint32_t memoryMask =
234-
DMA_SxCR_MBURST_1 | DMA_SxCR_MBURST_0 | // MemoryBurstTransfer
235-
DMA_SxCR_MSIZE_0 | DMA_SxCR_MSIZE_1 | // MemoryDataSize
236-
DMA_SxCR_MINC | // MemoryIncrementMode
237-
DMA_SxCR_DIR_0 | DMA_SxCR_DIR_1; // DataTransferDirection
265+
DMA_SxCR_MBURST_Msk | // MemoryBurstTransfer
266+
DMA_SxCR_MSIZE_Msk | // MemoryDataSize
267+
DMA_SxCR_MINC | // MemoryIncrementMode
268+
DMA_SxCR_DIR_Msk; // DataTransferDirection
238269
static constexpr uint32_t peripheralMask =
239-
DMA_SxCR_PBURST_1 | DMA_SxCR_PBURST_0 | // PeripheralBurstTransfer
240-
DMA_SxCR_PSIZE_0 | DMA_SxCR_PSIZE_1 | // PeripheralDataSize
241-
DMA_SxCR_PINC | // PeripheralIncrementMode
242-
DMA_SxCR_DIR_0 | DMA_SxCR_DIR_1; // DataTransferDirection
270+
DMA_SxCR_PBURST_Msk | // PeripheralBurstTransfer
271+
DMA_SxCR_PSIZE_Msk | // PeripheralDataSize
272+
DMA_SxCR_PINC_Msk | // PeripheralIncrementMode
273+
DMA_SxCR_DIR_Msk; // DataTransferDirection
243274
static constexpr uint32_t configmask =
244-
DMA_SxCR_CHSEL_2 | DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_0 | // Channel
245-
DMA_SxCR_PL_1 | DMA_SxCR_PL_0 | // Priority
246-
DMA_SxCR_CIRC | // CircularMode
247-
DMA_SxCR_PFCTRL; // FlowControl
275+
DMA_SxCR_CHSEL_Msk | // Channel
276+
DMA_SxCR_PL_Msk | // Priority
277+
DMA_SxCR_CIRC_Msk | // CircularMode
278+
DMA_SxCR_PFCTRL_Msk; // FlowControl
248279
%% elif dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]
249280
static constexpr uint32_t memoryMask =
250281
DMA_CCR_MSIZE_0 | DMA_CCR_MSIZE_1 | // MemoryDataSize

0 commit comments

Comments
 (0)