diff --git a/README.md b/README.md
index 899e26f1ee..e703ccb556 100644
--- a/README.md
+++ b/README.md
@@ -78,9 +78,9 @@ git clone --recurse-submodules --jobs 8 https://github.com/modm-io/modm.git
## Microcontrollers
-modm can create a HAL for 3195 devices of these vendors:
+modm can create a HAL for 3256 devices of these vendors:
-- STMicroelectronics STM32: 2621 devices.
+- STMicroelectronics STM32: 2682 devices.
- Microchip SAM: 186 devices.
- Microchip AVR: 388 devices.
@@ -206,13 +206,13 @@ Please [discover modm's peripheral drivers for your specific device][discover].
DMA
✅
✅
-
○
✅
✅
✅
✅
✅
-
○
+
✅
+
✅
✅
✅
✅
diff --git a/examples/nucleo_f446ze/dac_dma/main.cpp b/examples/nucleo_f446ze/dac_dma/main.cpp
new file mode 100644
index 0000000000..14ba626da6
--- /dev/null
+++ b/examples/nucleo_f446ze/dac_dma/main.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2021, Christopher Durand
+ *
+ * This file is part of the modm project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include
+
+#include
+#include
+#include
+
+using namespace Board;
+
+constexpr auto computeSinTable(float frequency = 1.f)
+{
+ std::array data{};
+ constexpr auto HalfOutput = ((1 << 12) - 1) / 2; // 12 bit dac
+ for (size_t i = 0; i < data.size(); ++i) {
+ constexpr auto pi = std::numbers::pi_v;
+ data[i] = HalfOutput * (1 + sin(i * (2 * pi * frequency / data.size())));
+ }
+ return data;
+}
+
+constexpr auto sinTable = computeSinTable(1.0f);
+
+// DAC1 channel 1 on GpioA4: constantly output sine signal in circular mode
+
+void setupDac()
+{
+ using Dac = DacDma;
+ using DacChannel = Dac::Channel1;
+
+ Dac::connect();
+ Dac::initialize();
+
+ DacChannel::configure(sinTable.data(), sinTable.size(), DmaBase::CircularMode::Enabled);
+
+ // trigger source 5: timer 4, see reference manual
+ DacChannel::setTriggerSource(5);
+
+ DacChannel::startDma();
+ DacChannel::enableDacChannel();
+}
+
+int main()
+{
+ Board::initialize();
+ LedGreen::setOutput();
+
+ MODM_LOG_INFO << "DAC DMA Demo" << modm::endl;
+
+ Dma1::enable();
+ setupDac();
+
+ // configure timer 4 as trigger for DACs
+ // 90 MHz / 90 = 1 MHz => 1 Msps DAC output
+ Timer4::enable();
+ Timer4::setMode(Timer4::Mode::UpCounter);
+ Timer4::setPrescaler(1);
+ Timer4::setOverflow(90 - 1);
+ Timer4::applyAndReset();
+ Timer4::start();
+
+ // Enable trigger out for timer 4
+ TIM4->CR2 |= TIM_CR2_MMS_1;
+
+ while (true)
+ {
+ LedGreen::toggle();
+ modm::delay_ms(500);
+ }
+
+ return 0;
+}
diff --git a/examples/nucleo_f446ze/dac_dma/project.xml b/examples/nucleo_f446ze/dac_dma/project.xml
new file mode 100644
index 0000000000..832c27fe72
--- /dev/null
+++ b/examples/nucleo_f446ze/dac_dma/project.xml
@@ -0,0 +1,13 @@
+
+ modm:nucleo-f446ze
+
+
+
+
+ modm:debug
+ modm:platform:dac
+ modm:platform:dma
+ modm:platform:timer:4
+ modm:build:scons
+
+
diff --git a/examples/nucleo_h723zg/dac_dma/main.cpp b/examples/nucleo_h723zg/dac_dma/main.cpp
new file mode 100644
index 0000000000..5dcf3ca72b
--- /dev/null
+++ b/examples/nucleo_h723zg/dac_dma/main.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2021, Christopher Durand
+ *
+ * This file is part of the modm project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include
+
+#include
+#include
+#include
+
+using namespace Board;
+
+constexpr auto computeSinTable(float frequency = 1.f)
+{
+ std::array data{};
+ constexpr auto HalfOutput = ((1 << 12) - 1) / 2; // 12 bit dac
+ for (size_t i = 0; i < data.size(); ++i) {
+ constexpr auto pi = std::numbers::pi_v;
+ data[i] = HalfOutput * (1 + sin(i * (2 * pi * frequency / data.size())));
+ }
+ return data;
+}
+
+constexpr auto sinTable = computeSinTable(1.0f);
+
+// DAC1 channel 1 on GpioA4: constantly output sine signal in circular mode
+
+void setupDac()
+{
+ using Dac = Dac1Dma;
+ using DacChannel = Dac::Channel1;
+
+ Dac::connect();
+ Dac::initialize();
+
+ DacChannel::configure(sinTable.data(), sinTable.size(), DmaBase::CircularMode::Enabled);
+
+ // trigger source 3: timer 4, see reference manual
+ DacChannel::setTriggerSource(3);
+
+ DacChannel::startDma();
+ DacChannel::enableDacChannel();
+}
+
+int main()
+{
+ Board::initialize();
+ LedGreen::setOutput();
+
+ MODM_LOG_INFO << "DAC DMA Demo" << modm::endl;
+
+ Dma1::enable();
+ setupDac();
+
+ // configure timer 4 as trigger for DACs
+ // 275 MHz / 275 = 1 MHz => 1 Msps DAC output
+ Timer4::enable();
+ Timer4::setMode(Timer4::Mode::UpCounter);
+ Timer4::setPrescaler(1);
+ Timer4::setOverflow(275 - 1);
+ Timer4::applyAndReset();
+ Timer4::start();
+
+ // Enable trigger out for timer 4
+ TIM4->CR2 |= TIM_CR2_MMS_1;
+
+ while (true)
+ {
+ LedGreen::toggle();
+ modm::delay_ms(500);
+ }
+
+ return 0;
+}
diff --git a/examples/nucleo_h723zg/dac_dma/project.xml b/examples/nucleo_h723zg/dac_dma/project.xml
new file mode 100644
index 0000000000..047b381dee
--- /dev/null
+++ b/examples/nucleo_h723zg/dac_dma/project.xml
@@ -0,0 +1,13 @@
+
+ modm:nucleo-h723zg
+
+
+
+
+ modm:debug
+ modm:platform:dac:1
+ modm:platform:dma
+ modm:platform:timer:4
+ modm:build:scons
+
+
diff --git a/examples/nucleo_l476rg/dac_dma/main.cpp b/examples/nucleo_l476rg/dac_dma/main.cpp
new file mode 100644
index 0000000000..d5ca2d031f
--- /dev/null
+++ b/examples/nucleo_l476rg/dac_dma/main.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2021, Christopher Durand
+ *
+ * This file is part of the modm project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include
+
+#include
+#include
+#include
+
+using namespace Board;
+
+constexpr auto computeSinTable(float frequency = 1.f)
+{
+ std::array data{};
+ constexpr auto HalfOutput = ((1 << 12) - 1) / 2; // 12 bit dac
+ for (size_t i = 0; i < data.size(); ++i) {
+ constexpr auto pi = std::numbers::pi_v;
+ data[i] = HalfOutput * (1 + sin(i * (2 * pi * frequency / data.size())));
+ }
+ return data;
+}
+
+constexpr auto sinTable = computeSinTable(1.0f);
+
+// DAC1 channel 1 on GpioA4: constantly output sine signal in circular mode
+
+void setupDac()
+{
+ using Dac = Dac1Dma;
+ using DacChannel = Dac::Channel1;
+
+ Dac::connect();
+ Dac::initialize();
+
+ DacChannel::configure(sinTable.data(), sinTable.size(), DmaBase::CircularMode::Enabled);
+
+ // trigger source 5: timer 4, see reference manual
+ DacChannel::setTriggerSource(5);
+
+ DacChannel::startDma();
+ DacChannel::enableDacChannel();
+}
+
+int main()
+{
+ Board::initialize();
+ LedGreen::setOutput();
+
+ MODM_LOG_INFO << "DAC DMA Demo" << modm::endl;
+
+ Dma1::enable();
+ setupDac();
+
+ // configure timer 4 as trigger for DACs
+ // 48 MHz / 48 = 1 MHz => 1 Msps DAC output
+ Timer4::enable();
+ Timer4::setMode(Timer4::Mode::UpCounter);
+ Timer4::setPrescaler(1);
+ Timer4::setOverflow(48 - 1);
+ Timer4::applyAndReset();
+ Timer4::start();
+
+ // Enable trigger out for timer 4
+ TIM4->CR2 |= TIM_CR2_MMS_1;
+
+ while (true)
+ {
+ LedGreen::toggle();
+ modm::delay_ms(500);
+ }
+
+ return 0;
+}
diff --git a/examples/nucleo_l476rg/dac_dma/project.xml b/examples/nucleo_l476rg/dac_dma/project.xml
new file mode 100644
index 0000000000..cbfdfab388
--- /dev/null
+++ b/examples/nucleo_l476rg/dac_dma/project.xml
@@ -0,0 +1,13 @@
+
+ modm:nucleo-l476rg
+
+
+
+
+ modm:debug
+ modm:platform:dac:1
+ modm:platform:dma
+ modm:platform:timer:4
+ modm:build:scons
+
+
diff --git a/examples/stm32f769i_discovery/dac_dma/main.cpp b/examples/stm32f769i_discovery/dac_dma/main.cpp
new file mode 100644
index 0000000000..597d85fd0c
--- /dev/null
+++ b/examples/stm32f769i_discovery/dac_dma/main.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2021, Christopher Durand
+ *
+ * This file is part of the modm project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include
+
+#include
+#include
+#include
+
+using namespace Board;
+
+constexpr auto computeSinTable(float frequency = 1.f)
+{
+ std::array data{};
+ constexpr auto HalfOutput = ((1 << 12) - 1) / 2; // 12 bit dac
+ for (size_t i = 0; i < data.size(); ++i) {
+ constexpr auto pi = std::numbers::pi_v;
+ data[i] = HalfOutput * (1 + sin(i * (2 * pi * frequency / data.size())));
+ }
+ return data;
+}
+
+constexpr auto sinTable = computeSinTable(1.0f);
+
+// DAC1 channel 1 on GpioA4: constantly output sine signal in circular mode
+
+void setupDac()
+{
+ using Dac = DacDma;
+ using DacChannel = Dac::Channel1;
+
+ Dac::connect();
+ Dac::initialize();
+
+ DacChannel::configure(sinTable.data(), sinTable.size(), DmaBase::CircularMode::Enabled);
+
+ // trigger source 5: timer 4, see reference manual
+ DacChannel::setTriggerSource(5);
+
+ DacChannel::startDma();
+ DacChannel::enableDacChannel();
+}
+
+int main()
+{
+ Board::initialize();
+ LedJ5::setOutput();
+ LedJ13::setOutput(true);
+
+ MODM_LOG_INFO << "DAC DMA Demo" << modm::endl;
+
+ Dma1::enable();
+ setupDac();
+
+ // configure timer 4 as trigger for DACs
+ // 108 MHz / 108 = 1 MHz => 1 Msps DAC output
+ Timer4::enable();
+ Timer4::setMode(Timer4::Mode::UpCounter);
+ Timer4::setPrescaler(1);
+ Timer4::setOverflow(108 - 1);
+ Timer4::applyAndReset();
+ Timer4::start();
+
+ // Enable trigger out for timer 4
+ TIM4->CR2 |= TIM_CR2_MMS_1;
+
+ //GpioOutputA4::setOutput(true);
+ while (true)
+ {
+ LedJ5::toggle();
+ LedJ13::toggle();
+ modm::delay_ms(500);
+ }
+
+ return 0;
+}
diff --git a/examples/stm32f769i_discovery/dac_dma/project.xml b/examples/stm32f769i_discovery/dac_dma/project.xml
new file mode 100644
index 0000000000..29bbd99714
--- /dev/null
+++ b/examples/stm32f769i_discovery/dac_dma/project.xml
@@ -0,0 +1,13 @@
+
+ modm:disco-f769ni
+
+
+
+
+ modm:debug
+ modm:platform:dac
+ modm:platform:dma
+ modm:platform:timer:4
+ modm:build:scons
+
+
diff --git a/ext/modm-devices b/ext/modm-devices
index 5d301724cb..b944bf6d03 160000
--- a/ext/modm-devices
+++ b/ext/modm-devices
@@ -1 +1 @@
-Subproject commit 5d301724cb4770e3fda5a2581b99e15df0d1edbd
+Subproject commit b944bf6d0367ead3e4b6008f9be7bba7a5710d97
diff --git a/ext/st/stm32 b/ext/st/stm32
index 1155ed4151..64a48c8394 160000
--- a/ext/st/stm32
+++ b/ext/st/stm32
@@ -1 +1 @@
-Subproject commit 1155ed415163d899300d1d4181ceca22fd805a34
+Subproject commit 64a48c8394dd0a7d545f9d95cb1e9c5f58b2db99
diff --git a/src/modm/board/disco_f769ni/board.hpp b/src/modm/board/disco_f769ni/board.hpp
index 9d2b321197..ea74c7d0e6 100644
--- a/src/modm/board/disco_f769ni/board.hpp
+++ b/src/modm/board/disco_f769ni/board.hpp
@@ -3,6 +3,7 @@
* Copyright (c) 2016, Fabian Greif
* Copyright (c) 2016-2017, Sascha Schade
* Copyright (c) 2018, Antal Szabó
+ * Copyright (c) 2021, Christopher Durand
*
* This file is part of the modm project.
*
@@ -33,8 +34,8 @@ namespace Board
struct SystemClock
{
static constexpr uint32_t Frequency = 216_MHz;
- static constexpr uint32_t Apb1 = Frequency / 8;
- static constexpr uint32_t Apb2 = Frequency / 4;
+ static constexpr uint32_t Apb1 = Frequency / 4;
+ static constexpr uint32_t Apb2 = Frequency / 2;
static constexpr uint32_t Adc1 = Apb2;
static constexpr uint32_t Adc2 = Apb2;
@@ -92,10 +93,8 @@ struct SystemClock
Rcc::enableOverdriveMode();
Rcc::setFlashLatency();
Rcc::enableSystemClock(Rcc::SystemClockSource::Pll);
- // APB1 is running only at 27MHz, since AHB / 4 = 54MHz > 45MHz limit!
- Rcc::setApb1Prescaler(Rcc::Apb1Prescaler::Div8);
- // APB2 is running only at 54MHz, since AHB / 2 = 108MHz > 90MHz limit!
- Rcc::setApb2Prescaler(Rcc::Apb2Prescaler::Div4);
+ Rcc::setApb1Prescaler(Rcc::Apb1Prescaler::Div4);
+ Rcc::setApb2Prescaler(Rcc::Apb2Prescaler::Div2);
Rcc::updateCoreFrequency();
return true;
diff --git a/src/modm/platform/dac/stm32/dac_dma_impl.hpp.in b/src/modm/platform/dac/stm32/dac_dma_impl.hpp.in
index be13b9e76e..72c5e7cf43 100644
--- a/src/modm/platform/dac/stm32/dac_dma_impl.hpp.in
+++ b/src/modm/platform/dac/stm32/dac_dma_impl.hpp.in
@@ -18,8 +18,10 @@ namespace modm::platform
%% if target.family == "g4"
template
-%% endif
void
+%% else
+inline void
+%% endif
Dac{{ id }}Dma::initialize()
{
Rcc::enable();
@@ -108,13 +110,21 @@ void
{{ channel }}::configure(const void* data, size_t dataLength, DmaBase::CircularMode circularMode,
DmaBase::Priority priority)
{
+%% if target.family in ["f2", "f4", "f7"]
+ using RequestMapping = typename DmaChannel::RequestMapping;
+%% else
using RequestMapping = typename DmaChannel::RequestMapping;
+%% endif
constexpr auto request = RequestMapping::Request;
DmaChannel::configure(
DmaBase::DataTransferDirection::MemoryToPeripheral,
DmaBase::MemoryDataSize::HalfWord,
+%% if target.family in ["f0", "f2", "f3", "f4", "f7", "h7"]
+ DmaBase::PeripheralDataSize::HalfWord,
+%% else
DmaBase::PeripheralDataSize::Word,
+%% endif
DmaBase::MemoryIncrementMode::Increment,
DmaBase::PeripheralIncrementMode::Fixed,
priority,
diff --git a/src/modm/platform/dma/stm32/dma.hpp.in b/src/modm/platform/dma/stm32/dma.hpp.in
index 4bc02ff703..3c9c603922 100644
--- a/src/modm/platform/dma/stm32/dma.hpp.in
+++ b/src/modm/platform/dma/stm32/dma.hpp.in
@@ -27,7 +27,7 @@ namespace modm
namespace platform
{
-%% if dmaType in ["stm32-mux"]
+%% if dmaType in ["stm32-mux", "stm32-mux-stream"]
namespace dma
{
template
@@ -59,6 +59,10 @@ public:
Rcc::enable();
%% if (dma.instance | length) > 1
else {
+%% if dmaType in ["stm32-mux-stream"]:
+ // DMAMUX is clocked from DMA1 clock
+ Rcc::enable();
+%% endif
Rcc::enable();
%% if target.string.startswith("stm32f100")
// TODO: Enable remap of DMA2_Channel5 IRQ
@@ -265,11 +269,14 @@ public:
%% endif
DMA_REQ->CSELR &= ~(0x0f << (uint32_t(ChannelID) * 4));
DMA_REQ->CSELR |= uint32_t(dmaRequest) << (uint32_t(ChannelID) * 4);
-%% elif dmaType in ["stm32-mux"]
+%% elif dmaType in ["stm32-mux", "stm32-mux-stream"]
constexpr auto muxChannel = std::find_if(muxChannels.begin(), muxChannels.end(), [](MuxChannel ch) {
+%% if dmaType == "stm32-mux"
return (ch.dmaInstance == ID) && (ch.dmaChannel == (uint32_t(ChannelID) + 1));
+%% else
+ return (ch.dmaInstance == ID) && (ch.dmaChannel == uint32_t(ChannelID));
+%% endif
})->muxChannel;
-
auto* channel = DMAMUX1_Channel0 + muxChannel;
channel->CCR = (channel->CCR & DMAMUX_CxCR_DMAREQ_ID) | uint32_t(dmaRequest);
%% elif dmaType in ["stm32-stream-channel"]
@@ -297,7 +304,7 @@ public:
static const uint32_t TE_Flag {
uint32_t(InterruptFlags::Error) << (uint32_t(ChannelID) * 4)
};
-%% elif dmaType in ["stm32-stream-channel"]
+%% elif dmaType in ["stm32-stream-channel", "stm32-mux-stream"]
constexpr uint8_t offsetLut[8] = {0, 6, 16, 22, 0+32, 6+32, 16+32, 22+32};
static const uint64_t TC_Flag {
uint64_t(InterruptFlags::TransferComplete) << offsetLut[uint32_t(ChannelID)]
@@ -360,7 +367,7 @@ public:
* Helper to verify that the selected channel supports the selected
* hardware and provides the Request to be set in setPeripheralRequest().
*/
-%% if dmaType in ["stm32-mux"]
+%% if dmaType in ["stm32-mux", "stm32-mux-stream"]
template
using RequestMapping = dma::RequestMapping;
%% else
@@ -373,7 +380,7 @@ public:
static inline DmaBase::IrqHandler transferError { nullptr };
static inline DmaBase::IrqHandler transferComplete { nullptr };
-%% if dmaType in ["stm32-mux"]:
+%% if dmaType in ["stm32-mux", "stm32-mux-stream"]:
struct MuxChannel
{
uint8_t muxChannel;
@@ -394,7 +401,7 @@ public:
* Derive DMA controller classes for convenience. Every derived class defines
* the channels available on that controller.
*/
-%% if dmaType in ["stm32-mux"]:
+%% if dmaType in ["stm32-mux", "stm32-mux-stream"]:
%% for controller in dmaController
class Dma{{ controller.instance }}: public DmaController<{{ controller.instance }}>
{
@@ -472,23 +479,24 @@ struct DmaController<{{ channels.instance }}>::Channel
#include
-%% if dmaType in ["stm32-stream-channel"]
+%% if dmaType in ["stm32-stream-channel", "stm32-mux-stream"]
%% set reg_prefix = "DMA_SxCR"
%% elif dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]
%% set reg_prefix = "DMA_CCR"
@@ -88,7 +88,7 @@ public:
%% endfor
};
-%% elif dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]
+%% elif dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux", "stm32-mux-stream"]
enum class
Channel
{
@@ -115,12 +115,19 @@ public:
Request{{ request }}{% if request == 0 %} = 0{% endif %},
%% endfor
};
- %% elif dmaType in ["stm32-mux"]:
+ %% elif dmaType in ["stm32-mux", "stm32-mux-stream"]:
+ %% set request_count = namespace(max_requests = 0)
+ %% for request in dma["requests"][0]["request"]
+ %% if request_count.max_requests < request.position | int
+ %% set request_count.max_requests = request.position | int
+ %% endif
+ %% endfor
+
enum class
Request
{
None = 0,
- %% for request in range(1, 127 + 1)
+ %% for request in range(1, request_count.max_requests + 1)
Request{{ request }},
%% endfor
};
@@ -192,7 +199,7 @@ public:
enum class
DataTransferDirection : uint32_t
{
-%% if dmaType in ["stm32-stream-channel"]
+%% if dmaType in ["stm32-stream-channel", "stm32-mux-stream"]
/// Source: DMA_SxPAR; Sink: DMA_SxM0AR
PeripheralToMemory = 0,
/// Source: DMA_SxM0AR; Sink: DMA_SxPAR
@@ -220,7 +227,7 @@ public:
%% endfor
};
-%% if dmaType in ["stm32-stream-channel"]
+%% if dmaType in ["stm32-stream-channel", "stm32-mux-stream"]
enum class InterruptEnable {
DirectModeError = DMA_SxCR_DMEIE,
TransferError = DMA_SxCR_TEIE,
@@ -260,7 +267,7 @@ public:
using IrqHandler = void (*)(void);
protected:
-%% if dmaType in ["stm32-stream-channel"]
+%% if dmaType in ["stm32-stream-channel", "stm32-mux-stream"]
static constexpr uint32_t memoryMask =
DMA_SxCR_MBURST_Msk | // MemoryBurstTransfer
DMA_SxCR_MSIZE_Msk | // MemoryDataSize
@@ -272,7 +279,9 @@ protected:
DMA_SxCR_PINC_Msk | // PeripheralIncrementMode
DMA_SxCR_DIR_Msk; // DataTransferDirection
static constexpr uint32_t configmask =
+%% if dmaType == "stm32-stream-channel"
DMA_SxCR_CHSEL_Msk | // Channel
+%% endif
DMA_SxCR_PL_Msk | // Priority
DMA_SxCR_CIRC_Msk | // CircularMode
DMA_SxCR_PFCTRL_Msk; // FlowControl
diff --git a/src/modm/platform/dma/stm32/dma_hal.hpp.in b/src/modm/platform/dma/stm32/dma_hal.hpp.in
index dc23e234a3..2159e825e0 100644
--- a/src/modm/platform/dma/stm32/dma_hal.hpp.in
+++ b/src/modm/platform/dma/stm32/dma_hal.hpp.in
@@ -25,7 +25,7 @@ namespace platform
%% if dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]
%% set cr = "CCR"
-%% elif dmaType in ["stm32-stream-channel"]
+%% elif dmaType in ["stm32-stream-channel", "stm32-mux-stream"]
%% set cr = "CR"
using DMA_Channel_TypeDef = DMA_Stream_TypeDef;
%% endif
@@ -72,7 +72,7 @@ class DmaHal : public DmaBase
else
return DMA2_Channel1_BASE;
%% endif
-%% elif dmaType in ["stm32-stream-channel"]
+%% elif dmaType in ["stm32-stream-channel", "stm32-mux-stream"]
if (id == 1)
return DMA1_Stream0_BASE;
%% if (dma.instance | length) > 1
@@ -112,7 +112,7 @@ public:
%% if dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]
/// Register offset from channel to channel
static constexpr uint32_t CHANNEL_2_CHANNEL { 0x14 };
-%% elif dmaType in ["stm32-stream-channel"]
+%% elif dmaType in ["stm32-stream-channel", "stm32-mux-stream"]
/// Register offset from channel to channel
static constexpr uint32_t CHANNEL_2_CHANNEL { 0x18 };
%% endif
@@ -123,7 +123,7 @@ public:
DMA_TypeDef *DMA = reinterpret_cast(DMA_BASE);
%% if dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]
DMA->IFCR = uint32_t(flags) << (uint32_t(ChannelID) * 4);
-%% elif dmaType in ["stm32-stream-channel"]
+%% elif dmaType in ["stm32-stream-channel", "stm32-mux-stream"]
uint8_t ch = uint8_t(ChannelID);
constexpr uint8_t offsetLut[4] = {0, 6, 16, 22};
if (ch < 4) {
@@ -142,7 +142,7 @@ public:
DMA_TypeDef *DMA = reinterpret_cast(DMA_BASE);
return DMA->ISR;
}
-%% elif dmaType in ["stm32-stream-channel"]
+%% elif dmaType in ["stm32-stream-channel", "stm32-mux-stream"]
static uint64_t
getInterruptFlags()
{
@@ -227,7 +227,7 @@ public:
DMA_Channel_TypeDef *Base = (DMA_Channel_TypeDef *) CHANNEL_BASE;
%% if dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]
Base->CMAR = address;
-%% elif dmaType in ["stm32-stream-channel"]
+%% elif dmaType in ["stm32-stream-channel", "stm32-mux-stream"]
Base->M0AR = address;
%% endif
}
@@ -245,7 +245,7 @@ public:
DMA_Channel_TypeDef *Base = (DMA_Channel_TypeDef *) CHANNEL_BASE;
%% if dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]
Base->CPAR = address;
-%% elif dmaType in ["stm32-stream-channel"]
+%% elif dmaType in ["stm32-stream-channel", "stm32-mux-stream"]
Base->PAR = address;
%% endif
}
@@ -297,7 +297,7 @@ public:
DMA_Channel_TypeDef *Base = (DMA_Channel_TypeDef *) CHANNEL_BASE;
%% if dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]
Base->CNDTR = length;
-%% elif dmaType in ["stm32-stream-channel"]
+%% elif dmaType in ["stm32-stream-channel", "stm32-mux-stream"]
Base->NDTR = length;
%% endif
}
diff --git a/src/modm/platform/dma/stm32/dma_hal_impl.hpp.in b/src/modm/platform/dma/stm32/dma_hal_impl.hpp.in
index dae26683af..187439a928 100644
--- a/src/modm/platform/dma/stm32/dma_hal_impl.hpp.in
+++ b/src/modm/platform/dma/stm32/dma_hal_impl.hpp.in
@@ -23,7 +23,7 @@ modm::platform::DmaChannelHal::start()
{
DMA_Channel_TypeDef *Base = (DMA_Channel_TypeDef *) CHANNEL_BASE;
-%% if dmaType in ["stm32-stream-channel"]
+%% if dmaType in ["stm32-stream-channel", "stm32-mux-stream"]
Base->CR |= DMA_SxCR_EN;
%% elif dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]
Base->CCR |= DMA_CCR_EN;
@@ -36,7 +36,7 @@ modm::platform::DmaChannelHal::stop()
{
DMA_Channel_TypeDef *Base = (DMA_Channel_TypeDef *) CHANNEL_BASE;
-%% if dmaType in ["stm32-stream-channel"]
+%% if dmaType in ["stm32-stream-channel", "stm32-mux-stream"]
Base->CR &= ~DMA_SxCR_EN;
while (Base->CR & DMA_SxCR_EN); // wait for stream to be stopped
%% elif dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]
@@ -52,7 +52,7 @@ modm::platform::DmaChannelHal::getDataTransferDirection
DMA_Channel_TypeDef *Base = (DMA_Channel_TypeDef *) CHANNEL_BASE;
return static_cast(
-%% if dmaType in ["stm32-stream-channel"]
+%% if dmaType in ["stm32-stream-channel", "stm32-mux-stream"]
Base->CR & (DMA_SxCR_DIR_0 | DMA_SxCR_DIR_1));
%% elif dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"]
Base->CCR & (DMA_CCR_MEM2MEM | DMA_CCR_DIR));
diff --git a/src/modm/platform/dma/stm32/module.lb b/src/modm/platform/dma/stm32/module.lb
index be341f1942..4caaf4e270 100644
--- a/src/modm/platform/dma/stm32/module.lb
+++ b/src/modm/platform/dma/stm32/module.lb
@@ -32,16 +32,11 @@ def prepare(module, options):
"stm32-channel-request",
"stm32-channel",
"stm32-mux",
+ "stm32-mux-stream",
"stm32-stream-channel",
]:
return False
-
- did = device.identifier
-
- if did["family"] in ["f0", "f1", "f3", "f4", "f7", "l0", "l1", "l4", "g0", "g4"]:
- return True
-
- return False
+ return True
def get_irq_list(device):
@@ -120,14 +115,13 @@ def build(env):
signal_names[signal_name] = 1
controller.append({"instance": int(channels["instance"]),
"min_channel": 1, "max_channel": int(max_channels)})
- elif dma["type"] in ["stm32-mux"]:
+ elif dma["type"] in ["stm32-mux", "stm32-mux-stream"]:
for request_data in dma["requests"]:
for request in request_data["request"]:
- assert len(request["signal"]) == 1 # one signal per request for dmamux
- signal = request["signal"][0]
- if "name" in signal:
- signal_name = signal["name"].capitalize()
- signal_names[signal_name] = 1
+ for signal in request["signal"]:
+ if "name" in signal:
+ signal_name = signal["name"].capitalize()
+ signal_names[signal_name] = 1
assert len(dma["mux-channels"]) == 1 # only one DMAMUX instance is supported
channels = dma["mux-channels"][0]["mux-channel"]