Skip to content

Commit e158b11

Browse files
committed
[dma] Support double buffer (only stm32-stream-channel)
1 parent 8f66fcc commit e158b11

File tree

4 files changed

+96
-10
lines changed

4 files changed

+96
-10
lines changed

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

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,18 @@ public:
137137
MemoryIncrementMode memoryIncrement,
138138
PeripheralIncrementMode peripheralIncrement,
139139
Priority priority = Priority::Medium,
140-
CircularMode circularMode = CircularMode::Disabled)
140+
CircularMode circularMode = CircularMode::Disabled
141+
%% if doubleBuffer
142+
,DoubleBufferMode doubleBufferMode = DoubleBufferMode::Disabled
143+
%% endif
144+
)
141145
{
142-
ChannelHal::configure(direction, memoryDataSize, peripheralDataSize,
143-
memoryIncrement, peripheralIncrement, priority, circularMode);
146+
ChannelHal::configure(direction, memoryDataSize, peripheralDataSize, memoryIncrement,
147+
peripheralIncrement, priority, circularMode
148+
%% if doubleBuffer
149+
, doubleBufferMode
150+
%% endif
151+
);
144152
}
145153

146154
/**
@@ -183,6 +191,33 @@ public:
183191
{
184192
ChannelHal::setMemoryAddress(address);
185193
}
194+
195+
%% if doubleBuffer
196+
/**
197+
* Set the secondary memory address of the DMA channel
198+
*
199+
* Only used in double buffer mode
200+
*
201+
* @param[in] address Source address
202+
*/
203+
static void
204+
setMemoryAddress2(uintptr_t address)
205+
{
206+
ChannelHal::setMemoryAddress2(address);
207+
}
208+
209+
/**
210+
* Detect which buffer is currently in use
211+
*
212+
* Only meaningful in double buffer mode
213+
*/
214+
static bool
215+
isPrimaryBufferActive()
216+
{
217+
return ChannelHal::isPrimaryBufferActive();
218+
}
219+
%% endif
220+
186221
/**
187222
* Set the peripheral address of the DMA channel
188223
*

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,15 @@ public:
196196
Enabled = {{ reg_prefix }}_CIRC, ///< circular mode
197197
};
198198

199+
%% if doubleBuffer
200+
enum class
201+
DoubleBufferMode : uint32_t
202+
{
203+
Disabled = 0,
204+
Enabled = {{ reg_prefix }}_DBM, ///< double buffer mode
205+
};
206+
%% endif
207+
199208
enum class
200209
DataTransferDirection : uint32_t
201210
{

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

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -181,20 +181,29 @@ public:
181181
* @param[in] circularMode Transfer data in circular mode?
182182
*/
183183
static void
184-
configure(DataTransferDirection direction, MemoryDataSize memoryDataSize,
185-
PeripheralDataSize peripheralDataSize,
186-
MemoryIncrementMode memoryIncrement,
187-
PeripheralIncrementMode peripheralIncrement,
188-
Priority priority = Priority::Medium,
189-
CircularMode circularMode = CircularMode::Disabled)
184+
configure(DataTransferDirection direction,
185+
MemoryDataSize memoryDataSize,
186+
PeripheralDataSize peripheralDataSize,
187+
MemoryIncrementMode memoryIncrement,
188+
PeripheralIncrementMode peripheralIncrement,
189+
Priority priority = Priority::Medium,
190+
CircularMode circularMode = CircularMode::Disabled
191+
%% if doubleBuffer
192+
, DoubleBufferMode doubleBufferMode = DoubleBufferMode::Disabled
193+
%% endif
194+
)
190195
{
191196
stop();
192197

193198
DMA_Channel_TypeDef *Base = (DMA_Channel_TypeDef *) CHANNEL_BASE;
194199
Base->{{ cr }} = uint32_t(direction) | uint32_t(memoryDataSize) |
195200
uint32_t(peripheralDataSize) | uint32_t(memoryIncrement) |
196201
uint32_t(peripheralIncrement) | uint32_t(priority) |
197-
uint32_t(circularMode);
202+
uint32_t(circularMode)
203+
%% if doubleBuffer
204+
| uint32_t(doubleBufferMode)
205+
%% endif
206+
;
198207
}
199208

200209
/**
@@ -236,6 +245,38 @@ public:
236245
%% endif
237246
}
238247

248+
%% if doubleBuffer
249+
/**
250+
* Set the secondary memory address of the DMA channel
251+
*
252+
* Only used in double buffer mode
253+
*
254+
* @param[in] address Source address
255+
*/
256+
static void
257+
setMemoryAddress2(uintptr_t address)
258+
{
259+
DMA_Channel_TypeDef *Base = (DMA_Channel_TypeDef *) CHANNEL_BASE;
260+
%% if dmaType in ["stm32-stream-channel"]
261+
Base->M1AR = address;
262+
%% endif
263+
}
264+
265+
/**
266+
* Detect which buffer is currently in use
267+
*
268+
* Only meaningful in double buffer mode
269+
*/
270+
static bool
271+
isPrimaryBufferActive()
272+
{
273+
DMA_Channel_TypeDef *Base = (DMA_Channel_TypeDef *) CHANNEL_BASE;
274+
%% if dmaType in ["stm32-stream-channel"]
275+
return (Base->CR & DMA_SxCR_CT);
276+
%% endif
277+
}
278+
%% endif
279+
239280
/**
240281
* Set the peripheral address of the DMA channel
241282
*

src/modm/platform/dma/stm32/module.lb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ def build(env):
186186
properties["dmaType"] = dma["type"]
187187
properties["dmaSignals"] = signal_names
188188
properties["dmaController"] = controller
189+
properties["doubleBuffer"] = (dma["type"] in ["stm32-stream-channel"]) ## TODO: which other types support double buffer mode?
189190

190191
properties['channel_count'] = {
191192
"min" : min(controller, key=lambda c: c["min_channel"])["min_channel"],

0 commit comments

Comments
 (0)