stm32g0: add dmamux

DMAMUX peripheral is a dma request router/trigger, present on g0, wb, h7 and l4+.

Basically it allows to easily map peripheral requests to whatever dma channel we
want to use (similarily to the DMA_CSELR register, but without limitation) but,
it also also adds some clever dma request synchronization and even some dma request
generation logic via internal request generator "channels", allowing some requests
chaining, or triggering reqs from non dma capable peripherals.

nb: g0 only features 1 dmamux bloc, supports 7 irq and 4 generators, l4+ supports 13
dma channels and 3 generators and h7 has two dmamuxes, with support for the 15 dma
channels and 7 generators - so as much CxCR and RGxCR register - but they are bit
to bit compatible - excluding of course the sync/sig and dma requests id mappings.
btw, currently, request generator channels are defined in common header, but maybe
we should define them in device header ? or we dont care (like for dma channels,
only defined in dma_f24 but not for other devices ?).

See ST AN5224 for more information
This commit is contained in:
Guillaume Revaillot 2019-06-12 11:52:04 +02:00 committed by Guillaume Revaillot
parent b9f183bf1e
commit a34da53c30
5 changed files with 782 additions and 0 deletions

View File

@ -0,0 +1,214 @@
/** @addtogroup dmamux_defines
*
* @author @htmlonly © @endhtmlonly 2019
* Guillaume Revaillot <g.revaillot@gmail.com>
*
* @version 1.0.0
*
* LGPL License Terms @ref lgpl_license
*/
/*
* This file is part of the libopencm3 project.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/** @cond */
#if defined(LIBOPENCM3_DMAMUX_H)
/** @endcond */
#ifndef LIBOPENCM3_DMAMUX_COMMON_ALL_H
#define LIBOPENCM3_DMAMUX_COMMON_ALL_H
/**@{*/
#define DMAMUX_CxCR(dmamux_base, dma_channel) MMIO32((dmamux_base) + 0x04 * ((dma_channel) - 1))
#define DMAMUX1_CxCR(dma_channel) DMAMUX_CxCR(DMAMUX1, (dma_channel))
#define DMAMUX2_CxCR(dma_channel) DMAMUX_CxCR(DMAMUX2, (dma_channel))
#define DMAMUX_CSR(dmamux_base) MMIO32((dmamux_base) + 0x80)
#define DMAMUX1_CSR(dmamux_base) DMAMUX_CSR(DMAMUX1)
#define DMAMUX2_CSR(dmamux_base) DMAMUX_CSR(DMAMUX2)
#define DMAMUX_CFR(dmamux_base) MMIO32((dmamux_base) + 0x84)
#define DMAMUX1_CFR(dmamux_base) DMAMUX_CFR(DMAMUX1)
#define DMAMUX2_CFR(dmamux_base) DMAMUX_CFR(DMAMUX2)
#define DMAMUX_RGxCR(dmamux_base, rg_channel) MMIO32((dmamux_base) + 0x100 + 0x04 * ((rg_channel) - 1))
#define DMAMUX1_RGxCR(dmamux_base, rg_channel) DMAMUX_RGxCR(DMAMUX1, (rg_channel))
#define DMAMUX2_RGxCR(dmamux_base, rg_channel) DMAMUX_RGxCR(DMAMUX2, (rg_channel))
#define DMAMUX_RGSR(dmamux_base) MMIO32((dmamux_base) + 0x140)
#define DMAMUX1_RGSR(dmamux_base) DMAMUX_RSGR(DMAMUX1)
#define DMAMUX2_RGSR(dmamux_base) DMAMUX_RSGR(DMAMUX2)
#define DMAMUX_RGCFR(dmamux_base) MMIO32((dmamux_base) + 0x144)
#define DMAMUX1_RGCFR(dmamux_base) DMAMUX_RGCFR(DMAMUX1)
#define DMAMUX2_RGCFR(dmamux_base) DMAMUX_RGCFR(DMAMUX2)
/** @defgroup dmamux_cxcr CxCR DMA request line multiplexer channel x control register
@{*/
/** DMAMUX_CxCR_SYNC_ID Synchronization input selected */
#define DMAMUX_CxCR_SYNC_ID_SHIFT 24
#define DMAMUX_CxCR_SYNC_ID_MASK 0x1f
/** DMAMUX_CxCR_NBREQ Number (minus 1) of DMA requests to forward */
#define DMAMUX_CxCR_NBREQ_SHIFT 19
#define DMAMUX_CxCR_NBREQ_MASK 0x1f
#define DMAMUX_CxCR_SPOL_SHIFT 17
#define DMAMUX_CxCR_SPOL_MASK 0x03
/** @defgroup dmamux_cxcr_spol SPOL Event Polarity
* @brief Synchronization event type selector
@{*/
#define DMAMUX_CxCR_SPOL_NO_EVENT 0
#define DMAMUX_CxCR_SPOL_RISING_EDGE 1
#define DMAMUX_CxCR_SPOL_FALLING_EDEG 2
#define DMAMUX_CxCR_SPOL_BOTH_EDGES 3
/**@}*/
/** DMAMUX_CxCR_SE Synchronous operating mode enable/disable */
#define DMAMUX_CxCR_SE (1 << 16)
/** DMAMUX_CxCR_EGE Event generation enable/disable */
#define DMAMUX_CxCR_EGE (1 << 9)
/** DMAMUX_CxCR_SOIE Interrupt enable at synchronization event overrun */
#define DMAMUX_CxCR_SOIE (1 << 8)
/** DMAMUX_CxCR_DMAREQ_ID Input DMA request line selected */
#define DMAMUX_CxCR_DMAREQ_ID_SHIFT 0
#define DMAMUX_CxCR_DMAREQ_ID_MASK 0xff
/**@}*/
/** @defgroup dmamux_csr CSR request line multiplexer interrupt channel status register
@{*/
/** DMAMUX_CSR_SOF Synchronization overrun event flag */
#define DMAMUX_CSR_SOF(dma_channel) (1 << ((dma_channel) - 1))
/**@}*/
/** @defgroup dmamux_cfr CFR request line multiplexer interrupt clear flag register
@{*/
/** DMAMUX_CFR_CSOF Clear synchronization overrun event flag */
#define DMAMUX_CFR_CSOF(dma_channel) (1 << ((dma_channel) - 1))
/**@}*/
/** @defgroup dmamux_rgxcr RGxCR DMA request generator channel x control register
@{*/
/** DMAMUX_RGxCR_GNBREQ GNBREQ Number (minus 1) of DMA requests to generate */
#define DMAMUX_RGxCR_GNBREQ_SHIFT 19
#define DMAMUX_RGxCR_GNBREQ_MASK 0x1f
#define DMAMUX_RGxCR_GPOL_SHIFT 17
#define DMAMUX_RGxCR_GPOL_MASK 0x03
/** @defgroup dmamux_rgxcr_gpol GPOL Event Polarity
* @brief DMA request generator trigger event type selection
@{*/
#define DMAMUX_RGxCR_GPOL_NO_EVENT 0
#define DMAMUX_RGxCR_GPOL_RISING_EDGE 1
#define DMAMUX_RGxCR_GPOL_FALLING_EDEG 2
#define DMAMUX_RGxCR_GPOL_BOTH_EDGES 3
/**@}*/
/** DMAMUX_RGxCR_GE GE DMA request generator channel enable/disable */
#define DMAMUX_RGxCR_GE (1 << 16)
/** DMAMUX_RGxCR_OIE OIE Interrupt enable at trigger event overrun */
#define DMAMUX_RGxCR_OIE (1 << 8)
/** DMAMUX_RGxCR_SIG_ID SIG_ID DMA request trigger input selected */
#define DMAMUX_RGxCR_SIG_ID_SHIFT 0
#define DMAMUX_RGxCR_SIG_ID_MASK 0x1f
/**@}*/
/** @defgroup dmamux_rgsr RGSR DMA request generator interrupt status register
@{*/
/** DMAMUX_RGSR_OF Trigger OF event overrun flag */
#define DMAMUX_RGSR_OF(rg_channel) (1 << ((rg_channel) - 1))
/**@}*/
/** @defgroup dmamux_rgcfr RGCFR DMA request generator clear flag register
@{*/
/** DMAMUX_RGCFR_COF COF Clear trigger event overrun flag */
#define DMAMUX_RGCFR_COF(rg_channel) (1 << ((rg_channel) - 1))
/**@}*/
/* --- Generic values ---------------------------------------- */
/** @defgroup dmamux_rg_channel DMAMUX Request Generator Channel Number
@{*/
#define DMAMUX_RG_CHANNEL1 1
#define DMAMUX_RG_CHANNEL2 2
#define DMAMUX_RG_CHANNEL3 3
#define DMAMUX_RG_CHANNEL4 4
/**@}*/
/* --- function prototypes ------------------------------------------------- */
BEGIN_DECLS
void dmamux_reset_dma_channel(uint32_t dmamux, uint8_t channel);
void dmamux_enable_dma_request_event_generation(uint32_t dmamux, uint8_t channel);
void dmamux_disable_dma_request_event_generation(uint32_t dmamux, uint8_t channel);
void dmamux_set_dma_channel_request(uint32_t dmamux, uint8_t channel, uint8_t request_id);
uint8_t dmamux_get_dma_channel_request(uint32_t dmamux, uint8_t channel);
void dmamux_enable_dma_request_sync(uint32_t dmamux, uint8_t channel);
void dmamux_disable_dma_request_sync(uint32_t dmamux, uint8_t channel);
void dmamux_set_dma_request_sync_input(uint32_t dmamux, uint8_t channel, uint8_t sync_id);
void dmamux_set_dma_request_sync_pol(uint32_t dmamux, uint8_t channel, uint8_t polarity);
void dmamux_set_dma_request_sync_nbreq(uint32_t dmamux, uint8_t channel, uint8_t nbreq);
void dmamux_enable_dma_request_sync_overrun_interrupt(uint32_t dmamux, uint8_t channel);
void dmamux_disable_dma_request_sync_overrun_interrupt(uint32_t dmamux, uint8_t channel);
uint32_t dmamux_get_dma_request_sync_overrun(uint32_t dmamux, uint8_t channel);
void dmamux_clear_dma_request_sync_overrun(uint32_t dmamux, uint8_t channel);
void dmamux_reset_request_generator_channel(uint32_t dmamux, uint8_t rg_channel);
void dmamux_enable_request_generator(uint32_t dmamux, uint8_t rg_channel);
void dmamux_disable_request_generator(uint32_t dmamux, uint8_t rg_channel);
void dmamux_set_request_generator_trigger(uint32_t dmamux, uint8_t rg_channel, uint8_t sig_id);
void dmamux_set_request_generator_trigger_pol(uint32_t dmamux, uint8_t rg_channel, uint8_t polarity);
void dmamux_set_request_generator_trigger_gnbreq(uint32_t dmamux, uint8_t rg_channel, uint8_t gnbreq);
void dmamux_enable_request_generator_trigger_overrun_interrupt(uint32_t dmamux, uint8_t rg_channel);
void dmamux_disable_request_generator_trigger_overrun_interrupt(uint32_t dmamux, uint8_t rg_channel);
uint32_t dmamux_get_request_generator_trigger_overrun_interrupt(uint32_t dmamux, uint8_t rg_channel);
void dmamux_clear_request_generator_trigger_overrun_interrupt(uint32_t dmamux, uint8_t rg_channel);
END_DECLS
/**@}*/
#endif
/** @cond */
#else
#warning "dmamux_common_all.h should not be included explicitly, only via dmamux.h"
#endif
/** @endcond */

View File

@ -0,0 +1,28 @@
/* This provides unification of code over STM32 subfamilies */
/*
* This file is part of the libopencm3 project.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/cm3/common.h>
#include <libopencm3/stm32/memorymap.h>
#if defined(STM32G0)
# include <libopencm3/stm32/g0/dmamux.h>
#else
# error "stm32 family not defined."
#endif

View File

@ -0,0 +1,172 @@
/** @defgroup dmamux_defines DMAMUX Defines
*
* @ingroup STM32G0xx_defines
*
* @author @htmlonly &copy; @endhtmlonly 2019
* Guillaume Revaillot <g.revaillot@gmail.com>
*
* @brief Defined Constants and Types for the STM32G0xx DMAMUX DMA request router
*
* @version 1.0.0
*
* LGPL License Terms @ref lgpl_license
*/
/*
* This file is part of the libopencm3 project.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LIBOPENCM3_DMAMUX_H
#define LIBOPENCM3_DMAMUX_H
/**@{*/
#include <libopencm3/stm32/common/dmamux_common_all.h>
/** @defgroup dmamux_reg_base DMAMUX register base addresses
* @{
*/
#define DMAMUX1 DMAMUX_BASE
/**@}*/
/* --- DMAMUX_CxCR values ------------------------------------ */
/** @defgroup dmamux_cxcr_sync_id SYNCID Synchronization input selected
@{*/
#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE0 0
#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE1 1
#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE2 2
#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE3 3
#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE4 4
#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE5 5
#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE6 6
#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE7 7
#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE8 8
#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE9 9
#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE10 10
#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE11 11
#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE12 12
#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE13 13
#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE14 14
#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE15 15
#define DMAMUX_CxCR_SYNC_ID_DMAMUX_EVT0 16
#define DMAMUX_CxCR_SYNC_ID_DMAMUX_EVT1 17
#define DMAMUX_CxCR_SYNC_ID_DMAMUX_EVT2 18
#define DMAMUX_CxCR_SYNC_ID_DMAMUX_EVT3 19
#define DMAMUX_CxCR_SYNC_ID_LPTIM1_OUT 20
#define DMAMUX_CxCR_SYNC_ID_LPTIM2_OUT 21
#define DMAMUX_CxCR_SYNC_ID_TIM14_OC 22
#define DMAMUX_CxCR_SYNC_ID_RESERVED23 23
/**@}*/
/** @defgroup dmamux_cxcr_dmareq_id DMAREQID DMA request line selected
@{*/
#define DMAMUX_CxCR_DMAREQ_ID_DMAMUX_REQ_GEN0 1
#define DMAMUX_CxCR_DMAREQ_ID_DMAMUX_REQ_GEN1 2
#define DMAMUX_CxCR_DMAREQ_ID_DMAMUX_REQ_GEN2 3
#define DMAMUX_CxCR_DMAREQ_ID_DMAMUX_REQ_GEN3 4
#define DMAMUX_CxCR_DMAREQ_ID_ADC 5
#define DMAMUX_CxCR_DMAREQ_ID_AES_IN 6
#define DMAMUX_CxCR_DMAREQ_ID_AES_OUT 7
#define DMAMUX_CxCR_DMAREQ_ID_DAC_Channel1 8
#define DMAMUX_CxCR_DMAREQ_ID_DAC_Channel2 9
#define DMAMUX_CxCR_DMAREQ_ID_I2C1_RX 10
#define DMAMUX_CxCR_DMAREQ_ID_I2C1_TX 11
#define DMAMUX_CxCR_DMAREQ_ID_I2C2_RX 12
#define DMAMUX_CxCR_DMAREQ_ID_I2C2_TX 13
#define DMAMUX_CxCR_DMAREQ_ID_LPUART_RX 14
#define DMAMUX_CxCR_DMAREQ_ID_LPUART_TX 15
#define DMAMUX_CxCR_DMAREQ_ID_SPI1_RX 16
#define DMAMUX_CxCR_DMAREQ_ID_SPI1_TX 17
#define DMAMUX_CxCR_DMAREQ_ID_SPI2_RX 18
#define DMAMUX_CxCR_DMAREQ_ID_SPI2_TX 19
#define DMAMUX_CxCR_DMAREQ_ID_TIM1_CH1 20
#define DMAMUX_CxCR_DMAREQ_ID_TIM1_CH2 21
#define DMAMUX_CxCR_DMAREQ_ID_TIM1_CH3 22
#define DMAMUX_CxCR_DMAREQ_ID_TIM1_CH4 23
#define DMAMUX_CxCR_DMAREQ_ID_TIM1_TRIG_COM 24
#define DMAMUX_CxCR_DMAREQ_ID_TIM1_UP 25
#define DMAMUX_CxCR_DMAREQ_ID_TIM2_CH1 26
#define DMAMUX_CxCR_DMAREQ_ID_TIM2_CH2 27
#define DMAMUX_CxCR_DMAREQ_ID_TIM2_CH3 28
#define DMAMUX_CxCR_DMAREQ_ID_TIM2_CH4 29
#define DMAMUX_CxCR_DMAREQ_ID_TIM2_TRIG 30
#define DMAMUX_CxCR_DMAREQ_ID_TIM2_UP 31
#define DMAMUX_CxCR_DMAREQ_ID_TIM3_CH1 32
#define DMAMUX_CxCR_DMAREQ_ID_TIM3_CH2 33
#define DMAMUX_CxCR_DMAREQ_ID_TIM3_CH3 34
#define DMAMUX_CxCR_DMAREQ_ID_TIM3_CH4 35
#define DMAMUX_CxCR_DMAREQ_ID_TIM3_TRIG 36
#define DMAMUX_CxCR_DMAREQ_ID_TIM3_UP 37
#define DMAMUX_CxCR_DMAREQ_ID_TIM6_UP 38
#define DMAMUX_CxCR_DMAREQ_ID_TIM7_UP 39
#define DMAMUX_CxCR_DMAREQ_ID_TIM15_CH1 40
#define DMAMUX_CxCR_DMAREQ_ID_TIM15_CH2 41
#define DMAMUX_CxCR_DMAREQ_ID_TIM15_TRIG_COM 42
#define DMAMUX_CxCR_DMAREQ_ID_TIM15_UP 43
#define DMAMUX_CxCR_DMAREQ_ID_TIM16_CH1 44
#define DMAMUX_CxCR_DMAREQ_ID_TIM16_TRIG_COM 45
#define DMAMUX_CxCR_DMAREQ_ID_TIM16_UP 46
#define DMAMUX_CxCR_DMAREQ_ID_TIM17_CH1 47
#define DMAMUX_CxCR_DMAREQ_ID_TIM17_TRIG_COM 48
#define DMAMUX_CxCR_DMAREQ_ID_TIM17_UP 49
#define DMAMUX_CxCR_DMAREQ_ID_USART1_RX 50
#define DMAMUX_CxCR_DMAREQ_ID_USART1_TX 51
#define DMAMUX_CxCR_DMAREQ_ID_USART2_RX 52
#define DMAMUX_CxCR_DMAREQ_ID_USART2_TX 53
#define DMAMUX_CxCR_DMAREQ_ID_USART3_RX 54
#define DMAMUX_CxCR_DMAREQ_ID_USART3_TX 55
#define DMAMUX_CxCR_DMAREQ_ID_USART4_RX 56
#define DMAMUX_CxCR_DMAREQ_ID_USART4_TX 57
#define DMAMUX_CxCR_DMAREQ_ID_UCPD1_RX 58
#define DMAMUX_CxCR_DMAREQ_ID_UCPD1_TX 59
#define DMAMUX_CxCR_DMAREQ_ID_UCPD2_RX 60
#define DMAMUX_CxCR_DMAREQ_ID_UCPD2_TX 61
#define DMAMUX_CxCR_DMAREQ_ID_RESERVED62 62
#define DMAMUX_CxCR_DMAREQ_ID_RESERVED63 63
/**@}*/
/* --- DMAMUX_RGxCR values ----------------------------------- */
/** @defgroup dmamux_rgxcr_sig_id SIGID DMA request trigger input selected
@{*/
#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE0 0
#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE1 1
#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE2 2
#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE3 3
#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE4 4
#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE5 5
#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE6 6
#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE7 7
#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE8 8
#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE9 9
#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE10 10
#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE11 11
#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE12 12
#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE13 13
#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE14 14
#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE15 15
#define DMAMUX_RGxCR_SIG_ID_DMAMUX_EVT0 16
#define DMAMUX_RGxCR_SIG_ID_DMAMUX_EVT1 17
#define DMAMUX_RGxCR_SIG_ID_DMAMUX_EVT2 18
#define DMAMUX_RGxCR_SIG_ID_DMAMUX_EVT3 19
#define DMAMUX_RGxCR_SIG_ID_LPTIM1_OUT 20
#define DMAMUX_RGxCR_SIG_ID_LPTIM2_OUT 21
#define DMAMUX_RGxCR_SIG_ID_TIM14_OC 22
#define DMAMUX_RGxCR_SIG_ID_RESERVED 23
/**@}*/
/**@}*/
#endif

367
lib/stm32/common/dmamux.c Normal file
View File

@ -0,0 +1,367 @@
/** @addtogroup dmamux_file DMAMUX peripheral API
@ingroup peripheral_apis
@author @htmlonly &copy; @endhtmlonly 2019 Guillaume Revaillot <g.revaillot@gmail.com>
LGPL License Terms @ref lgpl_license
*/
/*
* This file is part of the libopencm3 project.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/**@{*/
#include <libopencm3/stm32/dmamux.h>
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Reset DMA Channel
Reset DMA Request configuration and interrupt flags for given DMA channel.
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] channel DMA channel number (@ref dma_ch)
*/
void dmamux_reset_dma_channel(uint32_t dmamux, uint8_t channel)
{
DMAMUX_CxCR(dmamux, channel) = 0;
dmamux_clear_dma_request_sync_overrun(dmamux, channel);
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Set DMA Channel Request
Set DMA Request Signal ID (@ref dmamux_cxcr_dmareq_id) for given DMA channel.
Request must be set before enabling and after configuring said DMA channel.
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] channel DMA channel number (@ref dma_ch)
@param[in] request_id DMA request (@ref dmamux_cxcr_dmareq_id)
*/
void dmamux_set_dma_channel_request(uint32_t dmamux, uint8_t channel, uint8_t request_id)
{
uint32_t reg32 = DMAMUX_CxCR(dmamux, channel);
reg32 &= ~(DMAMUX_CxCR_DMAREQ_ID_MASK << DMAMUX_CxCR_DMAREQ_ID_SHIFT);
reg32 |= ((request_id & DMAMUX_CxCR_DMAREQ_ID_MASK) << DMAMUX_CxCR_DMAREQ_ID_SHIFT);
DMAMUX_CxCR(dmamux, channel) = reg32;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Get DMA Channel Request Selection
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] channel DMA channel number (@ref dma_ch)
@returns DMA request (@ref dmamux_cxcr_dmareq_id)
*/
uint8_t dmamux_get_dma_channel_request(uint32_t dmamux, uint8_t channel)
{
return (DMAMUX_CxCR(dmamux, channel) >> DMAMUX_CxCR_DMAREQ_ID_SHIFT) & DMAMUX_CxCR_DMAREQ_ID_MASK;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Enable DMA Request Event Generation
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] channel DMA channel number (@ref dma_ch)
*/
void dmamux_enable_dma_request_event_generation(uint32_t dmamux, uint8_t channel)
{
DMAMUX_CxCR(dmamux, channel) |= DMAMUX_CxCR_EGE;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Disable DMA Request Event Generation
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] channel DMA channel number (@ref dma_ch)
*/
void dmamux_disable_dma_request_event_generation(uint32_t dmamux, uint8_t channel)
{
DMAMUX_CxCR(dmamux, channel) &= ~DMAMUX_CxCR_EGE;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Set DMA Request Synchronization Input
Set DMAMUX request synchronization input trigger signal id (@ref dmamux_cxcr_sync_id)
for a given DMA channel.
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] channel DMA channel number (@ref dma_ch)
@param[in] sync_input_id synchronization signal input id (@ref dmamux_cxcr_sync_id)
*/
void dmamux_set_dma_request_sync_input(uint32_t dmamux, uint8_t channel, uint8_t sync_input_id)
{
uint32_t reg32 = DMAMUX_CxCR(dmamux, channel);
reg32 &= ~(DMAMUX_CxCR_SYNC_ID_MASK << DMAMUX_CxCR_SYNC_ID_SHIFT);
reg32 |= ((sync_input_id & DMAMUX_CxCR_SYNC_ID_MASK) << DMAMUX_CxCR_SYNC_ID_SHIFT);
DMAMUX_CxCR(dmamux, channel) = reg32;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Set DMA Request Synchronization Event Polarity
Set DMAMUX request synchronization input signal polarity (@ref dmamux_cxcr_spol)
for a given DMA channel.
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] channel DMA channel number (@ref dma_ch)
@param[in] polarity synchronization signal input polarity (@ref dmamux_cxcr_spol)
*/
void dmamux_set_dma_request_sync_pol(uint32_t dmamux, uint8_t channel, uint8_t polarity)
{
uint32_t reg32 = DMAMUX_CxCR(dmamux, channel);
reg32 &= ~(DMAMUX_CxCR_SPOL_MASK << DMAMUX_CxCR_SPOL_SHIFT);
reg32 |= ((polarity & DMAMUX_CxCR_SPOL_MASK) << DMAMUX_CxCR_SPOL_SHIFT);
DMAMUX_CxCR(dmamux, channel) = reg32;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Enable DMA Request Synchronization
Enable DMAMUX request synchronization for a given DMA channel, propagating DMA
request when configured event edge (DMAREQ_CxCR_SPOL) is detected on previously
selected synchronization trigger input id.
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] channel DMA channel number (@ref dma_ch)
*/
void dmamux_enable_dma_request_sync(uint32_t dmamux, uint8_t channel)
{
DMAMUX_CxCR(dmamux, channel) |= DMAMUX_CxCR_SE;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Disable DMA Request Synchronization
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] channel DMA channel number (@ref dma_ch)
*/
void dmamux_disable_dma_request_sync(uint32_t dmamux, uint8_t channel)
{
DMAMUX_CxCR(dmamux, channel) &= ~DMAMUX_CxCR_SE;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Set DMA Request NBREQ To Forward
Set number of request to forward (minus 1) to the dma controller after a synchronization
event. This must be configured with synchronization and event generation disabled.
@param[in] dmamux DMAMUX Controller base address (@ref dmamux_reg_base)
@param[in] channel DMA Channel Number (@ref dma_ch)
@param[in] nbreq Number of DMA Requests to Forward - minus 1 (0..31)
*/
void dmamux_set_dma_request_sync_nbreq(uint32_t dmamux, uint8_t channel, uint8_t nbreq)
{
uint32_t reg32 = DMAMUX_CxCR(dmamux, channel);
reg32 &= ~(DMAMUX_CxCR_NBREQ_MASK << DMAMUX_CxCR_NBREQ_SHIFT);
reg32 |= ((nbreq & DMAMUX_CxCR_NBREQ_MASK) << DMAMUX_CxCR_NBREQ_SHIFT);
DMAMUX_CxCR(dmamux, channel) = reg32;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Enable DMA Request Overrun Interrupt
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] channel DMA channel number (@ref dma_ch)
*/
void dmamux_enable_dma_request_sync_overrun_interrupt(uint32_t dmamux, uint8_t channel)
{
DMAMUX_CxCR(dmamux, channel) |= DMAMUX_CxCR_SOIE;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Disable DMA Request Overrun Interrupt
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] channel DMA channel number (@ref dma_ch)
*/
void dmamux_disable_dma_request_sync_overrun_interrupt(uint32_t dmamux, uint8_t channel)
{
DMAMUX_CxCR(dmamux, channel) &= ~DMAMUX_CxCR_SOIE;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Get DMA Request Synchronization Overrun Interrupt Flag
Get DMA Request Synchronization Overrun Interrupt for given DMA channel
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] channel DMA channel number (@ref dma_ch)
@returns DMA Channel Synchronization Overrun Interrupt Flag
*/
uint32_t dmamux_get_dma_request_sync_overrun(uint32_t dmamux, uint8_t channel)
{
return DMAMUX_CSR(dmamux) & DMAMUX_CSR_SOF(channel);
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Clear DMA Request Synchronization Overrun Interrupt Flag
Clear DMA Request Synchronization Overrun Interrupt for given DMA channel
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] channel DMA channel number (@ref dma_ch)
*/
void dmamux_clear_dma_request_sync_overrun(uint32_t dmamux, uint8_t channel)
{
DMAMUX_CFR(dmamux) = DMAMUX_CFR_CSOF(channel);
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Reset Request Generator Channel
Reset Request Generator Channel Configuration and interrupt flags.
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] rg_channel Request Generator Channel Number (@ref dmamux_rg_channel)
*/
void dmamux_reset_request_generator_channel(uint32_t dmamux, uint8_t rg_channel)
{
DMAMUX_CxCR(dmamux, rg_channel) = 0;
dmamux_clear_request_generator_trigger_overrun_interrupt(dmamux, rg_channel);
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Enable Request Generator Channel
Enable Request Generator Channel, Producting DMA Request on input signal trigger.
These Requests are usable by the DMA Request Router.
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] rg_channel Request Generator Channel Number (@ref dmamux_rg_channel)
*/
void dmamux_enable_request_generator(uint32_t dmamux, uint8_t rg_channel)
{
DMAMUX_RGxCR(dmamux, rg_channel) |= DMAMUX_RGxCR_GE;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Disable Request Generator Channel
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] rg_channel Request Generator Channel Number (@ref dmamux_rg_channel)
*/
void dmamux_disable_request_generator(uint32_t dmamux, uint8_t rg_channel)
{
DMAMUX_RGxCR(dmamux, rg_channel) &= ~DMAMUX_RGxCR_GE;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Set Request Generator Input Trigger Signal
Set DMAMUX Request Generator input signal id (@ref dmamux_rgxcr_sig_id) for given
Request Generator Channel.
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] rg_channel Request Generator Channel Number (@ref dmamux_rg_channel)
@param[in] sig_id Request Generator Channel Input Signal Id (@ref dmamux_rgxcr_sig_id)
*/
void dmamux_set_request_generator_trigger(uint32_t dmamux, uint8_t rg_channel, uint8_t sig_id)
{
uint32_t reg32 = DMAMUX_RGxCR(dmamux, rg_channel);
reg32 &= ~(DMAMUX_RGxCR_SIG_ID_MASK << DMAMUX_RGxCR_SIG_ID_SHIFT);
reg32 |= ((sig_id & DMAMUX_RGxCR_SIG_ID_MASK) << DMAMUX_RGxCR_SIG_ID_SHIFT);
DMAMUX_RGxCR(dmamux, rg_channel) = reg32;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Set Request Generator Trigger Polarity
Set DMAMUX Request Generator input signal polarity (@ref dmamux_rgxcr_gpol).
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] rg_channel Request Generator Channel Number (@ref dmamux_rg_channel)
@param[in] polarity Trigger signal input polarity (@ref dmamux_rgxcr_gpol)
*/
void dmamux_set_request_generator_trigger_pol(uint32_t dmamux, uint8_t rg_channel, uint8_t polarity)
{
uint32_t reg32 = DMAMUX_RGxCR(dmamux, rg_channel);
reg32 &= ~(DMAMUX_RGxCR_GPOL_MASK << DMAMUX_RGxCR_GPOL_SHIFT);
reg32 |= ((polarity & DMAMUX_RGxCR_GPOL_MASK) << DMAMUX_RGxCR_GPOL_SHIFT);
DMAMUX_RGxCR(dmamux, rg_channel) = reg32;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Set Request Generator Trigger GNBREQ
Set number of request to generate (minus 1). This must be configured while
given Request Generator is disabled.
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] rg_channel Request Generator Channel Number (@ref dmamux_rg_channel)
@param[in] gnbreq Number of DMA Requests to Generate - minus 1 (0..31).
*/
void dmamux_set_request_generator_trigger_gnbreq(uint32_t dmamux, uint8_t rg_channel, uint8_t gnbreq)
{
uint32_t reg32 = DMAMUX_RGxCR(dmamux, rg_channel);
reg32 &= ~(DMAMUX_RGxCR_GNBREQ_MASK << DMAMUX_RGxCR_GNBREQ_SHIFT);
reg32 |= ((gnbreq & DMAMUX_RGxCR_GNBREQ_MASK) << DMAMUX_RGxCR_GNBREQ_SHIFT);
DMAMUX_RGxCR(dmamux, rg_channel) = reg32;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Enable Request Generator Trigger Overrun Interrupt
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] rg_channel Request Generator Channel Number (@ref dmamux_rg_channel)
*/
void dmamux_enable_request_generator_trigger_overrun_interrupt(uint32_t dmamux, uint8_t rg_channel)
{
DMAMUX_RGxCR(dmamux, rg_channel) |= DMAMUX_RGxCR_OIE;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Disable Request Generator Trigger Overrun Interrupt
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] rg_channel Request Generator Channel Number (@ref dmamux_rg_channel)
*/
void dmamux_disable_request_generator_trigger_overrun_interrupt(uint32_t dmamux, uint8_t rg_channel)
{
DMAMUX_RGxCR(dmamux, rg_channel) &= ~DMAMUX_RGxCR_OIE;
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Get Request Generator Trigger Overrun Interrupt Flag
Get DMA Request Synchronization Overrun Interrupt Flag for given Request Generator Channel
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] rg_channel Request Generator Channel Number (@ref dmamux_rg_channel)
@returns Request Generator Channel Trigger Overrun Interrupt Flag
*/
uint32_t dmamux_get_request_generator_trigger_overrun_interrupt(uint32_t dmamux, uint8_t rg_channel)
{
return DMAMUX_RGSR(dmamux) & DMAMUX_RGSR_OF(rg_channel);
}
/*---------------------------------------------------------------------------*/
/** @brief DMAMUX Clear Request Generator Trigger Overrun Interrupt Flag
Clear DMA Request Synchronization Overrun Interrupt Flag for given Request Generator
Channel
@param[in] dmamux DMAMUX controller base address (@ref dmamux_reg_base)
@param[in] rg_channel Request Generator Channel Number (@ref dmamux_rg_channel)
*/
void dmamux_clear_request_generator_trigger_overrun_interrupt(uint32_t dmamux, uint8_t rg_channel)
{
DMAMUX_RGCFR(dmamux) = DMAMUX_RGCFR_COF(rg_channel);
}
/**@}*/

View File

@ -36,6 +36,7 @@ ARFLAGS = rcs
OBJS += crc_common_all.o
OBJS += dma_common_l1f013.o
OBJS += dmamux.o
OBJS += exti.o exti_common_all.o
OBJS += flash.o flash_common_all.o
OBJS += gpio_common_all.o gpio_common_f0234.o