Added XDMAC driver
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10477 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
a2081ff38d
commit
4c84325d5e
|
@ -0,0 +1,2 @@
|
||||||
|
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.c
|
||||||
|
PLATFORMINC += $(CHIBIOS)/os/hal/ports/SAMA/LLD/DMAv1
|
|
@ -0,0 +1,315 @@
|
||||||
|
/*
|
||||||
|
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||||
|
|
||||||
|
Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file DMAv1/sama_xdmac.c
|
||||||
|
* @brief Enhanced DMA helper driver code.
|
||||||
|
*
|
||||||
|
* @addtogroup SAMA_DMA
|
||||||
|
* @details DMA sharing helper driver. In the SAMA the DMA channels are a
|
||||||
|
* dedicated resource, this driver allows to allocate and free DMA
|
||||||
|
* channels at runtime.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
/* The following macro is only defined if some driver requiring DMA services
|
||||||
|
has been enabled.*/
|
||||||
|
#if defined(SAMA_DMA_REQUIRED) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
sama_dma_channel_t _sama_dma_channel_t[XDMAC_CHANNELS_TOT];
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Associates a controller to a DMA channel.
|
||||||
|
*
|
||||||
|
* @param[in] index index of the channel
|
||||||
|
* @return xdmacp pointer to DMA controller
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define dmaControllerSelect(index) \
|
||||||
|
index < (XDMAC_CONTROLLERS - 1) ? XDMAC0 : XDMAC1 \
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Associates ID number to controller.
|
||||||
|
*
|
||||||
|
* @param[in] xdmacp pointer to DMA controller
|
||||||
|
* @return ID_XDMACx peripheral ID of DMA controller
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define dmaGetControllerId(xdmacp) \
|
||||||
|
(Xdmac *) xdmacp == XDMAC0 ? ID_XDMAC0 : ID_XDMAC1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get content of Global Status register.
|
||||||
|
*
|
||||||
|
* @param[in] xdmacp pointer to DMA controller
|
||||||
|
* @return XDMAC_GS content of Global Status register
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define dmaGetGlobal(xdmacp) xdmacp->XDMAC_GS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get content of Global Interrupt Status register.
|
||||||
|
*
|
||||||
|
* @param[in] xdmacp pointer to DMA controller
|
||||||
|
* @return XDMAC_GIS content of Global Interrupt Status register
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define dmaGetGlobalInt(xdmacp) xdmacp->XDMAC_GIS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get content of Channel Interrupt Status register.
|
||||||
|
* @note Reading interrupt is equivalent to clearing interrupt.
|
||||||
|
*
|
||||||
|
* @param[in] dmachp pointer to a sama_dma_channel_t structure
|
||||||
|
* @return XDMAC_CISx content of Channel Interrupt Status register
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define dmaGetChannelInt(dmachp) \
|
||||||
|
(dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CIS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get content of Channel Interrupt Mask register.
|
||||||
|
*
|
||||||
|
* @param[in] dmachp pointer to a sama_dma_channel_t structure
|
||||||
|
* @return XDMAC_CIMx content of Channel Interrupt Mask register
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define dmaGetChannelIntMask(dmachp) \
|
||||||
|
(dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CIM
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver interrupt handlers. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XDMAC interrupt handler
|
||||||
|
*/
|
||||||
|
OSAL_IRQ_HANDLER(dmaHandler) {
|
||||||
|
uint32_t cont;
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
for (cont = 0; cont < XDMAC_CONTROLLERS; cont++) {
|
||||||
|
uint32_t chan, gis, gcs, cis;
|
||||||
|
|
||||||
|
Xdmac *xdmac = dmaControllerSelect(cont);
|
||||||
|
|
||||||
|
/* Read Global Interrupt Status Register */
|
||||||
|
gis = dmaGetGlobalInt(xdmac);
|
||||||
|
|
||||||
|
if ((gis & 0xFFFF) == 0)
|
||||||
|
/* There is no interrupt pending for this xdmac controller */
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Read Global Status Register */
|
||||||
|
gcs = dmaGetGlobal(xdmac);
|
||||||
|
for (chan = 0; chan < XDMAC_CHANNELS; chan++) {
|
||||||
|
sama_dma_channel_t *channel = &_sama_dma_channel_t[(cont * XDMAC_CHANNELS) + chan];
|
||||||
|
bool pendingInt = false;
|
||||||
|
|
||||||
|
if (!(gis & (0x1 << chan)))
|
||||||
|
/* There is no pending interrupt for this channel */
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (channel->state == SAMA_DMA_FREE)
|
||||||
|
/* Channel is free */
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!(gcs & (0x1 << chan))) {
|
||||||
|
cis = dmaGetChannelInt(channel);
|
||||||
|
|
||||||
|
if (cis & XDMAC_CIS_BIS) {
|
||||||
|
if (!(dmaGetChannelIntMask(channel) & XDMAC_CIM_LIM)) {
|
||||||
|
pendingInt = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cis & XDMAC_CIS_LIS) {
|
||||||
|
pendingInt = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cis & XDMAC_CIS_DIS) {
|
||||||
|
pendingInt = true;;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Execute callback */
|
||||||
|
//if (pendingInt && channel->dma_func) {
|
||||||
|
channel->dma_func(channel->dma_param,cis);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SAMA DMA helper initialization.
|
||||||
|
*
|
||||||
|
* @init
|
||||||
|
*/
|
||||||
|
void dmaInit(void) {
|
||||||
|
|
||||||
|
uint8_t cont, chan;
|
||||||
|
|
||||||
|
for (cont = 0; cont < XDMAC_CONTROLLERS; cont++) {
|
||||||
|
|
||||||
|
Xdmac *xdmac = dmaControllerSelect(cont);
|
||||||
|
|
||||||
|
for (chan = 0; chan < XDMAC_CHANNELS; chan++) {
|
||||||
|
sama_dma_channel_t *channel = &_sama_dma_channel_t[(cont * XDMAC_CHANNELS) + chan];
|
||||||
|
|
||||||
|
/* Initialization of the specific channel */
|
||||||
|
channel->xdmac = xdmac;
|
||||||
|
channel->chid = chan;
|
||||||
|
channel->state = SAMA_DMA_FREE;
|
||||||
|
channel->dma_func = NULL;
|
||||||
|
|
||||||
|
/* Clear interrupts */
|
||||||
|
dmaGetChannelInt(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t id = dmaGetControllerId(xdmac);
|
||||||
|
/* set aic source handler */
|
||||||
|
aicSetSourceHandler(id, dmaHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Assigns a DMA channel.
|
||||||
|
* @details The channel is assigned and, if required, the DMA clock enabled.
|
||||||
|
* The function also enables the IRQ vector associated to the channel
|
||||||
|
* and initializes its priority.
|
||||||
|
* @pre The channel must not be already in use or an error is returned.
|
||||||
|
* @post The channel is allocated and the default ISR handler redirected
|
||||||
|
* to the specified function.
|
||||||
|
* @post The channel ISR vector is enabled and its priority configured.
|
||||||
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
*
|
||||||
|
* @param[in] priority IRQ priority mask for the DMA stream
|
||||||
|
* @param[in] func handling function pointer, can be @p NULL
|
||||||
|
* @param[in] param a parameter to be passed to the handling function
|
||||||
|
* @return A pointer to sama_dma_channel_t structure if channel is
|
||||||
|
* assigned or NULL.
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
sama_dma_channel_t* dmaChannelAllocate(uint32_t priority,
|
||||||
|
sama_dmaisr_t func,
|
||||||
|
void *param) {
|
||||||
|
|
||||||
|
sama_dma_channel_t *channel = NULL;
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t chan;
|
||||||
|
for (chan = 0; chan < XDMAC_CHANNELS_TOT; chan++) {
|
||||||
|
channel = &_sama_dma_channel_t[chan];
|
||||||
|
if (channel->state != SAMA_DMA_FREE) {
|
||||||
|
channel = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channel != NULL) {
|
||||||
|
/* Marks the channel as allocated.*/
|
||||||
|
channel->state = SAMA_DMA_NOT_FREE;
|
||||||
|
channel->dma_func = func;
|
||||||
|
channel->dma_param = param;
|
||||||
|
id = dmaGetControllerId(channel->xdmac);
|
||||||
|
|
||||||
|
/* Setting aic */
|
||||||
|
aicSetSourcePriority(id, priority);
|
||||||
|
aicEnableInt(id);
|
||||||
|
/* Enabling DMA clocks required by the current channel set.*/
|
||||||
|
if (id == ID_XDMAC0) {
|
||||||
|
pmcEnableXDMAC0();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pmcEnableXDMAC1();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable channel interrupt */
|
||||||
|
/* Only works for single block transfer */
|
||||||
|
channel->xdmac->XDMAC_CHID[channel->chid].XDMAC_CIE = XDMAC_CIE_BIE;
|
||||||
|
channel->xdmac->XDMAC_GIE = XDMAC_GIE_IE0 << (channel->chid);
|
||||||
|
}
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Releases a DMA channel.
|
||||||
|
* @details The stream is channel and, if required, the DMA clock disabled.
|
||||||
|
* Trying to release a unallocated channel is an illegal operation
|
||||||
|
* and is trapped if assertions are enabled.
|
||||||
|
* @pre The channel must have been allocated using @p dmaChannelAllocate().
|
||||||
|
* @post The channel is again available.
|
||||||
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
*
|
||||||
|
* @param[in] dmachp pointer to a sama_dma_channel_t structure
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
void dmaChannelRelease(sama_dma_channel_t *dmachp) {
|
||||||
|
|
||||||
|
osalDbgCheck(dmachp != NULL);
|
||||||
|
uint8_t id;
|
||||||
|
/* Check if the channel is free.*/
|
||||||
|
osalDbgAssert(dmachp->state != SAMA_DMA_NOT_FREE,
|
||||||
|
"not allocated");
|
||||||
|
id = dmaGetControllerId(dmachp->xdmac);
|
||||||
|
/* Disables the associated IRQ vector.*/
|
||||||
|
aicDisableInt(id);
|
||||||
|
|
||||||
|
/* Disables channel */
|
||||||
|
dmaChannelDisable(dmachp);
|
||||||
|
|
||||||
|
/* Marks the stream as not allocated.*/
|
||||||
|
(dmachp)->state = SAMA_DMA_FREE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SAMA_DMA_REQUIRED */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,276 @@
|
||||||
|
/*
|
||||||
|
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||||
|
|
||||||
|
Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file DMAv1/sama_xdmac.h
|
||||||
|
* @brief Enhanced-DMA helper driver header.
|
||||||
|
*
|
||||||
|
* @addtogroup SAMA_XDMAC
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SAMA_XDMAC_H
|
||||||
|
#define SAMA_XDMAC_H
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DMA capability.
|
||||||
|
* @details if @p TRUE then the DMA is able of burst transfers, FIFOs,
|
||||||
|
* scatter gather and other advanced features.
|
||||||
|
*/
|
||||||
|
#define SAMA_XDMAC_ADVANCED TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Total number of DMA controllers.
|
||||||
|
* @details This is the total number of DMA controllers.
|
||||||
|
*/
|
||||||
|
#define XDMAC_CONTROLLERS 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of DMA channels.
|
||||||
|
* @details This is the number of DMA channel for each controller.
|
||||||
|
*/
|
||||||
|
#define XDMAC_CHANNELS (XDMACCHID_NUMBER)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Total number of DMA channels.
|
||||||
|
* @details This is the total number of channels among all the DMA units.
|
||||||
|
*/
|
||||||
|
#define XDMAC_CHANNELS_TOT (XDMACCHID_NUMBER * XDMAC_CONTROLLERS)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Max single transfer size.
|
||||||
|
* @details This is the maximum single transfer size supported.
|
||||||
|
*/
|
||||||
|
#define XDMAC_MAX_BT_SIZE 0xFFFFFF
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Max DMA length of the block.
|
||||||
|
* @details This is the maximum length of the block supported.
|
||||||
|
*/
|
||||||
|
#define XDMAC_MAX_BLOCK_LEN 0xFFF
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief States of the channel.
|
||||||
|
*/
|
||||||
|
#define SAMA_DMA_FREE 0U
|
||||||
|
#define SAMA_DMA_NOT_FREE 1U
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
/**
|
||||||
|
* @brief SAMA5D2 DMA ISR function type.
|
||||||
|
*
|
||||||
|
* @param[in] p parameter for the registered function
|
||||||
|
* @param[in] flags content of the CIS register.
|
||||||
|
*/
|
||||||
|
typedef void (*sama_dmaisr_t)(void *p, uint32_t flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SAMA5D2 DMA channel descriptor structure.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
Xdmac *xdmac; /**< @brief Associated DMA
|
||||||
|
controller. */
|
||||||
|
uint8_t chid; /**< @brief ID channel */
|
||||||
|
uint8_t state; /**< @brief State channel */
|
||||||
|
sama_dmaisr_t dma_func;
|
||||||
|
void *dma_param;
|
||||||
|
} sama_dma_channel_t;
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
/**
|
||||||
|
* @name Macro Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Associates a source to a DMA channel.
|
||||||
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
* @pre The channel must have been allocated using @p dmaChannelAllocate().
|
||||||
|
* @post After use the channel can be released using @p dmaChannelRelease().
|
||||||
|
*
|
||||||
|
* @param[in] dmachp pointer to a sama_dma_channel_t structure
|
||||||
|
* @param[in] addr value to be written in the SA register
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
#define dmaChannelSetSource(dmachp, addr) { \
|
||||||
|
(dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CSA = XDMAC_CSA_SA((uint32_t)addr); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Associates a destination to a DMA channel.
|
||||||
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
* @pre The channel must have been allocated using @p dmaChannelAllocate().
|
||||||
|
* @post After use the channel can be released using @p dmaChannelRelease().
|
||||||
|
*
|
||||||
|
* @param[in] dmachp pointer to a sama_dma_channel_t structure
|
||||||
|
* @param[in] addr value to be written in the DA register
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
#define dmaChannelSetDestination(dmachp, addr) { \
|
||||||
|
(dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CDA = XDMAC_CDA_DA((uint32_t)addr); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the number of transfers to be performed.
|
||||||
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
*
|
||||||
|
* @pre The channel must have been allocated using @p dmaChannelAllocate().
|
||||||
|
* @post After use the channel can be released using @p dmaChannelRelease().
|
||||||
|
*
|
||||||
|
* @param[in] dmastp pointer to a sama_dma_channel_t structure
|
||||||
|
* @param[in] size value to be written in the XDMAC_CUBC register
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
#define dmaChannelSetTransactionSize(dmachp, size) { \
|
||||||
|
(dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CUBC = XDMAC_CUBC_UBLEN(size); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the channel mode settings.
|
||||||
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
* @pre The channel must have been allocated using @p dmaChannelAllocate().
|
||||||
|
* @post After use the channel can be released using @p dmaChannelRelease().
|
||||||
|
*
|
||||||
|
* @param[in] dmachp pointer to a sama_dma_channel_t structure
|
||||||
|
* @param[in] mode value to be written in the XDMAC_CC register
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
#define dmaChannelSetMode(dmachp, mode) { \
|
||||||
|
(dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CC = mode; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DMA channel enable.
|
||||||
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
* The hardware disables a channel on transfer completion by clearing
|
||||||
|
* bit XDMAC_GS.STx.
|
||||||
|
* @pre The channel must have been allocated using @p dmaChannelAllocate().
|
||||||
|
*
|
||||||
|
* @param[in] dmachp pointer to a sama_dma_channel_t structure
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
#define dmaChannelEnable(dmachp) { \
|
||||||
|
(dmachp)->xdmac->XDMAC_GE |= (XDMAC_GE_EN0 << ((dmachp)->chid)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DMA channel disable.
|
||||||
|
* @details The function disables the specified channel, waits for the disable
|
||||||
|
* operation to complete and then clears any pending interrupt.
|
||||||
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
* @pre The channel must have been allocated using @p dmaChannelAllocate().
|
||||||
|
*
|
||||||
|
* @param[in] dmachp pointer to a sama_dma_channel_t structure
|
||||||
|
*
|
||||||
|
* @special
|
||||||
|
*/
|
||||||
|
#define dmaChannelDisable(dmachp) { \
|
||||||
|
(dmachp)->xdmac->XDMAC_GD |= XDMAC_GD_DI0 << ((dmachp)->chid); \
|
||||||
|
dmaGetChannelInt(dmachp); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts a memory to memory operation using the specified channel.
|
||||||
|
* @note The default transfer data mode is "byte to byte" but it can be
|
||||||
|
* changed by specifying extra options in the @p mode parameter.
|
||||||
|
* @pre The channel must have been allocated using @p dmaChannelAllocate().
|
||||||
|
* @post After use the channel can be released using @p dmaChannelRelease().
|
||||||
|
*
|
||||||
|
* @param[in] dmachp pointer to a sama_dma_channel_t structure
|
||||||
|
* @param[in] mode value to be written in the CC register, this value
|
||||||
|
* is implicitly ORed with:
|
||||||
|
* - @p XDMAC_CC_TYPE_MEM_TRAN
|
||||||
|
* - @p XDMAC_CC_SAM_INCREMENTED_AM
|
||||||
|
* - @p XDMAC_CC_DAM_INCREMENTED_AM
|
||||||
|
* - @p XDMAC_CC_SWREQ_SWR_CONNECTED
|
||||||
|
* - @p XDMAC_CC_SIF_AHB_IF0
|
||||||
|
* - @p XDMAC_CC_DIF_AHB_IF0
|
||||||
|
* - @p XDMAC_GE
|
||||||
|
* .
|
||||||
|
* @param[in] src source address
|
||||||
|
* @param[in] dst destination address
|
||||||
|
* @param[in] n number of data units to copy
|
||||||
|
*/
|
||||||
|
#define dmaStartMemCopy(dmachp, mode, src, dst, n) { \
|
||||||
|
dmaChannelSetSource(dmachp, src); \
|
||||||
|
dmaChannelSetDestination(dmachp, dst); \
|
||||||
|
dmaChannelSetTransactionSize(dmachp, n); \
|
||||||
|
dmaChannelSetMode(dmachp, (mode) | \
|
||||||
|
XDMAC_CC_TYPE_MEM_TRAN | XDMAC_CC_SAM_INCREMENTED_AM | \
|
||||||
|
XDMAC_CC_DAM_INCREMENTED_AM | XDMAC_CC_SWREQ_SWR_CONNECTED | \
|
||||||
|
XDMAC_CC_SIF_AHB_IF0 | XDMAC_CC_DIF_AHB_IF0); \
|
||||||
|
dmaChannelEnable(dmachp); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Polled wait for DMA transfer end.
|
||||||
|
* @pre The channel must have been allocated using @p dmaChannelAllocate().
|
||||||
|
* @post After use the channel can be released using @p dmaChannelRelease().
|
||||||
|
*
|
||||||
|
* @param[in] dmachp pointer to a sama_dma_channel_t structure
|
||||||
|
*/
|
||||||
|
#define dmaWaitCompletion(dmachp) { \
|
||||||
|
(dmachp)->xdmac->XDMAC_GID |= XDMAC_GID_ID0 << ((dmachp)->chid)); \
|
||||||
|
while ((dmachp)->xdmac->XDMAC_GS & (XDMAC_GS_ST0 << ((dmachp)->chid)))) \
|
||||||
|
; \
|
||||||
|
dmaGetChannelInt(dmachp); \
|
||||||
|
}
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if !defined(__DOXYGEN__)
|
||||||
|
extern sama_dma_channel_t _sama_dma_channel_t[XDMAC_CHANNELS_TOT];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void dmaInit(void);
|
||||||
|
sama_dma_channel_t* dmaChannelAllocate(uint32_t priority,
|
||||||
|
sama_dmaisr_t func,
|
||||||
|
void *param);
|
||||||
|
void dmaChannelRelease(sama_dma_channel_t *dmachp);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SAMA_DMA_H */
|
||||||
|
|
||||||
|
/** @} */
|
Loading…
Reference in New Issue