This is an automated email from the ASF dual-hosted git repository.

jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit 5bb45700b36bc8ac9e52677dcf6ced4118f0e1ce
Author: Jerzy Kasenberg <jerzy.kasenb...@codecoup.pl>
AuthorDate: Tue Jan 26 15:24:26 2021 +0100

    mcu/stm: Add DMA allocation schema API
    
    API for using ST HAL DMA functionality.
    It allows to safely share DMA channels/streams.
    
    All ST HAL uses same style functions for accessing
    peripherals. This adds allocate/release functionality.
    It also provides DMA interrupt handlers that will
    call ST HAL handlers with currently allocated for channel
    peripheral.
---
 .../stm32_common/include/stm32_common/stm32_dma.h  | 106 ++++++++
 hw/mcu/stm/stm32_common/src/stm32_dma.c            | 279 +++++++++++++++++++++
 2 files changed, 385 insertions(+)

diff --git a/hw/mcu/stm/stm32_common/include/stm32_common/stm32_dma.h 
b/hw/mcu/stm/stm32_common/include/stm32_common/stm32_dma.h
new file mode 100644
index 0000000..2386a9f
--- /dev/null
+++ b/hw/mcu/stm/stm32_common/include/stm32_common/stm32_dma.h
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __STM32_DMA_H_
+#define __STM32_DMA_H_
+
+#include <stm32_common/stm32_hal.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Enum for DMA channel.
+ * For F0, F1, F3, L0, L1, L4, WB it represents channel
+ * For F4, F7 it represents stream (because channel has other meaning).
+ */
+typedef enum {
+    DMA1_CH0,
+    DMA1_CH1,
+    DMA1_CH2,
+    DMA1_CH3,
+    DMA1_CH4,
+    DMA1_CH5,
+    DMA1_CH6,
+    DMA1_CH7,
+    DMA2_CH0,
+    DMA2_CH1,
+    DMA2_CH2,
+    DMA2_CH3,
+    DMA2_CH4,
+    DMA2_CH5,
+    DMA2_CH6,
+    DMA2_CH7,
+    DMA_CH_NUM,
+} stm32_dma_ch_t;
+
+/**
+ * Allocate DMA channel for specific ST DMA handle.
+ *
+ * Function assigns DMA handle to DMA channel.
+ * This handle is later used in interrupt handlers.
+ *
+ * @param ch    DMA channel id
+ * @param hdma  DMA handle to assign to channel
+ * @return SYS_EBUSY - when channel is already allocated
+ *         SYS_EOK - on success
+ */
+int stm32_dma_acquire_channel(stm32_dma_ch_t ch, DMA_HandleTypeDef *hdma);
+
+/**
+ * Release DMA channel.
+ *
+ * @param ch    DMA channel that was allocated with stm32_dma_acquire_channel()
+ *
+ * @return  SYS_EOK on success
+ *          SYS_EINVAL if channel was not previously allocated
+ */
+int stm32_dma_release_channel(stm32_dma_ch_t ch);
+
+/*
+ * Functions that can be used as interrupt handlers that redirect
+ * code execution to ST HAL drivers.
+ */
+void stm32_dma1_0_irq_handler(void);
+void stm32_dma1_1_irq_handler(void);
+void stm32_dma1_2_irq_handler(void);
+void stm32_dma1_3_irq_handler(void);
+void stm32_dma1_4_irq_handler(void);
+void stm32_dma1_5_irq_handler(void);
+void stm32_dma1_6_irq_handler(void);
+void stm32_dma1_7_irq_handler(void);
+void stm32_dma2_0_irq_handler(void);
+void stm32_dma2_1_irq_handler(void);
+void stm32_dma2_2_irq_handler(void);
+void stm32_dma2_3_irq_handler(void);
+void stm32_dma2_4_irq_handler(void);
+void stm32_dma2_5_irq_handler(void);
+void stm32_dma2_6_irq_handler(void);
+void stm32_dma2_7_irq_handler(void);
+
+/* F0 and L0 can have common vector for several DMA channels */
+void stm32_dma1_2_3_irq_handler(void);
+void stm32_dma1_4_5_6_7_irq_handler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32_DMA_H_ */
diff --git a/hw/mcu/stm/stm32_common/src/stm32_dma.c 
b/hw/mcu/stm/stm32_common/src/stm32_dma.c
new file mode 100644
index 0000000..b2ab923
--- /dev/null
+++ b/hw/mcu/stm/stm32_common/src/stm32_dma.c
@@ -0,0 +1,279 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+#include <os/os_trace_api.h>
+#include <stm32_common/stm32_dma.h>
+#include <defs/error.h>
+
+#ifdef DMA2
+DMA_HandleTypeDef *stm32_dma_ch[16];
+#else
+DMA_HandleTypeDef *stm32_dma_ch[8];
+#endif
+
+int
+stm32_dma_acquire_channel(stm32_dma_ch_t ch, DMA_HandleTypeDef *hdma)
+{
+    int rc = SYS_EBUSY;
+    int sr;
+
+    OS_ENTER_CRITICAL(sr);
+
+    if (ch <= DMA_CH_NUM && stm32_dma_ch[ch] == NULL) {
+        stm32_dma_ch[ch] = hdma;
+        rc = SYS_EOK;
+    }
+
+    OS_EXIT_CRITICAL(sr);
+
+    return rc;
+}
+
+int
+stm32_dma_release_channel(stm32_dma_ch_t ch)
+{
+    int rc = SYS_EINVAL;
+    int sr;
+
+    OS_ENTER_CRITICAL(sr);
+
+    if (stm32_dma_ch[ch]) {
+        stm32_dma_ch[ch] = NULL;
+        rc = SYS_EOK;
+    }
+    OS_EXIT_CRITICAL(sr);
+
+    return rc;
+}
+
+void
+stm32_dma1_0_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    HAL_DMA_IRQHandler(stm32_dma_ch[DMA1_CH0]);
+
+    os_trace_isr_exit();
+}
+
+void
+stm32_dma1_1_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    HAL_DMA_IRQHandler(stm32_dma_ch[DMA1_CH1]);
+
+    os_trace_isr_exit();
+}
+
+void
+stm32_dma1_2_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    HAL_DMA_IRQHandler(stm32_dma_ch[DMA1_CH2]);
+
+    os_trace_isr_exit();
+}
+
+void
+stm32_dma1_3_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    HAL_DMA_IRQHandler(stm32_dma_ch[DMA1_CH3]);
+
+    os_trace_isr_exit();
+}
+
+void
+stm32_dma1_4_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    HAL_DMA_IRQHandler(stm32_dma_ch[DMA1_CH4]);
+
+    os_trace_isr_exit();
+}
+
+void
+stm32_dma1_5_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    HAL_DMA_IRQHandler(stm32_dma_ch[DMA1_CH5]);
+
+    os_trace_isr_exit();
+}
+
+void
+stm32_dma1_6_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    HAL_DMA_IRQHandler(stm32_dma_ch[DMA1_CH6]);
+
+    os_trace_isr_exit();
+}
+
+void
+stm32_dma1_7_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    HAL_DMA_IRQHandler(stm32_dma_ch[DMA1_CH7]);
+
+    os_trace_isr_exit();
+}
+
+#ifdef DMA2
+
+void
+stm32_dma2_0_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    HAL_DMA_IRQHandler(stm32_dma_ch[DMA2_CH0]);
+
+    os_trace_isr_exit();
+}
+
+void
+stm32_dma2_1_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    HAL_DMA_IRQHandler(stm32_dma_ch[DMA2_CH1]);
+
+    os_trace_isr_exit();
+}
+
+void
+stm32_dma2_2_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    HAL_DMA_IRQHandler(stm32_dma_ch[DMA2_CH2]);
+
+    os_trace_isr_exit();
+}
+
+void
+stm32_dma2_3_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    HAL_DMA_IRQHandler(stm32_dma_ch[DMA2_CH3]);
+
+    os_trace_isr_exit();
+}
+
+void
+stm32_dma2_4_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    HAL_DMA_IRQHandler(stm32_dma_ch[DMA2_CH4]);
+
+    os_trace_isr_exit();
+}
+
+void
+stm32_dma2_5_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    HAL_DMA_IRQHandler(stm32_dma_ch[DMA2_CH5]);
+
+    os_trace_isr_exit();
+}
+
+void
+stm32_dma2_6_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    HAL_DMA_IRQHandler(stm32_dma_ch[DMA2_CH6]);
+
+    os_trace_isr_exit();
+}
+
+void
+stm32_dma2_7_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    HAL_DMA_IRQHandler(stm32_dma_ch[DMA2_CH7]);
+
+    os_trace_isr_exit();
+}
+
+#endif
+
+/*
+ * Next two handlers are used by F0 and L0 devices that have shared interrupt 
for
+ * several channels.
+ */
+void
+stm32_dma1_2_3_irq_handler(void)
+{
+    os_trace_isr_enter();
+
+    if (stm32_dma_ch[DMA1_CH2]) {
+        HAL_DMA_IRQHandler(stm32_dma_ch[DMA1_CH2]);
+    }
+    if (stm32_dma_ch[DMA1_CH3]) {
+        HAL_DMA_IRQHandler(stm32_dma_ch[DMA1_CH3]);
+    }
+#ifdef DMA2
+    if (stm32_dma_ch[DMA2_CH1]) {
+        HAL_DMA_IRQHandler(stm32_dma_ch[DMA2_CH1]);
+    }
+    if (stm32_dma_ch[DMA2_CH2]) {
+        HAL_DMA_IRQHandler(stm32_dma_ch[DMA2_CH2]);
+    }
+#endif
+
+    os_trace_isr_exit();
+}
+
+void
+stm32_dma1_4_5_6_7_irq_handler(void)
+{
+    stm32_dma_ch_t i;
+
+    os_trace_isr_enter();
+
+    for (i = DMA1_CH4; i <= DMA1_CH7; ++i) {
+        if (stm32_dma_ch[i]) {
+            HAL_DMA_IRQHandler(stm32_dma_ch[i]);
+        }
+    }
+#ifdef DMA2
+    for (i = DMA2_CH3; i <= DMA2_CH5; ++i) {
+        if (stm32_dma_ch[i]) {
+            HAL_DMA_IRQHandler(stm32_dma_ch[i]);
+        }
+    }
+#endif
+
+    os_trace_isr_exit();
+}
+

Reply via email to