* [ECOS] Flash Programming Example with ecos
@ 2001-09-25 12:27 Jeffrey Jopling
2001-09-25 23:58 ` Jesper Skov
0 siblings, 1 reply; 3+ messages in thread
From: Jeffrey Jopling @ 2001-09-25 12:27 UTC (permalink / raw)
To: ecos-discuss
Does anyone have a simple app or a code snip that I can look at as a sample
of how to write an ecos application that can write and read data from flash?
Any assistance is appreciated.
Cheers,
Jeff Jopling
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [ECOS] Flash Programming Example with ecos
2001-09-25 12:27 [ECOS] Flash Programming Example with ecos Jeffrey Jopling
@ 2001-09-25 23:58 ` Jesper Skov
0 siblings, 0 replies; 3+ messages in thread
From: Jesper Skov @ 2001-09-25 23:58 UTC (permalink / raw)
To: Jeffrey Jopling; +Cc: ecos-discuss
>>>>> "Jeffrey" == Jeffrey Jopling <jeff.jopling@indlogic.com> writes:
Jeffrey> Does anyone have a simple app or a code snip that I can look
Jeffrey> at as a sample of how to write an ecos application that can
Jeffrey> write and read data from flash?
Look at RedBoot. The flash.c file in particular.
Jesper
^ permalink raw reply [flat|nested] 3+ messages in thread
* RE: [ECOS] Flash Programming Example with ecos
@ 2001-09-26 1:16 Simpkins, Andy
0 siblings, 0 replies; 3+ messages in thread
From: Simpkins, Andy @ 2001-09-26 1:16 UTC (permalink / raw)
To: Jeffrey Jopling, ecos-discuss
[-- Attachment #1: Type: text/plain, Size: 465 bytes --]
see attached
> -----Original Message-----
> From: Jeffrey Jopling [ mailto:jeff.jopling@indlogic.com ]
> Sent: 25 September 2001 20:34
> To: ecos-discuss@sources.redhat.com
> Subject: [ECOS] Flash Programming Example with ecos
>
>
> Does anyone have a simple app or a code snip that I can look
> at as a sample
> of how to write an ecos application that can write and read
> data from flash?
>
> Any assistance is appreciated.
>
> Cheers,
> Jeff Jopling
>
[-- Attachment #2: fileSystem.h --]
[-- Type: text/x-c++, Size: 401 bytes --]
// fileSystem.h
#ifndef __FILESYSTEM_H__
#define __FILESYSTEM_H__
class fileSystem
{
public:
virtual bool format(void) = 0;
virtual bool create(int length, char *data, char *name) = 0;
virtual bool readAll(char *name, int *length, char *data) = 0;
virtual bool erase(char *name) = 0;
bool valid; // validity of this file system
};
#endif // __FILESYSTEM_H__
[-- Attachment #3: flash.h --]
[-- Type: text/x-c++, Size: 5396 bytes --]
/*-----------------------------------------------------------------------------
*
* (c) Tardis Mobile - 2000
*
* Name: flash.h
*
* Author: A Simpkins
*
* Date: 04 October
*
*-----------------------------------------------------------------------------
*
* Description:
*
* Header file to be used with flashTest.C & eventualy a flash libuary
* which flashTest.c will be a part.
*
* Modification history:
*
* --- 14/08/2001 002 - converted to eCos
* 04/10/2000 001 - Initial draft
*
*
*-----------------------------------------------------------------------------
*/
#ifndef __FLASH_H__
#define __FLASH_H__
// Address of code loaded into RAM (.2ram.flash_query)
#define FLASHCodeInRAM (0x4100caac)
/* Structures */
/* ~~~~~~~~~~ */
/* Structure array length */
#define flashEscape_maxLength (0x06)
struct flashPairStruct
{
cyg_uint32 pairAddress;
cyg_uint16 pairData;
};
struct flashEscape
{
cyg_uint16 length;
struct flashPairStruct flashpair[flashEscape_maxLength];
};
/* Definitions */
/* ~~~~~~~~~~~ */
/* Memory is 16 bit wide (2 bytes). */
#define memoryWidth (0x002)
#define startAddressFLASH (0x40000000)
#define LengthFLASH (0x00100000)
/* flash Commands */
#define flash_eraseSectorCmd (0x0030)
#define flash_reset (0x00f0)
#define flash_erraseCmd (0x0010)
#define flash_blank (0x00ff)
#if CYGHWR_HAL_ARM_TARDIS3_VERSION == 1
#define flash_make (startAddressFLASH + 0x00000000)
#define flash_deviceID (startAddressFLASH + 0x00000004)
#define flash_erraseAllAddr (startAddressFLASH + 0x00001554)
/* List of the sectors to erase with the above command */
#define flash_SA00 (0x00000000)
#define flash_SA01 (0x00002000)
#define flash_SA02 (0x00003000)
#define flash_SA03 (0x00004000)
#define flash_SA04 (0x00008000)
#define flash_SA05 (0x00010000)
#define flash_SA06 (0x00018000)
#define flash_SA07 (0x00020000)
#define flash_SA08 (0x00028000)
#define flash_SA09 (0x00030000)
#define flash_SA10 (0x00038000)
#define flash_SA11 (0x00040000)
#define flash_SA12 (0x00048000)
#define flash_SA13 (0x00050000)
#define flash_SA14 (0x00058000)
#define flash_SA15 (0x00060000)
#define flash_SA16 (0x00068000)
#define flash_SA17 (0x00070000)
#define flash_SA18 (0x00078000)
#else
#define flash_make (startAddressFLASH + 0x00000000)
#define flash_deviceID (startAddressFLASH + 0x00000002)
#define flash_erraseAllAddr (startAddressFLASH + 0x00000555)
/* List of the sectors to erase with the above command */
#define flash_SA00 (0x00000000)
#define flash_SA01 (0x00004000)
#define flash_SA02 (0x00006000)
#define flash_SA03 (0x00008000)
#define flash_SA04 (0x00010000)
#define flash_SA05 (0x00020000)
#define flash_SA06 (0x00030000)
#define flash_SA07 (0x00040000)
#define flash_SA08 (0x00050000)
#define flash_SA09 (0x00060000)
#define flash_SA10 (0x00070000)
#define flash_SA11 (0x00080000)
#define flash_SA12 (0x00090000)
#define flash_SA13 (0x000a0000)
#define flash_SA14 (0x000b0000)
#define flash_SA15 (0x000c0000)
#define flash_SA16 (0x000d0000)
#define flash_SA17 (0x000e0000)
#define flash_SA18 (0x000f0000)
#endif
/* Flash Error Bits */
#define flash_DQ0 (0x0001)
#define flash_DQ1 (0x0002)
#define flash_DQ2 (0x0004)
#define flash_DQ3 (0x0008)
#define flash_DQ4 (0x0010)
#define flash_DQ5 (0x0020)
#define flash_DQ6 (0x0040)
#define flash_DQ7 (0x0080)
/* Function Commands and assocated data structures */
#define flashCmd_Info (0x0001)
#define flashCmd_Erase (0x0002)
#define flashCmd_ResumeErase (0x0003)
#define flashCmd_Write (0x0004)
#define flashResult_OK (0x1001)
#define flashResult_badAddress (0x1002)
class flashcmd
{
public:
int flashCommand;
};
class infoFlashCmd : public flashcmd
{
public:
int make;
int deviceID;
};
class eraseFlashCmd : public flashcmd
{
public:
cyg_uint32 sectorNo;
bool success;
bool onHold;
};
class writeFlashCmd : public flashcmd
{
public:
cyg_uint32 writeAddress;
cyg_uint16 writeData;
int result;
};
// Bitmap of possible SiRF Interrupts
//#define SiRFIRQ (0xa260)
#define SiRFIRQ (0x0000)
// types of FLASH device
// ~~~~~~~~~~~~~~~~~~~~~
// MAKE
#define FLASHunknown (0x0000)
#define AMD (0x0001)
// Device ID
#define AMD29LV800BB (0x225b)
#define AMD29LV800BT (0x22da)
// function type to call to code in RAM
typedef cyg_uint32 (*RAMfn_type)(cyg_uint32 *);
#endif /* __FLASH_H__ */
[-- Attachment #4: FLASHFileSystem.cpp --]
[-- Type: text/x-c, Size: 31302 bytes --]
// These functions should reside below the API and be called only for calls to filesystem 'FLASH0'
// This will only work with AMD AM29LV800BB or AM29LV160BB flash devices!
//
// terminology
// superblock - one block of FLASH
// subblock - subdevision of a superblock, smallest space that the filesystem can allocate
// block - not used to avoid confusion :-)
#include "eCosIvory/FLASHFileSystem.h" // this file system
#include "eCosIvory/flash.h" // flash lib
#include <stdlib.h> // malloc
#include <stdio.h> /* sprintf */
#include <cyg/hal/t3.h> /* LED Control */
#include <cyg/infra/diag.h> /* diag_printf */
#include "eCosIvory/console.h" // display
#include "eCosIvory/system.h" // file system pointer
// Constructor
FLASHfileSystem::FLASHfileSystem()
{
// declare block information
// to be populated by hand!
subBlockSize = SUBBLOCKSIZE; // MUST NOT EXCEED superBlocksize / noSubBlocksPerSuperBlock
noSubBlocksPerSuperBlock = SUBBLOCKSPERSUPERBLOCK;
CYG_ADDRESS sbt[NUMSUPERBLOCKS] = SUPERBLOCKS;
memcpy(superBlockTable, sbt, sizeof(sbt));
// build FAT structure in RAM
noSuperBlocks = NUMSUPERBLOCKS;
noSubBlocks = NUMSUBBLOCKS;
// Attempt to read device information
infoFlashCmd flashData;
flashData.flashCommand = flashCmd_Info;
((RAMfn_type)(FLASHCodeInRAM))((cyg_uint32 *)&flashData);
// valid devices devices...
if (flashData.make == AMD && flashData.deviceID == AMD29LV800BB)
{
valid = true;
} else {
valid = false;
}
next = NULL; // invalid file pointer (no open files)
//## insert code to restore FAT contents from FLASH
//## insert code to create mutex for file system
}
// destructor
FLASHfileSystem::~FLASHfileSystem()
{
//## insert code to back RAM tables to FLASH
//## insert code to destry mutex
}
// erase block;
bool FLASHfileSystem::eraseBlock(CYG_ADDRESS superblock)
{
eraseFlashCmd flashErase;
flashErase.flashCommand = flashCmd_Erase;
flashErase.sectorNo = superblock;
((RAMfn_type)(FLASHCodeInRAM))((cyg_uint32 *)&flashErase);
while (flashErase.onHold)
{
cyg_thread_yield();
flashErase.flashCommand = flashCmd_ResumeErase;
((RAMfn_type)(FLASHCodeInRAM))((cyg_uint32 *)&flashErase);
}
return flashErase.success;
}
// FLASH Format
bool FLASHfileSystem::format(void)
{
// Confirm that this is flash we know about...
if (!valid) return false;
// confirm that there are no files open...
// i.e. we can not format if there are still files open
if(next != NULL)
{
#ifdef dbg_FLASH
diag_printf("format: files are still open - can't format!\r");
#endif
return false;
}
//## lock FLASH mutex
// erase superblocks used in our file system
for (int SB = 0; SB < noSuperBlocks; SB++)
if (!eraseBlock(superBlockTable[SB])) return false;
// Initialise structure
for (cyg_uint32 count = 0; count < noSubBlocks; count++)
{
subBlockTable[count].state = unused;
subBlockTable[count].next = FLASHNull;
subBlockTable[count].prev = FLASHNull;
}
freeCount = noSubBlocks - noSubBlocksPerSuperBlock; // leave 1 superblock as working space
usedCount = 0;
dirtyCount = 0;
subBlockFreePtr = 0;
subBlockUsedPtr = 0;
for (int FR = 0; FR < MAXFILES; FR++)
{
// technicly we need only initialise the name
strcpy(FAT[FR].name,"\0");
FAT[FR].start = FLASHNull;
FAT[FR].length = 0;
}
fileCount = 0;
//## unlock FLASH mutex
return true;
}
// write to FLASH
bool FLASHfileSystem::writeToFlash(cyg_uint16 writeData, cyg_uint32 writeAddress)
{
writeFlashCmd flashWrite;
flashWrite.flashCommand = flashCmd_Write;
flashWrite.writeData = writeData;
flashWrite.writeAddress = writeAddress;
((RAMfn_type)(FLASHCodeInRAM))((cyg_uint32 *)&flashWrite);
return flashWrite.result;
}
// examine the FAT for a matching name
int FLASHfileSystem::lookUp(char *name)
{
for (int count = 0; count < MAXFILES; count++)
if (strcmp(name, FAT[count].name) == 0) return count;
return FLASHFileNotFound;
}
// Calculate the start Address of the SubBlock
cyg_uint32 FLASHfileSystem::getSubBlockAddress(int subBlockNumber)
{
int superBlockNo = subBlockNumber / noSubBlocksPerSuperBlock;
int subBlockOfSuperBlock = subBlockNumber % noSubBlocksPerSuperBlock;
return (subBlockOfSuperBlock * subBlockSize) + superBlockTable[superBlockNo];
}
// FLASH create file
bool FLASHfileSystem::create(int length, char *data, char *name)
{
#ifdef dbg_FLASH
diag_printf("checking for valid file system...");
#endif
// Confirm that this is flash we know about...
if (!valid) return false;
//## lock FLASH mutex
// check if we have space for the file
#ifdef dbg_FLASH
diag_printf("FS VALID\rCheck for space in FAT...");
#endif
if (fileCount == MAXFILES) return false;
#ifdef dbg_FLASH
diag_printf("Enough space\r");
#endif
//Limit size of file name
#ifdef dbg_FLASH
diag_printf("Limit file name size...");
#endif
int nameLen = strlen(name);
if (nameLen > MAXNAMELEN)
{
nameLen = MAXNAMELEN;
}
name[nameLen] = '\0';
#ifdef dbg_FLASH
diag_printf("File name limited to %s\r", name);
#endif
// confirm that the file doesn't already exist
#ifdef dbg_FLASH
diag_printf("checking name is unique...");
#endif
if (int FileNumber = lookUp(name) != FLASHFileNotFound) return false; // name exists
#ifdef dbg_FLASH
diag_printf("DONE\r");
#endif
// grab the number of required subBlocks or return false if insufficiant space
#ifdef dbg_FLASH
diag_printf("Allocating required number of subBlocks...");
#endif
int subBlocksRequired = length / subBlockSize;
if ((length % subBlockSize) > 0) subBlocksRequired += 1;
if (subBlocksRequired > freeCount) return false;
freeCount-= subBlocksRequired;
#ifdef dbg_FLASH
diag_printf("%d subBlocks allocated\r", subBlocksRequired);
#endif
// build a table of the sub block numbers
diag_printf("Building table of subBlocks\r");
int subBlock[subBlocksRequired];
for (int selected = 0; selected < subBlocksRequired; selected++)
{
#ifdef dbg_FLASH
diag_printf("Outer Loop Start (selected = 0x%x\r", selected);
#endif
do
{
subBlock[selected] = subBlockFreePtr;
subBlockFreePtr++;
subBlockFreePtr = subBlockFreePtr % noSubBlocks;
} while (subBlockTable[subBlock[selected]].state != unused);
subBlockTable[subBlock[selected]].state = inuse;
#ifdef dbg_FLASH
diag_printf("Using subBlock 0x%x\r", selected);
#endif
}
// Find an unused entry in the FAT and populate it
int count = 0;
#ifdef dbg_FLASH
diag_printf("Looking for space in FAT...");
#endif
while (strcmp(FAT[count].name,"") != 0) count++;
#ifdef dbg_FLASH
diag_printf("added entry to FAT record 0x%x\r", count);
#endif
strcpy(FAT[count].name,name);
FAT[count].length = length;
FAT[count].start = subBlock[0];
fileCount++;
//## unlock FLASH mutex
// populate the data to flash and update each record
#ifdef dbg_FLASH
diag_printf("writing data to FLASH...");
#endif
cyg_uint32 written = 0; // how much data we have already written
cyg_uint32 writeEnd; // last data element to write in this subBlock
char *pMem = data;
for (count = 0; count < subBlocksRequired; count++)
{
// update subBlockTable
//## lock FLASH mutex
subBlockTable[subBlock[count]].next = (count != subBlocksRequired-1) ? subBlock[count+1] : FLASHNull;
subBlockTable[subBlock[count]].prev = (count != 0) ? subBlock[count-1] : FLASHNull;
//## unlock FLASH mutex
// Calculate the start Address of the SubBlock
cyg_uint32 writeAddress = getSubBlockAddress(subBlock[count]);
#ifdef dbg_FLASH
diag_printf("Writing subblock from address 0x%08x to ", writeAddress);
#endif
// calculate the amount of data to write
cyg_uint32 writeLength = length - written;
if (writeLength > subBlockSize)
{
writeEnd = writeAddress + subBlockSize;
writeLength = subBlockSize;
} else {
writeEnd = writeAddress + writeLength;
}
#ifdef dbg_FLASH
diag_printf("0x%08x \r\n", writeEnd);
#endif
//write to FLASH
while (writeAddress < writeEnd)
{
cyg_uint16 tmp = *pMem++; // 1st byte
cyg_uint16 wdata = (*pMem++ << 8) | tmp; // 2nd byte
// diag_printf("FLASHfileSystem::create Writing 0x%x from 0x%x to 0x%x\r\n", flashWrite.writeData, pMem - 2, flashWrite.writeAddress);
writeToFlash(wdata, writeAddress);
writeAddress += 2;
}
written += writeLength; // amount of date written
diag_printf("written = 0x%08x \r\n", written);
//## lock FLASH mutex
subBlockTable[subBlock[count]].state = used;
usedCount++;
//## unlock FLASH mutex
}
#ifdef dbg_FLASH
diag_printf("DONE\r\r FILE CREATED\r\r");
#endif
return true;
}
// FLASH read file
bool FLASHfileSystem::readAll(char *name, int *length, char *data)
{
// Confirm that this is flash we know about...
if (!valid) return false;
//## lock FLASH mutex
// check that the filename exists
int fileNumber = lookUp(name);
if (fileNumber == FLASHFileNotFound) return false;
// get file attributes
*length = FAT[fileNumber].length;
int subBlock = FAT[fileNumber].start;
// allocate buffer to read data into
if ((data = (char *) malloc(*length)) == NULL)
return false; // unable to allocate space in which to open the file
// read the data from FLASH into RAM
int bytesRead = 0;
char *storeAt = data;
CYG_ADDRESS readAddress = getSubBlockAddress(subBlock);
{
int readLength = (*length - bytesRead <= subBlockSize) ? *length - bytesRead : subBlockSize;
// read from FLASH into the buffer
memcpy(storeAt, (char *)readAddress, readLength);
// update pointers and counters
storeAt += readLength;
bytesRead += readLength;
subBlock = subBlockTable[subBlock].next;
readAddress = getSubBlockAddress(subBlock);
} while (readAddress != FLASHNull);
//## unlock FLASH mutex
}
// recover 'dirty' areas of FLASH
void FLASHfileSystem::reclaimDirtyFLASH(void)
{
while (dirtyCount >= noSubBlocksPerSuperBlock)
{
// find oldest dirtySubBlock
int dirtySubBlock;
do
{
dirtySubBlock = subBlockUsedPtr++;
subBlockUsedPtr = subBlockUsedPtr % noSubBlocks;
} while (subBlockTable[dirtySubBlock].state != dirty);
// calculate the SuperBlock within which this subBlock resides
int superBlockNo = dirtySubBlock / noSubBlocksPerSuperBlock;
int baseSubBlockNo = dirtySubBlock - (dirtySubBlock % noSubBlocksPerSuperBlock);
// re-loacate all used subblocks and update tables
for (int count = baseSubBlockNo; count < (baseSubBlockNo + noSubBlocksPerSuperBlock); count++)
{
switch (subBlockTable[count].state)
{
case used:
{
// relocate to another subBlock
// find a new location to write to
int newLocation;
do
{
newLocation = subBlockFreePtr++;
subBlockFreePtr = subBlockFreePtr % noSubBlocks;
} while (subBlockTable[newLocation].state != unused);
subBlockTable[newLocation].state = used;
// Calculate the start Address of the SubBlock
cyg_uint32 writeAddress = getSubBlockAddress(newLocation);
cyg_uint32 writeEnd = writeAddress + subBlockSize ;
char *pMem = (char *)getSubBlockAddress(count);
//write to FLASH
while (writeAddress < writeEnd)
{
cyg_uint16 tmp = *pMem++; // 1st byte
cyg_uint16 data = (*pMem++ << 8) | tmp; // 2nd byte
#ifdef dbg_FLASH
diag_printf("reclaimDirtyFLASH: Writing 0x%x from 0x%x to 0x%x\r\n", flashWrite.writeData, pMem - 2, flashWrite.writeAddress);
#endif
writeToFlash(data, writeAddress);
writeAddress += 2;
}
// update FAT if required
if (subBlockTable[count].prev == FLASHNull)
{
// Find Entry in FAT
int FR = 0;
while (FAT[FR].start != count) FR++;
// Update start field
FAT[FR].start = newLocation ;
}
// update linked list
subBlockTable[newLocation].state = subBlockTable[count].state;
subBlockTable[newLocation].next = subBlockTable[count].next;
subBlockTable[newLocation].prev = subBlockTable[count].prev;
subBlockTable[count].state = unused;
subBlockTable[count].next = FLASHNull;
subBlockTable[count].prev = FLASHNull;
break;
}
case dirty:
{
// change the state to free and update counters
subBlockTable[count].state = unused;
subBlockTable[count].next = FLASHNull;
subBlockTable[count].prev = FLASHNull;
--dirtyCount;
freeCount++;
break;
}
default:
// do not change the subBlockTable entry for this subBlock
// i.e. if the subBlock is marked as bad it will remain so
// note however that the DATA in flash related to this
// subBlock WILL still be ERASED
break;
}
}
// erase the superBlock
eraseBlock(superBlockTable[superBlockNo]);
}
}
// FLASH erase file
bool FLASHfileSystem::erase(char *name)
{
// Confirm that this is flash we know about...
if (!valid) return false;
//## lock FLASH mutex
// check that the filename exists
int fileNumber = lookUp(name);
if (fileNumber == FLASHFileNotFound) return false;
// delete file number and recover the 1st subBlock of the file
strcpy(FAT[fileNumber].name,""); // remove entry
int count = FAT[fileNumber].start;
fileCount--;
do
{
subBlockTable[count].state = dirty;
count = subBlockTable[count].next;
dirtyCount++;
--usedCount;
}
while (count != FLASHNull);
// reclaim SuperBlocks if possible
reclaimDirtyFLASH();
//## unlock FLASH mutex
}
// diagnostic routine to dump the current file structure to the serial port
void FLASHfileSystem::show(void)
{
//## Lock FLASH mutex
char buffer[128];
sprintf(buffer, "File System information:");
display (buffer);
sprintf(buffer, " noSuperBlocks = 0x%x", noSuperBlocks);
display (buffer);
sprintf(buffer, " subBlocksize = 0x%x", subBlockSize);
display (buffer);
sprintf(buffer, " noSubBlocksPerSuperBlock = 0x%x", noSubBlocksPerSuperBlock);
display (buffer);
sprintf(buffer, " noSubBlocks = 0x%x", noSubBlocks);
display (buffer);
sprintf(buffer, " freeCount = 0x%x", freeCount);
display (buffer);
sprintf(buffer, " usedCount = 0x%x", usedCount);
display (buffer);
sprintf(buffer, " dirtyCount = 0x%x", dirtyCount);
display (buffer);
sprintf(buffer, " subBlockFreePtr = 0x%x", subBlockFreePtr);
display (buffer);
sprintf(buffer, " subBlockUsedPtr = 0x%x", subBlockUsedPtr);
display (buffer);
sprintf(buffer, " fileCount = 0x%x", fileCount);
display (buffer);
sprintf(buffer, " FAT name start length");
display (buffer);
for (int count0 = 0; count0 < MAXFILES; count0++)
{
sprintf(buffer, " FAT[0x%x] = %s, 0x%x, 0x%x", count0, FAT[count0].name, FAT[count0].start, FAT[count0].length);
display (buffer);
}
sprintf(buffer, " subBlock state next prev start address");
display (buffer);
for (int count1 = 0; count1 < noSubBlocks; count1++)
{
sprintf(buffer, " subBlockTable[0x%04x] = %02d, 0x%04x, 0x%04x, 0x%08x", count1, subBlockTable[count1].state, subBlockTable[count1].next, subBlockTable[count1].prev, getSubBlockAddress(count1));
display (buffer);
}
//## unlock FLASH mutex
}
// show files in file system
void FLASHfileSystem::cat(void)
{
//## Lock FLASH mutex
char buffer[128];
int files = 0;
int used = 0;
for (int count = 0; count < MAXFILES; count++)
{
if (strcmp(FAT[count].name,"") != 0)
{
sprintf(buffer, "%s 0x%x", FAT[count].name, FAT[count].length);
display (buffer);
files++;
used += FAT[count].length;
}
}
sprintf(buffer, "%d File(s) 0x%x Bytes\r 0x%x Bytes free\r\n", files, used, (freeCount+dirtyCount)*subBlockSize);
display (buffer);
//## unlock FLASH mutex
}
// open a file for read/write returning a handle if valid
int FLASHfileSystem::open(char *name, openFile *&handle)
{
#ifdef dbg_FLASH
diag_printf("open\r");
#endif
// Confirm that this is flash we know about...
if (!valid) return FLASH_UnsupportedDevice;
#ifdef dbg_FLASH
diag_printf(" fileSystem is valid\r");
#endif
//Limit size of file name
int nameLen = strlen(name);
if (nameLen > MAXNAMELEN)
{
nameLen = MAXNAMELEN;
}
name[nameLen] = '\0';
#ifdef dbg_FLASH
diag_printf(" name = %s\r", name);
#endif
//## lock FLASH mutex
// check if the filename exists
int fileNumber = lookUp(name);
if (fileNumber == FLASHFileNotFound)
{
// file does not exist
#ifdef dbg_FLASH
diag_printf(" File does not exist - creating new file\r");
#endif
// check if there is space to create a new file
if (fileCount == MAXFILES) return FLASH_TooManyFiles;
// allocate 1st subBlock to the file (there has to be somewhere for the data!)
if (freeCount < 1) return FLASH_OutOfSpace;
freeCount--;
usedCount++;
int subBlockSelected;
do
{
subBlockSelected = subBlockFreePtr;
subBlockFreePtr++;
subBlockFreePtr = subBlockFreePtr % noSubBlocks;
} while (subBlockTable[subBlockSelected].state != unused);
subBlockTable[subBlockSelected].state = inuse;
// find a free entry in the FAT and populate it
int count = 0;
while (strcmp(FAT[count].name,"") != 0) count++;
strcpy(FAT[count].name,name);
FAT[count].length = 0;
FAT[count].start = subBlockSelected;
fileCount++;
fileNumber = count;
} else {
// file does exist
#ifdef dbg_FLASH
diag_printf(" Found file\r");
#endif
// check to see if the file is already open
openFile *fwd = next;
while (fwd != NULL)
{
if (fwd->fileNumber == fileNumber) return FLASH_FileAlreadyOpen;
fwd = fwd->next;
}
}
#ifdef dbg_FLASH
diag_printf(" handle originly 0x%x\r", handle);
#endif
handle = new openFile(next, fileNumber);
#ifdef dbg_FLASH
diag_printf(" handle 0x%x\r\n", handle);
#endif
//## unlock FLASH mutex
return FLASH_OperationSuccessful;
}
// confirm that the handle given is valid
bool FLASHfileSystem::validateHandle(openFile *handle)
{
// travers the linked list of open files to confirm that the handle does exist
#ifdef dbg_FLASH
diag_printf("validateHandle\r");
diag_printf(" handle = 0x%x\r", handle);
#endif
openFile *fwd = next;
while (fwd != NULL)
{
if (fwd == handle)
{
#ifdef dbg_FLASH
diag_printf(" handle is valid\r");
#endif
return true;
}
fwd = fwd->next;
}
#ifdef dbg_FLASH
diag_printf(" handle is invalid\r");
#endif
return false;
}
int FLASHfileSystem::read(openFile *handle, size_t position, size_t *length, void *ptr)
{
#ifdef dbg_FLASH
diag_printf("FLASHfileSystem::read\r");
#endif
//## lock FLASH mutex
// confirm that the handle is valid
if (!validateHandle(handle)) return FLASH_InvalidHandle;
size_t readPosition = position;
size_t toRead = *length;
*length = 0;
char *buffer = (char *)ptr;
char inChar;
#ifdef dbg_FLASH
diag_printf(" reading...\r");
#endif
while (toRead > 0)
{
#ifdef dbg_FLASH
diag_printf(" readPosition = 0x%x\r FAT[handle->fileNumber].length = 0x%x\r", readPosition, FAT[handle->fileNumber].length);
#endif
// check that the start position is inside the file
if (readPosition > FAT[handle->fileNumber].length)
{
#ifdef dbg_FLASH
diag_printf("\rFLASHfileSystem::read EOF DONE\r");
#endif
return FLASH_EOF;
}
// determine the subBlock that we are going to start from
int subBlock = readPosition / subBlockSize;
// get the address of this subBlock
int record = FAT[handle->fileNumber].start;
for (int count = 1; count < subBlock; count++)
{
record = subBlockTable[record].next;
}
int subBlockAddress = getSubBlockAddress(subBlock);
int readAddress = subBlockAddress + (readPosition % subBlockSize);
inChar = (*((char *)(readAddress)));
#ifdef dbg_FLASH
diag_printf("%c", inChar);
#endif
buffer[readPosition] = inChar;
toRead-=1;
*length = (size_t)readPosition++;
#ifdef dbg_FLASH
diag_printf(" bytes left to read = 0x%x\r we have read 0x%x bytes so far\r", toRead, length);
#endif
}
//## unlock FLASHmutex
#ifdef dbg_FLASH
diag_printf("\rFLASHfileSystem::read DONE\r");
#endif
return FLASH_OperationSuccessful;
}
int FLASHfileSystem::write(openFile *handle, size_t position, size_t *length, void *ptr)
{
//## lock FLASH mutex
#ifdef dbg_FLASH
diag_printf("write\r\n");
diag_printf(" handle = 0x%x\r", handle);
diag_printf(" position = 0x%x\r",position);
diag_printf(" length = 0x%x\r", *length);
diag_printf(" ptr = 0x%x\r", ptr);
#endif
// confirm that the handle is valid
if (!validateHandle(handle)) return FLASH_InvalidHandle;
// only support append type write
#ifdef dbg_FLASH
diag_printf(" FAT[handle->fileNumber].length = 0x%x\r", FAT[handle->fileNumber].length);
diag_printf(" handle->fileNumber = 0x%x\r", handle->fileNumber);
#endif
if (position != FAT[handle->fileNumber].length) return FLASH_OporationNotSupported;
size_t writePosition = position;
size_t toWrite = *length;
*length = 0;
char *buffer = (char *)ptr;
#ifdef dbg_FLASH
diag_printf(" We are going to write 0x%x bytes to file 0x%x starting at position 0x%x\r", toWrite, handle->fileNumber, writePosition);
#endif
while (toWrite > 0)
{
// determine the subBlock that we are going to start from
int subBlock = writePosition / subBlockSize;
int record;
#ifdef dbg_FLASH
diag_printf("\r ---- \r");
#endif
if ((writePosition % subBlockSize != 0) || writePosition == 0)
{
// We are still inside the last subBlock
#ifdef dbg_FLASH
diag_printf(" This falls inside the last subBlock of the file\r");
#endif
// get the address of this subBlock
record = FAT[handle->fileNumber].start;
while (subBlockTable[record].next != FLASHNull)
{
record = subBlockTable[record].next;
}
} else {
// We have run out of space to write data. Attempt to get another subBlock
#ifdef dbg_FLASH
diag_printf(" We have run out of space to write data. Attempt to get another subBlock\r");
#endif
// Confirm that there is another free subBlock
if (freeCount == 0) return FLASH_OutOfSpace;
freeCount--;
// get the last subBlock used by our file
int lastSubBlock = FAT[handle->fileNumber].start;
while (subBlockTable[lastSubBlock].next != FLASHNull)
{
lastSubBlock = subBlockTable[lastSubBlock].next;
}
// obtain the subBlock
do
{
record = subBlockFreePtr++;
subBlockFreePtr = subBlockFreePtr % noSubBlocks;
} while (subBlockTable[record].state != unused);
subBlockTable[record].state = used;
usedCount++;
// add the new subBlock to the end of the linked list for our file
subBlockTable[lastSubBlock].next = record;
subBlockTable[record].prev = lastSubBlock;
subBlockTable[record].next = FLASHNull;
}
// get the address to write to
int subBlockAddress = getSubBlockAddress(record);
int writeAddress = subBlockAddress + (writePosition % subBlockSize);
#ifdef dbg_FLASH
diag_printf(" subBlock Record number = 0x%x\r at address 0x%x\r we will write from address 0x%x\r", record, subBlockAddress, writeAddress);
#endif
// perform actual write operation
// note that this is a 16 bit oporation but we want to work in bytes!
if (writeAddress % 2 == 0)
{
// even address
cyg_uint16 data = 0xff00 | *buffer++; // LSB will be the byte to write MSB will be blank (0xff)
#ifdef dbg_FLASH
diag_printf(" even write data = 0x%04x\r", data);
#endif
writeToFlash(data, writeAddress);
} else {
// odd address
cyg_uint16 *tmp = (cyg_uint16 *)(writeAddress-1); // LSB is read from device
cyg_uint16 rval = *tmp;
#ifdef dbg_FLASH
diag_printf(" odd write\r read 0x%04x\r rval = 0x%04x\r", *tmp, rval);
#endif
rval &= 0x00ff; // just interested in the lower byte
#ifdef dbg_FLASH
diag_printf(" after mask 0x%04x\r", rval);
diag_printf(" *buffer = 0x%x\r", *buffer);
#endif
cyg_uint16 wchar = (cyg_uint16)*buffer++;
#ifdef dbg_FLASH
diag_printf(" wchr before rotate = 0x%04x\r", wchar);
#endif
wchar = wchar << 8;
#ifdef dbg_FLASH
diag_printf(" wchr after rotate = 0x%04x\r", wchar);
#endif
cyg_uint16 data = wchar | rval; // MSB is the byte to program
#ifdef dbg_FLASH
diag_printf(" value to write 0x%04x\r", data);
#endif
writeToFlash(data, writeAddress-1);
}
// update counts
FAT[handle->fileNumber].length++; // file length
toWrite--; // number of bytes left to write
*length++; // number of bytes written
writePosition++; // where to write data to next...
}
return FLASH_OperationSuccessful;
}
// closes an open file. free's up any available resources.
int FLASHfileSystem::close(openFile *handle)
{
//## lock FLASH mutex
// confirm that the handle is valid
if (!validateHandle(handle)) return FLASH_InvalidHandle;
// free up resources if possible
if (FAT[handle->fileNumber].length == 0)
{
subBlockTable[FAT[handle->fileNumber].start].state = unused; // mark block as free
freeCount++; // number of free blocks +1
usedCount--; // return used block to free state
fileCount--; // count of files -1
strcpy(FAT[handle->fileNumber].name,""); // remove entry from FAT
}
delete handle;
//## unlock FLASH mutex
return FLASH_OperationSuccessful;
}
openFile::openFile(openFile *&fwd, int fileNum)
{
// add the handle to the linked list of all open files
#ifdef dbg_FLASH
diag_printf("openFile::openFile\r");
#endif
if (fwd == NULL)
{
#ifdef dbg_FLASH
diag_printf(" No files open\r");
#endif
fwd = this;
prev = NULL;
next = NULL;
} else {
#ifdef dbg_FLASH
diag_printf(" files are open\r");
#endif
while (fwd->next != NULL)
{
#ifdef dbg_FLASH
diag_printf(" advaning down the list\r");
#endif
fwd = fwd->next;
}
#ifdef dbg_FLASH
diag_printf(" adding record to the list\r");
#endif
fwd->next = this;
prev = fwd;
next = NULL;
}
#ifdef dbg_FLASH
if (prev == NULL)
{
diag_printf(" prev = NULL\r");
} else {
diag_printf(" prev = 0x%x\r", prev);
}
if (next == NULL)
{
diag_printf(" next = NULL\r");
} else {
diag_printf(" next = 0x%x\r", next);
}
if (sys->fs->next == NULL)
{
diag_printf(" sys->fs->next = NULL\r");
} else {
diag_printf(" sys->fs->next = 0x%x\r", sys->fs->next);
}
diag_printf("openFile::openFile DONE\r");
#endif
fileNumber = fileNum;
}
openFile::~openFile()
{
#ifdef dbg_FLASH
diag_printf("openFile::~openFile\r");
#endif
// remove entry from the linked list of open files
if (prev != NULL)
{
prev->next = next;
} else {
sys->fs->next = next;
}
if (next != NULL) next->prev = prev;
#ifdef dbg_FLASH
if (prev == NULL)
{
diag_printf(" prev = NULL\r");
} else {
diag_printf(" prev = 0x%x\r", prev);
}
if (next == NULL)
{
diag_printf(" next = NULL\r");
} else {
diag_printf(" next = 0x%x\r", next);
}
if (sys->fs->next == NULL)
{
diag_printf(" sys->fs->next = NULL\r");
} else {
diag_printf(" sys->fs->next = 0x%x\r", sys->fs->next);
}
diag_printf("openFile::~openFile DONE\r");
#endif
}
[-- Attachment #5: FLASHFileSystem.h --]
[-- Type: text/x-c++, Size: 3715 bytes --]
// FLASHFileSystem.h
#ifndef __FLASHFILESYSTEM_H__
#define __FLASHFILESYSTEM_H__
#include <cyg/kernel/kapi.h> /* All the kernel specific stuff */
#include <cyg/hal/hal_arch.h> /* CYGNUM_HAL_STACK_SIZE_TYPICAL */
#include "eCosIvory/flash.h" // flash device primatives
#include "eCosIvory/filesystem.h"
// The following values need to be defined with care
#define MAXFILES 16
#define MAXNAMELEN 8
#define NUMSUPERBLOCKS 4
#define SUBBLOCKSPERSUPERBLOCK 8
#define SUBBLOCKSIZE 128
#define SUPERBLOCKS {flash_SA15, flash_SA16, flash_SA17, flash_SA18}
// you should not need to make changes past this point
#define NUMSUBBLOCKS (SUBBLOCKSPERSUPERBLOCK * NUMSUPERBLOCKS)
#define FLASHFileNotFound MAXFILES
#define FLASHNull NUMSUBBLOCKS
typedef enum
{
unallocated = 0,
unused = 1,
inuse = 2,
used = 3,
dirty = 4,
bad = 5
} subBlockState;
class subBlockRecord
{
public:
subBlockState state;
int next;
int prev;
// CYG_ADDRESS FLASHAddress;
};
class FATRecord
{
public:
char name[MAXNAMELEN + 1];
int start;
cyg_uint32 length;
};
class openFile
{
public:
openFile(openFile *&fwd, int FileNum);
~openFile();
int fileNumber; // which file we are dealing with
openFile *next; // the next file in the linked list of open files
openFile *prev; // the previous file in the linked list of open files
};
class FLASHfileSystem : public fileSystem
{
friend class openFile;
public:
FLASHfileSystem(); // constructor
~FLASHfileSystem(); // destructor
bool format(void);
bool create(int length, char *data, char *name);
bool readAll(char *name, int *length, char *data);
bool erase(char *name);
void show(void);
void cat(void);
int open(char *name, openFile *&handle);
int read(openFile *handle, size_t position, size_t *length, void *ptr);
int write(openFile *handle, size_t position, size_t *length, void *ptr);
int close(openFile *handle);
private:
// methods
bool eraseBlock(CYG_ADDRESS superblock);
bool writeToFlash(cyg_uint16 writeData, cyg_uint32 writeAddress);
int lookUp(char *name);
cyg_uint32 getSubBlockAddress(int subBlockNumber);
void reclaimDirtyFLASH(void);
bool validateHandle(openFile *handle);
// data
CYG_ADDRESS superBlockTable[NUMSUPERBLOCKS];
subBlockRecord subBlockTable[NUMSUBBLOCKS];
FATRecord FAT[MAXFILES];
int freeCount;
int usedCount;
int dirtyCount;
int subBlockFreePtr;
int subBlockUsedPtr;
int fileCount;
openFile *next;
// The following are almost constants
int noSuperBlocks;
int subBlockSize;
int noSubBlocksPerSuperBlock;
int noSubBlocks;
};
#define FLASH_OperationSuccessful 0
#define FLASH_FileNotFound -1
#define FLASH_OporationNotSupported -2
#define FLASH_OutOfSpace -3
#define FLASH_TooManyFiles -4
#define FLASH_EOF -5
#define FLASH_UndefinedError -6
#define FLASH_UnsupportedDevice -7
#define FLASH_FileAlreadyOpen -8
#define FLASH_InvalidHandle -9
#endif __FLASHFILESYSTEM_H__
[-- Attachment #6: FlashRAM.cpp --]
[-- Type: text/x-c, Size: 10431 bytes --]
/*-----------------------------------------------------------------------------
*
* (c) Tardis Mobile - 2000
*
* Name: flash.c
*
* Author: A Simpkins
*
* Date: 04 October
*
*-----------------------------------------------------------------------------
*
* Modification history:
*
* --- 14/08/2001 002 - converted to eCos
* 04/10/2000 001 - Initial functions to test FLASH; flashEraseSegment &
* flashWrite.
*
*
*-----------------------------------------------------------------------------
*/
#include <cyg/kernel/kapi.h> /* All the kernel specific stuff */
#include <cyg/hal/t3.h>
#include <eCosIvory/flash.h>
#include <cyg/io/eCosSiRF.h>
#if CYGHWR_HAL_ARM_TARDIS3_VERSION == 1
/* FLASH addresses corrected for address line error on hardware */
struct flashEscape flashDeviceInfoSeq =
{
0x03,
{
(startAddressFLASH + (0x00001554)), 0x00aa,
(startAddressFLASH + (0x00000aaa)), 0x0055,
(startAddressFLASH + (0x00001554)), 0x0090
}
};
struct flashEscape flashEraseSectorSeq =
{
0x05,
{
(startAddressFLASH + 0x00001554), 0x00aa,
(startAddressFLASH + 0x00000aaa), 0x0055,
(startAddressFLASH + 0x00001554), 0x0080,
(startAddressFLASH + 0x00001554), 0x00aa,
(startAddressFLASH + 0x00000aaa), 0x0055
}
};
struct flashEscape flashWriteSeq =
{
0x03,
{
(startAddressFLASH + 0x00001554), 0x00aa,
(startAddressFLASH + 0x00000aaa), 0x0055,
(startAddressFLASH + 0x00001554), 0x00A0
}
};
struct flashEscape flashEraseAllSeq =
{
0x06,
{
(startAddressFLASH + 0x00001554), 0x00aa,
(startAddressFLASH + 0x00000aaa), 0x0055,
(startAddressFLASH + 0x00001554), 0x0080,
(startAddressFLASH + 0x00001554), 0x00aa,
(startAddressFLASH + 0x00000aaa), 0x0055,
(startAddressFLASH + 0x00001554), 0x0010
}
};
#else
/* FLASH address values from AMD datasheet
NOTE : addresses are for 8-bit access data is for 16-bit access
all other combinations do not work!
*/
struct flashEscape flashDeviceInfoSeq =
{
0x03,
{
(startAddressFLASH + 0x00000aaa), 0xaa,
(startAddressFLASH + 0x00000555), 0x55,
(startAddressFLASH + 0x00000aaa), 0x90
}
};
struct flashEscape flashEraseSectorSeq =
{
0x05,
{
(startAddressFLASH + 0x00000aaa), 0xaa,
(startAddressFLASH + 0x00000555), 0x55,
(startAddressFLASH + 0x00000aaa), 0x80,
(startAddressFLASH + 0x00000aaa), 0xaa,
(startAddressFLASH + 0x00000555), 0x55
}
};
struct flashEscape flashWriteSeq =
{
0x03,
{
(startAddressFLASH + 0x00000aaa), 0xaa,
(startAddressFLASH + 0x00000555), 0x55,
(startAddressFLASH + 0x00000aaa), 0xA0
}
};
struct flashEscape flashEraseAllSeq =
{
0x06,
{
(startAddressFLASH + 0x00000aaa), 0xaa,
(startAddressFLASH + 0x00000555), 0x55,
(startAddressFLASH + 0x00000aaa), 0x80,
(startAddressFLASH + 0x00000aaa), 0xaa,
(startAddressFLASH + 0x00000555), 0x55,
(startAddressFLASH + 0x00000aaa), 0x10
}
};
#endif
void __attribute__ ((section (".2ram.playFlashEscapeSeq"))) playFlashEscapeSeq (struct flashEscape *sequence)
{
volatile cyg_uint16 *pMem;
for (cyg_uint16 count = 0; count < sequence->length; count++)
{
pMem = (cyg_uint16* )sequence->flashpair[count].pairAddress;
*pMem = sequence->flashpair[count].pairData;
}
}
void __attribute__ ((section (".2ram.flashReset"))) flashReset(void)
{
volatile cyg_uint16 *pMem;
pMem = (cyg_uint16 *)startAddressFLASH;
*pMem = flash_reset;
}
cyg_uint32 __attribute__ ((section (".2ram.flash_query"))) flash_query(cyg_uint32 *callAddr)
{
flashcmd *data = (flashcmd *)callAddr;
bool cacheOn = false;
switch (data->flashCommand)
{
// Read the FLASH device information
case flashCmd_Info:
int old;
HAL_DISABLE_INTERRUPTS(old); // disable interrupts
if (ASIC_CACHE_EN == 0x0001)
{
cacheOn = true;
ASIC_CACHE_EN = 0x0000; // dissable cache
}
flashReset();
playFlashEscapeSeq(&flashDeviceInfoSeq);
volatile cyg_uint16 *pMem;
pMem =(cyg_uint16 *)flash_make;
((infoFlashCmd *)data)->make = *pMem;
flashReset();
playFlashEscapeSeq(&flashDeviceInfoSeq);
pMem =(cyg_uint16 *)flash_deviceID;
((infoFlashCmd *)data)->deviceID = *pMem;
flashReset();
if (cacheOn) ASIC_CACHE_EN = 0x0001; // re-enable cache
HAL_RESTORE_INTERRUPTS(old); // re-enable interrupts
break;
// Erase the specified sector
// Erasing sectors on a FLASH device may take a while. Because we can not run code from the
// FLASH during this time, we should dissable interrupts. Whilst we poll the FLASH to see if
// the opoeration has compleated we should also poll the interrupt status, is an interrupt has
// occured then we should suspend the FLASH oporation, enable (thus handle) interrupts before
case flashCmd_Erase:
{
int old;
HAL_DISABLE_INTERRUPTS(old); // disable interrupts
if (ASIC_CACHE_EN == 0x0001)
{
cacheOn = true;
ASIC_CACHE_EN = 0x0000; // dissable cache
}
((eraseFlashCmd *)data)->onHold = false;
flashReset();
playFlashEscapeSeq(&flashEraseSectorSeq);
volatile cyg_uint16 *pMem;
pMem = (cyg_uint16 *)((eraseFlashCmd *)data)->sectorNo;
*pMem = flash_eraseSectorCmd;
while ((*pMem & flash_DQ7) == 0)
{
// ### fix me
// what about a timeout - i.e. if the FLASH never finishes erasing the sector?
// check to see if an interrupt has occured
if (ASIC_INTREG & SiRFIRQ != 0)
{
*pMem = 0xB0; // Suspend erase
((eraseFlashCmd *)data)->onHold = true; // flag erase incompleate
break; // terminate the while loop
}
}
if (((eraseFlashCmd *)data)->onHold == true)
{
// on hold so not compleated
((eraseFlashCmd *)data)->success = false;
} else {
// we have compleated signal this and reset FLASH
((eraseFlashCmd *)data)->success = true;
flashReset();
}
if (cacheOn) ASIC_CACHE_EN = 0x0001; // re-enable cache
HAL_RESTORE_INTERRUPTS(old); // re-enable interrupts
break;
}
case flashCmd_ResumeErase:
{
int old;
HAL_DISABLE_INTERRUPTS(old); // disable interrupts
if (ASIC_CACHE_EN == 0x0001)
{
cacheOn = true;
ASIC_CACHE_EN = 0x0000; // dissable cache
}
volatile cyg_uint16 *pMem;
pMem = (cyg_uint16 *)((eraseFlashCmd *)data)->sectorNo;
*pMem = 0x30; // continue erasing FLASH
((eraseFlashCmd *)data)->onHold = false;
while ((*pMem & flash_DQ7) == 0)
{
// ### fix me
// what about a timeout - i.e. if the FLASH never finishes erasing the sector?
// check to see if an interrupt has occured
if (ASIC_INTREG & SiRFIRQ != 0)
{
*pMem = 0xB0; // Suspend erase
((eraseFlashCmd *)data)->onHold = true; // flag suspended
break; // terminate the while loop
}
}
if (((eraseFlashCmd *)data)->onHold)
{
((eraseFlashCmd *)data)->success = false;
} else {
((eraseFlashCmd *)data)->success = true;
flashReset();
}
if (cacheOn) ASIC_CACHE_EN = 0x0001; // re-enable cache
HAL_RESTORE_INTERRUPTS(old); // re-enable interrupts
break;
}
case flashCmd_Write:
{
// test for bad address (we can only program 16 bit data at an even address)
if (((writeFlashCmd *)data)->writeAddress % 2 == 1 )
{
((writeFlashCmd *)data)->result = flashResult_badAddress;
} else {
int old;
HAL_DISABLE_INTERRUPTS(old); // disable interrupts
if (ASIC_CACHE_EN == 0x0001)
{
cacheOn = true;
ASIC_CACHE_EN = 0x0000; // dissable cache
}
flashReset();
playFlashEscapeSeq(&flashWriteSeq);
volatile cyg_uint16 *pMem;
pMem = (cyg_uint16 *)((writeFlashCmd *)data)->writeAddress;
cyg_uint16 writeChar = ((writeFlashCmd *)data)->writeData;
*pMem = writeChar;
while ( (*pMem & flash_DQ7) != (writeChar & flash_DQ7) )
{
// ### fix me
// what about a timeout - i.e. if the FLASH never finishes programming?
}
flashReset();
if (cacheOn) ASIC_CACHE_EN = 0x0001; // re-enable cache
HAL_RESTORE_INTERRUPTS(old); // re-enable interrupts
((writeFlashCmd *)data)->result = flashResult_OK;
}
break;
}
default:
break;
}
return 1;
}
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2001-09-26 1:16 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-09-25 12:27 [ECOS] Flash Programming Example with ecos Jeffrey Jopling
2001-09-25 23:58 ` Jesper Skov
2001-09-26 1:16 Simpkins, Andy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).