summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/xdmad.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/arm/atsam/libraries/libchip/source/xdmad.c')
-rw-r--r--c/src/lib/libbsp/arm/atsam/libraries/libchip/source/xdmad.c495
1 files changed, 0 insertions, 495 deletions
diff --git a/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/xdmad.c b/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/xdmad.c
deleted file mode 100644
index 0be891d2e9..0000000000
--- a/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/xdmad.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/* ---------------------------------------------------------------------------- */
-/* Atmel Microcontroller Software Support */
-/* SAM Software Package License */
-/* ---------------------------------------------------------------------------- */
-/* Copyright (c) 2015, Atmel Corporation */
-/* */
-/* All rights reserved. */
-/* */
-/* Redistribution and use in source and binary forms, with or without */
-/* modification, are permitted provided that the following condition is met: */
-/* */
-/* - Redistributions of source code must retain the above copyright notice, */
-/* this list of conditions and the disclaimer below. */
-/* */
-/* Atmel's name may not be used to endorse or promote products derived from */
-/* this software without specific prior written permission. */
-/* */
-/* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */
-/* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */
-/* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */
-/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
-/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
-/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
-/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
-/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
-/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-/* ---------------------------------------------------------------------------- */
-
-/** \addtogroup xdmad_module
- *
- * \section Xdma xDma Configuration Usage
- *
- * To configure a XDMA channel, the user has to follow these few steps :
- * <ul>
- * <li> Initialize a XDMA driver instance by XDMAD_Initialize().</li>
- * <li> choose an available (disabled) channel using XDMAD_AllocateChannel().</li>
- * <li> After the XDMAC selected channel has been programmed,
- * XDMAD_PrepareChannel() is to enable clock and dma peripheral of the DMA, and
- * set Configuration register to set up the transfer type (memory or non-memory
- * peripheral for source and destination) and flow control device.</li>
- * <li> Invoke XDMAD_StartTransfer() to start DMA transfer or
- * XDMAD_StopTransfer() to force stop DMA transfer.</li>
- * <li> Once the buffer of data is transferred, XDMAD_IsTransferDone()
- * checks if DMA transfer is finished.</li>
- * <li> XDMAD_Handler() handles XDMA interrupt, and invoking XDMAD_SetCallback()
- * if provided.</li>
- * </ul>
- *
- * Related files:\n
- * \ref xdmad.h\n
- * \ref xdmad.c.\n
- */
-
-/** \file */
-
-/** \addtogroup dmad_functions
- @{*/
-
-/*----------------------------------------------------------------------------
- * Includes
- *----------------------------------------------------------------------------*/
-
-#include "chip.h"
-#ifdef __rtems__
-#include "../../../utils/utility.h"
-#include <rtems/irq-extension.h>
-#include <rtems/sysinit.h>
-#include <bsp/fatal.h>
-#endif /* __rtems__ */
-#include <assert.h>
-
-/*----------------------------------------------------------------------------
- * Local functions
- *----------------------------------------------------------------------------*/
-static void XDMAD_Handler(void *arg);
-/**
- * \brief Try to allocate a DMA channel for on given controller.
- * \param pDmad Pointer to DMA driver instance.
- * \param bSrcID Source peripheral ID, 0xFF for memory.
- * \param bDstID Destination peripheral ID, 0xFF for memory.
- * \return Channel number if allocation successful, return
- * DMAD_ALLOC_FAILED if allocation failed.
- */
-static uint32_t XDMAD_AllocateXdmacChannel(sXdmad *pXdmad,
- uint8_t bSrcID,
- uint8_t bDstID)
-{
- uint32_t i;
-
- /* Can't support peripheral to peripheral */
- if (((bSrcID != XDMAD_TRANSFER_MEMORY)
- && (bDstID != XDMAD_TRANSFER_MEMORY)))
- return XDMAD_ALLOC_FAILED;
-
- /* dma transfer from peripheral to memory */
- if (bDstID == XDMAD_TRANSFER_MEMORY) {
- if ((!XDMAIF_IsValidatedPeripherOnDma(bSrcID))) {
- TRACE_ERROR("%s:: Allocation failed", __FUNCTION__);
- return XDMAD_ALLOC_FAILED;
- }
- }
-
- /* dma transfer from memory to peripheral */
- if (bSrcID == XDMAD_TRANSFER_MEMORY) {
- if ((!XDMAIF_IsValidatedPeripherOnDma(bDstID))) {
- TRACE_ERROR("%s:: Allocation failed", __FUNCTION__);
- return XDMAD_ALLOC_FAILED;
- }
- }
-
- for (i = 0; i < pXdmad->numChannels; i ++) {
- if (pXdmad->XdmaChannels[i].state == XDMAD_STATE_FREE) {
- /* Allocate the channel */
- pXdmad->XdmaChannels[i].state = XDMAD_STATE_ALLOCATED;
- /* Get general informations */
- pXdmad->XdmaChannels[i].bSrcPeriphID = bSrcID;
- pXdmad->XdmaChannels[i].bDstPeriphID = bDstID;
- pXdmad->XdmaChannels[i].bSrcTxIfID =
- XDMAIF_Get_ChannelNumber(bSrcID, 0);
- pXdmad->XdmaChannels[i].bSrcRxIfID =
- XDMAIF_Get_ChannelNumber(bSrcID, 1);
- pXdmad->XdmaChannels[i].bDstTxIfID =
- XDMAIF_Get_ChannelNumber(bDstID, 0);
- pXdmad->XdmaChannels[i].bDstRxIfID =
- XDMAIF_Get_ChannelNumber(bDstID, 1);
- return ((i) & 0xFF);
- }
- }
-
- TRACE_ERROR("%s:: Allocation failed, all channels are occupied", __FUNCTION__);
- return XDMAD_ALLOC_FAILED;
-}
-
-void XDMAD_DoNothingCallback(uint32_t Channel, void *pArg)
-{
- /* Do nothing */
-}
-
-/*----------------------------------------------------------------------------
- * Exported functions
- *----------------------------------------------------------------------------*/
-
-sXdmad XDMAD_Instance;
-
-static void XDMAD_SysInitialize(void)
-{
- sXdmad *pXdmad;
- uint32_t j;
- rtems_status_code sc;
-
- pXdmad = &XDMAD_Instance;
-
- pXdmad->pXdmacs = XDMAC;
- pXdmad->numControllers = XDMAC_CONTROLLER_NUM;
- pXdmad->numChannels = (XDMAC_GTYPE_NB_CH(XDMAC_GetType(XDMAC)) + 1);
-
- for (j = 0; j < pXdmad->numChannels; j ++) {
- pXdmad->XdmaChannels[j].fCallback = XDMAD_DoNothingCallback;
- }
-
- sc = rtems_interrupt_handler_install(
- ID_XDMAC,
- "XDMA",
- RTEMS_INTERRUPT_UNIQUE,
- XDMAD_Handler,
- pXdmad
- );
- if (sc != RTEMS_SUCCESSFUL) {
- bsp_fatal(ATSAM_FATAL_XDMA_IRQ_INSTALL);
- }
-}
-
-RTEMS_SYSINIT_ITEM(XDMAD_SysInitialize, RTEMS_SYSINIT_BSP_START,
- RTEMS_SYSINIT_ORDER_LAST);
-
-
-/**
- * \brief Allocate a XDMA channel for upper layer.
- * \param pXdmad Pointer to xDMA driver instance.
- * \param bSrcID Source peripheral ID, 0xFF for memory.
- * \param bDstID Destination peripheral ID, 0xFF for memory.
- * \return Channel number if allocation successful, return
- * XDMAD_ALLOC_FAILED if allocation failed.
- */
-uint32_t XDMAD_AllocateChannel(sXdmad *pXdmad,
- uint8_t bSrcID,
- uint8_t bDstID)
-{
- uint32_t dwChannel = XDMAD_ALLOC_FAILED;
- uint32_t volatile timer = 0x7FF;
-
- LockMutex(pXdmad->xdmaMutex, timer);
- dwChannel = XDMAD_AllocateXdmacChannel(pXdmad, bSrcID, bDstID);
- ReleaseMutex(pXdmad->xdmaMutex);
-
- return dwChannel;
-}
-
-/**
- * \brief Free the specified xDMA channel.
- * \param pXdmad Pointer to xDMA driver instance.
- * \param dwChannel ControllerNumber << 8 | ChannelNumber.
- */
-eXdmadRC XDMAD_FreeChannel(sXdmad *pXdmad,
- uint32_t dwChannel)
-{
- uint8_t iChannel = (dwChannel) & 0xFF;
- assert(pXdmad != NULL);
-
- if (iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
-
- switch (pXdmad->XdmaChannels[iChannel].state) {
- case XDMAD_STATE_ALLOCATED:
- case XDMAD_STATE_START:
- case XDMAD_STATE_IN_XFR:
- return XDMAD_BUSY;
-
- case XDMAD_STATE_DONE:
- case XDMAD_STATE_HALTED:
- pXdmad->XdmaChannels[iChannel].state = XDMAD_STATE_FREE;
- break;
- }
-
- return XDMAD_OK;
-}
-
-/**
- * \brief Set the callback function for xDMA channel transfer.
- * \param pXdmad Pointer to xDMA driver instance.
- * \param dwChannel ControllerNumber << 8 | ChannelNumber.
- * \param fCallback Pointer to callback function.
- * \param pArg Pointer to optional argument for callback.
- */
-eXdmadRC XDMAD_SetCallback(sXdmad *pXdmad,
- uint32_t dwChannel,
- XdmadTransferCallback fCallback,
- void *pArg)
-{
-
- uint8_t iChannel = (dwChannel) & 0xFF;
- assert(pXdmad != NULL);
-
- if (iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
-
- if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_FREE)
- return XDMAD_ERROR;
- else if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_START)
- return XDMAD_BUSY;
-
- pXdmad->XdmaChannels[iChannel].fCallback = fCallback;
- pXdmad->XdmaChannels[iChannel].pArg = pArg;
-
- return XDMAD_OK;
-}
-
-
-/**
- * \brief Enable clock of the xDMA peripheral, Enable the dma peripheral,
- * configure configuration register for xDMA transfer.
- * \param pXdmad Pointer to xDMA driver instance.
- * \param dwChannel ControllerNumber << 8 | ChannelNumber.
- * \param dwCfg Configuration value.
- */
-eXdmadRC XDMAD_PrepareChannel(sXdmad *pXdmad, uint32_t dwChannel)
-{
-
- uint8_t iChannel = (dwChannel) & 0xFF;
- Xdmac *pXdmac = pXdmad->pXdmacs;
-
- assert(pXdmad != NULL);
-
- if (iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
-
- if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_FREE)
- return XDMAD_ERROR;
- else if ((pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_START)
- || (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_IN_XFR))
- return XDMAD_BUSY;
-
-
- /* Enable clock of the DMA peripheral */
- if (!PMC_IsPeriphEnabled(ID_XDMAC))
- PMC_EnablePeripheral(ID_XDMAC);
-
- /* Clear dummy status */
- XDMAC_GetChannelIsr(pXdmac, iChannel);
- /* Disables XDMAC interrupt for the given channel. */
- XDMAC_DisableGIt (pXdmac, iChannel);
- XDMAC_DisableChannelIt (pXdmac, iChannel, 0xFF);
- /* Disable the given dma channel. */
- XDMAC_DisableChannel(pXdmac, iChannel);
- XDMAC_SetSourceAddr(pXdmac, iChannel, 0);
- XDMAC_SetDestinationAddr(pXdmac, iChannel, 0);
- XDMAC_SetBlockControl(pXdmac, iChannel, 0);
- XDMAC_SetChannelConfig(pXdmac, iChannel, 0x20);
- XDMAC_SetDescriptorAddr(pXdmac, iChannel, 0, 0);
- XDMAC_SetDescriptorControl(pXdmac, iChannel, 0);
- return XDMAD_OK;
-}
-
-/**
- * \brief xDMA interrupt handler
- * \param arg Pointer to DMA driver instance.
- */
-static void XDMAD_Handler(void *arg)
-{
- sXdmad *pDmad;
- Xdmac *pXdmac;
- sXdmadChannel *pCh;
- uint32_t xdmaChannelIntStatus, xdmaGlobaIntStatus, xdmaGlobalChStatus;
- uint8_t bExec;
- uint8_t _iChannel;
-
- pDmad = arg;
- pXdmac = pDmad->pXdmacs;
- xdmaGlobaIntStatus = XDMAC_GetGIsr(pXdmac) & 0xFFFFFF;
- xdmaGlobalChStatus = XDMAC_GetGlobalChStatus(pXdmac);
-
- while (xdmaGlobaIntStatus != 0) {
- _iChannel = 31 - __builtin_clz(xdmaGlobaIntStatus);
- xdmaGlobaIntStatus &= ~(UINT32_C(1) << _iChannel);
-
- pCh = &pDmad->XdmaChannels[_iChannel];
- bExec = 0;
-
- if ((xdmaGlobalChStatus & (XDMAC_GS_ST0 << _iChannel)) == 0) {
- xdmaChannelIntStatus = XDMAC_GetMaskChannelIsr(pXdmac, _iChannel);
-
- if (xdmaChannelIntStatus & XDMAC_CIS_BIS) {
- if ((XDMAC_GetChannelItMask(pXdmac, _iChannel) & XDMAC_CIM_LIM) == 0) {
- pCh->state = XDMAD_STATE_DONE;
- bExec = 1;
- }
-
- TRACE_DEBUG("XDMAC_CIS_BIS\n\r");
- }
-
- if (xdmaChannelIntStatus & XDMAC_CIS_FIS)
- TRACE_DEBUG("XDMAC_CIS_FIS\n\r");
-
- if (xdmaChannelIntStatus & XDMAC_CIS_RBEIS)
- TRACE_DEBUG("XDMAC_CIS_RBEIS\n\r");
-
- if (xdmaChannelIntStatus & XDMAC_CIS_WBEIS)
- TRACE_DEBUG("XDMAC_CIS_WBEIS\n\r");
-
- if (xdmaChannelIntStatus & XDMAC_CIS_ROIS)
- TRACE_DEBUG("XDMAC_CIS_ROIS\n\r");
-
- if (xdmaChannelIntStatus & XDMAC_CIS_LIS) {
- TRACE_DEBUG("XDMAC_CIS_LIS\n\r");
- pCh->state = XDMAD_STATE_DONE;
- bExec = 1;
- }
-
- if (xdmaChannelIntStatus & XDMAC_CIS_DIS) {
- pCh->state = XDMAD_STATE_DONE;
- bExec = 1;
- }
-
- } else {
- /* Block end interrupt for LLI dma mode */
- if (XDMAC_GetChannelIsr(pXdmac, _iChannel) & XDMAC_CIS_BIS) {
- bExec = 1;
- }
- }
-
- /* Execute callback */
- if (bExec)
- pCh->fCallback(_iChannel, pCh->pArg);
- }
-}
-
-
-/**
- * \brief Configure DMA for a single transfer.
- * \param pXdmad Pointer to xDMA driver instance.
- * \param dwChannel ControllerNumber << 8 | ChannelNumber.
- */
-eXdmadRC XDMAD_ConfigureTransfer(sXdmad *pXdmad,
- uint32_t dwChannel,
- sXdmadCfg *pXdmaParam,
- uint32_t dwXdmaDescCfg,
- uint32_t dwXdmaDescAddr,
- uint32_t dwXdmaIntEn)
-{
- uint8_t iChannel = (dwChannel) & 0xFF;
-
- assert(pXdmad != NULL);
-
- if (iChannel >= pXdmad->numChannels)
- return XDMAD_ERROR;
-
- Xdmac *pXdmac = pXdmad->pXdmacs;
- XDMAC_GetChannelIsr(pXdmac, iChannel);
-
- if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_FREE)
- return XDMAD_ERROR;
-
- if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_START)
- return XDMAD_BUSY;
-
- /* Linked List is enabled */
- if ((dwXdmaDescCfg & XDMAC_CNDC_NDE) == XDMAC_CNDC_NDE_DSCR_FETCH_EN) {
- if ((dwXdmaDescCfg & XDMAC_CNDC_NDVIEW_Msk) == XDMAC_CNDC_NDVIEW_NDV0) {
- XDMAC_SetChannelConfig(pXdmac, iChannel, pXdmaParam->mbr_cfg);
- XDMAC_SetSourceAddr(pXdmac, iChannel, pXdmaParam->mbr_sa);
- XDMAC_SetDestinationAddr(pXdmac, iChannel, pXdmaParam->mbr_da);
- }
-
- if ((dwXdmaDescCfg & XDMAC_CNDC_NDVIEW_Msk) == XDMAC_CNDC_NDVIEW_NDV1)
- XDMAC_SetChannelConfig(pXdmac, iChannel, pXdmaParam->mbr_cfg);
-
- XDMAC_SetDescriptorAddr(pXdmac, iChannel, dwXdmaDescAddr, 0);
- XDMAC_SetDescriptorControl(pXdmac, iChannel, dwXdmaDescCfg);
- XDMAC_DisableChannelIt (pXdmac, iChannel, 0xFF);
- XDMAC_EnableChannelIt (pXdmac, iChannel, dwXdmaIntEn);
- } else {
- /* LLI is disabled. */
- XDMAC_SetSourceAddr(pXdmac, iChannel, pXdmaParam->mbr_sa);
- XDMAC_SetDestinationAddr(pXdmac, iChannel, pXdmaParam->mbr_da);
- XDMAC_SetMicroblockControl(pXdmac, iChannel, pXdmaParam->mbr_ubc);
- XDMAC_SetBlockControl(pXdmac, iChannel, pXdmaParam->mbr_bc);
- XDMAC_SetDataStride_MemPattern(pXdmac, iChannel, pXdmaParam->mbr_ds);
- XDMAC_SetSourceMicroBlockStride(pXdmac, iChannel, pXdmaParam->mbr_sus);
- XDMAC_SetDestinationMicroBlockStride(pXdmac, iChannel, pXdmaParam->mbr_dus);
- XDMAC_SetChannelConfig(pXdmac, iChannel, pXdmaParam->mbr_cfg);
- XDMAC_SetDescriptorAddr(pXdmac, iChannel, 0, 0);
- XDMAC_SetDescriptorControl(pXdmac, iChannel, 0);
- XDMAC_EnableChannelIt (pXdmac, iChannel, dwXdmaIntEn);
- }
-
- return XDMAD_OK;
-}
-
-/**
- * \brief Start xDMA transfer.
- * \param pXdmad Pointer to XDMA driver instance.
- * \param dwChannel ControllerNumber << 8 | ChannelNumber.
- */
-eXdmadRC XDMAD_StartTransfer(sXdmad *pXdmad, uint32_t dwChannel)
-{
- uint8_t iChannel = (dwChannel) & 0xFF;
-
- assert(pXdmad != NULL);
-
- if (iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
-
- Xdmac *pXdmac = pXdmad->pXdmacs;
-
- if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_FREE) {
- TRACE_ERROR("%s:: XDMAD_STATE_FREE \n\r", __FUNCTION__);
- return XDMAD_ERROR;
- } else if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_START) {
- TRACE_ERROR("%s:: XDMAD_STATE_START \n\r", __FUNCTION__)
- return XDMAD_BUSY;
- }
-
- /* Change state to transferring */
- pXdmad->XdmaChannels[iChannel].state = XDMAD_STATE_START;
- XDMAC_EnableChannel(pXdmac, iChannel);
- XDMAC_EnableGIt(pXdmac, iChannel);
-
- return XDMAD_OK;
-}
-
-
-/**
- * \brief Stop DMA transfer.
- * \param pDmad Pointer to DMA driver instance.
- * \param dwChannel ControllerNumber << 8 | ChannelNumber.
- */
-eXdmadRC XDMAD_StopTransfer(sXdmad *pXdmad, uint32_t dwChannel)
-{
- uint8_t _iChannel = (dwChannel) & 0xFF;
- assert(pXdmad != NULL);
-
- if (_iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
-
- Xdmac *pXdmac = pXdmad->pXdmacs;
-
- pXdmad->XdmaChannels[_iChannel].state = XDMAD_STATE_HALTED;
- /* Disable channel */
- XDMAC_DisableChannel(pXdmac, _iChannel);
- /* Disable interrupts */
- XDMAC_DisableChannelIt(pXdmac, _iChannel, 0xFF);
- /* Clear pending status */
- XDMAC_GetChannelIsr(pXdmac, _iChannel);
- XDMAC_GetGlobalChStatus(pXdmac);
- return XDMAD_OK;
-}
-
-/**@}*/
-