Georg Acher <acher@in.tum.de> implements the buffer flash mode for Spansion flashes. It's basically a clone of the Intel version, just a few details differ
git-svn-id: svn://svn.berlios.de/openocd/trunk@1017 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
parent
9807a00206
commit
333499a962
|
@ -1595,6 +1595,75 @@ int cfi_spansion_write_word(struct flash_bank_s *bank, u8 *word, u32 address)
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int cfi_spansion_write_words(struct flash_bank_s *bank, u8 *word, u32 wordcount, u32 address)
|
||||
{
|
||||
cfi_flash_bank_t *cfi_info = bank->driver_priv;
|
||||
target_t *target = bank->target;
|
||||
u8 command[8];
|
||||
int sector;
|
||||
cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext;
|
||||
|
||||
/* Calculate buffer size and boundary mask */
|
||||
u32 buffersize = 1UL << cfi_info->max_buf_write_size;
|
||||
u32 buffermask = buffersize-1;
|
||||
u32 bufferwsize;
|
||||
|
||||
/* Check for valid range */
|
||||
if (address & buffermask)
|
||||
{
|
||||
LOG_ERROR("Write address at base 0x%x, address %x not aligned to 2^%d boundary", bank->base, address, cfi_info->max_buf_write_size);
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
switch(bank->chip_width)
|
||||
{
|
||||
case 4 : bufferwsize = buffersize / 4; break;
|
||||
case 2 : bufferwsize = buffersize / 2; break;
|
||||
case 1 : bufferwsize = buffersize; break;
|
||||
default:
|
||||
LOG_ERROR("Unsupported chip width %d", bank->chip_width);
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
/* Check for valid size */
|
||||
if (wordcount > bufferwsize)
|
||||
{
|
||||
LOG_ERROR("Number of data words %d exceeds available buffersize %d", wordcount, buffersize);
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
// Unlock
|
||||
cfi_command(bank, 0xaa, command);
|
||||
target->type->write_memory(target, flash_address(bank, 0, pri_ext->_unlock1), bank->bus_width, 1, command);
|
||||
|
||||
cfi_command(bank, 0x55, command);
|
||||
target->type->write_memory(target, flash_address(bank, 0, pri_ext->_unlock2), bank->bus_width, 1, command);
|
||||
|
||||
// Buffer load command
|
||||
cfi_command(bank, 0x25, command);
|
||||
target->type->write_memory(target, address, bank->bus_width, 1, command);
|
||||
|
||||
/* Write buffer wordcount-1 and data words */
|
||||
cfi_command(bank, bufferwsize-1, command);
|
||||
target->type->write_memory(target, address, bank->bus_width, 1, command);
|
||||
|
||||
target->type->write_memory(target, address, bank->bus_width, bufferwsize, word);
|
||||
|
||||
/* Commit write operation */
|
||||
cfi_command(bank, 0x29, command);
|
||||
target->type->write_memory(target, address, bank->bus_width, 1, command);
|
||||
|
||||
if (cfi_spansion_wait_status_busy(bank, 1000 * (1 << cfi_info->word_write_timeout_max)) != ERROR_OK)
|
||||
{
|
||||
cfi_command(bank, 0xf0, command);
|
||||
target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command);
|
||||
|
||||
LOG_ERROR("couldn't write block at base 0x%x, address %x, size %x", bank->base, address, bufferwsize);
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int cfi_write_word(struct flash_bank_s *bank, u8 *word, u32 address)
|
||||
{
|
||||
cfi_flash_bank_t *cfi_info = bank->driver_priv;
|
||||
|
@ -1627,8 +1696,7 @@ int cfi_write_words(struct flash_bank_s *bank, u8 *word, u32 wordcount, u32 addr
|
|||
return cfi_intel_write_words(bank, word, wordcount, address);
|
||||
break;
|
||||
case 2:
|
||||
/* return cfi_spansion_write_words(bank, word, address); */
|
||||
LOG_ERROR("cfi primary command set %i unimplemented - FIXME", cfi_info->pri_id);
|
||||
return cfi_spansion_write_words(bank, word, wordcount, address);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id);
|
||||
|
@ -2261,7 +2329,7 @@ int cfi_info(struct flash_bank_s *bank, char *buf, int buf_size)
|
|||
printed = snprintf(buf, buf_size, "size: 0x%x, interface desc: %i, max buffer write size: %x\n",
|
||||
1 << cfi_info->dev_size,
|
||||
cfi_info->interface_desc,
|
||||
cfi_info->max_buf_write_size);
|
||||
1 << cfi_info->max_buf_write_size);
|
||||
buf += printed;
|
||||
buf_size -= printed;
|
||||
|
||||
|
|
Loading…
Reference in New Issue