logo       

Micron Q Flash support: msg#00036

handhelds.ipaq.boot-loader

Subject: Micron Q Flash support

This note is addressed to those that use "bootldr" for custom boards. If you
plan to use Micron Q Flash devices, such MT28F640J3, replacing intel chips,
in your project with "bootldr" you have to modify the btflash.c file: after
each write command (word or block) a Read Array command (0xff) must be used
to go back to read state. The following stub of code illustrates the patch.

/*
* Programs value at flashAddress
* Sectors must be erased before they can be programmed.
*/
static int intelFlashProgramWord(unsigned long flashAddress, unsigned long
value)
{
unsigned long flashWordOffset = (flashAddress&flash_address_mask) >> 2;
long timeout = FLASH_TIMEOUT;
unsigned long flashContents = flashword[flashWordOffset];
unsigned long status = 0;

/* see if we can program the value without erasing */
if ((flashContents & value) != value) {
putstr("the flash sector needs to be erased first!\r\n");
putLabeledWord(" flashAddress=", flashAddress);
putLabeledWord(" flashWordOffset=", flashWordOffset);
putLabeledWord(" &flashword[flashWordOffset]=",
(dword)&flashword[flashWordOffset]);
putLabeledWord(" flashContents=", flashContents);
return -1;
}

/* send flash the program word command */
flashword[0x55] = bothbanks(0x40);
flashword[flashWordOffset] = value;
/* now wait for it to be programmed */
while (timeout > 0) {
status = flashword[flashWordOffset];
if ((status & bothbanks(0x80)) == bothbanks(0x80))
break;
timeout--;
}
intelFlashClearStatus();
flashword[0x55] = bothbanks(0xff); // back to read array

if ((timeout <= 0) || (status & bothbanks(0x7f))) {
putstr("programFlashWord error\r\n");
putLabeledWord(" flashAddress=", flashAddress);
putLabeledWord(" value=", value);
putLabeledWord(" flashContents=", flashContents);
putLabeledWord(" status=", status);
return(-1);
}
return 0;
}

/* each flash chip has 32B block, 64B block for chip array */
static int intelFlashProgramBlock(unsigned long flashAddress, unsigned long
*values, int nbytes)
{
unsigned long flashWordOffset = (flashAddress&flash_address_mask) >> 2;
unsigned long blockOffset = (flashWordOffset & 0xFFFFFFC0);
int nwords = nbytes >> 2;
int result = 0;
long timeout = FLASH_TIMEOUT;
unsigned long status = 0;
int i;

if (0) putLabeledWord("intelFlashProgramFlashBlock\r\n", flashAddress);

/* send the "write to buffer" command and read the extended status
register */
timeout = FLASH_TIMEOUT;
do {
flashword[flashWordOffset] = bothbanks(0xE8);
status = flashword[flashWordOffset];
if (0) putLabeledWord(" XSR=", status);
if (--timeout <= 0)
goto endprg;
} while ((status & 0x00800080) != 0x00800080);

/* write word count at block start address */
flashword[blockOffset] = bothbanks(nwords-1); /* length minus one */

/* send the data */
for (i = 0; i < nwords; i++) {
flashword[flashWordOffset+i] = values[i];
if (0) putLabeledWord(" sr=", flashword[blockOffset]);
}

/* send the confirmation to program */
flashword[blockOffset] = bothbanks(0xD0);

/* now wait for it to be programmed */
timeout = FLASH_TIMEOUT;
while (timeout > 0) {
status = flashword[blockOffset];
if (0) putLabeledWord(" status=", status);
if ((status & bothbanks(0x80)) == bothbanks(0x80))
break;
timeout--;
}
status = intelFlashReadStatus();
if (0) putLabeledWord("final status=", status);

endprg:
intelFlashClearStatus();
flashword[0x55] = bothbanks(0xff); // back to read array

if ((timeout <= 0) || (status & bothbanks(0x7f))) {
putstr("programFlashBlock error\r\n");
putLabeledWord(" flashAddress=", flashAddress);
putLabeledWord(" status=", status);
return(-1);
}
return 0;
}

Hope this helps.
Michele


<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise