X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Faduc702x.c;h=643705cae287c0df6cf1cc0ec31626c1ab99ca0b;hp=200ab4c7d25697557ca7b470e394773c4ccd5dde;hb=db094c2e60176b3c63ce788159b04a7024ad1010;hpb=2e779198535580515dfa9c8bfe1f3fe08abdb84b diff --git a/src/flash/aduc702x.c b/src/flash/aduc702x.c index 200ab4c7d2..643705cae2 100644 --- a/src/flash/aduc702x.c +++ b/src/flash/aduc702x.c @@ -27,21 +27,12 @@ #include "armv4_5.h" #include "binarybuffer.h" #include "time_support.h" +#include "algorithm.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, uint8_t *buffer, uint32_t offset, uint32_t count); -static int aduc702x_write_single(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count); -static int aduc702x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t 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); +static int aduc702x_build_sector_list(struct flash_bank *bank); +static int aduc702x_check_flash_completion(struct target* target, unsigned int timeout_ms); +static int aduc702x_set_write_enable(struct target *target, int enable); #define ADUC702x_FLASH 0xfffff800 #define ADUC702x_FLASH_FEESTA (0*4) @@ -53,49 +44,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 { - uint32_t feesta; - uint32_t feemod; - uint32_t feecon; - uint32_t feedat; - uint32_t feeadr; - uint32_t feesign; - uint32_t feepro; - uint32_t feehide; -} ADUC702x_FLASH_MMIO; - -typedef struct -{ - 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 +struct aduc702x_flash_bank { + struct working_area *write_algorithm; }; -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 @@ -106,16 +65,16 @@ static int aduc702x_flash_bank_command(struct command_context_s *cmd_ctx, char * return ERROR_OK; } -static int aduc702x_build_sector_list(struct flash_bank_s *bank) +static int aduc702x_build_sector_list(struct flash_bank *bank) { - //aduc7026_flash_bank_t *aduc7026_info = bank->driver_priv; + //aduc7026_struct flash_bank *aduc7026_info = bank->driver_priv; int i = 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; @@ -128,19 +87,19 @@ static int aduc702x_build_sector_list(struct flash_bank_s *bank) return ERROR_OK; } -static int aduc702x_protect_check(struct flash_bank_s *bank) +static int aduc702x_protect_check(struct flash_bank *bank) { printf("aduc702x_protect_check not implemented yet.\n"); return ERROR_OK; } -static int aduc702x_erase(struct flash_bank_s *bank, int first, int last) +static int aduc702x_erase(struct flash_bank *bank, int first, int last) { //int res; int x; int count; //uint32_t v; - target_t *target = bank->target; + struct target *target = bank->target; aduc702x_set_write_enable(target, 1); @@ -187,23 +146,34 @@ static int aduc702x_erase(struct flash_bank_s *bank, int first, int last) return ERROR_OK; } -static int aduc702x_protect(struct flash_bank_s *bank, int set, int first, int last) +static int aduc702x_protect(struct flash_bank *bank, int set, int first, int last) { printf("aduc702x_protect not implemented yet.\n"); return ERROR_FLASH_OPERATION_FAILED; } -static int aduc702x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t 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 *bank, uint8_t *buffer, uint32_t offset, uint32_t count) { - aduc702x_flash_bank_t *aduc702x_info = bank->driver_priv; - target_t *target = bank->target; + struct aduc702x_flash_bank *aduc702x_info = bank->driver_priv; + struct target *target = bank->target; uint32_t buffer_size = 7000; - working_area_t *source; + struct working_area *source; uint32_t address = bank->base + offset; - reg_param_t reg_params[6]; - armv4_5_algorithm_t armv4_5_info; + 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) @@ -249,8 +219,12 @@ static int aduc702x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; }; - target_write_buffer(target, aduc702x_info->write_algorithm->address, + 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) @@ -279,12 +253,16 @@ static int aduc702x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint while (count > 0) { - uint32_t thisrun_count = (count > (buffer_size / 2)) ? (buffer_size / 2) : count; + uint32_t thisrun_count = (count > buffer_size) ? buffer_size : count; - target_write_buffer(target, source->address, thisrun_count * 2, buffer); + 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); @@ -294,17 +272,19 @@ static int aduc702x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint 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; } @@ -322,11 +302,11 @@ static int aduc702x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint /* 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, uint8_t *buffer, uint32_t offset, uint32_t count) +static int aduc702x_write_single(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count) { uint32_t x; uint8_t b; - target_t *target = bank->target; + struct target *target = bank->target; aduc702x_set_write_enable(target, 1); @@ -363,7 +343,7 @@ static int aduc702x_write_single(struct flash_bank_s *bank, uint8_t *buffer, uin return ERROR_OK; } -int aduc702x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count) +int aduc702x_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count) { int retval; @@ -382,22 +362,17 @@ int aduc702x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, 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) +static int aduc702x_probe(struct flash_bank *bank) { return ERROR_OK; } -static int aduc702x_info(struct flash_bank_s *bank, char *buf, int buf_size) +static int aduc702x_info(struct flash_bank *bank, char *buf, int buf_size) { snprintf(buf, buf_size, "aduc702x flash driver info"); return ERROR_OK; @@ -405,7 +380,7 @@ static int aduc702x_info(struct flash_bank_s *bank, char *buf, int buf_size) /* sets FEEMOD bit 3 * enable = 1 enables writes & erases, 0 disables them */ -static int aduc702x_set_write_enable(target_t *target, int enable) +static int aduc702x_set_write_enable(struct target *target, int enable) { // don't bother to preserve int enable bit here target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEMOD, enable ? 8 : 0); @@ -418,7 +393,7 @@ static int aduc702x_set_write_enable(target_t *target, int enable) * * this function sleeps 1ms between checks (after the first one), * 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) +static int aduc702x_check_flash_completion(struct target* target, unsigned int timeout_ms) { uint8_t v = 4; @@ -436,3 +411,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 + };