|
The first functions in this group allow you to claim EDMA channels from the kernel’s pool for your own use. You must use one of these functions before touching the EDMA hardware. Each of the functions returns an (EDMA_REG *) pointer to the allocated EDMA channel’s hardware registers, or NULL if the requested EDMA channel cannot be allocated. See EDMA.H in the Diamond installation folder for the names and types of the various structures’ members.
SC6xEDMA_Claim
#include <edma.h>
EDMA_REG *SC6xEDMA_Claim(SC6xEDMA *EdmaI,
int n,
SC6xEDMAChannel **c);
|
stand-alone
|
This function attempts to allocate EDMA channel number n from the kernel’s pool of free channels. If it succeeds, it returns a pointer to the requested channel’s hardware control registers. If it fails, it returns NULL.
|
EdmaI
|
must be a pointer to the kernel’s EDMA manager interface, as returned by a call to SC6xKernel_LocateInterface with a second argument of SIID_SC6xEDMA.
|
|
n
|
is the requested EDMA channel number. It must be in the range 0–15 by default. This range can be extended by selecting more EDMA channels for the processor in the configuration file.
|
|
c
|
is a pointer to an (SC6xEDMAChannel *) variable. The function sets this variable to point to an EDMA channel descriptor in the kernel. This pointer is used to refer to the allocated EDMA channel when calling the functions described later.
|
|
|
SC6xEDMA_ClaimWait
#include <edma.h>
EDMA_REG *SC6xEDMA_ClaimWait(SC6xEDMA *EdmaI,
int n,
SC6xEDMAChannel **c);
|
stand-alone
|
This function attempts to allocate EDMA channel number n from the kernel’s pool of free channels. If the requested channel is unavailable, the calling thread is suspended until it does become available, if ever. Therefore this function never fails simply because the requested channel is not available. When it succeeds, it returns a pointer to the requested channel’s hardware control registers. If it fails for some other reason, it returns NULL.
The arguments are the same as for SC6xEDMA_Claim above.
|
|
SC6xEDMA_ClaimAny
#include <edma.h>
EDMA_REG *SC6xEDMA_ClaimAny(SC6xEDMA *EdmaI,
int oper,
SC6xEDMAChannel **c);
|
stand-alone
|
This function is similar to SC6xEDMA_Claim, except that instead of requesting a particular channel number, the call returns a pointer to any EDMA channel that happens to be free. You can get the number of the channel, which may be needed to deal with interrupts, from the result by means of the macro EDMA_INDEX. If no channel is presently free, or if the call fails for some other reason, it returns NULL.
|
EdmaI
|
must be a pointer to the kernel’s EDMA manager interface, as returned by a call to SC6xKernel_LocateInterface with a second argument of SIID_SC6xEDMA.
|
|
oper
|
ignored: retained for compatibility with the older DMA functions.
|
|
c
|
is a pointer to an (SC6xEDMAChannel *) variable. The function sets this variable to point to an EDMA channel descriptor in the kernel. This pointer is used to refer to the allocated EDMA channel when calling the functions described later.
|
|
|
SC6xEDMA_ClaimAnyWait
#include <edma.h>
EDMA_REG *SC6xEDMA_ClaimAnyWait(SC6xEDMA *EdmaI,
int oper,
SC6xEDMAChannel **c);
|
stand-alone
|
This function is similar to SC6xEDMA_ClaimAny, except that if no channel is presently free, the calling thread is suspended (indefinitely) until a channel does become free. Therefore this function never fails simply because a channel is not available. When it succeeds, it returns a pointer to the allocated channel’s hardware control registers. If it fails for some other reason, it returns NULL.
The arguments are the same as for SC6xEDMA_ClaimAny above.
|
|
SC6xEDMA_FlushCache
#include <edma.h>
void SC6xEDMA_FlushCache(SC6xEDMA *EdmaI,
unsigned int Modify,
unsigned int Bytes,
volatile void *Memory);
|
stand-alone
|
This function is provided to control the cache when using EDMA. The C6000 cache on processors with EDMA is unable to maintain coherence with external memory when both the CPU and an EDMA channel access the memory. This means, for example, that it is possible for a CPU read of external memory to be satisfied with wrong data from the cache even though an EDMA operation has written new values directly to that memory.
|
EdmaI
|
must be a pointer to the kernel’s EDMA manager interface, as returned by a call to SC6xKernel_LocateInterface with a second argument of SIID_SC6xEDMA.
|
|
Modify
|
set non-zero if the EDMA transfer that is to follow modifies the memory; otherwise it should be 0.
|
|
Bytes
|
the size of the memory to be used in a subsequent EDMA transfer.
|
|
Memory
|
the address of the memory to be used in a subsequent EDMA transfer.
|
The function flushes any data in the cache corresponding to the external memory area defined by Bytes and Memory. If Modify is non-zero, the cache data is also invalidated.
The function does nothing if internal memory is specified or if the memory is in a non-cached region (the relevant MAR registers are 0).
To work round the hardware limitation it is necessary to manipulate the cache explicitly each time you perform an EDMA transfer involving external memory. You should stick to the following guidelines for each EDMA transfer:
1.
|
Ensure that the CPU cannot access any external memory associated with the EDMA transfer you are about to start. 'Associated' here includes memory that falls into the same cache line (128 bytes) as the memory specified in the EDMA transfer parameters. For example, the memory associated with a transfer of 32 bytes from A000003016 to B000012016 affects cache lines from from A000000016 to A000007F16 and from B000010016 to B000017F16. The simplest way to do this is to align buffers on 128-byte boundaries and make them multiples of 128 bytes. This is not always possible.
|
2.
|
Call SC6xEDMA_FlushCache before starting the transfer. You may need to call this function twice if the transfer is from external memory to external memory.
|
3.
|
Start the transfer.
|
4.
|
Once the transfer has completed, the CPU may safely access the affected memory.
|
This function can be quite slow asthe C6000 hardware requires polling to detect completion of the cache operation.
|
|
SC6xEDMA_ClaimParam
#include <edma.h>
EDMA_REG *SC6xEDMA_ClaimParam(SC6xEDMA *EdmaI,
unsigned int Which);
|
stand-alone
|
The parameters for EDMA operations are held in blocks of registers. This function returns a pointer to one such block. The parameter Which determines selects the block you want. If Which is 0, the function returns a pointer to the first free block it finds, otherwise the value (in the range 16 ≤Which ≤ 84) is used to select a particular block. Parameter block 85 is reserved for use as a terminating null block (see EDMA_NULL_PARAM).
The function returns a NULL pointer if a suitable parameter block cannot be claimed.
|
|
SC6xEDMA_ReleaseParam
#include <edma.h>
void SC6xEDMA_ReleaseParam(SC6xEDMA *EdmaI,
EDMA_REG *Param);
|
stand-alone
|
Release a parameter block for reuse. The block, Param, must have been claimed previously using SC6xEDMA_ClaimParam.
|
|
EDMA_INDEX
#include <edma.h>
unsigned int EDMA_INDEX(EDMA_REG *P);
|
stand-alone
|
This macro converts a pointer to a parameter block into the index number of the associated EDMA channel. It is only meaningful for the first 64 entries in the parameter table. It is usually used in conjunction with SC6xEDMA_ClaimAny and SC6xEDMA_ClaimAnyWait to determine which EDMA channel has been claimed.
|
|
EDMA_LINK_OFFSET
#include <edma.h>
unsigned int EDMA_LINK_OFFSET(EDMA_REG *P);
|
stand-alone
|
This macro converts a pointer to a parameter block into an offset from the start of the parameter area. This offset is required in the link field of one parameter block to chain it to the next.
|
|
EDMA_EVENT_PARAM
#include <edma.h>
EDMA_REG *EDMA_EVENT_PARAM(int n);
|
stand-alone
|
This macro converts a parameter number (in the range 0 ≤ n ≤ 85) into a pointer to the corresponding parameter block.
|
|
EDMA_NULL_PARAM
#include <edma.h>
EDMA_REG *EDMA_NULL_PARAM;
|
stand-alone
|
This macro returns a pointer to the reserved parameter block that has been initialised to zeros. You use it to terminate a chain of transfer requests.
|
|
|