📄 strata_flash.c
字号:
/* * File: strata_flash.c * Purpose: Flash driver for programming Intel Strata Flash devices * * Notes: This driver supports a single banks of Intel Flash. * A bank is defined as one or more of the same Flash * device connected to a single chip-select. */#include "common.h"/* * Compiler specific code relocation section */#ifdef __DCC__#pragma section CODE ".code_relocation"#pragma section CONST ".code_relocation"#elif (defined(__ghs__))#pragma ghs section text=".code_relocation"#endif#include "strata_flash.h"/********************************************************************//* * Global pointer to base of Intel Flash device */#ifdef __MWERKS____relocate_data__#endifstatic STRATA_FLASH_CELL *pFlash;/********************************************************************/#ifdef __MWERKS____relocate_code__#endifSTRATA_FLASH_CELLstrata_flash_read_device_info(int offset){ /* Read Device Identifier command */ pFlash[0] = STRATA_FLASH_CMD_DATA(0x90); { int i; for (i = 0; i < 3; i++) { printf(" %02x ",pFlash[i]); } } return pFlash[offset];}/********************************************************************/#ifdef __MWERKS____relocate_code__#endifvoidstrata_flash_sector_unlock(int n){ STRATA_FLASH_CELL status; /* Unlock Block command */ pFlash[SF_SADDR(n)] = STRATA_FLASH_CMD_DATA(0x60); pFlash[SF_SADDR(n)] = STRATA_FLASH_CMD_DATA(0xD0); /* Wait for the unlock operation to finish */ do { status = pFlash[SF_SADDR(n)]; } while (!(status & STRATA_FLASH_CMD_DATA(0x80))); /* Place back in normal read mode */ pFlash[0] = STRATA_FLASH_CMD_DATA(0xFF);}/********************************************************************/#ifdef __MWERKS____relocate_code__#endifvoidstrata_flash_sector_lock(int n){ STRATA_FLASH_CELL status; /* Lock Block command */ pFlash[SF_SADDR(n)] = STRATA_FLASH_CMD_DATA(0x60); pFlash[SF_SADDR(n)] = STRATA_FLASH_CMD_DATA(0x01); /* Wait for the lock operation to finish */ do { status = pFlash[SF_SADDR(n)]; } while (!(status & STRATA_FLASH_CMD_DATA(0x80))); /* Place back in normal read mode */ pFlash[0] = STRATA_FLASH_CMD_DATA(0xFF);}/********************************************************************/#ifdef __MWERKS____relocate_code__#endifintstrata_flash_sector_erase(int n){ STRATA_FLASH_CELL status; /* Unlock Block command */ pFlash[SF_SADDR(n)] = STRATA_FLASH_CMD_DATA(0x60); pFlash[SF_SADDR(n)] = STRATA_FLASH_CMD_DATA(0xD0); /* Wait for the unlock operation to finish */ do { status = pFlash[SF_SADDR(n)]; } while (!(status & STRATA_FLASH_CMD_DATA(0x80))); /* Place back in normal read mode */ pFlash[0] = STRATA_FLASH_CMD_DATA(0xFF); /* Sector erase */ pFlash[SF_SADDR(n)] = STRATA_FLASH_CMD_DATA(0x20); pFlash[SF_SADDR(n)] = STRATA_FLASH_CMD_DATA(0xD0); /* Wait for the erase operation to finish */ do { status = pFlash[SF_SADDR(n)]; } while (!(status & STRATA_FLASH_CMD_DATA(0x80))); /* Place back in normal read mode */ pFlash[0] = STRATA_FLASH_CMD_DATA(0xFF); return (status != 0x80);}/********************************************************************/#ifdef __MWERKS____relocate_code__#endifintstrata_flash_erase(ADDRESS start, int bytes, void (*putchar)(char)){ int i, ebytes = 0; if (bytes == 0) return 0; i = strata_flash_sector_number(start); bytes += ((int)start - (int)((ADDRESS)pFlash + SF_SOFFSET(i))); while (ebytes < bytes) { if (putchar != NULL) putchar('.'); strata_flash_sector_erase(i); ebytes += SF_SSIZE(i); i++; } if (putchar != NULL) { putchar(10); /* LF */ putchar(13); /* CR */ } return ebytes;}/********************************************************************/#ifdef __MWERKS____relocate_code__#endifintstrata_flash_program_cell(STRATA_FLASH_CELL *dst, STRATA_FLASH_CELL data){ STRATA_FLASH_CELL status; *dst = STRATA_FLASH_CMD_DATA(0x40); *dst = data; /* Wait for program operation to finish */ do { status = *dst; } while (!(status & STRATA_FLASH_CMD_DATA(0x80))); /* Place back in normal read mode */ pFlash[0] = STRATA_FLASH_CMD_DATA(0xFF); return (status != 0x80);}/********************************************************************/#ifdef __MWERKS____relocate_code__#endifintstrata_flash_program(ADDRESS dest, ADDRESS source, int bytes, int erase, void (*func)(void), void (*putchar)(char)){ STRATA_FLASH_CELL *src, *dst; int hashi=1,hashj=0; char hash[5]; hash[0]=8; /* Backspace */ hash[1]=124;/* "|" */ hash[2]=47; /* "/" */ hash[3]=45; /* "-" */ hash[4]=92; /* "\" */ src = (STRATA_FLASH_CELL *)source; dst = (STRATA_FLASH_CELL *)dest; /* Erase device if necessary */ if (erase) strata_flash_erase(dest, bytes, putchar); /* Program device */ while (bytes > 0) { strata_flash_program_cell(dst,*src); /* Verify Write */ if (*dst == *src) { bytes -= STRATA_FLASH_CELL_BYTES; *dst++, *src++; if ((putchar != NULL)) { /* Hash marks to indicate progress */ if (hashj == 0x1000) { hashj = -1; putchar(hash[0]); putchar(hash[hashi]); hashi++; if (hashi == 5) hashi=1; } hashj++; } } else break; } if (putchar != NULL) putchar(hash[0]); /* If a function was passed in, call it now */ if ((func != NULL)) func(); return ((int)src - (int)source);}/********************************************************************/#ifdef __MWERKS____relocate_code__#endifintstrata_flash_sector_number(ADDRESS addr){ int i; /* Returns the number of the sector containing addr */ for (i = 0; i < STRATA_FLASH_SECTORS; i++) { if (addr >= (ADDRESS)((ADDRESS)pFlash + SF_SOFFSET(i)) && addr <= (ADDRESS)((ADDRESS)pFlash + SF_SOFFSET(i) + (SF_SSIZE(i) - 1))) { break; } } ASSERT(i != STRATA_FLASH_SECTORS); return i;}/********************************************************************/#ifdef __MWERKS____relocate_code__#endifADDRESSstrata_flash_sector_start(ADDRESS addr){ /* Returns beginning of sector containing addr */ int i; for (i = 0; i < STRATA_FLASH_SECTORS; i++) { if (addr >= (ADDRESS)((ADDRESS)pFlash + SF_SOFFSET(i)) && addr <= (ADDRESS)((ADDRESS)pFlash + SF_SOFFSET(i) + (SF_SSIZE(i) - 1))) { return (ADDRESS)((ADDRESS)pFlash + SF_SOFFSET(i)); } } return NULL;}/********************************************************************/#ifdef __MWERKS____relocate_code__#endifADDRESSstrata_flash_sector_end(ADDRESS addr){ /* Returns end of sector containing ADDRESS */ int i; for (i = 0; i < STRATA_FLASH_SECTORS; i++) { if (addr >= (ADDRESS)((ADDRESS)pFlash + SF_SOFFSET(i)) && addr <= (ADDRESS)((ADDRESS)pFlash + SF_SOFFSET(i) + (SF_SSIZE(i) - 1))) { return (ADDRESS)((ADDRESS)pFlash + SF_SOFFSET(i) + (SF_SSIZE(i) - 1)); } } return NULL;}/********************************************************************/#ifdef __MWERKS____relocate_code__#endifvoidstrata_flash_init(ADDRESS base){ pFlash = (STRATA_FLASH_CELL *)base;}/********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -