X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fflash%2Fstr9x.c;h=1160c7090a91ca36f2240cfdd0e97c21fca653d6;hb=f481deb58f586a72fc38253bbf89618a3611e4cc;hp=150f0f87353ce985da600ffb26196c88c77fcbbe;hpb=5d6c997b514e3a8cde971ae3090004ab54ba1d2f;p=fw%2Fopenocd diff --git a/src/flash/str9x.c b/src/flash/str9x.c index 150f0f873..1160c7090 100644 --- a/src/flash/str9x.c +++ b/src/flash/str9x.c @@ -2,6 +2,12 @@ * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * + * Copyright (C) 2008 by Spencer Oliver * + * spen@spen-soft.co.uk * + * + * Copyright (C) 2008 by Oyvind Harboe * + * oyvind.harboe@zylin.com * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -180,6 +186,7 @@ int str9x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char int str9x_protect_check(struct flash_bank_s *bank) { + int retval; str9x_flash_bank_t *str9x_info = bank->driver_priv; target_t *target = bank->target; @@ -189,6 +196,7 @@ int str9x_protect_check(struct flash_bank_s *bank) if (bank->target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } @@ -199,25 +207,46 @@ int str9x_protect_check(struct flash_bank_s *bank) if (str9x_info->bank1) { adr = bank1start + 0x18; - target_write_u16(target, adr, 0x90); - target_read_u16(target, adr, (u16*)&status); + if ((retval=target_write_u16(target, adr, 0x90))!=ERROR_OK) + { + return retval; + } + if ((retval=target_read_u16(target, adr, (u16*)&status))!=ERROR_OK) + { + return retval; + } } else { adr = bank1start + 0x14; - target_write_u16(target, adr, 0x90); - target_read_u32(target, adr, &status); + if ((retval=target_write_u16(target, adr, 0x90))!=ERROR_OK) + { + return retval; + } + if ((retval=target_read_u32(target, adr, &status))!=ERROR_OK) + { + return retval; + } } } else { adr = bank1start + 0x10; - target_write_u16(target, adr, 0x90); - target_read_u16(target, adr, (u16*)&status); + if ((retval=target_write_u16(target, adr, 0x90))!=ERROR_OK) + { + return retval; + } + if ((retval=target_read_u16(target, adr, (u16*)&status))!=ERROR_OK) + { + return retval; + } } /* read array command */ - target_write_u16(target, adr, 0xFF); + if ((retval=target_write_u16(target, adr, 0xFF))!=ERROR_OK) + { + return retval; + } for (i = 0; i < bank->num_sectors; i++) { @@ -236,41 +265,84 @@ int str9x_erase(struct flash_bank_s *bank, int first, int last) int i; u32 adr; u8 status; + u8 erase_cmd; if (bank->target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } + /* Check if we erase whole bank */ + if ((first == 0) && (last == (bank->num_sectors - 1))) + { + /* Optimize to run erase bank command instead of sector */ + erase_cmd = 0x80; + } + else + { + /* Erase sector command */ + erase_cmd = 0x20; + } + for (i = first; i <= last; i++) { + int retval; adr = bank->base + bank->sectors[i].offset; /* erase sectors */ - target_write_u16(target, adr, 0x20); - target_write_u16(target, adr, 0xD0); + if ((retval=target_write_u16(target, adr, erase_cmd))!=ERROR_OK) + { + return retval; + } + if ((retval=target_write_u16(target, adr, 0xD0))!=ERROR_OK) + { + return retval; + } /* get status */ - target_write_u16(target, adr, 0x70); - - while (1) { - target_read_u8(target, adr, &status); + if ((retval=target_write_u16(target, adr, 0x70))!=ERROR_OK) + { + return retval; + } + + int timeout; + for (timeout=0; timeout<1000; timeout++) { + if ((retval=target_read_u8(target, adr, &status))!=ERROR_OK) + { + return retval; + } if( status & 0x80 ) break; - usleep(1000); + alive_sleep(1); + } + if (timeout==1000) + { + LOG_ERROR("erase timed out"); + return ERROR_FAIL; } /* clear status, also clear read array */ - target_write_u16(target, adr, 0x50); + if ((retval=target_write_u16(target, adr, 0x50))!=ERROR_OK) + { + return retval; + } /* read array command */ - target_write_u16(target, adr, 0xFF); + if ((retval=target_write_u16(target, adr, 0xFF))!=ERROR_OK) + { + return retval; + } if( status & 0x22 ) { LOG_ERROR("error erasing flash bank, status: 0x%x", status); return ERROR_FLASH_OPERATION_FAILED; } + + /* If we ran erase bank command, we are finished */ + if (erase_cmd == 0x80) + break; } for (i = first; i <= last; i++) @@ -288,6 +360,7 @@ int str9x_protect(struct flash_bank_s *bank, int set, int first, int last) if (bank->target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } @@ -325,7 +398,7 @@ int str9x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou u32 address = bank->base + offset; reg_param_t reg_params[4]; armv4_5_algorithm_t armv4_5_info; - int retval; + int retval = ERROR_OK; u32 str9x_flash_write_code[] = { /* write: */ @@ -397,15 +470,15 @@ int str9x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou if ((retval = target->type->run_algorithm(target, 0, NULL, 4, reg_params, str9x_info->write_algorithm->address, str9x_info->write_algorithm->address + (18 * 4), 10000, &armv4_5_info)) != ERROR_OK) { - target_free_working_area(target, source); - target_free_working_area(target, str9x_info->write_algorithm); LOG_ERROR("error executing str9x flash write algorithm"); - return ERROR_FLASH_OPERATION_FAILED; + retval = ERROR_FLASH_OPERATION_FAILED; + break; } if (buf_get_u32(reg_params[3].value, 0, 32) != 0x80) { - return ERROR_FLASH_OPERATION_FAILED; + retval = ERROR_FLASH_OPERATION_FAILED; + break; } buffer += thisrun_count * 2; @@ -421,7 +494,7 @@ int str9x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 cou destroy_reg_param(®_params[2]); destroy_reg_param(®_params[3]); - return ERROR_OK; + return retval; } int str9x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) @@ -439,6 +512,7 @@ int str9x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) if (bank->target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } @@ -503,12 +577,19 @@ int str9x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) /* get status command */ target_write_u16(target, bank_adr, 0x70); - - while (1) { + + int timeout; + for (timeout=0; timeout<1000; timeout++) + { target_read_u8(target, bank_adr, &status); if( status & 0x80 ) break; - usleep(1000); + alive_sleep(1); + } + if (timeout==1000) + { + LOG_ERROR("write timed out"); + return ERROR_FAIL; } /* clear status reg and read array */ @@ -546,11 +627,18 @@ int str9x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) /* query status command */ target_write_u16(target, bank_adr, 0x70); - while (1) { + int timeout; + for (timeout=0; timeout<1000; timeout++) + { target_read_u8(target, bank_adr, &status); if( status & 0x80 ) break; - usleep(1000); + alive_sleep(1); + } + if (timeout==1000) + { + LOG_ERROR("write timed out"); + return ERROR_FAIL; } /* clear status reg and read array */ @@ -606,6 +694,7 @@ int str9x_handle_flash_config_command(struct command_context_s *cmd_ctx, char *c if (bank->target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; }