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

📄 sflash-st-m25.c

📁 em86xx 完整启动程序,支持网络下载与串通下载
💻 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 + -