📄 sflash.c
字号:
#include <common.h>#ifdef CONFIG_SERIAL_FLASH#include <asm/inca-ip.h>#include <serial_flash.h>extern uint incaip_get_fpiclk (void);#define SERIAL_FLASH_CHIPSELECT_0 *INCA_IP_Ports_P1_OUT &= ~(1 << 16); \ *INCA_IP_SSC1_SCC_CON_PRG &= ~INCA_IP_SSC1_SCC_CON_PRG_EN; \ *INCA_IP_SSC1_SCC_CON_PRG |= INCA_IP_SSC1_SCC_CON_PRG_HB; /* MSB First */ \ *INCA_IP_SSC1_SSC_BR = 1; \ *INCA_IP_SSC1_SCC_CON_OPR |= INCA_IP_SSC1_SCC_CON_OPR_EN;#define SERIAL_FLASH_CHIPSELECT_1 *INCA_IP_Ports_P1_OUT |= (1 << 16); \ *INCA_IP_SSC1_SCC_CON_PRG &= ~INCA_IP_SSC1_SCC_CON_PRG_EN; \ *INCA_IP_SSC1_SCC_CON_PRG &= ~INCA_IP_SSC1_SCC_CON_PRG_HB; /* LSB First */ \ *INCA_IP_SSC1_SSC_BR |= INCA_IP_SSC1_SSC_BR_BR_VALUE((incaip_get_fpiclk()>>1)/BAUD_RATE-1); \ *INCA_IP_SSC1_SCC_CON_OPR |= INCA_IP_SSC1_SCC_CON_OPR_EN;#define SF_WRITE_ENABLE SERIAL_FLASH_CHIPSELECT_0; \ ssc_write(SERIAL_FLASH_WREN); \ SERIAL_FLASH_CHIPSELECT_1;#define SF_WRITE_DISABLE SERIAL_FLASH_CHIPSELECT_0; \ ssc_write(SERIAL_FLASH_WRDI); \ SERIAL_FLASH_CHIPSELECT_1;#define SF_WRITE_ADDR(value) ssc_write((value & 0xFF0000) >> 16); \ ssc_write((value & 0x00FF00) >> 8); \ ssc_write(value & 0x0000FF);/************************************************************************ * Function name: SF_init * Description : Initializes the port that will be used to chip- select the serial flash * Input value : none * Return value : none ***********************************************************************/void SF_init(void){ /* Port 1.16 is used for the serial flash memory */ *INCA_IP_Ports_P1_ALTSEL |= (1 << 16); /* P1.16 set to GPIO */ *INCA_IP_Ports_P1_DIR |= (1 << 16); /* P1.16 direction output */ *INCA_IP_Ports_P1_OUT |= (1 << 16); /* Chipselect is at high */ return;}/************************************************************************ * Function name: SF_wait * Description : Waits until the write in progress bit WIP in in the status register is reset, or until timeout, which ever occurs first * Input value : timeout in milliseconds * Return value : 0 on success ***********************************************************************/int SF_wait (ulong timeout){ /* sr holds the status register reading */ uchar sr; /* Timeout variables */ ulong start, now, last; SERIAL_FLASH_CHIPSELECT_0; ssc_write (SERIAL_FLASH_RDSR); /* NOTE: TIMEOUT HAS TO BE ACCOUNTED FOR */ last = get_timer(0); start = get_timer(0); while (1) { ssc_write(0x00); ssc_read(&sr); /* Check if the instruction is completed */ if ((sr & SERIAL_FLASH_SR_WIP) != SERIAL_FLASH_SR_WIP && (sr & SERIAL_FLASH_SR_WEL) != SERIAL_FLASH_SR_WEL) { break; } if ((now = get_timer(start)) > timeout) { SERIAL_FLASH_CHIPSELECT_1; return SFLASH_TIMOUT; } /* Show that we are waiting, print a . every second */ if ((get_timer(last)) > CFG_HZ) { putc('.'); last = get_timer(0); } } SERIAL_FLASH_CHIPSELECT_1; return SFLASH_OK;}/************************************************************************ * Function name: SF_read_ID * Input value : None * Return value : 0 on success ***********************************************************************/int SF_read_id (ulong *id){ uchar temp[3]; SERIAL_FLASH_CHIPSELECT_0; ssc_write(SERIAL_FLASH_RDID); ssc_write(0x00); ssc_read(temp); ssc_write(0x00); ssc_read(temp+1); ssc_write(0x00); ssc_read(temp+2); SERIAL_FLASH_CHIPSELECT_1; *id = 0x000000; *id |= (temp[0] << 16); *id |= (temp[1] << 8); *id |= temp[2]; return SFLASH_OK;}/************************************************************************ * Function name: SF_read_status_register * Input value : pointer to a char to hold the status register value * Return value : 0 on success ***********************************************************************/int SF_read_status_register (uchar *sr){ SERIAL_FLASH_CHIPSELECT_0; ssc_write(SERIAL_FLASH_RDSR); ssc_write(0x00); ssc_read(sr); SERIAL_FLASH_CHIPSELECT_1; return SFLASH_OK;}/************************************************************************ * Function name: SF_write_status_register * Input value : Value to be written * Return value : 0 on success ***********************************************************************/int SF_write_status_register (uchar sr){ SF_WRITE_ENABLE; SERIAL_FLASH_CHIPSELECT_0; ssc_write(SERIAL_FLASH_WRSR); ssc_write(sr); SERIAL_FLASH_CHIPSELECT_1; return SF_wait(SERIAL_FLASH_WRSR_TIMEOUT);}/************************************************************************ * Function name: SF_page_program * Description : programs at address 'addr', 'size' bytes from 'result'. In case more that 256 bytes are sent, the the last 256 bytes are programmed. * Input value : address addr, number of bytes to be programmed, and a pointer to where the source data is stored * Return value : 0 on success, 1 on failure ***********************************************************************/int SF_page_program (ulong addr, ulong size, uchar *data){ unsigned int i; SF_WRITE_ENABLE; SERIAL_FLASH_CHIPSELECT_0; ssc_write(SERIAL_FLASH_PP); SF_WRITE_ADDR(addr); for (i = 0; i < size; i++) { ssc_write(data[i]); } SERIAL_FLASH_CHIPSELECT_1; return SF_wait(SERIAL_FLASH_PP_TIMEOUT);}/************************************************************************ * Function name: SF_sector_erase * Description : Erases the sector of memory which contains the address 'addr'. Assumes that a check whether this sector is protected was done by the calling function. * Input value : address addr * Return value : 0 on success, 1 on failure ***********************************************************************/int SF_sector_erase (ulong addr){ SF_WRITE_ENABLE; SERIAL_FLASH_CHIPSELECT_0; ssc_write(SERIAL_FLASH_SE); SF_WRITE_ADDR(addr); SERIAL_FLASH_CHIPSELECT_1; putc('.'); return SF_wait(SERIAL_FLASH_SE_TIMEOUT);}/************************************************************************ * Function name: SF_bulk_erase * Description : Erases the entire flash except for the protected sectors * Input value : None * Return value : 0 on success, 1 on failure ***********************************************************************/int SF_bulk_erase (void){ unsigned int i; unsigned char sr; SF_WRITE_ENABLE; SERIAL_FLASH_CHIPSELECT_0; ssc_write(SERIAL_FLASH_BE); SERIAL_FLASH_CHIPSELECT_1; /* With bulk erase, the timeout is 160 seconds, more than the ulong get_timer function can handle. Instead of using ulong long type that will introduce unnecessary overhead on other function, I split the entire wait for the bulk erase into 4 wait calls */ putc('.'); for (i = 0; i < 4; i++) { if (SF_wait(SERIAL_FLASH_BE_SUB_TIMEOUT) == SFLASH_OK) { return SFLASH_OK; break; } } return SFLASH_TIMOUT;}/************************************************************************ * Function name: SF_read * Description : reads 'size' bytes into 'result' from flash memory starting at address 'addr'. * Input value : address addr, size to be read, and a pointer to where the read data will be stored * Return value : 0 on success, 1 on failure ***********************************************************************/int SF_read (ulong addr, ulong size, uchar *result){ int i; SERIAL_FLASH_CHIPSELECT_0; ssc_write(SERIAL_FLASH_READ); SF_WRITE_ADDR(addr); for (i = 0; i < size; i++) { ssc_write(0x00); ssc_read(result + i); } SERIAL_FLASH_CHIPSELECT_1; return SFLASH_OK;}/************************************************************************ * Function name: SF_fast_read * Description : reads 'size' bytes into 'result' from flash memory starting at address 'addr'. Does not allows indefinite loop reading of memory! * Input value : address addr, size to be read, and a pointer to where the read data will be stored * Return value : 0 on success, 1 on failure ***********************************************************************/int SF_fast_read (ulong addr, ulong size, uchar *result){ unsigned int i; SERIAL_FLASH_CHIPSELECT_0; ssc_write(SERIAL_FLASH_READ); SF_WRITE_ADDR(addr); for (i = 0; i < size; i++) { ssc_write(0x00); ssc_read(result + i); } SERIAL_FLASH_CHIPSELECT_1; return SFLASH_OK;}/************************************************************************ * Function name: SF_block_protect * Input value : char with the three Block protect bits * Return value : 0 on success ***********************************************************************/int SF_block_protect (uchar bp){ uchar sr;/* SF_read_status_register(&sr);*/ SERIAL_FLASH_CHIPSELECT_0; ssc_write(SERIAL_FLASH_RDSR); ssc_write(0x00); ssc_read(sr); ssc_write(0x00); ssc_read(sr); SERIAL_FLASH_CHIPSELECT_1; sr &= ~SERIAL_FLASH_SR_BP_MASK; sr |= SERIAL_FLASH_SR_BP(bp); return SF_write_status_register(sr);}#endif /* CONFIG_SERIAL_FLASH */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -