SCSI2SD/software/SCSI2SD/v3/SCSI2SD.cydsn/Generated_Source/PSoC5/CyDmac.c
2017-05-01 09:07:22 +10:00

1040 lines
35 KiB
C
Executable File

/***************************************************************************//**
* \file CyDmac.c
* \version 5.50
*
* \brief
* Provides an API for the DMAC component. The API includes functions for the
* DMA controller, DMA channels and Transfer Descriptors. This API is the library
* version not the auto generated code that gets generated when the user places a
* DMA component on the schematic.
*
* The auto generated code would use the APi's in this module.
*
* \note This code is endian agnostic.
*
* \note The Transfer Descriptor memory can be used as regular memory if the
* TD's are not being used.
*
* \note This code uses the first byte of each TD to manage the free list of
* TD's. The user can overwrite this once the TD is allocated.
*
********************************************************************************
* \copyright
* Copyright 2008-2016, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "CyDmac.h"
/*******************************************************************************
* The following variables are initialized from CyDmacConfigure() function that
* is executed from initialize_psoc() at the early initialization stage.
* In case of IAR EW IDE, initialize_psoc() is executed before the data sections
* are initialized. To avoid zeroing, these variables should be initialized
* properly during segments initialization as well.
*******************************************************************************/
static uint8 CyDmaTdCurrentNumber = CY_DMA_NUMBEROF_TDS; /* Current Number of free elements on list */
static uint8 CyDmaTdFreeIndex = (uint8)(CY_DMA_NUMBEROF_TDS - 1u); /* Index of first available TD */
static uint32 CyDmaChannels = DMA_CHANNELS_USED__MASK0; /* Bit map of DMA channel ownership */
/*******************************************************************************
* Function Name: CyDmacConfigure
****************************************************************************//**
*
* Creates a linked list of all the TDs to be allocated. This function is called
* by the startup code; you do not normally need to call it. You can call this
* function if all of the DMA channels are inactive.
*
*******************************************************************************/
void CyDmacConfigure(void)
{
uint8 dmaIndex;
/* Set TD list variables. */
CyDmaTdFreeIndex = (uint8)(CY_DMA_NUMBEROF_TDS - 1u);
CyDmaTdCurrentNumber = CY_DMA_NUMBEROF_TDS;
/* Make TD free list. */
for(dmaIndex = (uint8)(CY_DMA_NUMBEROF_TDS - 1u); dmaIndex != 0u; dmaIndex--)
{
CY_DMA_TDMEM_STRUCT_PTR[dmaIndex].TD0[0u] = (uint8)(dmaIndex - 1u);
}
/* Make last one point to zero. */
CY_DMA_TDMEM_STRUCT_PTR[dmaIndex].TD0[0u] = 0u;
}
/*******************************************************************************
* Function Name: CyDmacError
****************************************************************************//**
*
* Returns errors of the last failed DMA transaction.
*
* \return Errors of the last failed DMA transaction.
*
* DMAC_PERIPH_ERR:
* Set to 1 when a peripheral responds to a bus transaction with an error
* response.
*
* DMAC_UNPOP_ACC:
* Set to 1 when an access is attempted to an invalid address.
*
* DMAC_BUS_TIMEOUT:
* Set to 1 when a bus timeout occurs. Cleared by writing a 1. Timeout values
* are determined by the BUS_TIMEOUT field in the PHUBCFG register.
*
* Theory:
* Once an error occurs the error bits are sticky and are only cleared by
* writing 1 to the error register.
*
*******************************************************************************/
uint8 CyDmacError(void)
{
return((uint8)(((uint32) 0x0Eu) & *CY_DMA_ERR_PTR));
}
/*******************************************************************************
* Function Name: CyDmacClearError
****************************************************************************//**
*
* Clears the error bits in the error register of the DMAC.
*
* \param error:
* Clears the error bits in the DMAC error register.
*
* \param DMAC_PERIPH_ERR:
* Set to 1 when a peripheral responds to a bus transaction with an error
* response.
*
* \param DMAC_UNPOP_ACC:
* Set to 1 when an access is attempted to an invalid address.
*
* \param DMAC_BUS_TIMEOUT:
* Set to 1 when a bus timeout occurs. Cleared by writing 1. Timeout values
* are determined by the BUS_TIMEOUT field in the PHUBCFG register.
*
* Theory:
* Once an error occurs the error bits are sticky and are only cleared by
* writing 1 to the error register.
*
*******************************************************************************/
void CyDmacClearError(uint8 error)
{
*CY_DMA_ERR_PTR = (((uint32)0x0Fu) & ((uint32)error));
}
/*******************************************************************************
* Function Name: CyDmacErrorAddress
****************************************************************************//**
*
* When DMAC_BUS_TIMEOUT, DMAC_UNPOP_ACC, and DMAC_PERIPH_ERR occur the
* address of the error is written to the error address register and can be read
* with this function.
*
* If there are multiple errors, only the address of the first is saved.
*
* \return The address that caused the error.
*
*******************************************************************************/
uint32 CyDmacErrorAddress(void)
{
return(CY_GET_REG32(CY_DMA_ERR_ADR_PTR));
}
/*******************************************************************************
* Function Name: CyDmaChAlloc
****************************************************************************//**
*
* Allocates a channel from the DMAC to be used in all functions that require a
* channel handle.
*
* \return The allocated channel number. Zero is a valid channel number.
* DMA_INVALID_CHANNEL is returned if there are no channels available.
*
*******************************************************************************/
uint8 CyDmaChAlloc(void)
{
uint8 interruptState;
uint8 dmaIndex;
uint32 channel = 1u;
/* Enter critical section! */
interruptState = CyEnterCriticalSection();
/* Look for free channel. */
for(dmaIndex = 0u; dmaIndex < CY_DMA_NUMBEROF_CHANNELS; dmaIndex++)
{
if(0uL == (CyDmaChannels & channel))
{
/* Mark channel as used. */
CyDmaChannels |= channel;
break;
}
channel <<= 1u;
}
if(dmaIndex >= CY_DMA_NUMBEROF_CHANNELS)
{
dmaIndex = CY_DMA_INVALID_CHANNEL;
}
/* Exit critical section! */
CyExitCriticalSection(interruptState);
return(dmaIndex);
}
/*******************************************************************************
* Function Name: CyDmaChFree
****************************************************************************//**
*
* Frees a channel allocated by \ref DmaChAlloc().
*
* \param chHandle The handle previously returned by \ref CyDmaChAlloc() or \ref
* DMA_DmaInitalize().
*
* \return CYRET_SUCCESS if successful.
* \return CYRET_BAD_PARAM if chHandle is invalid.
*
*******************************************************************************/
cystatus CyDmaChFree(uint8 chHandle)
{
cystatus status = CYRET_BAD_PARAM;
uint8 interruptState;
if(chHandle < CY_DMA_NUMBEROF_CHANNELS)
{
/* Enter critical section */
interruptState = CyEnterCriticalSection();
/* Clear bit mask that keeps track of ownership. */
CyDmaChannels &= ~(((uint32) 1u) << chHandle);
/* Exit critical section */
CyExitCriticalSection(interruptState);
status = CYRET_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: CyDmaChEnable
****************************************************************************//**
*
* Enables the DMA channel. A software or hardware request still must happen
* before the channel is executed.
*
* \param chHandle A handle previously returned by \ref CyDmaChAlloc() or \ref
* DMA_DmaInitalize().
*
* \param preserveTds Preserves the original TD state when the TD has completed.
* This parameter applies to all TDs in the channel.
*
* 0 - When TD is completed, the DMAC leaves the TD configuration values in
* their current state, and does not restore them to their original state.
*
* 1 - When TD is completed, the DMAC restores the original configuration
* values of the TD.
*
* When preserveTds is set, the TD slot that equals the channel number becomes
* RESERVED and that becomes where the working registers exist. So, for example,
* if you are using CH06 and preserveTds is set, you are not allowed to use TD
* slot 6. That is reclaimed by the DMA engine for its private use.
*
* \note Do not chain back to a completed TD if the preserveTds for the channel
* is set to 0. When a TD has completed preserveTds for the channel set to 0,
* the transfer count will be at 0. If a TD with a transfer count of 0 is
* started, the TD will transfer an indefinite amount of data.
*
* Take extra precautions when using the hardware request (DRQ) option when the
* preserveTds is set to 0, as you might be requesting the wrong data.
*
* \return CYRET_SUCCESS if successful.
* \return CYRET_BAD_PARAM if chHandle is invalid.
*
*******************************************************************************/
cystatus CyDmaChEnable(uint8 chHandle, uint8 preserveTds)
{
cystatus status = CYRET_BAD_PARAM;
if(chHandle < CY_DMA_NUMBEROF_CHANNELS)
{
if (0u != preserveTds)
{
/* Store intermediate TD states separately in CHn_SEP_TD0/1 to
* preserve original TD chain
*/
CY_DMA_CH_STRUCT_PTR[chHandle].basic_cfg[0u] |= CY_DMA_CH_BASIC_CFG_WORK_SEP;
}
else
{
/* Store intermediate and final TD states on top of original TD chain */
CY_DMA_CH_STRUCT_PTR[chHandle].basic_cfg[0u] &= (uint8)(~CY_DMA_CH_BASIC_CFG_WORK_SEP);
}
/* Enable channel */
CY_DMA_CH_STRUCT_PTR[chHandle].basic_cfg[0u] |= CY_DMA_CH_BASIC_CFG_EN;
status = CYRET_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: CyDmaChDisable
****************************************************************************//**
*
* Disables the DMA channel. Once this function is called, CyDmaChStatus() may
* be called to determine when the channel is disabled and which TDs were being
* executed.
*
* If it is currently executing it will allow the current burst to finish
* naturally.
*
* \param chHandle A handle previously returned by \ref CyDmaChAlloc() or \ref
* DMA_DmaInitalize().
*
* \return CYRET_SUCCESS if successful.
* \return CYRET_BAD_PARAM if chHandle is invalid.
*
*******************************************************************************/
cystatus CyDmaChDisable(uint8 chHandle)
{
cystatus status = CYRET_BAD_PARAM;
if(chHandle < CY_DMA_NUMBEROF_CHANNELS)
{
/***********************************************************************
* Should not change configuration information of a DMA channel when it
* is active (or vulnerable to becoming active).
***********************************************************************/
/* Disable channel */
CY_DMA_CH_STRUCT_PTR[chHandle].basic_cfg[0] &= ((uint8) (~CY_DMA_CH_BASIC_CFG_EN));
/* Store intermediate and final TD states on top of original TD chain */
CY_DMA_CH_STRUCT_PTR[chHandle].basic_cfg[0] &= ((uint8) (~CY_DMA_CH_BASIC_CFG_WORK_SEP));
status = CYRET_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: CyDmaClearPendingDrq
****************************************************************************//**
*
* Clears pending the DMA data request.
*
* \param chHandle Handle to the dma channel.
*
* \return CYRET_SUCCESS if successful.
* \return CYRET_BAD_PARAM if chHandle is invalid.
*
*******************************************************************************/
cystatus CyDmaClearPendingDrq(uint8 chHandle)
{
cystatus status = CYRET_BAD_PARAM;
if(chHandle < CY_DMA_NUMBEROF_CHANNELS)
{
CY_DMA_CH_STRUCT_PTR[chHandle].action[0] |= CY_DMA_CPU_TERM_CHAIN;
CY_DMA_CH_STRUCT_PTR[chHandle].basic_cfg[0] |= 0x01u;
status = CYRET_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: CyDmaChPriority
****************************************************************************//**
*
* Sets the priority of a DMA channel. You can use this function when you want
* to change the priority at run time. If the priority remains the same for a
* DMA channel, then you can configure the priority in the .cydwr file.
*
* \param chHandle A handle previously returned by \ref CyDmaChAlloc() or \ref
* DMA_DmaInitalize().
*
* \param priority Priority to set the channel to, 0 - 7.
*
* \return CYRET_SUCCESS if successful.
* \return CYRET_BAD_PARAM if chHandle is invalid.
*
*******************************************************************************/
cystatus CyDmaChPriority(uint8 chHandle, uint8 priority)
{
uint8 value;
cystatus status = CYRET_BAD_PARAM;
if(chHandle < CY_DMA_NUMBEROF_CHANNELS)
{
value = CY_DMA_CH_STRUCT_PTR[chHandle].basic_cfg[0u] & ((uint8)(~(0x0Eu)));
CY_DMA_CH_STRUCT_PTR[chHandle].basic_cfg[0u] = value | ((uint8) ((priority & 0x7u) << 0x01u));
status = CYRET_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: CyDmaChSetExtendedAddress
****************************************************************************//**
*
* Sets the high 16 bits of the source and destination addresses for the DMA
* channel (valid for all TDs in the chain).
*
* \param chHandle A handle previously returned by \ref CyDmaChAlloc() or \ref
* DMA_DmaInitalize().
*
* \param source Upper 16 bit address of the DMA transfer source.
*
* \param destination Upper 16 bit address of the DMA transfer destination.
*
* \return CYRET_SUCCESS if successful.
* \return CYRET_BAD_PARAM if chHandle is invalid.
*
*******************************************************************************/
cystatus CyDmaChSetExtendedAddress(uint8 chHandle, uint16 source, uint16 destination) \
{
cystatus status = CYRET_BAD_PARAM;
reg16 *convert;
#if(CY_PSOC5)
/* 0x1FFF8000-0x1FFFFFFF needs to use alias at 0x20008000-0x2000FFFF */
if(source == 0x1FFFu)
{
source = 0x2000u;
}
if(destination == 0x1FFFu)
{
destination = 0x2000u;
}
#endif /* (CY_PSOC5) */
if(chHandle < CY_DMA_NUMBEROF_CHANNELS)
{
/* Set source address */
convert = (reg16 *) &CY_DMA_CFGMEM_STRUCT_PTR[chHandle].CFG1[0];
CY_SET_REG16(convert, source);
/* Set destination address */
convert = (reg16 *) &CY_DMA_CFGMEM_STRUCT_PTR[chHandle].CFG1[2u];
CY_SET_REG16(convert, destination);
status = CYRET_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: CyDmaChSetInitialTd
****************************************************************************//**
*
* Sets the initial TD to be executed for the channel when the \ref CyDmaChEnable()
* function is called.
*
* \param chHandle A handle previously returned by \ref CyDmaChAlloc() or
* \ref DMA_DmaInitialize().
*
* \param startTd Set the TD index as the first TD associated with the
* channel. Zero is a valid TD index.
*
* \return CYRET_SUCCESS if successful.
* \return CYRET_BAD_PARAM if chHandle is invalid.
*
*******************************************************************************/
cystatus CyDmaChSetInitialTd(uint8 chHandle, uint8 startTd)
{
cystatus status = CYRET_BAD_PARAM;
if(chHandle < CY_DMA_NUMBEROF_CHANNELS)
{
CY_DMA_CH_STRUCT_PTR[chHandle].basic_status[1u] = startTd;
status = CYRET_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: CyDmaChSetRequest
****************************************************************************//**
*
* Allows the caller to terminate a chain of TDs, terminate one TD, or create a
* direct request to start the DMA channel.
*
* \param chHandle A handle previously returned by \ref CyDmaChAlloc() or \ref
* DMA_DmaInitalize().
*
* \param request One of the following constants. Each of the constants is a
* three-bit value.
* CPU_REQ - Create a direct request to start the DMA channel
* CPU_TERM_TD - Terminate one TD
* CPU_TERM_CHAIN - Terminate a chain of TDs
*
* \return CYRET_SUCCESS if successful.
* \return CYRET_BAD_PARAM if chHandle is invalid.
*
*******************************************************************************/
cystatus CyDmaChSetRequest(uint8 chHandle, uint8 request)
{
cystatus status = CYRET_BAD_PARAM;
if(chHandle < CY_DMA_NUMBEROF_CHANNELS)
{
CY_DMA_CH_STRUCT_PTR[chHandle].action[0u] |= (request & (CPU_REQ | CPU_TERM_TD | CPU_TERM_CHAIN));
status = CYRET_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: CyDmaChGetRequest
****************************************************************************//**
*
* This function allows the caller of \ref CyDmaChSetRequest() to determine if the
* request was completed.
*
* \param chHandle A handle previously returned by \ref CyDmaChAlloc() or \ref
* DMA_DmaInitalize().
*
* \return Returns a three-bit field, corresponding to the three bits of the
* request, which describes the state of the previously posted request. If the
* value is zero, the request was completed. CY_DMA_INVALID_CHANNEL if the handle
* is invalid.
*
*******************************************************************************/
cystatus CyDmaChGetRequest(uint8 chHandle)
{
cystatus status = CY_DMA_INVALID_CHANNEL;
if(chHandle < CY_DMA_NUMBEROF_CHANNELS)
{
status = (cystatus) ((uint32)CY_DMA_CH_STRUCT_PTR[chHandle].action[0u] &
(uint32)(CY_DMA_CPU_REQ | CY_DMA_CPU_TERM_TD | CY_DMA_CPU_TERM_CHAIN));
}
return(status);
}
/*******************************************************************************
* Function Name: CyDmaChStatus
****************************************************************************//**
*
* Determines the status of the DMA channel.
*
* \param chHandle A handle previously returned by \ref CyDmaChAlloc() or \ref
* DMA_DmaInitalize().
*
* \param currentTd The address to store the index of the current TD. Can be NULL
* if the value is not needed.
*
* \param state The address to store the state of the channel. Can be NULL if the
* value is not needed.
*
* STATUS_TD_ACTIVE
* \param 0: Channel is not currently being serviced by DMAC
* \param 1: Channel is currently being serviced by DMAC
*
* STATUS_CHAIN_ACTIVE
* \param 0: TD chain is inactive; either no DMA requests have triggered a new chain
* or the previous chain has completed.
* \param 1: TD chain has been triggered by a DMA request
*
* \return CYRET_SUCCESS if successful.
* \return CYRET_BAD_PARAM if chHandle is invalid.
*
* Theory:
* The caller can check on the activity of the Current TD and the Chain.
*
*******************************************************************************/
cystatus CyDmaChStatus(uint8 chHandle, uint8 * currentTd, uint8 * state)
{
cystatus status = CYRET_BAD_PARAM;
if(chHandle < CY_DMA_NUMBEROF_CHANNELS)
{
if(NULL != currentTd)
{
*currentTd = CY_DMA_CH_STRUCT_PTR[chHandle].basic_status[1] & 0x7Fu;
}
if(NULL != state)
{
*state= CY_DMA_CH_STRUCT_PTR[chHandle].basic_status[0];
}
status = CYRET_SUCCESS;
}
return (status);
}
/*******************************************************************************
* Function Name: CyDmaChSetConfiguration
****************************************************************************//**
*
* Sets configuration information of the channel.
*
* \param uint8 chHandle:
* A handle previously returned by CyDmaChAlloc() or DMA_DmaInitialize().
*
* \param uint8 burstCount:
* Specifies the size of bursts (1 to 127) the data transfer should be divided
* into. If this value is zero then the whole transfer is done in one burst.
*
* \param uint8 requestPerBurst:
* The whole of the data can be split into multiple bursts, if this is
* \param required to complete the transaction:
* \param 0: All subsequent bursts after the first burst will be automatically
* requested and carried out
* \param 1: All subsequent bursts after the first burst must also be individually
* requested.
*
* \param uint8 tdDone0:
* Selects one of the TERMOUT0 interrupt lines to signal completion. The line
* connected to the nrq terminal will determine the TERMOUT0_SEL definition and
* should be used as supplied by cyfitter.h
*
* \param uint8 tdDone1:
* Selects one of the TERMOUT1 interrupt lines to signal completion. The line
* connected to the nrq terminal will determine the TERMOUT1_SEL definition and
* should be used as supplied by cyfitter.h
*
* \param uint8 tdStop:
* Selects one of the TERMIN interrupt lines to signal to the DMAC that the TD
* should terminate. The signal connected to the trq terminal will determine
* which TERMIN (termination request) is used.
*
* \return
* CYRET_SUCCESS if successful.
* CYRET_BAD_PARAM if chHandle is invalid.
*
*******************************************************************************/
cystatus CyDmaChSetConfiguration(uint8 chHandle, uint8 burstCount, uint8 requestPerBurst,
uint8 tdDone0, uint8 tdDone1, uint8 tdStop)
{
cystatus status = CYRET_BAD_PARAM;
if(chHandle < CY_DMA_NUMBEROF_CHANNELS)
{
CY_DMA_CFGMEM_STRUCT_PTR[chHandle].CFG0[0] = (burstCount & 0x7Fu) | ((uint8)((requestPerBurst & 0x1u) << 7u));
CY_DMA_CFGMEM_STRUCT_PTR[chHandle].CFG0[1] = ((uint8)((tdDone1 & 0xFu) << 4u)) | (tdDone0 & 0xFu);
CY_DMA_CFGMEM_STRUCT_PTR[chHandle].CFG0[2] = 0x0Fu & tdStop;
CY_DMA_CFGMEM_STRUCT_PTR[chHandle].CFG0[3] = 0u; /* burstcount_remain. */
status = CYRET_SUCCESS;
}
return (status);
}
/*******************************************************************************
* Function Name: CyDmaTdAllocate
****************************************************************************//**
*
* Allocates a TD for use with an allocated DMA channel.
*
* \return
* Zero-based index of the TD to be used by the caller. Since there are 128 TDs
* minus the reserved TDs (0 to 23), the value returned would range from 24 to
* 127 not 24 to 128. DMA_INVALID_TD is returned if there are no free TDs
* available.
*
*******************************************************************************/
uint8 CyDmaTdAllocate(void)
{
uint8 interruptState;
uint8 element = CY_DMA_INVALID_TD;
/* Enter critical section! */
interruptState = CyEnterCriticalSection();
if(CyDmaTdCurrentNumber > NUMBEROF_CHANNELS)
{
/* Get pointer to Next available. */
element = CyDmaTdFreeIndex;
/* Decrement the count. */
CyDmaTdCurrentNumber--;
/* Update next available pointer. */
CyDmaTdFreeIndex = CY_DMA_TDMEM_STRUCT_PTR[element].TD0[0];
}
/* Exit critical section! */
CyExitCriticalSection(interruptState);
return(element);
}
/*******************************************************************************
* Function Name: CyDmaTdFree
****************************************************************************//**
*
* Returns a TD to the free list.
*
* \param uint8 tdHandle:
* The TD handle returned by the CyDmaTdAllocate().
*
*******************************************************************************/
void CyDmaTdFree(uint8 tdHandle)
{
if(tdHandle < CY_DMA_NUMBEROF_TDS)
{
/* Enter critical section! */
uint8 interruptState = CyEnterCriticalSection();
/* Get pointer to Next available. */
CY_DMA_TDMEM_STRUCT_PTR[tdHandle].TD0[0u] = CyDmaTdFreeIndex;
/* Set new Next Available. */
CyDmaTdFreeIndex = tdHandle;
/* Keep track of how many left. */
CyDmaTdCurrentNumber++;
/* Exit critical section! */
CyExitCriticalSection(interruptState);
}
}
/*******************************************************************************
* Function Name: CyDmaTdFreeCount
****************************************************************************//**
*
* Returns the number of free TDs available to be allocated.
*
* \return
* The number of free TDs.
*
*******************************************************************************/
uint8 CyDmaTdFreeCount(void)
{
return(CyDmaTdCurrentNumber - CY_DMA_NUMBEROF_CHANNELS);
}
/*******************************************************************************
* Function Name: CyDmaTdSetConfiguration
****************************************************************************//**
*
* Configures the TD.
*
* \param uint8 tdHandle:
* A handle previously returned by CyDmaTdAlloc().
*
* \param uint16 transferCount:
* The size of the data transfer (in bytes) for this TD. A size of zero will
* cause the transfer to continue indefinitely. This parameter is limited to
* 4095 bytes; the TD is not initialized at all when a higher value is passed.
*
* \param uint8 nextTd:
* Zero based index of the next Transfer Descriptor in the TD chain. Zero is a
* valid pointer to the next TD; DMA_END_CHAIN_TD is the end of the chain.
* DMA_DISABLE_TD indicates an end to the chain and the DMA is disabled. No
* further TDs are fetched. DMA_DISABLE_TD is only supported on PSoC3 and
* PSoC 5LP silicons.
*
* \param uint8 configuration:
* Stores the Bit field of configuration bits.
*
* CY_DMA_TD_SWAP_EN - Perform endian swap
*
* CY_DMA_TD_SWAP_SIZE4 - Swap size = 4 bytes
*
* CY_DMA_TD_AUTO_EXEC_NEXT - The next TD in the chain will trigger
* automatically when the current TD completes.
*
* CY_DMA_TD_TERMIN_EN - Terminate this TD if a positive edge on the trq
* input line occurs. The positive edge must occur
* during a burst. That is the only time the DMAC
* will listen for it.
*
* DMA__TD_TERMOUT_EN - When this TD completes, the TERMOUT signal will
* generate a pulse. Note that this option is
* instance specific with the instance name followed
* by two underscores. In this example, the instance
* name is DMA.
*
* CY_DMA_TD_INC_DST_ADR - Increment DST_ADR according to the size of each
* data transaction in the burst.
*
* CY_DMA_TD_INC_SRC_ADR - Increment SRC_ADR according to the size of each
* data transaction in the burst.
*
* \return
* CYRET_SUCCESS if successful.
* CYRET_BAD_PARAM if tdHandle or transferCount is invalid.
*
*******************************************************************************/
cystatus CyDmaTdSetConfiguration(uint8 tdHandle, uint16 transferCount, uint8 nextTd, uint8 configuration) \
{
cystatus status = CYRET_BAD_PARAM;
if((tdHandle < CY_DMA_NUMBEROF_TDS) && (0u == (0xF000u & transferCount)))
{
/* Set 12 bits transfer count. */
reg16 *convert = (reg16 *) &CY_DMA_TDMEM_STRUCT_PTR[tdHandle].TD0[0u];
CY_SET_REG16(convert, transferCount);
/* Set Next TD pointer. */
CY_DMA_TDMEM_STRUCT_PTR[tdHandle].TD0[2u] = nextTd;
/* Configure the TD */
CY_DMA_TDMEM_STRUCT_PTR[tdHandle].TD0[3u] = configuration;
status = CYRET_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: CyDmaTdGetConfiguration
****************************************************************************//**
*
* Retrieves the configuration of the TD. If a NULL pointer is passed as a
* parameter, that parameter is skipped. You may request only the values you are
* interested in.
*
* \param uint8 tdHandle:
* A handle previously returned by CyDmaTdAlloc().
*
* \param uint16 * transferCount:
* The address to store the size of the data transfer (in bytes) for this TD.
* A size of zero could indicate that the TD has completed its transfer, or
* that the TD is doing an indefinite transfer.
*
* \param uint8 * nextTd:
* The address to store the index of the next TD in the TD chain.
*
* \param uint8 * configuration:
* The address to store the Bit field of configuration bits.
* See CyDmaTdSetConfiguration() function description.
*
* \return
* CYRET_SUCCESS if successful.
* CYRET_BAD_PARAM if tdHandle is invalid.
*
* \sideeffect
* If TD has a transfer count of N and is executed, the transfer count becomes
* 0. If it is reexecuted, the Transfer count of zero will be interpreted as a
* request for indefinite transfer. Be careful when requesting TD with a
* transfer count of zero.
*
*******************************************************************************/
cystatus CyDmaTdGetConfiguration(uint8 tdHandle, uint16 * transferCount, uint8 * nextTd, uint8 * configuration) \
{
cystatus status = CYRET_BAD_PARAM;
if(tdHandle < CY_DMA_NUMBEROF_TDS)
{
/* If we have pointer */
if(NULL != transferCount)
{
/* Get 12 bits of transfer count */
reg16 *convert = (reg16 *) &CY_DMA_TDMEM_STRUCT_PTR[tdHandle].TD0[0];
*transferCount = 0x0FFFu & CY_GET_REG16(convert);
}
/* If we have pointer */
if(NULL != nextTd)
{
/* Get Next TD pointer */
*nextTd = CY_DMA_TDMEM_STRUCT_PTR[tdHandle].TD0[2u];
}
/* If we have pointer */
if(NULL != configuration)
{
/* Get configuration TD */
*configuration = CY_DMA_TDMEM_STRUCT_PTR[tdHandle].TD0[3u];
}
status = CYRET_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: CyDmaTdSetAddress
****************************************************************************//**
*
* Sets the lower 16 bits of the source and destination addresses for this TD
* only.
*
* \param uint8 tdHandle:
* A handle previously returned by CyDmaTdAlloc().
*
* \param uint16 source:
* The lower 16 address bits of the source of the data transfer.
*
* \param uint16 destination:
* The lower 16 address bits of the destination of the data transfer.
*
* \return
* CYRET_SUCCESS if successful.
* CYRET_BAD_PARAM if tdHandle is invalid.
*
*******************************************************************************/
cystatus CyDmaTdSetAddress(uint8 tdHandle, uint16 source, uint16 destination)
{
cystatus status = CYRET_BAD_PARAM;
reg16 *convert;
if(tdHandle < CY_DMA_NUMBEROF_TDS)
{
/* Set source address */
convert = (reg16 *) &CY_DMA_TDMEM_STRUCT_PTR[tdHandle].TD1[0u];
CY_SET_REG16(convert, source);
/* Set destination address */
convert = (reg16 *) &CY_DMA_TDMEM_STRUCT_PTR[tdHandle].TD1[2u];
CY_SET_REG16(convert, destination);
status = CYRET_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: CyDmaTdGetAddress
****************************************************************************//**
*
* Retrieves the lower 16 bits of the source and/or destination addresses for
* this TD only. If NULL is passed for a pointer parameter, that value is
* skipped. You may request only the values of interest.
*
* \param uint8 tdHandle:
* A handle previously returned by CyDmaTdAlloc().
*
* \param uint16 * source:
* The address to store the lower 16 address bits of the source of the data
* transfer.
*
* \param uint16 * destination:
* The address to store the lower 16 address bits of the destination of the
* data transfer.
*
* \return
* CYRET_SUCCESS if successful.
* CYRET_BAD_PARAM if tdHandle is invalid.
*
*******************************************************************************/
cystatus CyDmaTdGetAddress(uint8 tdHandle, uint16 * source, uint16 * destination)
{
cystatus status = CYRET_BAD_PARAM;
reg16 *convert;
if(tdHandle < CY_DMA_NUMBEROF_TDS)
{
/* If we have a pointer. */
if(NULL != source)
{
/* Get source address */
convert = (reg16 *) &CY_DMA_TDMEM_STRUCT_PTR[tdHandle].TD1[0u];
*source = CY_GET_REG16(convert);
}
/* If we have a pointer. */
if(NULL != destination)
{
/* Get Destination address. */
convert = (reg16 *) &CY_DMA_TDMEM_STRUCT_PTR[tdHandle].TD1[2u];
*destination = CY_GET_REG16(convert);
}
status = CYRET_SUCCESS;
}
return(status);
}
/*******************************************************************************
* Function Name: CyDmaChRoundRobin
****************************************************************************//**
*
* Either enables or disables the Round-Robin scheduling enforcement algorithm.
* Within a priority level a Round-Robin fairness algorithm is enforced.
*
* \param uint8 chHandle:
* A handle previously returned by CyDmaChAlloc() or Dma_DmaInitialize().
*
* \param uint8 enableRR:
* \param 0: Disable Round-Robin fairness algorithm
* \param 1: Enable Round-Robin fairness algorithm
*
* \return
* CYRET_SUCCESS if successful.
* CYRET_BAD_PARAM if chHandle is invalid.
*
*******************************************************************************/
cystatus CyDmaChRoundRobin(uint8 chHandle, uint8 enableRR)
{
cystatus status = CYRET_BAD_PARAM;
if(chHandle < CY_DMA_NUMBEROF_CHANNELS)
{
if (0u != enableRR)
{
CY_DMA_CH_STRUCT_PTR[chHandle].basic_cfg[0u] |= (uint8)CY_DMA_ROUND_ROBIN_ENABLE;
}
else
{
CY_DMA_CH_STRUCT_PTR[chHandle].basic_cfg[0u] &= (uint8)(~CY_DMA_ROUND_ROBIN_ENABLE);
}
status = CYRET_SUCCESS;
}
return(status);
}
/* [] END OF FILE */