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

📄 spiflash.asm

📁 ADI 公司的DSP ADSP21369 EZ-KIT LITE开发板的全部源代码
💻 ASM
字号:
///////////////////////////////////////////////////////////////////////////////////////
//NAME:     SPIflash.asm (ATMEL SPI Flash)
//DATE:     7/29/05
//PURPOSE:  Program the SPI Flash for the ADSP-21369 Ezkit
//
//USAGE:    This file contains the subroutines used to program and verify the SPI Flash
//
////////////////////////////////////////////////////////////////////////////////////////
#include "SPIflash.h"

.global write_enable;
.global write_disable;
.global read_status_register;
.global write_status_register;
.global read_data_bytes;
.global page_program;
.global flash_program;
.global sector_erase;
.global chip_erase;
.global read_device_id;
.global setup_spi;
.global setup_spi_dma;
.global wait_for_SPIF;
.global wait_for_WIP;
.global bit_reverse_command;

.extern flash_curr_page;
.extern sector_base_addr;
.extern read_base_addr;
.extern read_buffer_addr;
.extern read_buffer_length;
.extern write_buffer_addr;
.extern write_base_addr;
.extern write_buffer_length;
.extern file_data;
.extern file_data_verf;
.extern flash_data_out;
.extern flash_data_out.end;
.extern flash_data_verf;
.extern spi_setting;
.extern spi_dma_setting;
.extern status_register;
.extern electronic_signature;
.extern curr_command;
.extern verf_errors;

.section/pm seg_pmco;
//----------------------------------------
//WRITE ENABLE SUBROUTINE (1 Byte)
//Enables the Write Enable Latch of the Flash
//Inputs - none
//Outputs- none
//Core sends the command
write_enable:
r0=COMMON_SPI_SETTINGS|TIMOD1|WL8|MSBF;
dm(spi_setting)=r0;
call setup_spi;

//Pause before continuing
lcntr=1000, do (pc,_loop_end0) until lce;
_loop_end0:
nop;

r0=SPI_WREN;    // Write Enable Command
dm(TXSPI)=r0;

call wait_for_SPIF;

dm(SPICTL)=r15; //Disable SPI
dm(SPIFLG)=r15;
dm(SPIBAUD)=r15;

//Pause before continuing
lcntr=1000, do (pc,_loop_end1) until lce;
_loop_end1:
nop;

write_enable.end: rts;

//----------------------------------------
//WRITE DISABLE SUBROUTINE (1 Byte)
//Disables the Write Enable Latch of the Flash
//Inputs - none
//Outputs- none
//Core sends the command
write_disable:
r0=COMMON_SPI_SETTINGS|TIMOD1|WL8|MSBF;
dm(spi_setting)=r0;
call setup_spi;

r0=SPI_WRDI;    // Write Disable Command
dm(TXSPI)=r0;

call wait_for_SPIF;


dm(SPICTL)=r15; //Disable SPI
dm(SPIFLG)=r15;
dm(SPIBAUD)=r15;

write_disable.end: rts;

//----------------------------------------
//READ STATUS REGISTER SUBROUTINE (2 Bytes)
//Returns the 8-bit value of the status register.
//Inputs - none
//Outputs- second location of status_register[2],
//         first location is garbage.
//Core sends the command
read_status_register:
r0=COMMON_SPI_SETTINGS|TIMOD2|WL8|MSBF;
dm(spi_setting)=r0;
call setup_spi;

r0=SPI_RDSR;    //Read Status Register command
dm(TXSPI)=r0;

r0=2;
dm(CSPI)=r0;
r0=status_register;
dm(IISPI)=r0;
r0=1;
dm(IMSPI)=r0;
r0=COMMON_SPI_DMA_SETTINGS|SPIRCV;
dm(spi_dma_setting)=r0;

call setup_spi_dma;

dm(SPICTL)=r15; //Disable SPI
dm(SPIFLG)=r15;
dm(SPIBAUD)=r15;

//Pause before continuing
lcntr=1000, do (pc,_loop_end3) until lce;
_loop_end3:
nop;

read_status_register.end: rts;

//----------------------------------------
//WRITE STATUS REGISTER SUBROUTINE (2 Bytes)
//Writes 8-bit value of the status register.
//Inputs - second location of status_register[2]
//         first location will be corrupted.
//Outputs- none
//1st word of DMA buffer is the command
write_status_register:
call write_enable;

r0=COMMON_SPI_SETTINGS|TIMOD2|WL8|MSBF;
dm(spi_setting)=r0;
call setup_spi;

r0=SPI_WRSR;
dm(status_register)=r0;

r0=2;
dm(CSPI)=r0;
r0=status_register;
dm(IISPI)=r0;
r0=1;
dm(IMSPI)=r0;
r0=COMMON_SPI_DMA_SETTINGS;
dm(spi_dma_setting)=r0;

call setup_spi_dma;

call wait_for_SPIF;

dm(SPICTL)=r15; //Disable SPI
dm(SPIFLG)=r15;
dm(SPIBAUD)=r15;

call wait_for_WIP;

//Read back the register
call read_status_register;

write_status_register.end: rts;

//----------------------------------------
//READ DATA BYTES SUBROUTINE (read_buffer_length 32-bit words)
//Reads the specified number of words from the Flash.
//Inputs - read_base_addr - Starting Flash address
//       - read_buffer_addr - Address of buffer to write
//       - read_buffer_length - Number of 32-bit words to read
//         plus one
//Outputs- Buffer specified by read_buffer_addr will be updated
//         by the specified number of words plus one. The first
//         32-bit word in the buffer is not valid
//Core sends the command
read_data_bytes:
r0=SPI_READ;
dm(curr_command)=r0;
r0=COMMON_SPI_SETTINGS|TIMOD2|WL32;
dm(spi_setting)=r0;
call setup_spi;

r0=dm(read_base_addr);
dm(flash_curr_page)=r0;

call bit_reverse_command;
r0=dm(curr_command);
dm(TXSPI)=r0;

r0=dm(read_buffer_length);
dm(CSPI)=r0;
r0=dm(read_buffer_addr);
dm(IISPI)=r0;
r0=1;
dm(IMSPI)=r0;
r0=COMMON_SPI_DMA_SETTINGS|SPIRCV;
dm(spi_dma_setting)=r0;

call setup_spi_dma;

dm(SPICTL)=r15; //Disable SPI
dm(SPIFLG)=r15;
dm(SPIBAUD)=r15;

//Pause before continuing
lcntr=1000, do (pc,_loop_end5) until lce;
_loop_end5:
nop;

read_data_bytes.end: rts;

//----------------------------------------
//PAGE PROGRAM SUBROUTINE (write_buffer_length 32-bit words)
//Reads the specified number of words from the Flash.
//Inputs - write_base_addr - Starting Flash address
//       - write_buffer_addr - Address of buffer to read
//       - write_buffer_length - Number of 32-bit words to write
//Outputs- verf_errors - number of errors detected
//1st word of DMA buffer is the command
page_program:
flash_program:
bit set mode1 CBUFEN;
b5=dm(write_buffer_addr);
l5=dm(write_buffer_length);
r14=dm(write_buffer_length);

r0=dm(write_base_addr);
dm(flash_curr_page)=r0;

page_write:
call write_enable;

//Page is PAGE_LENGTH bytes, only 1 page can be programmed
//per command. This loop breaks the data into pages for transmission.
//Set up the page pointers
get_page:
b6=flash_data_out+1;
m5=1;
l6=PAGE_LENGTH;

r0=PAGE_LENGTH;
r0=r14-r0;
if lt l6=r14;

//Get the page data into a separate buffer
lcntr = l6, do get_page.end until lce;
r0=dm(i5,m5);
get_page.end: dm(i6,m5)=r0;

spi_setup:
r0=COMMON_SPI_SETTINGS|TIMOD1|WL32;
dm(spi_setting)=r0;
call setup_spi;

//Concatentate the write command and 24-bit flash address into 1 32-bit
//word and bit reverse it. (Since the ADSP-2126x must boot in LSBF mode.)
r0=SPI_PP;
dm(curr_command)=r0;
call bit_reverse_command;
r0=dm(curr_command);
dm(flash_data_out)=r0;

//Determine if this is the last page and is shorter than PAGE_LENGTH
r13=PAGE_LENGTH;
r14=r14-r13;
if GE jump start_transfer;
//only send remaining number of bytes
r13=r14+r13;

//Send an entire page, or if this is the last page
//only send remaining words.
start_transfer:
//Send out write command and address
r13=r13+1;
b3=flash_data_out;
l3=0;
m3=1;
//Send PAGE_LENGTH+2 words to account for read command and extra word to avoid
//bit error problems seen in Atmel flashes.
r13=r13+1;
lcntr=r13, do writing until lce;
r0=dm(i3,m3);
dm(TXSPI)=r0;

//Pause before continuing
lcntr=1000, do (pc,_loop_end6) until lce;
_loop_end6:
nop;

writing: call wait_for_SPIF;

//Set r13 to contain the real amount of page data sent.
r13=r13-1;
r13=r13-1;

ustat1=dm(SPISTAT);
bit tst ustat1 TXS;
if tf jump (pc,-2);

dm(SPICTL)=r15; //Disable SPI
dm(SPIFLG)=r15;
dm(SPIBAUD)=r15;

call wait_for_WIP;

//Read back the page just programmed for verification
r0=dm(flash_curr_page);
dm(read_base_addr)=r0;
r0=flash_data_verf;
dm(read_buffer_addr)=r0;
r0=@flash_data_verf;
dm(read_buffer_length)=r0;
call read_data_bytes;

//Set up the pointers
//The first location in each of the buffers corresponds to the command and
//24-bit address.
b1=flash_data_out+1;
b2=flash_data_verf+1;
m1=1;
l1=PAGE_LENGTH;
l2=PAGE_LENGTH;

error_check:
lcntr=r13, do error_check.end until lce;
r0=dm(i1,m1);
r1=dm(i2,m1);
comp(r0,r1);
if eq jump error_check.end;
r0=dm(verf_errors);
r0=r0+1;
dm(verf_errors)=r0;
error_check.end: nop;

//Update the page address
r1=PAGE_LENGTH*4;
r0=dm(flash_curr_page);
r0=r0+r1;
dm(flash_curr_page)=r0;

//If r14 < 0, no more data
r14 = pass r14;
if gt jump page_write;

page_write.end:
flash_program.end:
page_program.end: rts;

//----------------------------------------
//SECTOR ERASE SUBROUTINE (4 Bytes)
//Erases the sector of the Flash corresponding to the specified address..
//Inputs - sector_base_addr - Starting 24-bit Flash address
//Outputs- none
//Core sends the command
sector_erase:
call write_enable;

r0=COMMON_SPI_SETTINGS|TIMOD1|WL32;
dm(spi_setting)=r0;
call setup_spi;

r0=dm(sector_base_addr);
dm(flash_curr_page)=r0;

r0=SPI_SE;
dm(curr_command)=r0;
call bit_reverse_command;
r0=dm(curr_command);
dm(TXSPI)=r0;

call wait_for_SPIF;

dm(SPICTL)=r15; //Disable SPI
dm(SPIFLG)=r15;
dm(SPIBAUD)=r15;

call wait_for_WIP;

sector_erase.end: rts;

//----------------------------------------
//CHIP ERASE SUBROUTINE (1 Byte)
//Erases the entire Flash
//Inputs - none
//Outputs- none
//Core sends the command
chip_erase:
call write_enable;

r0=COMMON_SPI_SETTINGS|TIMOD1|WL8|MSBF;
dm(spi_setting)=r0;
call setup_spi;

r3=SPI_CE;
dm(TXSPI)=r3;

call wait_for_SPIF;

dm(SPICTL)=r15; //Disable SPI
dm(SPIFLG)=r15;
dm(SPIBAUD)=r15;

call wait_for_WIP;

chip_erase.end: rts;

//----------------------------------------
//READ DEVICE ID SUBROUTINE (2 Bytes)
//Returns the electronic signature of the Flash
//Inputs - none
//Outputs- Second location is Electronic_signature
//         First locations is garbage
//Core sends the command
read_device_id:
r0=COMMON_SPI_SETTINGS|TIMOD2|WL8|MSBF;
dm(spi_setting)=r0;
call setup_spi;

r0=3;
dm(CSPI)=r0;
r0=electronic_signature;
dm(IISPI)=r0;
r0=1;
dm(IMSPI)=r0;
r0=COMMON_SPI_DMA_SETTINGS|SPIRCV;
dm(spi_dma_setting)=r0;

r0=SPI_RDID;
dm(TXSPI)=r0;

call setup_spi_dma;

dm(SPICTL)=r15; //Disable SPI
dm(SPIFLG)=r15;
dm(SPIBAUD)=r15;

read_device_id.end: rts;

//----------------------------------------
//SETUP SPI SUBROUTINE (1 Byte)
//Sets up the SPI for mode specified in spi_setting
//Inputs - spi_setting
//Outputs- none
setup_spi:

r0=0xFE01;
dm(SPIFLG)=r0;

r0=BAUD_RATE_DIVISOR;
dm(SPIBAUD)=r0;

r0=dm(spi_setting);
dm(SPICTL)=r0;

setup_spi.end: rts;

//----------------------------------------
//WAIT FOR SPIF SUBROUTINE (1 Byte)
//Polls the SPIF (SPI single word transfer complete) bit
//of SPISTAT until the transfer is complete.
//Inputs - none
//Outputs- none
wait_for_SPIF:
ustat1=dm(SPISTAT);
bit tst ustat1 SPIF;
if not tf jump (pc,-2);
wait_for_SPIF.end: rts;

//----------------------------------------
//SETUP SPI DMA SUBROUTINE (1 Byte)
//Sets up the SPI DMA for mode specified in spi_dma_setting
//Inputs - spi_dma_setting
//Outputs- none

setup_spi_dma:

ustat1=dm(spi_dma_setting);
dm(SPIDMAC)=ustat1;
//Wait for SPI DMA to complete using polling------
ustat1=dm(SPIDMAC);
bit tst ustat1 SPIDMAS; // Check SPI DMA Status bit
IF TF jump (pc,-2);     // SPIDMAS = 1 when DMA in progress

//Disable DMA
dm(SPIDMAC)=r15;
setup_spi_dma.end: rts;

//----------------------------------------
//BIT REVERSE COMMAND SUBROUTINE (1 Byte)
//For booting the SHARC EX requires that the data in the Flash
//be sent LSB first, but all PROM/FLASH devices are MSB first
//so the data must be programmed into the Flash LSBF, but the
//command word for the flash must be bit reversed for the Flash
//to recognize the command in LSBF mode.
//Inputs - curr_command - current command to send
//       - flash_curr_page - address of the page to access
//Outputs- curr_command
bit_reverse_command:
i7=dm(curr_command);
bitrev(i7,0);
r0=i7;
r0=rot r0 by -24;
i7=dm(flash_curr_page);
bitrev(i7,0);
r1=i7;
r2=BITREV_ADDRESS_MASK;
r1=r1 and r2;
r0=r0 or r1;
dm(curr_command)=r0;
bit_reverse_command.end: rts;

//----------------------------------------
//WAIT FOR WIP SUBROUTINE (1 Byte)
//Polls the WIP (Write In Progress) bit of the Flash's status
//register until the Flash is finished with its access. Accesses
//that are affected by a latency are Page_Program, Sector_Erase,
//and Block_Erase.
//Inputs - none
//Outputs- none
wait_for_WIP:

lcntr=10000, do _loop_end99 until lce;
_loop_end99:
nop;

call read_status_register;

ustat1=dm(status_register+1);
bit tst ustat1 WIP;
if not tf jump wait_for_WIP.end;

lcntr=1000, do (pc,_loop_end12) until lce;
_loop_end12:
nop;
jump wait_for_WIP;

wait_for_WIP.end: rts;

⌨️ 快捷键说明

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