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

📄 161_spi.asm

📁 ADI SHARC DSP系统启动源码
💻 ASM
📖 第 1 页 / 共 2 页
字号:

//--------------- 6 0x0006 INIT DM40 ---------------
test_dm40_init: R0=R0-1;	// checks for tag init dm40
    			IF NE JUMP (PC, test_pm_zero);
dm40_init:		B0=R3;
	    		LCNTR=R2, DO dm40_init.end UNTIL LCE;
					CALL read_dma_info;
			        PX=dm(0x40004);
			        dm(i0,M6)=PX;
			        PX=dm(0x40005);
dm40_init.end:		dm(i0,M6)=PX;
    			JUMP read_boot_info;
// -------------------------------------------------------


//--------------- 7 0x0007 ZERO PM16 ---------------
//--------------- 8 0x0008 ZERO PM32 ---------------
//--------------- 9 0x0009 ZERO PM40 ---------------
//--------------- 10 0x000A ZERO PM48 ---------------
test_pm_zero:   R0=R0-R5;	// R5=2, checks for tag zero pm16, zero pm32
                    IF LE JUMP (PC, dm_zero);
                R0=R0-R5;	// R5=2, checks for tag zero pm40, zero 48
        			IF LE JUMP (PC, dm40_zero);
// -------------------------------------------------------


//--------------- 11 0x000B INIT PM16 ---------------
//--------------- 12 0x000C INIT PM32 ---------------
//--------------- 13 0x000D INIT PM40 ---------------
//--------------- 14 0x000E INIT PM48 ---------------
test_pm_init:   R0=R0-R5;	// R5=2, checks for tag init pm16, init pm32
        		    IF LE JUMP (PC, dm_init);
                R0=R0-R5;	// R5=2, checks for tag init pm40, init pm48
        			IF LE JUMP (PC, dm40_init);
// -------------------------------------------------------


//--------------- 15 0x000F ZERO DM64 ---------------
test_dm64_zero: R0=R0-1;
                IF NE JUMP (PC, test_dm64_init);
dm64_zero:      R2=R2+R2;               //double count and initialize in NW memory
                R3 = LSHIFT R3 by 1;    //double longword address to NW memory
                jump dm_zero;
//------------------------------------------------------------


//--------------- 16 0x0010 INIT DM64 ---------------
test_dm64_init: R0=R0-1;
				IF NE JUMP (PC, test_pm64_zero);
dm64_init:		I0=R3;
				LCNTR=R2, DO dm64_init.end UNTIL LCE;
					CALL read_SPI_word;		/* read 32 lsbs of 64-bit word	*/
					PX2=R8;
					CALL read_SPI_word;		/* read 32 msbs of 64-bit word	*/
					PX1=R8;
					nop;
					nop;						/* Call cannot be in last 3 instructions of loop	*/
dm64_init.end:		DM(I0,M6)=PX (lw);			/* write all 64-bits to longword address location	*/
				JUMP read_boot_info;
//------------------------------------------------------------


//--------------- 17 0x0011 ZERO PM64 ---------------
//--------------- 18 0x0012 INIT PM64 ---------------
test_pm64_zero: R0=R0-1;
                IF EQ JUMP (PC, dm64_zero);
test_pm64_init: R0=R0-1;
                IF EQ JUMP (PC, dm64_init);
//------------------------------------------------------------



//=================================================================================
// "INIT PMx EXT" load "packed" instructions into external memory.  External memory
// starts at address 0x200000 on the 21161. The format for this packing can be found
// in the Chapter 5 of the 21161 Hardware Reference.  Zero-init code sections (many
// consecutive NOP's) are initialized using the EXT_ZERO_CODE subroutine above.
//----------------------------------------------------------------------------------

//--------------- 19 0x0013 INIT PM8 EXT ---------------
test_pm8_init_ext:
                R0=R0-1; //checks for init pm8 ext tag
                    IF NE JUMP (PC, test_pm16_init_ext);

        		B0=R3;
		        R2=LSHIFT R2 by -1; //r2 was # 32-bit words -> two inits per loop, so half R2
            	LCNTR=R2, DO pm8_init.end UNTIL LCE;

           		CALL read_SPI_word; // r8 = B1 B2 B3 B4
                    lcntr=4, do loop8 until lce;
            		r8=rot r8 by 8; // rotate the 32 word left by 8 bits
loop8:	    	    DM(I0,M6)=R8;   // to write out MSB (B1) first

                CALL read_SPI_word; // r8 = B0 B0 B5 B6
                    DM(1,I0)=R8;        // write out B6 to address n+1
                    R8=rot R8 by -8;
pm8_init.end:		DM(I0,4)=R8;        // write out B5 to address N, and then leave two
                                        // blank addresses to comply w/ 8-bit packing convention.
                JUMP read_boot_info;
//------------------------------------------------------------


//--------------- 20 0X0014 INIT PM16 EXT ---------------
test_pm16_init_ext:
                R0=R0-1; //checks for init pm16 ext tag
                IF NE JUMP (PC, test_pm32_init_ext);
            	B0=R3;
            	R2=LSHIFT R2 by -1;
            	LCNTR=R2, DO pm16_init.end UNTIL LCE;
            		CALL read_SPI_word; // r8 = B1 B2 B3 B4
            		DM(1,I0)=R8;        // write out b3, b4
            		R8=LSHIFT R8 by -16;
            		DM(I0,2)=R8;        // write out b1, b2
            		CALL read_SPI_word; // r8 = B0 B0 B5 B6
            		DM(I0,2)=R8;       // write out B5, b6, leave 1 black address for 16-bit packing
            		nop;
pm16_init.end:		nop; // call can't be in last 3 instructions of loop
            	JUMP read_boot_info;
//------------------------------------------------------------


//--------------- 21 0X0015 INIT PM32 EXT ---------------
test_pm32_init_ext:
                R0=R0-1;
				IF NE JUMP (PC, test_pm48_init_ext);
        		B0=R3;
        		LCNTR=R2, DO pm32_init.end UNTIL LCE;
            		CALL read_SPI_word;// r8 = B1 B2 B3 B4, then R8 = B0 B0 B5 B6
            		DM(I0,M6)=R8;
                  	nop;
pm32_init.end:      nop; // a call can't be in the last 3 instructions
            	JUMP read_boot_info;
//------------------------------------------------------------


//--------------- 22 0X0016 INIT PM48 EXT ---------------
test_pm48_init_ext:
                R0=R0-1;	//checks for init pm48 ext tag
                IF NE JUMP (PC, ext_zero_code);

                // configure External port for 48-bit writes (disable linkports)
    			ustat1=dm(SYSCON);
        	    bit set ustat1 IPACK0;
    			dm(SYSCON)=ustat1;

                I8=R3;
            	lcntr=R2, do pm48_init.end until lce;
            		CALL read_dma_info; // get 2 instructions (three 32-bit words)
                    I6=0x40004;
        		   	LCNTR=0x2, do loop1 until lce;
        				PX=DM(I6,M6); // read word from internal scratch locations
        				R0=PX1;	        // swap px registers for external write
        				PX1=PX2;        // (see pag 5-13 of the 161 HW-Ref Rev3.0)
        				PX2=R0;
loop1:	                PM(I8,M14)=px;	//write word to external memory
pm48_init.end:      nop; 	 	//nested loops can't terminate on the same instruction
                jump read_boot_info;
//===========================================================================



//============================= EXT_ZERO_CODE =============================
// This portion of code is used to initialize external memory with zero's
//  r0 holds (tag - 22)
//  r2 holds number of external #NOP's to be initialized
//
//  calculate how many external addresses are used by each NOP based on the tag:
//
//      If  pm8 (tag: 23 0X0017 ZERO PM8  EXT), r0 = 1, so multiply count by 8   (lshift r2 by 3)
//      If pm16 (tag: 24 0X0018 ZERO PM16 EXT), r0 = 2, so multiply count by 4   (lshift r2 by 2)
//      If pm32 (tag: 25 0X0019 ZERO PM32 EXT), r0 = 3, so multiply count by 2   (lshift r2 by 1)
//      If pm48 (tag: 26 0X001A ZERO PM48 EXT), r0 = 4, so multiply count by 1   (lshift r2 by 0)
//------------------------------------------------------------
ext_zero_code: 	r6=4;
                r0=r6-r0, I0=R3;	// calculate amount to shift by based on (4 - tag)
				r2=lshift r2 by r0;	// r2 = number addresses per NOP
                LCNTR=R2, DO ext_zero_code.end UNTIL LCE;
ext_zero_code.end:      DM(I0,M6)=M13;          //m13=0
                JUMP read_boot_info;  //fetch header for next block
//===========================================================================



//============================= read_dma_info =============================
// This section performs a length 3, 32bit dma into scratch location
// that can be read out as 2 40 or 48 bit words
//------------------------------------------------------------
read_dma_info:
		DM(IMSRX)=M14;            	/* setup up modify to 1*/
		DM(CSRX)=M15;				/* Setup DMA count to be 3 ~ 3 32 bit words = 2 48 bit words  */
		jump more;

//============================= read_SPI_word =============================
//	This section reads ONE 32-bit spi word into a scratch location (0x40006)
//	and then also into register R8
//------------------------------------------------------------
read_SPI_word:
		DM(IMSRX)=M14;            	/* setup up modify to 1*/
		DM(CSRX)=M14;				/* Setup DMA count to be 1  */

more:   DM(IISRX)=I15;          	/* Setup DMA destination address; I15 should be 0x40006*/
    	ustat1=dm(SPICTL);
    	bit set ustat1 RDMAEN;
    	dm(SPICTL)=ustat1;


SPI_DMA_not_done_yet:               // Test SPI completion
		R1 = DMA8ST;
		R0 = DM(DMASTAT);
		R0 = R0 AND R1;
		IF NE jump SPI_DMA_not_done_yet;
    	ustat1=dm(SPICTL);
	    bit clr ustat1 RDMAEN;
    	dm(SPICTL)=ustat1;
        r8=dm(0x40006);
        rts;
//===========================================================================




// =============================  USER_INIT   ========================================
// If any registers need initialization before the kernel begins importing the application,
// they should be done so here.  Typically, a user would need to initialize SDRAM settings,
// but they may also modify WAIT, SYSCON, SPICTL, or LCTL to increase the speed of the boot
// process.
//
// This subroutine may include NO MORE THAN 48 instructions (in addition to the RTS). As
// modifications are made, "kernel.map" shows the updated number of remaining free locations
// under "Memory-Words-Unused".
// -----------------------------------------------------------------------------------
user_init:

#if SDRAM
                r0=0xFFFFF;      // clear MSx waitstate and mode
                dm(WAIT)=r0;
                r0=900;          // refresh rate
                dm(SDRDIV)=r0;
                r0=0x5114662;      // SDRAM running @ Core-clock
                dm(SDCTL)=r0;
#endif



//          ~~~~~INSERT SYSTEM INITIALIZATION CODE HERE ~~~~



                RTS;                // return from user_init to loader_kernel_init
// ============================  END USER_INIT  =====================================

⌨️ 快捷键说明

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