From 2c8e7e48fc4fbb6e7aae7a8b807db99e54909ab5 Mon Sep 17 00:00:00 2001 From: Fabrizio Monti <fabrizio.monti@skywarder.eu> Date: Fri, 14 Feb 2025 20:36:39 +0100 Subject: [PATCH] [DMA] Implemented dynamic stream acquire and moved definitions inside DMADefs. --- src/shared/drivers/dma/DMA.cpp | 82 +++-- src/shared/drivers/dma/DMA.h | 81 ++-- src/shared/drivers/dma/DMADefs.h | 426 ++++++++++++++++++++++ src/tests/drivers/test-dma-mem-to-mem.cpp | 20 +- 4 files changed, 520 insertions(+), 89 deletions(-) create mode 100644 src/shared/drivers/dma/DMADefs.h diff --git a/src/shared/drivers/dma/DMA.cpp b/src/shared/drivers/dma/DMA.cpp index fef96ad56..1a60eeabb 100644 --- a/src/shared/drivers/dma/DMA.cpp +++ b/src/shared/drivers/dma/DMA.cpp @@ -39,7 +39,7 @@ void __attribute__((naked)) DMA1_Stream0_IRQHandler() void __attribute__((used)) DMA1_Stream0_IRQImpl() { Boardcore::DMADriver::instance().IRQhandleInterrupt( - Boardcore::DMAStreamId::DMA1_Str0); + Boardcore::DMADefs::DMAStreamId::DMA1_Str0); } // TODO: decide how to handle this situation @@ -53,7 +53,7 @@ void __attribute__((used)) DMA1_Stream0_IRQImpl() // void __attribute__((used)) DMA1_Stream1_IRQImpl() // { // Boardcore::DMADriver::instance().IRQhandleInterrupt( -// Boardcore::DMAStreamId::DMA1_Str1); +// Boardcore::DMADefs::DMAStreamId::DMA1_Str1); // } void __attribute__((naked)) DMA1_Stream2_IRQHandler() @@ -66,7 +66,7 @@ void __attribute__((naked)) DMA1_Stream2_IRQHandler() void __attribute__((used)) DMA1_Stream2_IRQImpl() { Boardcore::DMADriver::instance().IRQhandleInterrupt( - Boardcore::DMAStreamId::DMA1_Str2); + Boardcore::DMADefs::DMAStreamId::DMA1_Str2); } // TODO: decide how to handle this situation @@ -93,7 +93,7 @@ void __attribute__((naked)) DMA1_Stream4_IRQHandler() void __attribute__((used)) DMA1_Stream4_IRQImpl() { Boardcore::DMADriver::instance().IRQhandleInterrupt( - Boardcore::DMAStreamId::DMA1_Str4); + Boardcore::DMADefs::DMAStreamId::DMA1_Str4); } void __attribute__((naked)) DMA1_Stream5_IRQHandler() @@ -106,7 +106,7 @@ void __attribute__((naked)) DMA1_Stream5_IRQHandler() void __attribute__((used)) DMA1_Stream5_IRQImpl() { Boardcore::DMADriver::instance().IRQhandleInterrupt( - Boardcore::DMAStreamId::DMA1_Str5); + Boardcore::DMADefs::DMAStreamId::DMA1_Str5); } void __attribute__((naked)) DMA1_Stream6_IRQHandler() @@ -119,7 +119,7 @@ void __attribute__((naked)) DMA1_Stream6_IRQHandler() void __attribute__((used)) DMA1_Stream6_IRQImpl() { Boardcore::DMADriver::instance().IRQhandleInterrupt( - Boardcore::DMAStreamId::DMA1_Str6); + Boardcore::DMADefs::DMAStreamId::DMA1_Str6); } void __attribute__((naked)) DMA1_Stream7_IRQHandler() @@ -132,7 +132,7 @@ void __attribute__((naked)) DMA1_Stream7_IRQHandler() void __attribute__((used)) DMA1_Stream7_IRQImpl() { Boardcore::DMADriver::instance().IRQhandleInterrupt( - Boardcore::DMAStreamId::DMA1_Str7); + Boardcore::DMADefs::DMAStreamId::DMA1_Str7); } void __attribute__((naked)) DMA2_Stream0_IRQHandler() @@ -145,7 +145,7 @@ void __attribute__((naked)) DMA2_Stream0_IRQHandler() void __attribute__((used)) DMA2_Stream0_IRQImpl() { Boardcore::DMADriver::instance().IRQhandleInterrupt( - Boardcore::DMAStreamId::DMA2_Str0); + Boardcore::DMADefs::DMAStreamId::DMA2_Str0); } void __attribute__((naked)) DMA2_Stream1_IRQHandler() @@ -158,7 +158,7 @@ void __attribute__((naked)) DMA2_Stream1_IRQHandler() void __attribute__((used)) DMA2_Stream1_IRQImpl() { Boardcore::DMADriver::instance().IRQhandleInterrupt( - Boardcore::DMAStreamId::DMA2_Str1); + Boardcore::DMADefs::DMAStreamId::DMA2_Str1); } void __attribute__((naked)) DMA2_Stream2_IRQHandler() @@ -171,7 +171,7 @@ void __attribute__((naked)) DMA2_Stream2_IRQHandler() void __attribute__((used)) DMA2_Stream2_IRQImpl() { Boardcore::DMADriver::instance().IRQhandleInterrupt( - Boardcore::DMAStreamId::DMA2_Str2); + Boardcore::DMADefs::DMAStreamId::DMA2_Str2); } // TODO: decide how to handle this situation @@ -186,7 +186,7 @@ void __attribute__((used)) DMA2_Stream2_IRQImpl() // void __attribute__((used)) DMA2_Stream3_IRQImpl() // { // Boardcore::DMADriver::instance().IRQhandleInterrupt( -// Boardcore::DMAStreamId::DMA2_Str3); +// Boardcore::DMADefs::DMAStreamId::DMA2_Str3); // } void __attribute__((naked)) DMA2_Stream4_IRQHandler() @@ -199,7 +199,7 @@ void __attribute__((naked)) DMA2_Stream4_IRQHandler() void __attribute__((used)) DMA2_Stream4_IRQImpl() { Boardcore::DMADriver::instance().IRQhandleInterrupt( - Boardcore::DMAStreamId::DMA2_Str4); + Boardcore::DMADefs::DMAStreamId::DMA2_Str4); } void __attribute__((naked)) DMA2_Stream5_IRQHandler() @@ -212,7 +212,7 @@ void __attribute__((naked)) DMA2_Stream5_IRQHandler() void __attribute__((used)) DMA2_Stream5_IRQImpl() { Boardcore::DMADriver::instance().IRQhandleInterrupt( - Boardcore::DMAStreamId::DMA2_Str5); + Boardcore::DMADefs::DMAStreamId::DMA2_Str5); } void __attribute__((naked)) DMA2_Stream6_IRQHandler() @@ -225,7 +225,7 @@ void __attribute__((naked)) DMA2_Stream6_IRQHandler() void __attribute__((used)) DMA2_Stream6_IRQImpl() { Boardcore::DMADriver::instance().IRQhandleInterrupt( - Boardcore::DMAStreamId::DMA2_Str6); + Boardcore::DMADefs::DMAStreamId::DMA2_Str6); } void __attribute__((naked)) DMA2_Stream7_IRQHandler() @@ -238,13 +238,13 @@ void __attribute__((naked)) DMA2_Stream7_IRQHandler() void __attribute__((used)) DMA2_Stream7_IRQImpl() { Boardcore::DMADriver::instance().IRQhandleInterrupt( - Boardcore::DMAStreamId::DMA2_Str7); + Boardcore::DMADefs::DMAStreamId::DMA2_Str7); } namespace Boardcore { -void DMADriver::IRQhandleInterrupt(DMAStreamId id) +void DMADriver::IRQhandleInterrupt(DMADefs::DMAStreamId id) { auto stream = streams[id]; @@ -298,7 +298,7 @@ DMADriver& DMADriver::instance() return instance; } -bool DMADriver::tryChannel(DMAStreamId id) +bool DMADriver::tryChannel(DMADefs::DMAStreamId id) { Lock<FastMutex> l(mutex); @@ -307,7 +307,8 @@ bool DMADriver::tryChannel(DMAStreamId id) return streams.count(id) == 0; } -DMAStream& DMADriver::acquireStream(DMAStreamId id) +DMAStream* DMADriver::acquireStream(DMADefs::DMAStreamId id, + DMADefs::Channel channel) { Lock<FastMutex> l(mutex); @@ -320,10 +321,33 @@ DMAStream& DMADriver::acquireStream(DMAStreamId id) // if (streams.size() == 0) // RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; - return *(streams[id] = new DMAStream(id)); + return streams[id] = new DMAStream(id, channel); } -void DMADriver::releaseStream(DMAStreamId id) +DMAStream* DMADriver::automaticAcquireStream(DMADefs::Peripherals peripheral) +{ + auto availableStreams = DMADefs::mapPeripherals.equal_range(peripheral); + + // Iterate through the streams for that peripheral, + // return the first available + Lock<FastMutex> l(mutex); + for (auto it = availableStreams.first; it != availableStreams.second; ++it) + { + DMADefs::DMAStreamId id = it->second.first; + DMADefs::Channel channel = it->second.second; + + if (streams.count(id) == 0) + { + // Stream is free + return streams[id] = new DMAStream(id, channel); + } + } + + // TODO: improve error handling + return nullptr; +} + +void DMADriver::releaseStream(DMADefs::DMAStreamId id) { Lock<FastMutex> l(mutex); @@ -365,7 +389,7 @@ void DMAStream::setup(DMATransaction transaction) while (registers->CR & DMA_SxCR_EN) ; - registers->CR |= static_cast<uint32_t>(transaction.channel); + setChannel(currentChannel); registers->CR |= static_cast<uint32_t>(transaction.direction); registers->CR |= static_cast<uint32_t>(transaction.priority); if (transaction.circularMode) @@ -560,21 +584,27 @@ void DMAStream::setNumberOfDataItems(const uint16_t nBytes) registers->NDTR = nBytes; } +void DMAStream::setChannel(const DMADefs::Channel channel) +{ + registers->CR |= static_cast<uint32_t>(channel); +} + int DMAStream::getCurrentBufferNumber() { return (registers->CR & DMA_SxCR_CT) != 0 ? 2 : 1; } -DMAStream::DMAStream(DMAStreamId id) : id(id) +DMAStream::DMAStream(DMADefs::DMAStreamId id, DMADefs::Channel channel) + : id(id), currentChannel(channel) { // Get the channel registers base address and the interrupt flags clear // register address - if (id < DMAStreamId::DMA2_Str0) + if (id < DMADefs::DMAStreamId::DMA2_Str0) { registers = reinterpret_cast<DMA_Stream_TypeDef*>( DMA1_BASE + 0x10 + 0x18 * static_cast<uint8_t>(id)); - if (id < DMAStreamId::DMA1_Str4) + if (id < DMADefs::DMAStreamId::DMA1_Str4) { // Streams from 0 to 3 use low registers (LIFCR and LISR) IFCR = &DMA1->LIFCR; @@ -592,7 +622,7 @@ DMAStream::DMAStream(DMAStreamId id) : id(id) registers = reinterpret_cast<DMA_Stream_TypeDef*>( DMA2_BASE + 0x10 + 0x18 * (static_cast<uint8_t>(id) - 8)); - if (id < DMAStreamId::DMA2_Str4) + if (id < DMADefs::DMAStreamId::DMA2_Str4) { // Streams from 0 to 3 use low registers (LIFCR and LISR) IFCR = &DMA2->LIFCR; @@ -612,7 +642,7 @@ DMAStream::DMAStream(DMAStreamId id) : id(id) IFindex = (offset % 2) * 6 + (offset / 2) * 16; // Select the interrupt - irqNumber = irqNumberMapping[static_cast<uint8_t>(id)]; + irqNumber = DMADefs::irqNumberMapping[static_cast<uint8_t>(id)]; } } // namespace Boardcore diff --git a/src/shared/drivers/dma/DMA.h b/src/shared/drivers/dma/DMA.h index 754e9ba8f..e94b49ea7 100644 --- a/src/shared/drivers/dma/DMA.h +++ b/src/shared/drivers/dma/DMA.h @@ -22,7 +22,6 @@ #pragma once -#include <interfaces/arch_registers.h> #include <kernel/scheduler/scheduler.h> #include <kernel/sync.h> #include <utils/TimedPollingFlag.h> @@ -31,6 +30,8 @@ #include <functional> #include <map> +#include "DMADefs.h" + namespace Boardcore { @@ -43,57 +44,8 @@ namespace Boardcore #define DMA_SxCR_PSIZE_Pos (11U) #endif -enum class DMAStreamId : uint8_t -{ - // TODO: some streams are commented because the - // corresponding irq handler is already defined - // by miosix. For now those streams are not usable, - // decide how to handle this situation. - - DMA1_Str0 = 0, - // DMA1_Str1 = 1, - DMA1_Str2 = 2, - // DMA1_Str3 = 3, - DMA1_Str4 = 4, - DMA1_Str5 = 5, - DMA1_Str6 = 6, - DMA1_Str7 = 7, - DMA2_Str0 = 8, - DMA2_Str1 = 9, - DMA2_Str2 = 10, - // DMA2_Str3 = 11, - DMA2_Str4 = 12, - DMA2_Str5 = 13, - DMA2_Str6 = 14, - DMA2_Str7 = 15, -}; - -/** - * @brief Mapping between `DMAStreamId` and the corresponding irq number. - * This is needed because irq number values are not contiguous and they are - * architecture dependent. - */ -const IRQn_Type irqNumberMapping[] = { - DMA1_Stream0_IRQn, DMA1_Stream1_IRQn, DMA1_Stream2_IRQn, DMA1_Stream3_IRQn, - DMA1_Stream4_IRQn, DMA1_Stream5_IRQn, DMA1_Stream6_IRQn, DMA1_Stream7_IRQn, - DMA2_Stream0_IRQn, DMA2_Stream1_IRQn, DMA2_Stream2_IRQn, DMA2_Stream3_IRQn, - DMA2_Stream4_IRQn, DMA2_Stream5_IRQn, DMA2_Stream6_IRQn, DMA2_Stream7_IRQn, -}; - struct DMATransaction { - enum class Channel : uint32_t - { - CHANNEL0 = 0, - CHANNEL1 = DMA_SxCR_CHSEL_0, - CHANNEL2 = DMA_SxCR_CHSEL_1, - CHANNEL3 = DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_0, - CHANNEL4 = DMA_SxCR_CHSEL_2, - CHANNEL5 = DMA_SxCR_CHSEL_2 | DMA_SxCR_CHSEL_0, - CHANNEL6 = DMA_SxCR_CHSEL_2 | DMA_SxCR_CHSEL_1, - CHANNEL7 = DMA_SxCR_CHSEL, - }; - enum class Direction : uint16_t { MEM_TO_MEM = DMA_SxCR_DIR_1, @@ -116,7 +68,6 @@ struct DMATransaction BITS_32, }; - Channel channel = Channel::CHANNEL0; Direction direction = Direction::MEM_TO_MEM; Priority priority = Priority::LOW; DataSize srcSize = DataSize::BITS_32; @@ -142,15 +93,18 @@ class DMAStream; class DMADriver { public: - void IRQhandleInterrupt(DMAStreamId id); + void IRQhandleInterrupt(DMADefs::DMAStreamId id); static DMADriver& instance(); - bool tryChannel(DMAStreamId id); + bool tryChannel(DMADefs::DMAStreamId id); - DMAStream& acquireStream(DMAStreamId id); + DMAStream* acquireStream(DMADefs::DMAStreamId id, DMADefs::Channel channel); - void releaseStream(DMAStreamId id); + // TODO: change name + DMAStream* automaticAcquireStream(DMADefs::Peripherals peripheral); + + void releaseStream(DMADefs::DMAStreamId id); private: DMADriver(); @@ -159,7 +113,7 @@ private: miosix::FastMutex mutex; miosix::ConditionVariable cv; - std::map<DMAStreamId, DMAStream*> streams; + std::map<DMADefs::DMAStreamId, DMAStream*> streams; public: DMADriver(const DMADriver&) = delete; @@ -218,6 +172,12 @@ public: */ void setNumberOfDataItems(const uint16_t nBytes); + /** + * @brief Select the channel to be used by the stream during + * the transactions. + */ + void setChannel(const DMADefs::Channel channel); + /** * @brief Returns the last read status of the half transfer flag. * @@ -260,6 +220,10 @@ public: */ int getCurrentBufferNumber(); + inline DMADefs::DMAStreamId getStreamId() { return id; } + + inline DMADefs::Channel getCurrentChannel() { return currentChannel; } + inline void clearHalfTransferFlag() { *IFCR |= DMA_LIFCR_CHTIF0 << IFindex; @@ -294,7 +258,7 @@ public: } private: - DMAStream(DMAStreamId id); + DMAStream(DMADefs::DMAStreamId id, DMADefs::Channel channel); DMATransaction currentSetup; @@ -316,7 +280,8 @@ private: std::function<void()> transferCompleteCallback; std::function<void()> errorCallback; - DMAStreamId id; + DMADefs::DMAStreamId id; + DMADefs::Channel currentChannel; IRQn_Type irqNumber; DMA_Stream_TypeDef* registers; diff --git a/src/shared/drivers/dma/DMADefs.h b/src/shared/drivers/dma/DMADefs.h new file mode 100644 index 000000000..bdbca679f --- /dev/null +++ b/src/shared/drivers/dma/DMADefs.h @@ -0,0 +1,426 @@ +/* Copyright (c) 2025 Skyward Experimental Rocketry + * Author: Fabrizio Monti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include <interfaces/arch_registers.h> +#include <stdint.h> + +#include <map> + +namespace Boardcore +{ + +namespace DMADefs +{ + +enum class DMAStreamId : uint8_t +{ + // TODO: some streams are commented because the + // corresponding irq handler is already defined + // by miosix. For now those streams are not usable, + // decide how to handle this situation. + + DMA1_Str0 = 0, + // DMA1_Str1 = 1, + DMA1_Str2 = 2, + // DMA1_Str3 = 3, + DMA1_Str4 = 4, + DMA1_Str5 = 5, + DMA1_Str6 = 6, + DMA1_Str7 = 7, + DMA2_Str0 = 8, + DMA2_Str1 = 9, + DMA2_Str2 = 10, + // DMA2_Str3 = 11, + DMA2_Str4 = 12, + DMA2_Str5 = 13, + DMA2_Str6 = 14, + DMA2_Str7 = 15, +}; + +/** + * @brief Mapping between `DMAStreamId` and the corresponding irq number. + * This is needed because irq number values are not contiguous and they are + * architecture dependent. + */ +const IRQn_Type irqNumberMapping[] = { + DMA1_Stream0_IRQn, DMA1_Stream1_IRQn, DMA1_Stream2_IRQn, DMA1_Stream3_IRQn, + DMA1_Stream4_IRQn, DMA1_Stream5_IRQn, DMA1_Stream6_IRQn, DMA1_Stream7_IRQn, + DMA2_Stream0_IRQn, DMA2_Stream1_IRQn, DMA2_Stream2_IRQn, DMA2_Stream3_IRQn, + DMA2_Stream4_IRQn, DMA2_Stream5_IRQn, DMA2_Stream6_IRQn, DMA2_Stream7_IRQn, +}; + +/** + * @brief Channels selectable for each dma stream. + */ +enum class Channel : uint32_t +{ + CHANNEL0 = 0, + CHANNEL1 = DMA_SxCR_CHSEL_0, + CHANNEL2 = DMA_SxCR_CHSEL_1, + CHANNEL3 = DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_0, + CHANNEL4 = DMA_SxCR_CHSEL_2, + CHANNEL5 = DMA_SxCR_CHSEL_2 | DMA_SxCR_CHSEL_0, + CHANNEL6 = DMA_SxCR_CHSEL_2 | DMA_SxCR_CHSEL_1, + CHANNEL7 = DMA_SxCR_CHSEL, +}; + +/** + * @brief All the peripherals connected to dma. + */ +enum class Peripherals : uint8_t +{ + PE_MEM_ONLY, + + PE_SPI1_TX, + PE_SPI1_RX, + PE_SPI2_TX, + PE_SPI2_RX, + PE_SPI3_TX, + PE_SPI3_RX, + PE_SPI4_TX, + PE_SPI4_RX, + PE_SPI5_TX, + PE_SPI5_RX, + PE_SPI6_TX, + PE_SPI6_RX, + PE_USART1_TX, + PE_USART1_RX, + PE_USART2_TX, + PE_USART2_RX, + PE_USART3_TX, + PE_USART3_RX, + PE_UART4_TX, + PE_UART4_RX, + PE_UART5_TX, + PE_UART5_RX, + PE_USART6_TX, + PE_USART6_RX, + PE_UART7_TX, + PE_UART7_RX, + PE_UART8_TX, + PE_UART8_RX, + PE_I2C1_TX, + PE_I2C1_RX, + PE_I2C2_TX, + PE_I2C2_RX, + PE_I2C3_TX, + PE_I2C3_RX, + PE_I2S2_EXT_TX, + PE_I2S2_EXT_RX, + PE_I2S3_EXT_TX, + PE_I2S3_EXT_RX, + PE_TIM1_UP, + PE_TIM1_TRIG, + PE_TIM1_COM, + PE_TIM1_CH1, + PE_TIM1_CH2, + PE_TIM1_CH3, + PE_TIM1_CH4, + PE_TIM2_UP, + PE_TIM2_CH1, + PE_TIM2_CH2, + PE_TIM2_CH3, + PE_TIM2_CH4, + PE_TIM3_UP, + PE_TIM3_TRIG, + PE_TIM3_CH1, + PE_TIM3_CH2, + PE_TIM3_CH3, + PE_TIM3_CH4, + PE_TIM4_UP, + PE_TIM4_CH1, + PE_TIM4_CH2, + PE_TIM4_CH3, + PE_TIM5_UP, + PE_TIM5_TRIG, + PE_TIM5_CH1, + PE_TIM5_CH2, + PE_TIM5_CH3, + PE_TIM5_CH4, + PE_TIM6_UP, + PE_TIM7_UP, + PE_TIM8_UP, + PE_TIM8_TRIG, + PE_TIM8_COM, + PE_TIM8_CH1, + PE_TIM8_CH2, + PE_TIM8_CH3, + PE_TIM8_CH4, + PE_DAC1, + PE_DAC2, + PE_ADC1, + PE_ADC2, + PE_ADC3, + PE_SAI1_A, + PE_SAI1_B, + PE_DCMI, + PE_SDIO, + PE_CRYP_OUT, + PE_CRYP_IN, + PE_HASH_IN, + +}; + +/** + * @brief Maps the peripherals to the dma streams (and + * the corresponding channel) that are connected with. + */ +const std::multimap<Peripherals, std::pair<DMAStreamId, Channel>> + mapPeripherals = { + + // MEM-TO-MEM (only dma2 can perform mem-to-mem copy) + {Peripherals::PE_MEM_ONLY, {DMAStreamId::DMA2_Str0, Channel::CHANNEL0}}, + {Peripherals::PE_MEM_ONLY, {DMAStreamId::DMA2_Str1, Channel::CHANNEL0}}, + {Peripherals::PE_MEM_ONLY, {DMAStreamId::DMA2_Str2, Channel::CHANNEL0}}, + // {Peripherals::PE_MEM_ONLY, {DMAStreamId::DMA2_Str3, + // Channel::CHANNEL0}}, // Stream currently not supported + {Peripherals::PE_MEM_ONLY, {DMAStreamId::DMA2_Str4, Channel::CHANNEL0}}, + {Peripherals::PE_MEM_ONLY, {DMAStreamId::DMA2_Str5, Channel::CHANNEL0}}, + {Peripherals::PE_MEM_ONLY, {DMAStreamId::DMA2_Str6, Channel::CHANNEL0}}, + {Peripherals::PE_MEM_ONLY, {DMAStreamId::DMA2_Str7, Channel::CHANNEL0}}, + + // SPI + {Peripherals::PE_SPI1_TX, {DMAStreamId::DMA2_Str5, Channel::CHANNEL3}}, + // {Peripherals::PE_SPI1_TX, {DMAStreamId::DMA2_Str3, + // Channel::CHANNEL3}}, // Stream currently not supported + {Peripherals::PE_SPI1_RX, {DMAStreamId::DMA2_Str2, Channel::CHANNEL3}}, + {Peripherals::PE_SPI1_RX, {DMAStreamId::DMA2_Str0, Channel::CHANNEL3}}, + + {Peripherals::PE_SPI2_TX, {DMAStreamId::DMA1_Str4, Channel::CHANNEL0}}, + // {Peripherals::PE_SPI2_RX, {DMAStreamId::DMA1_Str3, + // Channel::CHANNEL0}}, // Stream currently not supported + + {Peripherals::PE_SPI3_TX, {DMAStreamId::DMA1_Str5, Channel::CHANNEL0}}, + {Peripherals::PE_SPI3_TX, {DMAStreamId::DMA1_Str7, Channel::CHANNEL0}}, + {Peripherals::PE_SPI3_RX, {DMAStreamId::DMA1_Str0, Channel::CHANNEL0}}, + {Peripherals::PE_SPI3_RX, {DMAStreamId::DMA1_Str2, Channel::CHANNEL0}}, + + // {Peripherals::PE_SPI4_TX, {DMAStreamId::DMA2_Str1, + // Channel::CHANNEL4}}, // available on STM32F42xxx and STM32F43xxx only + // {Peripherals::PE_SPI4_TX, {DMAStreamId::DMA2_Str4, + // Channel::CHANNEL5}}, // available on STM32F42xxx and STM32F43xxx only + // {Peripherals::PE_SPI4_RX, {DMAStreamId::DMA2_Str0, + // Channel::CHANNEL4}}, // available on STM32F42xxx and STM32F43xxx only + // {Peripherals::PE_SPI4_RX, {DMAStreamId::DMA2_Str3, + // Channel::CHANNEL5}}, // available on STM32F42xxx and STM32F43xxx only + + // {Peripherals::PE_SPI5_TX, {DMAStreamId::DMA2_Str4, + // Channel::CHANNEL2}}, // available on STM32F42xxx and STM32F43xxx only + // {Peripherals::PE_SPI5_TX, {DMAStreamId::DMA2_Str6, + // Channel::CHANNEL7}}, // available on STM32F42xxx and STM32F43xxx only + // {Peripherals::PE_SPI5_RX, {DMAStreamId::DMA2_Str3, + // Channel::CHANNEL2}}, // available on STM32F42xxx and STM32F43xxx only + // {Peripherals::PE_SPI5_RX, {DMAStreamId::DMA2_Str5, + // Channel::CHANNEL7}}, // available on STM32F42xxx and STM32F43xxx only + + // {Peripherals::PE_SPI6_TX, {DMAStreamId::DMA2_Str5, + // Channel::CHANNEL1}}, // available on STM32F42xxx and STM32F43xxx only + // {Peripherals::PE_SPI6_RX, {DMAStreamId::DMA2_Str6, + // Channel::CHANNEL1}}, // available on STM32F42xxx and STM32F43xxx only + + // UART & USART + {Peripherals::PE_USART1_TX, + {DMAStreamId::DMA2_Str7, Channel::CHANNEL4}}, + {Peripherals::PE_USART1_RX, + {DMAStreamId::DMA2_Str2, Channel::CHANNEL4}}, + {Peripherals::PE_USART1_RX, + {DMAStreamId::DMA2_Str5, Channel::CHANNEL4}}, + + {Peripherals::PE_USART2_TX, + {DMAStreamId::DMA1_Str6, Channel::CHANNEL4}}, + {Peripherals::PE_USART2_RX, + {DMAStreamId::DMA1_Str5, Channel::CHANNEL4}}, + + // {Peripherals::PE_USART3_TX, {DMAStreamId::DMA1_Str3, + // Channel::CHANNEL4}}, // Stream currently not supported + {Peripherals::PE_USART3_TX, + {DMAStreamId::DMA1_Str4, Channel::CHANNEL7}}, + // {Peripherals::PE_USART3_RX, {DMAStreamId::DMA1_Str1, + // Channel::CHANNEL4}}, // Stream currently not supported + + {Peripherals::PE_UART4_TX, {DMAStreamId::DMA1_Str4, Channel::CHANNEL4}}, + {Peripherals::PE_UART4_RX, {DMAStreamId::DMA1_Str2, Channel::CHANNEL4}}, + + {Peripherals::PE_UART5_TX, {DMAStreamId::DMA1_Str7, Channel::CHANNEL4}}, + {Peripherals::PE_UART5_RX, {DMAStreamId::DMA1_Str0, Channel::CHANNEL4}}, + + // {Peripherals::PE_UART7_TX, {DMAStreamId::DMA1_Str1, + // Channel::CHANNEL5}}, // available on STM32F42xxx and STM32F43xxx only + // {Peripherals::PE_UART7_RX, {DMAStreamId::DMA1_Str3, + // Channel::CHANNEL5}}, // available on STM32F42xxx and STM32F43xxx only + + // {Peripherals::PE_UART8_TX, {DMAStreamId::DMA1_Str0, + // Channel::CHANNEL5}}, // available on STM32F42xxx and STM32F43xxx only + // {Peripherals::PE_UART8_RX, {DMAStreamId::DMA1_Str6, + // Channel::CHANNEL5}}, // available on STM32F42xxx and STM32F43xxx only + + {Peripherals::PE_USART6_TX, + {DMAStreamId::DMA2_Str6, Channel::CHANNEL5}}, + {Peripherals::PE_USART6_TX, + {DMAStreamId::DMA2_Str7, Channel::CHANNEL5}}, + {Peripherals::PE_USART6_RX, + {DMAStreamId::DMA2_Str1, Channel::CHANNEL5}}, + {Peripherals::PE_USART6_RX, + {DMAStreamId::DMA2_Str2, Channel::CHANNEL5}}, + + // I2C + {Peripherals::PE_I2C1_TX, {DMAStreamId::DMA1_Str6, Channel::CHANNEL1}}, + {Peripherals::PE_I2C1_TX, {DMAStreamId::DMA1_Str7, Channel::CHANNEL1}}, + {Peripherals::PE_I2C1_RX, {DMAStreamId::DMA1_Str0, Channel::CHANNEL1}}, + {Peripherals::PE_I2C1_RX, {DMAStreamId::DMA1_Str5, Channel::CHANNEL1}}, + + {Peripherals::PE_I2C2_TX, {DMAStreamId::DMA1_Str7, Channel::CHANNEL7}}, + {Peripherals::PE_I2C2_RX, {DMAStreamId::DMA1_Str2, Channel::CHANNEL7}}, + // {Peripherals::PE_I2C2_RX, {DMAStreamId::DMA1_Str3, + // Channel::CHANNEL7}}, // Stream currently not supported + + {Peripherals::PE_I2C3_TX, {DMAStreamId::DMA1_Str4, Channel::CHANNEL3}}, + {Peripherals::PE_I2C3_RX, {DMAStreamId::DMA1_Str2, Channel::CHANNEL3}}, + + {Peripherals::PE_I2S2_EXT_TX, + {DMAStreamId::DMA1_Str4, Channel::CHANNEL2}}, + // {Peripherals::PE_I2S2_EXT_RX, {DMAStreamId::DMA1_Str3, + // Channel::CHANNEL3}}, // Stream currently not supported + + {Peripherals::PE_I2S3_EXT_TX, + {DMAStreamId::DMA1_Str5, Channel::CHANNEL2}}, + {Peripherals::PE_I2S3_EXT_RX, + {DMAStreamId::DMA1_Str2, Channel::CHANNEL2}}, + {Peripherals::PE_I2S3_EXT_RX, + {DMAStreamId::DMA1_Str0, Channel::CHANNEL3}}, + + // TIMERS + {Peripherals::PE_TIM1_UP, {DMAStreamId::DMA2_Str5, Channel::CHANNEL6}}, + {Peripherals::PE_TIM1_TRIG, + {DMAStreamId::DMA2_Str0, Channel::CHANNEL6}}, + {Peripherals::PE_TIM1_TRIG, + {DMAStreamId::DMA2_Str4, Channel::CHANNEL6}}, + {Peripherals::PE_TIM1_COM, {DMAStreamId::DMA2_Str4, Channel::CHANNEL6}}, + {Peripherals::PE_TIM1_CH1, {DMAStreamId::DMA2_Str6, Channel::CHANNEL0}}, + {Peripherals::PE_TIM1_CH1, {DMAStreamId::DMA2_Str1, Channel::CHANNEL6}}, + // {Peripherals::PE_TIM1_CH1, {DMAStreamId::DMA2_Str3, + // Channel::CHANNEL6}}, // Stream currently not supported + {Peripherals::PE_TIM1_CH2, {DMAStreamId::DMA2_Str6, Channel::CHANNEL0}}, + {Peripherals::PE_TIM1_CH2, {DMAStreamId::DMA2_Str2, Channel::CHANNEL6}}, + {Peripherals::PE_TIM1_CH3, {DMAStreamId::DMA2_Str6, Channel::CHANNEL0}}, + {Peripherals::PE_TIM1_CH3, {DMAStreamId::DMA2_Str6, Channel::CHANNEL6}}, + {Peripherals::PE_TIM1_CH4, {DMAStreamId::DMA2_Str4, Channel::CHANNEL6}}, + + // {Peripherals::PE_TIM2_UP, {DMAStreamId::DMA1_Str1, + // Channel::CHANNEL3}}, // Stream currently not supported + {Peripherals::PE_TIM2_UP, {DMAStreamId::DMA1_Str7, Channel::CHANNEL3}}, + {Peripherals::PE_TIM2_CH1, {DMAStreamId::DMA1_Str5, Channel::CHANNEL3}}, + {Peripherals::PE_TIM2_CH2, {DMAStreamId::DMA1_Str6, Channel::CHANNEL3}}, + // {Peripherals::PE_TIM2_CH3, {DMAStreamId::DMA1_Str1, + // Channel::CHANNEL3}}, // Stream currently not supported + {Peripherals::PE_TIM2_CH4, {DMAStreamId::DMA1_Str6, Channel::CHANNEL3}}, + {Peripherals::PE_TIM2_CH4, {DMAStreamId::DMA1_Str7, Channel::CHANNEL3}}, + + {Peripherals::PE_TIM3_UP, {DMAStreamId::DMA1_Str2, Channel::CHANNEL5}}, + {Peripherals::PE_TIM3_TRIG, + {DMAStreamId::DMA1_Str4, Channel::CHANNEL5}}, + {Peripherals::PE_TIM3_CH1, {DMAStreamId::DMA1_Str4, Channel::CHANNEL5}}, + {Peripherals::PE_TIM3_CH2, {DMAStreamId::DMA1_Str5, Channel::CHANNEL5}}, + {Peripherals::PE_TIM3_CH3, {DMAStreamId::DMA1_Str7, Channel::CHANNEL5}}, + {Peripherals::PE_TIM3_CH4, {DMAStreamId::DMA1_Str2, Channel::CHANNEL5}}, + + {Peripherals::PE_TIM4_UP, {DMAStreamId::DMA1_Str6, Channel::CHANNEL2}}, + {Peripherals::PE_TIM4_CH1, {DMAStreamId::DMA1_Str0, Channel::CHANNEL2}}, + // {Peripherals::PE_TIM4_CH2, {DMAStreamId::DMA1_Str3, + // Channel::CHANNEL2}}, // Stream currently not supported + {Peripherals::PE_TIM4_CH3, {DMAStreamId::DMA1_Str7, Channel::CHANNEL2}}, + + {Peripherals::PE_TIM5_UP, {DMAStreamId::DMA1_Str0, Channel::CHANNEL6}}, + {Peripherals::PE_TIM5_UP, {DMAStreamId::DMA1_Str6, Channel::CHANNEL6}}, + // {Peripherals::PE_TIM5_TRIG, {DMAStreamId::DMA1_Str1, + // Channel::CHANNEL6}}, // Stream currently not supported + // {Peripherals::PE_TIM5_TRIG, {DMAStreamId::DMA1_Str3, + // Channel::CHANNEL6}}, // Stream currently not supported + {Peripherals::PE_TIM5_CH1, {DMAStreamId::DMA1_Str2, Channel::CHANNEL6}}, + {Peripherals::PE_TIM5_CH2, {DMAStreamId::DMA1_Str4, Channel::CHANNEL6}}, + {Peripherals::PE_TIM5_CH3, {DMAStreamId::DMA1_Str0, Channel::CHANNEL6}}, + // {Peripherals::PE_TIM5_CH4, {DMAStreamId::DMA1_Str1, + // Channel::CHANNEL6}}, // Stream currently not supported + // {Peripherals::PE_TIM5_CH4, {DMAStreamId::DMA1_Str3, + // Channel::CHANNEL6}}, // Stream currently not supported + + // {Peripherals::PE_TIM6_UP, {DMAStreamId::DMA1_Str1, + // Channel::CHANNEL7}}, // Stream currently not supported + + {Peripherals::PE_TIM7_UP, {DMAStreamId::DMA1_Str2, Channel::CHANNEL1}}, + {Peripherals::PE_TIM7_UP, {DMAStreamId::DMA1_Str4, Channel::CHANNEL1}}, + + {Peripherals::PE_TIM8_UP, {DMAStreamId::DMA2_Str1, Channel::CHANNEL7}}, + {Peripherals::PE_TIM8_TRIG, + {DMAStreamId::DMA2_Str7, Channel::CHANNEL7}}, + {Peripherals::PE_TIM8_COM, {DMAStreamId::DMA2_Str7, Channel::CHANNEL7}}, + {Peripherals::PE_TIM8_CH1, {DMAStreamId::DMA2_Str2, Channel::CHANNEL0}}, + {Peripherals::PE_TIM8_CH1, {DMAStreamId::DMA2_Str2, Channel::CHANNEL7}}, + {Peripherals::PE_TIM8_CH2, {DMAStreamId::DMA2_Str2, Channel::CHANNEL0}}, + // {Peripherals::PE_TIM8_CH2, {DMAStreamId::DMA2_Str3, + // Channel::CHANNEL7}}, // Stream currently not supported + {Peripherals::PE_TIM8_CH3, {DMAStreamId::DMA2_Str2, Channel::CHANNEL0}}, + {Peripherals::PE_TIM8_CH3, {DMAStreamId::DMA2_Str4, Channel::CHANNEL7}}, + {Peripherals::PE_TIM8_CH4, {DMAStreamId::DMA2_Str7, Channel::CHANNEL7}}, + + // Others + {Peripherals::PE_DAC1, {DMAStreamId::DMA1_Str5, Channel::CHANNEL7}}, + {Peripherals::PE_DAC2, {DMAStreamId::DMA1_Str6, Channel::CHANNEL7}}, + + {Peripherals::PE_ADC1, {DMAStreamId::DMA2_Str0, Channel::CHANNEL0}}, + {Peripherals::PE_ADC1, {DMAStreamId::DMA2_Str4, Channel::CHANNEL0}}, + + {Peripherals::PE_ADC2, {DMAStreamId::DMA2_Str2, Channel::CHANNEL1}}, + // {Peripherals::PE_ADC2, {DMAStreamId::DMA2_Str3, Channel::CHANNEL1}}, + // // Stream currently not supported + + {Peripherals::PE_ADC3, {DMAStreamId::DMA2_Str0, Channel::CHANNEL2}}, + {Peripherals::PE_ADC3, {DMAStreamId::DMA2_Str1, Channel::CHANNEL2}}, + + // {Peripherals::PE_SAI1_A, {DMAStreamId::DMA2_Str1, + // Channel::CHANNEL0}}, // available on STM32F42xxx and STM32F43xxx only + // {Peripherals::PE_SAI1_A, {DMAStreamId::DMA2_Str3, + // Channel::CHANNEL0}}, // available on STM32F42xxx and STM32F43xxx only + + // {Peripherals::PE_SAI1_B, {DMAStreamId::DMA2_Str5, + // Channel::CHANNEL0}}, // available on STM32F42xxx and STM32F43xxx only + // {Peripherals::PE_SAI1_B, {DMAStreamId::DMA2_Str4, + // Channel::CHANNEL1}}, // available on STM32F42xxx and STM32F43xxx only + + {Peripherals::PE_DCMI, {DMAStreamId::DMA2_Str1, Channel::CHANNEL1}}, + {Peripherals::PE_DCMI, {DMAStreamId::DMA2_Str7, Channel::CHANNEL1}}, + + // {Peripherals::PE_SDIO, {DMAStreamId::DMA2_Str3, Channel::CHANNEL4}}, + // // Stream currently not supported + {Peripherals::PE_SDIO, {DMAStreamId::DMA2_Str6, Channel::CHANNEL4}}, + + {Peripherals::PE_CRYP_OUT, {DMAStreamId::DMA2_Str5, Channel::CHANNEL2}}, + {Peripherals::PE_CRYP_IN, {DMAStreamId::DMA2_Str6, Channel::CHANNEL2}}, + + {Peripherals::PE_HASH_IN, {DMAStreamId::DMA2_Str7, Channel::CHANNEL2}}, +}; + +} // namespace DMADefs + +} // namespace Boardcore \ No newline at end of file diff --git a/src/tests/drivers/test-dma-mem-to-mem.cpp b/src/tests/drivers/test-dma-mem-to-mem.cpp index f11549bcd..aa53a2b7f 100644 --- a/src/tests/drivers/test-dma-mem-to-mem.cpp +++ b/src/tests/drivers/test-dma-mem-to-mem.cpp @@ -29,12 +29,22 @@ using namespace miosix; using namespace Boardcore; -DMAStream &stream = DMADriver::instance().acquireStream(DMAStreamId::DMA2_Str0); - void printBuffer(uint8_t *buffer, size_t size); int main() { + // DMAStream* stream = + // DMADriver::instance().acquireStream(DMADefs::DMAStreamId::DMA2_Str0, + // DMADefs::Channel::CHANNEL0); + DMAStream *stream = DMADriver::instance().automaticAcquireStream( + DMADefs::Peripherals::PE_MEM_ONLY); + + if (stream == nullptr) + { + printf("Error, cannot allocate dma stream\n"); + return 0; + } + /** * In this test we want to copy a buffer1 into buffer2 with the DMA. */ @@ -59,11 +69,11 @@ int main() .dstIncrement = true, .enableTransferCompleteInterrupt = true, }; - stream.setup(trn); - stream.enable(); + stream->setup(trn); + stream->enable(); auto begin = std::chrono::steady_clock::now(); - stream.waitForTransferComplete(); + stream->waitForTransferComplete(); auto end = std::chrono::steady_clock::now(); printf("After:\n"); -- GitLab