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.
 
 
 
 
 
 

744 lines
20 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2005 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program; if not, write to the *
  17. * Free Software Foundation, Inc., *
  18. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  19. ***************************************************************************/
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include "replacements.h"
  24. #include "str7x.h"
  25. #include "flash.h"
  26. #include "target.h"
  27. #include "log.h"
  28. #include "armv4_5.h"
  29. #include "algorithm.h"
  30. #include "binarybuffer.h"
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <unistd.h>
  34. str7x_mem_layout_t mem_layout[] = {
  35. {0x00000000, 0x02000, 0x01},
  36. {0x00002000, 0x02000, 0x02},
  37. {0x00004000, 0x02000, 0x04},
  38. {0x00006000, 0x02000, 0x08},
  39. {0x00008000, 0x08000, 0x10},
  40. {0x00010000, 0x10000, 0x20},
  41. {0x00020000, 0x10000, 0x40},
  42. {0x00030000, 0x10000, 0x80},
  43. {0x000C0000, 0x02000, 0x10000},
  44. {0x000C2000, 0x02000, 0x20000},
  45. };
  46. int str7x_register_commands(struct command_context_s *cmd_ctx);
  47. int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
  48. int str7x_erase(struct flash_bank_s *bank, int first, int last);
  49. int str7x_protect(struct flash_bank_s *bank, int set, int first, int last);
  50. int str7x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
  51. int str7x_probe(struct flash_bank_s *bank);
  52. int str7x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  53. int str7x_protect_check(struct flash_bank_s *bank);
  54. int str7x_erase_check(struct flash_bank_s *bank);
  55. int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size);
  56. flash_driver_t str7x_flash =
  57. {
  58. .name = "str7x",
  59. .register_commands = str7x_register_commands,
  60. .flash_bank_command = str7x_flash_bank_command,
  61. .erase = str7x_erase,
  62. .protect = str7x_protect,
  63. .write = str7x_write,
  64. .probe = str7x_probe,
  65. .erase_check = str7x_erase_check,
  66. .protect_check = str7x_protect_check,
  67. .info = str7x_info
  68. };
  69. int str7x_register_commands(struct command_context_s *cmd_ctx)
  70. {
  71. return ERROR_OK;
  72. }
  73. int str7x_get_flash_adr(struct flash_bank_s *bank, u32 reg)
  74. {
  75. return (bank->base | reg);
  76. }
  77. int str7x_build_block_list(struct flash_bank_s *bank)
  78. {
  79. str7x_flash_bank_t *str7x_info = bank->driver_priv;
  80. int i;
  81. int num_sectors = 0, b0_sectors = 0, b1_sectors = 0;
  82. switch (bank->size)
  83. {
  84. case 16 * 1024:
  85. b0_sectors = 2;
  86. break;
  87. case 64 * 1024:
  88. b0_sectors = 5;
  89. break;
  90. case 128 * 1024:
  91. b0_sectors = 6;
  92. break;
  93. case 256 * 1024:
  94. b0_sectors = 8;
  95. break;
  96. default:
  97. ERROR("BUG: unknown bank->size encountered");
  98. exit(-1);
  99. }
  100. if( str7x_info->bank1 == 1 )
  101. {
  102. b1_sectors += 2;
  103. }
  104. num_sectors = b0_sectors + b1_sectors;
  105. bank->num_sectors = num_sectors;
  106. bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
  107. str7x_info->sector_bits = malloc(sizeof(u32) * num_sectors);
  108. str7x_info->sector_bank = malloc(sizeof(u32) * num_sectors);
  109. num_sectors = 0;
  110. for (i = 0; i < b0_sectors; i++)
  111. {
  112. bank->sectors[num_sectors].offset = mem_layout[i].sector_start;
  113. bank->sectors[num_sectors].size = mem_layout[i].sector_size;
  114. bank->sectors[num_sectors].is_erased = -1;
  115. bank->sectors[num_sectors].is_protected = 1;
  116. str7x_info->sector_bank[num_sectors] = 0;
  117. str7x_info->sector_bits[num_sectors++] = mem_layout[i].sector_bit;
  118. }
  119. if (b1_sectors)
  120. {
  121. for (i = 8; i < 10; i++)
  122. {
  123. bank->sectors[num_sectors].offset = mem_layout[i].sector_start;
  124. bank->sectors[num_sectors].size = mem_layout[i].sector_size;
  125. bank->sectors[num_sectors].is_erased = -1;
  126. bank->sectors[num_sectors].is_protected = 1;
  127. str7x_info->sector_bank[num_sectors] = 1;
  128. str7x_info->sector_bits[num_sectors++] = mem_layout[i].sector_bit;
  129. }
  130. }
  131. return ERROR_OK;
  132. }
  133. /* flash bank str7x <base> <size> 0 0 <str71_variant> <target#>
  134. */
  135. int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
  136. {
  137. str7x_flash_bank_t *str7x_info;
  138. if (argc < 7)
  139. {
  140. WARNING("incomplete flash_bank str7x configuration");
  141. return ERROR_FLASH_BANK_INVALID;
  142. }
  143. str7x_info = malloc(sizeof(str7x_flash_bank_t));
  144. bank->driver_priv = str7x_info;
  145. if (strcmp(args[5], "STR71x") == 0)
  146. {
  147. str7x_info->bank1 = 1;
  148. if (bank->base != 0x40000000)
  149. {
  150. WARNING("overriding flash base address for STR71x device with 0x40000000");
  151. bank->base = 0x40000000;
  152. }
  153. }
  154. else if (strcmp(args[5], "STR73x") == 0)
  155. {
  156. str7x_info->bank1 = 0;
  157. if (bank->base != 0x80000000)
  158. {
  159. WARNING("overriding flash base address for STR73x device with 0x80000000");
  160. bank->base = 0x80000000;
  161. }
  162. }
  163. else if (strcmp(args[5], "STR75x") == 0)
  164. {
  165. str7x_info->bank1 = 1;
  166. if (bank->base != 0x20000000)
  167. {
  168. WARNING("overriding flash base address for STR75x device with 0x20000000");
  169. bank->base = 0x20000000;
  170. }
  171. }
  172. else
  173. {
  174. ERROR("unknown STR7x variant");
  175. free(str7x_info);
  176. return ERROR_FLASH_BANK_INVALID;
  177. }
  178. str7x_info->target = get_target_by_num(strtoul(args[6], NULL, 0));
  179. if (!str7x_info->target)
  180. {
  181. ERROR("no target '%s' configured", args[6]);
  182. exit(-1);
  183. }
  184. str7x_build_block_list(bank);
  185. str7x_info->write_algorithm = NULL;
  186. return ERROR_OK;
  187. }
  188. u32 str7x_status(struct flash_bank_s *bank)
  189. {
  190. str7x_flash_bank_t *str7x_info = bank->driver_priv;
  191. target_t *target = str7x_info->target;
  192. u32 retval;
  193. target_read_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), &retval);
  194. return retval;
  195. }
  196. u32 str7x_result(struct flash_bank_s *bank)
  197. {
  198. str7x_flash_bank_t *str7x_info = bank->driver_priv;
  199. target_t *target = str7x_info->target;
  200. u32 retval;
  201. target_read_u32(target, str7x_get_flash_adr(bank, FLASH_ER), &retval);
  202. return retval;
  203. }
  204. int str7x_blank_check(struct flash_bank_s *bank, int first, int last)
  205. {
  206. str7x_flash_bank_t *str7x_info = bank->driver_priv;
  207. target_t *target = str7x_info->target;
  208. u8 *buffer;
  209. int i;
  210. int nBytes;
  211. if ((first < 0) || (last > bank->num_sectors))
  212. return ERROR_FLASH_SECTOR_INVALID;
  213. if (str7x_info->target->state != TARGET_HALTED)
  214. {
  215. return ERROR_TARGET_NOT_HALTED;
  216. }
  217. buffer = malloc(256);
  218. for (i = first; i <= last; i++)
  219. {
  220. bank->sectors[i].is_erased = 1;
  221. target->type->read_memory(target, bank->base + bank->sectors[i].offset, 4, 256/4, buffer);
  222. for (nBytes = 0; nBytes < 256; nBytes++)
  223. {
  224. if (buffer[nBytes] != 0xFF)
  225. {
  226. bank->sectors[i].is_erased = 0;
  227. break;
  228. }
  229. }
  230. }
  231. free(buffer);
  232. return ERROR_OK;
  233. }
  234. int str7x_protect_check(struct flash_bank_s *bank)
  235. {
  236. str7x_flash_bank_t *str7x_info = bank->driver_priv;
  237. target_t *target = str7x_info->target;
  238. int i;
  239. u32 retval;
  240. if (str7x_info->target->state != TARGET_HALTED)
  241. {
  242. return ERROR_TARGET_NOT_HALTED;
  243. }
  244. target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVWPAR), &retval);
  245. for (i = 0; i < bank->num_sectors; i++)
  246. {
  247. if (retval & str7x_info->sector_bits[i])
  248. bank->sectors[i].is_protected = 0;
  249. else
  250. bank->sectors[i].is_protected = 1;
  251. }
  252. return ERROR_OK;
  253. }
  254. int str7x_erase(struct flash_bank_s *bank, int first, int last)
  255. {
  256. str7x_flash_bank_t *str7x_info = bank->driver_priv;
  257. target_t *target = str7x_info->target;
  258. int i;
  259. u32 cmd;
  260. u32 retval;
  261. u32 b0_sectors = 0, b1_sectors = 0;
  262. if (str7x_info->target->state != TARGET_HALTED)
  263. {
  264. return ERROR_TARGET_NOT_HALTED;
  265. }
  266. for (i = first; i <= last; i++)
  267. {
  268. if (str7x_info->sector_bank[i] == 0)
  269. b0_sectors |= str7x_info->sector_bits[i];
  270. else if (str7x_info->sector_bank[i] == 1)
  271. b1_sectors |= str7x_info->sector_bits[i];
  272. else
  273. ERROR("BUG: str7x_info->sector_bank[i] neither 0 nor 1 (%i)", str7x_info->sector_bank[i]);
  274. }
  275. if (b0_sectors)
  276. {
  277. DEBUG("b0_sectors: 0x%x", b0_sectors);
  278. /* clear FLASH_ER register */
  279. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
  280. cmd = FLASH_SER;
  281. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  282. cmd = b0_sectors;
  283. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);
  284. cmd = FLASH_SER|FLASH_WMS;
  285. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  286. while (((retval = str7x_status(bank)) & (FLASH_BSYA1|FLASH_BSYA2))){
  287. usleep(1000);
  288. }
  289. retval = str7x_result(bank);
  290. if (retval)
  291. {
  292. ERROR("error erasing flash bank, FLASH_ER: 0x%x", retval);
  293. return ERROR_FLASH_OPERATION_FAILED;
  294. }
  295. }
  296. if (b1_sectors)
  297. {
  298. DEBUG("b1_sectors: 0x%x", b1_sectors);
  299. /* clear FLASH_ER register */
  300. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
  301. cmd = FLASH_SER;
  302. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  303. cmd = b1_sectors;
  304. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);
  305. cmd = FLASH_SER|FLASH_WMS;
  306. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  307. while (((retval = str7x_status(bank)) & (FLASH_BSYA1|FLASH_BSYA2))){
  308. usleep(1000);
  309. }
  310. retval = str7x_result(bank);
  311. if (retval)
  312. {
  313. ERROR("error erasing flash bank, FLASH_ER: 0x%x", retval);
  314. return ERROR_FLASH_OPERATION_FAILED;
  315. }
  316. }
  317. for (i = first; i <= last; i++)
  318. bank->sectors[i].is_erased = 1;
  319. return ERROR_OK;
  320. }
  321. int str7x_protect(struct flash_bank_s *bank, int set, int first, int last)
  322. {
  323. str7x_flash_bank_t *str7x_info = bank->driver_priv;
  324. target_t *target = str7x_info->target;
  325. int i;
  326. u32 cmd;
  327. u32 retval;
  328. u32 protect_blocks;
  329. if (str7x_info->target->state != TARGET_HALTED)
  330. {
  331. return ERROR_TARGET_NOT_HALTED;
  332. }
  333. protect_blocks = 0xFFFFFFFF;
  334. if (set)
  335. {
  336. for (i = first; i <= last; i++)
  337. protect_blocks &= ~(str7x_info->sector_bits[i]);
  338. }
  339. /* clear FLASH_ER register */
  340. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
  341. cmd = FLASH_SPR;
  342. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  343. cmd = str7x_get_flash_adr(bank, FLASH_NVWPAR);
  344. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), cmd);
  345. cmd = protect_blocks;
  346. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), cmd);
  347. cmd = FLASH_SPR|FLASH_WMS;
  348. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  349. while (((retval = str7x_status(bank)) & (FLASH_BSYA1|FLASH_BSYA2))){
  350. usleep(1000);
  351. }
  352. retval = str7x_result(bank);
  353. DEBUG("retval: 0x%8.8x", retval);
  354. if (retval & FLASH_ERER)
  355. return ERROR_FLASH_SECTOR_NOT_ERASED;
  356. else if (retval & FLASH_WPF)
  357. return ERROR_FLASH_OPERATION_FAILED;
  358. return ERROR_OK;
  359. }
  360. int str7x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
  361. {
  362. str7x_flash_bank_t *str7x_info = bank->driver_priv;
  363. target_t *target = str7x_info->target;
  364. u32 buffer_size = 8192;
  365. working_area_t *source;
  366. u32 address = bank->base + offset;
  367. reg_param_t reg_params[5];
  368. armv4_5_algorithm_t armv4_5_info;
  369. int retval = ERROR_OK;
  370. u32 str7x_flash_write_code[] = {
  371. /* write: */
  372. 0xe3a04201, /* mov r4, #0x10000000 */
  373. 0xe5824000, /* str r4, [r2, #0x0] */
  374. 0xe5821010, /* str r1, [r2, #0x10] */
  375. 0xe4904004, /* ldr r4, [r0], #4 */
  376. 0xe5824008, /* str r4, [r2, #0x8] */
  377. 0xe4904004, /* ldr r4, [r0], #4 */
  378. 0xe582400c, /* str r4, [r2, #0xc] */
  379. 0xe3a04209, /* mov r4, #0x90000000 */
  380. 0xe5824000, /* str r4, [r2, #0x0] */
  381. /* busy: */
  382. 0xe5924000, /* ldr r4, [r2, #0x0] */
  383. 0xe3140016, /* tst r4, #0x16 */
  384. 0x1afffffc, /* bne busy */
  385. 0xe5924014, /* ldr r4, [r2, #0x14] */
  386. 0xe31400ff, /* tst r4, #0xff */
  387. 0x03140c01, /* tsteq r4, #0x100 */
  388. 0x1a000002, /* bne exit */
  389. 0xe2811008, /* add r1, r1, #0x8 */
  390. 0xe2533001, /* subs r3, r3, #1 */
  391. 0x1affffec, /* bne write */
  392. /* exit: */
  393. 0xeafffffe, /* b exit */
  394. };
  395. u8 str7x_flash_write_code_buf[80];
  396. int i;
  397. /* flash write code */
  398. if (!str7x_info->write_algorithm)
  399. {
  400. if (target_alloc_working_area(target, 4 * 20, &str7x_info->write_algorithm) != ERROR_OK)
  401. {
  402. WARNING("no working area available, can't do block memory writes");
  403. return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
  404. };
  405. /* convert flash writing code into a buffer in target endianness */
  406. for (i = 0; i < 20; i++)
  407. target_buffer_set_u32(target, str7x_flash_write_code_buf + i*4, str7x_flash_write_code[i]);
  408. target_write_buffer(target, str7x_info->write_algorithm->address, 20 * 4, str7x_flash_write_code_buf);
  409. }
  410. /* memory buffer */
  411. while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
  412. {
  413. buffer_size /= 2;
  414. if (buffer_size <= 256)
  415. {
  416. /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
  417. if (str7x_info->write_algorithm)
  418. target_free_working_area(target, str7x_info->write_algorithm);
  419. WARNING("no large enough working area available, can't do block memory writes");
  420. return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
  421. }
  422. };
  423. armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
  424. armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
  425. armv4_5_info.core_state = ARMV4_5_STATE_ARM;
  426. init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
  427. init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
  428. init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
  429. init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
  430. init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
  431. while (count > 0)
  432. {
  433. u32 thisrun_count = (count > (buffer_size / 8)) ? (buffer_size / 8) : count;
  434. target_write_buffer(target, source->address, thisrun_count * 8, buffer);
  435. buf_set_u32(reg_params[0].value, 0, 32, source->address);
  436. buf_set_u32(reg_params[1].value, 0, 32, address);
  437. buf_set_u32(reg_params[2].value, 0, 32, str7x_get_flash_adr(bank, FLASH_CR0));
  438. buf_set_u32(reg_params[3].value, 0, 32, thisrun_count);
  439. if ((retval = target->type->run_algorithm(target, 0, NULL, 5, reg_params, str7x_info->write_algorithm->address, str7x_info->write_algorithm->address + (19 * 4), 10000, &armv4_5_info)) != ERROR_OK)
  440. {
  441. ERROR("error executing str7x flash write algorithm");
  442. break;
  443. }
  444. if (buf_get_u32(reg_params[4].value, 0, 32) != 0x00)
  445. {
  446. retval = ERROR_FLASH_OPERATION_FAILED;
  447. break;
  448. }
  449. buffer += thisrun_count * 8;
  450. address += thisrun_count * 8;
  451. count -= thisrun_count;
  452. }
  453. target_free_working_area(target, source);
  454. destroy_reg_param(&reg_params[0]);
  455. destroy_reg_param(&reg_params[1]);
  456. destroy_reg_param(&reg_params[2]);
  457. destroy_reg_param(&reg_params[3]);
  458. destroy_reg_param(&reg_params[4]);
  459. return retval;
  460. }
  461. int str7x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
  462. {
  463. str7x_flash_bank_t *str7x_info = bank->driver_priv;
  464. target_t *target = str7x_info->target;
  465. u32 dwords_remaining = (count / 8);
  466. u32 bytes_remaining = (count & 0x00000007);
  467. u32 address = bank->base + offset;
  468. u32 bytes_written = 0;
  469. u32 cmd;
  470. u32 retval;
  471. u32 check_address = offset;
  472. int i;
  473. if (str7x_info->target->state != TARGET_HALTED)
  474. {
  475. return ERROR_TARGET_NOT_HALTED;
  476. }
  477. if (offset & 0x7)
  478. {
  479. WARNING("offset 0x%x breaks required 8-byte alignment", offset);
  480. return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
  481. }
  482. for (i = 0; i < bank->num_sectors; i++)
  483. {
  484. u32 sec_start = bank->sectors[i].offset;
  485. u32 sec_end = sec_start + bank->sectors[i].size;
  486. /* check if destination falls within the current sector */
  487. if ((check_address >= sec_start) && (check_address < sec_end))
  488. {
  489. /* check if destination ends in the current sector */
  490. if (offset + count < sec_end)
  491. check_address = offset + count;
  492. else
  493. check_address = sec_end;
  494. }
  495. }
  496. if (check_address != offset + count)
  497. return ERROR_FLASH_DST_OUT_OF_BANK;
  498. /* clear FLASH_ER register */
  499. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
  500. /* multiple dwords (8-byte) to be programmed? */
  501. if (dwords_remaining > 0)
  502. {
  503. /* try using a block write */
  504. if ((retval = str7x_write_block(bank, buffer, offset, dwords_remaining)) != ERROR_OK)
  505. {
  506. if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
  507. {
  508. /* if block write failed (no sufficient working area),
  509. * we use normal (slow) single dword accesses */
  510. WARNING("couldn't use block writes, falling back to single memory accesses");
  511. }
  512. else if (retval == ERROR_FLASH_OPERATION_FAILED)
  513. {
  514. /* if an error occured, we examine the reason, and quit */
  515. retval = str7x_result(bank);
  516. ERROR("flash writing failed with error code: 0x%x", retval);
  517. return ERROR_FLASH_OPERATION_FAILED;
  518. }
  519. }
  520. else
  521. {
  522. buffer += dwords_remaining * 8;
  523. address += dwords_remaining * 8;
  524. dwords_remaining = 0;
  525. }
  526. }
  527. while (dwords_remaining > 0)
  528. {
  529. // command
  530. cmd = FLASH_DWPG;
  531. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  532. // address
  533. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
  534. // data word 1
  535. target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, buffer + bytes_written);
  536. bytes_written += 4;
  537. // data word 2
  538. target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, buffer + bytes_written);
  539. bytes_written += 4;
  540. /* start programming cycle */
  541. cmd = FLASH_DWPG | FLASH_WMS;
  542. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  543. while (((retval = str7x_status(bank)) & (FLASH_BSYA1 | FLASH_BSYA2)))
  544. {
  545. usleep(1000);
  546. }
  547. retval = str7x_result(bank);
  548. if (retval & FLASH_PGER)
  549. return ERROR_FLASH_OPERATION_FAILED;
  550. else if (retval & FLASH_WPF)
  551. return ERROR_FLASH_OPERATION_FAILED;
  552. dwords_remaining--;
  553. address += 8;
  554. }
  555. if (bytes_remaining)
  556. {
  557. u8 last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  558. int i = 0;
  559. while(bytes_remaining > 0)
  560. {
  561. last_dword[i++] = *(buffer + bytes_written);
  562. bytes_remaining--;
  563. bytes_written++;
  564. }
  565. // command
  566. cmd = FLASH_DWPG;
  567. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  568. // address
  569. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
  570. // data word 1
  571. target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, last_dword);
  572. bytes_written += 4;
  573. // data word 2
  574. target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, last_dword + 4);
  575. bytes_written += 4;
  576. /* start programming cycle */
  577. cmd = FLASH_DWPG | FLASH_WMS;
  578. target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
  579. while (((retval = str7x_status(bank)) & (FLASH_BSYA1 | FLASH_BSYA2)))
  580. {
  581. usleep(1000);
  582. }
  583. retval = str7x_result(bank);
  584. if (retval & FLASH_PGER)
  585. return ERROR_FLASH_OPERATION_FAILED;
  586. else if (retval & FLASH_WPF)
  587. return ERROR_FLASH_OPERATION_FAILED;
  588. }
  589. return ERROR_OK;
  590. }
  591. int str7x_probe(struct flash_bank_s *bank)
  592. {
  593. return ERROR_OK;
  594. }
  595. int str7x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  596. {
  597. return ERROR_OK;
  598. }
  599. int str7x_erase_check(struct flash_bank_s *bank)
  600. {
  601. return str7x_blank_check(bank, 0, bank->num_sectors - 1);
  602. }
  603. int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size)
  604. {
  605. snprintf(buf, buf_size, "str7x flash driver info" );
  606. return ERROR_OK;
  607. }