amd parallel flash programmer.asm

来自「ADI 公司的DSP ADSP21262 EZ-KIT LITE开发板的全部源代」· 汇编 代码 · 共 460 行

ASM
460
字号
//**********************************************************************************************************************************
//**********************************************************************************************************************************
//"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 + =
减小字号Ctrl + -
显示快捷键?