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/4684

-- gerrit

commit f5185cdcdaebc8e90f707eec9d1ea5c675233e2c
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: I2d654dd250f416e74262c0228cad8713a283402f
    Signed-off-by: Rod Boyce <[email protected]>

diff --git a/src/flash/nor/lpc2000.c b/src/flash/nor/lpc2000.c
index 8e15c31..cb8227a 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

Reply via email to