⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usboperation.asm

📁 dsp转换USB通讯程序样例
💻 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 + -