libopencm3/lib/stm32/common/dmamux.c

368 lines
15 KiB
C

/** @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);
}
/**@}*/