X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Flpc2000.c;h=396f910c0b3fd5c24d72d381b016a2d6f0cf3f27;hp=68181c6f044ec921364c8721fff967180695e9e5;hb=d17e1cd93384d56886be7e67cf2b31e97118d811;hpb=82d2633b5f550115e9e7c7d0520babb6680aa38f diff --git a/src/flash/lpc2000.c b/src/flash/lpc2000.c index 68181c6f04..396f910c0b 100644 --- a/src/flash/lpc2000.c +++ b/src/flash/lpc2000.c @@ -46,6 +46,9 @@ * variant 2 (lpc2000_v2): * - 213x * - 214x + * - 2101|2|3 + * - 2364|6|8 + * - 2378 */ int lpc2000_register_commands(struct command_context_s *cmd_ctx); @@ -69,6 +72,7 @@ flash_driver_t lpc2000_flash = .protect = lpc2000_protect, .write = lpc2000_write, .probe = lpc2000_probe, + .auto_probe = lpc2000_probe, .erase_check = lpc2000_erase_check, .protect_check = lpc2000_protect_check, .info = lpc2000_info @@ -87,7 +91,10 @@ int lpc2000_register_commands(struct command_context_s *cmd_ctx) int lpc2000_build_sector_list(struct flash_bank_s *bank) { lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv; - + + /* default to a 4096 write buffer */ + lpc2000_info->cmd51_max_buffer = 4096; + if (lpc2000_info->variant == 1) { int i = 0; @@ -152,6 +159,17 @@ int lpc2000_build_sector_list(struct flash_bank_s *bank) /* variant 2 has a uniform layout, only number of sectors differs */ switch (bank->size) { + case 4 * 1024: + lpc2000_info->cmd51_max_buffer = 1024; + num_sectors = 1; + break; + case 8 * 1024: + lpc2000_info->cmd51_max_buffer = 1024; + num_sectors = 2; + break; + case 16 * 1024: + num_sectors = 4; + break; case 32 * 1024: num_sectors = 8; break; @@ -164,6 +182,7 @@ int lpc2000_build_sector_list(struct flash_bank_s *bank) case 256 * 1024: num_sectors = 15; break; + case 512 * 1024: case 500 * 1024: num_sectors = 27; break; @@ -175,7 +194,7 @@ int lpc2000_build_sector_list(struct flash_bank_s *bank) bank->num_sectors = num_sectors; bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors); - + for (i = 0; i < num_sectors; i++) { if ((i >= 0) && (i < 8)) @@ -223,7 +242,7 @@ int lpc2000_build_sector_list(struct flash_bank_s *bank) int lpc2000_iap_call(flash_bank_t *bank, int code, u32 param_table[5], u32 result_table[2]) { lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv; - target_t *target = lpc2000_info->target; + target_t *target = bank->target; mem_param_t mem_params[2]; reg_param_t reg_params[5]; armv4_5_algorithm_t armv4_5_info; @@ -242,9 +261,9 @@ int lpc2000_iap_call(flash_bank_t *bank, int code, u32 param_table[5], u32 resul } /* write IAP code to working area */ - buf_set_u32(jump_gate, 0, 32, ARMV4_5_BX(12)); - buf_set_u32(jump_gate, 32, 32, 0xeafffffe); - target->type->write_memory(target, lpc2000_info->iap_working_area->address, 4, 2, (u8*)jump_gate); + target_buffer_set_u32(target, jump_gate, ARMV4_5_BX(12)); + target_buffer_set_u32(target, jump_gate + 4, ARMV4_5_B(0xfffffe, 0)); + target->type->write_memory(target, lpc2000_info->iap_working_area->address, 4, 2, jump_gate); } armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC; @@ -253,12 +272,12 @@ int lpc2000_iap_call(flash_bank_t *bank, int code, u32 param_table[5], u32 resul /* command parameter table */ init_mem_param(&mem_params[0], lpc2000_info->iap_working_area->address + 8, 4 * 6, PARAM_OUT); - buf_set_u32(mem_params[0].value, 0, 32, code); - buf_set_u32(mem_params[0].value, 32, 32, param_table[0]); - buf_set_u32(mem_params[0].value, 64, 32, param_table[1]); - buf_set_u32(mem_params[0].value, 96, 32, param_table[2]); - buf_set_u32(mem_params[0].value, 128, 32, param_table[3]); - buf_set_u32(mem_params[0].value, 160, 32, param_table[4]); + target_buffer_set_u32(target, mem_params[0].value, code); + target_buffer_set_u32(target, mem_params[0].value + 0x4, param_table[0]); + target_buffer_set_u32(target, mem_params[0].value + 0x8, param_table[1]); + target_buffer_set_u32(target, mem_params[0].value + 0xc, param_table[2]); + target_buffer_set_u32(target, mem_params[0].value + 0x10, param_table[3]); + target_buffer_set_u32(target, mem_params[0].value + 0x14, param_table[4]); init_reg_param(®_params[0], "r0", 32, PARAM_OUT); buf_set_u32(reg_params[0].value, 0, 32, lpc2000_info->iap_working_area->address + 0x8); @@ -284,8 +303,8 @@ int lpc2000_iap_call(flash_bank_t *bank, int code, u32 param_table[5], u32 resul target->type->run_algorithm(target, 2, mem_params, 5, reg_params, lpc2000_info->iap_working_area->address, lpc2000_info->iap_working_area->address + 0x4, 10000, &armv4_5_info); status_code = buf_get_u32(mem_params[1].value, 0, 32); - result_table[0] = buf_get_u32(mem_params[1].value, 32, 32); - result_table[1] = buf_get_u32(mem_params[1].value, 64, 32); + result_table[0] = target_buffer_get_u32(target, mem_params[1].value); + result_table[1] = target_buffer_get_u32(target, mem_params[1].value + 4); destroy_mem_param(&mem_params[0]); destroy_mem_param(&mem_params[1]); @@ -340,7 +359,7 @@ int lpc2000_iap_blank_check(struct flash_bank_s *bank, int first, int last) return ERROR_OK; } -/* flash_bank lpc2000 0 0 [calc_checksum] +/* flash bank lpc2000 0 0 [calc_checksum] */ int lpc2000_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank) { @@ -355,14 +374,14 @@ int lpc2000_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, cha lpc2000_info = malloc(sizeof(lpc2000_flash_bank_t)); bank->driver_priv = lpc2000_info; - if (strcmp(args[5], "lpc2000_v1") == 0) + if (strcmp(args[6], "lpc2000_v1") == 0) { lpc2000_info->variant = 1; lpc2000_info->cmd51_dst_boundary = 512; lpc2000_info->cmd51_can_256b = 0; lpc2000_info->cmd51_can_8192b = 1; } - else if (strcmp(args[5], "lpc2000_v2") == 0) + else if (strcmp(args[6], "lpc2000_v2") == 0) { lpc2000_info->variant = 2; lpc2000_info->cmd51_dst_boundary = 256; @@ -376,18 +395,11 @@ int lpc2000_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, cha return ERROR_FLASH_BANK_INVALID; } - lpc2000_info->target = get_target_by_num(strtoul(args[6], NULL, 0)); - if (!lpc2000_info->target) - { - ERROR("no target '%s' configured", args[6]); - exit(-1); - } lpc2000_info->iap_working_area = NULL; lpc2000_info->cclk = strtoul(args[7], NULL, 0); lpc2000_info->calc_checksum = 0; lpc2000_build_sector_list(bank); - - + if (argc >= 9) { if (strcmp(args[8], "calc_checksum") == 0) @@ -404,16 +416,6 @@ int lpc2000_erase(struct flash_bank_s *bank, int first, int last) u32 result_table[2]; int status_code; - if (lpc2000_info->target->state != TARGET_HALTED) - { - return ERROR_TARGET_NOT_HALTED; - } - - if ((first < 0) || (last < first) || (last >= bank->num_sectors)) - { - return ERROR_FLASH_SECTOR_INVALID; - } - param_table[0] = first; param_table[1] = last; param_table[2] = lpc2000_info->cclk; @@ -462,7 +464,7 @@ int lpc2000_protect(struct flash_bank_s *bank, int set, int first, int last) int lpc2000_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) { lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv; - target_t *target = lpc2000_info->target; + target_t *target = bank->target; u32 dst_min_alignment; u32 bytes_remaining = count; u32 bytes_written = 0; @@ -474,13 +476,8 @@ int lpc2000_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) int i; working_area_t *download_area; - if (lpc2000_info->target->state != TARGET_HALTED) - { - return ERROR_TARGET_NOT_HALTED; - } - /* allocate a working area */ - if (target_alloc_working_area(target, 4096, &download_area) != ERROR_OK) + if (target_alloc_working_area(target, lpc2000_info->cmd51_max_buffer, &download_area) != ERROR_OK) { ERROR("no working area specified, can't write LPC2000 internal flash"); return ERROR_FLASH_OPERATION_FAILED; @@ -529,8 +526,8 @@ int lpc2000_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) while (bytes_remaining > 0) { u32 thisrun_bytes; - if (bytes_remaining >= 4096) - thisrun_bytes = 4096; + if (bytes_remaining >= lpc2000_info->cmd51_max_buffer) + thisrun_bytes = lpc2000_info->cmd51_max_buffer; else if (bytes_remaining >= 1024) thisrun_bytes = 1024; else if ((bytes_remaining >= 512) || (!lpc2000_info->cmd51_can_256b)) @@ -558,7 +555,7 @@ int lpc2000_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) if (bytes_remaining >= thisrun_bytes) { - if (target_write_buffer(lpc2000_info->target, download_area->address, thisrun_bytes, buffer + bytes_written) != ERROR_OK) + if (target_write_buffer(bank->target, download_area->address, thisrun_bytes, buffer + bytes_written) != ERROR_OK) { target_free_working_area(target, download_area); return ERROR_FLASH_OPERATION_FAILED; @@ -571,7 +568,7 @@ int lpc2000_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) memcpy(last_buffer, buffer + bytes_written, bytes_remaining); for (i = bytes_remaining; i < thisrun_bytes; i++) last_buffer[i] = 0xff; - target_write_buffer(lpc2000_info->target, download_area->address, thisrun_bytes, last_buffer); + target_write_buffer(bank->target, download_area->address, thisrun_bytes, last_buffer); free(last_buffer); } @@ -619,9 +616,7 @@ int lpc2000_probe(struct flash_bank_s *bank) int lpc2000_erase_check(struct flash_bank_s *bank) { - lpc2000_flash_bank_t *lpc2000_info = bank->driver_priv; - - if (lpc2000_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; } @@ -654,8 +649,7 @@ int lpc2000_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, if (argc < 1) { - command_print(cmd_ctx, "usage: lpc2000 part_id "); - return ERROR_OK; + return ERROR_COMMAND_SYNTAX_ERROR; } bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0)); @@ -666,7 +660,7 @@ int lpc2000_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, } lpc2000_info = bank->driver_priv; - if (lpc2000_info->target->state != TARGET_HALTED) + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; }