X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Faduc702x.c;h=ebda702af9ff15ea2943d9b658d78b3c77b9d9ed;hp=6268b1cde83977e2faa8d5604fc241ddfed03026;hb=15e8e4530866454c18c5d91ad9e867f339c2e82b;hpb=fbe8cf72a5e6c80fed5fba8754d790ca63ad2b65 diff --git a/src/flash/aduc702x.c b/src/flash/aduc702x.c index 6268b1cde8..ebda702af9 100644 --- a/src/flash/aduc702x.c +++ b/src/flash/aduc702x.c @@ -29,16 +29,6 @@ #include "time_support.h" -static int aduc702x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank); -static int aduc702x_register_commands(struct command_context_s *cmd_ctx); -static int aduc702x_erase(struct flash_bank_s *bank, int first, int last); -static int aduc702x_protect(struct flash_bank_s *bank, int set, int first, int last); -static int aduc702x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count); -static int aduc702x_write_single(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count); -static int aduc702x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count); -static int aduc702x_probe(struct flash_bank_s *bank); -static int aduc702x_info(struct flash_bank_s *bank, char *buf, int buf_size); -static int aduc702x_protect_check(struct flash_bank_s *bank); static int aduc702x_build_sector_list(struct flash_bank_s *bank); static int aduc702x_check_flash_completion(target_t* target, unsigned int timeout_ms); static int aduc702x_set_write_enable(target_t *target, int enable); @@ -53,49 +43,17 @@ static int aduc702x_set_write_enable(target_t *target, int enable); #define ADUC702x_FLASH_FEEPRO (6*4) #define ADUC702x_FLASH_FEEHIDE (7*4) -typedef struct { - u32 feesta; - u32 feemod; - u32 feecon; - u32 feedat; - u32 feeadr; - u32 feesign; - u32 feepro; - u32 feehide; -} ADUC702x_FLASH_MMIO; - -typedef struct -{ +struct aduc702x_flash_bank { working_area_t *write_algorithm; -} aduc702x_flash_bank_t; - -flash_driver_t aduc702x_flash = -{ - .name = "aduc702x", - .register_commands = aduc702x_register_commands, - .flash_bank_command = aduc702x_flash_bank_command, - .erase = aduc702x_erase, - .protect = aduc702x_protect, - .write = aduc702x_write, - .probe = aduc702x_probe, - .auto_probe = aduc702x_probe, - .erase_check = default_flash_blank_check, - .protect_check = aduc702x_protect_check, - .info = aduc702x_info }; -static int aduc702x_register_commands(struct command_context_s *cmd_ctx) -{ - return ERROR_OK; -} - /* flash bank aduc702x 0 0 0 0 * The ADC7019-28 devices all have the same flash layout */ -static int aduc702x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank) +FLASH_BANK_COMMAND_HANDLER(aduc702x_flash_bank_command) { - aduc702x_flash_bank_t *nbank; + struct aduc702x_flash_bank *nbank; - nbank = malloc(sizeof(aduc702x_flash_bank_t)); + nbank = malloc(sizeof(struct aduc702x_flash_bank)); bank->base = 0x80000; bank->size = 0xF800; // top 4k not accessible @@ -109,13 +67,13 @@ static int aduc702x_flash_bank_command(struct command_context_s *cmd_ctx, char * static int aduc702x_build_sector_list(struct flash_bank_s *bank) { //aduc7026_flash_bank_t *aduc7026_info = bank->driver_priv; - + int i = 0; - u32 offset = 0; - + uint32_t offset = 0; + // sector size is 512 bank->num_sectors = bank->size / 512; - bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors); + bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); for (i = 0; i < bank->num_sectors; ++i) { bank->sectors[i].offset = offset; @@ -139,7 +97,7 @@ static int aduc702x_erase(struct flash_bank_s *bank, int first, int last) //int res; int x; int count; - //u32 v; + //uint32_t v; target_t *target = bank->target; aduc702x_set_write_enable(target, 1); @@ -193,17 +151,28 @@ static int aduc702x_protect(struct flash_bank_s *bank, int set, int first, int l return ERROR_FLASH_OPERATION_FAILED; } -static int aduc702x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) +/* If this fn returns ERROR_TARGET_RESOURCE_NOT_AVAILABLE, then the caller can fall + * back to another mechanism that does not require onboard RAM + * + * Caller should not check for other return values specifically + */ +static int aduc702x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count) { - aduc702x_flash_bank_t *aduc702x_info = bank->driver_priv; + struct aduc702x_flash_bank *aduc702x_info = bank->driver_priv; target_t *target = bank->target; - u32 buffer_size = 7000; + uint32_t buffer_size = 7000; working_area_t *source; - u32 address = bank->base + offset; - reg_param_t reg_params[6]; - armv4_5_algorithm_t armv4_5_info; + uint32_t address = bank->base + offset; + struct reg_param reg_params[6]; + struct armv4_5_algorithm armv4_5_info; int retval = ERROR_OK; - + + if (((count%2)!=0)||((offset%2)!=0)) + { + LOG_ERROR("write block must be multiple of two bytes in offset & length"); + return ERROR_FAIL; + } + /* parameters: r0 - address of source data (absolute) @@ -218,7 +187,7 @@ static int aduc702x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offse r6 - set to 2, used to write flash command */ - u32 aduc702x_flash_write_code[] = { + uint32_t aduc702x_flash_write_code[] = { //<_start>: 0xe3a05008, // mov r5, #8 ; 0x8 0xe5845004, // str r5, [r4, #4] @@ -240,7 +209,7 @@ static int aduc702x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offse //: 0xeafffffe // b 1003c }; - + /* flash write code */ if (target_alloc_working_area(target, sizeof(aduc702x_flash_write_code), &aduc702x_info->write_algorithm) != ERROR_OK) @@ -248,9 +217,13 @@ static int aduc702x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offse LOG_WARNING("no working area available, can't do block memory writes"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; }; - - target_write_buffer(target, aduc702x_info->write_algorithm->address, - sizeof(aduc702x_flash_write_code), (u8*)aduc702x_flash_write_code); + + retval=target_write_buffer(target, aduc702x_info->write_algorithm->address, + sizeof(aduc702x_flash_write_code), (uint8_t*)aduc702x_flash_write_code); + if (retval!=ERROR_OK) + { + return retval; + } /* memory buffer */ while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) @@ -261,73 +234,79 @@ static int aduc702x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offse /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */ if (aduc702x_info->write_algorithm) target_free_working_area(target, aduc702x_info->write_algorithm); - + LOG_WARNING("no large enough working area available, can't do block memory writes"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } } - + armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC; armv4_5_info.core_mode = ARMV4_5_MODE_SVC; armv4_5_info.core_state = ARMV4_5_STATE_ARM; - + init_reg_param(®_params[0], "r0", 32, PARAM_OUT); init_reg_param(®_params[1], "r1", 32, PARAM_OUT); init_reg_param(®_params[2], "r2", 32, PARAM_OUT); init_reg_param(®_params[3], "r3", 32, PARAM_IN); init_reg_param(®_params[4], "r4", 32, PARAM_OUT); - + while (count > 0) { - u32 thisrun_count = (count > (buffer_size / 2)) ? (buffer_size / 2) : count; - - target_write_buffer(target, source->address, thisrun_count * 2, buffer); + uint32_t thisrun_count = (count > buffer_size) ? buffer_size : count; + + retval=target_write_buffer(target, source->address, thisrun_count, buffer); + if (retval!=ERROR_OK) + { + break; + } buf_set_u32(reg_params[0].value, 0, 32, source->address); - buf_set_u32(reg_params[1].value, 0, 32, thisrun_count); + buf_set_u32(reg_params[1].value, 0, 32, thisrun_count/2); buf_set_u32(reg_params[2].value, 0, 32, address); buf_set_u32(reg_params[4].value, 0, 32, 0xFFFFF800); - if ((retval = target_run_algorithm(target, 0, NULL, 5, - reg_params, aduc702x_info->write_algorithm->address, - aduc702x_info->write_algorithm->address + sizeof(aduc702x_flash_write_code) - 4, + if ((retval = target_run_algorithm(target, 0, NULL, 5, + reg_params, aduc702x_info->write_algorithm->address, + aduc702x_info->write_algorithm->address + sizeof(aduc702x_flash_write_code) - 4, 10000, &armv4_5_info)) != ERROR_OK) { LOG_ERROR("error executing aduc702x flash write algorithm"); - retval = ERROR_FLASH_OPERATION_FAILED; break; } - - if ((buf_get_u32(reg_params[3].value, 0, 32) & 1) != 1) { - retval = ERROR_FLASH_OPERATION_FAILED; + + if ((buf_get_u32(reg_params[3].value, 0, 32) & 1) != 1) + { + /* FIX!!!! what does this mean??? replace w/sensible error message */ + LOG_ERROR("aduc702x detected error writing flash"); + retval = ERROR_FAIL; break; } - buffer += thisrun_count * 2; - address += thisrun_count * 2; + buffer += thisrun_count; + address += thisrun_count; count -= thisrun_count; } target_free_working_area(target, source); target_free_working_area(target, aduc702x_info->write_algorithm); - + destroy_reg_param(®_params[0]); destroy_reg_param(®_params[1]); destroy_reg_param(®_params[2]); destroy_reg_param(®_params[3]); destroy_reg_param(®_params[4]); - + return retval; } -/* All-JTAG, single-access method. Very slow. Used only if there is no +/* All-JTAG, single-access method. Very slow. Used only if there is no * working area available. */ -static int aduc702x_write_single(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) +static int aduc702x_write_single(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count) { - u32 x; - u8 b; + uint32_t x; + uint8_t b; target_t *target = bank->target; - + aduc702x_set_write_enable(target, 1); for (x = 0; x < count; x += 2) { @@ -363,7 +342,7 @@ static int aduc702x_write_single(struct flash_bank_s *bank, u8 *buffer, u32 offs return ERROR_OK; } -int aduc702x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) +int aduc702x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count) { int retval; @@ -373,23 +352,18 @@ int aduc702x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { /* if block write failed (no sufficient working area), - * use normal (slow) JTAG method */ + * use normal (slow) JTAG method */ LOG_WARNING("couldn't use block writes, falling back to single memory accesses"); if ((retval = aduc702x_write_single(bank, buffer, offset, count)) != ERROR_OK) { LOG_ERROR("slow write failed"); - return ERROR_FLASH_OPERATION_FAILED; + return ERROR_FLASH_OPERATION_FAILED; } } - else if (retval == ERROR_FLASH_OPERATION_FAILED) - { - LOG_ERROR("flash block writing failed"); - return ERROR_FLASH_OPERATION_FAILED; - } } - return ERROR_OK; + return retval; } static int aduc702x_probe(struct flash_bank_s *bank) @@ -399,7 +373,7 @@ static int aduc702x_probe(struct flash_bank_s *bank) static int aduc702x_info(struct flash_bank_s *bank, char *buf, int buf_size) { - snprintf(buf, buf_size, "aduc702x flash driver info" ); + snprintf(buf, buf_size, "aduc702x flash driver info"); return ERROR_OK; } @@ -420,7 +394,7 @@ static int aduc702x_set_write_enable(target_t *target, int enable) * so in some cases may slow things down without a usleep after the first read */ static int aduc702x_check_flash_completion(target_t* target, unsigned int timeout_ms) { - u8 v = 4; + uint8_t v = 4; long long endtime = timeval_ms() + timeout_ms; while (1) { @@ -436,3 +410,15 @@ static int aduc702x_check_flash_completion(target_t* target, unsigned int timeou else return ERROR_OK; } +struct flash_driver aduc702x_flash = { + .name = "aduc702x", + .flash_bank_command = &aduc702x_flash_bank_command, + .erase = &aduc702x_erase, + .protect = &aduc702x_protect, + .write = &aduc702x_write, + .probe = &aduc702x_probe, + .auto_probe = &aduc702x_probe, + .erase_check = &default_flash_blank_check, + .protect_check = &aduc702x_protect_check, + .info = &aduc702x_info + };