/* * This file is part of the Black Magic Debug project. * * Copyright (C) 2011 Mike Smith * Copyright (C) 2016 Gareth McMullin * * 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 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "general.h" #include "target.h" #include "target_internal.h" #include "cortexm.h" #include "lpc_common.h" #define IAP_PGM_CHUNKSIZE 512 /* should fit in RAM on any device */ #define MIN_RAM_SIZE 1024 #define RAM_USAGE_FOR_IAP_ROUTINES 32 /* IAP routines use 32 bytes at top of ram */ #define IAP_ENTRY_MOST 0x1fff1ff1 /* all except LPC802, LPC804 & LPC84x */ #define IAP_ENTRY_84x 0x0f001ff1 /* LPC802, LPC804 & LPC84x */ #define IAP_RAM_BASE 0x10000000 #define LPC11XX_DEVICE_ID 0x400483F4 #define LPC8XX_DEVICE_ID 0x400483F8 /* * CHIP Ram Flash page sector Rsvd pages EEPROM * LPX80x 2k 16k 64 1024 2 * LPC804 4k 32k 64 1024 2 * LPC8N04 8k 32k 64 1024 32 * LPC810 1k 4k 64 1024 0 * LPC811 2k 8k 64 1024 0 * LPC812 4k 16k 64 1024 * LPC822 4k 16k 64 1024 * LPC822 8k 32k 64 1024 * LPC832 4k 16k 64 1024 * LPC834 4k 32k 64 1024 * LPC844 8k 64k 64 1024 * LPC845 16k 64k 64 1024 */ static bool lpc11xx_read_uid(target *t, int argc, const char *argv[]) { (void)argc; (void)argv; struct lpc_flash *f = (struct lpc_flash *)t->flash; uint8_t uid[16]; if (lpc_iap_call(f, uid, IAP_CMD_READUID)) return false; tc_printf(t, "UID: 0x"); for (uint32_t i = 0; i < sizeof(uid); ++i) tc_printf(t, "%02x", uid[i]); tc_printf(t, "\n"); return true; } const struct command_s lpc11xx_cmd_list[] = { {"readuid", lpc11xx_read_uid, "Read out the 16-byte UID."}, {NULL, NULL, NULL} }; void lpc11xx_add_flash(target *t, uint32_t addr, size_t len, size_t erasesize, uint32_t iap_entry, uint8_t reserved_pages) { struct lpc_flash *lf = lpc_add_flash(t, addr, len); lf->f.blocksize = erasesize; lf->f.buf_size = IAP_PGM_CHUNKSIZE; lf->f.write = lpc_flash_write_magic_vect; lf->iap_entry = iap_entry; lf->iap_ram = IAP_RAM_BASE; lf->iap_msp = IAP_RAM_BASE + MIN_RAM_SIZE - RAM_USAGE_FOR_IAP_ROUTINES; lf->reserved_pages = reserved_pages; } bool lpc11xx_probe(target *t) { uint32_t idcode; /* read the device ID register */ /* For LPC11xx & LPC11Cxx see UM10398 Rev. 12.4 Chapter 26.5.11 Table 387 * For LPC11Uxx see UM10462 Rev. 5.5 Chapter 20.13.11 Table 377 * Nota Bene: the DEVICE_ID register at address 0x400483F4 is not valid * for: * 1) the LPC11xx & LPC11Cxx "XL" series, see UM10398 Rev.12.4 Chapter 3.1 * 2) the LPC11U3x series, see UM10462 Rev.5.5 Chapter 3.1 * But see the comment for the LPC8xx series below. */ idcode = target_mem_read32(t, LPC11XX_DEVICE_ID); switch (idcode) { case 0x0A07102B: /* LPC1110 - 4K Flash 1K SRAM */ case 0x1A07102B: /* LPC1110 - 4K Flash 1K SRAM */ case 0x0A16D02B: /* LPC1111/002 - 8K Flash 2K SRAM */ case 0x1A16D02B: /* LPC1111/002 - 8K Flash 2K SRAM */ case 0x041E502B: /* LPC1111/101 - 8K Flash 2K SRAM */ case 0x2516D02B: /* LPC1111/101/102 - 8K Flash 2K SRAM */ case 0x0416502B: /* LPC1111/201 - 8K Flash 4K SRAM */ case 0x2516902B: /* LPC1111/201/202 - 8K Flash 4K SRAM */ case 0x0A23902B: /* LPC1112/102 - 16K Flash 4K SRAM */ case 0x1A23902B: /* LPC1112/102 - 16K Flash 4K SRAM */ case 0x042D502B: /* LPC1112/101 - 16K Flash 2K SRAM */ case 0x2524D02B: /* LPC1112/101/102 - 16K Flash 2K SRAM */ case 0x0425502B: /* LPC1112/201 - 16K Flash 4K SRAM */ case 0x2524902B: /* LPC1112/201/202 - 16K Flash 4K SRAM */ case 0x0434502B: /* LPC1113/201 - 24K Flash 4K SRAM */ case 0x2532902B: /* LPC1113/201/202 - 24K Flash 4K SRAM */ case 0x0434102B: /* LPC1113/301 - 24K Flash 8K SRAM */ case 0x2532102B: /* LPC1113/301/302 - 24K Flash 8K SRAM */ case 0x0A40902B: /* LPC1114/102 - 32K Flash 4K SRAM */ case 0x1A40902B: /* LPC1114/102 - 32K Flash 4K SRAM */ case 0x0444502B: /* LPC1114/201 - 32K Flash 4K SRAM */ case 0x2540902B: /* LPC1114/201/202 - 32K Flash 4K SRAM */ case 0x0444102B: /* LPC1114/301 - 32K Flash 8K SRAM */ case 0x2540102B: /* LPC1114/301/302 & LPC11D14/302 - 32K Flash 8K SRAM */ case 0x00050080: /* LPC1115/303 - 64K Flash 8K SRAM (redundant? see UM10398, XL has Device ID at different address) */ case 0x1421102B: /* LPC11c12/301 - 16K Flash 8K SRAM */ case 0x1440102B: /* LPC11c14/301 - 32K Flash 8K SRAM */ case 0x1431102B: /* LPC11c22/301 - 16K Flash 8K SRAM */ case 0x1430102B: /* LPC11c24/301 - 32K Flash 8K SRAM */ case 0x095C802B: /* LPC11u12x/201 - 16K Flash 4K SRAM */ case 0x295C802B: /* LPC11u12x/201 - 16K Flash 4K SRAM */ case 0x097A802B: /* LPC11u13/201 - 24K Flash 4K SRAM */ case 0x297A802B: /* LPC11u13/201 - 24K Flash 4K SRAM */ case 0x0998802B: /* LPC11u14/201 - 32K Flash 4K SRAM */ case 0x2998802B: /* LPC11u14/201 - 32K Flash 4K SRAM */ case 0x2954402B: /* LPC11u22/301 - 16K Flash 6K SRAM */ case 0x2972402B: /* LPC11u23/301 - 24K Flash 6K SRAM */ case 0x2988402B: /* LPC11u24x/301 - 32K Flash 6K SRAM */ case 0x2980002B: /* LPC11u24x/401 - 32K Flash 8K SRAM */ t->driver = "LPC11xx"; target_add_ram(t, 0x10000000, 0x2000); lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC11xx"); return true; case 0x0A24902B: case 0x1A24902B: t->driver = "LPC1112"; target_add_ram(t, 0x10000000, 0x1000); lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x1000, IAP_ENTRY_MOST, 0); return true; case 0x1000002b: // FX LPC11U6 32 kB SRAM/256 kB flash (max) t->driver = "LPC11U6"; target_add_ram(t, 0x10000000, 0x8000); lpc11xx_add_flash(t, 0x00000000, 0x40000, 0x1000, IAP_ENTRY_MOST, 0); return true; case 0x3000002B: case 0x3D00002B: t->driver = "LPC1343"; target_add_ram(t, 0x10000000, 0x2000); lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x1000, IAP_ENTRY_MOST, 0); return true; case 0x00008A04: /* LPC8N04 (see UM11074 Rev.1.3 section 4.5.19) */ t->driver = "LPC8N04"; target_add_ram(t, 0x10000000, 0x2000); /* UM11074/ Flash controller/15.2: The two topmost sectors * contain the initialization code and IAP firmware. * Do not touch them! */ lpc11xx_add_flash(t, 0x00000000, 0x7800, 0x400, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC8N04"); return true; } if ((t->t_designer != AP_DESIGNER_SPECULAR) && idcode) { DEBUG_INFO("LPC11xx: Unknown IDCODE 0x%08" PRIx32 "\n", idcode); } /* For LPC802, see UM11045 Rev. 1.4 Chapter 6.6.29 Table 84 * For LPC804, see UM11065 Rev. 1.0 Chapter 6.6.31 Table 87 * For LPC81x, see UM10601 Rev. 1.6 Chapter 4.6.33 Table 50 * For LPC82x, see UM10800 Rev. 1.2 Chapter 5.6.34 Table 55 * For LPC83x, see UM11021 Rev. 1.1 Chapter 5.6.34 Table 53 * For LPC84x, see UM11029 Rev. 1.4 Chapter 8.6.49 Table 174 * * Not documented, but the DEVICE_ID register at address 0x400483F8 * for the LPC8xx series is also valid for the LPC11xx "XL" and the * LPC11U3x variants. */ idcode = target_mem_read32(t, LPC8XX_DEVICE_ID); switch (idcode) { case 0x00008021: /* LPC802M001JDH20 - 16K Flash 2K SRAM */ case 0x00008022: /* LPC802M011JDH20 */ case 0x00008023: /* LPC802M001JDH16 */ case 0x00008024: /* LPC802M001JHI33 */ t->driver = "LPC802"; target_add_ram(t, 0x10000000, 0x800); lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_84x, 2); target_add_commands(t, lpc11xx_cmd_list, "LPC802"); return true; case 0x00008040: /* LPC804M101JBD64 - 32K Flash 4K SRAM */ case 0x00008041: /* LPC804M101JDH20 */ case 0x00008042: /* LPC804M101JDH24 */ case 0x00008043: /* LPC804M111JDH24 */ case 0x00008044: /* LPC804M101JHI33 */ t->driver = "LPC804"; target_add_ram(t, 0x10000000, 0x1000); lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_84x, 2); target_add_commands(t, lpc11xx_cmd_list, "LPC804"); return true; case 0x00008100: /* LPC810M021FN8 - 4K Flash 1K SRAM */ case 0x00008110: /* LPC811M001JDH16 - 8K Flash 2K SRAM */ case 0x00008120: /* LPC812M101JDH16 - 16K Flash 4K SRAM */ case 0x00008121: /* LPC812M101JD20 - 16K Flash 4K SRAM */ case 0x00008122: /* LPC812M101JDH20 / LPC812M101JTB16 - 16K Flash 4K SRAM */ t->driver = "LPC81x"; target_add_ram(t, 0x10000000, 0x1000); lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC81x"); return true; case 0x00008221: /* LPC822M101JHI33 - 16K Flash 4K SRAM */ case 0x00008222: /* LPC822M101JDH20 */ case 0x00008241: /* LPC824M201JHI33 - 32K Flash 8K SRAM */ case 0x00008242: /* LPC824M201JDH20 */ t->driver = "LPC82x"; target_add_ram(t, 0x10000000, 0x2000); lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC82x"); return true; case 0x00008322: /* LPC832M101FDH20 - 16K Flash 4K SRAM */ t->driver = "LPC832"; target_add_ram(t, 0x10000000, 0x1000); lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC832"); return true; case 0x00008341: /* LPC834M101FHI33 - 32K Flash 4K SRAM */ t->driver = "LPC834"; target_add_ram(t, 0x10000000, 0x1000); lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC834"); return true; case 0x00008441: /* LPC844M201JBD64 - 64K Flash 8K SRAM */ case 0x00008442: /* LPC844M201JBD48 */ case 0x00008443: /* LPC844M201JHI48, note UM11029 Rev.1.4 table 29 is wrong, see table 174 (in same manual) */ case 0x00008444: /* LPC844M201JHI33 */ t->driver = "LPC844"; target_add_ram(t, 0x10000000, 0x2000); lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x400, IAP_ENTRY_84x, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC844"); return true; case 0x00008451: /* LPC845M301JBD64 - 64K Flash 16K SRAM */ case 0x00008452: /* LPC845M301JBD48 */ case 0x00008453: /* LPC845M301JHI48 */ case 0x00008454: /* LPC845M301JHI33 */ t->driver = "LPC845"; target_add_ram(t, 0x10000000, 0x4000); lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x400, IAP_ENTRY_84x, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC845"); return true; case 0x0003D440: /* LPC11U34/311 - 40K Flash 8K SRAM */ case 0x0001cc40: /* LPC11U34/421 - 48K Flash 8K SRAM */ case 0x0001BC40: /* LPC11U35/401 - 64K Flash 8K SRAM */ case 0x0000BC40: /* LPC11U35/501 - 64K Flash 8K SRAM */ case 0x00019C40: /* LPC11U36/401 - 96K Flash 8K SRAM */ case 0x00017C40: /* LPC11U37FBD48/401 - 128K Flash 8K SRAM */ case 0x00007C44: /* LPC11U37HFBD64/401 */ case 0x00007C40: /* LPC11U37FBD64/501 */ t->driver = "LPC11U3x"; target_add_ram(t, 0x10000000, 0x2000); lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC11U3x"); return true; case 0x00010013: /* LPC1111/103 - 8K Flash 2K SRAM */ case 0x00010012: /* LPC1111/203 - 8K Flash 4K SRAM */ case 0x00020023: /* LPC1112/103 - 16K Flash 2K SRAM */ case 0x00020022: /* LPC1112/203 - 16K Flash 4K SRAM */ case 0x00030030: /* LPC1113/303 - 24K Flash 8K SRAM */ case 0x00030032: /* LPC1113/203 - 24K Flash 4K SRAM */ case 0x00040040: /* LPC1114/303 - 32K Flash 8K SRAM */ case 0x00040042: /* LPC1114/203 - 32K Flash 4K SRAM */ case 0x00040060: /* LPC1114/323 - 48K Flash 8K SRAM */ case 0x00040070: /* LPC1114/333 - 56K Flash 8K SRAM */ case 0x00050080: /* LPC1115/303 - 64K Flash 8K SRAM */ t->driver = "LPC11xx-XL"; target_add_ram(t, 0x10000000, 0x2000); lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC11xx-XL"); return true; } if (idcode) { DEBUG_INFO("LPC8xx: Unknown IDCODE 0x%08" PRIx32 "\n", idcode); } return false; }