📄 acpy2_start.c
字号:
/*
* Copyright 2002 by Texas Instruments Incorporated.
* All rights reserved. Property of Texas Instruments Incorporated.
* Restricted rights to use, duplicate or disclose this code are
* granted through contract.
*
*/
/* "@(#) XDAS 2.5.11 10-11-02 (xdas-d15)" */
/*
* ======== acpy2_start.c ========
* C model of the assembly code in acpy2_start.s62
*/
#pragma CODE_SECTION(ACPY2_start, ".text:ACPY2_start")
#include <std.h>
#include <hwi.h>
#include <csl_edma.h>
#include <_acpy2.h>
#include <idma2_priv.h>
static inline Void elemIdxAdjust(IDMA2_Handle handle, Uns * opt, Uns * idx,
Uns * cnt);
Void ACPY2_start(IDMA2_Handle handle, Void * src, Void * dst, Uns cnt)
{
Int csr;
Int temp; //variable used to check available TCCs
Int usedTCC; //actual TCC chosen for present transfer
Int alignment;
Uns opt = handle->config.opt;
Uns idx = handle->config.idx;
Uns * base = (Uns *)_EDMA_QOPT_ADDR; //base address of QDMA regs
//Check to see if element indexing is used
if ((handle->params.srcElementIndex != 0) ||
(handle->params.dstElementIndex != 0)) {
elemIdxAdjust(handle, &opt, &idx, &cnt);
}
else {
//Perform alignment checking to optimize transfer
alignment = 0;
if (handle->params.elemSize == IDMA2_ELEM32) {
if (handle->params.xType == IDMA2_1D1D) {
alignment = ((Uns)src | (Uns)dst);
}
else {
alignment = ((handle->params.srcElementIndex) |
(handle->params.dstElementIndex) |
(Uns)src | (Uns)dst);
}
if ((alignment & 0x1) == 0) { //at least 16-bit aligned
if ((alignment & 0x2) != 0) { //16bit xfer
cnt <<= 1;
opt |= 0x08000000;
}
}
else { //not aligned => 8 bit transfer needed
cnt <<= 2;
opt |= 0x10000000;
}
}
else if (handle ->params.elemSize == IDMA2_ELEM16) {
if (handle->params.xType == IDMA2_1D1D) {
alignment = ((Uns)src | (Uns)dst | (cnt << 1));
}
else {
alignment = ((handle->params.srcElementIndex) |
(handle->params.dstElementIndex) | (Uns)src
| (Uns)dst | (cnt << 1));
}
if ((alignment & 0x1) == 0) { //at least 16-bit aligned
if ((alignment & 0x2) == 0) { //32-bit xfers
cnt >>= 1;
opt &= 0xE7FFFFFF; //clear element size field
}
}
else { //not aligned => 8 bit transfer needed
cnt <<= 1;
opt &= 0xE7FFFFFF; //clear element size field
opt |= 0x10000000;
}
}
else {
if ((handle->params.xType) != IDMA2_1D1D) {
alignment = ((handle->params.srcElementIndex) |
(handle->params.dstElementIndex) | (Uns)src | (Uns)dst
| cnt);
}
else {
alignment = ((Uns)src | (Uns) dst | (Uns)cnt);
}
if ((alignment & 0x1) == 0) { //at least 16-bit aligned
cnt >>= 1;
opt &= 0xE7FFFFFF; //clear element size field
opt |= 0x08000000;
if ((alignment & 0x2) == 0) { //32 bit xfer
opt &= 0xE7FFFFFF; //clear element size field
cnt >>= 1;
}
}
}
}
//Disable interrupts when modifying QDMA registers
csr = HWI_disable();
//Determines if there are TCCs available for ACPY2's use
temp = EDMA_RGET(CIPR) & _ACPY2_TCCmask;
base[_EDMA_QSRC_OFFSET] = (Uns)src;
base[_EDMA_QDST_OFFSET] = (Uns)dst;
while(temp == 0)
{
HWI_restore(csr);
csr = HWI_disable();
temp = EDMA_RGET(CIPR) & _ACPY2_TCCmask;
base[_EDMA_QSRC_OFFSET] = (Uns)src;
base[_EDMA_QDST_OFFSET] = (Uns)dst;
}
//Calculate the TCC number used
usedTCC = 31 - _lmbd(1, temp);
//Clear TCC bit in CIPR to record next transfer completion event
EDMA_RSET(CIPR,1 << usedTCC);
//Record in TCC table as the last handle to have used this TCC
_ACPY2_TCCTable[usedTCC] = handle;
//Record this TCC as the last TCC used by this handle
handle->lastTCC = usedTCC;
//Write to QDMA registers.
base[_EDMA_QIDX_OFFSET] = idx;
base[_EDMA_QOPT_OFFSET] = opt | (usedTCC << 16);
if(handle->params.xType != IDMA2_1D1D)
{
base[_EDMA_QSCNT_OFFSET] = (handle->config).cnt + (Uns)cnt;
}
else
{
base[_EDMA_QSCNT_OFFSET] = (Uns)cnt;
}
HWI_restore(csr); //reenable interrupts
}
static inline Void elemIdxAdjust(IDMA2_Handle handle, Uns * opt, Uns * idx,
Uns * cnt)
{
Uns elementSize;
/*
* When element index is used, go with the conservative approach
* to schedule everything as 8-bit transfers to ensure there is no
* alignment issues
*/
*opt &= 0xE7FFFFFF; //clear element size field
*opt |= 0x10000000; // Mask for 8-bit element size
//elementSize = {1 (for 8bit), 2 (for 16bit), 4 for (32bit)}
elementSize = (handle->params.elemSize) * 2;
if (elementSize == 0) {
elementSize++;
}
//new FIdx = EIdx - esize
*idx = (handle->config.idx - elementSize) << 16;
//new numFrames = cnt - 1
*cnt -= 1;
*cnt = *cnt << 16;
//new # element/frame = element size
*cnt = *cnt + elementSize;
*opt &= 0xFC9FFFFF; //clear SUM and DUM addressing fields
if ((handle->params.srcElementIndex != 0) &&
(handle->params.dstElementIndex != 0)) {
//set as 2D2D transfer if both element indices are set
*opt |= 0x05A00000;
}
else if (handle->params.srcElementIndex == 0) {
//set as 1D2D transfer if only dstEIdx is used
*opt |= 0x01A00000;
}
else if (handle->params.dstElementIndex == 0) {
//set as 2D1D transfer if only srcEIdx is used
*opt |= 0x05200000;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -