📄 acpy2_start.s62
字号:
;; 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)";******************************************************************************
;* Hand-assembled ACPY2_start()
;******************************************************************************
;
;******************************************************************************
;*
;* This function follows the following steps to submit a DMA transfer request:
;* 1. Check if element indexing is used, if yes convert the transfer into
;* an equivalent 2D 8-bit transfer.
;* If not, verify the alignment of the src addr, dst addr, cnt and
;* frmIdx and configure the transfer to use the highest element size
;* possible to improve DMA performance (e.g. 32 bit transfers are faster
;* than 16 and 8 bit transfers)
;* 2. Disable interrupts, check the CIPR register for available TCCs.
;* If nothing is available, re-enable interrupts and repeat this step
;* til a TCC bit is set in the CIPR.
;* 3. Record the handle in the entry in ACPY2_TCCTable corresponding to the
;* TCC used.
;* 4. Update the last TCC field in the IDMA2_Obj pointed to by the handle
;* argument with the number of the TCC bit used.
;* 5. Write to QDMA registers to initiate tranfer
;* 6. Re-enable interrupts and return from function
;*
;* USAGE
;* This routine has the following C prototype:
;*
;* Void ACPY2_start
;* (
;* IDMA2_Handle handle,
;* Void * src,
;* Void * dst,
;* Uns cnt,
;* )
;*
;* handle : Logical channel handle
;* src : source data address
;* dst : destination data address
;* cnt : number of elements to be transferred
;*
;* C CODE
;* 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -