Flash/LPC2000: Add support for LPC11(x)xx, LPC13xx
authorCosmin Gorgovan <cosmin@linux-geek.org>
Sat, 29 Mar 2014 19:20:08 +0000 (19:20 +0000)
committerAndreas Fritiofson <andreas.fritiofson@gmail.com>
Sun, 1 Jun 2014 18:07:23 +0000 (18:07 +0000)
LPC11(x)xx and LPC13xx devices are mostly compatible with the lpc1700
variant of the LPC2000 driver, but use a fixed flash sector size of 4KB.

Change-Id: I033515f4ff6bc61d3b9babd27096f78c99cea927
Signed-off-by: Cosmin Gorgovan <cosmin@linux-geek.org>
Reviewed-on: http://openocd.zylin.com/2071
Tested-by: jenkins
Reviewed-by: Paul Fertser <fercerpav@gmail.com>
doc/openocd.texi
src/flash/nor/lpc2000.c

index fd25e870368512bb3a851b5f1ef921a12772e61a..1461521065bcacc9b0b95c14b49470aea3ed0146 100644 (file)
@@ -5173,9 +5173,10 @@ supported.}
 @end deffn
 
 @deffn {Flash Driver} lpc2000
-Most members of the LPC1700, LPC1800, LPC2000 and LPC4300 microcontroller
-families from NXP include internal flash and use Cortex-M3 (LPC1700, LPC1800),
-Cortex-M4 (LPC4300) or ARM7TDMI (LPC2000) cores.
+All members of the LPC11(x)00 and LPC1300 microcontroller families and most members
+of the LPC1700, LPC1800, LPC2000 and LPC4300 microcontroller families from NXP
+include internal flash and use Cortex-M0 (LPC11(x)00), Cortex-M3 (LPC1300, LPC1700,
+LPC1800), Cortex-M4 (LPC4300) or ARM7TDMI (LPC2000) cores.
 
 @quotation Note
 There are LPC2000 devices which are not supported by the @var{lpc2000}
@@ -5192,8 +5193,9 @@ which must appear in the following order:
 @option{lpc2000_v1} (older LPC21xx and LPC22xx)
 @option{lpc2000_v2} (LPC213x, LPC214x, LPC210[123], LPC23xx and LPC24xx)
 @option{lpc1700} (LPC175x and LPC176x)
-or @option{lpc4300} - available also as @option{lpc1800} alias (LPC18x[2357] and
+@option{lpc4300} - available also as @option{lpc1800} alias (LPC18x[2357] and
 LPC43x[2357])
+or @option{lpc1100} (LPC11(x)xx and LPC13xx)
 @item @var{clock_kHz} ... the frequency, in kiloHertz,
 at which the core is running
 @item @option{calc_checksum} ... optional (but you probably want to provide this!),
index 69c8b0341e02ced7a1d8a7ffc138fb8930979cfe..e81c97d4d5ca61489a32897c1cb3b63a5793fc4e 100644 (file)
  *
  * lpc800:
  * - 810 | 1 | 2 (tested with LPC810/LPC812)
+ *
+ * lpc1100:
+ * - 11xx
+ * - 11Axx
+ * - 11Cxx
+ * - 11Dxx
+ * - 11Exx
+ * - 11Uxx (tested with LPC11U34)
+ * - 131x
+ * - 134x
  */
 
 typedef enum {
@@ -73,6 +83,7 @@ typedef enum {
        lpc1700,
        lpc4300,
        lpc800,
+       lpc1100,
 } lpc2000_variant;
 
 struct lpc2000_flash_bank {
@@ -329,6 +340,25 @@ static int lpc2000_build_sector_list(struct flash_bank *bank)
                        bank->sectors[i].is_protected = 1;
                }
 
+       } else if (lpc2000_info->variant == lpc1100) {
+               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 */
+               bank->num_sectors = bank->size / 4096;
+
+               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 {
                LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
                exit(-1);
@@ -360,6 +390,7 @@ 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 lpc1700:
                case lpc4300:
                        target_buffer_set_u32(target, jump_gate, ARMV4_5_T_BX(12));
@@ -397,6 +428,7 @@ static int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_wo
 
        switch (lpc2000_info->variant) {
                case lpc800:
+               case lpc1100:
                case lpc1700:
                        armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
                        armv7m_info.core_mode = ARM_MODE_THREAD;
@@ -448,6 +480,7 @@ static int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_wo
 
        switch (lpc2000_info->variant) {
                case lpc800:
+               case lpc1100:
                case lpc1700:
                case lpc4300:
                        /* IAP stack */
@@ -601,6 +634,13 @@ FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command)
                lpc2000_info->cmd51_can_8192b = 0;
                lpc2000_info->checksum_vector = 7;
                lpc2000_info->iap_max_stack = 148;
+       } else if (strcmp(CMD_ARGV[6], "lpc1100") == 0) {
+               lpc2000_info->variant = lpc1100;
+               lpc2000_info->cmd51_dst_boundary = 256;
+               lpc2000_info->cmd51_can_256b = 1;
+               lpc2000_info->cmd51_can_8192b = 0;
+               lpc2000_info->checksum_vector = 7;
+               lpc2000_info->iap_max_stack = 128;
        } else {
                LOG_ERROR("unknown LPC2000 variant: %s", CMD_ARGV[6]);
                free(lpc2000_info);