You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

923 lines
28KB

  1. /***************************************************************************
  2. * Copyright (C) 2005 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * LPC1700 support Copyright (C) 2009 by Audrius Urmanavicius *
  6. * didele.deze@gmail.com *
  7. * *
  8. * This program is free software; you can redistribute it and/or modify *
  9. * it under the terms of the GNU General Public License as published by *
  10. * the Free Software Foundation; either version 2 of the License, or *
  11. * (at your option) any later version. *
  12. * *
  13. * This program is distributed in the hope that it will be useful, *
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  16. * GNU General Public License for more details. *
  17. * *
  18. * You should have received a copy of the GNU General Public License *
  19. * along with this program; if not, write to the *
  20. * Free Software Foundation, Inc., *
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
  22. ***************************************************************************/
  23. #ifdef HAVE_CONFIG_H
  24. #include "config.h"
  25. #endif
  26. #include "imp.h"
  27. #include <helper/binarybuffer.h>
  28. #include <target/algorithm.h>
  29. #include <target/arm_opcodes.h>
  30. #include <target/armv7m.h>
  31. /**
  32. * @file
  33. * flash programming support for NXP LPC17xx and LPC2xxx devices.
  34. *
  35. * @todo Provide a way to update CCLK after declaring the flash bank. The value which is correct after chip reset will
  36. * rarely still work right after the clocks switch to use the PLL (e.g. 4MHz --> 100 MHz).
  37. */
  38. /*
  39. * currently supported devices:
  40. * variant 1 (lpc2000_v1):
  41. * - 2104 | 5 | 6
  42. * - 2114 | 9
  43. * - 2124 | 9
  44. * - 2194
  45. * - 2212 | 4
  46. * - 2292 | 4
  47. *
  48. * variant 2 (lpc2000_v2):
  49. * - 213x
  50. * - 214x
  51. * - 2101 | 2 | 3
  52. * - 2364 | 6 | 8
  53. * - 2378
  54. *
  55. * lpc1700:
  56. * - 175x
  57. * - 176x (tested with LPC1768)
  58. *
  59. * lpc4300 (also available as lpc1800 - alias)
  60. * - 43x2 | 3 | 5 | 7 (tested with 4337)
  61. * - 18x2 | 3 | 5 | 7
  62. */
  63. typedef enum {
  64. lpc2000_v1,
  65. lpc2000_v2,
  66. lpc1700,
  67. lpc4300,
  68. } lpc2000_variant;
  69. struct lpc2000_flash_bank {
  70. lpc2000_variant variant;
  71. uint32_t cclk;
  72. int cmd51_dst_boundary;
  73. int cmd51_can_256b;
  74. int cmd51_can_8192b;
  75. int calc_checksum;
  76. uint32_t cmd51_max_buffer;
  77. int checksum_vector;
  78. uint32_t iap_max_stack;
  79. uint32_t cmd51_src_offset;
  80. uint32_t lpc4300_bank;
  81. };
  82. enum lpc2000_status_codes {
  83. LPC2000_CMD_SUCCESS = 0,
  84. LPC2000_INVALID_COMMAND = 1,
  85. LPC2000_SRC_ADDR_ERROR = 2,
  86. LPC2000_DST_ADDR_ERROR = 3,
  87. LPC2000_SRC_ADDR_NOT_MAPPED = 4,
  88. LPC2000_DST_ADDR_NOT_MAPPED = 5,
  89. LPC2000_COUNT_ERROR = 6,
  90. LPC2000_INVALID_SECTOR = 7,
  91. LPC2000_SECTOR_NOT_BLANK = 8,
  92. LPC2000_SECTOR_NOT_PREPARED = 9,
  93. LPC2000_COMPARE_ERROR = 10,
  94. LPC2000_BUSY = 11,
  95. LPC2000_PARAM_ERROR = 12,
  96. LPC2000_ADDR_ERROR = 13,
  97. LPC2000_ADDR_NOT_MAPPED = 14,
  98. LPC2000_CMD_NOT_LOCKED = 15,
  99. LPC2000_INVALID_CODE = 16,
  100. LPC2000_INVALID_BAUD_RATE = 17,
  101. LPC2000_INVALID_STOP_BIT = 18,
  102. LPC2000_CRP_ENABLED = 19,
  103. LPC2000_INVALID_FLASH_UNIT = 20,
  104. LPC2000_USER_CODE_CHECKSUM = 21,
  105. LCP2000_ERROR_SETTING_ACTIVE_PARTITION = 22,
  106. };
  107. static int lpc2000_build_sector_list(struct flash_bank *bank)
  108. {
  109. struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
  110. uint32_t offset = 0;
  111. /* default to a 4096 write buffer */
  112. lpc2000_info->cmd51_max_buffer = 4096;
  113. if (lpc2000_info->variant == lpc2000_v1) {
  114. /* variant 1 has different layout for 128kb and 256kb flashes */
  115. if (bank->size == 128 * 1024) {
  116. bank->num_sectors = 16;
  117. bank->sectors = malloc(sizeof(struct flash_sector) * 16);
  118. for (int i = 0; i < 16; i++) {
  119. bank->sectors[i].offset = offset;
  120. bank->sectors[i].size = 8 * 1024;
  121. offset += bank->sectors[i].size;
  122. bank->sectors[i].is_erased = -1;
  123. bank->sectors[i].is_protected = 1;
  124. }
  125. } else if (bank->size == 256 * 1024) {
  126. bank->num_sectors = 18;
  127. bank->sectors = malloc(sizeof(struct flash_sector) * 18);
  128. for (int i = 0; i < 8; i++) {
  129. bank->sectors[i].offset = offset;
  130. bank->sectors[i].size = 8 * 1024;
  131. offset += bank->sectors[i].size;
  132. bank->sectors[i].is_erased = -1;
  133. bank->sectors[i].is_protected = 1;
  134. }
  135. for (int i = 8; i < 10; i++) {
  136. bank->sectors[i].offset = offset;
  137. bank->sectors[i].size = 64 * 1024;
  138. offset += bank->sectors[i].size;
  139. bank->sectors[i].is_erased = -1;
  140. bank->sectors[i].is_protected = 1;
  141. }
  142. for (int i = 10; i < 18; i++) {
  143. bank->sectors[i].offset = offset;
  144. bank->sectors[i].size = 8 * 1024;
  145. offset += bank->sectors[i].size;
  146. bank->sectors[i].is_erased = -1;
  147. bank->sectors[i].is_protected = 1;
  148. }
  149. } else {
  150. LOG_ERROR("BUG: unknown bank->size encountered");
  151. exit(-1);
  152. }
  153. } else if (lpc2000_info->variant == lpc2000_v2) {
  154. /* variant 2 has a uniform layout, only number of sectors differs */
  155. switch (bank->size) {
  156. case 4 * 1024:
  157. lpc2000_info->cmd51_max_buffer = 1024;
  158. bank->num_sectors = 1;
  159. break;
  160. case 8 * 1024:
  161. lpc2000_info->cmd51_max_buffer = 1024;
  162. bank->num_sectors = 2;
  163. break;
  164. case 16 * 1024:
  165. bank->num_sectors = 4;
  166. break;
  167. case 32 * 1024:
  168. bank->num_sectors = 8;
  169. break;
  170. case 64 * 1024:
  171. bank->num_sectors = 9;
  172. break;
  173. case 128 * 1024:
  174. bank->num_sectors = 11;
  175. break;
  176. case 256 * 1024:
  177. bank->num_sectors = 15;
  178. break;
  179. case 500 * 1024:
  180. bank->num_sectors = 27;
  181. break;
  182. case 512 * 1024:
  183. case 504 * 1024:
  184. bank->num_sectors = 28;
  185. break;
  186. default:
  187. LOG_ERROR("BUG: unknown bank->size encountered");
  188. exit(-1);
  189. break;
  190. }
  191. bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
  192. for (int i = 0; i < bank->num_sectors; i++) {
  193. if (i < 8) {
  194. bank->sectors[i].offset = offset;
  195. bank->sectors[i].size = 4 * 1024;
  196. offset += bank->sectors[i].size;
  197. bank->sectors[i].is_erased = -1;
  198. bank->sectors[i].is_protected = 1;
  199. } else if (i < 22) {
  200. bank->sectors[i].offset = offset;
  201. bank->sectors[i].size = 32 * 1024;
  202. offset += bank->sectors[i].size;
  203. bank->sectors[i].is_erased = -1;
  204. bank->sectors[i].is_protected = 1;
  205. } else if (i < 28) {
  206. bank->sectors[i].offset = offset;
  207. bank->sectors[i].size = 4 * 1024;
  208. offset += bank->sectors[i].size;
  209. bank->sectors[i].is_erased = -1;
  210. bank->sectors[i].is_protected = 1;
  211. }
  212. }
  213. } else if (lpc2000_info->variant == lpc1700) {
  214. switch (bank->size) {
  215. case 32 * 1024:
  216. bank->num_sectors = 8;
  217. break;
  218. case 64 * 1024:
  219. bank->num_sectors = 16;
  220. break;
  221. case 128 * 1024:
  222. bank->num_sectors = 18;
  223. break;
  224. case 256 * 1024:
  225. bank->num_sectors = 22;
  226. break;
  227. case 512 * 1024:
  228. bank->num_sectors = 30;
  229. break;
  230. default:
  231. LOG_ERROR("BUG: unknown bank->size encountered");
  232. exit(-1);
  233. }
  234. bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
  235. for (int i = 0; i < bank->num_sectors; i++) {
  236. bank->sectors[i].offset = offset;
  237. /* sectors 0-15 are 4kB-sized, 16 and above are 32kB-sized for LPC17xx devices */
  238. bank->sectors[i].size = (i < 16) ? 4 * 1024 : 32 * 1024;
  239. offset += bank->sectors[i].size;
  240. bank->sectors[i].is_erased = -1;
  241. bank->sectors[i].is_protected = 1;
  242. }
  243. } else if (lpc2000_info->variant == lpc4300) {
  244. switch (bank->size) {
  245. case 256 * 1024:
  246. bank->num_sectors = 11;
  247. break;
  248. case 384 * 1024:
  249. bank->num_sectors = 13;
  250. break;
  251. case 512 * 1024:
  252. bank->num_sectors = 15;
  253. break;
  254. default:
  255. LOG_ERROR("BUG: unknown bank->size encountered");
  256. exit(-1);
  257. }
  258. bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
  259. for (int i = 0; i < bank->num_sectors; i++) {
  260. bank->sectors[i].offset = offset;
  261. /* sectors 0-7 are 8kB-sized, 8 and above are 64kB-sized for LPC43xx devices */
  262. bank->sectors[i].size = (i < 8) ? 8 * 1024 : 64 * 1024;
  263. offset += bank->sectors[i].size;
  264. bank->sectors[i].is_erased = -1;
  265. bank->sectors[i].is_protected = 1;
  266. }
  267. } else {
  268. LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
  269. exit(-1);
  270. }
  271. return ERROR_OK;
  272. }
  273. /* this function allocates and initializes working area used for IAP algorithm
  274. * uses 52 + max IAP stack bytes working area
  275. * 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait)
  276. * 0x8 to 0x1f: command parameter table (1+5 words)
  277. * 0x20 to 0x33: command result table (1+4 words)
  278. * 0x34 to 0xb3|0x104: stack (only 128b needed for lpc17xx/2000, 208 for lpc43xx)
  279. */
  280. static int lpc2000_iap_working_area_init(struct flash_bank *bank, struct working_area **iap_working_area)
  281. {
  282. struct target *target = bank->target;
  283. struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
  284. if (target_alloc_working_area(target, 0x34 + lpc2000_info->iap_max_stack, iap_working_area) != ERROR_OK) {
  285. LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
  286. return ERROR_FLASH_OPERATION_FAILED;
  287. }
  288. uint8_t jump_gate[8];
  289. /* write IAP code to working area */
  290. switch (lpc2000_info->variant) {
  291. case lpc1700:
  292. case lpc4300:
  293. target_buffer_set_u32(target, jump_gate, ARMV4_5_T_BX(12));
  294. target_buffer_set_u32(target, jump_gate + 4, ARMV5_T_BKPT(0));
  295. break;
  296. case lpc2000_v1:
  297. case lpc2000_v2:
  298. target_buffer_set_u32(target, jump_gate, ARMV4_5_BX(12));
  299. target_buffer_set_u32(target, jump_gate + 4, ARMV4_5_B(0xfffffe, 0));
  300. break;
  301. default:
  302. LOG_ERROR("BUG: unknown lpc2000_info->variant encountered");
  303. exit(-1);
  304. }
  305. int retval = target_write_memory(target, (*iap_working_area)->address, 4, 2, jump_gate);
  306. if (retval != ERROR_OK)
  307. LOG_ERROR("Write memory at address 0x%8.8" PRIx32 " failed (check work_area definition)",
  308. (*iap_working_area)->address);
  309. return retval;
  310. }
  311. /* call LPC1700/LPC2000 IAP function */
  312. static int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_working_area, int code,
  313. uint32_t param_table[5], uint32_t result_table[4])
  314. {
  315. struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
  316. struct target *target = bank->target;
  317. struct arm_algorithm arm_algo; /* for LPC2000 */
  318. struct armv7m_algorithm armv7m_info; /* for LPC1700 */
  319. uint32_t iap_entry_point = 0; /* to make compiler happier */
  320. switch (lpc2000_info->variant) {
  321. case lpc1700:
  322. armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
  323. armv7m_info.core_mode = ARM_MODE_THREAD;
  324. iap_entry_point = 0x1fff1ff1;
  325. break;
  326. case lpc2000_v1:
  327. case lpc2000_v2:
  328. arm_algo.common_magic = ARM_COMMON_MAGIC;
  329. arm_algo.core_mode = ARM_MODE_SVC;
  330. arm_algo.core_state = ARM_STATE_ARM;
  331. iap_entry_point = 0x7ffffff1;
  332. break;
  333. case lpc4300:
  334. armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
  335. armv7m_info.core_mode = ARM_MODE_THREAD;
  336. /* read out IAP entry point from ROM driver table at 0x10400100 */
  337. target_read_u32(target, 0x10400100, &iap_entry_point);
  338. break;
  339. default:
  340. LOG_ERROR("BUG: unknown lpc2000->variant encountered");
  341. exit(-1);
  342. }
  343. struct mem_param mem_params[2];
  344. /* command parameter table */
  345. init_mem_param(&mem_params[0], iap_working_area->address + 8, 6 * 4, PARAM_OUT);
  346. target_buffer_set_u32(target, mem_params[0].value, code);
  347. target_buffer_set_u32(target, mem_params[0].value + 0x04, param_table[0]);
  348. target_buffer_set_u32(target, mem_params[0].value + 0x08, param_table[1]);
  349. target_buffer_set_u32(target, mem_params[0].value + 0x0c, param_table[2]);
  350. target_buffer_set_u32(target, mem_params[0].value + 0x10, param_table[3]);
  351. target_buffer_set_u32(target, mem_params[0].value + 0x14, param_table[4]);
  352. struct reg_param reg_params[5];
  353. init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
  354. buf_set_u32(reg_params[0].value, 0, 32, iap_working_area->address + 0x08);
  355. /* command result table */
  356. init_mem_param(&mem_params[1], iap_working_area->address + 0x20, 5 * 4, PARAM_IN);
  357. init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
  358. buf_set_u32(reg_params[1].value, 0, 32, iap_working_area->address + 0x20);
  359. /* IAP entry point */
  360. init_reg_param(&reg_params[2], "r12", 32, PARAM_OUT);
  361. buf_set_u32(reg_params[2].value, 0, 32, iap_entry_point);
  362. switch (lpc2000_info->variant) {
  363. case lpc1700:
  364. case lpc4300:
  365. /* IAP stack */
  366. init_reg_param(&reg_params[3], "sp", 32, PARAM_OUT);
  367. buf_set_u32(reg_params[3].value, 0, 32, iap_working_area->address + lpc2000_info->cmd51_src_offset);
  368. /* return address */
  369. init_reg_param(&reg_params[4], "lr", 32, PARAM_OUT);
  370. buf_set_u32(reg_params[4].value, 0, 32, (iap_working_area->address + 0x04) | 1);
  371. /* bit0 of LR = 1 to return in Thumb mode */
  372. target_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address, 0, 10000,
  373. &armv7m_info);
  374. break;
  375. case lpc2000_v1:
  376. case lpc2000_v2:
  377. /* IAP stack */
  378. init_reg_param(&reg_params[3], "sp_svc", 32, PARAM_OUT);
  379. buf_set_u32(reg_params[3].value, 0, 32, iap_working_area->address + lpc2000_info->cmd51_src_offset);
  380. /* return address */
  381. init_reg_param(&reg_params[4], "lr_svc", 32, PARAM_OUT);
  382. buf_set_u32(reg_params[4].value, 0, 32, iap_working_area->address + 0x04);
  383. target_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address,
  384. iap_working_area->address + 0x4, 10000, &arm_algo);
  385. break;
  386. default:
  387. LOG_ERROR("BUG: unknown lpc2000->variant encountered");
  388. exit(-1);
  389. }
  390. int status_code = target_buffer_get_u32(target, mem_params[1].value);
  391. result_table[0] = target_buffer_get_u32(target, mem_params[1].value + 0x04);
  392. result_table[1] = target_buffer_get_u32(target, mem_params[1].value + 0x08);
  393. result_table[2] = target_buffer_get_u32(target, mem_params[1].value + 0x0c);
  394. result_table[3] = target_buffer_get_u32(target, mem_params[1].value + 0x10);
  395. LOG_DEBUG("IAP command = %i (0x%8.8" PRIx32 ", 0x%8.8" PRIx32 ", 0x%8.8" PRIx32 ", 0x%8.8" PRIx32 ", 0x%8.8" PRIx32
  396. ") completed with result = %8.8" PRIx32,
  397. code, param_table[0], param_table[1], param_table[2], param_table[3], param_table[4], status_code);
  398. destroy_mem_param(&mem_params[0]);
  399. destroy_mem_param(&mem_params[1]);
  400. destroy_reg_param(&reg_params[0]);
  401. destroy_reg_param(&reg_params[1]);
  402. destroy_reg_param(&reg_params[2]);
  403. destroy_reg_param(&reg_params[3]);
  404. destroy_reg_param(&reg_params[4]);
  405. return status_code;
  406. }
  407. static int lpc2000_iap_blank_check(struct flash_bank *bank, int first, int last)
  408. {
  409. if ((first < 0) || (last >= bank->num_sectors))
  410. return ERROR_FLASH_SECTOR_INVALID;
  411. uint32_t param_table[5] = {0};
  412. uint32_t result_table[4];
  413. struct working_area *iap_working_area;
  414. int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
  415. if (retval != ERROR_OK)
  416. return retval;
  417. struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
  418. if (lpc2000_info->variant == lpc4300)
  419. param_table[2] = lpc2000_info->lpc4300_bank;
  420. for (int i = first; i <= last && retval == ERROR_OK; i++) {
  421. /* check single sector */
  422. param_table[0] = param_table[1] = i;
  423. int status_code = lpc2000_iap_call(bank, iap_working_area, 53, param_table, result_table);
  424. switch (status_code) {
  425. case ERROR_FLASH_OPERATION_FAILED:
  426. retval = ERROR_FLASH_OPERATION_FAILED;
  427. break;
  428. case LPC2000_CMD_SUCCESS:
  429. bank->sectors[i].is_erased = 1;
  430. break;
  431. case LPC2000_SECTOR_NOT_BLANK:
  432. bank->sectors[i].is_erased = 0;
  433. break;
  434. case LPC2000_INVALID_SECTOR:
  435. bank->sectors[i].is_erased = 0;
  436. break;
  437. case LPC2000_BUSY:
  438. retval = ERROR_FLASH_BUSY;
  439. break;
  440. default:
  441. LOG_ERROR("BUG: unknown LPC2000 status code %i", status_code);
  442. exit(-1);
  443. }
  444. }
  445. struct target *target = bank->target;
  446. target_free_working_area(target, iap_working_area);
  447. return retval;
  448. }
  449. /*
  450. * flash bank lpc2000 <base> <size> 0 0 <target#> <lpc_variant> <cclk> [calc_checksum]
  451. */
  452. FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command)
  453. {
  454. if (CMD_ARGC < 8)
  455. return ERROR_COMMAND_SYNTAX_ERROR;
  456. struct lpc2000_flash_bank *lpc2000_info = malloc(sizeof(struct lpc2000_flash_bank));
  457. bank->driver_priv = lpc2000_info;
  458. if (strcmp(CMD_ARGV[6], "lpc2000_v1") == 0) {
  459. lpc2000_info->variant = lpc2000_v1;
  460. lpc2000_info->cmd51_dst_boundary = 512;
  461. lpc2000_info->cmd51_can_256b = 0;
  462. lpc2000_info->cmd51_can_8192b = 1;
  463. lpc2000_info->checksum_vector = 5;
  464. lpc2000_info->iap_max_stack = 128;
  465. } else if (strcmp(CMD_ARGV[6], "lpc2000_v2") == 0) {
  466. lpc2000_info->variant = lpc2000_v2;
  467. lpc2000_info->cmd51_dst_boundary = 256;
  468. lpc2000_info->cmd51_can_256b = 1;
  469. lpc2000_info->cmd51_can_8192b = 0;
  470. lpc2000_info->checksum_vector = 5;
  471. lpc2000_info->iap_max_stack = 128;
  472. } else if (strcmp(CMD_ARGV[6], "lpc1700") == 0) {
  473. lpc2000_info->variant = lpc1700;
  474. lpc2000_info->cmd51_dst_boundary = 256;
  475. lpc2000_info->cmd51_can_256b = 1;
  476. lpc2000_info->cmd51_can_8192b = 0;
  477. lpc2000_info->checksum_vector = 7;
  478. lpc2000_info->iap_max_stack = 128;
  479. } else if (strcmp(CMD_ARGV[6], "lpc1800") == 0 || strcmp(CMD_ARGV[6], "lpc4300") == 0) {
  480. lpc2000_info->variant = lpc4300;
  481. lpc2000_info->cmd51_dst_boundary = 512;
  482. lpc2000_info->cmd51_can_256b = 0;
  483. lpc2000_info->cmd51_can_8192b = 0;
  484. lpc2000_info->checksum_vector = 7;
  485. lpc2000_info->iap_max_stack = 208;
  486. } else {
  487. LOG_ERROR("unknown LPC2000 variant: %s", CMD_ARGV[6]);
  488. free(lpc2000_info);
  489. return ERROR_FLASH_BANK_INVALID;
  490. }
  491. /* see lpc2000_iap_working_area_init() for the reason behind the 0x34 value */
  492. lpc2000_info->cmd51_src_offset = 0x34 + lpc2000_info->iap_max_stack;
  493. COMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], lpc2000_info->cclk);
  494. lpc2000_info->calc_checksum = 0;
  495. lpc2000_build_sector_list(bank);
  496. uint32_t temp_base = 0;
  497. COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], temp_base);
  498. if (temp_base >= 0x1B000000)
  499. lpc2000_info->lpc4300_bank = 1; /* bank B */
  500. else
  501. lpc2000_info->lpc4300_bank = 0; /* bank A */
  502. if (CMD_ARGC >= 9) {
  503. if (strcmp(CMD_ARGV[8], "calc_checksum") == 0)
  504. lpc2000_info->calc_checksum = 1;
  505. }
  506. return ERROR_OK;
  507. }
  508. static int lpc2000_erase(struct flash_bank *bank, int first, int last)
  509. {
  510. if (bank->target->state != TARGET_HALTED) {
  511. LOG_ERROR("Target not halted");
  512. return ERROR_TARGET_NOT_HALTED;
  513. }
  514. struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
  515. uint32_t param_table[5] = {0};
  516. param_table[0] = first;
  517. param_table[1] = last;
  518. if (lpc2000_info->variant == lpc4300)
  519. param_table[2] = lpc2000_info->lpc4300_bank;
  520. else
  521. param_table[2] = lpc2000_info->cclk;
  522. uint32_t result_table[4];
  523. struct working_area *iap_working_area;
  524. int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
  525. if (retval != ERROR_OK)
  526. return retval;
  527. /* Prepare sectors */
  528. int status_code = lpc2000_iap_call(bank, iap_working_area, 50, param_table, result_table);
  529. switch (status_code) {
  530. case ERROR_FLASH_OPERATION_FAILED:
  531. retval = ERROR_FLASH_OPERATION_FAILED;
  532. break;
  533. case LPC2000_CMD_SUCCESS:
  534. break;
  535. case LPC2000_INVALID_SECTOR:
  536. retval = ERROR_FLASH_SECTOR_INVALID;
  537. break;
  538. default:
  539. LOG_WARNING("lpc2000 prepare sectors returned %i", status_code);
  540. retval = ERROR_FLASH_OPERATION_FAILED;
  541. break;
  542. }
  543. if (retval == ERROR_OK) {
  544. /* Erase sectors */
  545. param_table[2] = lpc2000_info->cclk;
  546. if (lpc2000_info->variant == lpc4300)
  547. param_table[3] = lpc2000_info->lpc4300_bank;
  548. status_code = lpc2000_iap_call(bank, iap_working_area, 52, param_table, result_table);
  549. switch (status_code) {
  550. case ERROR_FLASH_OPERATION_FAILED:
  551. retval = ERROR_FLASH_OPERATION_FAILED;
  552. break;
  553. case LPC2000_CMD_SUCCESS:
  554. break;
  555. case LPC2000_INVALID_SECTOR:
  556. retval = ERROR_FLASH_SECTOR_INVALID;
  557. break;
  558. default:
  559. LOG_WARNING("lpc2000 erase sectors returned %i", status_code);
  560. retval = ERROR_FLASH_OPERATION_FAILED;
  561. break;
  562. }
  563. }
  564. struct target *target = bank->target;
  565. target_free_working_area(target, iap_working_area);
  566. return retval;
  567. }
  568. static int lpc2000_protect(struct flash_bank *bank, int set, int first, int last)
  569. {
  570. /* can't protect/unprotect on the lpc2000 */
  571. return ERROR_OK;
  572. }
  573. static int lpc2000_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
  574. {
  575. struct target *target = bank->target;
  576. if (bank->target->state != TARGET_HALTED) {
  577. LOG_ERROR("Target not halted");
  578. return ERROR_TARGET_NOT_HALTED;
  579. }
  580. if (offset + count > bank->size)
  581. return ERROR_FLASH_DST_OUT_OF_BANK;
  582. struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
  583. uint32_t dst_min_alignment = lpc2000_info->cmd51_dst_boundary;
  584. if (offset % dst_min_alignment) {
  585. LOG_WARNING("offset 0x%" PRIx32 " breaks required alignment 0x%" PRIx32, offset, dst_min_alignment);
  586. return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
  587. }
  588. int first_sector = 0;
  589. int last_sector = 0;
  590. for (int i = 0; i < bank->num_sectors; i++) {
  591. if (offset >= bank->sectors[i].offset)
  592. first_sector = i;
  593. if (offset + DIV_ROUND_UP(count, dst_min_alignment) * dst_min_alignment > bank->sectors[i].offset)
  594. last_sector = i;
  595. }
  596. LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
  597. /* check if exception vectors should be flashed */
  598. if ((offset == 0) && (count >= 0x20) && lpc2000_info->calc_checksum) {
  599. uint32_t checksum = 0;
  600. for (int i = 0; i < 8; i++) {
  601. LOG_DEBUG("Vector 0x%2.2x: 0x%8.8" PRIx32, i * 4, buf_get_u32(buffer + (i * 4), 0, 32));
  602. if (i != lpc2000_info->checksum_vector)
  603. checksum += buf_get_u32(buffer + (i * 4), 0, 32);
  604. }
  605. checksum = 0 - checksum;
  606. LOG_DEBUG("checksum: 0x%8.8" PRIx32, checksum);
  607. uint32_t original_value = buf_get_u32(buffer + (lpc2000_info->checksum_vector * 4), 0, 32);
  608. if (original_value != checksum) {
  609. LOG_WARNING("Verification will fail since checksum in image (0x%8.8" PRIx32 ") to be written to flash is "
  610. "different from calculated vector checksum (0x%8.8" PRIx32 ").", original_value, checksum);
  611. LOG_WARNING("To remove this warning modify build tools on developer PC to inject correct LPC vector "
  612. "checksum.");
  613. }
  614. buf_set_u32(buffer + (lpc2000_info->checksum_vector * 4), 0, 32, checksum);
  615. }
  616. struct working_area *iap_working_area;
  617. int retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
  618. if (retval != ERROR_OK)
  619. return retval;
  620. struct working_area *download_area;
  621. /* allocate a working area */
  622. if (target_alloc_working_area(target, lpc2000_info->cmd51_max_buffer, &download_area) != ERROR_OK) {
  623. LOG_ERROR("no working area specified, can't write LPC2000 internal flash");
  624. target_free_working_area(target, iap_working_area);
  625. return ERROR_FLASH_OPERATION_FAILED;
  626. }
  627. uint32_t bytes_remaining = count;
  628. uint32_t bytes_written = 0;
  629. uint32_t param_table[5] = {0};
  630. uint32_t result_table[4];
  631. while (bytes_remaining > 0) {
  632. uint32_t thisrun_bytes;
  633. if (bytes_remaining >= lpc2000_info->cmd51_max_buffer)
  634. thisrun_bytes = lpc2000_info->cmd51_max_buffer;
  635. else if (bytes_remaining >= 1024)
  636. thisrun_bytes = 1024;
  637. else if ((bytes_remaining >= 512) || (!lpc2000_info->cmd51_can_256b))
  638. thisrun_bytes = 512;
  639. else
  640. thisrun_bytes = 256;
  641. /* Prepare sectors */
  642. param_table[0] = first_sector;
  643. param_table[1] = last_sector;
  644. if (lpc2000_info->variant == lpc4300)
  645. param_table[2] = lpc2000_info->lpc4300_bank;
  646. else
  647. param_table[2] = lpc2000_info->cclk;
  648. int status_code = lpc2000_iap_call(bank, iap_working_area, 50, param_table, result_table);
  649. switch (status_code) {
  650. case ERROR_FLASH_OPERATION_FAILED:
  651. retval = ERROR_FLASH_OPERATION_FAILED;
  652. break;
  653. case LPC2000_CMD_SUCCESS:
  654. break;
  655. case LPC2000_INVALID_SECTOR:
  656. retval = ERROR_FLASH_SECTOR_INVALID;
  657. break;
  658. default:
  659. LOG_WARNING("lpc2000 prepare sectors returned %i", status_code);
  660. retval = ERROR_FLASH_OPERATION_FAILED;
  661. break;
  662. }
  663. /* Exit if error occured */
  664. if (retval != ERROR_OK)
  665. break;
  666. if (bytes_remaining >= thisrun_bytes) {
  667. retval = target_write_buffer(bank->target, download_area->address, thisrun_bytes, buffer + bytes_written);
  668. if (retval != ERROR_OK) {
  669. retval = ERROR_FLASH_OPERATION_FAILED;
  670. break;
  671. }
  672. } else {
  673. uint8_t *last_buffer = malloc(thisrun_bytes);
  674. memcpy(last_buffer, buffer + bytes_written, bytes_remaining);
  675. memset(last_buffer + bytes_remaining, 0xff, thisrun_bytes - bytes_remaining);
  676. target_write_buffer(bank->target, download_area->address, thisrun_bytes, last_buffer);
  677. free(last_buffer);
  678. }
  679. LOG_DEBUG("writing 0x%" PRIx32 " bytes to address 0x%" PRIx32, thisrun_bytes,
  680. bank->base + offset + bytes_written);
  681. /* Write data */
  682. param_table[0] = bank->base + offset + bytes_written;
  683. param_table[1] = download_area->address;
  684. param_table[2] = thisrun_bytes;
  685. param_table[3] = lpc2000_info->cclk;
  686. status_code = lpc2000_iap_call(bank, iap_working_area, 51, param_table, result_table);
  687. switch (status_code) {
  688. case ERROR_FLASH_OPERATION_FAILED:
  689. retval = ERROR_FLASH_OPERATION_FAILED;
  690. break;
  691. case LPC2000_CMD_SUCCESS:
  692. break;
  693. case LPC2000_INVALID_SECTOR:
  694. retval = ERROR_FLASH_SECTOR_INVALID;
  695. break;
  696. default:
  697. LOG_WARNING("lpc2000 returned %i", status_code);
  698. retval = ERROR_FLASH_OPERATION_FAILED;
  699. break;
  700. }
  701. /* Exit if error occured */
  702. if (retval != ERROR_OK)
  703. break;
  704. if (bytes_remaining > thisrun_bytes)
  705. bytes_remaining -= thisrun_bytes;
  706. else
  707. bytes_remaining = 0;
  708. bytes_written += thisrun_bytes;
  709. }
  710. target_free_working_area(target, iap_working_area);
  711. target_free_working_area(target, download_area);
  712. return retval;
  713. }
  714. static int lpc2000_probe(struct flash_bank *bank)
  715. {
  716. /* we can't probe on an lpc2000 if this is an lpc2xxx, it has the configured flash */
  717. return ERROR_OK;
  718. }
  719. static int lpc2000_erase_check(struct flash_bank *bank)
  720. {
  721. if (bank->target->state != TARGET_HALTED) {
  722. LOG_ERROR("Target not halted");
  723. return ERROR_TARGET_NOT_HALTED;
  724. }
  725. return lpc2000_iap_blank_check(bank, 0, bank->num_sectors - 1);
  726. }
  727. static int lpc2000_protect_check(struct flash_bank *bank)
  728. {
  729. /* sectors are always protected */
  730. return ERROR_OK;
  731. }
  732. static int get_lpc2000_info(struct flash_bank *bank, char *buf, int buf_size)
  733. {
  734. struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;
  735. snprintf(buf, buf_size, "lpc2000 flash driver variant: %i, clk: %" PRIi32 "kHz", lpc2000_info->variant,
  736. lpc2000_info->cclk);
  737. return ERROR_OK;
  738. }
  739. COMMAND_HANDLER(lpc2000_handle_part_id_command)
  740. {
  741. if (CMD_ARGC < 1)
  742. return ERROR_COMMAND_SYNTAX_ERROR;
  743. struct flash_bank *bank;
  744. int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
  745. if (ERROR_OK != retval)
  746. return retval;
  747. if (bank->target->state != TARGET_HALTED) {
  748. LOG_ERROR("Target not halted");
  749. return ERROR_TARGET_NOT_HALTED;
  750. }
  751. uint32_t param_table[5] = {0};
  752. uint32_t result_table[4];
  753. struct working_area *iap_working_area;
  754. retval = lpc2000_iap_working_area_init(bank, &iap_working_area);
  755. if (retval != ERROR_OK)
  756. return retval;
  757. int status_code = lpc2000_iap_call(bank, iap_working_area, 54, param_table, result_table);
  758. if (status_code != 0x0) {
  759. if (status_code == ERROR_FLASH_OPERATION_FAILED) {
  760. command_print(CMD_CTX, "no sufficient working area specified, can't access LPC2000 IAP interface");
  761. } else
  762. command_print(CMD_CTX, "lpc2000 IAP returned status code %i", status_code);
  763. } else
  764. command_print(CMD_CTX, "lpc2000 part id: 0x%8.8" PRIx32, result_table[0]);
  765. return retval;
  766. }
  767. static const struct command_registration lpc2000_exec_command_handlers[] = {
  768. {
  769. .name = "part_id",
  770. .handler = lpc2000_handle_part_id_command,
  771. .mode = COMMAND_EXEC,
  772. .help = "print part id of lpc2000 flash bank <num>",
  773. .usage = "<bank>",
  774. },
  775. COMMAND_REGISTRATION_DONE
  776. };
  777. static const struct command_registration lpc2000_command_handlers[] = {
  778. {
  779. .name = "lpc2000",
  780. .mode = COMMAND_ANY,
  781. .help = "lpc2000 flash command group",
  782. .usage = "",
  783. .chain = lpc2000_exec_command_handlers,
  784. },
  785. COMMAND_REGISTRATION_DONE
  786. };
  787. struct flash_driver lpc2000_flash = {
  788. .name = "lpc2000",
  789. .commands = lpc2000_command_handlers,
  790. .flash_bank_command = lpc2000_flash_bank_command,
  791. .erase = lpc2000_erase,
  792. .protect = lpc2000_protect,
  793. .write = lpc2000_write,
  794. .read = default_flash_read,
  795. .probe = lpc2000_probe,
  796. .auto_probe = lpc2000_probe,
  797. .erase_check = lpc2000_erase_check,
  798. .protect_check = lpc2000_protect_check,
  799. .info = get_lpc2000_info,
  800. };