This is an automated email from Gerrit. Rod Boyce ([email protected]) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/4683
-- gerrit commit 38a95813ffa6c13b8470ebbc3881c3ecc9e92417 Author: Rod Boyce <[email protected]> Date: Fri Sep 28 17:49:16 2018 +0100 NOR: lpc2000 Add support for LPC84x devices These devices differ from LPC8xx devices in that they have a different IAP entry point, but everything else is the same. Using Tcl to pass different flash identifier also added code to set a different IAP entry point. no new Clang analyser warnings and no new build sanitizers issues. Change-Id: I7550d9560449184e488888cf2e1708984e6f5b31 Signed-off-by: Rod Boyce <[email protected]> diff --git a/src/flash/nor/lpc2000.c b/src/flash/nor/lpc2000.c index 8e15c31..f542c84 100644 --- a/src/flash/nor/lpc2000.c +++ b/src/flash/nor/lpc2000.c @@ -77,6 +77,7 @@ * lpc800: * - 810 | 1 | 2 (tested with LPC810/LPC811/LPC812) * - 822 | 4 (tested with LPC824) + * - 844 | 5 (tested with LPC845) * * lpc1100: * - 11xx @@ -257,6 +258,18 @@ #define LPC824_201 0x00008241 #define LPC824_201_1 0x00008242 +#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 + +/* Changed IAP entry point for the LPC84x */ +#define LPC840_IAP_ENTRY 0x0F001FF1 + #define IAP_CODE_LEN 0x34 #define LPC11xx_REG_SECTORS 24 @@ -282,6 +295,7 @@ struct lpc2000_flash_bank { int checksum_vector; uint32_t iap_max_stack; uint32_t lpc4300_bank; + uint32_t iap_entry_alternitive; bool probed; }; @@ -311,435 +325,105 @@ enum lpc2000_status_codes { LCP2000_ERROR_SETTING_ACTIVE_PARTITION = 22, }; -static int lpc2000_build_sector_list(struct flash_bank *bank) +/* this function allocates and initializes working area used for IAP algorithm + * uses 52 + max IAP stack bytes working area + * 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait) + * 0x8 to 0x1f: command parameter table (1+5 words) + * 0x20 to 0x33: command result table (1+4 words) + * 0x34 to 0xb3|0x104: stack + * (128b needed for lpc1xxx/2000/5410x, 208b for lpc43xx/lpc82x and 148b for lpc81x) + */ + +static int lpc2000_iap_working_area_init(struct flash_bank *bank, struct working_area **iap_working_area) { + struct target *target = bank->target; struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; - uint32_t offset = 0; - /* default to a 4096 write buffer */ - lpc2000_info->cmd51_max_buffer = 4096; - - if (lpc2000_info->variant == lpc2000_v1) { - lpc2000_info->cmd51_dst_boundary = 512; - lpc2000_info->checksum_vector = 5; - lpc2000_info->iap_max_stack = 128; + if (target_alloc_working_area(target, IAP_CODE_LEN + lpc2000_info->iap_max_stack, iap_working_area) != ERROR_OK) { + LOG_ERROR("no working area specified, can't write LPC2000 internal flash"); + return ERROR_FLASH_OPERATION_FAILED; + } - /* variant 1 has different layout for 128kb and 256kb flashes */ - if (bank->size == 128 * 1024) { - bank->num_sectors = 16; - bank->sectors = malloc(sizeof(struct flash_sector) * 16); - for (int i = 0; i < 16; i++) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = 8 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - } else if (bank->size == 256 * 1024) { - bank->num_sectors = 18; - bank->sectors = malloc(sizeof(struct flash_sector) * 18); + uint8_t jump_gate[8]; - for (int i = 0; i < 8; i++) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = 8 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - for (int i = 8; i < 10; i++) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = 64 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - for (int i = 10; i < 18; i++) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = 8 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - } else { - LOG_ERROR("BUG: unknown bank->size encountered"); + /* 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: + 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: + 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; + default: + LOG_ERROR("BUG: unknown lpc2000_info->variant encountered"); exit(-1); - } - } else if (lpc2000_info->variant == lpc2000_v2) { - lpc2000_info->cmd51_dst_boundary = 256; - lpc2000_info->checksum_vector = 5; - lpc2000_info->iap_max_stack = 128; + } - /* variant 2 has a uniform layout, only number of sectors differs */ - switch (bank->size) { - case 4 * 1024: - lpc2000_info->cmd51_max_buffer = 1024; - bank->num_sectors = 1; - break; - case 8 * 1024: - lpc2000_info->cmd51_max_buffer = 1024; - bank->num_sectors = 2; - break; - case 16 * 1024: - bank->num_sectors = 4; - break; - case 32 * 1024: - bank->num_sectors = 8; - break; - case 64 * 1024: - bank->num_sectors = 9; - break; - case 128 * 1024: - bank->num_sectors = 11; - break; - case 256 * 1024: - bank->num_sectors = 15; - break; - case 500 * 1024: - bank->num_sectors = 27; - break; - case 512 * 1024: - case 504 * 1024: - bank->num_sectors = 28; - break; - default: - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - break; - } + 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)", + (*iap_working_area)->address); + target_free_working_area(target, *iap_working_area); + } - bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); + return retval; +} - for (int i = 0; i < bank->num_sectors; i++) { - if (i < 8) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = 4 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } else if (i < 22) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = 32 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } else if (i < 28) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = 4 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - } - } else if (lpc2000_info->variant == lpc1700) { - lpc2000_info->cmd51_dst_boundary = 256; - lpc2000_info->checksum_vector = 7; - lpc2000_info->iap_max_stack = 128; +/* call LPC8xx/LPC1xxx/LPC4xxx/LPC5410x/LPC2000 IAP function */ - switch (bank->size) { - case 4 * 1024: - lpc2000_info->cmd51_max_buffer = 256; - bank->num_sectors = 1; - break; - case 8 * 1024: - lpc2000_info->cmd51_max_buffer = 512; - bank->num_sectors = 2; - break; - case 16 * 1024: - lpc2000_info->cmd51_max_buffer = 512; - bank->num_sectors = 4; - break; - case 32 * 1024: - lpc2000_info->cmd51_max_buffer = 1024; - bank->num_sectors = 8; - break; - case 64 * 1024: - bank->num_sectors = 16; - break; - case 128 * 1024: - bank->num_sectors = 18; - break; - case 256 * 1024: - bank->num_sectors = 22; - break; - case 512 * 1024: - bank->num_sectors = 30; - break; - default: - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - } +static int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_working_area, int code, + uint32_t param_table[5], uint32_t result_table[4]) +{ + struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; + struct target *target = bank->target; - bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); + struct arm_algorithm arm_algo; /* for LPC2000 */ + struct armv7m_algorithm armv7m_info; /* for LPC8xx/LPC1xxx/LPC4xxx/LPC5410x */ + uint32_t iap_entry_point = 0; /* to make compiler happier */ - for (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; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - } else if (lpc2000_info->variant == lpc4300) { - lpc2000_info->cmd51_dst_boundary = 512; - lpc2000_info->checksum_vector = 7; - lpc2000_info->iap_max_stack = 208; - - switch (bank->size) { - case 256 * 1024: - bank->num_sectors = 11; - break; - case 384 * 1024: - bank->num_sectors = 13; - break; - case 512 * 1024: - bank->num_sectors = 15; - break; - default: - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - } - - bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - - for (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; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - } 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. */ - lpc2000_info->cmd51_max_buffer = 256; /* smallest MCU in the series, LPC810, has 1 kB of SRAM */ - - switch (bank->size) { - case 4 * 1024: - bank->num_sectors = 4; - break; - case 8 * 1024: - bank->num_sectors = 8; - break; - case 16 * 1024: - bank->num_sectors = 16; - break; - case 32 * 1024: - lpc2000_info->cmd51_max_buffer = 1024; /* For LPC824, has 8kB of SRAM */ - bank->num_sectors = 32; - break; - default: - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - } - - bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - - for (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; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - } else if (lpc2000_info->variant == lpc1100) { - lpc2000_info->cmd51_dst_boundary = 256; - lpc2000_info->checksum_vector = 7; - lpc2000_info->iap_max_stack = 128; - - if ((bank->size % (4 * 1024)) != 0) { - LOG_ERROR("BUG: unknown bank->size encountered,\nLPC1100 flash size must be a multiple of 4096"); - exit(-1); - } - lpc2000_info->cmd51_max_buffer = 512; /* smallest MCU in the series, LPC1110, has 1 kB of SRAM */ - 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; - } - - 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++) { - bank->sectors[i].offset = offset; - 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) { - lpc2000_info->cmd51_dst_boundary = 256; - lpc2000_info->checksum_vector = 7; - lpc2000_info->iap_max_stack = 128; - - switch (bank->size) { - case 64 * 1024: - bank->num_sectors = 16; - break; - case 128 * 1024: - bank->num_sectors = 32; - break; - case 256 * 1024: - bank->num_sectors = 64; - break; - default: - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - } - - bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - - for (int i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].offset = offset; - /* all sectors are 4kB-sized */ - bank->sectors[i].size = 4 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - } else if (lpc2000_info->variant == lpc54100) { - lpc2000_info->cmd51_dst_boundary = 256; - lpc2000_info->checksum_vector = 7; - lpc2000_info->iap_max_stack = 128; - - switch (bank->size) { - case 256 * 1024: - bank->num_sectors = 8; - break; - case 512 * 1024: - bank->num_sectors = 16; - break; - default: - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - } - - bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - - for (int i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].offset = offset; - /* all sectors are 32kB-sized */ - bank->sectors[i].size = 32 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - } else { - LOG_ERROR("BUG: unknown lpc2000_info->variant encountered"); - exit(-1); - } - - return ERROR_OK; -} - -/* this function allocates and initializes working area used for IAP algorithm - * uses 52 + max IAP stack bytes working area - * 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait) - * 0x8 to 0x1f: command parameter table (1+5 words) - * 0x20 to 0x33: command result table (1+4 words) - * 0x34 to 0xb3|0x104: stack - * (128b needed for lpc1xxx/2000/5410x, 208b for lpc43xx/lpc82x and 148b for lpc81x) - */ - -static int lpc2000_iap_working_area_init(struct flash_bank *bank, struct working_area **iap_working_area) -{ - struct target *target = bank->target; - struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; - - if (target_alloc_working_area(target, IAP_CODE_LEN + lpc2000_info->iap_max_stack, iap_working_area) != ERROR_OK) { - LOG_ERROR("no working area specified, can't write LPC2000 internal flash"); - return ERROR_FLASH_OPERATION_FAILED; - } - - uint8_t jump_gate[8]; - - /* 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: - 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: - 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; - default: - LOG_ERROR("BUG: unknown lpc2000_info->variant encountered"); - exit(-1); - } - - 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)", - (*iap_working_area)->address); - target_free_working_area(target, *iap_working_area); - } - - return retval; -} - -/* call LPC8xx/LPC1xxx/LPC4xxx/LPC5410x/LPC2000 IAP function */ - -static int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_working_area, int code, - uint32_t param_table[5], uint32_t result_table[4]) -{ - struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; - struct target *target = bank->target; - - struct arm_algorithm arm_algo; /* for LPC2000 */ - struct armv7m_algorithm armv7m_info; /* for LPC8xx/LPC1xxx/LPC4xxx/LPC5410x */ - uint32_t iap_entry_point = 0; /* to make compiler happier */ - - switch (lpc2000_info->variant) { - 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: - 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: - 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: - 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 */ - target_read_u32(target, 0x10400100, &iap_entry_point); - break; - default: - LOG_ERROR("BUG: unknown lpc2000->variant encountered"); - exit(-1); - } + switch (lpc2000_info->variant) { + 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; + if (lpc2000_info->iap_entry_alternitive != 0x0) + iap_entry_point = lpc2000_info->iap_entry_alternitive; + break; + 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: + 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: + 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 */ + target_read_u32(target, 0x10400100, &iap_entry_point); + break; + default: + LOG_ERROR("BUG: unknown lpc2000->variant encountered"); + exit(-1); + } struct mem_param mem_params[2]; @@ -903,6 +587,9 @@ FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command) lpc2000_info->variant = lpc4300; } else if (strcmp(CMD_ARGV[6], "lpc800") == 0) { lpc2000_info->variant = lpc800; + } else if (strcmp(CMD_ARGV[6], "lpc840") == 0) { + lpc2000_info->variant = lpc800; + lpc2000_info->iap_entry_alternitive = LPC840_IAP_ENTRY; } else if (strcmp(CMD_ARGV[6], "lpc1100") == 0) { lpc2000_info->variant = lpc1100; } else if (strcmp(CMD_ARGV[6], "lpc1500") == 0) { @@ -1458,6 +1145,17 @@ static int lpc2000_auto_probe_flash(struct flash_bank *bank) bank->size = 32 * 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); @@ -1466,6 +1164,348 @@ static int lpc2000_auto_probe_flash(struct flash_bank *bank) return ERROR_OK; } +static int lpc2000_build_sector_list(struct flash_bank *bank) +{ + struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; + uint32_t offset = 0; + + /* default to a 4096 write buffer */ + lpc2000_info->cmd51_max_buffer = 4096; + + if (lpc2000_info->variant == lpc2000_v1) { + lpc2000_info->cmd51_dst_boundary = 512; + lpc2000_info->checksum_vector = 5; + lpc2000_info->iap_max_stack = 128; + + /* variant 1 has different layout for 128kb and 256kb flashes */ + if (bank->size == 128 * 1024) { + bank->num_sectors = 16; + bank->sectors = malloc(sizeof(struct flash_sector) * 16); + for (int i = 0; i < 16; i++) { + bank->sectors[i].offset = offset; + bank->sectors[i].size = 8 * 1024; + offset += bank->sectors[i].size; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = 1; + } + } else if (bank->size == 256 * 1024) { + bank->num_sectors = 18; + bank->sectors = malloc(sizeof(struct flash_sector) * 18); + + for (int i = 0; i < 8; i++) { + bank->sectors[i].offset = offset; + bank->sectors[i].size = 8 * 1024; + offset += bank->sectors[i].size; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = 1; + } + for (int i = 8; i < 10; i++) { + bank->sectors[i].offset = offset; + bank->sectors[i].size = 64 * 1024; + offset += bank->sectors[i].size; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = 1; + } + for (int i = 10; i < 18; i++) { + bank->sectors[i].offset = offset; + bank->sectors[i].size = 8 * 1024; + offset += bank->sectors[i].size; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = 1; + } + } else { + LOG_ERROR("BUG: unknown bank->size encountered"); + exit(-1); + } + } else if (lpc2000_info->variant == lpc2000_v2) { + lpc2000_info->cmd51_dst_boundary = 256; + lpc2000_info->checksum_vector = 5; + lpc2000_info->iap_max_stack = 128; + + /* variant 2 has a uniform layout, only number of sectors differs */ + switch (bank->size) { + case 4 * 1024: + lpc2000_info->cmd51_max_buffer = 1024; + bank->num_sectors = 1; + break; + case 8 * 1024: + lpc2000_info->cmd51_max_buffer = 1024; + bank->num_sectors = 2; + break; + case 16 * 1024: + bank->num_sectors = 4; + break; + case 32 * 1024: + bank->num_sectors = 8; + break; + case 64 * 1024: + bank->num_sectors = 9; + break; + case 128 * 1024: + bank->num_sectors = 11; + break; + case 256 * 1024: + bank->num_sectors = 15; + break; + case 500 * 1024: + bank->num_sectors = 27; + break; + case 512 * 1024: + case 504 * 1024: + bank->num_sectors = 28; + break; + default: + LOG_ERROR("BUG: unknown bank->size encountered"); + exit(-1); + break; + } + + bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); + + for (int i = 0; i < bank->num_sectors; i++) { + if (i < 8) { + bank->sectors[i].offset = offset; + bank->sectors[i].size = 4 * 1024; + offset += bank->sectors[i].size; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = 1; + } else if (i < 22) { + bank->sectors[i].offset = offset; + bank->sectors[i].size = 32 * 1024; + offset += bank->sectors[i].size; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = 1; + } else if (i < 28) { + bank->sectors[i].offset = offset; + bank->sectors[i].size = 4 * 1024; + offset += bank->sectors[i].size; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = 1; + } + } + } else if (lpc2000_info->variant == lpc1700) { + lpc2000_info->cmd51_dst_boundary = 256; + lpc2000_info->checksum_vector = 7; + lpc2000_info->iap_max_stack = 128; + + switch (bank->size) { + case 4 * 1024: + lpc2000_info->cmd51_max_buffer = 256; + bank->num_sectors = 1; + break; + case 8 * 1024: + lpc2000_info->cmd51_max_buffer = 512; + bank->num_sectors = 2; + break; + case 16 * 1024: + lpc2000_info->cmd51_max_buffer = 512; + bank->num_sectors = 4; + break; + case 32 * 1024: + lpc2000_info->cmd51_max_buffer = 1024; + bank->num_sectors = 8; + break; + case 64 * 1024: + bank->num_sectors = 16; + break; + case 128 * 1024: + bank->num_sectors = 18; + break; + case 256 * 1024: + bank->num_sectors = 22; + break; + case 512 * 1024: + bank->num_sectors = 30; + break; + default: + LOG_ERROR("BUG: unknown bank->size encountered"); + exit(-1); + } + + bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); + + for (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; + offset += bank->sectors[i].size; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = 1; + } + } else if (lpc2000_info->variant == lpc4300) { + lpc2000_info->cmd51_dst_boundary = 512; + lpc2000_info->checksum_vector = 7; + lpc2000_info->iap_max_stack = 208; + + switch (bank->size) { + case 256 * 1024: + bank->num_sectors = 11; + break; + case 384 * 1024: + bank->num_sectors = 13; + break; + case 512 * 1024: + bank->num_sectors = 15; + break; + default: + LOG_ERROR("BUG: unknown bank->size encountered"); + exit(-1); + } + + bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); + + for (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; + offset += bank->sectors[i].size; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = 1; + } + + } 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. */ + lpc2000_info->cmd51_max_buffer = 256; /* smallest MCU in the series, LPC810, has 1 kB of SRAM */ + + if (bank->size == 0 ) { + int status = lpc2000_auto_probe_flash(bank); + if (status != ERROR_OK) + return status; + } + + switch (bank->size) { + case 4 * 1024: + bank->num_sectors = 4; + break; + case 8 * 1024: + bank->num_sectors = 8; + break; + case 16 * 1024: + bank->num_sectors = 16; + 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); + } + + bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); + + for (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; + offset += bank->sectors[i].size; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = 1; + } + + } else if (lpc2000_info->variant == lpc1100) { + lpc2000_info->cmd51_dst_boundary = 256; + lpc2000_info->checksum_vector = 7; + lpc2000_info->iap_max_stack = 128; + + if ((bank->size % (4 * 1024)) != 0) { + LOG_ERROR("BUG: unknown bank->size encountered,\nLPC1100 flash size must be a multiple of 4096"); + exit(-1); + } + lpc2000_info->cmd51_max_buffer = 512; /* smallest MCU in the series, LPC1110, has 1 kB of SRAM */ + 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; + } + + 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++) { + bank->sectors[i].offset = offset; + 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) { + lpc2000_info->cmd51_dst_boundary = 256; + lpc2000_info->checksum_vector = 7; + lpc2000_info->iap_max_stack = 128; + + switch (bank->size) { + case 64 * 1024: + bank->num_sectors = 16; + break; + case 128 * 1024: + bank->num_sectors = 32; + break; + case 256 * 1024: + bank->num_sectors = 64; + break; + default: + LOG_ERROR("BUG: unknown bank->size encountered"); + exit(-1); + } + + bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); + + for (int i = 0; i < bank->num_sectors; i++) { + bank->sectors[i].offset = offset; + /* all sectors are 4kB-sized */ + bank->sectors[i].size = 4 * 1024; + offset += bank->sectors[i].size; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = 1; + } + + } else if (lpc2000_info->variant == lpc54100) { + lpc2000_info->cmd51_dst_boundary = 256; + lpc2000_info->checksum_vector = 7; + lpc2000_info->iap_max_stack = 128; + + switch (bank->size) { + case 256 * 1024: + bank->num_sectors = 8; + break; + case 512 * 1024: + bank->num_sectors = 16; + break; + default: + LOG_ERROR("BUG: unknown bank->size encountered"); + exit(-1); + } + + bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); + + for (int i = 0; i < bank->num_sectors; i++) { + bank->sectors[i].offset = offset; + /* all sectors are 32kB-sized */ + bank->sectors[i].size = 32 * 1024; + offset += bank->sectors[i].size; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = 1; + } + + } else { + LOG_ERROR("BUG: unknown lpc2000_info->variant encountered"); + exit(-1); + } + + return ERROR_OK; +} + static int lpc2000_probe(struct flash_bank *bank) { int status; diff --git a/tcl/target/lpc1xxx.cfg b/tcl/target/lpc1xxx.cfg index 701adf2..f355316 100644 --- a/tcl/target/lpc1xxx.cfg +++ b/tcl/target/lpc1xxx.cfg @@ -9,6 +9,7 @@ # !!!!!! # LPC8xx chips support only SWD transport. +# LPC84x chips support only SWD transport. # LPC11xx chips support only SWD transport. # LPC12xx chips support only SWD transport. # LPC11Uxx chips support only SWD transports. @@ -26,7 +27,7 @@ if { [info exists CHIPNAME] } { if { [info exists CHIPSERIES] } { # Validate chip series is supported - if { $CHIPSERIES != "lpc800" && $CHIPSERIES != "lpc1100" && $CHIPSERIES != "lpc1200" && $CHIPSERIES != "lpc1300" && $CHIPSERIES != "lpc1700" && $CHIPSERIES != "lpc4000" } { + if { $CHIPSERIES != "lpc800" && $CHIPSERIES != "lpc840" && $CHIPSERIES != "lpc1100" && $CHIPSERIES != "lpc1200" && $CHIPSERIES != "lpc1300" && $CHIPSERIES != "lpc1700" && $CHIPSERIES != "lpc4000" } { error "Unsupported LPC1xxx chip series specified." } set _CHIPSERIES $CHIPSERIES @@ -45,7 +46,7 @@ if { [info exists CCLK] } { set _CCLK $CCLK } else { # LPC8xx/LPC11xx/LPC12xx/LPC13xx use a 12MHz one, LPC17xx uses a 4MHz one(except for LPC177x/8x,LPC407x/8x) - if { $_CHIPSERIES == "lpc800" || $_CHIPSERIES == "lpc1100" || $_CHIPSERIES == "lpc1200" || $_CHIPSERIES == "lpc1300" } { + if { $_CHIPSERIES == "lpc800" || $_CHIPSERIES == "lpc840" || $_CHIPSERIES == "lpc1100" || $_CHIPSERIES == "lpc1200" || $_CHIPSERIES == "lpc1300" } { set _CCLK 12000 } elseif { $_CHIPSERIES == "lpc1700" || $_CHIPSERIES == "lpc4000" } { set _CCLK 4000 @@ -57,7 +58,7 @@ if { [info exists CPUTAPID] } { set _CPUTAPID $CPUTAPID } else { # LPC8xx/LPC11xx/LPC12xx use a Cortex-M0/M0+ core, LPC13xx/LPC17xx use a Cortex-M3 core, LPC40xx use a Cortex-M4F core. - if { $_CHIPSERIES == "lpc800" || $_CHIPSERIES == "lpc1100" || $_CHIPSERIES == "lpc1200" } { + if { $_CHIPSERIES == "lpc800" || $_CHIPSERIES == "lpc840" || $_CHIPSERIES == "lpc1100" || $_CHIPSERIES == "lpc1200" } { set _CPUTAPID 0x0bb11477 } elseif { $_CHIPSERIES == "lpc1300" || $_CHIPSERIES == "lpc1700" || $_CHIPSERIES == "lpc4000" } { if { [using_jtag] } { @@ -101,10 +102,14 @@ $_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE # # flash bank <name> lpc2000 <base> <size> 0 0 <target#> <variant> <clock> [calc checksum] set _FLASHNAME $_CHIPNAME.flash +set _FLASHVARIANT auto +if { $_CHIPSERIES == "lpc840" } { + set _FLASHVARIANT $_CHIPSERIES +} flash bank $_FLASHNAME lpc2000 0x0 0 0 0 $_TARGETNAME \ - auto $_CCLK calc_checksum + $_FLASHVARIANT $_CCLK calc_checksum -if { $_CHIPSERIES == "lpc800" || $_CHIPSERIES == "lpc1100" || $_CHIPSERIES == "lpc1200" || $_CHIPSERIES == "lpc1300" } { +if { $_CHIPSERIES == "lpc800" || $_CHIPSERIES == "lpc840" || $_CHIPSERIES == "lpc1100" || $_CHIPSERIES == "lpc1200" || $_CHIPSERIES == "lpc1300" } { # Do not remap 0x0000-0x0200 to anything but the flash (i.e. select # "User Flash Mode" where interrupt vectors are _not_ remapped, # and reside in flash instead). @@ -150,6 +155,7 @@ if {[using_jtag]} { } # LPC8xx (Cortex-M0+ core) support SYSRESETREQ +# LPC84x (Cortex-M0+ core) support SYSRESETREQ # LPC11xx/LPC12xx (Cortex-M0 core) support SYSRESETREQ # LPC13xx/LPC17xx (Cortex-M3 core) support SYSRESETREQ # LPC40xx (Cortex-M4F core) support SYSRESETREQ diff --git a/tcl/target/lpc84x.cfg b/tcl/target/lpc84x.cfg new file mode 100644 index 0000000..f8e48b4 --- /dev/null +++ b/tcl/target/lpc84x.cfg @@ -0,0 +1,10 @@ +# NXP LPC84x Cortex-M0+ with at least 8kB SRAM +if { ![info exists CHIPNAME] } { + set CHIPNAME lpc84x +} +set CHIPSERIES lpc840 +if { ![info exists WORKAREASIZE] } { + set WORKAREASIZE 0x2000 +} + +source [find target/lpc1xxx.cfg] -- _______________________________________________ OpenOCD-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
