📄 flashutil.c
字号:
/*
* Write flash-unlock sequence to device
*/
*dataPtr = CMD_CLEAR_STATUS_REG;
*dataPtr = CMD_PROGRAM_SETUP;
/*
* Write data to device
*/
*dataPtr = value;
/*
* Poll the flash to wait for the value to stabilise
*/
endTime = time_plus(time_now(), time_ticks_per_sec() * WRITE_TIMEOUT);
while (((*dataPtr & PECS_STATUS_BIT) != PECS_STATUS_BIT) && !time_after(time_now(), endTime))
{
}
if ((*dataPtr & STATUS_MASK) != PECS_STATUS_BIT)
{
fprintf(stderr, "\nError writing to %s @ 0x%08x\n", device->deviceName, address);
fprintf(stderr, "status: 0x%08x\n", *dataPtr);
exit(1);
}
}
static void writeCFI16(flashDevice_t* device, unsigned int address, unsigned short value)
{
volatile unsigned short* dataPtr;
osclock_t endTime;
dataPtr = (volatile unsigned short*)physToUncachedFlashAddr(address);
/*
* Write flash-unlock sequence to device
*/
*dataPtr = CMD_CLEAR_STATUS_REG16;
*dataPtr = CMD_PROGRAM_SETUP16;
/*
* Write data to device
*/
*dataPtr = value;
/*
* Poll the flash to wait for the value to stabilise
*/
endTime = time_plus(time_now(), time_ticks_per_sec() * WRITE_TIMEOUT);
while (((*dataPtr & PECS_STATUS_BIT16) != PECS_STATUS_BIT16) && !time_after(time_now(), endTime))
{
}
if ((*dataPtr & STATUS_MASK16) != PECS_STATUS_BIT16)
{
fprintf(stderr, "\nError writing to %s @ 0x%08x\n", device->deviceName, address);
fprintf(stderr, "status: 0x%04x\n", *dataPtr);
exit(1);
}
}
/*
* Routine to write a 32-bit word of data to a CFI device using
* a 16 bit bus.
*/
static void writeWordCFI16(flashDevice_t* device, unsigned int address, unsigned int value)
{
/* Don't bother writing words which are the default erased value */
if (value == 0xFFFFFFFF)
return;
writeCFI16(device, address, (unsigned short) (value & 0xFFFF));
writeCFI16(device, address + 2, (unsigned short) ((value >> 16)));
}
/*
* CFI block unprotect method
* Using 16 bit accesses
*/
static void blockUnprotectCFI16(flashDevice_t* device, unsigned int blockAddress)
{
volatile unsigned short* blockPtr;
osclock_t endTime;
blockPtr = (volatile unsigned short*)physToUncachedFlashAddr(blockAddress + 4);
*blockPtr = CMD_READ_ESIG16;
if ((*blockPtr & PROTECT_STATUS_BIT16) == 0)
{
/*
* Block is not protected
*/
return;
}
*blockPtr = CMD_CLEAR_STATUS_REG16;
*blockPtr = CMD_PROTECTION_SETUP16;
*blockPtr = CMD_CONFIRM16;
*blockPtr = CMD_READ_STATUS_REG16;
endTime = time_plus(time_now(), time_ticks_per_sec() * UNPROTECT_TIMEOUT);
while (((*blockPtr & PECS_STATUS_BIT16) != PECS_STATUS_BIT16) && !time_after(time_now(), endTime))
{
}
if ((*blockPtr & STATUS_MASK16) != PECS_STATUS_BIT16)
{
fprintf(stderr, "\nFailed to unprotect block @ 0x%08x\n", (unsigned int)blockAddress);
fprintf(stderr, "status = 0x%x\n", *blockPtr);
*blockPtr = CMD_READ_ARRAY16;
exit(1);
}
*blockPtr = CMD_READ_ARRAY16;
}
/*
* CFI block unprotect method
*/
static void blockUnprotectCFI(flashDevice_t* device, unsigned int blockAddress)
{
volatile unsigned int* blockPtr;
osclock_t endTime;
blockPtr = (volatile unsigned int*)physToUncachedFlashAddr(blockAddress+8);
*blockPtr = CMD_READ_ESIG;
if ((*blockPtr & PROTECT_STATUS_BIT) == 0)
{
/*
* Block is not protected
*/
return;
}
*blockPtr = CMD_CLEAR_STATUS_REG;
*blockPtr = CMD_PROTECTION_SETUP;
*blockPtr = CMD_CONFIRM;
*blockPtr = CMD_READ_STATUS_REG;
endTime = time_plus(time_now(), time_ticks_per_sec() * UNPROTECT_TIMEOUT);
while (((*blockPtr & PECS_STATUS_BIT) != PECS_STATUS_BIT) && !time_after(time_now(), endTime))
{
}
if ((*blockPtr & STATUS_MASK) != PECS_STATUS_BIT)
{
fprintf(stderr, "\nFailed to unprotect block @ 0x%08x\n", (unsigned int)blockAddress);
fprintf(stderr, "status = 0x%x\n", *blockPtr);
*blockPtr = CMD_READ_ARRAY;
exit(1);
}
*blockPtr = CMD_READ_ARRAY;
}
/*
* Routine to verify that a block erase worked
*/
static void checkErase(flashDevice_t* device, unsigned int blockAddress)
{
unsigned int* blockPtr;
unsigned int blkSize;
unsigned int i;
blockPtr = (unsigned int*)physToUncachedFlashAddr(blockAddress);
blkSize = flashBlockSize(device, blockAddress);
for (i = 0; i < blkSize / sizeof(int); i++, blockPtr++)
{
if (*blockPtr != 0xFFFFFFFF)
{
fprintf(stderr, "\nErase of block 0x%x failed at 0x%08x (0x%x != 0xFFFFFFFF)\n",
(unsigned int)blockAddress, blockAddress + (i * sizeof(int)), *blockPtr);
exit(1);
}
}
}
/*
* Routine to erase a block on an M29W type of device.
*/
static void blockEraseM29W(flashDevice_t* device, unsigned int blockAddress)
{
/*
* chipErase(device);
*/
volatile unsigned int* command1Ptr;
volatile unsigned int* command2Ptr;
volatile unsigned int* blockPtr;
osclock_t endTime;
blockUnprotect(device, blockAddress);
blockPtr = (volatile unsigned int*)physToUncachedFlashAddr(blockAddress);
command1Ptr = (volatile unsigned int*)physToUncachedFlashAddr(device->baseAddress + 0x1554);
command2Ptr = (volatile unsigned int*)physToUncachedFlashAddr(device->baseAddress + 0x2AA8);
/*
* Write flash-unlock sequence to device
*/
*command1Ptr = 0x00AA00AA;
*command2Ptr = 0x00550055;
*command1Ptr = 0x00800080;
*command1Ptr = 0x00AA00AA;
*command2Ptr = 0x00550055;
*blockPtr = 0x00300030;
/*
* Wait for a short while for the erase to start
*/
endTime = time_plus(time_now(), time_ticks_per_sec() * BLOCK_ERASE_TIMEOUT);
while ((((*blockPtr) & 0x00080008) != 0x00080008) && !time_after(time_now(), endTime))
{
}
if ((((*blockPtr) & 0x00080008) != 0x00080008))
{
fprintf(stderr, "\nError for block erase start for 0x%08x\n", (unsigned int)blockAddress);
}
/*
* Poll the FLASH to wait for the erase to complete
*/
endTime = time_plus(time_now(), time_ticks_per_sec() * BLOCK_ERASE_TIMEOUT);
while ((*blockPtr != 0xFFFFFFFF) && !time_after(time_now(), endTime))
{
}
if (*blockPtr != 0xFFFFFFFF)
{
fprintf(stderr, "\nError erasing block @ 0x%08x\n", (unsigned int)blockAddress);
exit(1);
}
checkErase(device, blockAddress);
}
/*
* Routine to erase a block on an M29W type of device.
*/
static void blockEraseM29W16(flashDevice_t* device, unsigned int blockAddress)
{
/*
* chipErase(device);
*/
volatile unsigned short* command1Ptr;
volatile unsigned short* command2Ptr;
volatile unsigned short* blockPtr;
osclock_t endTime;
/* blockUnprotect(device, blockAddress);*/
blockPtr = (volatile unsigned short*)physToUncachedFlashAddr(blockAddress);
command1Ptr = (volatile unsigned short*)physToUncachedFlashAddr(device->baseAddress + 0xAAA);
command2Ptr = (volatile unsigned short*)physToUncachedFlashAddr(device->baseAddress + 0x554);
/*
* Write flash-unlock sequence to device
*/
*command1Ptr = 0x00AA;
*command2Ptr = 0x0055;
*command1Ptr = 0x0080;
*command1Ptr = 0x00AA;
*command2Ptr = 0x0055;
*blockPtr = 0x0030;
/*
* Wait for a short while for the erase to start
*/
endTime = time_plus(time_now(), time_ticks_per_sec() * BLOCK_ERASE_TIMEOUT);
while ((((*blockPtr) & PECS_STATUS_BIT16) != PECS_STATUS_BIT16) && !time_after(time_now(), endTime))
{
}
if ((((*blockPtr) & PECS_STATUS_BIT16) != PECS_STATUS_BIT16))
{
fprintf(stderr, "\nError for block erase start for 0x%08x\n", (unsigned int)blockAddress);
}
/*
* Poll the FLASH to wait for the erase to complete
*/
endTime = time_plus(time_now(), time_ticks_per_sec() * BLOCK_ERASE_TIMEOUT);
while ((*blockPtr != 0xFFFF) && !time_after(time_now(), endTime))
{
}
if (*blockPtr != 0xFFFF)
{
fprintf(stderr, "\nError erasing block @ 0x%08x\n", (unsigned int)blockAddress);
exit(1);
}
checkErase(device, blockAddress);
}
/*
* Routine to erase a block used by many types of FLASH
* Uses 16 bit accesses
*/
static void blockEraseCFI16(flashDevice_t* device, unsigned int blockAddress)
{
volatile unsigned short* blockPtr;
osclock_t endTime;
blockUnprotectCFI16(device, blockAddress);
blockPtr = (volatile unsigned short*)physToUncachedFlashAddr(blockAddress);
*blockPtr = CMD_CLEAR_STATUS_REG16;
*blockPtr = CMD_ERASE_SETUP16;
*blockPtr = CMD_CONFIRM16;
endTime = time_plus(time_now(), time_ticks_per_sec() * BLOCK_ERASE_TIMEOUT);
while (((*blockPtr & PECS_STATUS_BIT16) != PECS_STATUS_BIT16) && !time_after(time_now(), endTime))
{
}
if ((*blockPtr & STATUS_MASK16) != PECS_STATUS_BIT16)
{
fprintf(stderr, "\nError during erase of block 0x%08x on %s\n",
(unsigned int)blockAddress, device->deviceName);
fprintf(stderr, "status is 0x%08x\n", *blockPtr);
exit(1);
}
*blockPtr = CMD_READ_ARRAY16;
checkErase(device, blockAddress);
}
/*
* Routine to erase a block used by many types of FLASH
*/
static void blockEraseCFI(flashDevice_t* device, unsigned int blockAddress)
{
volatile unsigned int* blockPtr;
osclock_t endTime;
blockUnprotect(device, blockAddress);
blockPtr = (volatile unsigned int*)physToUncachedFlashAddr(blockAddress);
*blockPtr = CMD_CLEAR_STATUS_REG;
*blockPtr = CMD_ERASE_SETUP;
*blockPtr = CMD_CONFIRM;
*blockPtr = CMD_READ_STATUS_REG;
endTime = time_plus(time_now(), time_ticks_per_sec() * BLOCK_ERASE_TIMEOUT);
while (((*blockPtr & PECS_STATUS_BIT) != PECS_STATUS_BIT) && !time_after(time_now(), endTime))
{
}
if ((*blockPtr & STATUS_MASK) != PECS_STATUS_BIT)
{
fprintf(stderr, "\nError during erase of block 0x%08x on %s\n",
blockAddress, device->deviceName);
fprintf(stderr, "status is 0x%08x\n", *blockPtr);
*blockPtr = CMD_READ_ARRAY;
exit(1);
}
*blockPtr = CMD_READ_ARRAY;
checkErase(device, blockAddress);
}
/*
* Routine to erase most FLASHes - just erase all its blocks
*/
static void chipEraseSimple(flashTarget_t* target, flashDevice_t* device, flashProgress_t progressFn)
{
unsigned int offset = 0;
while (offset < device->bankSize)
{
showProgress(progressFn, offset, device->bankSize);
flashBlockErase(target, device, device->baseAddress + offset);
offset += flashBlockSize(device, device->baseAddress + offset);
}
showProgress(progressFn, offset, device->bankSize);
}
/*
* Routine to erase an M29W
*/
static void chipEraseM29W(flashTarget_t* target, flashDevice_t* device, flashProgress_t progressFn)
{
volatile unsigned int* command1Ptr;
volatile unsigned int* command2Ptr;
volatile unsigned int* statusPtr;
osclock_t endTime;
showProgress(progressFn, 0, device->bankSize);
command1Ptr = (volatile unsigned int*)physToUncachedFlashAddr(device->baseAddress + 0x1554);
command2Ptr = (volatile unsigned int*)physToUncachedFlashAddr(device->baseAddress + 0x2AA8);
statusPtr = (volatile unsigned int*)physToUncachedFlashAddr(device->baseAddress);
*command1Ptr = 0x00AA00AA; /* Auto select command */
*command2Ptr = 0x00550055;
*command1Ptr = 0x00800080;
*command1Ptr = 0x00AA00AA;
*command2Ptr = 0x00550055;
*command1Ptr = 0x00100010;
endTime = time_plus(time_now(), time_ticks_per_sec() * CHIP_ERASE_TIMEOUT);
while ((*statusPtr != 0xFFFFFFFF) && !time_after(time_now(), endTime))
{
}
if (*statusPtr != 0xFFFFFFFF)
{
fprintf(stderr, "\nError erasing device\n");
exit(1);
}
showProgress(progressFn, device->bankSize, device->bankSize);
}
/*
* Routines to switch on / off VDD (programming voltage)
*/
static void switchOnVDD(flashTarget_t* target)
{
if (target->switchOnVDD)
{
target->switchOnVDD();
}
}
static void switchOffVDD(flashTarget_t* target)
{
if (target->switchOffVDD)
{
target->switchOffVDD();
}
}
#if defined(__st200__)
#else
#if defined(__st40gx1__)
static void switchOnVDD_mb317(void)
{
volatile unsigned int* vpp_reg = (volatile unsigned int*)
vmem_create((void*)0x07300000, vmem_min_page_size(), NULL, VMEM_CREATE_UNCACHED);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -