From 8896b5b5050b3cfb753c2fc2ddc7e42494991e63 Mon Sep 17 00:00:00 2001 From: Christopher Durand Date: Sun, 6 Jun 2021 23:25:57 +0200 Subject: [PATCH] [stm32] Add DMA support for F030xC, F091 and F098 Now all F0, F1, F3, L0, L1, L4, G0 and G4 are supported. --- src/modm/platform/dma/stm32/dma.hpp.in | 6 ++++- src/modm/platform/dma/stm32/dma_hal.hpp.in | 4 ++-- src/modm/platform/dma/stm32/module.lb | 27 ++++++++++++++-------- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/modm/platform/dma/stm32/dma.hpp.in b/src/modm/platform/dma/stm32/dma.hpp.in index 51624d58bd..43d321ce8d 100644 --- a/src/modm/platform/dma/stm32/dma.hpp.in +++ b/src/modm/platform/dma/stm32/dma.hpp.in @@ -252,7 +252,11 @@ public: setPeripheralRequest() { %% if dmaType in ["stm32-channel-request"] - DMA_Request_TypeDef *DMA_REQ = reinterpret_cast(ControlHal::DMA_CSEL); +%% if target["family"] == "f0" + auto* DMA_REQ = reinterpret_cast(ControlHal::DMA_BASE); +%% else + auto* DMA_REQ = reinterpret_cast(ControlHal::DMA_CSEL); +%% endif DMA_REQ->CSELR &= ~(0x0f << (uint32_t(ChannelID) * 4)); DMA_REQ->CSELR |= uint32_t(dmaRequest) << (uint32_t(ChannelID) * 4); %% elif dmaType in ["stm32-mux"] diff --git a/src/modm/platform/dma/stm32/dma_hal.hpp.in b/src/modm/platform/dma/stm32/dma_hal.hpp.in index 04a30d2bfa..eeada661c9 100644 --- a/src/modm/platform/dma/stm32/dma_hal.hpp.in +++ b/src/modm/platform/dma/stm32/dma_hal.hpp.in @@ -67,7 +67,7 @@ class DmaHal : public DmaBase %% endif } -%% if dmaType in ["stm32-channel-request"] +%% if dmaType in ["stm32-channel-request"] and target["family"] != "f0" /** * Get the address of the channel selection register * @@ -87,7 +87,7 @@ class DmaHal : public DmaBase public: /// DMA base register address static constexpr uint32_t DMA_BASE { getBaseAddress() }; -%% if dmaType in ["stm32-channel-request"] +%% if dmaType in ["stm32-channel-request"] and target["family"] != "f0" /// DMA channel selection register address static constexpr uint32_t DMA_CSEL { getCselAddress() }; %% endif diff --git a/src/modm/platform/dma/stm32/module.lb b/src/modm/platform/dma/stm32/module.lb index 216a5c125b..ddcf76c02f 100644 --- a/src/modm/platform/dma/stm32/module.lb +++ b/src/modm/platform/dma/stm32/module.lb @@ -37,15 +37,7 @@ def prepare(module, options): did = device.identifier - # Enable DMA for all but some devices... - - if did["family"] in ["f0"]: - if did["name"] in ["91", "98"] or (did["name"] == "30" and did["size"] == "c"): - # type "stm32-channel-request" incompatible to driver - return False - return True - - if did["family"] in ["f1", "f3", "l0", "l1", "l4", "g0", "g4"]: + if did["family"] in ["f0", "f1", "f3", "l0", "l1", "l4", "g0", "g4"]: return True return False @@ -95,11 +87,28 @@ def build(env): for channel in channels["channel"]: max_channels = channel["position"] if dma["type"] in ["stm32-channel-request"]: + # Some F0 allow to use multiple requests for the same peripheral signal + # on the same channel. This is not supported with the current api. + # Therefore, signals are deduplicated. + signal_set = set() + duplicates = [] for request in channel["request"]: for signal in request["signal"]: + signal_data = (signal.get("driver"), + signal.get("instance"), + signal.get("name")) + if signal_data in signal_set: + duplicates.append((channel, request, signal)) + else: + signal_set.add(signal_data) if "name" in signal: signal_name = signal["name"].capitalize() signal_names[signal_name] = 1 + for duplicate in duplicates: + (channel, request, signal) = duplicate + request["signal"].remove(signal) + if len(request["signal"]) == 0: + channel["request"].remove(request) else: for signal in channel["signal"]: if "name" in signal: