📄 sflash-st-m25.c
字号:
/***************************************** Copyright (c) 2003-2004 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the EM86XX boot loader *//* * sflash.c * * Serial Flash support * * by Ho Lee 02/04/2003 */#include "config.h"#include "uart.h"#include "io.h"#include "util.h"#include "hardware.h"#include "em86xxapi.h"#include "sflash.h"/* comments about ST25 series * * - Don't send each command after chip select. sending WREN and BE together doesn't work * - To read status register, after sending command, it is needed to send 8 stuff bits * - To program flash, send WREN each time before programming. programming flash reset * write eanble latch bit before completing programming. * * model size sectors sector size * M25P05 512Kb (64KB, 0x10000) 2 0x08000 * M25P10 1Mb (128KB, 0x20000) 4 0x08000 * M25P20 2Mb (256KB, 0x40000) 4 0x10000 * M25P40 4Mb (512KB, 0x80000) 8 0x10000 * M25P80 8Mb (1MB, 0x100000) 16 0x10000 *///// For SGI Thompson Serial Flash series//// ST M25Pxx series serial flash#define ST25_CMD_WREN 0x06 // write enable#define ST25_CMD_WRDI 0x04 // write disable#define ST25_CMD_RDSR 0x05 // read status register#define ST25_CMD_WRSR 0x01 // write status register#define ST25_CMD_READ 0x03 // read data bytes#define ST25_CMD_FAST_READ 0x0b // read data bytes at higher speed#define ST25_CMD_PP 0x02 // page program#define ST25_CMD_SE 0xd8 // sector erase#define ST25_CMD_CE 0xc7 // chip erase#define ST25_CMD_DP 0xb9 // deep power down#define ST25_CMD_RES 0xab // release from deep power down// ST M25Pxx series status regsiter#define ST25_STAT_WIP 0x01 // write in progress bit#define ST25_STAT_WEL 0x02 // write enable latch#define ST25_STAT_BP0 0x04 // block protect bit 0#define ST25_STAT_BP1 0x08 // block protect bit 1#define ST25_STAT_BP2 0x10 // block protect bit 2#define ST25_STAT_SRWD 0x80 // status register write protect// page size of pageprogram command#define ST25_PAGESIZE 128 // M25P10 : 128 bytes // M25P40 : 256 bytesenum { SFLASH_ST_M25P05, SFLASH_ST_M25P10, SFLASH_ST_M25P20, SFLASH_ST_M25P40, SFLASH_ST_M25P80, SFLASH_ST_DEFAULT = SFLASH_ST_M25P05,};static sflash_db_t s_sflash_db_st_m25[] = { { SFLASH_ST_M25P05, "ST-M25P05", 0x10000, 2, 0x08000 }, { SFLASH_ST_M25P10, "ST-M25P10", 0x20000, 4, 0x08000 }, { SFLASH_ST_M25P20, "ST-M25P20", 0x40000, 4, 0x10000 }, { SFLASH_ST_M25P40, "ST-M25P40", 0x80000, 8, 0x10000 }, { SFLASH_ST_M25P80, "ST-M25P80", 0x100000, 16, 0x10000 }, { 0, NULL, 0, 0, 0 },};//// Serial Flash operations//static void sflash_st_m25_setparam(sflash_db_t *pdb, int verbose);static int sflash_st_m25_detect(sflash_op_t **pop, sflash_db_t **pdb, int verbose);static int sflash_st_m25_readstatus(void);static void sflash_st_m25_writeenable(void);static void sflash_st_m25_writedisable(void);static void sflash_st_m25_chiperase(sflash_db_t *pdb);static void sflash_st_m25_sectorerase(sflash_db_t *pdb, unsigned int addr);static void sflash_st_m25_pageprogram(sflash_db_t *pdb, unsigned int addr, unsigned char *data, int len);static void sflash_st_m25_read(sflash_db_t *pdb, unsigned int addr, unsigned char *to, int len);static void sflash_st_m25_fast_read(sflash_db_t *pdb, unsigned int addr, unsigned char *to, int len);sflash_op_t g_sflash_op_st_m25 = { vendor : SFLASH_VENDOR_ST_M25, name : "ST M25 series", sflash_list : s_sflash_db_st_m25, setparam : sflash_st_m25_setparam, detect : sflash_st_m25_detect, readstatus : sflash_st_m25_readstatus, writeenable : sflash_st_m25_writeenable, writedisable : sflash_st_m25_writedisable, chiperase : sflash_st_m25_chiperase, sectorerase : sflash_st_m25_sectorerase, pageprogram : sflash_st_m25_pageprogram, read : sflash_st_m25_read, fast_read : sflash_st_m25_fast_read,};//// Serial Flash functions//void sflash_st_m25_setparam(sflash_db_t *pdb, int verbose){ unsigned int data_param, data_speed; // try to setup parameter for ST M25 series data_param = 0x0302007f; data_speed = 0x0f000003; sflash_setparam(data_param, data_speed, verbose);}int sflash_st_m25_detect(sflash_op_t **pop, sflash_db_t **pdb, int verbose){ int model = -1; unsigned int JS, JI, JO; unsigned int data; if (verbose) uart_puts("Try to detect ST M25Pxx...\n"); data = __raw_readl(REG_BASE_HOST + SFLA_status); JS = data & 0x01000000; JI = data & 0x00020000; JO = data & 0x00010000; if (!JI && !JO) model = SFLASH_ST_DEFAULT; if (model >= 0) { *pop = &g_sflash_op_st_m25; *pdb = &s_sflash_db_st_m25[model]; sflash_st_m25_setparam(*pdb, verbose); } return model;}int sflash_st_m25_readstatus(void){ unsigned char data; sflash_chipselect(); sflash_sendcommand(ST25_CMD_RDSR); // send command data = sflash_readb(); sflash_chipdeselect(); return data;}void sflash_st_m25_writeenable(void){ sflash_chipselect(); sflash_sendcommand(ST25_CMD_WREN); sflash_chipdeselect();}void sflash_st_m25_writedisable(void){ sflash_chipselect(); sflash_sendcommand(ST25_CMD_WRDI); sflash_chipdeselect();}void sflash_st_m25_chiperase(sflash_db_t *pdb){ int status; sflash_st_m25_writeenable(); sflash_chipselect(); sflash_sendcommand(ST25_CMD_CE); sflash_chipdeselect(); do { em86xx_usleep(10); status = sflash_st_m25_readstatus(); } while (status & ST25_STAT_WIP); sflash_st_m25_writedisable();}void sflash_st_m25_sectorerase(sflash_db_t *pdb, unsigned int addr){ int status; sflash_st_m25_writeenable(); sflash_chipselect(); sflash_writel((ST25_CMD_SE << 24) | addr); sflash_chipdeselect(); do { em86xx_usleep(10); status = sflash_st_m25_readstatus(); } while (status & ST25_STAT_WIP); sflash_st_m25_writedisable();}void sflash_st_m25_pageprogram(sflash_db_t *pdb, unsigned int addr, unsigned char *data, int len){ int i; int status; while (len > 0) { sflash_st_m25_writeenable(); sflash_chipselect(); sflash_writel((ST25_CMD_PP << 24) | addr); for (i = 0; i < len && i < ST25_PAGESIZE; ++i) sflash_writeb(data[i]); sflash_chipdeselect(); addr += ST25_PAGESIZE; len -= ST25_PAGESIZE; data += ST25_PAGESIZE; do { em86xx_usleep(1); status = sflash_st_m25_readstatus(); } while (status & ST25_STAT_WIP); sflash_st_m25_writedisable(); }}void sflash_st_m25_read(sflash_db_t *pdb, unsigned int addr, unsigned char *to, int len){ int i; sflash_chipselect(); sflash_writel((ST25_CMD_READ << 24) | addr); for (i = 0; i < len; ++i) to[i] = sflash_readb(); sflash_chipdeselect();}void sflash_st_m25_fast_read(sflash_db_t *pdb, unsigned int addr, unsigned char *to, int len){ int i; sflash_chipselect(); sflash_writel((ST25_CMD_FAST_READ << 24) | addr); sflash_writeb(0); for (i = 0; i < len; ++i) to[i] = sflash_readb(); sflash_chipdeselect();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -