📄 intel32.c
字号:
/* * intel32.c: Intel 32 bit (2x 16 bit) flash driver * * Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) * Copyright (C) 1999 Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */#ident "$Id: intel32.c,v 1.4 2002/01/03 16:07:18 erikm Exp $"#ifdef HAVE_CONFIG_H# include <blob/config.h>#endif#include <blob/errno.h>#include <blob/flash.h>#include <blob/util.h>#include <blob/serial.h>/* flash commands for two 16 bit intel flash chips */#define READ_ARRAY 0x00FF00FF#define ERASE_SETUP 0x00200020#define ERASE_CONFIRM 0x00D000D0#define PGM_SETUP 0x00400040#define STATUS_READ 0x00700070#define STATUS_CLEAR 0x00500050#define STATUS_BUSY 0x00800080#define STATUS_ERASE_ERR 0x00200020#define STATUS_PGM_ERR 0x00100010#define CONFIG_SETUP 0x00600060#define LOCK_SECTOR 0x00010001#define UNLOCK_SECTOR 0x00D000D0#define READ_CONFIG 0x00900090#define LOCK_STATUS_LOCKED 0x00010001#define LOCK_STATUS_LOCKEDDOWN 0x00020002/* erases a flash block at the given address */static int flash_erase_intel32(u32 *addr){ u32 result; *addr = data_to_flash(STATUS_CLEAR); barrier(); /* prepare for erase */ *addr = data_to_flash(ERASE_SETUP); barrier(); /* erase block */ *addr = data_to_flash(ERASE_CONFIRM); barrier(); /* status check */ do { *addr = data_to_flash(STATUS_READ); barrier(); result = data_from_flash(*addr); barrier(); } while((~result & STATUS_BUSY) != 0); /* put flash back into Read Array mode */ *addr = data_to_flash(READ_ARRAY); barrier(); if((result & STATUS_ERASE_ERR) != 0) {#ifdef BLOB_DEBUG SerialOutputString(__FUNCTION__ " failed, result=0x"); SerialOutputHex(result); SerialOutputString(", addr=0x"); SerialOutputHex((u32) addr); serial_write('\n');#endif return -EFLASHERASE; } return 0;}/* write a flash block at a given location */static int flash_write_intel32(u32 *dst, const u32* src){ u32 result; *dst = data_to_flash(STATUS_CLEAR); barrier(); /* setup flash for writing */ *dst = data_to_flash(PGM_SETUP); barrier(); /* write data */ *dst = *src; barrier(); /* status check */ do { *dst = data_to_flash(STATUS_READ); barrier(); result = data_from_flash(*dst); barrier(); } while((~result & STATUS_BUSY) != 0); /* put flash back into Read Array mode */ *dst = data_to_flash(READ_ARRAY); barrier(); if(((result & STATUS_PGM_ERR) != 0) || (*dst != *src)) {#ifdef BLOB_DEBUG SerialOutputString(__FUNCTION__ "failed, result=0x"); SerialOutputHex(result); SerialOutputString(", addr=0x"); SerialOutputHex((u32) dst); serial_write('\n');#endif return -EFLASHPGM; } return 0;}static int flash_lock_block_intel32(u32 *blockStart){ u32 result; *blockStart = data_to_flash(STATUS_CLEAR); barrier(); *blockStart = data_to_flash(CONFIG_SETUP); barrier(); *blockStart = data_to_flash(LOCK_SECTOR); barrier(); *blockStart = data_to_flash(READ_ARRAY); barrier(); /* status check */ *blockStart = data_to_flash(STATUS_READ); barrier(); result = data_from_flash(*blockStart); barrier(); *blockStart = data_to_flash(READ_ARRAY); barrier(); if ((result & STATUS_PGM_ERR) != 0) {#ifdef FLASH_DEBUG SerialOutputString(__FUNCTION__ " failed at 0x"); SerialOutputHex((u32) blockStart); SerialOutputString(", status=0x"); SerialOutputHex((u32) result); SerialOutputByte('\n');#endif return -EFLASHPGM; } return 0;}static int flash_unlock_block_intel32(u32 *blockStart){ u32 result; *blockStart = data_to_flash(STATUS_CLEAR); barrier(); *blockStart = data_to_flash(CONFIG_SETUP); barrier(); *blockStart = data_to_flash(UNLOCK_SECTOR); barrier(); *blockStart = data_to_flash(STATUS_READ); barrier(); result = data_from_flash(*blockStart); barrier(); *blockStart = data_to_flash(READ_ARRAY); barrier(); if ((result & STATUS_PGM_ERR) != 0) {#ifdef FLASH_DEBUG SerialOutputString(__FUNCTION__ " failed at 0x"); SerialOutputHex((u32) blockStart); SerialOutputString(", status=0x"); SerialOutputHex((u32) result); SerialOutputByte('\n');#endif return -EFLASHPGM; } return 0;}static int flash_query_block_lock_intel32(u32 *blockStart){ u32 result; *blockStart = data_to_flash(READ_CONFIG); barrier(); result = data_from_flash(*(blockStart + 2)); barrier(); *blockStart = data_to_flash(READ_ARRAY); barrier();#ifdef FLASH_DEBUG SerialOutputString(__FUNCTION__ ": status of block starting at 0x"); SerialOutputHex((u32) blockStart); SerialOutputString(": 0x"); SerialOutputHex((u32) result); SerialOutputByte('\n');#endif return result & (LOCK_STATUS_LOCKED | LOCK_STATUS_LOCKEDDOWN);}/* flash driver structure */flash_driver_t intel32_flash_driver = { erase: flash_erase_intel32, write: flash_write_intel32, lock_block: flash_lock_block_intel32, unlock_block: flash_unlock_block_intel32, query_block_lock: flash_query_block_lock_intel32};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -