📄 usboperation.asm
字号:
#include "defBF531.h"
#include "BF531_USB_Head.h"
#define Fx2Ep2_Addr 0x20220000
#define Fx2Ep4_Addr 0x20220010
#define Fx2Ep6_Addr 0x20220020
#define Fx2Ep8_Addr 0x20220030
/*
#define Fx2Ep2_Addr 0x20220000
#define Fx2Ep4_Addr 0x20220008
#define Fx2Ep6_Addr 0x20220010
#define Fx2Ep8_Addr 0x20220018
*/
.extern Ch1Vol,Ch2Vol,Ch3Vol,Ch4Vol,OutPutGainTableForAllCh;
.extern UsbRxBuf,UsbTxBuf,USBFrameIndex;
.extern UsDelay;
.extern UsbAudioBuffer;
.extern UsbABuf_RPtr,UsbABuf_RPtrPre,UsbABuf_RPtrPst;
.extern UsbABuf_WPtr,UsbABuf_WPtrPre,UsbABuf_WPtrPst;
.extern UsbABuf_RWPtrSamePage;
.extern UsbABuf_WBeyondR_Distance;
.extern _28ReservedByteBuffer;
.extern PKTENDOut;
.extern Led0Tgl,Led0Off,Led0On;
.extern Led1Tgl,Led1Off,Led1On;
.extern Led2Tgl,Led2Off,Led2On;
.extern Led3Tgl,Led3Off,Led3On;
.section SECTION_Code2;
/*****************************************************************************
CheckFx2Fifo:
check FlagA 4 times, with interval of FlagACheckingInterval.
if all 4 times sample of Flag is high, that means FX2 EP2 is ready
and waits DSP to read 64bytes inside its FIFO
result is in R0, 0 means FX2 EP2 FIFO not ready
1 means FX2 EP2 FIFO is ready
//
******************************************************************************/
.global CheckFx2Fifo;
CheckFx2Fifo:
[ --SP ] = RETS;
//get EP2 empty flag form FX2 4 times, at 15us interval
p0.l = lo(FIO_FLAG_S);
p0.h = hi(FIO_FLAG_S);
r0.l=w[ p0 ]; //PF5 is FlagA_EP2Empty from FX2
r1=0x00000020;
r4=r0 & r1; //r4 stores the 1st FlagA_EP2Empty sample result
r4.h=0;
//call Led1Tgl;
r0=FlagACheckingInterval;
call UsDelay;
p0.l = lo(FIO_FLAG_S);
p0.h = hi(FIO_FLAG_S);
r0.l=w[ p0 ]; //PF5 is FlagA_EP2Empty from FX2
r1=0x00000020;
r5=r0 & r1; //r5 stores the 2nd FlagA_EP2Empty sample result
r5.h=0;
//call Led1Tgl;
r0=FlagACheckingInterval;
call UsDelay;
p0.l = lo(FIO_FLAG_S);
p0.h = hi(FIO_FLAG_S);
r0.l=w[ p0 ]; //PF5 is FlagA_EP2Empty from FX2
r1=0x00000020;
r6=r0 & r1; //r6 stores the 3ed FlagA_EP2Empty sample result
r6.h=0;
//call Led1Tgl;
r0=FlagACheckingInterval;
call UsDelay;
p0.l = lo(FIO_FLAG_S);
p0.h = hi(FIO_FLAG_S);
r0.l=w[ p0 ]; //PF5 is FlagA_EP2Empty from FX2
r1=0x00000020;
r7=r0 & r1; //r7 stores the 4th FlagA_EP2Empty sample result
r7.h=0;
//call Led1Tgl;
//if all 4 times FlagA_EP2Empty is high, that means FX2 EP2 fifo
//is ready, contains 64 USB bytes, and waits for DSP to read
//r4=0x0; //ttttttttttttttttttt
//r5=0x0; //ttttttttttttttttttt
//r6=0x0; //ttttttttttttttttttt
//r7=0x0; //ttttttttttttttttttt
cc=r4==0;
if cc jump Fx2FlagAIsNotHigh;
cc=r5==0;
if cc jump Fx2FlagAIsNotHigh;
cc=r6==0;
if cc jump Fx2FlagAIsNotHigh;
cc=r7==0;
if cc jump Fx2FlagAIsNotHigh;
Fx2FlagAIsHigh:
r0=1; //result is in R0, 1 means FX2 EP2 FIFO is ready
jump CheckFx2FifoFinish;
Fx2FlagAIsNotHigh:
r0=0; //result is in R0, 0 means FX2 EP2 FIFO is not ready
CheckFx2FifoFinish:
RETS = [ SP++ ];
rts;
CheckFx2Fifo.end:
/*****************************************************************************
Get512BytesFromFx2:
first check FX2 FIFO is ready or not by checking r0:
if r0=0 then exit
then check if USBAudioSlotWriteID=0, if is, there is no space for this USB frame
leave to next cycle, exit
if not, save audio from FX2 into aera pointed
by USBAudioSlotWriteID
******************************************************************************/
.global Get512BytesFromFx2;
Get512BytesFromFx2:
[ --SP ] = RETS;
//first check r0, if r0=0 then exit
cc=r0==0;
if cc jump Get512BytesFromFx2Finish;
//then check WBeyondR_Distance
//if WBeyondR_Distance<60*8 then AudioBuffer free size is enough
// for sotring the 60 samples in the Fx2 fifo
// and go to get the 60 audio samples
//if WBeyondR_Distance>=60*8 then AudioBuffer free size is not enough
// for sotring the 60 samples in the Fx2 fifo
// and not to read the Fx2 fifo
p0.h=UsbABuf_WBeyondR_Distance;
p0.l=UsbABuf_WBeyondR_Distance;
r0=[ p0 ];
r1=(60*(UsbAudioBufferSlotSize-1)-10);
cc=r0<r1;
if !cc jump Get512BytesFromFx2Finish;
Get512BytesFromFx2Start:
call Led2Tgl;
//prepare p0 for Fx2 Fifo Address
p0.h=hi(Fx2Ep2_Addr);
p0.l=lo(Fx2Ep2_Addr);
//FrameHead Audit here
r0.l=w[ p0 ]; //read Fx2 USB frame byte0
r1.l=w[ p0 ]; //read Fx2 USB frame byte1
r2.l=0x00ff;
r0=r0 & r2;
r1=r1 & r2;
r0=1;r1=2; //ZZZZZZZZZZZZZZZZZZZ
cc=r0==1;
if !cc jump USBFrameHeadAuditFail;
cc=r1==2;
if !cc jump USBFrameHeadAuditFail;
USBFrameHeadAuditOK:
//get the following 28 reserved bytes and save to researved bytes buffer
//prepare the destination pointer to _28ReservedByteBuffer
p1.h=_28ReservedByteBuffer;
p1.l=_28ReservedByteBuffer;
p2=28;
r1.l=0x00ff;
lsetup(HeadAuditOKGetReservedBytesLoop_start,HeadAuditOKGetReservedBytesLoop_end) lc0=p2;
HeadAuditOKGetReservedBytesLoop_start:
r0.l=w[ p0 ]; //data read from Fx2 is useless, cause Head audit is failed
r0=r0&r1;
w[ p1 ]=r0.l;
HeadAuditOKGetReservedBytesLoop_end:
p1+=2;
//WptrPre=Wptr
p1.h=UsbABuf_WPtr;
p1.l=UsbABuf_WPtr;
p2.h=UsbABuf_WPtrPre;
p2.l=UsbABuf_WPtrPre;
r0=[ p1 ];
[ p2 ]=r0;
//get 60 samples of Ch1~Ch4 and save to WPtr
//prepare circular buffer of UsbAudioBuf
l0=240*UsbAudioBufferSlotSize*2;
r1.l=(UsbAudioBuffer);
r1.h=(UsbAudioBuffer);
b0=r1;
i0=r0; //the destination
m0=2;
p2=240;
r2.l=0x00ff;
lsetup(HeadAuditOKGet60SamplesLoop_start,HeadAuditOKGet60SamplesLoop_end) lc0=p2;
HeadAuditOKGet60SamplesLoop_start:
r0.l=w[ p0 ]; //read sample L byte
r1.l=w[ p0 ]; //read sample H byte
r0=r0&r2;
r1<<=8;
r0=r0|r1;
w[ i0 ]=r0.l;
HeadAuditOKGet60SamplesLoop_end:
i0+=m0;
//save Wptr, and WptrPst=Wptr
p1.h=UsbABuf_WPtr;
p1.l=UsbABuf_WPtr;
r0=i0;
[ p1 ]=r0;
p2.h=UsbABuf_WPtrPst;
p2.l=UsbABuf_WPtrPst;
[ p2 ]=r0;
//FrameTail Audit here
r0.l=w[ p0 ]; //read Fx2 USB frame byte0
r1.l=w[ p0 ]; //read Fx2 USB frame byte1
r2.l=0x00ff;
r0=r0 & r2;
r1=r1 & r2;
r0=2;r1=1; //ZZZZZZZZZZZZZZZZZZZ
cc=r0==2;
if !cc jump USBFrameTailAuditFail;
cc=r1==1;
if !cc jump USBFrameTailAuditFail;
USBFrameTailAuditOK:
//the 28 reserved byte is OK, and take out
//USBFrameIndex,Ch1Vol,Ch2Vol,Ch3Vol,Ch4Vol
p0.h=USBFrameIndex;
p0.l=USBFrameIndex;
r0=[ p0 ];
r1=0x00ff;
r0=r0&r1;
p1.h=_28ReservedByteBuffer;
p1.l=_28ReservedByteBuffer;
r6.h=OutPutGainTableForAllCh;
r6.l=OutPutGainTableForAllCh;
r5.l=w[ p1 ]; p1+=2; //FrameIndex
r1.l=w[ p1 ]; p1+=2; //Ch1Vol
r2.l=w[ p1 ]; p1+=2; //Ch2Vol
r3.l=w[ p1 ]; p1+=2; //Ch3Vol
r4.l=w[ p1 ]; p1+=2; //Ch4Vol
r7.l=w[ p1 ]; //FrameIndex clear flag
r7.h=0;
//IndexID audit, (but result is not critical, just for evaluation)
//if r7=1 then to clear FIndex
cc=r7==1;
if cc jump ToClearFrameIndex;
NotToClearFrameIndex:
cc=r0==r5;
if cc jump UsbFrameIndexAuditOK;
UsbFrameIndexAuditFail:
call Led3On;
nop;
UsbFrameIndexAuditOK:
r0+=1;
[ p0 ]=r0;
jump FrameIndexAuditFinish;
ToClearFrameIndex:
r0=1;
[ p0 ]=r0; //clear frame index
call Led3Off;
FrameIndexAuditFinish:
//if ChXVol is leagal, update the volume
r0=20;
cc=r0<r1;
if cc jump _28ReservedByteProcessSkipCh1VolUpdate;
//update Ch1 Volume
r1<<=1;
r7=r6+r1;
p2=r7;nop;nop;nop;
r1.l=w[ p2 ];
p2.h=Ch1Vol;
p2.l=Ch1Vol;
w[ p2 ]=r1.l;
_28ReservedByteProcessSkipCh1VolUpdate:
cc=r0<r2;
if cc jump _28ReservedByteProcessSkipCh2VolUpdate;
//update Ch1 Volume
r2<<=1;
r7=r6+r2;
p2=r7;nop;nop;nop;
r2.l=w[ p2 ];
p2.h=Ch2Vol;
p2.l=Ch2Vol;
w[ p2 ]=r2.l;
_28ReservedByteProcessSkipCh2VolUpdate:
cc=r0<r3;
if cc jump _28ReservedByteProcessSkipCh3VolUpdate;
//update Ch1 Volume
r3<<=1;
r7=r6+r3;
p2=r7;nop;nop;nop;
r3.l=w[ p2 ];
p2.h=Ch3Vol;
p2.l=Ch3Vol;
w[ p2 ]=r3.l;
_28ReservedByteProcessSkipCh3VolUpdate:
cc=r0<r4;
if cc jump _28ReservedByteProcessSkipCh5VolUpdate;
//update Ch1 Volume
r4<<=1;
r7=r6+r4;
p2=r7;nop;nop;nop;
r4.l=w[ p2 ];
p2.h=Ch4Vol;
p2.l=Ch4Vol;
w[ p2 ]=r4.l;
_28ReservedByteProcessSkipCh5VolUpdate:
//UsbABuf_RWPtrSamePage update
//if WPtrPos-WPtrPre < 0 then RWPtrSamePage*=-1
p0.h=UsbABuf_WPtrPre;
p0.l=UsbABuf_WPtrPre;
p1.h=UsbABuf_WPtrPst;
p1.l=UsbABuf_WPtrPst;
r0=[ p0 ];
r1=[ p1 ];
r1=r1-r0;
cc=r1<0;
if !cc jump NotToNeg_RWPtrSamePage;
ToNeg_RWPtrSamePage:
p0.h=UsbABuf_RWPtrSamePage;
p0.l=UsbABuf_RWPtrSamePage;
r0=[ p0 ];
r0= -r0;
[ p0 ]=r0;
NotToNeg_RWPtrSamePage:
nop;
//update UsbABuf_WBeyondR_Distance
p0.h=UsbABuf_RWPtrSamePage;
p0.l=UsbABuf_RWPtrSamePage;
r0=[ p0 ];
cc=r0<0;
if cc jump RWPtrIsNotInSamePage_;
RWPtrIsInSamePage_:
//the distance that WPtr beyond RPtr is:
//d=(Wptr-RPte)>>3;
p0.h=UsbABuf_RPtr;
p0.l=UsbABuf_RPtr;
p1.h=UsbABuf_WPtr;
p1.l=UsbABuf_WPtr;
r0=[ p0 ];
r1=[ p1 ];
r1=r1-r0;
r1>>=3;
p0.h=UsbABuf_WBeyondR_Distance;
p0.l=UsbABuf_WBeyondR_Distance;
[ p0 ]=r1;
jump Get512BytesFromFx2Finish;
RWPtrIsNotInSamePage_:
//the distance that WPtr beyond RPtr is:
//d=(Wptr+240*UsbAudioBufferSlotSize*2-RPte)>>3;
p0.h=UsbABuf_RPtr;
p0.l=UsbABuf_RPtr;
p1.h=UsbABuf_WPtr;
p1.l=UsbABuf_WPtr;
r0=[ p0 ];
r1=[ p1 ];
r1=r1-r0;
r0=240*UsbAudioBufferSlotSize*2;
r1=r1+r0;
r1>>=3;
p0.h=UsbABuf_WBeyondR_Distance;
p0.l=UsbABuf_WBeyondR_Distance;
[ p0 ]=r1;
jump Get512BytesFromFx2Finish;
USBFrameTailAuditFail:
call Led3On;
//WPtr go back 60, i.e. WPtr=WPtrPre
p1.h=UsbABuf_WPtr;
p1.l=UsbABuf_WPtr;
p2.h=UsbABuf_WPtrPre;
p2.l=UsbABuf_WPtrPre;
r0=[ p2 ];
[ p1 ]=r0;
jump Get512BytesFromFx2Finish;
USBFrameHeadAuditFail:
call Led3On;
//Head audit failed, then read the left 510 bytes from Fx2 to clear Fx2's fifo
//these bytes are useless
p1=512;
lsetup(HeadAuditFailClearFx2FifoLoop_start,HeadAuditFailClearFx2FifoLoop_end) lc0=p1;
HeadAuditFailClearFx2FifoLoop_start:
r0.l=w[ p0 ]; //data read from Fx2 is useless, cause Head audit is failed
HeadAuditFailClearFx2FifoLoop_end:
nop;
Get512BytesFromFx2Finish:
RETS = [ SP++ ];
rts;
Get512BytesFromFx2.end:
.global UsbOperationVarInit;
UsbOperationVarInit:
[ --SP ] = RETS;
p0.h=UsbABuf_WPtr;
p0.l=UsbABuf_WPtr;
r0.h=UsbAudioBuffer;
r0.l=UsbAudioBuffer;
[ p0 ]=r0;
p0.h=UsbABuf_RPtr;
p0.l=UsbABuf_RPtr;
r0.h=UsbAudioBuffer;
r0.l=UsbAudioBuffer;
[ p0 ]=r0;
p0.h=UsbABuf_RWPtrSamePage;
p0.l=UsbABuf_RWPtrSamePage;
r0=1;
[ p0 ]=r0;
p0.h=UsbABuf_WBeyondR_Distance;
p0.l=UsbABuf_WBeyondR_Distance;
r0=0;
[ p0 ]=r0;
RETS = [ SP++ ];
rts;
UsbOperationVarInit.end:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -