diff options
author | MrDimLis <mrlisdim@gmail.com> | 2019-06-03 18:26:28 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-03 18:26:28 +0300 |
commit | 806b2621f7163bd104a925173bcc3c446b32d3b6 (patch) | |
tree | 7c975035e0ff2d1aadc1e73a5e69ed8127de73b8 | |
parent | e5bbcc02fa5cef76e1a4dea13f8aae125f12a95a (diff) | |
parent | a4d3d266b2f8c9d331c16d8799514f0f2f7f408a (diff) |
Merge pull request #3 from thirdpin/feature/uart_dmarelease/v.2.1.0_04.06.2019
Added USART and DMA drivers
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | cm3cpp_dma.cpp | 117 | ||||
-rw-r--r-- | cm3cpp_dma.hpp | 156 |
3 files changed, 274 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 3780dfc..a740cc5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ target_sources(${PROJECT_NAME} INTERFACE ${CM3CPP_LOCATION}/cm3cpp_usart_rb.cpp ${CM3CPP_LOCATION}/cm3cpp_usart.cpp ${CM3CPP_LOCATION}/rs485.cpp + ${CM3CPP_LOCATION}/cm3cpp_dma.cpp ) target_include_directories(${PROJECT_NAME} diff --git a/cm3cpp_dma.cpp b/cm3cpp_dma.cpp new file mode 100644 index 0000000..5f7ed46 --- /dev/null +++ b/cm3cpp_dma.cpp @@ -0,0 +1,117 @@ +/** + ****************************************************************************** + * @file cm3cpp_dma + * @author + * @version V1.0 + * @date 05-2019 + * @brief This is file realise uart. + ****************************************************************************** + * @attention + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "cm3cpp_dma.hpp" + +// LIBOPENCM3 INCLUDES +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/cm3/scs.h> +#include <libopencm3/stm32/rcc.h> + +namespace cm3cpp { + +namespace dma { + +Dma::Dma(const LowLevelConfig& config) : + _dma_num(config.dma_num), + _stream(config.stream), + _irq(config.irq) +{ + // Enable clock DMA + if (_dma_num == DmaNumber::_1) { + rcc_periph_clock_enable(RCC_DMA1); + } + else { + rcc_periph_clock_enable(RCC_DMA2); + } + + // Reset channel + dma_stream_reset(_dma_num, _stream); + + // Config DMA + dma_set_priority(_dma_num, _stream, config.priority); + dma_set_memory_size(_dma_num, _stream, config.mem_size); + dma_set_peripheral_size(_dma_num, _stream, config.periph_size); + + if (config.periph_inc_mode == IncrementedMode::ENABLE) { + dma_enable_peripheral_increment_mode(_dma_num, _stream); + } + else { + dma_disable_peripheral_increment_mode(_dma_num, _stream); + } + + if (config.mem_inc_mode == IncrementedMode::ENABLE) { + dma_enable_memory_increment_mode(_dma_num, _stream); + } + else { + dma_disable_memory_increment_mode(_dma_num, _stream); + } + + if (config.mode == Mode::CIRCULAR) { + dma_enable_circular_mode(_dma_num, _stream); + } + + dma_set_transfer_mode(_dma_num, _stream, config.direction); + + dma_set_peripheral_address(_dma_num, _stream, config.peripheral_base_addr); + + dma_channel_select(_dma_num, _stream, config.channel); + + /// Configure interrupt + dma_enable_transfer_complete_interrupt(_dma_num, _stream); + enable_irq(); +} + +void Dma::set_memory_address(uint32_t address) const +{ + dma_set_memory_address(_dma_num, _stream, address); +} + +void Dma::set_data_counter(uint16_t len) const +{ + dma_set_number_of_data(_dma_num, _stream, len); +} + +void Dma::enable_stream() const +{ + dma_enable_stream(_dma_num, _stream); +} + +void Dma::disable_stream() const +{ + dma_disable_stream(_dma_num, _stream); +} + +void Dma::enable_irq() const +{ + nvic_enable_irq(_irq); +} + +void Dma::disable_irq() const +{ + nvic_disable_irq(_irq); +} + +bool Dma::get_interrupt_flag() const +{ + return dma_get_interrupt_flag(_dma_num, _stream, DMA_TCIF); +} + +void Dma::clear_interrupt_flag() const +{ + dma_clear_interrupt_flags(_dma_num, _stream, DMA_TCIF); +} + +} // namespace dma +} // namespace cm3cpp diff --git a/cm3cpp_dma.hpp b/cm3cpp_dma.hpp new file mode 100644 index 0000000..5f164a2 --- /dev/null +++ b/cm3cpp_dma.hpp @@ -0,0 +1,156 @@ +/** + ****************************************************************************** + * @file cm3cpp_dma.hpp + * @author + * @version V1.0 + * @date 05-2019 + * @brief This is file realise DMA. + ****************************************************************************** + * @attention + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#pragma once + +// LIBOPENCM3 INCLUDES +#include <libopencm3/stm32/dma.h> + +namespace cm3cpp { + +namespace dma { + +enum DmaNumber +{ + _1 = DMA1, + _2 = DMA2, +}; + +/// Streams for USARTs +enum Stream +{ + STREAM1 = DMA_STREAM1, + STREAM2 = DMA_STREAM2, + STREAM3 = DMA_STREAM3, + STREAM4 = DMA_STREAM4, + STREAM5 = DMA_STREAM5, + STREAM6 = DMA_STREAM6, + STREAM7 = DMA_STREAM7 +}; + +/// Channels for USARTs +enum Channel +{ + CHANNEL1 = DMA_SxCR_CHSEL_1, + CHANNEL2 = DMA_SxCR_CHSEL_2, + CHANNEL3 = DMA_SxCR_CHSEL_3, + CHANNEL4 = DMA_SxCR_CHSEL_4, + CHANNEL5 = DMA_SxCR_CHSEL_5, + CHANNEL6 = DMA_SxCR_CHSEL_6, + CHANNEL7 = DMA_SxCR_CHSEL_7 +}; + +enum DataTransferDirection +{ + MEM_TO_PERIPHERAL = DMA_SxCR_DIR_MEM_TO_PERIPHERAL, + PERIPHERAL_TO_MEM = DMA_SxCR_DIR_PERIPHERAL_TO_MEM, + MEM_TO_MEM = DMA_SxCR_DIR_MEM_TO_MEM +}; + +/// Shows where or where data will be sent, to the periphery or memory +enum class IncrementedMode +{ + DISABLE, + ENABLE +}; + +/// Shows how much the size will be increased for the periphery +enum DataSize +{ + PERIPHERAL_BYTE = DMA_SxCR_PSIZE_8BIT, + PERIPHERAL_HALF_WORD = DMA_SxCR_PSIZE_16BIT, + PERIPHERAL_WORD = DMA_SxCR_PSIZE_32BIT, + + MEMORY_BYTE = DMA_SxCR_MSIZE_8BIT, + MEMORY_HALF_WORD = DMA_SxCR_MSIZE_16BIT, + MEMORY_WORD = DMA_SxCR_MSIZE_32BIT, +}; + +/// DMA data recording mode, cyclic or normal +enum class Mode +{ + NORMAL, + CIRCULAR +}; + +/// The priorities of DMA +enum Priority +{ + LOW = DMA_SxCR_PL_LOW, + MEDIUM = DMA_SxCR_PL_MEDIUM, + HIGH = DMA_SxCR_PL_HIGH, + VERY_HIGH = DMA_SxCR_PL_VERY_HIGH +}; + +/// Low level config for DMA +struct LowLevelConfig +{ + DmaNumber dma_num; + Stream stream; + Channel channel; + uint32_t peripheral_base_addr; + DataTransferDirection direction; + IncrementedMode periph_inc_mode; + IncrementedMode mem_inc_mode; + DataSize periph_size; + DataSize mem_size; + Mode mode; + Priority priority; + uint8_t irq; +}; + +/** + * Class hard DMA + */ +class Dma +{ + public: + Dma(const LowLevelConfig& config); + + ~Dma() = default; + + bool get_interrupt_flag() const; + + void clear_interrupt_flag() const; + + void set_memory_address(uint32_t address) const; + + void enable_stream() const; + + void disable_stream() const; + + void set_data_counter(uint16_t len) const; + + void enable_irq() const; + + void disable_irq() const; + + protected: + Dma() = delete; /// Constructor default is delete + Dma(const Dma& a) = delete; /// Constructor copy is delete + Dma(Dma&& a) = delete; /// Constructor move is delete + + Dma& operator=(const Dma&) = delete; /// Operator copy is delete + Dma& operator=(Dma&&) = delete; /// Operator move is delete + + private: + Stream _stream; ///< Shows the stream on which DMA is configured + DmaNumber _dma_num; ///< Number configured DMA + + uint8_t _irq; ///< Interrupt number +}; + +} // namespace dma + +} // namespace cm3cpp // namespace cm3cpp |