📄 acpy2_startaligned.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_startAligned()
;******************************************************************************
;
;******************************************************************************
;*
;* This function follows the following steps to submit a DMA transfer request:
;* 1. 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.
;* 2. Record the handle in the entry in ACPY2_TCCTable corresponding to the
;* TCC used.
;* 3. Update the last TCC field in the IDMA2_Obj pointed to by the handle
;* argument with the number of the TCC bit used.
;* 4. Write to QDMA registers to initiate tranfer
;* 5. Re-enable interrupts and return from function
;*
;* DISCLAIMER: THIS API IS PRESENTLY UNDER REVIEW. IT IS NOT
;* PART OF THE CURRENT XDAIS SPECIFICATIONS AND SHOULD NOT BE USED
;* IN PRODUCTION CODE.
;*
;* USAGE
;* This routine has the following C prototype:
;*
;* Void ACPY2_startAligned
;* (
;* 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_startAligned(IDMA2_Handle handle, Void * src, Void *dst, Uns cnt)
;* {
;* Int csr;
;* Int temp;
;* Int usedTCC;
;* Uns * base = (Uns *)_EDMA_QOPT_ADDR; //base address of QDMA regs
;*
;* //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] = (handle->config).idx;
;* base[_EDMA_QOPT_OFFSET] = (handle->config).opt | (usedTCC << 16);
;* if(handle->params.xType != IDMA2_1D1D)
;* {
;* base[_EDMA_QSCNT_OFFSET] = (handle->config).cnt + cnt;
;* }
;* else
;* {
;* base[_EDMA_QSCNT_OFFSET] = (Uns)cnt;
;* }
;*
;* HWI_restore(csr); //reenable interrupts
;*
;* }
;*
;*
;* NOTES
;* This code is interrupt tolerant and is interruptible until a TCC in the
;* CIPR becomes available for use, in the event of which interrupts will
;* become disabled.
;*
;* ENDIANNESS
;* Little
;*
;* BEST CASE CYCLES
;* 61 cycles
;*
;* CODESIZE
;* 192 bytes
;*
;******************************************************************************
.include acpy2_6x1x.h62
.include c62.h62
.sect ".text:ACPY2_startAligned"
.def _ACPY2_startAligned
.ref __ACPY2_TCCmask,__ACPY2_TCCTable
_ACPY2_startAligned:
MVKL __ACPY2_TCCmask,A3
|| MVKL 0x1a0ffe4,B1 ;B1 contains address of CIPR
|| LDW *+A4(IDMA2_O_OPT),B8
MVKH __ACPY2_TCCmask,A3
|| MVKH 0x1a0ffe4,B1 ;B1 contains address of CIPR
|| LDW *+A4(IDMA2_O_XTYPE),A5
;QDMA base reg = _EDMA_QOPT_ADDR (was an MVKL inst. originally)
|| ZERO A7
LDW *A3,A3 ;A3 contains ACPY2_TCCmask
|| MV B1,A9 ;A9 contains address of CIPR
pollingLoop:
;Disable interrupts
B dummyLabel
|| LDW *A9,A0 ;CIPR is in A0
MVC CSR,B1 ;B1 contains old CSR value
|| MVKH 0x2000000,A7 ;QDMA base reg = (_EDMA_QOPT_ADDR)
AND B1,~GIE,A2
|| MVKL __ACPY2_TCCTable,B2 ;Set up regs to update TCC Table
MVC A2, CSR ;Clear GIE bit
MV A5,A1 ;Putting xType into cond. reg.
AND A0,A3,A2 ;A2 == 1 implies a TCC is available
dummyLabel:
[!A2] B pollingLoop ;Branch until a TCC is available
||[!A2] MVC B1,CSR ;Reenable interrupts for a short time
||[!A2] ZERO A1 ;Avoid executing the last statement in loop
||[ A2] LDW *+A4(IDMA2_O_IDX),A8
[ A2] MVKL 0x001f,A3
||[ A2] STW B4,*+A7(CONFIG_O_SRC)
||[ A2] LMBD 1,A2,B0 ;B0 contains the left-most TCC bit set in CIPR
[ A2] SUB A3,B0,B0 ;B0 contains the number of the TCC available
||[ A2] MVKL 0x0001,B7
||[ A2] STW A6,*+A7(CONFIG_O_DST)
[ A2] SHL B7,B0,B7
||[ A2] STW B0,*+A4(IDMA2_O_LASTTCC) ;Update last TCC used for this handle
[ A2] STW B7,*A9 ;Write to CIPR to reset TCC
||[ A2] MVKH __ACPY2_TCCTable,B2 ;Set up regs to update TCC Table
||[ A2] MV B0,B5
[ A1] LDW *+A4(IDMA2_O_CNT),A0 ;Not executed if no TCC available
;Set all QDMA registers and return
B B3 ;function return
|| STW A4,*+B2[B5] ;Update TCCtable
SHL B0,16,B0 ;TCC number is shifted to upper 16 bits
STW A8,*+A7(CONFIG_O_IDX)
|| OR B0,B8,B8 ;B8 = (handle->config).opt | (ACPY2_temp<<16)
STW B8,*+A7(CONFIG_O_OPT)
[ A1] ADD B6,A0,B6 ;B6 now contains the value for QSCNT
|| MVC B1,CSR ;Reenable interrupts
STW B6,*+A7(CONFIG_O_SCNT) ;Write to QSCNT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -