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

📄 bf561_prom16.dsp

📁 基于visual dsp++开发环境
💻 DSP
📖 第 1 页 / 共 2 页
字号:
        [P1+OFFSET_(SICA_IWR1)] = R3;
                

//----------------------------------------------------------
// Set DMA for 16-bit flash read with modify = 2 bytes
//----------------------------------------------------------

// Source Modify = 2
        R6 = 0x2 (Z);  
        W[P1+OFFSET_(MDMA2_S0_X_MODIFY)] = R6;        

// Destination Modify = 2 for 16 bit transfers
         W[P1+OFFSET_(MDMA2_D0_X_MODIFY)] = R6;        

// set the DMA config words for 16 bit DMA transfers

// Source DMAConfig Value (16-bit words)
        R3.L = 0x5;
        R3.H = 0;

// Destination DMAConfig Value (16-bit words)
        R4.L = 0x87;        
        R4.H = 0;

// Read the DXE count for each DXE we want to skip
// beginning with DXE #0, which was the 2nd stage loader

// P0 Points to the beginning of CORE MMR Space
     P0.H = UPPER_(COREMMR_BASE);        
     P0.L = LOWER_(COREMMR_BASE);

// see if it's the load program command (0)          
     R2.L = 0;
     R2.H = 0;     
     CC = R0 == R2;
     IF CC JUMP LOAD_PROGRAM;

// see if it's the jump to user program command (1)          
     R2.L = 1;
     CC = R0 == R2;
     IF !CC JUMP COMMAND_ERROR;

     P0.L = JUMP_USER_PROGRAM;     
     P0.H = JUMP_USER_PROGRAM;     

     JUMP (P0);
          
COMMAND_ERROR:
	R0.L = 0x05;
	R0.H = 0x00;
	RTS;     
     
LOAD_PROGRAM:
// R1 = WHICH program to load; put it in R5
	R5 = R1;

// The following must be repeated for each DXE we want to skip over, 
// to get to the DXE we want to boot load.  R5 will contain the DXE#.
	
// skip the global header 
// now we are pointing to the ten byte block header for the DXE count.
	R0.L = 0x0004;
	R0.H = 0x2000;

SKIP_DXE:
// skip the DXE count 10 byte header
	R0 += 10;
	
// R1 is destination address
	R1.L = LOWER_(GPStorage);
	R1.H = UPPER_(GPStorage);
	
// count value for reading 4 byte DXE byte count
	R2 = 0x2 (Z);
	CALL MEM_DMA; 

// Update the Source Address
	R0 = [P1+OFFSET_(MDMA2_S0_CURR_ADDR)];	

// Get the value just read from the external device = DXE count
	P3 = R1;
	nop;nop;nop;nop;
	R1 = [P3];

	
// Add the DXE count to the current source pointer	
	R0 = R0 + R1;

	R5 += -1;
	CC = R5 == 0;
	IF !CC JUMP SKIP_DXE;

// The above would be repeated to read DXE 2, 3, 4, etc.


//-----------------------------------------------------------------------
// Reading the block header
//-----------------------------------------------------------------------

.ALIGN 2;
FGRAB_HEADER:
// From now on, P3 Points to the Header Buffer in core A scratch
        P3.L = LOWER_(HeaderBuffer);        
        P3.H = UPPER_(HeaderBuffer);

// DMA Destination Address
        R1 = P3;  // P3 contains the destination pointer        

// Count Value for Header: 10 bytes, 5 words
        R2 = 0x5 (Z);        

// Source Modify = 2 = 16 bit transfer from Flash
        R6 = 0x2 (Z);   // 
        W[P1+OFFSET_(MDMA2_S0_X_MODIFY)] = R6;        

// Destination Modify = 2 for 16 bit transfers
        W[P1+OFFSET_(MDMA2_D0_X_MODIFY)] = R6;
        CALL MEM_DMA;

// Get Source Base Address
        R0 = [P1+OFFSET_(MDMA2_S0_CURR_ADDR)];        

// and save for zero fill
        R7 = R0;                

// Get Destination Base Address
        R1 = [P3];                

// Get Count
        R2 = [P3+0x4];                

// Get Flag
        R5 = W[P3+0x8] (Z);        
   
FCHECK_ZERO_FILL_BIT:

// Bit zero of the flag word indicates zero fill block
        cc = BITTST(R5,0);                
        IF !CC JUMP FDO_DMA;        

// Source Base Address = ZERO Location
        R0 = P4;                
        R6 = 0x0;

// Source Modify = 0 for Zero Fill
        W[P1+OFFSET_(MDMA2_S0_X_MODIFY)] = R6;        

FDO_DMA:
// divide count by 2 for 16 bit transfer
        R2 >>= 1;

        CALL MEM_DMA;
// Bit zero of the flag word indicates zero fill block
        cc = BITTST(R5,0);                
        IF !CC JUMP GET_DMA_CURR_PTR;

// Restore Source Modify to 2 (it was just changed to 0 for zero fill) 
        R6 = 0x2 (Z);
        W[P1+OFFSET_(MDMA2_S0_X_MODIFY)] = R6;        

// Restore R0 to Flash Memory Address (was pointing to "ZERO")
        JUMP GET_NEXT_FLASH_PTR;

GET_DMA_CURR_PTR:

// read CURR pointer if last block was not a zero fill
// otherwise CURR pointer will point just beyond the zero!

        R7 = [P1+OFFSET_(MDMA2_S0_CURR_ADDR)];

GET_NEXT_FLASH_PTR:
// if last block was zero fill, R7 still has the saved flash pointer
// if last block was NOT zero fill, R7 has DMA CURR pointer
// put in in R0 for next call to MEM_DMA
        R0 = R7;                 

F_CHECK_FOR_LAST_SECTION:
// Last Section?
        CC = BITTST(R5,15);          

// If not, Jump to grab header
        IF !CC JUMP FGRAB_HEADER; 
        RETS = [sp++];
// return a success flag back to the command protocol        
        R0 = 0x0;
        RTS;

////////////////////////////////////////////////////////////////
DMA_ERROR_OR_EXCEPT:
//--------------

// Clear flash DMA_ERR condition
	R0 = 0x3;
	W[P1+OFFSET_(MDMA2_D0_IRQ_STATUS)] = R0; 
	W[P1+OFFSET_(MDMA2_S0_IRQ_STATUS)] = R0;

	
// Disable MEM DMA to completely clear the error, so we can continue to 
// use MEMDMA again, if we want.
	R0 = 0x0;
	W[P1+OFFSET_(MDMA2_S0_CONFIG)] = R0;
	W[P1+OFFSET_(MDMA2_D0_CONFIG)] = R0;	

	IDLE;
	
////  ZERO will point to a zero (accessed as both byte and word)  ////////

.align 4;

.BYTE ZERO[4] = 0x0, 0x0, 0x0, 0x0;

.align 4;
     
//=========================================================
JUMP_USER_PROGRAM:

// zero out the last locations of L2
	P0.L = 0xFFE8;
	P0.H = 0xFEB1;
    R0 = 0x0;
    [P0++] = R0;	// ffe8
    [P0++] = R0;	// ffeC
    [P0++] = R0;	// fff0
    [P0++] = R0;	// fff4
    [P0++] = R0;	// fff8
	[P0++] = R0;	// fffC


	P2.L = LOWER_(CoreA_Code_SRAM);  // point the user_code address
	P2.H = UPPER_(CoreA_Code_SRAM);


// Erase the 2nd stage loader from beginning to almost the end
// End address in R3	
	R2.L = end_ldr;
	R2.H = end_ldr;
	R1.L = START_ERASE;
	R1.H = START_ERASE;        

// Get count in R2 for DMA transfer
	R2 = R2 - R1;

// divide count by 2
	R2 >>= 1;

// Source Base Address = ZERO Location
	R0 = P4;		

// Source Modify = 0 for Zero Fill 
	R6 = 0x0;
	W[P1+OFFSET_(MDMA2_S0_X_MODIFY)] = R6;	

// Source Base Address                
	[P1+OFFSET_(MDMA2_S0_START_ADDR)] = R0;        

// Source Count
	W[P1+OFFSET_(MDMA2_S0_X_COUNT)] = R2;        

// Destination Base Address
	[P1+OFFSET_(MDMA2_D0_START_ADDR)] = R1;        

// Destination Count
	W[P1+OFFSET_(MDMA2_D0_X_COUNT)] = R2;        

// Source DMAConfig
	W[P1+OFFSET_(MDMA2_S0_CONFIG)] = R3;
                        
// Destination DMAConfig
	W[P1+OFFSET_(MDMA2_D0_CONFIG)] = R4;        

end_ldr:

// Wait for DMA to Complete
	IDLE;                                        
	R0 = 0x1;
// Write 1 to clear DMA interrupt
	W[P1+OFFSET_(MDMA2_D0_IRQ_STATUS)] = R0; 
	
	JUMP(P2);      // jump to user code

   

⌨️ 快捷键说明

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