diff options
author | drath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2007-08-14 09:48:54 +0000 |
---|---|---|
committer | drath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2007-08-14 09:48:54 +0000 |
commit | 29000b204d039bc1123027eba755329ab36a3dde (patch) | |
tree | 841d600e015592b5abd77b982dfb0d9cde51a399 /src/flash | |
parent | abbd2b62ad445d4056567e2573416498a55da9af (diff) | |
download | openocd+libswd-29000b204d039bc1123027eba755329ab36a3dde.tar.gz openocd+libswd-29000b204d039bc1123027eba755329ab36a3dde.tar.bz2 openocd+libswd-29000b204d039bc1123027eba755329ab36a3dde.tar.xz openocd+libswd-29000b204d039bc1123027eba755329ab36a3dde.zip |
- reworked presto.c to allow use of either FTD2XX or libftdi (libftdi not functional yet). Configure option changed from --enable-presto to
--enable-presto_ftd2xx and --enable-presto_libftdi
- completed trace point support for use with ARM7/9 DCC
- completed debug message output with support for HEX dumps (1, 2 or 4 byte quantities)
- fixed bug in delete_debug_msg_receiver (thanks to Pavel Chromy)
- fixed bug in image_add_section (thanks to Pavel Chromy)
- at91sam7 sector erase reworked (thanks to Pavel Chromy)
- merge consecutive sections during flash image write to work around possible section alignment issues with LPC2000 targets
git-svn-id: svn://svn.berlios.de/openocd/trunk@194 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src/flash')
-rw-r--r-- | src/flash/at91sam7.c | 35 | ||||
-rw-r--r-- | src/flash/flash.c | 64 | ||||
-rw-r--r-- | src/flash/nand.c | 2 |
3 files changed, 76 insertions, 25 deletions
diff --git a/src/flash/at91sam7.c b/src/flash/at91sam7.c index fdc1c51a..b4b34758 100644 --- a/src/flash/at91sam7.c +++ b/src/flash/at91sam7.c @@ -326,7 +326,15 @@ int at91sam7_read_part_info(struct flash_bank_s *bank) at91sam7_info->cidr_version = cidr&0x001F; bank->size = NVPSIZ[at91sam7_info->cidr_nvpsiz]; at91sam7_info->target_name = "Unknown"; - + + /* Support just for bulk erase of the whole device */ + bank->num_sectors = 1; + bank->sectors = malloc(sizeof(flash_sector_t)); + bank->sectors[0].offset = 0; + bank->sectors[0].size = bank->size; + bank->sectors[0].is_erased = -1; + bank->sectors[0].is_protected = -1; + DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch ); /* Read main and master clock freqency register */ @@ -565,22 +573,27 @@ int at91sam7_erase(struct flash_bank_s *bank, int first, int last) return ERROR_FLASH_OPERATION_FAILED; } - if ((first < 0) || (last < first) || (last >= at91sam7_info->num_lockbits)) + if ((first < 0) || (last < first) || (last >= bank->num_sectors)) { - return ERROR_FLASH_SECTOR_INVALID; + if ((first == 0) && (last == (at91sam7_info->num_lockbits-1))) + { + WARNING("Sector numbers based on lockbit count, probably a deprecated script"); + last = bank->num_sectors-1; + } + else return ERROR_FLASH_SECTOR_INVALID; } - /* Configure the flash controller timing */ - at91sam7_read_clock_info(bank); - at91sam7_set_flash_mode(bank,FMR_TIMING_FLASH); - - if ((first == 0) && (last == (at91sam7_info->num_lockbits-1))) + if ((first != 0) || (last != (bank->num_sectors-1))) { - return at91sam7_flash_command(bank, EA, 0); + WARNING("Can only erase the whole flash area, pages are autoerased on write"); + return ERROR_FLASH_OPERATION_FAILED; } - WARNING("Can only erase the whole flash area, pages are autoerased on write"); - return ERROR_FLASH_OPERATION_FAILED; + /* Configure the flash controller timing */ + at91sam7_read_clock_info(bank); + at91sam7_set_flash_mode(bank,FMR_TIMING_FLASH); + + return at91sam7_flash_command(bank, EA, 0); } int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last) diff --git a/src/flash/flash.c b/src/flash/flash.c index e3389b19..4481fc63 100644 --- a/src/flash/flash.c +++ b/src/flash/flash.c @@ -738,24 +738,36 @@ int flash_erase(target_t *target, u32 addr, u32 length) int flash_write(target_t *target, image_t *image, u32 *image_size, char **error_str, u32 *failed) { + int last_section; int section; + int next_section; int retval; *image_size = 0; /* for each section in the image */ - for (section = 0; section < image->num_sections; section++) + last_section = 0; + section = 0; + while (section < image->num_sections) { u32 offset = 0; u32 address = image->sections[section].base_address; u32 size = image->sections[section].size; - failed[section] = 0; + /* collect consecutive sections */ + next_section = section + 1; + while ((next_section < image->num_sections) + && (image->sections[next_section].base_address == (address + size))) + { + size += image->sections[next_section].size; + next_section++; + } while (size != 0) { flash_bank_t *c; u32 thisrun_size = size; + u32 buffer_size; u32 size_read; u8 *buffer; @@ -767,23 +779,50 @@ int flash_write(target_t *target, image_t *image, u32 *image_size, char **error_ break; } - /* check whether it fits, split into multiple runs if not */ + /* check whether cumulated sections fit the bank, split into multiple runs if not */ if ((address + size) > (c->base + c->size)) thisrun_size = c->base + c->size - address; buffer = malloc(thisrun_size); - if (((retval = image_read_section(image, section, offset, size, buffer, &size_read)) != ERROR_OK) - || (thisrun_size != size_read)) + buffer_size = 0; + + while (buffer_size < thisrun_size) { - *error_str = malloc(FLASH_MAX_ERROR_STR); - snprintf(*error_str, FLASH_MAX_ERROR_STR, "error reading from image"); - return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE; + u32 thissection_size = image->sections[section].size - offset; + + if ((retval = image_read_section(image, section, offset, + MIN(thisrun_size, thissection_size), + buffer + buffer_size, &size_read)) != ERROR_OK) + { + *error_str = malloc(FLASH_MAX_ERROR_STR); + snprintf(*error_str, FLASH_MAX_ERROR_STR, "error reading from image"); + return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE; + } + + /* see if we're done with the current section */ + if (thissection_size < thisrun_size) + { + /* start with the next section */ + offset = 0; + failed[section] = 0; + section++; + } + else + { + /* continue inside the current section */ + offset += size_read; + } + + buffer_size += size_read; } if ((retval = c->driver->write(c, buffer, address - c->base, thisrun_size)) != ERROR_OK) { - /* mark the current section as failed */ - failed[section] = 1; + int i; + /* mark sections as failed */ + for (i = last_section; i <= section; i++) + failed[i] = 1; + *error_str = malloc(FLASH_MAX_ERROR_STR); switch (retval) { @@ -817,12 +856,11 @@ int flash_write(target_t *target, image_t *image, u32 *image_size, char **error_ free(buffer); - offset += thisrun_size; address += thisrun_size; size -= thisrun_size; + *image_size += thisrun_size; + last_section = section; } - - *image_size += image->sections[section].size; } return ERROR_OK; diff --git a/src/flash/nand.c b/src/flash/nand.c index d06a232c..52c92328 100644 --- a/src/flash/nand.c +++ b/src/flash/nand.c @@ -256,7 +256,7 @@ int handle_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, cha int nand_register_commands(struct command_context_s *cmd_ctx) { - nand_cmd = register_command(cmd_ctx, NULL, "nand", NULL, COMMAND_ANY, NULL); + nand_cmd = register_command(cmd_ctx, NULL, "nand", NULL, COMMAND_ANY, "NAND specific commands"); register_command(cmd_ctx, nand_cmd, "device", handle_nand_device_command, COMMAND_CONFIG, NULL); |