Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/thirdpin/libopencm3_cpp_extensions.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMrDimLis <mrlisdim@gmail.com>2019-06-03 18:26:28 +0300
committerGitHub <noreply@github.com>2019-06-03 18:26:28 +0300
commit806b2621f7163bd104a925173bcc3c446b32d3b6 (patch)
tree7c975035e0ff2d1aadc1e73a5e69ed8127de73b8
parente5bbcc02fa5cef76e1a4dea13f8aae125f12a95a (diff)
parenta4d3d266b2f8c9d331c16d8799514f0f2f7f408a (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.txt1
-rw-r--r--cm3cpp_dma.cpp117
-rw-r--r--cm3cpp_dma.hpp156
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