diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b42b897f5c237d0e63701c1105c63b6cd954be4e..c64ce34f449c07c4ae8344ad2f956b9cff813bb3 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,12 +2,12 @@ "name": "Machine PM - Embedded Development", "dockerFile": "./Dockerfile", "settings": { - "terminal.integrated.shell.linux": "/bin/zsh" + "terminal.integrated.defaultProfile.linux": "zsh", }, "extensions": [ "asabil.meson", - "marus25.cortex-debug", - "ms-vscode.cpptools", + "marus25.cortex-debug@0.4.4", + "ms-vscode.cpptools@1.5.1", "xaver.clang-format", "visualstudioexptteam.vscodeintellicode", "mhutchie.git-graph", diff --git a/.vscode/launch.json b/.vscode/launch.json index 919f29b474e41f6286a0984b3ac13c0eaba6b8bc..2ae10e03536d6eaf911a7b394345994c360735a1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -45,6 +45,10 @@ { "label": "Extended Interrupt Sample", "value": "extended-interrupt" + }, + { + "label": "Dma Uart", + "value": "dma-uart" } ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 1a0d5689147877133796158dee48ffce1b24bfc1..6b208bfd8090650e81ab4d8fbb5a513074f6cfa8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,6 @@ { "editor.formatOnSave": true, "task.problemMatchers.neverPrompt": true, - "task.autoDetect": "off", "files.autoSave": "onFocusChange", "mesonbuild.buildFolder": "build", "search.exclude": { @@ -9,5 +8,5 @@ }, "[cpp]": { "editor.defaultFormatter": "xaver.clang-format" - }, + } } diff --git a/library/stm32f072xb/dma/abstract-dma/abstract-dma-init.hpp b/library/stm32f072xb/dma/abstract-dma/abstract-dma-init.hpp new file mode 100644 index 0000000000000000000000000000000000000000..22a65d0a4024a1511eade2b220d170697d515e2e --- /dev/null +++ b/library/stm32f072xb/dma/abstract-dma/abstract-dma-init.hpp @@ -0,0 +1,24 @@ +#ifndef ABSTRACT_DMA_INIT_H +#define ABSTRACT_DMA_INIT_H + +#include <variant> + +#include "dma-register.hpp" + +namespace stm32f072xb { + +struct AbstractDmaInit { + const DmaPeripheral peripheral; + const DmaDirection direction; + const DmaCircularMode circularMode; + const DmaMemoryIncrement memoryIncrement; + const DmaMemorySize memorySize; + const DmaPeripheralIncrement peripheralIncrement; + const DmaPeripheralSize peripheralSize; + const uint8_t* buffer; + const uint16_t bufferSize; +}; + +} // namespace stm32f072xb + +#endif diff --git a/library/stm32f072xb/dma/abstract-dma/abstract-dma.cpp b/library/stm32f072xb/dma/abstract-dma/abstract-dma.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ad0f160f04b1e6723d7d49bcdfb20be785513e01 --- /dev/null +++ b/library/stm32f072xb/dma/abstract-dma/abstract-dma.cpp @@ -0,0 +1,131 @@ +#include "abstract-dma.hpp" + +using namespace stm32f072xb; + +AbstractDma::AbstractDma(DMA_Channel_TypeDef* dmaChannel, AbstractDmaInit& dmaInit) + : _dmaChannel(dmaChannel), _dmaInit(dmaInit) { + if (!READ_BIT(RCC->AHBENR, RCC_AHBENR_DMAEN)) { + SET_BIT(RCC->AHBENR, RCC_AHBENR_DMAEN); + } + setupRegister(); +} + +AbstractDma::~AbstractDma() { + stop(); +} + +void AbstractDma::start() { + if (READ_BIT(_dmaChannel->CCR, DMA_CCR_EN)) { + stop(); + setNumberOfDataTransfer(_dmaInit.bufferSize); + } + SET_BIT(_dmaChannel->CCR, DMA_CCR_EN); +} + +void AbstractDma::stop() { + CLEAR_BIT(_dmaChannel->CCR, DMA_CCR_EN); +} + +void AbstractDma::setupRegister() { + WRITE_REG(_dmaChannel->CCR, 0); + setPeripheral(_dmaInit.peripheral); + setMemory(_dmaInit.buffer); + setNumberOfDataTransfer(_dmaInit.bufferSize); + setDirection(_dmaInit.direction); + setCircularMode(_dmaInit.circularMode); + setMemoryIncrement(_dmaInit.memoryIncrement); + setMemorySize(_dmaInit.memorySize); + setPeripheralIncrement(_dmaInit.peripheralIncrement); + setPeripheralSize(_dmaInit.peripheralSize); +} + +void AbstractDma::setPeripheral(DmaPeripheral peripheral) { + switch (peripheral) { + case DmaPeripheral::USART2_RX: + WRITE_REG(_dmaChannel->CPAR, (uint32_t)&USART2->RDR); + break; + case DmaPeripheral::USART2_TX: + WRITE_REG(_dmaChannel->CPAR, (uint32_t)&USART2->TDR); + break; + } +} + +void AbstractDma::setMemory(const uint8_t* buffer) { + WRITE_REG(_dmaChannel->CMAR, (uint32_t)(buffer)); +} + +void AbstractDma::setNumberOfDataTransfer(uint16_t numberOfDataTransfer) { + WRITE_REG(_dmaChannel->CNDTR, numberOfDataTransfer); +} + +void AbstractDma::setDirection(DmaDirection direction) { + switch (direction) { + case DmaDirection::MEMORY_TO_PERIPHERAL: + SET_BIT(_dmaChannel->CCR, DMA_CCR_DIR); + break; + case DmaDirection::PERIPHERAL_TO_MEMORY: + CLEAR_BIT(_dmaChannel->CCR, DMA_CCR_DIR); + break; + } +} + +void AbstractDma::setCircularMode(DmaCircularMode circularMode) { + switch (circularMode) { + case DmaCircularMode::ENABLE: + SET_BIT(_dmaChannel->CCR, DMA_CCR_CIRC); + break; + case DmaCircularMode::DISABLE: + CLEAR_BIT(_dmaChannel->CCR, DMA_CCR_CIRC); + break; + } +} + +void AbstractDma::setMemoryIncrement(DmaMemoryIncrement memoryIncrement) { + switch (memoryIncrement) { + case DmaMemoryIncrement::ENABLE: + SET_BIT(_dmaChannel->CCR, DMA_CCR_MINC); + break; + case DmaMemoryIncrement::DISABLE: + CLEAR_BIT(_dmaChannel->CCR, DMA_CCR_MINC); + break; + } +} + +void AbstractDma::setMemorySize(DmaMemorySize memorySize) { + switch (memorySize) { + case DmaMemorySize::BYTE: + CLEAR_BIT(_dmaChannel->CCR, DMA_CCR_MSIZE); + break; + case DmaMemorySize::HALF_WORD: + MODIFY_REG(_dmaChannel->CCR, DMA_CCR_PSIZE, DMA_CCR_MSIZE_0); + break; + case DmaMemorySize::WORD: + MODIFY_REG(_dmaChannel->CCR, DMA_CCR_PSIZE, DMA_CCR_MSIZE_1); + break; + } +} + +void AbstractDma::setPeripheralIncrement(DmaPeripheralIncrement peripheralIncrement) { + switch (peripheralIncrement) { + case DmaPeripheralIncrement::ENABLE: + SET_BIT(_dmaChannel->CCR, DMA_CCR_PINC); + break; + case DmaPeripheralIncrement::DISABLE: + CLEAR_BIT(_dmaChannel->CCR, DMA_CCR_PINC); + break; + } +} + +void AbstractDma::setPeripheralSize(DmaPeripheralSize peripheralSize) { + switch (peripheralSize) { + case DmaPeripheralSize::BYTE: + CLEAR_BIT(_dmaChannel->CCR, DMA_CCR_PSIZE); + break; + case DmaPeripheralSize::HALF_WORD: + MODIFY_REG(_dmaChannel->CCR, DMA_CCR_PSIZE, DMA_CCR_PSIZE_0); + break; + case DmaPeripheralSize::WORD: + MODIFY_REG(_dmaChannel->CCR, DMA_CCR_PSIZE, DMA_CCR_PSIZE_1); + break; + } +} diff --git a/library/stm32f072xb/dma/abstract-dma/abstract-dma.hpp b/library/stm32f072xb/dma/abstract-dma/abstract-dma.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1a60dd5248f1334280ff991842c4396b515cb501 --- /dev/null +++ b/library/stm32f072xb/dma/abstract-dma/abstract-dma.hpp @@ -0,0 +1,36 @@ +#ifndef ABSTRACT_DMA_H +#define ABSTRACT_DMA_H + +#include <stm32f0xx.h> +#include "abstract-dma-init.hpp" + +namespace stm32f072xb { + +class AbstractDma { + public: + AbstractDma(DMA_Channel_TypeDef* dmaChannel, AbstractDmaInit& dmaInit); + ~AbstractDma(); + void start(); + void stop(); + + protected: + void setupRegister(); + + private: + void setPeripheral(DmaPeripheral peripheral); + void setMemory(const uint8_t* buffer); + void setNumberOfDataTransfer(uint16_t numberOfDataTransfer); + void setDirection(DmaDirection direction); + void setCircularMode(DmaCircularMode circularMode); + void setMemoryIncrement(DmaMemoryIncrement memoryIncrement); + void setMemorySize(DmaMemorySize memorySize); + void setPeripheralIncrement(DmaPeripheralIncrement peripheralIncrement); + void setPeripheralSize(DmaPeripheralSize peripheralSize); + + DMA_Channel_TypeDef* _dmaChannel; + AbstractDmaInit& _dmaInit; +}; + +} // namespace stm32f072xb + +#endif diff --git a/library/stm32f072xb/dma/dma-register/dma-channel.hpp b/library/stm32f072xb/dma/dma-register/dma-channel.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0ff56fae873f866db7f518a040149a6f261bed9b --- /dev/null +++ b/library/stm32f072xb/dma/dma-register/dma-channel.hpp @@ -0,0 +1,7 @@ +#ifndef DMA_CHANNEL_H +#define DMA_CHANNEL_H + +namespace stm32f072xb { +enum class DmaChannel { CHANNEL1, CHANNEL2, CHANNEL3, CHANNEL4, CHANNEL5, CHANNEL6, CHANNEL7 }; +} +#endif diff --git a/library/stm32f072xb/dma/dma-register/dma-circular-mode.hpp b/library/stm32f072xb/dma/dma-register/dma-circular-mode.hpp new file mode 100644 index 0000000000000000000000000000000000000000..dcbd3a75fe6f477207d4f4394009ba6bc87a87d7 --- /dev/null +++ b/library/stm32f072xb/dma/dma-register/dma-circular-mode.hpp @@ -0,0 +1,7 @@ +#ifndef DMA_CIRCULAR_MODE_H +#define DMA_CIRCULAR_MODE_H + +namespace stm32f072xb { +enum class DmaCircularMode { DISABLE, ENABLE }; +} +#endif diff --git a/library/stm32f072xb/dma/dma-register/dma-direction.hpp b/library/stm32f072xb/dma/dma-register/dma-direction.hpp new file mode 100644 index 0000000000000000000000000000000000000000..aa64be887f467907599bfbf0476f0309e7ec2957 --- /dev/null +++ b/library/stm32f072xb/dma/dma-register/dma-direction.hpp @@ -0,0 +1,9 @@ +#ifndef DMA_DIRECTION_H +#define DMA_DIRECTION_H + +namespace stm32f072xb { +enum class DmaDirection { MEMORY_TO_PERIPHERAL, PERIPHERAL_TO_MEMORY }; + +} + +#endif diff --git a/library/stm32f072xb/dma/dma-register/dma-memory-increment.hpp b/library/stm32f072xb/dma/dma-register/dma-memory-increment.hpp new file mode 100644 index 0000000000000000000000000000000000000000..fee7f1c715fb42cc8138981f4115db7961418600 --- /dev/null +++ b/library/stm32f072xb/dma/dma-register/dma-memory-increment.hpp @@ -0,0 +1,10 @@ +#ifndef DMA_MEMORY_INCREMENT_H +#define DMA_MEMORY_INCREMENT_H + +namespace stm32f072xb { +enum class DmaMemoryIncrement { + DISABLE, + ENABLE, +}; +} +#endif diff --git a/library/stm32f072xb/dma/dma-register/dma-memory-size.hpp b/library/stm32f072xb/dma/dma-register/dma-memory-size.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8ed07e28ccaf3ade8c1c662d523f732cd821fa5f --- /dev/null +++ b/library/stm32f072xb/dma/dma-register/dma-memory-size.hpp @@ -0,0 +1,7 @@ +#ifndef DMA_MEMORY_SIZE_H +#define DMA_MEMORY_SIZE_H + +namespace stm32f072xb { +enum class DmaMemorySize { BYTE, HALF_WORD, WORD }; +} +#endif diff --git a/library/stm32f072xb/dma/dma-register/dma-peripheral-increment.hpp b/library/stm32f072xb/dma/dma-register/dma-peripheral-increment.hpp new file mode 100644 index 0000000000000000000000000000000000000000..66c04013152982b30b6680cb64774d3d14370bd9 --- /dev/null +++ b/library/stm32f072xb/dma/dma-register/dma-peripheral-increment.hpp @@ -0,0 +1,9 @@ +#ifndef DMA_PERIPHERAL_INCREMENT_H +#define DMA_PERIPHERAL_INCREMENT_H +namespace stm32f072xb { +enum class DmaPeripheralIncrement { + DISABLE, + ENABLE, +}; +} +#endif diff --git a/library/stm32f072xb/dma/dma-register/dma-peripheral-size.hpp b/library/stm32f072xb/dma/dma-register/dma-peripheral-size.hpp new file mode 100644 index 0000000000000000000000000000000000000000..00539a577faa58443c9495ecb7019076e870c812 --- /dev/null +++ b/library/stm32f072xb/dma/dma-register/dma-peripheral-size.hpp @@ -0,0 +1,11 @@ +#ifndef DMA_PERIPHERAL_SIZE_H +#define DMA_PERIPHERAL_SIZE_H + +namespace stm32f072xb { +enum class DmaPeripheralSize { + BYTE, + HALF_WORD, + WORD, +}; +} +#endif diff --git a/library/stm32f072xb/dma/dma-register/dma-peripheral.hpp b/library/stm32f072xb/dma/dma-register/dma-peripheral.hpp new file mode 100644 index 0000000000000000000000000000000000000000..059067de285866b79d4cdf7055fddb6773b4bb60 --- /dev/null +++ b/library/stm32f072xb/dma/dma-register/dma-peripheral.hpp @@ -0,0 +1,7 @@ +#ifndef DMA_PERIPHERAL_H +#define DMA_PERIPHERAL_H + +namespace stm32f072xb { +enum class DmaPeripheral { USART2_RX, USART2_TX }; +} +#endif diff --git a/library/stm32f072xb/dma/dma-register/dma-register.hpp b/library/stm32f072xb/dma/dma-register/dma-register.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c33279484aebc2af6bdf0790393afc1ef463c7aa --- /dev/null +++ b/library/stm32f072xb/dma/dma-register/dma-register.hpp @@ -0,0 +1,8 @@ +#include "dma-channel.hpp" +#include "dma-circular-mode.hpp" +#include "dma-direction.hpp" +#include "dma-memory-increment.hpp" +#include "dma-memory-size.hpp" +#include "dma-peripheral-increment.hpp" +#include "dma-peripheral-size.hpp" +#include "dma-peripheral.hpp" diff --git a/library/stm32f072xb/dma/dma.cpp b/library/stm32f072xb/dma/dma.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8c8b5ede33d4725f6ea6dfb6a664f4ebda99a1b5 --- /dev/null +++ b/library/stm32f072xb/dma/dma.cpp @@ -0,0 +1,15 @@ +#include "dma.hpp" + +using namespace stm32f072xb; + +Dma<DmaChannel::CHANNEL4, DmaPeripheral::USART2_TX>::Dma(AbstractDmaInit& dmaInit, + Uart<UartRegister::UART2, Port::A>& uart) + : AbstractDma(DMA1_Channel4, dmaInit) { + uart.enableDmaTransmission(); +} + +Dma<DmaChannel::CHANNEL5, DmaPeripheral::USART2_RX>::Dma(AbstractDmaInit& dmaInit, + Uart<UartRegister::UART2, Port::A>& uart) + : AbstractDma(DMA1_Channel5, dmaInit) { + uart.enableDmaReception(); +} diff --git a/library/stm32f072xb/dma/dma.hpp b/library/stm32f072xb/dma/dma.hpp new file mode 100644 index 0000000000000000000000000000000000000000..42ab955155c16dd4b0668d0ba1bcb4bc2b2b2792 --- /dev/null +++ b/library/stm32f072xb/dma/dma.hpp @@ -0,0 +1,28 @@ + +#ifndef DMA_H +#define DMA_H + +#include "abstract-dma.hpp" +#include "dma-register.hpp" +#include "stm32f072xb.h" +#include "uart.hpp" + +namespace stm32f072xb { + +template <DmaChannel T, DmaPeripheral P> +class Dma {}; + +template <> +class Dma<DmaChannel::CHANNEL4, DmaPeripheral::USART2_TX> : public AbstractDma { + public: + Dma(AbstractDmaInit& dmaInit, Uart<UartRegister::UART2, Port::A>& uart); +}; + +template <> +class Dma<DmaChannel::CHANNEL5, DmaPeripheral::USART2_RX> : public AbstractDma { + public: + Dma(AbstractDmaInit& dmaInit, Uart<UartRegister::UART2, Port::A>& uart); +}; + +} // namespace stm32f072xb +#endif diff --git a/library/stm32f072xb/gpio/abstract-gpio/abstract-gpio-init.hpp b/library/stm32f072xb/gpio/abstract-gpio/abstract-gpio-init.hpp index 01e45c2e04cb29ec4afdc8539545798e1b7556f6..9df7217bdd4a521b55ff667c4854923a5ddf3e89 100644 --- a/library/stm32f072xb/gpio/abstract-gpio/abstract-gpio-init.hpp +++ b/library/stm32f072xb/gpio/abstract-gpio/abstract-gpio-init.hpp @@ -1,8 +1,8 @@ -#include "gpio-register.hpp" - #ifndef ABSTRACT_GPIO_INIT_H #define ABSTRACT_GPIO_INIT_H +#include "gpio-register.hpp" + namespace stm32f072xb { struct AbstractGpioInit { diff --git a/library/stm32f072xb/meson.build b/library/stm32f072xb/meson.build index 783422d90e28d66864688e7e25f17c9e0ba4eb31..860bfb02485ec79dac1763ffe1ba662391c9995f 100644 --- a/library/stm32f072xb/meson.build +++ b/library/stm32f072xb/meson.build @@ -4,18 +4,22 @@ stm32f072xb_modules = [] stm32f072xb_includes = [] stm32f072xb_sources = [] -stm32f072xb_modules += ['gpio/abstract-gpio'] stm32f072xb_modules += ['gpio'] +stm32f072xb_modules += ['gpio/abstract-gpio'] stm32f072xb_modules += ['gpio/gpio-register'] stm32f072xb_modules += ['gpio/output-gpio'] stm32f072xb_modules += ['gpio/input-gpio'] stm32f072xb_modules += ['gpio/alternate-gpio'] stm32f072xb_modules += ['gpio/uart-gpio'] -stm32f072xb_modules += ['uart/abstract-uart'] stm32f072xb_modules += ['uart'] +stm32f072xb_modules += ['uart/abstract-uart'] stm32f072xb_modules += ['uart/uart-register'] +stm32f072xb_modules += ['dma'] +stm32f072xb_modules += ['dma/abstract-dma'] +stm32f072xb_modules += ['dma/dma-register'] + stm32f072xb_modules += ['basic-timer'] fs = import('fs') diff --git a/library/stm32f072xb/uart/abstract-uart/abstract-uart.cpp b/library/stm32f072xb/uart/abstract-uart/abstract-uart.cpp index bfa38aa3011de404e76b3f8305ebe92dc98e3780..5c65adb9715d0e679779355a6d72d9175a62f1c0 100644 --- a/library/stm32f072xb/uart/abstract-uart/abstract-uart.cpp +++ b/library/stm32f072xb/uart/abstract-uart/abstract-uart.cpp @@ -89,3 +89,11 @@ void AbstractUart::enableTransmitter() { void AbstractUart::enableReception() { SET_BIT(_uart->CR1, USART_CR1_RE); // enable Reception (p.734) } + +void AbstractUart::enableDmaReception() { + SET_BIT(USART2->CR3, USART_CR3_DMAR); +} + +void AbstractUart::enableDmaTransmission() { + SET_BIT(USART2->CR3, USART_CR3_DMAT); +} diff --git a/library/stm32f072xb/uart/abstract-uart/abstract-uart.hpp b/library/stm32f072xb/uart/abstract-uart/abstract-uart.hpp index bc50990ecb16cad36cf4d579495328161c80d0ba..4ea79ca63a2fdcf4ae2050e1b638259071196c92 100644 --- a/library/stm32f072xb/uart/abstract-uart/abstract-uart.hpp +++ b/library/stm32f072xb/uart/abstract-uart/abstract-uart.hpp @@ -8,12 +8,14 @@ namespace stm32f072xb { class AbstractUart { public: AbstractUart(USART_TypeDef* uart, AbstractUartInit uartInit); + ~AbstractUart(); USART_TypeDef* getUart() { return _uart; }; char readWord(); void writeWord(uint16_t word); - ~AbstractUart(); + void enableDmaReception(); + void enableDmaTransmission(); protected: void setupRegister(); diff --git a/samples/meson.build b/samples/meson.build index 1ef686b5e36c27cc42e02544f78aca23b5c765bf..dc471f667b763acc70d6c6427c561b0a19989022 100644 --- a/samples/meson.build +++ b/samples/meson.build @@ -7,6 +7,7 @@ samples += ['gpio'] samples += ['interruption'] samples += ['pwm'] samples += ['extended-interrupt'] +samples += ['dma-uart'] # samples += ['timeout'] samples += ['uart'] diff --git a/samples/stm32f072xb/dma-uart/main.cpp b/samples/stm32f072xb/dma-uart/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..88978e119c8689867105ee0956abe711a13323a8 --- /dev/null +++ b/samples/stm32f072xb/dma-uart/main.cpp @@ -0,0 +1,65 @@ +#include <stm32f072xb.h> +#include <dma.hpp> +#include <gpio.hpp> +#include <uart-gpio.hpp> +#include <uart.hpp> + +using namespace stm32f072xb; + +AbstractUartInit uartInit = {WordLength::HEIGHT_BITS, StopBits::ONE_BIT, 115200}; +UartGpio<UartRegister::UART2, UartGpioType::RX, Port::A> rxGpio; +UartGpio<UartRegister::UART2, UartGpioType::TX, Port::A> txGpio; + +Uart<UartRegister::UART2, Port::A> uartTxRx(uartInit, txGpio, rxGpio); + +constexpr uint8_t bufferSize = 5; +uint8_t buffer[bufferSize] = {0}; + +AbstractDmaInit dmaUartRxInit = {DmaPeripheral::USART2_RX, + DmaDirection::PERIPHERAL_TO_MEMORY, + DmaCircularMode::ENABLE, + DmaMemoryIncrement::ENABLE, + DmaMemorySize::BYTE, + DmaPeripheralIncrement::DISABLE, + DmaPeripheralSize::BYTE, + buffer, + bufferSize}; +Dma<DmaChannel::CHANNEL5, DmaPeripheral::USART2_RX> dmaUartRx(dmaUartRxInit, uartTxRx); +AbstractDmaInit dmaUartTxInit = {DmaPeripheral::USART2_TX, + DmaDirection::MEMORY_TO_PERIPHERAL, + DmaCircularMode::DISABLE, + DmaMemoryIncrement::ENABLE, + DmaMemorySize::BYTE, + DmaPeripheralIncrement::DISABLE, + DmaPeripheralSize::BYTE, + buffer, + bufferSize}; + +Dma<DmaChannel::CHANNEL4, DmaPeripheral::USART2_TX> dmaUartTx(dmaUartTxInit, uartTxRx); + +extern "C" void DMA1_Channel4_5_6_7_IRQHandler() { + if (READ_BIT(DMA1->ISR, DMA_ISR_TEIF6)) { // DMA Error occured + SET_BIT(DMA1->IFCR, DMA_IFCR_CTEIF6); // Clear interrupt register + } + + if (READ_BIT(DMA1->ISR, DMA_ISR_TCIF5)) { + SET_BIT(DMA1->IFCR, DMA_IFCR_CTCIF5); + dmaUartTx.start(); + } +} + +void enableDmaChannel4_5_6_7Irq(); + +int main() { + SET_BIT(DMA1_Channel5->CCR, DMA_CCR_TCIE); + enableDmaChannel4_5_6_7Irq(); + dmaUartRx.start(); + + while (true) { + } +} + +void enableDmaChannel4_5_6_7Irq() { + NVIC_EnableIRQ(DMA1_Channel4_5_6_7_IRQn); + NVIC_SetPriority(DMA1_Channel4_5_6_7_IRQn, 0); +}