/*---------------------------------------------------------------------------------------------------- INCLUDE HEADE FILES ----------------------------------------------------------------------------------------------------*/ #include "Includes.h" /*---------------------------------------------------------------------------------------------------- SPI COMMAND -----------------------------------------------------------------------------------------------------*/ #define CMD_RDID 0x9F #define CMD_PAGE_ERASE 0x81 #define CMD_READ_STATUS2 0x35 #define CMD_WRITE_STATUS 0x01 #define CMD_READ_DATA 0x03 #define CMD_READ_STATUS 0x05 #define CMD_CHIP_ERASE 0xc7 #define CMD_WRITE_ENABLE 0x06 #define CMD_PAGE_PROGRAM 0x02 #define CMD_BLOCK_ERASE 0xD8 #define CMD_SECTOR_ERASE 0x20 #define CMD_RELEASE_PWRDWN 0xAB #define CMD_PWRDWN 0xB9 #define CMD_ID 0x4B #define PACKET_FULL_LEN FLASH_PAGE_SIZE static uint8_t __attribute__((aligned(4))) txbuff[(PACKET_FULL_LEN+4)]; static uint8_t __attribute__((aligned(4))) rxbuff[(PACKET_FULL_LEN+4)]; /* --------------------------------------------------------------------------------------------------- - 函数名称: Init_spi_master - 函数功能: 初始化spi主模式 - 创建日期: 2015-09-14 ----------------------------------------------------------------------------------------------------*/ void Init_spi_master(uint32_t ch, uint32_t freq) { uint32_t val; __write_hw_reg32(CPR_SPIx_MCLK_CTL(ch), 0x110010);//1分频 //- spi(x)_mclk = 32Mhz(When TXCO=32Mhz). __write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL , (0x1000100<>16); txbuff[0] = CMD_READ_DATA; txbuff[3] = (uint8_t)(addr); txbuff[2] = (uint8_t)(addr>>8); __write_hw_reg32(SSI0_EN , 0x00); __write_hw_reg32(SSI0_DMAS , 0x03); __write_hw_reg32(SSI0_DMATDL, 0x4); //- __write_hw_reg32(SSI0_DMARDL, 0x4); //- 1/4 FIFO __write_hw_reg32(SSI0_EN , 0x01); //- RX Channel __write_hw_reg32(DMAS_CHx_SAR(10) , 0x40013060); __write_hw_reg32(DMAS_CHx_DAR(10) , (uint32_t)rxbuff); __write_hw_reg32(DMAS_CHx_CTL1(10) ,((2 << 8)| 0)); __write_hw_reg32(DMAS_CHx_CTL0(10) ,(PACKET_FULL_LEN+4)); __write_hw_reg32(DMAS_EN , 10); //- TX Channel __write_hw_reg32(DMAS_CHx_SAR(2) , (uint32_t)txbuff); __write_hw_reg32(DMAS_CHx_DAR(2) , 0x40013060); __write_hw_reg32(DMAS_CHx_CTL1(2) ,((2 << 8)| 0)); __write_hw_reg32(DMAS_CHx_CTL0(2) ,(PACKET_FULL_LEN+4)); __write_hw_reg32(DMAS_EN , 2); do { __read_hw_reg32(DMAS_INT_RAW , iWK); }while((iWK&0x404) != 0x404); __write_hw_reg32(DMAS_INT_RAW, 0x404); __write_hw_reg32(DMAS_CLR , 10); __write_hw_reg32(DMAS_CLR , 2); __write_hw_reg32(SSI0_EN , 0x00); for(int i=0;i>16); txbuff[0] = CMD_PAGE_PROGRAM; txbuff[3] = (uint8_t)(addr); txbuff[2] = (uint8_t)(addr>>8); __write_hw_reg32(SSI0_EN , 0x00); __write_hw_reg32(SSI0_DMAS , 0x03); __write_hw_reg32(SSI0_DMATDL, 0x4); //- __write_hw_reg32(SSI0_DMARDL, 0x4); //- 1/2FIFO __write_hw_reg32(SSI0_EN , 0x01); //- RX Channel __write_hw_reg32(DMAS_CHx_SAR(10), 0x40013060); __write_hw_reg32(DMAS_CHx_DAR(10), (uint32_t)rxbuff); __write_hw_reg32(DMAS_CHx_CTL1(10),((2 << 8)| 0)); __write_hw_reg32(DMAS_CHx_CTL0(10),(PACKET_FULL_LEN+4)); __write_hw_reg32(DMAS_EN, 10); //- TX Channel __write_hw_reg32(DMAS_CHx_SAR(2), (uint32_t)txbuff); __write_hw_reg32(DMAS_CHx_DAR(2), 0x40013060); __write_hw_reg32(DMAS_CHx_CTL1(2),((2 << 8)| 0)); __write_hw_reg32(DMAS_CHx_CTL0(2),(PACKET_FULL_LEN+4)); __write_hw_reg32(DMAS_EN, 2); do { __read_hw_reg32(DMAS_INT_RAW , iWK); }while((iWK&0x404) != 0x404); __write_hw_reg32(DMAS_INT_RAW, 0x404); __write_hw_reg32(DMAS_CLR , 10); __write_hw_reg32(DMAS_CLR , 2); __write_hw_reg32(SSI0_EN , 0x00); } //void spi_flash_page_erase(uint32_t addr) //{ // uint32_t bWk, cWk; // __read_hw_reg32(SSI0_CTRL0 , bWk); // __write_hw_reg32(SSI0_EN , 0x00); // __write_hw_reg32(SSI0_DMAS , 0x00); // __write_hw_reg32(SSI0_CTRL0 , 0x07); /* 8bit SPI data */ // __write_hw_reg32(SSI0_EN , 0x01); // __write_hw_reg32(SSI0_DATA, CMD_PAGE_ERASE); // __write_hw_reg32(SSI0_DATA, (uint8_t)(addr>>16)); // __write_hw_reg32(SSI0_DATA, (uint8_t)(addr>>8)); // __write_hw_reg32(SSI0_DATA, (uint8_t)(addr)); // do { // __read_hw_reg32(SSI0_STS, cWk); // }while((cWk&0x05) != 0x04); // __write_hw_reg32(SSI0_EN , 0x00); // __write_hw_reg32(SSI0_CTRL0 , bWk); //} void spi_flash_sector_erase(uint32_t addr) { // if((addr>=(4096+param_backup_addr))&&(addr<(8192+param_backup_addr))) return; //forbid erase the calibration parameter area uint32_t bWk, cWk; __read_hw_reg32(SSI0_CTRL0 , bWk); __write_hw_reg32(SSI0_EN , 0x00); __write_hw_reg32(SSI0_DMAS , 0x00); __write_hw_reg32(SSI0_CTRL0 , 0x07); /* 8bit SPI data */ __write_hw_reg32(SSI0_EN , 0x01); __write_hw_reg32(SSI0_DATA, CMD_SECTOR_ERASE); __write_hw_reg32(SSI0_DATA, (uint8_t)(addr>>16)); __write_hw_reg32(SSI0_DATA, (uint8_t)(addr>>8)); __write_hw_reg32(SSI0_DATA, (uint8_t)(addr)); do { __read_hw_reg32(SSI0_STS, cWk); }while((cWk&0x05) != 0x04); __write_hw_reg32(SSI0_EN , 0x00); __write_hw_reg32(SSI0_CTRL0 , bWk); } void spi_flash_block_erase(uint32_t addr) { uint32_t bWk, cWk; __read_hw_reg32(SSI0_CTRL0 , bWk); __write_hw_reg32(SSI0_EN , 0x00); __write_hw_reg32(SSI0_DMAS , 0x00); __write_hw_reg32(SSI0_CTRL0 , 0x07); /* 8bit SPI data */ __write_hw_reg32(SSI0_EN , 0x01); __write_hw_reg32(SSI0_DATA, CMD_BLOCK_ERASE); __write_hw_reg32(SSI0_DATA, (uint8_t)(addr>>16)); __write_hw_reg32(SSI0_DATA, (uint8_t)(addr>>8)); __write_hw_reg32(SSI0_DATA, (uint8_t)(addr)); do { __read_hw_reg32(SSI0_STS, cWk); }while((cWk&0x05) != 0x04); __write_hw_reg32(SSI0_EN , 0x00); __write_hw_reg32(SSI0_CTRL0 , bWk); } void spi_flash_write_enable(void) { uint32_t bWk, cWk; __read_hw_reg32(SSI0_CTRL0 , bWk); __write_hw_reg32(SSI0_EN, 0x00); __write_hw_reg32(SSI0_DMAS , 0x00); __write_hw_reg32(SSI0_CTRL0 , 0x07); /* 8bit SPI data */ __write_hw_reg32(SSI0_EN, 0x01); __write_hw_reg32(SSI0_DATA, CMD_WRITE_ENABLE); do { __read_hw_reg32(SSI0_STS, cWk); }while((cWk&0x05) != 0x04); __write_hw_reg32(SSI0_EN, 0x00); __write_hw_reg32(SSI0_CTRL0, bWk); } void spi_flash_Release_powerdown(void) { uint32_t bWk, cWk; __read_hw_reg32(SSI0_CTRL0, bWk); __write_hw_reg32(SSI0_EN, 0x00); __write_hw_reg32(SSI0_DMAS, 0x00); __write_hw_reg32(SSI0_CTRL0, 0x07); /* 8bit SPI data */ __write_hw_reg32(SSI0_EN, 0x01); __write_hw_reg32(SSI0_DATA, CMD_RELEASE_PWRDWN); do { __read_hw_reg32(SSI0_STS, cWk); }while((cWk&0x05) != 0x04); __write_hw_reg32(SSI0_EN, 0x00); __write_hw_reg32(SSI0_CTRL0, bWk); } void spi_flash_Enter_powerdown(void) { uint32_t bWk, cWk; __read_hw_reg32(SSI0_CTRL0, bWk); __write_hw_reg32(SSI0_EN, 0x00); __write_hw_reg32(SSI0_DMAS, 0x00); __write_hw_reg32(SSI0_CTRL0, 0x07); /* 8bit SPI data */ __write_hw_reg32(SSI0_EN, 0x01); __write_hw_reg32(SSI0_DATA, CMD_PWRDWN); do { __read_hw_reg32(SSI0_STS, cWk); }while((cWk&0x05) != 0x04); __write_hw_reg32(SSI0_EN, 0x00); __write_hw_reg32(SSI0_CTRL0, bWk); } uint8_t spi_flash_wait_till_ready (void) { uint16_t cmd = (CMD_READ_STATUS<<8); uint32_t iWK,bWk; uint16_t dWK = 0; __read_hw_reg32(SSI0_CTRL0 , bWk); __write_hw_reg32(SSI0_EN , 0x00); __write_hw_reg32(SSI0_CTRL0 , 0x0F); /* 16bit SPI data */ __write_hw_reg32(SSI0_DMAS , 0x00); /* turn off dma*/ __write_hw_reg32(SSI0_DMATDL, 0x0); //- __write_hw_reg32(SSI0_DMARDL, 0x0); //- __write_hw_reg32(SSI0_EN , 0x01); __write_hw_reg32(SSI0_DATA , cmd); do { __read_hw_reg32(SSI0_STS, iWK); }while((iWK&0x05) != 0x04); __read_hw_reg32(SSI0_DATA , dWK); __write_hw_reg32(SSI0_EN , 0x00); __write_hw_reg32(SSI0_CTRL0 , bWk); return (uint8_t)(dWK&0x01); } #ifdef TEST_SPI_FLASH void test_spi_master(void) { spi_flash_Release_powerdown(); #ifdef QUAD_ENABLE if((spi_flash_read_stat()&0x02)==0) { printf("\n@@ QUAD ENABLE @@\n"); spi_flash_write_enable(); spi_flash_quad_en(); while(spi_flash_wait_till_ready()); } printf("s15_8=%#X\n",spi_flash_read_stat()); #endif uint8_t tx_arr[256]; uint8_t rx_arr[256]; static uint8_t flag=0; printf("capacity=%#X\n",spi_flash_read_identific()); /*read a page*/ spi_flash_Read_Page(0*4096,rx_arr); for(int i=0;i<256;i++) printf("%02x ",rx_arr[i]); printf("\n*****************#*******************\n"); if(flag){ flag=0; for(int i=0; i<256; i++) tx_arr[i]=i; }else{ for(int i=0; i<256; i++) tx_arr[i]=255-i; flag=1; } /*erase a page/sector*/ spi_flash_write_enable(); spi_flash_sector_erase(31*4096); //spi_flash_page_erase(31*4096); while(spi_flash_wait_till_ready()); /*write a page*/ spi_flash_write_enable(); spi_flash_write_page(31*4096,tx_arr); while(spi_flash_wait_till_ready()); /*read a page*/ spi_flash_Read_Page(31*4096,rx_arr); for(int i=0;i<256;i++) printf("%02x ",rx_arr[i]); printf("\n*****************@*******************\n"); // spi_flash_Enter_powerdown(); } #endif