X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fflash%2Fat91sam7.c;h=7aba6db44d638754956361893911e67095d3b6f9;hb=5aa93a5e8a9290cb4eabb6044406552891c2ef80;hp=cf3547942d39638ac95dd4162327c762b2c67b5c;hpb=1796e1602e9ffe1cbf35f1b001cb6a534bb2f738;p=openocd diff --git a/src/flash/at91sam7.c b/src/flash/at91sam7.c index cf354794..7aba6db4 100644 --- a/src/flash/at91sam7.c +++ b/src/flash/at91sam7.c @@ -57,6 +57,7 @@ int at91sam7_erase(struct flash_bank_s *bank, int first, int last); int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last); int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count); int at91sam7_probe(struct flash_bank_s *bank); +int at91sam7_auto_probe(struct flash_bank_s *bank); int at91sam7_erase_check(struct flash_bank_s *bank); int at91sam7_protect_check(struct flash_bank_s *bank); int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size); @@ -76,6 +77,7 @@ flash_driver_t at91sam7_flash = .protect = at91sam7_protect, .write = at91sam7_write, .probe = at91sam7_probe, + .auto_probe = at91sam7_probe, .erase_check = at91sam7_erase_check, .protect_check = at91sam7_protect_check, .info = at91sam7_info @@ -143,7 +145,7 @@ u32 at91sam7_get_flash_status(flash_bank_t *bank, u8 flashplane) return fsr; } -/** Read clock configuration and set at91sam7_info->usec_clocks*/ +/* Read clock configuration and set at91sam7_info->usec_clocks*/ void at91sam7_read_clock_info(flash_bank_t *bank) { at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; @@ -178,7 +180,7 @@ void at91sam7_read_clock_info(flash_bank_t *bank) case 2: /* Reserved */ break; - case 3: /* PLL Clock */ + case 3: /* PLL Clock */ if (mcfr & CKGR_MCFR_MAINRDY) { target_read_u32(target, CKGR_PLLR, &pllr); @@ -241,7 +243,7 @@ void at91sam7_set_flash_mode(flash_bank_t *bank, u8 flashplane, int mode) if (at91sam7_info->mck_freq > 30000000ul) fws = 1; - DEBUG("fmcn[%i]: %i", flashplane, fmcn); + LOG_DEBUG("fmcn[%i]: %i", flashplane, fmcn); fmr = fmcn << 16 | fws << 8; target_write_u32(target, MC_FMR[flashplane], fmr); } @@ -255,21 +257,21 @@ u32 at91sam7_wait_status_busy(flash_bank_t *bank, u8 flashplane, u32 waitbits, i while ((!((status = at91sam7_get_flash_status(bank,flashplane)) & waitbits)) && (timeout-- > 0)) { - DEBUG("status[%i]: 0x%x", flashplane, status); + LOG_DEBUG("status[%i]: 0x%x", flashplane, status); usleep(1000); } - DEBUG("status[%i]: 0x%x", flashplane, status); + LOG_DEBUG("status[%i]: 0x%x", flashplane, status); if (status & 0x0C) { - ERROR("status register: 0x%x", status); + LOG_ERROR("status register: 0x%x", status); if (status & 0x4) - ERROR("Lock Error Bit Detected, Operation Abort"); + LOG_ERROR("Lock Error Bit Detected, Operation Abort"); if (status & 0x8) - ERROR("Invalid command and/or bad keyword, Operation Abort"); + LOG_ERROR("Invalid command and/or bad keyword, Operation Abort"); if (status & 0x10) - ERROR("Security Bit Set, Operation Abort"); + LOG_ERROR("Security Bit Set, Operation Abort"); } return status; @@ -285,7 +287,7 @@ int at91sam7_flash_command(struct flash_bank_s *bank, u8 flashplane, u8 cmd, u16 fcr = (0x5A<<24) | ((pagen&0x3FF)<<8) | cmd; target_write_u32(target, MC_FCR[flashplane], fcr); - DEBUG("Flash command: 0x%x, flashplane: %i, pagenumber:%u", fcr, flashplane, pagen); + LOG_DEBUG("Flash command: 0x%x, flashplane: %i, pagenumber:%u", fcr, flashplane, pagen); if ((at91sam7_info->cidr_arch == 0x60)&&((cmd==SLB)|(cmd==CLB))) { @@ -311,18 +313,16 @@ int at91sam7_read_part_info(struct flash_bank_s *bank) target_t *target = bank->target; u32 cidr, status; int sectornum; - - if (bank->target->state != TARGET_HALTED) - { - return ERROR_TARGET_NOT_HALTED; - } + + if (at91sam7_info->cidr != 0) + return ERROR_OK; /* already probed, multiple probes may cause memory leak, not allowed */ /* Read and parse chip identification register */ target_read_u32(target, DBGU_CIDR, &cidr); if (cidr == 0) { - WARNING("Cannot identify target as an AT91SAM"); + LOG_WARNING("Cannot identify target as an AT91SAM"); return ERROR_FLASH_OPERATION_FAILED; } @@ -363,7 +363,7 @@ int at91sam7_read_part_info(struct flash_bank_s *bank) - DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch ); + LOG_DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch ); /* Read main and master clock freqency register */ at91sam7_read_clock_info(bank); @@ -384,7 +384,7 @@ int at91sam7_read_part_info(struct flash_bank_s *bank) at91sam7_info->target_name = "AT91SAM7S512"; at91sam7_info->num_planes = 2; if (at91sam7_info->num_planes != bank->num_sectors) - WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");; + LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");; at91sam7_info->num_lockbits = 2*16; at91sam7_info->pagesize = 256; at91sam7_info->pages_in_lockregion = 64; @@ -437,7 +437,7 @@ int at91sam7_read_part_info(struct flash_bank_s *bank) at91sam7_info->target_name = "AT91SAM7XC512"; at91sam7_info->num_planes = 2; if (at91sam7_info->num_planes != bank->num_sectors) - WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");; + LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");; at91sam7_info->num_lockbits = 2*16; at91sam7_info->pagesize = 256; at91sam7_info->pages_in_lockregion = 64; @@ -465,8 +465,8 @@ int at91sam7_read_part_info(struct flash_bank_s *bank) if (at91sam7_info->cidr_arch == 0x72 ) { - at91sam7_info->num_nvmbits = 2; - at91sam7_info->nvmbits = (status>>8)&0x03; + at91sam7_info->num_nvmbits = 3; + at91sam7_info->nvmbits = (status>>8)&0x07; bank->base = 0x100000; bank->bus_width = 4; if (bank->size==0x80000) /* AT91SAM7SE512 */ @@ -474,7 +474,7 @@ int at91sam7_read_part_info(struct flash_bank_s *bank) at91sam7_info->target_name = "AT91SAM7SE512"; at91sam7_info->num_planes = 2; if (at91sam7_info->num_planes != bank->num_sectors) - WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");; + LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");; at91sam7_info->num_lockbits = 32; at91sam7_info->pagesize = 256; at91sam7_info->pages_in_lockregion = 64; @@ -511,12 +511,12 @@ int at91sam7_read_part_info(struct flash_bank_s *bank) at91sam7_info->target_name = "AT91SAM7X512"; at91sam7_info->num_planes = 2; if (at91sam7_info->num_planes != bank->num_sectors) - WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");; + LOG_WARNING("Internal error: Number of flash planes and erase sectors does not match, please report");; at91sam7_info->num_lockbits = 32; at91sam7_info->pagesize = 256; at91sam7_info->pages_in_lockregion = 64; at91sam7_info->num_pages = 2*16*64; - DEBUG("Support for AT91SAM7X512 is experimental in this version!"); + LOG_DEBUG("Support for AT91SAM7X512 is experimental in this version!"); } if (bank->size==0x40000) /* AT91SAM7X256 */ { @@ -556,9 +556,8 @@ int at91sam7_read_part_info(struct flash_bank_s *bank) return ERROR_OK; } - WARNING("at91sam7 flash only tested for AT91SAM7Sxx series"); - - return ERROR_OK; + LOG_WARNING("at91sam7 flash only tested for AT91SAM7Sxx series"); + return ERROR_OK; } int at91sam7_erase_check(struct flash_bank_s *bank) @@ -584,13 +583,12 @@ int at91sam7_protect_check(struct flash_bank_s *bank) if (at91sam7_info->cidr == 0) { - at91sam7_read_part_info(bank); + return ERROR_FLASH_BANK_NOT_PROBED; } - if (at91sam7_info->cidr == 0) + if (bank->target->state != TARGET_HALTED) { - WARNING("Cannot identify target as an AT91SAM"); - return ERROR_FLASH_OPERATION_FAILED; + return ERROR_TARGET_NOT_HALTED; } for (flashplane=0;flashplanenum_planes;flashplane++) @@ -611,7 +609,7 @@ int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, ch if (argc < 6) { - WARNING("incomplete flash_bank at91sam7 configuration"); + LOG_WARNING("incomplete flash_bank at91sam7 configuration"); return ERROR_FLASH_BANK_INVALID; } @@ -631,27 +629,21 @@ int at91sam7_erase(struct flash_bank_s *bank, int first, int last) at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; u8 flashplane; - if (bank->target->state != TARGET_HALTED) - { - return ERROR_TARGET_NOT_HALTED; - } - if (at91sam7_info->cidr == 0) { - at91sam7_read_part_info(bank); + return ERROR_FLASH_BANK_NOT_PROBED; } - if (at91sam7_info->cidr == 0) + if (bank->target->state != TARGET_HALTED) { - WARNING("Cannot identify target as an AT91SAM"); - return ERROR_FLASH_OPERATION_FAILED; - } + return ERROR_TARGET_NOT_HALTED; + } if ((first < 0) || (last < first) || (last >= bank->num_sectors)) { if ((first == 0) && (last == (at91sam7_info->num_lockbits-1))) { - WARNING("Sector numbers based on lockbit count, probably a deprecated script"); + LOG_WARNING("Sector numbers based on lockbit count, probably a deprecated script"); last = bank->num_sectors-1; } else return ERROR_FLASH_SECTOR_INVALID; @@ -680,6 +672,11 @@ int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last) at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; + if (at91sam7_info->cidr == 0) + { + return ERROR_FLASH_BANK_NOT_PROBED; + } + if (bank->target->state != TARGET_HALTED) { return ERROR_TARGET_NOT_HALTED; @@ -690,17 +687,6 @@ int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last) return ERROR_FLASH_SECTOR_INVALID; } - if (at91sam7_info->cidr == 0) - { - at91sam7_read_part_info(bank); - } - - if (at91sam7_info->cidr == 0) - { - WARNING("Cannot identify target as an AT91SAM"); - return ERROR_FLASH_OPERATION_FAILED; - } - at91sam7_read_clock_info(bank); for (lockregion=first;lockregion<=last;lockregion++) @@ -735,22 +721,16 @@ int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) u32 first_page, last_page, pagen, buffer_pos; u8 flashplane; - if (bank->target->state != TARGET_HALTED) - { - return ERROR_TARGET_NOT_HALTED; - } - if (at91sam7_info->cidr == 0) { - at91sam7_read_part_info(bank); + return ERROR_FLASH_BANK_NOT_PROBED; } - if (at91sam7_info->cidr == 0) + if (bank->target->state != TARGET_HALTED) { - WARNING("Cannot identify target as an AT91SAM"); - return ERROR_FLASH_OPERATION_FAILED; + return ERROR_TARGET_NOT_HALTED; } - + if (offset + count > bank->size) return ERROR_FLASH_DST_OUT_OF_BANK; @@ -758,7 +738,7 @@ int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) if (offset % dst_min_alignment) { - WARNING("offset 0x%x breaks required alignment 0x%x", offset, dst_min_alignment); + LOG_WARNING("offset 0x%x breaks required alignment 0x%x", offset, dst_min_alignment); return ERROR_FLASH_DST_BREAKS_ALIGNMENT; } @@ -768,7 +748,7 @@ int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) first_page = offset/dst_min_alignment; last_page = CEIL(offset + count, dst_min_alignment); - DEBUG("first_page: %i, last_page: %i, count %i", first_page, last_page, count); + LOG_DEBUG("first_page: %i, last_page: %i, count %i", first_page, last_page, count); at91sam7_read_clock_info(bank); @@ -793,7 +773,7 @@ int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) { return ERROR_FLASH_OPERATION_FAILED; } - DEBUG("Write flash plane:%i page number:%i", flashplane, pagen); + LOG_DEBUG("Write flash plane:%i page number:%i", flashplane, pagen); } return ERROR_OK; @@ -806,34 +786,34 @@ int at91sam7_probe(struct flash_bank_s *bank) * if this is an at91sam7, it has the configured flash */ at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; + int retval; - if (at91sam7_info->cidr == 0) + if (at91sam7_info->cidr != 0) { - at91sam7_read_part_info(bank); + return ERROR_OK; /* already probed */ } - if (at91sam7_info->cidr == 0) + if (bank->target->state != TARGET_HALTED) { - WARNING("Cannot identify target as an AT91SAM"); - return ERROR_FLASH_OPERATION_FAILED; + return ERROR_TARGET_NOT_HALTED; } + + retval = at91sam7_read_part_info(bank); + if (retval != ERROR_OK) + return retval; return ERROR_OK; } + int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size) { int printed, flashplane; at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; - at91sam7_read_part_info(bank); - if (at91sam7_info->cidr == 0) { - printed = snprintf(buf, buf_size, "Cannot identify target as an AT91SAM\n"); - buf += printed; - buf_size -= printed; - return ERROR_FLASH_OPERATION_FAILED; + return ERROR_FLASH_BANK_NOT_PROBED; } printed = snprintf(buf, buf_size, "\nat91sam7 information: Chip is %s\n",at91sam7_info->target_name); @@ -869,7 +849,7 @@ int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size) buf_size -= printed; } - printed = snprintf(buf, buf_size, "securitybit: %i, nvmbits: 0x%1.1x\n", at91sam7_info->securitybit, at91sam7_info->nvmbits); + printed = snprintf(buf, buf_size, "securitybit: %i, nvmbits(%i): 0x%1.1x\n", at91sam7_info->securitybit, at91sam7_info->num_nvmbits, at91sam7_info->nvmbits); buf += printed; buf_size -= printed; @@ -877,7 +857,7 @@ int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size) } /* -* On AT91SAM7S: When the gpnmv bits are set with +* On AT91SAM7S: When the gpnvm bits are set with * > at91sam7 gpnvm 0 bitnr set * the changes are not visible in the flash controller status register MC_FSR * until the processor has been reset. @@ -894,6 +874,7 @@ int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, u32 status; char *value; at91sam7_flash_bank_t *at91sam7_info; + int retval; if (argc < 3) { @@ -901,32 +882,48 @@ int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, return ERROR_OK; } - bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0)); + bank = get_flash_bank_by_num_noprobe(strtoul(args[0], NULL, 0)); bit = atoi(args[1]); value = args[2]; - if (!bank) + if (bank == NULL) { - command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]); - return ERROR_OK; + return ERROR_FLASH_BANK_INVALID; + } + + if (bank->driver != &at91sam7_flash) + { + command_print(cmd_ctx, "not an at91sam7 flash bank '%s'", args[0]); + return ERROR_FLASH_BANK_INVALID; + } + + if (strcmp(value, "set") == 0) + { + flashcmd = SGPB; + } + else if (strcmp(value, "clear") == 0) + { + flashcmd = CGPB; + } + else + { + return ERROR_COMMAND_SYNTAX_ERROR; } at91sam7_info = bank->driver_priv; if (bank->target->state != TARGET_HALTED) { + LOG_ERROR("target has to be halted to perform flash operation"); return ERROR_TARGET_NOT_HALTED; } if (at91sam7_info->cidr == 0) { - at91sam7_read_part_info(bank); - } - - if (at91sam7_info->cidr == 0) - { - WARNING("Cannot identify target as an AT91SAM"); - return ERROR_FLASH_OPERATION_FAILED; + retval = at91sam7_read_part_info(bank); + if (retval != ERROR_OK) { + return retval; + } } if ((bit<0) || (at91sam7_info->num_nvmbits <= bit)) @@ -935,20 +932,6 @@ int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, return ERROR_OK; } - if (strcmp(value, "set") == 0) - { - flashcmd = SGPB; - } - else if (strcmp(value, "clear") == 0) - { - flashcmd = CGPB; - } - else - { - command_print(cmd_ctx, "usage: at91sam7 gpnvm "); - return ERROR_OK; - } - /* Configure the flash controller timing */ at91sam7_read_clock_info(bank); at91sam7_set_flash_mode(bank, 0, FMR_TIMING_NVBITS); @@ -959,7 +942,7 @@ int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, } status = at91sam7_get_flash_status(bank, 0); - DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n",flashcmd,bit,status); + LOG_DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value 0x%x, status 0x%x \n",flashcmd,bit,status); at91sam7_info->nvmbits = (status>>8)&((1<num_nvmbits)-1); return ERROR_OK;