Fix sector layout for 504-KiB LPC2000 devices
[fw/openocd] / src / flash / nor / lpc2000.c
index 438ab544c21be51684a06377d3febb87768c91ef..fea663e9478913830cdf21186edff6dac4328d09 100644 (file)
@@ -26,7 +26,6 @@
 #endif
 
 #include "imp.h"
-#include "lpc2000.h"
 #include <helper/binarybuffer.h>
 #include <target/algorithm.h>
 #include <target/arm_opcodes.h>
  * - 176x (tested with LPC1768)
  */
 
+typedef enum
+{
+       lpc2000_v1,
+       lpc2000_v2,
+       lpc1700
+} lpc2000_variant;
+
+struct lpc2000_flash_bank
+{
+       lpc2000_variant variant;
+       struct working_area *iap_working_area;
+       uint32_t cclk;
+       int cmd51_dst_boundary;
+       int cmd51_can_256b;
+       int cmd51_can_8192b;
+       int calc_checksum;
+       uint32_t cmd51_max_buffer;
+       int checksum_vector;
+};
+
+enum lpc2000_status_codes
+{
+       LPC2000_CMD_SUCCESS = 0,
+       LPC2000_INVALID_COMMAND = 1,
+       LPC2000_SRC_ADDR_ERROR = 2,
+       LPC2000_DST_ADDR_ERROR = 3,
+       LPC2000_SRC_ADDR_NOT_MAPPED = 4,
+       LPC2000_DST_ADDR_NOT_MAPPED = 5,
+       LPC2000_COUNT_ERROR = 6,
+       LPC2000_INVALID_SECTOR = 7,
+       LPC2000_SECTOR_NOT_BLANK = 8,
+       LPC2000_SECTOR_NOT_PREPARED = 9,
+       LPC2000_COMPARE_ERROR = 10,
+       LPC2000_BUSY = 11,
+       LPC2000_PARAM_ERROR = 12,
+       LPC2000_ADDR_ERROR = 13,
+       LPC2000_ADDR_NOT_MAPPED = 14,
+       LPC2000_CMD_NOT_LOCKED = 15,
+       LPC2000_INVALID_CODE = 16,
+       LPC2000_INVALID_BAUD_RATE = 17,
+       LPC2000_INVALID_STOP_BIT = 18,
+       LPC2000_CRP_ENABLED = 19
+
+};
+
 static int lpc2000_build_sector_list(struct flash_bank *bank)
 {
        struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
@@ -152,10 +196,13 @@ static int lpc2000_build_sector_list(struct flash_bank *bank)
                        case 256 * 1024:
                                bank->num_sectors = 15;
                                break;
-                       case 512 * 1024:
                        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);
@@ -166,7 +213,7 @@ static int lpc2000_build_sector_list(struct flash_bank *bank)
 
                for (i = 0; i < bank->num_sectors; i++)
                {
-                       if ((i >= 0) && (i < 8))
+                       if (i < 8)
                        {
                                bank->sectors[i].offset = offset;
                                bank->sectors[i].size = 4 * 1024;
@@ -174,7 +221,7 @@ static int lpc2000_build_sector_list(struct flash_bank *bank)
                                bank->sectors[i].is_erased = -1;
                                bank->sectors[i].is_protected = 1;
                        }
-                       if ((i >= 8) && (i < 22))
+                       else if (i < 22)
                        {
                                bank->sectors[i].offset = offset;
                                bank->sectors[i].size = 32 * 1024;
@@ -182,7 +229,7 @@ static int lpc2000_build_sector_list(struct flash_bank *bank)
                                bank->sectors[i].is_erased = -1;
                                bank->sectors[i].is_protected = 1;
                        }
-                       if ((i >= 22) && (i < 27))
+                       else if (i < 28)
                        {
                                bank->sectors[i].offset = offset;
                                bank->sectors[i].size = 4 * 1024;
@@ -346,7 +393,7 @@ static int lpc2000_iap_call(struct flash_bank *bank, int code, uint32_t param_ta
                        init_reg_param(&reg_params[4], "lr", 32, PARAM_OUT);
                        buf_set_u32(reg_params[4].value, 0, 32, (lpc2000_info->iap_working_area->address + 0x04) | 1); /* bit0 of LR = 1 to return in Thumb mode */
 
-                       target_run_algorithm(target, 2, mem_params, 5, reg_params, lpc2000_info->iap_working_area->address, lpc2000_info->iap_working_area->address + 0x4, 10000, &armv7m_info);
+                       target_run_algorithm(target, 2, mem_params, 5, reg_params, lpc2000_info->iap_working_area->address, 0, 10000, &armv7m_info);
                        break;
                case lpc2000_v1:
                case lpc2000_v2:
@@ -594,7 +641,6 @@ static int lpc2000_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offs
        if ((offset == 0) && (count >= 0x20) && lpc2000_info->calc_checksum)
        {
                uint32_t checksum = 0;
-               int i;
                for (i = 0; i < 8; i++)
                {
                        LOG_DEBUG("Vector 0x%2.2x: 0x%8.8" PRIx32, i * 4, buf_get_u32(buffer + (i * 4), 0, 32));
@@ -740,7 +786,7 @@ static int lpc2000_protect_check(struct flash_bank *bank)
        return ERROR_OK;
 }
 
-static int lpc2000_info(struct flash_bank *bank, char *buf, int buf_size)
+static int get_lpc2000_info(struct flash_bank *bank, char *buf, int buf_size)
 {
        struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
 
@@ -814,9 +860,10 @@ struct flash_driver lpc2000_flash = {
        .erase = lpc2000_erase,
        .protect = lpc2000_protect,
        .write = lpc2000_write,
+       .read = default_flash_read,
        .probe = lpc2000_probe,
        .auto_probe = lpc2000_probe,
        .erase_check = lpc2000_erase_check,
        .protect_check = lpc2000_protect_check,
-       .info = lpc2000_info,
+       .info = get_lpc2000_info,
 };