This is an automated email from Gerrit.

J Evans (g...@novadsp.com) just uploaded a new patch set to Gerrit, which you 
can find at http://openocd.zylin.com/5161

-- gerrit

commit b879e1ea5e08b6814ecfd808f44625a39ca3f681
Author: g40 <g...@novadsp.com>
Date:   Fri May 10 12:23:48 2019 +0100

    flash/nor: Add support for NXP LPC804
    
    Add support for the NXP LPC804 Cortex M0 part.
    
    Change-Id: I4ce16ae5ebf1b85a4e0560f642fd12c2df945f46
    Signed-off-by: J Evans <g...@novadsp.com>

diff --git a/src/flash/nor/lpc2000.c b/src/flash/nor/lpc2000.c
index cb3f58e..b292aac 100644
--- a/src/flash/nor/lpc2000.c
+++ b/src/flash/nor/lpc2000.c
@@ -15,6 +15,9 @@
  *   LPC8N04/HNS31xx support Copyright (C) 2018                            *
  *   by Jean-Christian de Rivaz jcdr [at] innodelec [dot] ch               *
  *                                                                         *
+ *   LPC804 support Copyright (C) 2019                                     *
+ *   by Jerry Evans g40 [at] novadsp [dot] com                             *
+ *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
  *   the Free Software Foundation; either version 2 of the License, or     *
@@ -265,6 +268,13 @@
 #define LPC824_201     0x00008241
 #define LPC824_201_1   0x00008242
 
+/* UM11065 section 4.5.12 Table 20 */
+#define LPC804_101_64 0x00008040
+#define LPC804_101_20 0x00008041
+#define LPC804_101_24 0x00008042
+#define LPC804_111_24 0x00008043
+#define LPC804_101_33 0x00008044
+
 #define LPC8N04        0x00008A04
 #define NHS3100        0x4e310020
 #define NHS3152        0x4e315220
@@ -282,6 +292,8 @@
 #define IAP_CODE_LEN 0x34
 
 #define LPC11xx_REG_SECTORS    24
+/* UM11065 PP31 */
+#define LPC800_IAP_ENTRY 0x0F001FF1
 
 typedef enum {
        lpc2000_v1,
@@ -289,6 +301,7 @@ typedef enum {
        lpc1700,
        lpc4300,
        lpc800,
+       lpc804,
        lpc1100,
        lpc1500,
        lpc54100,
@@ -308,6 +321,20 @@ struct lpc2000_flash_bank {
        bool probed;
 };
 
+enum lpc2000_op_codes {
+       IAP_INIT = 49,
+       IAP_PREPARE = 50,
+       IAP_COPY_RAM2FLASH,
+       IAP_ERASE_SECTOR,
+       IAP_CHECK_SECTOR_BLANK,
+       IAP_READ_PART_ID,
+       IAP_READ_BOOT_VERSION,
+       IAP_COMPARE,
+       IAP_REINVOKE_ISP,
+       IAP_READ_UID,
+       IAP_ERASE_PAGE
+};
+
 enum lpc2000_status_codes {
        LPC2000_CMD_SUCCESS = 0,
        LPC2000_INVALID_COMMAND = 1,
@@ -565,6 +592,23 @@ static int lpc2000_build_sector_list(struct flash_bank 
*bank)
                                LOG_ERROR("BUG: unknown bank->size 
encountered");
                                exit(-1);
                }
+       } else if (lpc2000_info->variant == lpc804) {
+               lpc2000_info->cmd51_dst_boundary = 64;
+               lpc2000_info->checksum_vector = 7;
+               /* NXP forum answer implies 48 but had problems with that */
+               lpc2000_info->iap_max_stack = 208;
+               /* LPC804 has 8 kB of SRAM */
+               lpc2000_info->cmd51_max_buffer = 256;
+
+               switch (bank->size) {
+                       case 32 * 1024:
+                               lpc2000_info->cmd51_max_buffer = 1024;
+                               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);
 
@@ -698,6 +742,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 lpc804:
                case lpc1100:
                case lpc1500:
                case lpc1700:
@@ -719,7 +764,7 @@ static int lpc2000_iap_working_area_init(struct flash_bank 
*bank, struct working
 
        int retval = target_write_memory(target, (*iap_working_area)->address, 
4, 2, jump_gate);
        if (retval != ERROR_OK) {
-               LOG_ERROR("Write memory at address " TARGET_ADDR_FMT " failed 
(check work_area definition)",
+               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);
        }
@@ -740,6 +785,11 @@ static int lpc2000_iap_call(struct flash_bank *bank, 
struct working_area *iap_wo
        uint32_t iap_entry_point = 0;   /* to make compiler happier */
 
        switch (lpc2000_info->variant) {
+               case lpc804:
+                       armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+                       armv7m_info.core_mode = ARM_MODE_THREAD;
+                       iap_entry_point = LPC800_IAP_ENTRY;
+                       break;
                case lpc800:
                case lpc1100:
                case lpc1700:
@@ -803,6 +853,7 @@ static int lpc2000_iap_call(struct flash_bank *bank, struct 
working_area *iap_wo
 
        switch (lpc2000_info->variant) {
                case lpc800:
+               case lpc804:
                case lpc1100:
                case lpc1500:
                case lpc1700:
@@ -884,7 +935,7 @@ static int lpc2000_iap_blank_check(struct flash_bank *bank, 
int first, int last)
        for (int i = first; i <= last && retval == ERROR_OK; i++) {
                /* check single sector */
                param_table[0] = param_table[1] = i;
-               int status_code = lpc2000_iap_call(bank, iap_working_area, 53, 
param_table, result_table);
+               int status_code = lpc2000_iap_call(bank, iap_working_area, 
IAP_CHECK_SECTOR_BLANK, param_table, result_table);
 
                switch (status_code) {
                        case ERROR_FLASH_OPERATION_FAILED:
@@ -937,6 +988,8 @@ 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], "lpc804") == 0) {
+               lpc2000_info->variant = lpc804;
        } else if (strcmp(CMD_ARGV[6], "lpc1100") == 0) {
                lpc2000_info->variant = lpc1100;
        } else if (strcmp(CMD_ARGV[6], "lpc1500") == 0) {
@@ -993,6 +1046,8 @@ static int lpc2000_erase(struct flash_bank *bank, int 
first, int last)
 
        if (lpc2000_info->variant == lpc4300)
                param_table[2] = lpc2000_info->lpc4300_bank;
+       else if (lpc2000_info->variant == lpc804)
+               param_table[2] = 0;
        else
                param_table[2] = lpc2000_info->cclk;
 
@@ -1006,10 +1061,10 @@ static int lpc2000_erase(struct flash_bank *bank, int 
first, int last)
 
        if (lpc2000_info->variant == lpc4300)
                /* Init IAP Anyway */
-               lpc2000_iap_call(bank, iap_working_area, 49, param_table, 
result_table);
+               lpc2000_iap_call(bank, iap_working_area, IAP_INIT, param_table, 
result_table);
 
        /* Prepare sectors */
-       int status_code = lpc2000_iap_call(bank, iap_working_area, 50, 
param_table, result_table);
+       int status_code = lpc2000_iap_call(bank, iap_working_area, IAP_PREPARE, 
param_table, result_table);
        switch (status_code) {
                case ERROR_FLASH_OPERATION_FAILED:
                        retval = ERROR_FLASH_OPERATION_FAILED;
@@ -1030,8 +1085,10 @@ static int lpc2000_erase(struct flash_bank *bank, int 
first, int last)
                param_table[2] = lpc2000_info->cclk;
                if (lpc2000_info->variant == lpc4300)
                        param_table[3] = lpc2000_info->lpc4300_bank;
+               else if (lpc2000_info->variant == lpc804)
+                       param_table[2] = 0;
 
-               status_code = lpc2000_iap_call(bank, iap_working_area, 52, 
param_table, result_table);
+               status_code = lpc2000_iap_call(bank, iap_working_area, 
IAP_ERASE_SECTOR, param_table, result_table);
                switch (status_code) {
                        case ERROR_FLASH_OPERATION_FAILED:
                                retval = ERROR_FLASH_OPERATION_FAILED;
@@ -1134,7 +1191,7 @@ static int lpc2000_write(struct flash_bank *bank, const 
uint8_t *buffer, uint32_
 
        if (lpc2000_info->variant == lpc4300)
                /* Init IAP Anyway */
-               lpc2000_iap_call(bank, iap_working_area, 49, param_table, 
result_table);
+               lpc2000_iap_call(bank, iap_working_area, IAP_INIT, param_table, 
result_table);
 
        while (bytes_remaining > 0) {
                uint32_t thisrun_bytes;
@@ -1149,10 +1206,12 @@ static int lpc2000_write(struct flash_bank *bank, const 
uint8_t *buffer, uint32_
 
                if (lpc2000_info->variant == lpc4300)
                        param_table[2] = lpc2000_info->lpc4300_bank;
+               else if (lpc2000_info->variant == lpc804)
+                       param_table[2] = 0;
                else
                        param_table[2] = lpc2000_info->cclk;
 
-               int status_code = lpc2000_iap_call(bank, iap_working_area, 50, 
param_table, result_table);
+               int status_code = lpc2000_iap_call(bank, iap_working_area, 
IAP_PREPARE, param_table, result_table);
                switch (status_code) {
                        case ERROR_FLASH_OPERATION_FAILED:
                                retval = ERROR_FLASH_OPERATION_FAILED;
@@ -1186,15 +1245,18 @@ static int lpc2000_write(struct flash_bank *bank, const 
uint8_t *buffer, uint32_
                        free(last_buffer);
                }
 
-               LOG_DEBUG("writing 0x%" PRIx32 " bytes to address " 
TARGET_ADDR_FMT,
-                               thisrun_bytes, bank->base + offset + 
bytes_written);
+               LOG_DEBUG("writing 0x%" PRIx32 " bytes to address 0x%" PRIx32, 
thisrun_bytes,
+                               (unsigned int) bank->base + offset + 
bytes_written);
 
                /* Write data */
                param_table[0] = bank->base + offset + bytes_written;
                param_table[1] = download_area->address;
                param_table[2] = thisrun_bytes;
                param_table[3] = lpc2000_info->cclk;
-               status_code = lpc2000_iap_call(bank, iap_working_area, 51, 
param_table, result_table);
+               if (lpc2000_info->variant == lpc804)
+                       param_table[3] = 0;
+
+               status_code = lpc2000_iap_call(bank, iap_working_area, 
IAP_COPY_RAM2FLASH, param_table, result_table);
                switch (status_code) {
                        case ERROR_FLASH_OPERATION_FAILED:
                                retval = ERROR_FLASH_OPERATION_FAILED;
@@ -1245,7 +1307,7 @@ static int get_lpc2000_part_id(struct flash_bank *bank, 
uint32_t *part_id)
 
        /* The status seems to be bogus with the part ID command on some IAP
           firmwares, so ignore it. */
-       lpc2000_iap_call(bank, iap_working_area, 54, param_table, result_table);
+       lpc2000_iap_call(bank, iap_working_area, IAP_READ_PART_ID, param_table, 
result_table);
 
        struct target *target = bank->target;
        target_free_working_area(target, iap_working_area);
@@ -1482,6 +1544,15 @@ static int lpc2000_auto_probe_flash(struct flash_bank 
*bank)
                        bank->size = 16 * 1024;
                        break;
 
+               case LPC804_101_64:
+               case LPC804_101_20:
+               case LPC804_101_24:
+               case LPC804_111_24:
+               case LPC804_101_33:
+                       lpc2000_info->variant = lpc804;
+                       bank->size = 32 * 1024;
+                       break;
+
                case LPC824_201:
                case LPC824_201_1:
                        lpc2000_info->variant = lpc800;

-- 


_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to