#include "typedef.h" #include "atm630h.h" #define MAX_WAIT_LOOP_COUNT 100000 #define LITTLE_ENDIAN #define SPI_WRITE_ENABLE 0x06 #define SPI_WRITE_DISABLE 0x04 #define SPI_READ_STATUS 0x05 #define SPI_READ_STATUS2 0x35 #define SPI_READ_STATUS3 0x15 #define SPI_WRITE_STATUS 0x01 #define SPI_WRITE_STATUS2 0x31 #define SPI_WRITE_STATUS3 0x11 #define SPI_READ_DATA 0x03 #define SPI_FAST_READ 0x0B #define SPI_PAGE_PROGRAM 0x02 #define SPI_SECTOR_ERASE 0x20 #define SPI_SECTOR_ERASE_1 0xD7 #define SPI_BLOCK_ERASE 0xD8 #define SPI_BLOCK_ERASE_1 0x52 #define SPI_CHIP_ERASE 0xC7 #define SPI_CHIP_ERASE_1 0x60 #define SPI_POWER_DOWN 0xB9 #define SPI_READ_JEDEC_ID 0x9F #define SPI_READ_ID_1 0xAB #define SPI_MF_DEVICE_ID 0x90 #define SPI_MF_DEVICE_ID_1 0x15 #define SPI_READ_ELECTRON_SIGN 0xAB #define SPI_4READ_MODE0 0xEB #define SPI_4WRITE_MODE 0x32 #define SPI_4READ_MODE1 0x6B #define SPI_MF_WINBOND 0xEF #define SPI_MF_EON 0x1C #define SPI_MF_AMIC 0x37 #define SPI_MF_ATMEL 0x1F #define SPI_MF_SST 0xBF #define SPI_MF_MXIC 0xC2 #define SPI_RXFIFO_ENABLE (1<<8) #define SPI_TRANS_COMPLETE (1<<7) #define SPI_RXFIFO_OVER (1<<6) #define SPI_TXFIFO_FULL (1<<2) #define SPI_TXFIFO_REQ (1<<1) #define SPI_RXFIFO_FULL (1<<4) #define SPI_RXFIFO_NOTEMPTY (1<<3) #define SPI_TXFIFO_EMPTY (1<<2) #define SPI_TXFIFO_NOTFULL (1<<1) #define SPI_BUSY (1<<0) #define SPIFLASH_BUSY (1<<0) #define SPIFLASH_WRITEENABLE (1<<1) #define STANDARDFORMAT 0 #define DUALFORMAT 1 #define QUADFORMAT 2 #define READ_WRITE 0 #define READ_ONLY 2 #define WRITE_ONLY 1 #define STRANDARD_MODE 0 #define ADDR_4BYTES 1 #define BOTH_4BYTES 2 #define WORDSPERPAGE 64 #define BYTESPERPAGE 256 #define PAGESPERSECTORS 16 #define SECTORSPERBLOCK 16 #define BLOCKSPERFLASH 16//64 //#define WORDSPERPAGE 64 //#define BYTESPERPAGE 256 //#define PAGESPERSECTORS 16 //#define SECTORSPERBLOCK 16 //#define BLOCKSPERFLASH 256 #define BYTESPERBLOCK (BYTESPERPAGE*PAGESPERSECTORS*SECTORSPERBLOCK) #define BYTESPERSECTOR (BYTESPERPAGE*PAGESPERSECTORS) #define SPI_DMA_ENABLE 1 #define GPIO101 101 static void delay(unsigned int time) { volatile unsigned int count = time; while(count--); } void SpiSetFrameFormatMode(unsigned char format,unsigned char tmod); void TestSpiInterrupt(void); static void SetCSGpioEnable(int enable) { // rSYS_PAD_CTRL0A &= ~((0x7<<3)); // SetGPIODataDirection(GPIO101,euOutputPad); // SetGPIOPadData(GPIO101, !enable); rSYS_PAD_CTRL02 &= ~(0x3<<0); *((volatile unsigned int *)(0x60900000+0x84)) |= (0x1 << 0); if(!enable) *((volatile unsigned int *)(0x60900000+0x80)) |= (0x1 << 0); else *((volatile unsigned int *)(0x60900000+0x80)) &= ~(0x1 << 0); } static void SetSpiDataMode(unsigned int bitMode) { unsigned int val = 0; while((rSPI_SR & SPI_BUSY)); rSPI_SSIENR = 0; val = rSPI_CTLR0; val &=~(0x1f<<16); val |=((bitMode-1)<<16); rSPI_CTLR0 = val; rSPI_SSIENR = 1; } static void SetSpiRevNDF(unsigned int ndf) { while((rSPI_SR & SPI_BUSY)); rSPI_SSIENR = 0; rSPI_CTLR1 = ndf & 0xffff; rSPI_SSIENR = 1; } static void SpiEmptyRxFIFO(void) { INT32 data = 0; while(rSPI_SR & SPI_RXFIFO_NOTEMPTY) { data = rSPI_DR; } } static UINT8 SpiReadSta(void) { UINT8 status; SetSpiDataMode(8); rSPI_DR = SPI_READ_STATUS; rSPI_DR = 0; while(!(rSPI_SR & SPI_RXFIFO_NOTEMPTY)); status = rSPI_DR; while(!(rSPI_SR & SPI_RXFIFO_NOTEMPTY)); status = rSPI_DR; SetSpiDataMode(32); return status; } static UINT8 SpiReadSta2(void) { UINT8 status; SetSpiDataMode(8); rSPI_DR = SPI_READ_STATUS2; rSPI_DR = 0; while(!(rSPI_SR & SPI_RXFIFO_NOTEMPTY)); status = rSPI_DR; while(!(rSPI_SR & SPI_RXFIFO_NOTEMPTY)); status = rSPI_DR; SetSpiDataMode(32); return status; } static UINT8 SpiReadSta3(void) { UINT8 status; SetSpiDataMode(8); rSPI_DR = SPI_READ_STATUS3; rSPI_DR = 0; while(!(rSPI_SR & SPI_RXFIFO_NOTEMPTY)); status = rSPI_DR; while(!(rSPI_SR & SPI_RXFIFO_NOTEMPTY)); status = rSPI_DR; SetSpiDataMode(32); return status; } void SpiWriteEnable(void) { SetSpiDataMode(8); rSPI_DR = SPI_WRITE_ENABLE; while((SpiReadSta() & SPIFLASH_BUSY)); while(!(SpiReadSta() & SPIFLASH_WRITEENABLE)); SetSpiDataMode(32); } void SpiWriteDisable(void) { SetSpiDataMode(8); rSPI_DR = SPI_WRITE_DISABLE; while((SpiReadSta() & SPIFLASH_BUSY)); while((SpiReadSta() & SPIFLASH_WRITEENABLE)); SetSpiDataMode(32); } static UINT8 SpiWriteSta(unsigned char state) { SpiWriteEnable(); SetSpiDataMode(8); rSPI_DR = SPI_WRITE_STATUS; rSPI_DR = state; while((SpiReadSta() & SPIFLASH_BUSY)); SetSpiDataMode(32); } static UINT8 SpiWriteSta2(unsigned char state) { SpiWriteEnable(); SetSpiDataMode(8); rSPI_DR = SPI_WRITE_STATUS2; rSPI_DR = state; while((SpiReadSta() & SPIFLASH_BUSY)); SetSpiDataMode(32); } static UINT8 SpiWriteSta3(unsigned char state) { SpiWriteEnable(); SetSpiDataMode(8); rSPI_DR = SPI_WRITE_STATUS3; rSPI_DR = state; while((SpiReadSta() & SPIFLASH_BUSY)); SetSpiDataMode(32); } static void SpiSelectPad() { UINT32 val; val = rSYS_PAD_CTRL02; val &= ~(0xfff); // val |= (0x1<<10)|(0x1 << 8)|(0x1 << 6)|(0x1 << 4)| (0x1 << 2)| (0x1 << 0); val |= (0x1 << 6)|(0x1 << 4)| (0x1 << 2)| (0x1 << 0); rSYS_PAD_CTRL02 = val; val = rSYS_SSP_CLK_CFG; val &= ~((0x1<<31)|(0x1<<30)); val |= (0x1<<31)|(0x1<<30); rSYS_SSP_CLK_CFG = val; *((volatile unsigned int *)(0x60900000+0x84)) |= (0x1 << 4); *((volatile unsigned int *)(0x60900000+0x84)) |= (0x1 << 5); *((volatile unsigned int *)(0x60900000+0x80)) |= (0x1 << 5); *((volatile unsigned int *)(0x60900000+0x80)) |= (0x1 << 4); // rSYS_SSP_CLK_CFG |= (0x1 << 4) ; rSYS_BUS_CLK_SEL |= (0x1 << 16); } static void SpiInit() { rSPI_SSIENR = 0; rSPI_CTLR0 = 0; rSPI_CTLR0 |=(0<<21)|(0x1f<<16)|(0x0<<12)|(0x0<<8)|(0x0<<4); // rSPI_CTLR1 = 63; rSPI_BAUDR = 2;//16;//2; rSPI_SER = 1; rSPI_SSIENR = 1; SetCSGpioEnable(0); } static void SpiReadDeviceId(UINT8 *mfid, UINT8 *devid) { UINT8 val[6]; int i; SetSpiDataMode(8); rSPI_DR = SPI_MF_DEVICE_ID; rSPI_DR = 0; rSPI_DR = 0; rSPI_DR = 0; rSPI_DR = 0; rSPI_DR = 0; for (i = 0; i < 6; i++) { while(!(rSPI_SR & SPI_RXFIFO_NOTEMPTY)); val[i] = rSPI_DR; } *mfid = val[4]; *devid = val[5]; SetSpiDataMode(32); } #if 1 /******************************************************************************* *正常 * SpiDmaRead 能正常读取 * * 参数 *buf 数据缓存区域 * burst_length bit数 ********************************************************************************/ void SpiDmaRead(UINT32 *buf , UINT32 burst_length ) { } /******************************************************************************* *正常 * SpiDmaWrite 能正常写 * * 参数 *buf 数据缓存区域 * burst_length 数据bit数 ********************************************************************************/ void SpiDmaWrite(UINT32 *buf , UINT32 burst_length ) { } #endif static void SpiReadJedecId(UINT8 *mfid, UINT8 *memid, UINT8 *capid) { UINT8 val[4]; int i; SetSpiDataMode(8); rSPI_DR = SPI_READ_JEDEC_ID; rSPI_DR = 0; rSPI_DR = 0; rSPI_DR = 0; for (i = 0; i < 4; i++) { while(!(rSPI_SR & SPI_RXFIFO_NOTEMPTY)); val[i] = rSPI_DR; } *mfid = val[1]; *memid = val[2]; *capid = val[3]; SetSpiDataMode(32); } void Test() { UINT32 val; UINT32 i=3; SpiEmptyRxFIFO(); rSPI_DR = (0xef)<<24; while(!(rSPI_SR & SPI_RXFIFO_NOTEMPTY)); val = rSPI_DR; while((rSPI_SR & SPIFLASH_BUSY)); printk("+++++val_t0++++++= 0x%x\n",val); SpiEmptyRxFIFO(); rSPI_DR = (0xDf)<<24; while(!(rSPI_SR & SPI_RXFIFO_NOTEMPTY)); val = rSPI_DR; while((rSPI_SR & SPIFLASH_BUSY)); printk("+++++val_t1++++++= 0x%x\n",val); SpiEmptyRxFIFO(); rSPI_DR = (0x9f)<<24; while(!(rSPI_SR & SPI_RXFIFO_NOTEMPTY)); val = rSPI_DR; while((rSPI_SR & SPIFLASH_BUSY)); printk("+++++val_t2++++++= 0x%x\n",val); } static void SpiReadId(void) { UINT8 mfid,devid,memid,capid; SpiReadDeviceId(&mfid,&devid); SpiReadJedecId(&mfid,&memid,&capid); PrintVariableValueHex("ManufacturerID: ", mfid); PrintVariableValueHex("DeviceID: ", devid); PrintVariableValueHex("Memory Type ID: ", memid); PrintVariableValueHex("Capacity ID: ", capid); } void SpiWritePage(UINT32 pagenum, UINT32 *buf) { UINT32 addr; UINT32 val; INT32 i; UINT32 dmach; UINT8 tmpaddr[3]; addr = pagenum*BYTESPERPAGE; tmpaddr[0] = addr; tmpaddr[1] = addr>>8; tmpaddr[2] = addr>>16; SpiWriteEnable(); // rSPI_DR = (tmpaddr[0]<<0) | (tmpaddr[1]<<8) | (tmpaddr[2]<<16) | (SPI_PAGE_PROGRAM<<24); #if 1 #ifdef LITTLE_ENDIAN rSPI_DR = (tmpaddr[0]<<24) | (tmpaddr[1]<<16) | (tmpaddr[2]<<8) | SPI_PAGE_PROGRAM; #else rSPI_DR = (tmpaddr[0]<<0) | (tmpaddr[1]<<8) | (tmpaddr[2]<<16) | (SPI_PAGE_PROGRAM<<24); #endif for(i=0;i>8; tmpaddr[2] = addr>>16; SpiWriteEnable(); rSPI_DR = (tmpaddr[0]<<0) | (tmpaddr[1]<<8) | (tmpaddr[2]<<16) | (SPI_PAGE_PROGRAM<<24); for(i=0;i>8; tmpaddr[2] = addr>>16; SpiEmptyRxFIFO(); /* rSPI_DR = (tmpaddr[0]<<0) | (tmpaddr[1]<<8) | (tmpaddr[2]<<16) | (SPI_READ_DATA<<24); for(i=0;i>8; tmpaddr[2] = addr>>16; SpiEmptyRxFIFO(); rSPI_DR = (tmpaddr[0]<<0) | (tmpaddr[1]<<8) | (tmpaddr[2]<<16) | (SPI_READ_DATA<<24); rSPI_DR = 0; while(!(rSPI_SR & SPI_RXFIFO_NOTEMPTY)); data = rSPI_DR; while(!(rSPI_SR & SPI_RXFIFO_NOTEMPTY)); data = rSPI_DR; printk("+++++data = 0x%x++++++\n",data); return (data&0xFF); } #if 0 void SpiFastReadPage(UINT32 pagenum, UINT32 *buf) { UINT32 addr; UINT32 val; INT32 i; UINT32 dmach; UINT8 tmpaddr[3]; UINT8 tmp[64*4+4]; UINT8 *p =(UINT8 *)buf; addr = pagenum*BYTESPERPAGE; tmpaddr[0] = addr; tmpaddr[1] = addr>>8; tmpaddr[2] = addr>>16; SpiEmptyRxFIFO(); #if 1 // SpiSetFrameFormatMode(STANDARDFORMAT,READ_ONLY); rSPI_DR = (tmpaddr[0]<<0) | (tmpaddr[1]<<8) | (tmpaddr[2]<<16) | (SPI_FAST_READ<<24); #else SetSpiDataMode(16); rSPI_DR =SPI_FAST_READ; rSPI_DR =tmpaddr[2]; rSPI_DR =tmpaddr[1]; rSPI_DR =tmpaddr[0]; rSPI_DR =0; SetSpiDataMode(32); #endif for(i=0;i>8; tmpaddr[2] = addr>>16; SpiEmptyRxFIFO(); #if 1 // SpiSetFrameFormatMode(STANDARDFORMAT,READ_ONLY); rSPI_DR = (tmpaddr[0]<<0) | (tmpaddr[1]<<8) | (tmpaddr[2]<<16) | (SPI_FAST_READ<<24); #else SetSpiDataMode(8); rSPI_DR =SPI_FAST_READ; rSPI_DR =tmpaddr[2]; rSPI_DR =tmpaddr[1]; rSPI_DR =tmpaddr[0]; rSPI_DR =0; SetSpiDataMode(32); #endif for(i=0;i>8; tmpaddr[2] = addr>>16; SpiEmptyRxFIFO(); SetCSGpioEnable(1); SpiSetFrameFormatMode(QUADFORMAT, READ_ONLY); //set instruction 8bits,1byte mode; addr 24bit,1byte mode; 8 dummy clocks rSPI_SSIENR = 0; rSPI_SPI_CTRLR0 = (8 << 11) | (2 << 8) | (6 << 2); rSPI_SSIENR = 1; SetSpiDataMode(32); SetSpiRevNDF(WORDSPERPAGE - 1); rSPI_DR = SPI_4READ_MODE1; rSPI_DR = addr;//(tmpaddr[2] << 8) | (tmpaddr[1] << 16) | (tmpaddr[0] << 24); for(i=0; i>8; tmpaddr[2] = addr>>16; tmpaddr[3] = addr>>24; SpiEmptyRxFIFO(); rSPI_SSIENR = 0; rSPI_SPI_CTRLR0 = (0x6<<11)|(0x2<<8)|(0x8<<2)|(0x1<<0); rSPI_SSIENR = 1; SpiSetFrameFormatMode(QUADFORMAT,READ_ONLY); // SetCSGpioOutData(0); // rSPI_DR = (tmpaddr[0]<<0) | (tmpaddr[1]<<8) | (tmpaddr[2]<<16) | (SPI_4READ_MODE1<<24); rSPI_DR = 0xec;//SPI_4READ_MODE1; rSPI_DR = (tmpaddr[0]<<0) | (tmpaddr[1]<<8) | (tmpaddr[2]<<16)|(tmpaddr[2]<<24); for(i=0;i>8; tmpaddr[2] = addr>>16; SpiWriteEnable(); SpiEmptyRxFIFO(); SetCSGpioEnable(1); SpiSetFrameFormatMode(QUADFORMAT, WRITE_ONLY); //set instruction 8bits,1byte mode; addr 24bit,1byte mode; no dummy clocks rSPI_SSIENR = 0; rSPI_SPI_CTRLR0 = (2 << 8) | (6 << 2); rSPI_SSIENR = 1; SetSpiDataMode(32); rSPI_DR = SPI_4WRITE_MODE; rSPI_DR = addr;//(tmpaddr[2] << 8) | (tmpaddr[1] << 16) | (tmpaddr[0] << 24); for(i=0; i>8; tmpaddr[2] = addr>>16; printk("\nStart erase the spi flash block %d,\n",blockNum); SpiWriteEnable(); #ifdef LITTLE_ENDIAN rSPI_DR = (tmpaddr[0]<<24) | (tmpaddr[1]<<16) | (tmpaddr[2]<<8) | SPI_BLOCK_ERASE; #else rSPI_DR = (tmpaddr[0]<<0) | (tmpaddr[1]<<8) | (tmpaddr[2]<<16) | SPI_BLOCK_ERASE<<24; #endif while((SpiReadSta() & SPIFLASH_WRITEENABLE)); printk("\nThe block erased!\n"); } void SpiEraseChip(void) { UINT32 i; printk("\nStart erase the whole spi flash,please wait...\n"); SpiWriteEnable(); SetSpiDataMode(8); rSPI_DR = SPI_CHIP_ERASE; SetSpiDataMode(32); while(SpiReadSta() & SPIFLASH_BUSY); printk("\n The whole flash erased! \n"); } //UINT32 WriteData[WORDSPERPAGE]; //UINT32 ReadData[WORDSPERPAGE]; UINT8 WriteData[WORDSPERPAGE*4]; UINT8 ReadData[WORDSPERPAGE*4]; void TestSpiRWPage(void) { INT32 i,j,k,p,m; UINT32 page = 0; UINT8 data = 0; // SpiEraseChip(); SpiEraseBlock(0); for(i = 0;i<64*4;i++) { WriteData[i] = 0x5a505000+i; ReadData[i] = 0; } for(j = 0;j<64;j++) { SpiEraseBlock(j); for(k=0;k<16;k++) { for(m=0;m<16;m++) { page = j*16*16+k*16+m; printk("Test the Page %d \n",page); SpiWritePage(page,(UINT32 *)WriteData); SpiReadPage(page,(UINT32 *)ReadData); //SpiFastReadPage(page,(UINT32 *)ReadData); // data = SpiReadSingleByte(0); for(i = 0;i> 16) & 0xff; rSPI_DR = (page_addr >> 8) & 0xff; rSPI_DR = page_addr & 0xff; while((rSPI_SR & SPI_BUSY)); SetCSGpioEnable(0); SetSpiDataMode(32); } int SpiNandWaitTillReady(void) { int timeout = 100; u8 status; while(timeout--) { status = SpiNandReadReg(SPI_NAND_STATUS_REG); //printk("status=0x%x.\n", status); if (!(status & SPI_NAND_STATUS_REG_BUSY)) return status; delay(1000); } return -1; } static int SpiNandEnableECC(void) { u8 status; status = SpiNandReadReg(SPI_NAND_FEATURE_REG); status |= SPI_NAND_ECC_EN; SpiNandWriteReg(SPI_NAND_FEATURE_REG, status); return 0; } static int SpiNandDisableQuad(void) { u8 status; status = SpiNandReadReg(SPI_NAND_FEATURE_REG); status &= ~SPI_NAND_QUAD_EN; SpiNandWriteReg(SPI_NAND_FEATURE_REG, status); return 0; } void SpiNandLoadPage(unsigned int page_addr) { SetSpiDataMode(8); SetCSGpioEnable(1); rSPI_DR = SPI_NAND_PAGE_READ; rSPI_DR = (page_addr >> 16) & 0xff; rSPI_DR = (page_addr >> 8) & 0xff; rSPI_DR = page_addr & 0xff; while((rSPI_SR & SPI_BUSY)); SetCSGpioEnable(0); SetSpiDataMode(32); } void SpiNandStorePage(unsigned int page_addr) { SetSpiDataMode(8); SetCSGpioEnable(1); rSPI_DR = SPI_NAND_PROGRAM_EXEC; rSPI_DR = (page_addr >> 16) & 0xff; rSPI_DR = (page_addr >> 8) & 0xff; rSPI_DR = page_addr & 0xff; while((rSPI_SR & SPI_BUSY)); SetCSGpioEnable(0); SetSpiDataMode(32); } int SpiNandReadCache(unsigned int page_offset, int length, u8 *read_buf) { int i; u8 val; SetSpiDataMode(8); SetCSGpioEnable(1); rSPI_DR = SPI_NAND_READ_CACHE; rSPI_DR = (page_offset >> 8) & 0xff; rSPI_DR = page_offset & 0xff; rSPI_DR = 0; for (i = 0; i < 4; i++) { while(!(rSPI_SR & SPI_RXFIFO_NOTEMPTY)); val = rSPI_DR; } for (i = 0; i < length; i++) { rSPI_DR = 0; while(!(rSPI_SR & SPI_RXFIFO_NOTEMPTY)); read_buf[i] = rSPI_DR; } while((rSPI_SR & SPI_BUSY)); SetCSGpioEnable(0); SetSpiDataMode(32); } int SpiNandReadPage(unsigned int page_addr, void *buf) { int status; int ecc_status; SpiNandLoadPage(page_addr); status = SpiNandWaitTillReady(); if (status < 0) return status; ecc_status = (status >> SPI_NAND_STATUS_REG_ECC_SHIFT) & SPI_NAND_STATUS_REG_ECC_MASK; if (ecc_status == SPI_NAND_ECC_UNCORR) { printk("Bit errors greater than ECC capability(8 bits) and not corrected.\n"); return -1; } SpiNandReadCache(0, BYTES_PER_PAGE, buf); } int SpiNandStoreCache(unsigned int page_offset, int length, u8 *write_buf) { int i; u8 val; SetSpiDataMode(8); SetCSGpioEnable(1); rSPI_DR = SPI_NAND_PROGRAM_LOAD; rSPI_DR = (page_offset >> 8) & 0xff; rSPI_DR = page_offset & 0xff; for (i = 0; i < length; i++) { while(!(rSPI_SR & SPI_TXFIFO_NOTFULL)); rSPI_DR = write_buf[i]; } while((rSPI_SR & SPI_BUSY)); SetCSGpioEnable(0); SetSpiDataMode(32); } void SpiNandWritePage(unsigned int page_addr, void *buf) { SpiNandWriteEnable(); SpiNandStoreCache(0, BYTES_PER_PAGE, buf); SpiNandStorePage(page_addr); SpiNandWaitTillReady(); } u8 spinand_wbuf[2048]; u8 spinand_rbuf[2048] = {0}; #if 0 void bootFromSPI() { void (*funPtr)(void); INT32 nSectorLen; UINT32 *pData; INT32 nMaxSectors; INT32 nLeftSize; INT32 nReadSize; INT32 i,j,k,p,m; UINT32 addr; UINT8 status; printk("SPI Booter\n"); SpiSelectPad(); #if 0 SetCSGpioEnable(1); rSPI_SSIENR = 0; rSPI_CTLR0 = (2 << 21) | (31 << 16) | (1 << 8); rSPI_SPI_CTRLR0 = (2 << 8) | (6 << 2); //rSPI_CTLR1 = 63; rSPI_BAUDR = 4; rSPI_SER = 1; rSPI_SSIENR = 1; rSPI_DR = 0x32; rSPI_DR = 0; rSPI_DR = 0x12345678; rSPI_DR = 0x12345678; while(1); #endif SpiInit(); SpinandSoftreset(); SpiNandWaitTillReady(); SpiNandReadId(); SpiNandWriteReg(SPI_NAND_LOCK_REG, SPI_NAND_PROT_UNLOCK_ALL); SpiNandEnableECC(); SpiNandDisableQuad(); SpiNandWriteEnable(); SpiNandEraseBlock(0); SpiNandWaitTillReady(); #if 0 for (i = 0; i < BYTES_PER_PAGE; i++) spinand_wbuf[i] = rand(); SpiNandWritePage(0, spinand_wbuf); SpiNandReadPage(0, spinand_rbuf); for (i = 0; i < BYTES_PER_PAGE; i++) { if (spinand_wbuf[i] != spinand_rbuf[i]) printk("compare data fail 0x%.2x 0x%.2x.\n", spinand_wbuf[i], spinand_rbuf[i]); } #else pData = (UINT32*)0x42000000; for (i = 0; i < 8; i++) { SpiNandWritePage(i, pData); pData += BYTES_PER_PAGE / 4; } SpiNandReadPage(0, (void*)0x43000000); #endif while(1); #if 1 // TestSpiInterrupt(); // TestSpiRWPage(); // TestFastRead(); Test4bitMode(); #else //test the QE enable status = SpiReadSta(); status &= ~(1<<6); status |= (1<<6); SpiWriteSta(status); status = SpiReadSta(); printk("+++00+++status = 0x%x++++\n",status); SpiWriteDisable(); status = SpiReadSta(); printk("+++01+++status = 0x%x++++\n",status); #endif printk("Test Over!!!\n"); while(1); } #endif static void BurnSpiNandData(unsigned int Memaddr, unsigned int addr, unsigned int size) { INT32 i; INT32 nStartPage; UINT8 *pDataBuf; INT32 nPages; pDataBuf = (UINT8*)Memaddr; PrintVariableValueHex("memaddr Address ", Memaddr); PrintVariableValueHex("Spi Address ", addr); PrintVariableValueHex("Write size ", size); nStartPage = addr / BYTES_PER_PAGE; nPages = (size + BYTES_PER_PAGE - 1) / BYTES_PER_PAGE; for(i = nStartPage; i < nStartPage + nPages; i++) { SpiNandWritePage(i,(UINT32 *)pDataBuf); pDataBuf += BYTES_PER_PAGE; printf("#"); } } void SpiNandBurnLoad(void) { void (*funPtr)(void); UINT8 *pData; INT32 i,j; INT32 nPageCount; u8 *spinand_wbuf = (UINT8 *)(0x30A000); u8 *spinand_rbuf = (UINT8 *)(0x30C000); u8 *spinand_tbuf = (UINT8 *)(0x30A000); SpiSelectPad(); SpiInit(); SpinandSoftreset(); SpiNandWaitTillReady(); SpiNandReadId(); SpiNandWriteReg(SPI_NAND_LOCK_REG, SPI_NAND_PROT_UNLOCK_ALL); SpiNandEnableECC(); SpiNandDisableQuad(); #if 1 SpiNandWriteEnable(); SpiNandEraseBlock(0); SpiNandWaitTillReady(); BurnSpiNandData(0x30A000, 0, 0x4000); printf("\r\nBurn the spi Nand Flash Over !!!\n"); while(1); #else pData = (UINT8*)IMAGE_ENTRY; nPageCount = (IMAGE_MAX_SIZE + BYTES_PER_PAGE - 1) / BYTES_PER_PAGE; for(i = 0; i < nPageCount; i++) { SpiNandReadPage(i, pData); pData += BYTES_PER_PAGE; } printf("Read the spi Nand Flash Over !!!\n"); while(1); #endif #if 1 SpiNandWriteEnable(); SpiNandEraseBlock(0); SpiNandWaitTillReady(); /* for (i = 0; i < BYTES_PER_PAGE; i++) { spinand_wbuf[i] = i;//rand(); spinand_rbuf[i] = 0; } */ for(i = 0;i<8;i++) { //i = 23; /* for (j = 0; j < BYTES_PER_PAGE; j++) { spinand_wbuf[j] = j;//rand(); spinand_rbuf[j] = 0; } */ printk("test block 0 page i = %d\n",i); SpiNandWritePage(i, spinand_wbuf); delay(1000); #if 0 SpiNandReadPage(i, spinand_rbuf); delay(1000); for (j = 0; j < BYTES_PER_PAGE; j++) { if (spinand_wbuf[j] != spinand_rbuf[j]) { printk("page %d offset %d compare data fail 0x%.2x 0x%.2x.\n", i,j,spinand_wbuf[j], spinand_rbuf[j]); //SendUartString("data is error!!!!\n"); //break; } } #endif spinand_wbuf += BYTES_PER_PAGE; spinand_rbuf += BYTES_PER_PAGE; } SendUartString("test data over!!\n"); while(1); pData = (UINT8*)IMAGE_ENTRY; nPageCount = (IMAGE_MAX_SIZE + BYTES_PER_PAGE - 1) / BYTES_PER_PAGE; for(i = 0; i < nPageCount; i++) { SpiNandReadPage(i, pData); pData += BYTES_PER_PAGE; } if (CheckImageValid) { funPtr = (void (*)(void))IMAGE_ENTRY; funPtr(); } else SendUartString("Can't find loader image\n"); #endif }