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"]