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

📄 sflash-st-m95.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-st-m95.c * * Serial Flash support for ST M95xxx * * by Ho Lee 11/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 ST M95xxx series * * - It doesn't suport 'bulk erase' or 'sector erase'. Writes overwrite the contents * - M95010, M95020 and M95040 send 8 bits address for reads and writes *   M95040 sends address bit 8 at bit 3 of command (reads and writes) *   M95080 and M95160 send 16 bits address for reads and writes.  * - It should have different read parameter because of the width of address lines  *   M95010, M95020 : 0x0300007f *   M95040 : 0x0300017f *   M95080, M95160 : 0x0301007f * - Correct signature byte should be written  *   M95010, M95020 : 0x7f00ed7e *   M95040 : 0xff00ed7e *   M95080, M95160 : 0x7f01ed7e * - M95010, M95020, M95040 operates at the rate of 5MHz (maximum) *   M95080L ond M95160L operates at the rate of 5MHz and M95080W and M95160W  *   operates at 10MHz. More slower serial flash timing is needed * - The page size of M95010, M95020 and M95040 is 16 bytes *   That of M95080 and M95160 is 32 bytes * * model    size                sectors sector size * M95010   1Kb (128B, 0x080)   1       0x080 * M95020   2Kb (256B, 0x100)   1       0x100 * M95040   4Kb (512B, 0x200)   1       0x200 * M95080   8Kb (1KB, 0x400)    1       0x400 * M95160   16Kb (2KB, 0x800)   1       0x800 */// ST M95xxx series serial flash#define ST95_CMD_WREN           0x06    // write enable#define ST95_CMD_WRDI           0x04    // write disable#define ST95_CMD_RDSR           0x05    // read status register#define ST95_CMD_WRSR           0x01    // write status register#define ST95_CMD_READ           0x03    // read data bytes                                        // M95040 sends A8 bits at bit 3#define ST95_CMD_PP             0x02    // page program// ST M95Pxx series status regsiter#define ST95_STAT_WIP           0x01    // write in progress bit#define ST95_STAT_WEL           0x02    // write enable latch#define ST95_STAT_BP0           0x04    // block protect bit 0#define ST95_STAT_BP1           0x08    // block protect bit 1#define ST95_STAT_SRWD          0x80    // status register write protect                                        // only M95080 and M95160                                        // this bit is 1 with M95010, M95020 and M95040// page size of pageprogram command#define ST95_PAGESIZE           16      // M95010, M95020, M95040 : 16 bytes                                        // M95080, M95160 : 32 bytesenum {    SFLASH_ST_M95010,    SFLASH_ST_M95020,    SFLASH_ST_M95040,    SFLASH_ST_M95080,    SFLASH_ST_M95160,    SFLASH_ST_DEFAULT = SFLASH_ST_M95080,};static sflash_db_t s_sflash_db_st_m95[] = {    { SFLASH_ST_M95010,     "ST-M95010",    0x080,      1,  0x080 },    { SFLASH_ST_M95020,     "ST-M95020",    0x100,      1,  0x100 },    { SFLASH_ST_M95040,     "ST-M95040",    0x200,      1,  0x200 },    { SFLASH_ST_M95080,     "ST-M95080",    0x400,      1,  0x400 },    { SFLASH_ST_M95160,     "ST-M95160",    0x800,      1,  0x800 },    { 0, NULL, 0, 0, 0 },};//// Serial Flash operations//static void sflash_st_m95_setparam(sflash_db_t *pdb, int verbose);static int sflash_st_m95_detect(sflash_op_t **pop, sflash_db_t **pdb, int verbose);static int sflash_st_m95_readstatus(void);static void sflash_st_m95_writestatus(int status);static void sflash_st_m95_waitforwip(void);static void sflash_st_m95_writeenable(void);static void sflash_st_m95_writedisable(void);static void sflash_st_m95_chiperase(sflash_db_t *pdb);static void sflash_st_m95_sectorerase(sflash_db_t *pdb, unsigned int addr);static void sflash_st_m95_pageprogram(sflash_db_t *pdb, unsigned int addr, unsigned char *data, int len);static void sflash_st_m95_read(sflash_db_t *pdb, unsigned int addr, unsigned char *to, int len);sflash_op_t g_sflash_op_st_m95 = {    vendor : SFLASH_VENDOR_ST_M95,     name : "ST M95 series",    sflash_list : s_sflash_db_st_m95,    setparam : sflash_st_m95_setparam,    detect : sflash_st_m95_detect,    readstatus : sflash_st_m95_readstatus,    writeenable : sflash_st_m95_writeenable,    writedisable : sflash_st_m95_writedisable,    chiperase : sflash_st_m95_chiperase,    sectorerase : sflash_st_m95_sectorerase,    pageprogram : sflash_st_m95_pageprogram,    read : sflash_st_m95_read,    fast_read : NULL,};//// Serial Flash functions//void sflash_st_m95_setparam(sflash_db_t *pdb, int verbose){    unsigned int data_param, data_speed;    // try to setup parameter for ST M95 series    switch (pdb->model) {    case SFLASH_ST_M95010 :    case SFLASH_ST_M95020 :         data_param = 0x0300007f;        break;    case SFLASH_ST_M95040:        data_param = 0x0300017f;        break;    case SFLASH_ST_M95080 :    case SFLASH_ST_M95160 :    default :        data_param = 0x0301007f;        break;    }    data_speed= 0x0f000020;    sflash_setparam(data_param, data_speed, verbose);}int sflash_st_m95_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 M95xxx...\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_m95;        *pdb = &s_sflash_db_st_m95[model];        sflash_st_m95_setparam(*pdb, verbose);    }    return model;}int sflash_st_m95_readstatus(void){    unsigned char data;        sflash_chipselect();    sflash_sendcommand(ST95_CMD_RDSR);                      // send command    data = sflash_readb();    sflash_chipdeselect();    return data;}void sflash_st_m95_writestatus(int status){    sflash_chipselect();    sflash_sendcommand(ST95_CMD_WRSR);                      // send command    sflash_writeb(status);    sflash_chipdeselect();    sflash_st_m95_waitforwip();}void sflash_st_m95_waitforwip(void){    int status;    do {         em86xx_usleep(1);        status = sflash_st_m95_readstatus();    } while (status & ST95_STAT_WIP);}void sflash_st_m95_writeenable(void){    int data;            data = sflash_st_m95_readstatus();    data &= ~(ST95_STAT_BP0 | ST95_STAT_BP1);    sflash_st_m95_writestatus(data);    sflash_chipselect();    sflash_sendcommand(ST95_CMD_WREN);    sflash_chipdeselect();}void sflash_st_m95_writedisable(void){    sflash_chipselect();    sflash_sendcommand(ST95_CMD_WRDI);    sflash_chipdeselect();}void sflash_st_m95_chiperase(sflash_db_t *pdb){    unsigned char data[ST95_PAGESIZE];    unsigned int addr = 0;    int len = pdb->size, unit;    memset(data, 0xff, sizeof data);        while (len > 0) {        unit = (len > ST95_PAGESIZE) ? ST95_PAGESIZE : len;        sflash_st_m95_pageprogram(pdb, addr, data, unit);        len -= unit;        addr += unit;    }}void sflash_st_m95_sectorerase(sflash_db_t *pdb, unsigned int addr){    sflash_st_m95_chiperase(pdb);}void sflash_st_m95_pageprogram(sflash_db_t *pdb, unsigned int addr, unsigned char *data, int len){    int i;            while (len > 0) {        sflash_st_m95_writeenable();        sflash_chipselect();        sflash_writeb(ST95_CMD_PP | ((pdb->model == SFLASH_ST_M95040) ? ((addr & 0x100) >> 5) : 0));        if (pdb->model <= SFLASH_ST_M95040)            sflash_writeb(addr);        else            sflash_writew(addr);        for (i = 0; i < len && i < ST95_PAGESIZE; ++i)            sflash_writeb(data[i]);        sflash_chipdeselect();        addr += ST95_PAGESIZE;        len -= ST95_PAGESIZE;        data += ST95_PAGESIZE;                sflash_st_m95_waitforwip();        sflash_st_m95_writedisable();    }}void sflash_st_m95_read(sflash_db_t *pdb, unsigned int addr, unsigned char *to, int len){    int i;    sflash_chipselect();    sflash_writeb(ST95_CMD_READ | ((pdb->model == SFLASH_ST_M95040) ? ((addr & 0x100) >> 5) : 0));    if (pdb->model <= SFLASH_ST_M95040)        sflash_writeb(addr);    else        sflash_writew(addr);    for (i = 0; i < len; ++i)        to[i] = sflash_readb();    sflash_chipdeselect();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -