?? amd parallel flash programmer.asm
字號:
//**********************************************************************************************************************************
//**********************************************************************************************************************************
//"AMD Parallel Flash Programmer.asm" RJM 9/2003 DSP Applications Engineering
//This program is intended for the AMD 8-bit 1M parallel flash
//found on the ADSP-21262 Ez-Kit.
//The subroutines will:
// -FLASH_FILE_SIZE: -check to see that the buffer 'my_file' is not too large to fit in the 1Mx8 flash
// -FLASH_RESET: -issue the flash reset command
// -ERASE_FLASH_CHIP; -erase the entire flash and wait until the erase command is completed
// -SECTOR_ERASE: -calculate the number of sector needed to hold the data and erase accordingly (and verify erasure)
// -PROGRAM_FLASH: -program the flash with the data/code in my_file and check for write cmd completion after each byte
// -VERIFY_FLASH: -verify the contents of the flash with the values in 'my_file',
//
//This example is intended to provide a starting point to be tailored to fit specific needs.
//The VERIFY_FLASH routine can be omitted and you can use either SECTOR_ERASE or ERASE_FLASH_CHIP
//To program boot loader code into the flash, use the Loader in VisualDSP++ 3.0 and generate a .ldr file with the following options:
// -Width: 16
// -Boot Type: Parallel Port (prom)
// -Format: Include
//**********************************************************************************************************************************
//**********************************************************************************************************************************
#include <def21262.h>
#define FLASH_START_ADDRESS 0x01000000
#define FLASH_SIZE 0x100000
#define LED_ADDRESS 0x01400000
#define SECTOR_SIZE 65536
#define NUMBER_SECTORS (LENGTH(my_file)*BYTES >>16) +1
//i.e. if length of file in bytes is 0x1ffff, 1 sector= 0xffff, shift by 16 gives us 1+1 etc.
#define BYTES 2 //i.e. 4 * 8bits = 32 bit logical data width
// 2 * 8bits = 16 bit logical data width
// 1 * 8bits = 8 bit logical data width
.global _main;
.section/dm seg_dmda;
.var LED_value;
.var External_Byte_Address;
.var External_Sector_Address[]=0;
.var Data_Byte;
.var Word_To_Write[2];
.var Word_Read_In[2];
.section/dm seg_dm16; //short-word address space
.var my_file[] = "input.ldr"; //16-bit loader file
.var read_back; //buffer to read the programmed data to
.section/pm seg_pmco;
_main:
nop;
bit set mode1 IRPTEN; nop; //Global Interrupt Enable
bit set LIRPTL PPIMSK; nop; //The Parallel Port interrupt is the only one used
nop;nop;nop;
//Status Lights
r4=1; call WRITE_TO_LEDS; //LED1 lit at start
call SETUP;
r4=3; call WRITE_TO_LEDS; //LED2 lit after erase command
call PROGRAM_FLASH;
r4=0x7; call WRITE_TO_LEDS; //LED4 lit after flash programmed
call VERIFY_FLASH;
r4=0xf; call WRITE_TO_LEDS; //LED5 lit after verified successfully
jump DONE;
SETUP:
call FLASH_FILE_SIZE; //be sure the data will fit in the flash
call FLASH_RESET; //issue the flash reset command
//call ERASE_FLASH_CHIP; //erases entire flash
call SECTOR_ERASE; //erases proper # of sectors and verifies erasure
rts;
ERASE_FLASH_CHIP:
r0 = 0x55aa0000; nop; //this is the CHIP ERASE Command for the AMD 29LV081B
dm(Word_To_Write) = r0; nop;
r0 = 0x1055aa80; nop;
dm(Word_To_Write+1) = r0; nop;
// init DMA reg's
r0 = Word_To_Write; dm(IIPP)=r0; nop;
r0=1; dm(IMPP)=r0; nop;
r0=4; dm(ICPP)=r0; nop;
r0 = FLASH_START_ADDRESS; dm(EIPP)=r0; nop;
r0=0; dm(EMPP)=r0; nop;
r0=8; dm(ECPP)=r0; nop;
ustat1= PPTRAN| // transmit
PPBHC| // bus hold cycle
PPDUR20;// data cycle duration of 20 core clock cycles
dm(PPCTL)=ustat1; nop;
// initiate DMA
bit set ustat1 PPDEN|PPEN;
dm(PPCTL)=ustat1; nop;
// wait for DMA to complete
idle;
r0=0;
dm(PPCTL)=r0; nop;
r0 = FLASH_START_ADDRESS;
dm(External_Byte_Address) = r0;
call FLASH_ERASED; //check if sector is erased
nop;
rts;
SECTOR_ERASE:
r1=65536-1;//Calculate second to last address of sector
r2=FLASH_START_ADDRESS;
r2=r2+r1; //create address within 1st sector
dm(External_Sector_Address) = r2; //first sector address
r0=NUMBER_SECTORS; //this loop erases and verifies one sector per iteration
lcntr=r0, do sectors until lce;
r0 = 0x55aa0000; nop; //this is the SECTOR ERASE Command for the AMD 29LV081B
dm(Word_To_Write) = r0; nop;
r0 = 0x3055aa80; nop;
dm(Word_To_Write+1) = r0; nop;
// init DMA reg's
r0 = Word_To_Write; dm(IIPP)=r0; nop;
r0=1; dm(IMPP)=r0; nop;
r0=4; dm(ICPP)=r0; nop;
r0 =dm(External_Sector_Address); dm(EIPP)=r0; nop; //address of the sector we wish to erase this iteration
r0=0; dm(EMPP)=r0; nop;
r0=8; dm(ECPP)=r0; nop;
ustat1= PPTRAN| // transmit
PPBHC| // bus hold cycle
PPDUR20;// data cycle duration of 20 core clock cycles
dm(PPCTL)=ustat1; nop;
// initiate DMA
bit set ustat1 PPDEN|PPEN;
dm(PPCTL)=ustat1; nop;
// wait for DMA to complete
idle;
r0=0;
dm(PPCTL)=r0; nop;
nop;nop;
call FLASH_ERASED; //check if sector is erased
r1 = 65536;
r0 = dm(External_Sector_Address);
r0=r0+r1; //add for next sector
dm(External_Sector_Address) = r0;
sectors:nop;
nop;
nop;
rts;
FLASH_ERASED:
r2 = 0;
r0 = dm(External_Sector_Address);
dm(External_Byte_Address)=r0;
call READ_FLASH_WORD; //Check that the data in the flash = 0xFF
r0 = dm(Word_Read_In); nop; //This indicates the flash is erased, but you wait until the
r1 = 0xFFFFFFFF; //data has stopped toggling so that you know you are reading a flash
r1 = r0 - r1; //location, not the flash's status register
if ne jump FLASH_ERASED;
nop;
rts;
PROGRAM_FLASH:
r0 = FLASH_START_ADDRESS;
dm(External_Byte_Address) = r0;
i0=my_file;
m0=1;
lcntr=@my_file, do PROGRAM_FLASH_LOOP until lce; //each loop iteration writes two 8-bit flash locations
r6 = dm(i0,m0); //data is 16 bits wide in 'my_file'
dm(Data_Byte) = r6;
call WRITE_FLASH_BYTE ; //write 8 bits of the data
r0 = dm(External_Byte_Address);
r0 = r0 + 1;
dm(External_Byte_Address) = r0; //update flash address for DMA in WRITE_FLASH_BYTE
r6 = lshift r6 by -8; //get the other 8 bits
dm(Data_Byte) = r6;
call WRITE_FLASH_BYTE ; //write the other 8 bits of the word
r0 = dm(External_Byte_Address);
r0 = r0 +1;
dm(External_Byte_Address) = r0; //update flash address for DMA in WRITE_FLASH_BYTE
nop;
PROGRAM_FLASH_LOOP:
nop;
nop;
rts;
VERIFY_FLASH:
r0=FLASH_START_ADDRESS-1;
dm(External_Byte_Address)=r0;
i0=my_file;
m0=1;l0=0;
i1=read_back;
m1=1;l1=0;
lcntr=@my_file; do VERIFY until lce;
r0=dm(External_Byte_Address);
r0=r0+1;
dm(External_Byte_Address)=r0;
//fetch two bytes from flash
call READ_FLASH_WORD;
r0=dm(Word_Read_In);
r1=fext R0 BY 0:8;
//increment address
r0=dm(External_Byte_Address);
r0=r0+1;
dm(External_Byte_Address)=r0;
call READ_FLASH_WORD;
r0=dm(Word_Read_In);
r2=fext r0 BY 0:8;
//two bytes from source
r4 = dm(i0,m0);
r8 = fext R4 by 0:8;
r12= fext R4 by 8:8;
//compare
r8=r8-r1;
if ne jump TEST_FAIL;
r12=r12-r2;
if ne jump TEST_FAIL;
r2= lshift r2 by 8; //move 8 bits over
r1=r1+r2; //combine 2 bytes to make 16-bit data
dm(i1,m1)=r1;
//don't branch in last 3 instr of loop:
nop;
nop;
VERIFY: nop;
rts;
WRITE_FLASH_BYTE:
// init DMA reg's
r0=0;
dm(PPCTL)=r0;
r0 = 0x00000000; nop; //These several lines of code take the 8-bit data and combine it with
dm(Word_To_Write) = r0; nop; //the PROGRAM command word for the AMD flash, resulting in a 32-bit word to be issued to the flash
r3 = dm(Data_Byte); nop; //using parallel port DMA
r3 = lshift r3 by 24; nop;
r0 = 0x00a055aa; nop;
r3 = r3 + r0; nop;
dm(Word_To_Write +1) = r3; nop;
r0 = Word_To_Write; dm(IIPP)=r0; nop;
r0=1; dm(IMPP)=r0; nop;
r0=4; dm(ICPP)=r0; nop;
r0 = dm(External_Byte_Address); dm(EIPP)=r0; nop;
r0=0; dm(EMPP)=r0; nop;
r0=8; dm(ECPP)=r0; nop;
ustat1= PPTRAN| // transmit
PPBHC| // bus hold cycle
PPDUR20;
dm(PPCTL)=ustat1; nop;
// initiate DMA
bit set ustat1 PPDEN|PPEN;
dm(PPCTL)=ustat1; nop;
// wait for DMA to complete
idle;
nop;
call POLL_FLASH; //After issuing the program command and the data to be written, we cannot move on until
nop; //the program command is completed by the flash. When data read back does not toggle
r0=0; //in 2 consecutive reads,the program command has completed successfully
dm(PPCTL)=r0;
rts;
READ_FLASH_WORD:
// init DMA reg's
r0=Word_Read_In; dm(IIPP)=r0; nop;
r0=1; dm(IMPP)=r0; nop;
r0=1; dm(ICPP)=r0; nop;
r0=dm(External_Byte_Address); dm(EIPP)=r0; nop;
r0=0; dm(EMPP)=r0; nop;
r0=4; dm(ECPP)=r0; nop;
ustat1= PPBHC| // bus hold cycle
PPDUR20;
dm(PPCTL)=ustat1; nop;
// initiate DMA
bit set ustat1 PPDEN|PPEN;
dm(PPCTL)=ustat1; nop;
//wait for rx DMA to complete
idle;
r0=0;
dm(PPCTL)=r0;
nop;
nop;
nop;
nop;
rts;
FLASH_FILE_SIZE:
r5 = length(my_file)*BYTES; // read the # of bytes to program
r6 = 1024000; // size of flash is 1Mx8
comp (r5, r6);
if ge jump TEST_FAIL; // verify file will fit in flash
rts;
FLASH_RESET:
r0= 0xF0;//Command for RESET of FLASH
dm(Word_To_Write+1)=r0;
r0=Word_To_Write; dm(IIPP)=r0; nop;
r0=1; dm(IMPP)=r0; nop;
r0=2; dm(ICPP)=r0; nop;
r0 = dm(External_Byte_Address); dm(EIPP)=r0; nop;
r0=0; dm(EMPP)=r0; nop;
r0=8; dm(ECPP)=r0; nop;
ustat1= PPTRAN| // transmit
PPBHC| // bus hold cycle
PPDUR20;
dm(PPCTL)=ustat1; nop;
// initiate DMA
bit set ustat1 PPDEN|PPEN;
dm(PPCTL)=ustat1; nop;
// wait for DMA to complete
idle;
nop;
r0=0;
dm(PPCTL)=r0;
rts;
POLL_FLASH: //After issuing the program command and the data to be written, we cannot move on until
r1 = 0; //the program command is completed by the flash. When data read back does not toggle
r2 = 0; //in 2 consecutive reads,the program command has completed successfully
call READ_FLASH_WORD;
r0 = dm(Word_Read_In); nop;
r1 = fext R0 BY 0:8;
r2 = fext R0 BY 8:8;
r1 = r1 - R2;
if ne jump POLL_FLASH;
nop;
rts;
WRITE_TO_LEDS: //The 8 user LEDs on the ADSP-21262 EZ-Kit are mapped to flag
//pins as well as the parallel port AD0-7 pins, so we can use a dma to write the latch to light the LEDs
// new LED value passed in via R4
dm(LED_value)=r4;
// init DMA reg's
r0=LED_value; dm(IIPP)=r0; nop;
r0=1; dm(IMPP)=r0; nop;
r0=1; dm(ICPP)=r0; nop;
r0=1; dm(EMPP)=r0; nop;
r0=0x01400000; dm(EIPP)=r0; nop;
r0=1; dm(ECPP)=r0; nop;
ustat1= PPTRAN| // transmit
PPBHC| // bus hold cycle
PPDUR20; // 10 waitstates
dm(PPCTL)=ustat1; nop;
// initiate DMA
bit set ustat1 PPDEN|PPEN;
dm(PPCTL)=ustat1; nop;
// wait for DMA to complete
idle;
r0=0;
dm(PPCTL)=r0;
rts;
DONE:
r0 = 0x00FF0000;
dm(LED_value)=r0;
lcntr=20; do DONE_LOOP until lce; nop;
r4=dm(LED_value);
r4 = rot r4 by 16;
dm(LED_value)=r4;
Call WRITE_TO_LEDS;
lcntr=2250000; do Wait_Loop until lce; nop;
nop;
nop;
nop;
Wait_Loop:
nop;
nop;
nop;
DONE_LOOP:
nop;
END:
nop;
jump END;
TEST_FAIL:
nop;
jump TEST_FAIL;
_main.end:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -