X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fflash%2Fnor%2Flpc2000.c;h=f12eef7e4ce68fc8830773f6c57da57dfb87d6b8;hb=HEAD;hp=9da5da2cac282eebbb7e262df4483e3d7972f0e9;hpb=47b8cf84202bf792cf66fbfa01169e9592236b8a;p=openocd.git diff --git a/src/flash/nor/lpc2000.c b/src/flash/nor/lpc2000.c index 9da5da2cac..f12eef7e4c 100644 --- a/src/flash/nor/lpc2000.c +++ b/src/flash/nor/lpc2000.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * @@ -12,18 +14,8 @@ * by Nemui Trinomius * * nemuisan_kawausogasuki@live.jp * * * - * 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 * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * + * LPC8N04/HNS31xx support Copyright (C) 2018 * + * by Jean-Christian de Rivaz jcdr [at] innodelec [dot] ch * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -38,7 +30,7 @@ /** * @file - * flash programming support for NXP LPC8xx,LPC1xxx,LPC4xxx,LP5410x and LPC2xxx devices. + * flash programming support for NXP LPC8xx,LPC1xxx,LPC4xxx,LP5410x,LPC2xxx and NHS31xx devices. * * @todo Provide a way to update CCLK after declaring the flash bank. The value which is correct after chip reset will * rarely still work right after the clocks switch to use the PLL (e.g. 4MHz --> 100 MHz). @@ -77,6 +69,9 @@ * lpc800: * - 810 | 1 | 2 (tested with LPC810/LPC811/LPC812) * - 822 | 4 (tested with LPC824) + * - 8N04 + * - NHS31xx (tested with NHS3100) + * - 844 | 5 (tested with LPC845) * * lpc1100: * - 11xx @@ -111,6 +106,8 @@ * - 408x * - 81x * - 82x + * - 8N04 + * - NHS31xx */ /* Part IDs for autodetection */ @@ -257,20 +254,34 @@ #define LPC824_201 0x00008241 #define LPC824_201_1 0x00008242 +#define LPC8N04 0x00008A04 +#define NHS3100 0x4e310020 +#define NHS3152 0x4e315220 +#define NHS3153 0x4e315320 /* Only specified in Rev.1 of the datasheet */ + +#define LPC844_201 0x00008441 +#define LPC844_201_1 0x00008442 +#define LPC844_201_2 0x00008444 + +#define LPC845_301 0x00008451 +#define LPC845_301_1 0x00008452 +#define LPC845_301_2 0x00008453 +#define LPC845_301_3 0x00008454 + #define IAP_CODE_LEN 0x34 -#define LPC11xx_REG_SECTORS 24 +#define LPC11XX_REG_SECTORS 24 typedef enum { - lpc2000_v1, - lpc2000_v2, - lpc1700, - lpc4300, - lpc800, - lpc1100, - lpc1500, - lpc54100, - lpc_auto, + LPC2000_V1, + LPC2000_V2, + LPC1700, + LPC4300, + LPC800, + LPC1100, + LPC1500, + LPC54100, + LPC_AUTO, } lpc2000_variant; struct lpc2000_flash_bank { @@ -282,6 +293,7 @@ struct lpc2000_flash_bank { int checksum_vector; uint32_t iap_max_stack; uint32_t lpc4300_bank; + uint32_t iap_entry_alternative; bool probed; }; @@ -319,7 +331,7 @@ static int lpc2000_build_sector_list(struct flash_bank *bank) /* default to a 4096 write buffer */ lpc2000_info->cmd51_max_buffer = 4096; - if (lpc2000_info->variant == lpc2000_v1) { + if (lpc2000_info->variant == LPC2000_V1) { lpc2000_info->cmd51_dst_boundary = 512; lpc2000_info->checksum_vector = 5; lpc2000_info->iap_max_stack = 128; @@ -364,7 +376,7 @@ static int lpc2000_build_sector_list(struct flash_bank *bank) LOG_ERROR("BUG: unknown bank->size encountered"); exit(-1); } - } else if (lpc2000_info->variant == lpc2000_v2) { + } else if (lpc2000_info->variant == LPC2000_V2) { lpc2000_info->cmd51_dst_boundary = 256; lpc2000_info->checksum_vector = 5; lpc2000_info->iap_max_stack = 128; @@ -409,7 +421,7 @@ static int lpc2000_build_sector_list(struct flash_bank *bank) bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - for (int i = 0; i < bank->num_sectors; i++) { + for (unsigned int i = 0; i < bank->num_sectors; i++) { if (i < 8) { bank->sectors[i].offset = offset; bank->sectors[i].size = 4 * 1024; @@ -430,7 +442,7 @@ static int lpc2000_build_sector_list(struct flash_bank *bank) bank->sectors[i].is_protected = 1; } } - } else if (lpc2000_info->variant == lpc1700) { + } else if (lpc2000_info->variant == LPC1700) { lpc2000_info->cmd51_dst_boundary = 256; lpc2000_info->checksum_vector = 7; lpc2000_info->iap_max_stack = 128; @@ -471,7 +483,7 @@ static int lpc2000_build_sector_list(struct flash_bank *bank) bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - for (int i = 0; i < bank->num_sectors; i++) { + for (unsigned int i = 0; i < bank->num_sectors; i++) { bank->sectors[i].offset = offset; /* sectors 0-15 are 4kB-sized, 16 and above are 32kB-sized for LPC17xx/LPC40xx devices */ bank->sectors[i].size = (i < 16) ? 4 * 1024 : 32 * 1024; @@ -479,7 +491,7 @@ static int lpc2000_build_sector_list(struct flash_bank *bank) bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 1; } - } else if (lpc2000_info->variant == lpc4300) { + } else if (lpc2000_info->variant == LPC4300) { lpc2000_info->cmd51_dst_boundary = 512; lpc2000_info->checksum_vector = 7; lpc2000_info->iap_max_stack = 208; @@ -501,7 +513,7 @@ static int lpc2000_build_sector_list(struct flash_bank *bank) bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - for (int i = 0; i < bank->num_sectors; i++) { + for (unsigned int i = 0; i < bank->num_sectors; i++) { bank->sectors[i].offset = offset; /* sectors 0-7 are 8kB-sized, 8 and above are 64kB-sized for LPC43xx devices */ bank->sectors[i].size = (i < 8) ? 8 * 1024 : 64 * 1024; @@ -510,7 +522,7 @@ static int lpc2000_build_sector_list(struct flash_bank *bank) bank->sectors[i].is_protected = 1; } - } else if (lpc2000_info->variant == lpc800) { + } else if (lpc2000_info->variant == LPC800) { lpc2000_info->cmd51_dst_boundary = 64; lpc2000_info->checksum_vector = 7; lpc2000_info->iap_max_stack = 208; /* 148byte for LPC81x,208byte for LPC82x. */ @@ -526,10 +538,18 @@ static int lpc2000_build_sector_list(struct flash_bank *bank) case 16 * 1024: bank->num_sectors = 16; break; + case 30 * 1024: + lpc2000_info->cmd51_max_buffer = 1024; /* For LPC8N04 and NHS31xx, have 8kB of SRAM */ + bank->num_sectors = 30; /* There have only 30kB of writable Flash out of 32kB */ + break; case 32 * 1024: lpc2000_info->cmd51_max_buffer = 1024; /* For LPC824, has 8kB of SRAM */ bank->num_sectors = 32; break; + case 64 * 1024: + lpc2000_info->cmd51_max_buffer = 1024; /* For LPC844, has 8kB of SRAM */ + bank->num_sectors = 64; + break; default: LOG_ERROR("BUG: unknown bank->size encountered"); exit(-1); @@ -537,7 +557,7 @@ static int lpc2000_build_sector_list(struct flash_bank *bank) bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - for (int i = 0; i < bank->num_sectors; i++) { + for (unsigned int i = 0; i < bank->num_sectors; i++) { bank->sectors[i].offset = offset; /* all sectors are 1kB-sized for LPC8xx devices */ bank->sectors[i].size = 1 * 1024; @@ -546,7 +566,7 @@ static int lpc2000_build_sector_list(struct flash_bank *bank) bank->sectors[i].is_protected = 1; } - } else if (lpc2000_info->variant == lpc1100) { + } else if (lpc2000_info->variant == LPC1100) { lpc2000_info->cmd51_dst_boundary = 256; lpc2000_info->checksum_vector = 7; lpc2000_info->iap_max_stack = 128; @@ -559,24 +579,24 @@ static int lpc2000_build_sector_list(struct flash_bank *bank) unsigned int large_sectors = 0; unsigned int normal_sectors = bank->size / 4096; - if (normal_sectors > LPC11xx_REG_SECTORS) { - large_sectors = (normal_sectors - LPC11xx_REG_SECTORS) / 8; - normal_sectors = LPC11xx_REG_SECTORS; + if (normal_sectors > LPC11XX_REG_SECTORS) { + large_sectors = (normal_sectors - LPC11XX_REG_SECTORS) / 8; + normal_sectors = LPC11XX_REG_SECTORS; } bank->num_sectors = normal_sectors + large_sectors; bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - for (int i = 0; i < bank->num_sectors; i++) { + for (unsigned int i = 0; i < bank->num_sectors; i++) { bank->sectors[i].offset = offset; - bank->sectors[i].size = (i < LPC11xx_REG_SECTORS ? 4 : 32) * 1024; + bank->sectors[i].size = (i < LPC11XX_REG_SECTORS ? 4 : 32) * 1024; offset += bank->sectors[i].size; bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 1; } - } else if (lpc2000_info->variant == lpc1500) { + } else if (lpc2000_info->variant == LPC1500) { lpc2000_info->cmd51_dst_boundary = 256; lpc2000_info->checksum_vector = 7; lpc2000_info->iap_max_stack = 128; @@ -598,7 +618,7 @@ static int lpc2000_build_sector_list(struct flash_bank *bank) bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - for (int i = 0; i < bank->num_sectors; i++) { + for (unsigned int i = 0; i < bank->num_sectors; i++) { bank->sectors[i].offset = offset; /* all sectors are 4kB-sized */ bank->sectors[i].size = 4 * 1024; @@ -607,7 +627,7 @@ static int lpc2000_build_sector_list(struct flash_bank *bank) bank->sectors[i].is_protected = 1; } - } else if (lpc2000_info->variant == lpc54100) { + } else if (lpc2000_info->variant == LPC54100) { lpc2000_info->cmd51_dst_boundary = 256; lpc2000_info->checksum_vector = 7; lpc2000_info->iap_max_stack = 128; @@ -626,7 +646,7 @@ static int lpc2000_build_sector_list(struct flash_bank *bank) bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - for (int i = 0; i < bank->num_sectors; i++) { + for (unsigned int i = 0; i < bank->num_sectors; i++) { bank->sectors[i].offset = offset; /* all sectors are 32kB-sized */ bank->sectors[i].size = 32 * 1024; @@ -666,18 +686,18 @@ static int lpc2000_iap_working_area_init(struct flash_bank *bank, struct working /* write IAP code to working area */ switch (lpc2000_info->variant) { - case lpc800: - case lpc1100: - case lpc1500: - case lpc1700: - case lpc4300: - case lpc54100: - case lpc_auto: + case LPC800: + case LPC1100: + case LPC1500: + case LPC1700: + case LPC4300: + case LPC54100: + case LPC_AUTO: target_buffer_set_u32(target, jump_gate, ARMV4_5_T_BX(12)); target_buffer_set_u32(target, jump_gate + 4, ARMV5_T_BKPT(0)); break; - case lpc2000_v1: - case lpc2000_v2: + case LPC2000_V1: + case LPC2000_V2: target_buffer_set_u32(target, jump_gate, ARMV4_5_BX(12)); target_buffer_set_u32(target, jump_gate + 4, ARMV4_5_B(0xfffffe, 0)); break; @@ -688,7 +708,7 @@ static int lpc2000_iap_working_area_init(struct flash_bank *bank, struct working int retval = target_write_memory(target, (*iap_working_area)->address, 4, 2, jump_gate); if (retval != ERROR_OK) { - LOG_ERROR("Write memory at address 0x%8.8" TARGET_PRIxADDR " failed (check work_area definition)", + LOG_ERROR("Write memory at address " TARGET_ADDR_FMT " failed (check work_area definition)", (*iap_working_area)->address); target_free_working_area(target, *iap_working_area); } @@ -709,28 +729,28 @@ static int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_wo uint32_t iap_entry_point = 0; /* to make compiler happier */ switch (lpc2000_info->variant) { - case lpc800: - case lpc1100: - case lpc1700: - case lpc_auto: + case LPC800: + case LPC1100: + case LPC1700: + case LPC_AUTO: armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; armv7m_info.core_mode = ARM_MODE_THREAD; iap_entry_point = 0x1fff1ff1; break; - case lpc1500: - case lpc54100: + case LPC1500: + case LPC54100: armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; armv7m_info.core_mode = ARM_MODE_THREAD; iap_entry_point = 0x03000205; break; - case lpc2000_v1: - case lpc2000_v2: + case LPC2000_V1: + case LPC2000_V2: arm_algo.common_magic = ARM_COMMON_MAGIC; arm_algo.core_mode = ARM_MODE_SVC; arm_algo.core_state = ARM_STATE_ARM; iap_entry_point = 0x7ffffff1; break; - case lpc4300: + case LPC4300: armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; armv7m_info.core_mode = ARM_MODE_THREAD; /* read out IAP entry point from ROM driver table at 0x10400100 */ @@ -741,6 +761,9 @@ static int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_wo exit(-1); } + if (lpc2000_info->iap_entry_alternative != 0x0) + iap_entry_point = lpc2000_info->iap_entry_alternative; + struct mem_param mem_params[2]; /* command parameter table */ @@ -768,13 +791,13 @@ static int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_wo buf_set_u32(reg_params[2].value, 0, 32, iap_entry_point); switch (lpc2000_info->variant) { - case lpc800: - case lpc1100: - case lpc1500: - case lpc1700: - case lpc4300: - case lpc54100: - case lpc_auto: + case LPC800: + case LPC1100: + case LPC1500: + case LPC1700: + case LPC4300: + case LPC54100: + case LPC_AUTO: /* IAP stack */ init_reg_param(®_params[3], "sp", 32, PARAM_OUT); buf_set_u32(reg_params[3].value, 0, 32, @@ -788,8 +811,8 @@ static int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_wo target_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address, 0, 10000, &armv7m_info); break; - case lpc2000_v1: - case lpc2000_v2: + case LPC2000_V1: + case LPC2000_V2: /* IAP stack */ init_reg_param(®_params[3], "sp_svc", 32, PARAM_OUT); buf_set_u32(reg_params[3].value, 0, 32, @@ -829,9 +852,10 @@ static int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_wo return status_code; } -static int lpc2000_iap_blank_check(struct flash_bank *bank, int first, int last) +static int lpc2000_iap_blank_check(struct flash_bank *bank, unsigned int first, + unsigned int last) { - if ((first < 0) || (last >= bank->num_sectors)) + if (last >= bank->num_sectors) return ERROR_FLASH_SECTOR_INVALID; uint32_t param_table[5] = {0}; @@ -844,10 +868,10 @@ static int lpc2000_iap_blank_check(struct flash_bank *bank, int first, int last) return retval; struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; - if (lpc2000_info->variant == lpc4300) + if (lpc2000_info->variant == LPC4300) param_table[2] = lpc2000_info->lpc4300_bank; - for (int i = first; i <= last && retval == ERROR_OK; i++) { + for (unsigned int i = first; i <= last && retval == ERROR_OK; i++) { /* check single sector */ param_table[0] = param_table[1] = i; int status_code = lpc2000_iap_call(bank, iap_working_area, 53, param_table, result_table); @@ -894,23 +918,23 @@ FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command) bank->driver_priv = lpc2000_info; if (strcmp(CMD_ARGV[6], "lpc2000_v1") == 0) { - lpc2000_info->variant = lpc2000_v1; + lpc2000_info->variant = LPC2000_V1; } else if (strcmp(CMD_ARGV[6], "lpc2000_v2") == 0) { - lpc2000_info->variant = lpc2000_v2; + lpc2000_info->variant = LPC2000_V2; } else if (strcmp(CMD_ARGV[6], "lpc1700") == 0 || strcmp(CMD_ARGV[6], "lpc4000") == 0) { - lpc2000_info->variant = lpc1700; + lpc2000_info->variant = LPC1700; } else if (strcmp(CMD_ARGV[6], "lpc1800") == 0 || strcmp(CMD_ARGV[6], "lpc4300") == 0) { - lpc2000_info->variant = lpc4300; + lpc2000_info->variant = LPC4300; } else if (strcmp(CMD_ARGV[6], "lpc800") == 0) { - lpc2000_info->variant = lpc800; + lpc2000_info->variant = LPC800; } else if (strcmp(CMD_ARGV[6], "lpc1100") == 0) { - lpc2000_info->variant = lpc1100; + lpc2000_info->variant = LPC1100; } else if (strcmp(CMD_ARGV[6], "lpc1500") == 0) { - lpc2000_info->variant = lpc1500; + lpc2000_info->variant = LPC1500; } else if (strcmp(CMD_ARGV[6], "lpc54100") == 0) { - lpc2000_info->variant = lpc54100; + lpc2000_info->variant = LPC54100; } else if (strcmp(CMD_ARGV[6], "auto") == 0) { - lpc2000_info->variant = lpc_auto; + lpc2000_info->variant = LPC_AUTO; } else { LOG_ERROR("unknown LPC2000 variant: %s", CMD_ARGV[6]); free(lpc2000_info); @@ -938,11 +962,14 @@ FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command) if (strcmp(CMD_ARGV[8], "calc_checksum") == 0) lpc2000_info->calc_checksum = 1; } + if (CMD_ARGC >= 10 && !lpc2000_info->iap_entry_alternative) + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[9], lpc2000_info->iap_entry_alternative); return ERROR_OK; } -static int lpc2000_erase(struct flash_bank *bank, int first, int last) +static int lpc2000_erase(struct flash_bank *bank, unsigned int first, + unsigned int last) { if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -955,7 +982,7 @@ static int lpc2000_erase(struct flash_bank *bank, int first, int last) param_table[0] = first; param_table[1] = last; - if (lpc2000_info->variant == lpc4300) + if (lpc2000_info->variant == LPC4300) param_table[2] = lpc2000_info->lpc4300_bank; else param_table[2] = lpc2000_info->cclk; @@ -968,7 +995,7 @@ static int lpc2000_erase(struct flash_bank *bank, int first, int last) if (retval != ERROR_OK) return retval; - if (lpc2000_info->variant == lpc4300) + if (lpc2000_info->variant == LPC4300) /* Init IAP Anyway */ lpc2000_iap_call(bank, iap_working_area, 49, param_table, result_table); @@ -992,7 +1019,7 @@ static int lpc2000_erase(struct flash_bank *bank, int first, int last) if (retval == ERROR_OK) { /* Erase sectors */ param_table[2] = lpc2000_info->cclk; - if (lpc2000_info->variant == lpc4300) + if (lpc2000_info->variant == LPC4300) param_table[3] = lpc2000_info->lpc4300_bank; status_code = lpc2000_iap_call(bank, iap_working_area, 52, param_table, result_table); @@ -1018,12 +1045,6 @@ static int lpc2000_erase(struct flash_bank *bank, int first, int last) return retval; } -static int lpc2000_protect(struct flash_bank *bank, int set, int first, int last) -{ - /* can't protect/unprotect on the lpc2000 */ - return ERROR_OK; -} - static int lpc2000_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { struct target *target = bank->target; @@ -1048,7 +1069,7 @@ static int lpc2000_write(struct flash_bank *bank, const uint8_t *buffer, uint32_ int first_sector = 0; int last_sector = 0; - for (int i = 0; i < bank->num_sectors; i++) { + for (unsigned int i = 0; i < bank->num_sectors; i++) { if (offset >= bank->sectors[i].offset) first_sector = i; if (offset + DIV_ROUND_UP(count, dst_min_alignment) * dst_min_alignment > bank->sectors[i].offset) @@ -1071,9 +1092,9 @@ static int lpc2000_write(struct flash_bank *bank, const uint8_t *buffer, uint32_ uint32_t original_value = buf_get_u32(buffer + (lpc2000_info->checksum_vector * 4), 0, 32); if (original_value != checksum) { - LOG_WARNING("Verification will fail since checksum in image (0x%8.8" PRIx32 ") to be written to flash is " + LOG_WARNING("Boot verification checksum in image (0x%8.8" PRIx32 ") to be written to flash is " "different from calculated vector checksum (0x%8.8" PRIx32 ").", original_value, checksum); - LOG_WARNING("To remove this warning modify build tools on developer PC to inject correct LPC vector " + LOG_WARNING("OpenOCD will write the correct checksum. To remove this warning modify build tools on developer PC to inject correct LPC vector " "checksum."); } @@ -1102,7 +1123,7 @@ static int lpc2000_write(struct flash_bank *bank, const uint8_t *buffer, uint32_ uint32_t param_table[5] = {0}; uint32_t result_table[4]; - if (lpc2000_info->variant == lpc4300) + if (lpc2000_info->variant == LPC4300) /* Init IAP Anyway */ lpc2000_iap_call(bank, iap_working_area, 49, param_table, result_table); @@ -1117,7 +1138,7 @@ static int lpc2000_write(struct flash_bank *bank, const uint8_t *buffer, uint32_ param_table[0] = first_sector; param_table[1] = last_sector; - if (lpc2000_info->variant == lpc4300) + if (lpc2000_info->variant == LPC4300) param_table[2] = lpc2000_info->lpc4300_bank; else param_table[2] = lpc2000_info->cclk; @@ -1138,7 +1159,7 @@ static int lpc2000_write(struct flash_bank *bank, const uint8_t *buffer, uint32_ break; } - /* Exit if error occured */ + /* Exit if error occurred */ if (retval != ERROR_OK) break; @@ -1156,8 +1177,8 @@ static int lpc2000_write(struct flash_bank *bank, const uint8_t *buffer, uint32_ free(last_buffer); } - LOG_DEBUG("writing 0x%" PRIx32 " bytes to address 0x%" PRIx32, thisrun_bytes, - bank->base + offset + bytes_written); + LOG_DEBUG("writing 0x%" PRIx32 " bytes to address " TARGET_ADDR_FMT, + thisrun_bytes, bank->base + offset + bytes_written); /* Write data */ param_table[0] = bank->base + offset + bytes_written; @@ -1180,7 +1201,7 @@ static int lpc2000_write(struct flash_bank *bank, const uint8_t *buffer, uint32_ break; } - /* Exit if error occured */ + /* Exit if error occurred */ if (retval != ERROR_OK) break; @@ -1248,7 +1269,7 @@ static int lpc2000_auto_probe_flash(struct flash_bank *bank) switch (part_id) { case LPC1110_1: case LPC1110_2: - lpc2000_info->variant = lpc1100; + lpc2000_info->variant = LPC1100; bank->size = 4 * 1024; break; @@ -1264,7 +1285,7 @@ static int lpc2000_auto_probe_flash(struct flash_bank *bank) case LPC11E11_101: case LPC1311: case LPC1311_1: - lpc2000_info->variant = lpc1100; + lpc2000_info->variant = LPC1100; bank->size = 8 * 1024; break; @@ -1284,7 +1305,7 @@ static int lpc2000_auto_probe_flash(struct flash_bank *bank) case LPC11U12_201_1: case LPC11U12_201_2: case LPC1342: - lpc2000_info->variant = lpc1100; + lpc2000_info->variant = LPC1100; bank->size = 16 * 1024; break; @@ -1299,7 +1320,7 @@ static int lpc2000_auto_probe_flash(struct flash_bank *bank) case LPC11U13_201_1: case LPC11U13_201_2: case LPC11U23_301: - lpc2000_info->variant = lpc1100; + lpc2000_info->variant = LPC1100; bank->size = 24 * 1024; break; @@ -1327,18 +1348,18 @@ static int lpc2000_auto_probe_flash(struct flash_bank *bank) case LPC1343: case LPC1343_1: case LPC1345: - lpc2000_info->variant = lpc1100; + lpc2000_info->variant = LPC1100; bank->size = 32 * 1024; break; case LPC1751_1: case LPC1751_2: - lpc2000_info->variant = lpc1700; + lpc2000_info->variant = LPC1700; bank->size = 32 * 1024; break; case LPC11U34_311: - lpc2000_info->variant = lpc1100; + lpc2000_info->variant = LPC1100; bank->size = 40 * 1024; break; @@ -1346,12 +1367,12 @@ static int lpc2000_auto_probe_flash(struct flash_bank *bank) case LPC11U34_421: case LPC1316: case LPC1346: - lpc2000_info->variant = lpc1100; + lpc2000_info->variant = LPC1100; bank->size = 48 * 1024; break; case LPC1114_333_1: - lpc2000_info->variant = lpc1100; + lpc2000_info->variant = LPC1100; bank->size = 56 * 1024; break; @@ -1362,19 +1383,19 @@ static int lpc2000_auto_probe_flash(struct flash_bank *bank) case LPC11U66: case LPC1317: case LPC1347: - lpc2000_info->variant = lpc1100; + lpc2000_info->variant = LPC1100; bank->size = 64 * 1024; break; case LPC1752: case LPC4072: - lpc2000_info->variant = lpc1700; + lpc2000_info->variant = LPC1700; bank->size = 64 * 1024; break; case LPC11E36_501: case LPC11U36_401: - lpc2000_info->variant = lpc1100; + lpc2000_info->variant = LPC1100; bank->size = 96 * 1024; break; @@ -1387,7 +1408,7 @@ static int lpc2000_auto_probe_flash(struct flash_bank *bank) case LPC11E68: case LPC11U67_1: case LPC11U67_2: - lpc2000_info->variant = lpc1100; + lpc2000_info->variant = LPC1100; bank->size = 128 * 1024; break; @@ -1395,13 +1416,13 @@ static int lpc2000_auto_probe_flash(struct flash_bank *bank) case LPC1764: case LPC1774: case LPC4074: - lpc2000_info->variant = lpc1700; + lpc2000_info->variant = LPC1700; bank->size = 128 * 1024; break; case LPC11U68_1: case LPC11U68_2: - lpc2000_info->variant = lpc1100; + lpc2000_info->variant = LPC1100; bank->size = 256 * 1024; break; @@ -1413,7 +1434,7 @@ static int lpc2000_auto_probe_flash(struct flash_bank *bank) case LPC1785: case LPC1786: case LPC4076: - lpc2000_info->variant = lpc1700; + lpc2000_info->variant = LPC1700; bank->size = 256 * 1024; break; @@ -1428,17 +1449,17 @@ static int lpc2000_auto_probe_flash(struct flash_bank *bank) case LPC1788: case LPC4078: case LPC4088: - lpc2000_info->variant = lpc1700; + lpc2000_info->variant = LPC1700; bank->size = 512 * 1024; break; case LPC810_021: - lpc2000_info->variant = lpc800; + lpc2000_info->variant = LPC800; bank->size = 4 * 1024; break; case LPC811_001: - lpc2000_info->variant = lpc800; + lpc2000_info->variant = LPC800; bank->size = 8 * 1024; break; @@ -1448,16 +1469,35 @@ static int lpc2000_auto_probe_flash(struct flash_bank *bank) case LPC812_101_3: case LPC822_101: case LPC822_101_1: - lpc2000_info->variant = lpc800; + lpc2000_info->variant = LPC800; bank->size = 16 * 1024; break; case LPC824_201: case LPC824_201_1: - lpc2000_info->variant = lpc800; + lpc2000_info->variant = LPC800; bank->size = 32 * 1024; break; + case LPC8N04: + case NHS3100: + case NHS3152: + case NHS3153: + lpc2000_info->variant = LPC800; + bank->size = 30 * 1024; + break; + + case LPC844_201: + case LPC844_201_1: + case LPC844_201_2: + case LPC845_301: + case LPC845_301_1: + case LPC845_301_2: + case LPC845_301_3: + lpc2000_info->variant = LPC800; + bank->size = 64 * 1024; + break; + default: LOG_ERROR("BUG: unknown Part ID encountered: 0x%" PRIx32, part_id); exit(-1); @@ -1473,11 +1513,11 @@ static int lpc2000_probe(struct flash_bank *bank) struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; if (!lpc2000_info->probed) { - if (lpc2000_info->variant == lpc_auto) { + if (lpc2000_info->variant == LPC_AUTO) { status = lpc2000_auto_probe_flash(bank); if (status != ERROR_OK) return status; - } else if (lpc2000_info->variant == lpc1100 || lpc2000_info->variant == lpc1700) { + } else if (lpc2000_info->variant == LPC1100 || lpc2000_info->variant == LPC1700) { status = get_lpc2000_part_id(bank, &part_id); if (status == LPC2000_CMD_SUCCESS) LOG_INFO("If auto-detection fails for this part, please email " @@ -1501,18 +1541,12 @@ static int lpc2000_erase_check(struct flash_bank *bank) return lpc2000_iap_blank_check(bank, 0, bank->num_sectors - 1); } -static int lpc2000_protect_check(struct flash_bank *bank) -{ - /* sectors are always protected */ - return ERROR_OK; -} - -static int get_lpc2000_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_lpc2000_info(struct flash_bank *bank, struct command_invocation *cmd) { struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; - snprintf(buf, buf_size, "lpc2000 flash driver variant: %i, clk: %" PRIi32 "kHz", lpc2000_info->variant, - lpc2000_info->cclk); + command_print_sameline(cmd, "lpc2000 flash driver variant: %i, clk: %" PRIu32 "kHz", + lpc2000_info->variant, lpc2000_info->cclk); return ERROR_OK; } @@ -1524,7 +1558,7 @@ COMMAND_HANDLER(lpc2000_handle_part_id_command) struct flash_bank *bank; int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (ERROR_OK != retval) + if (retval != ERROR_OK) return retval; if (bank->target->state != TARGET_HALTED) { @@ -1536,11 +1570,11 @@ COMMAND_HANDLER(lpc2000_handle_part_id_command) int status_code = get_lpc2000_part_id(bank, &part_id); if (status_code != 0x0) { if (status_code == ERROR_FLASH_OPERATION_FAILED) { - command_print(CMD_CTX, "no sufficient working area specified, can't access LPC2000 IAP interface"); + command_print(CMD, "no sufficient working area specified, can't access LPC2000 IAP interface"); } else - command_print(CMD_CTX, "lpc2000 IAP returned status code %i", status_code); + command_print(CMD, "lpc2000 IAP returned status code %i", status_code); } else - command_print(CMD_CTX, "lpc2000 part id: 0x%8.8" PRIx32, part_id); + command_print(CMD, "lpc2000 part id: 0x%8.8" PRIx32, part_id); return retval; } @@ -1566,17 +1600,16 @@ static const struct command_registration lpc2000_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -struct flash_driver lpc2000_flash = { +const struct flash_driver lpc2000_flash = { .name = "lpc2000", .commands = lpc2000_command_handlers, .flash_bank_command = lpc2000_flash_bank_command, .erase = lpc2000_erase, - .protect = lpc2000_protect, .write = lpc2000_write, .read = default_flash_read, .probe = lpc2000_probe, .auto_probe = lpc2000_probe, .erase_check = lpc2000_erase_check, - .protect_check = lpc2000_protect_check, .info = get_lpc2000_info, + .free_driver_priv = default_flash_free_driver_priv, };