.protect = at91sam7_protect,
.write = at91sam7_write,
.probe = at91sam7_probe,
- .auto_probe = at91sam7_auto_probe,
+ .auto_probe = at91sam7_probe,
.erase_check = at91sam7_erase_check,
.protect_check = at91sam7_protect_check,
.info = at91sam7_info
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;
case 2: /* Reserved */
break;
- case 3: /* PLL Clock */
+ case 3: /* PLL Clock */
if (mcfr & CKGR_MCFR_MAINRDY)
{
target_read_u32(target, CKGR_PLLR, &pllr);
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);
}
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;
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)))
{
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;
}
- 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);
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;
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;
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 */
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;
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 */
{
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)
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;flashplane<at91sam7_info->num_planes;flashplane++)
if (argc < 6)
{
- WARNING("incomplete flash_bank at91sam7 configuration");
+ LOG_WARNING("incomplete flash_bank at91sam7 configuration");
return ERROR_FLASH_BANK_INVALID;
}
at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t));
bank->driver_priv = at91sam7_info;
- at91sam7_info->probed = 0;
/* part wasn't probed for info yet */
at91sam7_info->cidr = 0;
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;
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;
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++)
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;
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;
}
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);
{
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;
* if this is an at91sam7, it has the configured flash
*/
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
- at91sam7_info->probed = 0;
+ 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;
}
-
- at91sam7_info->probed = 1;
+
+ retval = at91sam7_read_part_info(bank);
+ if (retval != ERROR_OK)
+ return retval;
return ERROR_OK;
}
-int at91sam7_auto_probe(struct flash_bank_s *bank)
-{
- at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
- if (at91sam7_info->probed)
- return ERROR_OK;
- return at91sam7_probe(bank);
-}
-
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);
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;
}
/*
-* 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.
u32 status;
char *value;
at91sam7_flash_bank_t *at91sam7_info;
+ int retval;
if (argc < 3)
{
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))
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 <num> <bit> <set|clear>");
- return ERROR_OK;
- }
-
/* Configure the flash controller timing */
at91sam7_read_clock_info(bank);
at91sam7_set_flash_mode(bank, 0, FMR_TIMING_NVBITS);
}
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<<at91sam7_info->num_nvmbits)-1);
return ERROR_OK;