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

📄 sflash-sst.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-sst.c * * Serial Flash support - SST *   Supported Model : SST25VF512 * * by Ho Lee 04/22/2003 */#include "config.h"#include "uart.h"#include "io.h"#include "util.h"#include "hardware.h"#include "em86xxapi.h"#include "sflash.h"/* comments about SST25 series * * - It supports vendor ID and device ID, so it's possible to read the ID *   and to set the correct model number.  * - There are protection bits in status register. It protects the serial *   flash from programming. These bits should be turned off before programming *   and on after programming.  * * model        size            sectors sector size * SSTVF512     512Kb (64KB)    16      0x01000 (4KB) * SSTVF010     1Mb (128KB)     32      0x01000 (4KB) * SSTVF020     2Mb (256KB)     32      0x01000 (4KB) * SSTVF040     4Mb (512KB)     32      0x01000 (4KB) *///// For SST Serial Flash series//// IDs#define SST_VENDORID            0xbf#define SST_DEVICEID_25VF512    0x48#define SST_DEVICEID_25VF010    0x49#define SST_DEVICEID_25VF020    0x43#define SST_DEVICEID_25VF040    0x44// Commands#define SST25_CMD_WREN          0x06    // write enable#define SST25_CMD_WRDI          0x04    // write disable#define SST25_CMD_RDSR          0x05    // read status register#define SST25_CMD_WRSR          0x01    // write status register#define SST25_CMD_EWSR          0x50    // enable write status register#define SST25_CMD_READ          0x03    // read data bytes#define SST25_CMD_AAIP          0xaf    // auto address increment program#define SST25_CMD_BP            0x02    // byte program#define SST25_CMD_SE            0x20    // sector erase#define SST25_CMD_BE            0x52    // block erase#define SST25_CMD_CE            0x60    // chip erase#define SST25_CMD_READID        0xab    // read ID// Status register#define SST25_STAT_WIP          0x01    // write in progress bit (busy)#define SST25_STAT_WEL          0x02    // write enable latch#define SST25_STAT_BP0          0x04    // block protect bit 0#define SST25_STAT_BP1          0x08    // block protect bit 1#define SST25_STAT_AAI          0x40    // auto address increment programming status#define SST25_STAT_BPL          0x80    // block write protect write protect// page size of pageprogram command#define SST25_PAGESIZE          256enum {    SFLASH_SST_25VF512,    SFLASH_SST_25VF010,    SFLASH_SST_25VF020,    SFLASH_SST_25VF040,};static sflash_db_t s_sflash_db_sst[] = {    { SFLASH_SST_25VF512,   "SST-25VF512",  0x10000,   16,  0x01000 },    { SFLASH_SST_25VF010,   "SST-25VF010",  0x20000,   32,  0x01000 },    { SFLASH_SST_25VF020,   "SST-25VF020",  0x40000,   64,  0x01000 },    { SFLASH_SST_25VF040,   "SST-25VF040",  0x80000,  128,  0x01000 },    { 0, NULL, 0, 0, 0 },};//// Serial Flash operations//static void sflash_sst_setparam(sflash_db_t *pdb, int verbose);static int sflash_sst_detect(sflash_op_t **pop, sflash_db_t **pdb, int verbose);static int sflash_sst_readid(int *pvendor, int *pdevice);static int sflash_sst_readstatus(void);static void sflash_sst_writeenable(void);static void sflash_sst_writedisable(void);static void sflash_sst_setprotection(int enable);static void sflash_sst_chiperase(sflash_db_t *pdb);static void sflash_sst_sectorerase(sflash_db_t *pdb, unsigned int addr);static void sflash_sst_pageprogram(sflash_db_t *pdb, unsigned int addr, unsigned char *data, int len);static void sflash_sst_read(sflash_db_t *pdb, unsigned int addr, unsigned char *to, int len);sflash_op_t g_sflash_op_sst = {    vendor : SFLASH_VENDOR_SST_25,     name : "SST 25VF series",    sflash_list : s_sflash_db_sst,    setparam : sflash_sst_setparam,    detect : sflash_sst_detect,    readstatus : sflash_sst_readstatus,    writeenable : sflash_sst_writeenable,    writedisable : sflash_sst_writedisable,    chiperase : sflash_sst_chiperase,    sectorerase : sflash_sst_sectorerase,    pageprogram : sflash_sst_pageprogram,    read : sflash_sst_read,    fast_read : NULL,};//// Serial Flash functions//void sflash_sst_setparam(sflash_db_t *pdb, int verbose){    unsigned int data_param, data_speed;    // try to setup parameter for SST 25VF series    data_param = 0x0302007f;    data_speed = 0x0f000003;    sflash_setparam(data_param, data_speed, verbose);}int sflash_sst_detect(sflash_op_t **pop, sflash_db_t **pdb, int verbose){    int model = -1;    unsigned int JS, JI, JO;    int vendorid, deviceid;    unsigned int data;    if (verbose)        uart_puts("Try to detect SST 25VFxxx...\n");    sflash_sst_setparam(NULL, verbose);    // read jumper settings    data = __raw_readl(REG_BASE_HOST + SFLA_status);    JS = data & 0x01000000;    JI = data & 0x00020000;    JO = data & 0x00010000;    if (!JI && !JO) {        sflash_sst_readid(&vendorid, &deviceid);        if (vendorid == SST_VENDORID) {            switch (deviceid) {            case SST_DEVICEID_25VF512 :                model = SFLASH_SST_25VF512;                break;            case SST_DEVICEID_25VF010 :                model = SFLASH_SST_25VF010;                break;            case SST_DEVICEID_25VF020 :                model = SFLASH_SST_25VF020;                break;            case SST_DEVICEID_25VF040 :                model = SFLASH_SST_25VF040;                break;            }        }    }    if (model >= 0) {        *pop = &g_sflash_op_sst;        *pdb = &s_sflash_db_sst[model];        sflash_sst_setparam(*pdb, verbose);    }    return model;}int sflash_sst_readid(int *pvendor, int *pdevice){    int i;    int data[2];    sflash_chipselect();    sflash_writel((SST25_CMD_READID << 24) | 0);    for (i = 0; i < 2; ++i)        data[i] = sflash_readb();    if (pvendor)        *pvendor = data[0];    if (pdevice)        *pdevice = data[1];    sflash_chipdeselect();    return 0;}int sflash_sst_readstatus(void){    unsigned char data;        sflash_chipselect();    sflash_sendcommand(SST25_CMD_RDSR);                     // send command    data = sflash_readb();    sflash_chipdeselect();    return data;}void sflash_sst_writeenable(void){    sflash_chipselect();    sflash_sendcommand(SST25_CMD_WREN);    sflash_chipdeselect();}void sflash_sst_writedisable(void){    sflash_chipselect();    sflash_sendcommand(SST25_CMD_WRDI);    sflash_chipdeselect();}void sflash_sst_setprotection(int enable){    int status = sflash_sst_readstatus();    // send Enable Write Status Register command    sflash_chipselect();    sflash_sendcommand(SST25_CMD_EWSR);    sflash_chipdeselect();    // set status    //   BP0 = BP1 = enable    //   BPL = 0    status &= ~SST25_STAT_BPL;    if (enable)         status |= (SST25_STAT_BP0 | SST25_STAT_BP1);    else        status &= ~(SST25_STAT_BP0 | SST25_STAT_BP1);        // send Write Status Register command    sflash_chipselect();    sflash_sendcommand(SST25_CMD_WRSR);    sflash_writeb(status);    sflash_chipdeselect();}void sflash_sst_chiperase(sflash_db_t *pdb){    int status;            sflash_sst_setprotection(0);    sflash_sst_writeenable();    sflash_chipselect();    sflash_sendcommand(SST25_CMD_CE);    sflash_chipdeselect();    do {         em86xx_usleep(10);        status = sflash_sst_readstatus();    } while (status & SST25_STAT_WIP);    sflash_sst_writedisable();    sflash_sst_setprotection(1);}void sflash_sst_sectorerase(sflash_db_t *pdb, unsigned int addr){    int status;    sflash_sst_setprotection(0);    sflash_sst_writeenable();    sflash_chipselect();    sflash_writel((SST25_CMD_SE << 24) | addr);    sflash_chipdeselect();    do {         em86xx_usleep(10);        status = sflash_sst_readstatus();    } while (status & SST25_STAT_WIP);    sflash_sst_writedisable();    sflash_sst_setprotection(1);}#define PROGRAMDELAY    do { int x; for (x = 0; x < 10; ++x); ++x; } while (0)void sflash_sst_pageprogram(sflash_db_t *pdb, unsigned int addr, unsigned char *data, int len){    int i;    int status;        sflash_sst_setprotection(0);    while (len > 0) {        sflash_sst_writeenable();        sflash_chipselect();        sflash_writel((SST25_CMD_AAIP << 24) | addr);        for (i = 0; i < len && i < SST25_PAGESIZE; ++i) {            if (i != 0) {                sflash_chipselect();                sflash_sendcommand(SST25_CMD_AAIP);            }            sflash_writeb(data[i]);            sflash_chipdeselect();            PROGRAMDELAY;                    do {                 status = sflash_sst_readstatus();            } while (status & SST25_STAT_WIP);            PROGRAMDELAY;        }        addr += SST25_PAGESIZE;        len -= SST25_PAGESIZE;        data += SST25_PAGESIZE;                do {             em86xx_usleep(1);            status = sflash_sst_readstatus();        } while (status & SST25_STAT_WIP);            sflash_sst_writedisable();    }    sflash_sst_setprotection(1);}void sflash_sst_read(sflash_db_t *pdb, unsigned int addr, unsigned char *to, int len){    int i;    sflash_chipselect();    sflash_writel((SST25_CMD_READ << 24) | addr);    for (i = 0; i < len; ++i)        to[i] = sflash_readb();    sflash_chipdeselect();}

⌨️ 快捷键说明

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