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

📄 spiflash.asm

📁 ADI 公司的DSP ADSP21262 EZ-KIT LITE开发板的全部源代码
💻 ASM
字号:
///////////////////////////////////////////////////////////////////////////////////////
//NAME:     SPIflash.asm (ST SPI Flash)
//DATE:     2/20/04
//PURPOSE:  Program the SPI Flash for the ADSP-21262
//
//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 read_data_bytes_hs;
.global page_program;
.global flash_program;
.global sector_erase;
.global bulk_erase;
.global deep_powerdown;
.global deep_powerdown_release;
.global setup_spi;
.global setup_spi_dma;
.global wait_for_SPIF;
.global wait_for_WIP;
.global bit_reverse_command;

.extern flash_inst;
.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_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;

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

call wait_for_SPIF;
dm(SPICTL)=r15;
bit set flags FLG0;

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;
bit set flags FLG0; //Disable SPI

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;
bit set flags FLG0; //Disable SPI

// check if the receive buffer is empty
ustat1=dm(SPISTAT);
bit tst ustat1 RXS;
if tf jump (pc,-2);

// check if receive is complete
call wait_for_SPIF;

//Wait 5 us for part to be available in all cases.
//1000 cycles @ 200 MHz
lcntr=10000, do (pc,1) until lce;
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;    //Write Status Register Command
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;

dm(SPICTL)=r15; //Disable SPI
bit set flags FLG0;

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
bit set flags FLG0;

read_data_bytes.end: rts;

//----------------------------------------
//HIGH SPEED 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_hs://This mode is not implemented.
jump read_data_bytes;


read_data_bytes_hs.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);
b6=flash_data_out+1;
m5=1;
l6=PAGE_LENGTH;
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.
get_page:
lcntr = PAGE_LENGTH, do get_page.end until lce;
r0=dm(i5,m5);
get_page.end: dm(i6,m5)=r0;

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

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
r13=PAGE_LENGTH;
r14=r14-r13;
if GT jump (pc,2);
r13=r13+r14;

//Send an entire page, or if this is the last page
//only send remaining words.
r12=r13+1;
r0=r12+1;
dm(CSPI)=r0;
r0=flash_data_out;
dm(IISPI)=r0;
r0=1;
dm(IMSPI)=r0;
r0=COMMON_SPI_DMA_SETTINGS;
dm(spi_dma_setting)=r0;

call setup_spi_dma;

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

dm(SPICTL)=r15; //Disable SPI
bit set flags FLG0;

call wait_for_WIP;

//Wait 5 ms for part to be available in all cases.
//1000000 cycles @ 200 MHz
lcntr=1000000; do (pc,1) until lce;
nop;

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;

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
bit set flags FLG0;

call wait_for_WIP;

sector_erase.end: rts;

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

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

r3=SPI_BE;
dm(TXSPI)=r3;

call wait_for_SPIF;

dm(SPICTL)=r15; //Disable SPI
bit set flags FLG0;

call wait_for_WIP;

bulk_erase.end: rts;


//----------------------------------------
//DEEP POWERDOWN SUBROUTINE (1 Byte)
//Places the Flash into Deep Powerdown mode
//Inputs - none
//Outputs- none
//Core sends the command
deep_powerdown:
r0=COMMON_SPI_SETTINGS|TIMOD1|WL8|MSBF;
dm(spi_setting)=r0;
call setup_spi;

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

call wait_for_SPIF;

dm(SPICTL)=r15; //Disable SPI
bit set flags FLG0;

call wait_for_WIP;

deep_powerdown.end: rts;

//----------------------------------------
//DEEP POWERDOWN RELEASE SUBROUTINE (5 Bytes)
//READ ELECTRONIC SIGNATURE
//Awakens the Flash from Deep Powerdown mode
//Also returns the electronic signature of the Flash
//Inputs - none
//Outputs- Fifth location of electronic_signature
//         First four locations are garbage
//Core sends the command
deep_powerdown_release:
r0=COMMON_SPI_SETTINGS|TIMOD2|WL8|MSBF;
dm(spi_setting)=r0;
call setup_spi;

r0=5;
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_RES;
dm(TXSPI)=r0;

call setup_spi_dma;

dm(SPICTL)=r15; //Disable SPI
bit set flags FLG0;

//Wait 5 us for part to be available in all cases.
//1000 cycles @ 200 MHz
lcntr=10000, do (pc,1) until lce;
nop;

deep_powerdown_release.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

ustat1=0;   //Disable DMA
dm(SPIDMAC)=ustat1;
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:
call read_status_register;

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

wait_for_WIP.end: rts;

⌨️ 快捷键说明

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