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

📄 ad1836_reg_init_viasports.asm

📁 语音信号进行Fir滤波
💻 ASM
字号:
/***   SPORTs1&3_SPI_Emulation.ASM   ********************************************
*                                                                               *
*       AD1836/ADSP-21161 SPI Code Register Initialization via SPI Emulation    *
*                                                                               *
*                                                                               *
*********************************************************************************/

/* ADSP-21161 System Register bit definitions */
/*  refer to latest DEF21161.H file for SPORT bitfield definitions */
#include 	"def21161.h"

.GLOBAL		Program_AD1836_regs_via_SPI;
.GLOBAL 	Count_SPORT1_RX_IRQs;
.GLOBAL 	Count_SPORT3_TX_IRQs;
//.EXTERN		Wait_Approx_999us;
.GLOBAL		Wait_Approx_1500ms;
.GLOBAL		Wait_Approx_167ms;

// AD1836 codec SPI control/status register definitions
#define		READ_REG		0x0800
#define		WRITE_REG		0x0000
#define		DAC_CONTROL1	0x0000
#define		DAC_CONTROL2	0x1000
#define		DAC_VOLUME0		0x2000
#define		DAC_VOLUME1		0x3000
#define		DAC_VOLUME2		0x4000
#define		DAC_VOLUME3		0x5000
#define		DAC_VOLUME4		0x6000
#define		DAC_VOLUME5		0x7000
#define		ADC0_PEAK_LEVEL	0x8000
#define		ADC1_PEAK_LEVEL	0x9000
#define		ADC2_PEAK_LEVEL	0xA000
#define		ADC3_PEAK_LEVEL	0xB000
#define		ADC_CONTROL1	0xC000
#define		ADC_CONTROL2	0xD000
#define		ADC_CONTROL3	0xE000
#define		RESERVED_REG	0xF000

.SEGMENT/dm dm_data;
 
/* Powerdown ADCs and DACs twice to get around AD1836 SPI/powerdown anomaly */
.var powerdown_AD1836[4] = 	DAC_CONTROL1 | WRITE_REG | 0x004, 	
							DAC_CONTROL1 | WRITE_REG | 0x004,
							ADC_CONTROL1 | WRITE_REG | 0x080, 	
							ADC_CONTROL1 | WRITE_REG | 0x080;
.var powerdown_rx_buf0a[4]; // rx dma dummy buffer not used for anything;

// 	AD1836 codec register commands - Serial SPI 16-bit Word Format as follows:
// 			D15 to D12 	= Codec Register Address
//			D11 		= Read/Write register (1=rd, 0=wr)
//			D10 		= reserved bit, clear to zero
//			D9 to D0 	= Data Field for codec register

.var tx_buf3a[21] = //program register commands
					DAC_CONTROL1 | WRITE_REG | 0x000, 	// we "OR" in address, rd/wr, and register data
					DAC_CONTROL1 | WRITE_REG | 0x000,	// for ease in reading register values	
					DAC_CONTROL2 | WRITE_REG | 0x000,	// write DAC_CTL1 twice to workaround pwdwn SPI anomaly
					DAC_VOLUME0  | WRITE_REG | 0x3FF,
					DAC_VOLUME1  | WRITE_REG | 0x3FF,
					DAC_VOLUME2  | WRITE_REG | 0x3FF,
					DAC_VOLUME3  | WRITE_REG | 0x3FF,
					DAC_VOLUME4  | WRITE_REG | 0x3FF,
					DAC_VOLUME5  | WRITE_REG | 0x3FF,
					ADC_CONTROL1 | WRITE_REG | 0x000,	// write ADC_CTL1 twice to workaround pwdwn SPI anomaly
					ADC_CONTROL1 | WRITE_REG | 0x000,
					ADC_CONTROL3 | WRITE_REG | 0x000,	// 256*Fs Clock Mode !!!, differential PGA mode
					ADC_CONTROL2 | WRITE_REG | 0x380,	// SOUT MODE = 110 --> TDM Mode, Master device
					ADC_CONTROL2 | WRITE_REG | 0x380,
					// read register commands
					ADC0_PEAK_LEVEL | READ_REG | 0x000, // status will be in rx_buf1a[13-19] memory locations	
					ADC1_PEAK_LEVEL | READ_REG | 0x000,
					ADC2_PEAK_LEVEL | READ_REG | 0x000,
					ADC3_PEAK_LEVEL | READ_REG | 0x000,
					ADC_CONTROL1 	| READ_REG | 0x000,
					ADC_CONTROL2 	| READ_REG | 0x000,
					ADC_CONTROL3 	| READ_REG | 0x000;	
.var rx_buf1a[21];

/* ISR counters, for debug purposes to see how many times SPORT DMA interrupts are serviced */
.VAR		SP1I_counter = 0;
.VAR		SP3I_counter = 0;

.endseg;

.segment /pm pm_code;

/////////////////////////////////////////////////////////////////////////////////////////
//	                                                                                   //
//           Program SPORT1 & SPORT3 Control Registers for SPI emulation control       //	
//                                                                                     //
/////////////////////////////////////////////////////////////////////////////////////////

Program_AD1836_regs_via_SPI:
		r0=0x00000000;							// initially clear SPORT control register
		dm(SPCTL1)=r0;
	    dm(SPCTL3)=r0; 
  		ustat1=dm(SPCTL3);
  		ustat2=dm(SPCTL1);		
		ustat3=dm(SP13MCTL);

powerdown_reset_AD1836:
		r0=powerdown_AD1836;	dm(II3A)=r0;    /* Internal DMA6 memory address		      		*/	   
 		r0=1;					dm(IM3A)=r0;	/* Internal DMA6 memory access modifier	      	*/   	 
		r0=@powerdown_AD1836;	dm(C3A)=r0;	 	/* Contains number of DMA6 transfers to be done */

		r0=powerdown_rx_buf0a;	dm(II1A)=r0;	/* Internal DMA2 memory address		      		*/
 		r0=1;					dm(IM1A)=r0;	/* Internal DMA2 memory access modifier	      	*/   	  
		r0=@powerdown_rx_buf0a;	dm(C1A)=r0;		/* Contains number of DMA2 transfers to be done */

		/* clear multichannel/miscellaneous control register for SPORT1 & SPORT3 */
		R0 = 0x0; 			dm(SP13MCTL) = R0;
		R0 = 0x0011002B;	dm(DIV3) = R0;
   		R0 = 0;				dm(DIV1) = R0;	
				 
		bit set ustat1 DDIR | SDEN_A | LAFS | LFS |  IFS | FSR | CKRE | ICLK | SLEN16 | SPEN_A;
		dm(SPCTL3) = ustat1;
		
		bit set ustat2 SDEN_A | LAFS | LFS | FSR | CKRE | SLEN16 | SPEN_A; 
		bit clr ustat2 DDIR | IFS | ICLK;
		dm(SPCTL1) = ustat2;

		bit set imask SP1I | SP3I;		// enable SPORT1 RX and SPORT3 TX interrupts

powerdwm_not_done_yet:
		idle;		
		R1 = 0x00000008;					// Test for SPORT3 
		R0 = DM(DMASTAT);
		R0 = R0 AND R1;
		IF NE jump powerdwm_not_done_yet;
		bit clr imask SP1I|SP3I;				// disable SPORT1 RX and SPORT3 TX interrupts

Wait_Approx_1s:
		lcntr = 3000, do waitloop until lce;
				nop;
				nop;
				nop;
waitloop:		nop;

		bit clr ustat1 0xFFFFFFFF;
		dm(SPCTL1) = ustat1;
		dm(SPCTL3) = ustat1;
		IRPTL=0;
		bit clr IMASK SP1I | SP3I;

SPORT_DMA_setup:
		r0=0x00000000;					// initially clear SPORT control register
		dm(SPCTL1)=r0;
	    dm(SPCTL3)=r0; 
  		ustat1=dm(SPCTL3);
  		ustat2=dm(SPCTL1);		
		ustat3=dm(SP13MCTL);

		r0=tx_buf3a;	dm(II3A)=r0;    /* Internal DMA6 memory address		      		*/	   
 		r0=1;			dm(IM3A)=r0;	/* Internal DMA6 memory access modifier	      	*/   	 
		r0=@tx_buf3a;	dm(C3A)=r0;	 	/* Contains number of DMA6 transfers to be done */

		r0=rx_buf1a;	dm(II1A)=r0;	/* Internal DMA2 memory address		      		*/
 		r0=1;			dm(IM1A)=r0;	/* Internal DMA2 memory access modifier	      	*/   	  
		r0=@rx_buf1a;	dm(C1A)=r0;		/* Contains number of DMA2 transfers to be done */

		/* clear multichannel/miscellaneous control register for SPORT1 & SPORT3 */
		R0 = 0x0; 		dm(SP13MCTL) = R0;     
 		
		/* internally generating FS3 and *HARDWARE* looping it back to FS1 for SPORT1/3 SPI control */
/* 
   	  	 Maximum SPI serial bit clock rate is 8MHz...  select 1 MHz to allow safety factor of 8
 		 according to 9-42 of user's manual, xCLKDIV = ((2 x fCLKIN)/(serial clock frequency)) - 1
		 Thus, xCLKDIV = ((2 x 30 MHz)/(1 MHz)) - 1 = 59 = 0011 1011 (binary) = 0x003B

		 Now, since we want 16 bit clocks per frame, set FSDIV to 16-1 = 15 = 0x000F */

//		R0 = 0x00270004;	dm(DIV3) = R0;
//		R0 = 0x000F003B;	dm(DIV3) = R0;
		R0 = 0x0011002B;	dm(DIV3) = R0;
		R0 = 0;				dm(DIV1) = R0;		 

		/* SPCTL3 SPORT CONTROL REGISTER BITs
		31:26   -- Read-only status bits
		25 		-- DDIR Bit = 1, Transmitter
		24 		-- SPORT Enable B: 0 Disabled
		23 		-- reserved
		22 		-- Word Select: 0 issue if data in either Tx
		21:20 	-- DMA chaining and DMA enables for Channel B: 0:0 Disabled
		19 		-- SPORT xmit DMA chaining enable A:  0 disable 
		18 		-- SPORT xmit DMA enable A:           0 disable 
		17 		-- Late FS:  1 Late (see p.7 of 1836 data sheet)
		16 		-- Active Low FS:  1 Active Low
		15 		-- TFS data dependency: 0 TFS signal generated only when new data is in SPORT channel's transmit data buffer
		14 		-- IFS Source: 1 internal
		13 		-- FSR Requirement:  1 FS required
		12 		-- Active Clock Edge:  1 rising edge
		11 		-- Operation mode:  0 non-I2S mode
		10 		-- Xmit Clk source:  1 internal
		 9 		-- 16/32-bit pack:  0 no unpacking of 32-bit words into separate 16-bit words for transmission
	     8:4 	-- Serial Word Length minus 1:  01111
		 3 		-- Endian word format:  0 MSB first
 	    2:1 	-- Data Type:  0:0 r-justify; fill MSBs w/0s
		 0 		-- SPORT Enable A:  1 enable A  */

//		R0 = 0x020374F1;
		bit set ustat1 DDIR | SDEN_A | LAFS | LFS |  IFS | FSR | CKRE | ICLK | SLEN16 | SPEN_A;
		dm(SPCTL3) = ustat1;

		/* SRCTL0 SPORT CONTROL REGISTER BITs
		31:26   -- Read-only status bits
		25 		-- DDIR Bit = 0, Receiver
		24 		-- SPORT Enable B: 0 Disabled
		23 		-- MCE - SPORT Mode:  0 DSP SPORT Mode
		22 		-- SPORT Loopback:  0 disable
		21:20 	-- DMA chaining and DMA enables for Channel B: 0:0 Disabled
		19 		-- SPORT Rcv DMA chaining enable A:   0 disabled
		18 		-- SPORT Rcv DMA enable A:			 0 disabled
		17 		-- Late RFS:  1 Late (see 9-54 of workshop manual and p.7 of 1836 data sheet)
		16 		-- Active Low RFS:  1 Active Low (again, see 9-54 of workshop manual and p.7 of...)
		15 		-- reserved
		14 		-- IRFS - RFS Source: 0 external
		13 		-- RFS Requirement:  1 RFS required
		12 		-- Active Clock Edge:  1 rising edge
		11 		-- Operation mode:  0 non-I2S mode
		10 		-- Rcv Clk source:  0 external
		 9 		-- 16/32-bit pack:  0 no packing of received 16-bit words into 32-bit words
		 8:4 	-- Serial Word Length minus 1:  01111
		 3 		-- Endian word format:  0 MSB first
		 2:1 	-- Data Type:  0:0 r-justify; fill MSBs w/0s
		 0 		-- SPORT Enable A:  1 enable A

		NOTE: SPORT1 & SPORT3 clock and frame syncs tied together, generated by SPORT3 */

//		R0 = 0x000330F1;
		bit set ustat2 SDEN_A | LAFS | LFS | FSR | CKRE | SLEN16 | SPEN_A; 
		bit clr ustat2 DDIR | IFS | ICLK;
		dm(SPCTL1) = ustat2;

		bit set imask SP1I | SP3I;		// enable SPORT0 RX and SPORT2 TX interrupts

SPORT_DMAs_not_done_yet:
		idle;		
		R1 = 0x0000000A;				// Test for SPORT1 and SPORT3 DMA completion
		R0 = DM(DMASTAT);
		R0 = R0 AND R1;
		IF NE jump SPORT_DMAs_not_done_yet;

		bit clr ustat1 0xFFFFFFFF;
		dm(SPCTL1) = ustat1;
		dm(SPCTL3) = ustat1;
		IRPTL=0;
		bit clr IMASK SP1I | SP3I;		// disable SPORT1 and SPORT3 interrupts

		rts;
Program_AD1836_regs_via_SPI.end:

	/* With lcntr = 1000, this actually waits roughly 1s*/
Wait_Approx_1500ms:
lcntr = 1000, do waitloop250ms until lce;
				nop;
				nop;
				nop;
				//call Wait_Approx_999us;
				nop;
				nop;
waitloop250ms:	nop;

				nop;
				nop;
rts;
Wait_Approx_1500ms.end:

/* This loop has been cut to approx length 110ms instead of 167ms*/
Wait_Approx_167ms:
lcntr = 110, do waitloop200ms until lce;
				nop;
				nop;
				nop;
				//call Wait_Approx_999us;
				nop;
				nop;
	waitloop200ms:	nop;

				nop;
				nop;
rts;
Wait_Approx_167ms.end:

/////////////////////////////////////////////////////////////
//                                                         //
//     SPORT1 and SPORT3 Interrupt Service Routines        //
//                                                         //
/////////////////////////////////////////////////////////////

Count_SPORT1_RX_IRQs:
	r0=dm(SP1I_counter);			/* get last count */
	r0=r0+1;						/* increment count */
	dm(SP1I_counter)=r0;			/* save updated count */
	RTI;
Count_SPORT1_RX_IRQs.end:

Count_SPORT3_TX_IRQs:
	r0=dm(SP3I_counter);			/* get last count */
	r0=r0+1;						/* increment count */
	dm(SP3I_counter)=r0;			/* save updated count */
	RTI;
Count_SPORT3_TX_IRQs.end:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -