flash_28fxxx.inl

来自「eCos操作系统源码」· INL 代码 · 共 767 行 · 第 1/2 页

INL
767
字号
#ifndef CYGONCE_DEVS_FLASH_INTEL_28FXXX_INL#define CYGONCE_DEVS_FLASH_INTEL_28FXXX_INL//==========================================================================////      flash_28fxxx.inl////      Intel 28Fxxx series flash driver////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.// Copyright (C) 2002 Gary Thomas//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):    jskov// Contributors: jskov// Date:         2001-03-21// Purpose:      // Description:  //              // Notes:        Device table could use unions of flags to save some space////####DESCRIPTIONEND####////==========================================================================#include <pkgconf/hal.h>#include <pkgconf/io_flash.h>#include <pkgconf/devs_flash_intel_28fxxx.h>#include <cyg/hal/hal_arch.h>#include <cyg/hal/hal_cache.h>#include CYGHWR_MEMORY_LAYOUT_H#include <cyg/hal/hal_io.h>#define  _FLASH_PRIVATE_#include <cyg/io/flash.h>#define nDEBUG#ifdef DEBUGtypedef void (*call_t)(char* str, ...);extern void diag_printf(char* str, ...);call_t d_print = &diag_printf;#endif//----------------------------------------------------------------------------// Common device details.#define FLASH_Read_ID                   FLASHWORD( 0x90 )#define FLASH_Reset                     FLASHWORD( 0xFF )#define FLASH_Program                   FLASHWORD( 0x40 )#define FLASH_Write_Buffer              FLASHWORD( 0xe8 )#define FLASH_Block_Erase               FLASHWORD( 0x20 )#define FLASH_Confirm                   FLASHWORD( 0xD0 )#define FLASH_Resume                    FLASHWORD( 0xD0 )#define FLASH_Set_Lock                  FLASHWORD( 0x60 )#define FLASH_Set_Lock_Confirm          FLASHWORD( 0x01 )#define FLASH_Clear_Lock                FLASHWORD( 0x60 )#define FLASH_Clear_Lock_Confirm        FLASHWORD( 0xd0 )#define FLASH_Read_Status               FLASHWORD( 0x70 )#define FLASH_Clear_Status              FLASHWORD( 0x50 )#define FLASH_Status_Ready              FLASHWORD( 0x80 )// Status that we read back:                         #define FLASH_ErrorMask                 FLASHWORD( 0x7E )#define FLASH_ErrorProgram              FLASHWORD( 0x10 )#define FLASH_ErrorErase                FLASHWORD( 0x20 )#define FLASH_ErrorLock                 FLASHWORD( 0x30 )#define FLASH_ErrorLowVoltage           FLASHWORD( 0x08 )#define FLASH_ErrorLocked               FLASHWORD( 0x02 )// Platform code must define the below// #define CYGNUM_FLASH_INTERLEAVE      : Number of interleaved devices (in parallel)// #define CYGNUM_FLASH_SERIES          : Number of devices in series// #define CYGNUM_FLASH_WIDTH           : Width of devices on platform// #define CYGNUM_FLASH_BASE            : Address of first device#define CYGNUM_FLASH_BLANK              (1)#define CYGNUM_FLASH_DEVICES            (CYGNUM_FLASH_INTERLEAVE*CYGNUM_FLASH_SERIES)#ifndef FLASH_P2V# define FLASH_P2V( _a_ ) ((volatile flash_data_t *)((CYG_ADDRWORD)(_a_)))#endif#ifndef CYGHWR_FLASH_28FXXX_PLF_INIT# define CYGHWR_FLASH_28FXXX_PLF_INIT()#endif#ifndef CYGHWR_FLASH_WRITE_ENABLE#define CYGHWR_FLASH_WRITE_ENABLE()#endif#ifndef CYGHWR_FLASH_WRITE_DISABLE#define CYGHWR_FLASH_WRITE_DISABLE()#endif//----------------------------------------------------------------------------// Now that device properties are defined, include magic for defining// accessor type and constants.#include <cyg/io/flash_dev.h>//----------------------------------------------------------------------------// Information about supported devicestypedef struct flash_dev_info {    flash_data_t device_id;    cyg_uint32   block_size;    cyg_int32    block_count;    cyg_uint32   base_mask;    cyg_uint32   device_size;    cyg_bool     locking;               // supports locking    cyg_bool     buffered_w;            // supports buffered writes    cyg_bool     bootblock;    cyg_uint32   bootblocks[12];         // 0 is bootblock offset, 1-11 sub-sector sizes (or 0)    cyg_bool     banked;    cyg_uint32   banks[2];               // bank offets, highest to lowest (lowest should be 0)                                         // (only one entry for now, increase to support devices                                         // with more banks).} flash_dev_info_t;static const flash_dev_info_t* flash_dev_info;static const flash_dev_info_t supported_devices[] = {#include <cyg/io/flash_28fxxx_parts.inl>};#define NUM_DEVICES (sizeof(supported_devices)/sizeof(flash_dev_info_t))//----------------------------------------------------------------------------// Functions that put the flash device into non-read mode must reside// in RAM.void flash_query(void* data) __attribute__ ((section (".2ram.flash_query")));int  flash_erase_block(void* block, unsigned int size)     __attribute__ ((section (".2ram.flash_erase_block")));int  flash_program_buf(void* addr, void* data, int len,                       unsigned long block_mask, int buffer_size)    __attribute__ ((section (".2ram.flash_program_buf")));int  flash_lock_block(void* addr)    __attribute__ ((section (".2ram.flash_lock_block")));int flash_unlock_block(void* block, int block_size, int blocks)    __attribute__ ((section (".2ram.flash_unlock_block")));//----------------------------------------------------------------------------// Initialize driver detailsintflash_hwr_init(void){    int i;    flash_data_t id[2];    CYGHWR_FLASH_28FXXX_PLF_INIT();    flash_dev_query(id);    // Look through table for device data    flash_dev_info = supported_devices;    for (i = 0; i < NUM_DEVICES; i++) {        if (flash_dev_info->device_id == id[1])            break;        flash_dev_info++;    }    // Did we find the device? If not, return error.    if (NUM_DEVICES == i)        return FLASH_ERR_DRV_WRONG_PART;    // Hard wired for now    flash_info.block_size = flash_dev_info->block_size;    flash_info.blocks = flash_dev_info->block_count * CYGNUM_FLASH_SERIES;    flash_info.start = (void *)CYGNUM_FLASH_BASE;    flash_info.end = (void *)(CYGNUM_FLASH_BASE+ (flash_dev_info->device_size * CYGNUM_FLASH_SERIES));    return FLASH_ERR_OK;}//----------------------------------------------------------------------------// Map a hardware status to a package errorintflash_hwr_map_error(int e){    return e;}//----------------------------------------------------------------------------// See if a range of FLASH addresses overlaps currently running codeboolflash_code_overlaps(void *start, void *end){    extern unsigned char _stext[], _etext[];    return ((((unsigned long)&_stext >= (unsigned long)start) &&             ((unsigned long)&_stext < (unsigned long)end)) ||            (((unsigned long)&_etext >= (unsigned long)start) &&             ((unsigned long)&_etext < (unsigned long)end)));}//----------------------------------------------------------------------------// Flash Query//// Only reads the manufacturer and part number codes for the first// device(s) in series. It is assumed that any devices in series// will be of the same type.voidflash_query(void* data){    volatile flash_data_t *ROM;    flash_data_t* id = (flash_data_t*) data;    flash_data_t w;    ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;    w = ROM[0];    CYGHWR_FLASH_WRITE_ENABLE();        ROM[0] = FLASH_Read_ID;    // Manufacturers' code    id[0] = ROM[0];    // Part number    id[1] = ROM[1];    ROM[0] = FLASH_Reset;    CYGHWR_FLASH_WRITE_DISABLE();        // Stall, waiting for flash to return to read mode.    while (w != ROM[0]);}//----------------------------------------------------------------------------// Erase Blockintflash_erase_block(void* block, unsigned int block_size){    int res = FLASH_ERR_OK;    int timeout;    unsigned long len;    int len_ix = 1;    flash_data_t stat;    volatile flash_data_t *ROM;    volatile flash_data_t *b_p = (flash_data_t*) block;    volatile flash_data_t *b_v;    cyg_bool bootblock;    ROM = FLASH_P2V((unsigned long)block & flash_dev_info->base_mask);    // Is this the boot sector?    bootblock = (flash_dev_info->bootblock &&                 (flash_dev_info->bootblocks[0] == ((unsigned long)block - (unsigned long)ROM)));    if (bootblock) {        len = flash_dev_info->bootblocks[len_ix++];    } else {        len = flash_dev_info->block_size;    }    CYGHWR_FLASH_WRITE_ENABLE();        while (len > 0) {        b_v = FLASH_P2V(b_p);        // Clear any error conditions        ROM[0] = FLASH_Clear_Status;        // Erase block        ROM[0] = FLASH_Block_Erase;        *b_v = FLASH_Confirm;        timeout = 5000000;        while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {            if (--timeout == 0) break;        }            // Restore ROM to "normal" mode        ROM[0] = FLASH_Reset;        if (stat & FLASH_ErrorMask) {            if (!(stat & FLASH_ErrorErase)) {                res = FLASH_ERR_HWR;    // Unknown error             } else {                if (stat & FLASH_ErrorLowVoltage)                    res = FLASH_ERR_LOW_VOLTAGE;                else if (stat & FLASH_ErrorLocked)                    res = FLASH_ERR_PROTECT;                else                    res = FLASH_ERR_ERASE;            }        }        // Check if block got erased        while (len > 0) {            b_v = FLASH_P2V(b_p++);            if (*b_v != FLASH_BlankValue ) {                // Only update return value if erase operation was OK                if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;                return res;            }            len -= sizeof(*b_p);        }        if (bootblock)            len = flash_dev_info->bootblocks[len_ix++];    }    CYGHWR_FLASH_WRITE_DISABLE();        return res;}//----------------------------------------------------------------------------// Program Bufferintflash_program_buf(void* addr, void* data, int len,                  unsigned long block_mask, int buffer_size){    flash_data_t stat = 0;    int timeout;    volatile flash_data_t* ROM;    volatile flash_data_t* BA;    volatile flash_data_t* addr_v;    volatile flash_data_t* addr_p = (flash_data_t*) addr;    volatile flash_data_t* data_p = (flash_data_t*) data;    int res = FLASH_ERR_OK;    // Base address of device(s) being programmed.     ROM = FLASH_P2V((unsigned long)addr & flash_dev_info->base_mask);    BA = FLASH_P2V((unsigned long)addr & ~(flash_dev_info->block_size - 1));    CYGHWR_FLASH_WRITE_ENABLE();        // Clear any error conditions    ROM[0] = FLASH_Clear_Status;#ifdef CYGHWR_DEVS_FLASH_INTEL_BUFFERED_WRITES    // FIXME: This code has not been adjusted to handle bootblock    // parts yet.    // FIXME: This code does not appear to work anymore    if (0 && flash_dev_info->buffered_w) {        int i, wc;        // Write any big chunks first        while (len >= buffer_size) {            wc = buffer_size;            if (wc > len) wc = len;            len -= wc;            wc = wc / ((CYGNUM_FLASH_WIDTH/8)*CYGNUM_FLASH_INTERLEAVE);  // Word count            timeout = 5000000;                        *BA = FLASH_Write_Buffer;            while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {                if (--timeout == 0) {                    res = FLASH_ERR_DRV_TIMEOUT;

⌨️ 快捷键说明

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