This is an automated email from Gerrit.

Cosmin Gorgovan ([email protected]) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/2071

-- gerrit

commit 9ba9956395a49f686d1dfa86be8afe96cea26c97
Author: Cosmin Gorgovan <[email protected]>
Date:   Sat Mar 29 19:20:08 2014 +0000

    Flash/LPC2000: Add support for LPC11XX, LPC13XX parts, with auto-probing
    
    LPC1100 and LPC1300 devices are mostly compatible with the lpc1700 variant
    of the LPC2000 driver, but use a fixed flash sector size of 4KB.
    Auto-probing has been implemented using the IAP 'Read Part ID' command.
    The IDs for all LPC13XX and LPC11UXX devices have been added.
    Auto-probing is only enabled if the flash bank size in the flash bank
    is 0, otherwise the size passed to the flash bank command is used.
    
    Change-Id: I033515f4ff6bc61d3b9babd27096f78c99cea927
    Signed-off-by: Cosmin Gorgovan <[email protected]>

diff --git a/src/flash/nor/lpc2000.c b/src/flash/nor/lpc2000.c
index 69c8b03..64a52fc 100644
--- a/src/flash/nor/lpc2000.c
+++ b/src/flash/nor/lpc2000.c
@@ -67,12 +67,44 @@
  * - 810 | 1 | 2 (tested with LPC810/LPC812)
  */
 
+#define LPC11U12_201_1 0x095C802B
+#define LPC11U12_201_2 0x295C802B
+#define LPC11U13_201_1 0x097A802B
+#define LPC11U13_201_2 0x297A802B
+#define LPC11U14_201_1 0x0998802B
+#define LPC11U14_201_2 0x2998802B
+#define LPC11U23_301   0x2972402B
+#define LPC11U24_301   0x2988402B
+#define LPC11U24_401   0x2980002B
+#define LPC11U34_311   0x0003D440
+#define LPC11U34_421   0x0001CC40
+#define LPC11U35_401   0x0001BC40
+#define LPC11U35_501   0x0000BC40
+#define LPC11U36_401   0x00019C40
+#define LPC11U37_401   0x00017C40
+#define LPC11U37H_401  0x00007C44
+#define LPC11U37_501   0x00007C40
+
+#define LPC1311        0x2C42502B
+#define LPC1311_1      0x1816902B
+#define LPC1313        0x2C40102B
+#define LPC1313_1      0x1830102B
+#define LPC1315        0x3A010523
+#define LPC1316        0x1A018524
+#define LPC1317        0x1A020525
+#define LPC1342        0x3D01402B
+#define LPC1343        0x3D00002B
+#define LPC1345        0x28010541
+#define LPC1346        0x08018542
+#define LPC1347        0x08020543
+
 typedef enum {
        lpc2000_v1,
        lpc2000_v2,
        lpc1700,
        lpc4300,
        lpc800,
+       lpc1100,
 } lpc2000_variant;
 
 struct lpc2000_flash_bank {
@@ -88,6 +120,7 @@ struct lpc2000_flash_bank {
        uint32_t iap_max_stack;
        uint32_t cmd51_src_offset;
        uint32_t lpc4300_bank;
+       bool probed;
 };
 
 enum lpc2000_status_codes {
@@ -329,6 +362,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 = 1024;
+               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 +412,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 +450,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 +502,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 */
@@ -562,6 +617,7 @@ FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
        struct lpc2000_flash_bank *lpc2000_info = calloc(1, 
sizeof(*lpc2000_info));
+       lpc2000_info->probed = false;
 
        bank->driver_priv = lpc2000_info;
 
@@ -601,6 +657,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);
@@ -612,7 +675,6 @@ FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command)
 
        COMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], lpc2000_info->cclk);
        lpc2000_info->calc_checksum = 0;
-       lpc2000_build_sector_list(bank);
 
        uint32_t temp_base = 0;
        COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], temp_base);
@@ -890,9 +952,119 @@ static int lpc2000_write(struct flash_bank *bank, const 
uint8_t *buffer, uint32_
        return retval;
 }
 
+static int get_lpc2000_part_id(struct flash_bank *bank, uint32_t *part_id)
+{
+       if (bank->target->state != TARGET_HALTED) {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       uint32_t param_table[5] = {0};
+       uint32_t result_table[4];
+       struct working_area *iap_working_area;
+
+       int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
+
+       if (retval != ERROR_OK)
+               return retval;
+
+       int status_code = lpc2000_iap_call(bank, iap_working_area, 54, 
param_table, result_table);
+
+       if (status_code == LPC2000_CMD_SUCCESS)
+               *part_id = result_table[0];
+
+       return status_code;
+}
+
+static int lpc2000_auto_probe_flash(struct flash_bank *bank)
+{
+       uint32_t part_id;
+       int retval;
+
+       if (bank->target->state != TARGET_HALTED) {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       retval = get_lpc2000_part_id(bank, &part_id);
+       if (retval != LPC2000_CMD_SUCCESS) {
+               LOG_ERROR("Could not get part ID");
+               return retval;
+       }
+
+       switch (part_id) {
+               case LPC1311:
+               case LPC1311_1:
+                       bank->size = 8 * 1024;
+                       break;
+
+               case LPC11U12_201_1:
+               case LPC11U12_201_2:
+         case LPC1342:
+           bank->size = 16 * 1024;
+           break;
+
+         case LPC11U13_201_1:
+         case LPC11U13_201_2:
+         case LPC11U23_301:
+                       bank->size = 24 * 1024;
+                       break;
+
+         case LPC11U14_201_1:
+         case LPC11U14_201_2:
+         case LPC11U24_301:
+               case LPC11U24_401:
+               case LPC1313:
+               case LPC1313_1:
+               case LPC1315:
+               case LPC1343:
+               case LPC1345:
+                       bank->size = 32 * 1024;
+                       break;
+
+               case LPC11U34_311:
+                       bank->size = 40 * 1024;
+                       break;
+
+               case LPC11U34_421:
+               case LPC1316:
+               case LPC1346:
+                       bank->size = 48 * 1024;
+                       break;
+
+               case LPC11U35_401:
+               case LPC11U35_501:
+               case LPC1317:
+               case LPC1347:
+                 bank->size = 64 * 1024;
+                       break;
+
+               case LPC11U36_401:
+                       bank->size = 96 * 1024;
+                       break;
+
+               case LPC11U37_401:
+               case LPC11U37H_401:
+               case LPC11U37_501:
+                       bank->size = 128 * 1024;
+                       break;
+       }
+
+       return ERROR_OK;
+}
+
 static int lpc2000_probe(struct flash_bank *bank)
 {
-       /* we can't probe on an lpc2000 if this is an lpc2xxx, it has the 
configured flash */
+       struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
+
+       if (!lpc2000_info->probed) {
+               if (bank->size == 0)
+                       lpc2000_auto_probe_flash(bank);
+
+               lpc2000_build_sector_list(bank);
+               lpc2000_info->probed = true;
+       }
+
        return ERROR_OK;
 }
 
@@ -937,23 +1109,15 @@ COMMAND_HANDLER(lpc2000_handle_part_id_command)
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       uint32_t param_table[5] = {0};
-       uint32_t result_table[4];
-       struct working_area *iap_working_area;
-
-       retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
-
-       if (retval != ERROR_OK)
-               return retval;
-
-       int status_code = lpc2000_iap_call(bank, iap_working_area, 54, 
param_table, result_table);
+       uint32_t part_id;
+       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");
                } else
                        command_print(CMD_CTX, "lpc2000 IAP returned status 
code %i", status_code);
        } else
-               command_print(CMD_CTX, "lpc2000 part id: 0x%8.8" PRIx32, 
result_table[0]);
+               command_print(CMD_CTX, "lpc2000 part id: 0x%8.8" PRIx32, 
part_id);
 
        return retval;
 }
diff --git a/tcl/target/lpc1xxx.cfg b/tcl/target/lpc1xxx.cfg
index 304504c..42d5707 100644
--- a/tcl/target/lpc1xxx.cfg
+++ b/tcl/target/lpc1xxx.cfg
@@ -99,17 +99,23 @@ $_TARGETNAME configure -work-area-phys 0x10000000 
-work-area-size $_CPURAMSIZE
 # The LPC11xx devies have 8/16/24/32/48/56/64kB of flash memory (at 0x00000000)
 # The LPC12xx devies have 32/48/64/80/96/128kB of flash memory (at 0x00000000)
 # The LPC11Uxx devies have 16/24/32/40/48/64/96/128kB of flash memory (at 
0x00000000)
-# The LPC13xx devies have 8/16/32kB of flash memory (at 0x00000000)
+# The LPC13xx devies have 8/16/32/48/64kB of flash memory (at 0x00000000)
 # The LPC17xx devies have 32/64/128/256/512kB of flash memory (at 0x00000000)
 #
-# All are compatible with the "lpc1700" variant of the LPC2000 flash driver
-# (same cmd51 destination boundary alignment, and all three support 256 byte
-# transfers).
+# All would be compatible with the "lpc1700" variant of the LPC2000 flash 
driver
+# (same cmd51 destination boundary alignment, and all three support 256 byte 
transfers),
+# but have a fixed sector size of 4kB, as opposed to the LPC1700 parts which 
have a mix
+# of 4 kB and 32 kB sectors. A new type called lpc1100 has been created.
 #
 # flash bank <name> lpc2000 <base> <size> 0 0 <target#> <variant> <clock> 
[calc checksum]
 set _FLASHNAME $_CHIPNAME.flash
+if { $_CHIPSERIES == "lpc1100" || $_CHIPSERIES == "lpc1300" } {
+       set FLASH_VARIANT "lpc1100"
+} else {
+       set FLASH_VARIANT "lpc1700"
+}
 flash bank $_FLASHNAME lpc2000 0x0 $_CPUROMSIZE 0 0 $_TARGETNAME \
-       lpc1700 $_CCLK calc_checksum
+       $FLASH_VARIANT $_CCLK calc_checksum
 
 if { $_CHIPSERIES == "lpc1100" || $_CHIPSERIES == "lpc1200" || $_CHIPSERIES == 
"lpc1300" } {
        # Do not remap 0x0000-0x0200 to anything but the flash (i.e. select

-- 

------------------------------------------------------------------------------
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to