PageRenderTime 2814ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/stm32.c

http://stm32flash.googlecode.com/
C | 373 lines | 274 code | 56 blank | 43 comment | 69 complexity | 0c6bd157b8a88f6f5e23f2e31a0362cb MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. stm32flash - Open Source ST STM32 flash program for *nix
  3. Copyright (C) 2010 Geoffrey McRae <geoff@spacevs.com>
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  15. */
  16. #include <stdlib.h>
  17. #include <assert.h>
  18. #include <stdio.h>
  19. #include "stm32.h"
  20. #include "utils.h"
  21. #define STM32_ACK 0x79
  22. #define STM32_NACK 0x1F
  23. #define STM32_CMD_INIT 0x7F
  24. #define STM32_CMD_GET 0x00 /* get the version and command supported */
  25. #define STM32_CMD_EE 0x44 /* extended erase */
  26. struct stm32_cmd {
  27. uint8_t get;
  28. uint8_t gvr;
  29. uint8_t gid;
  30. uint8_t rm;
  31. uint8_t go;
  32. uint8_t wm;
  33. uint8_t er; /* this may be extended erase */
  34. uint8_t wp;
  35. uint8_t uw;
  36. uint8_t rp;
  37. uint8_t ur;
  38. };
  39. /* device table */
  40. const stm32_dev_t devices[] = {
  41. {0x412, "Low-density" , 0x20000200, 0x20002800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800},
  42. {0x410, "Medium-density" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800},
  43. {0x411, "STM32F2xx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF},
  44. {0x413, "STM32F4xx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF},
  45. {0x414, "High-density" , 0x20000200, 0x20010000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800},
  46. {0x416, "Medium-density ULP", 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000},
  47. {0x418, "Connectivity line" , 0x20001000, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFB000, 0x1FFFF800},
  48. {0x420, "Medium-density VL" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800},
  49. {0x428, "High-density VL" , 0x20000200, 0x20008000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800},
  50. {0x430, "XL-density" , 0x20000800, 0x20018000, 0x08000000, 0x08100000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFE000, 0x1FFFF800},
  51. {0x0}
  52. };
  53. /* internal functions */
  54. uint8_t stm32_gen_cs(const uint32_t v);
  55. void stm32_send_byte(const stm32_t *stm, uint8_t byte);
  56. uint8_t stm32_read_byte(const stm32_t *stm);
  57. char stm32_send_command(const stm32_t *stm, const uint8_t cmd);
  58. /* stm32 programs */
  59. extern unsigned int stmreset_length;
  60. extern unsigned char stmreset_binary[];
  61. uint8_t stm32_gen_cs(const uint32_t v) {
  62. return ((v & 0xFF000000) >> 24) ^
  63. ((v & 0x00FF0000) >> 16) ^
  64. ((v & 0x0000FF00) >> 8) ^
  65. ((v & 0x000000FF) >> 0);
  66. }
  67. void stm32_send_byte(const stm32_t *stm, uint8_t byte) {
  68. serial_err_t err;
  69. err = serial_write(stm->serial, &byte, 1);
  70. if (err != SERIAL_ERR_OK) {
  71. perror("send_byte");
  72. assert(0);
  73. }
  74. }
  75. uint8_t stm32_read_byte(const stm32_t *stm) {
  76. uint8_t byte;
  77. serial_err_t err;
  78. err = serial_read(stm->serial, &byte, 1);
  79. if (err != SERIAL_ERR_OK) {
  80. perror("read_byte");
  81. assert(0);
  82. }
  83. return byte;
  84. }
  85. char stm32_send_command(const stm32_t *stm, const uint8_t cmd) {
  86. stm32_send_byte(stm, cmd);
  87. stm32_send_byte(stm, cmd ^ 0xFF);
  88. if (stm32_read_byte(stm) != STM32_ACK) {
  89. fprintf(stderr, "Error sending command 0x%02x to device\n", cmd);
  90. return 0;
  91. }
  92. return 1;
  93. }
  94. stm32_t* stm32_init(const serial_t *serial, const char init) {
  95. uint8_t len;
  96. stm32_t *stm;
  97. stm = calloc(sizeof(stm32_t), 1);
  98. stm->cmd = calloc(sizeof(stm32_cmd_t), 1);
  99. stm->serial = serial;
  100. if (init) {
  101. stm32_send_byte(stm, STM32_CMD_INIT);
  102. if (stm32_read_byte(stm) != STM32_ACK) {
  103. stm32_close(stm);
  104. fprintf(stderr, "Failed to get init ACK from device\n");
  105. return NULL;
  106. }
  107. }
  108. /* get the bootloader information */
  109. if (!stm32_send_command(stm, STM32_CMD_GET)) return 0;
  110. len = stm32_read_byte(stm) + 1;
  111. stm->bl_version = stm32_read_byte(stm); --len;
  112. stm->cmd->get = stm32_read_byte(stm); --len;
  113. stm->cmd->gvr = stm32_read_byte(stm); --len;
  114. stm->cmd->gid = stm32_read_byte(stm); --len;
  115. stm->cmd->rm = stm32_read_byte(stm); --len;
  116. stm->cmd->go = stm32_read_byte(stm); --len;
  117. stm->cmd->wm = stm32_read_byte(stm); --len;
  118. stm->cmd->er = stm32_read_byte(stm); --len;
  119. stm->cmd->wp = stm32_read_byte(stm); --len;
  120. stm->cmd->uw = stm32_read_byte(stm); --len;
  121. stm->cmd->rp = stm32_read_byte(stm); --len;
  122. stm->cmd->ur = stm32_read_byte(stm); --len;
  123. if (len > 0) {
  124. fprintf(stderr, "Seems this bootloader returns more then we understand in the GET command, we will skip the unknown bytes\n");
  125. while(len-- > 0) stm32_read_byte(stm);
  126. }
  127. if (stm32_read_byte(stm) != STM32_ACK) {
  128. stm32_close(stm);
  129. return NULL;
  130. }
  131. /* get the version and read protection status */
  132. if (!stm32_send_command(stm, stm->cmd->gvr)) {
  133. stm32_close(stm);
  134. return NULL;
  135. }
  136. stm->version = stm32_read_byte(stm);
  137. stm->option1 = stm32_read_byte(stm);
  138. stm->option2 = stm32_read_byte(stm);
  139. if (stm32_read_byte(stm) != STM32_ACK) {
  140. stm32_close(stm);
  141. return NULL;
  142. }
  143. /* get the device ID */
  144. if (!stm32_send_command(stm, stm->cmd->gid)) {
  145. stm32_close(stm);
  146. return NULL;
  147. }
  148. len = stm32_read_byte(stm) + 1;
  149. if (len != 2) {
  150. stm32_close(stm);
  151. fprintf(stderr, "More then two bytes sent in the PID, unknown/unsupported device\n");
  152. return NULL;
  153. }
  154. stm->pid = (stm32_read_byte(stm) << 8) | stm32_read_byte(stm);
  155. if (stm32_read_byte(stm) != STM32_ACK) {
  156. stm32_close(stm);
  157. return NULL;
  158. }
  159. stm->dev = devices;
  160. while(stm->dev->id != 0x00 && stm->dev->id != stm->pid)
  161. ++stm->dev;
  162. if (!stm->dev->id) {
  163. fprintf(stderr, "Unknown/unsupported device (Device ID: 0x%03x)\n", stm->pid);
  164. stm32_close(stm);
  165. return NULL;
  166. }
  167. return stm;
  168. }
  169. void stm32_close(stm32_t *stm) {
  170. if (stm) free(stm->cmd);
  171. free(stm);
  172. }
  173. char stm32_read_memory(const stm32_t *stm, uint32_t address, uint8_t data[], unsigned int len) {
  174. uint8_t cs;
  175. unsigned int i;
  176. assert(len > 0 && len < 257);
  177. /* must be 32bit aligned */
  178. assert(address % 4 == 0);
  179. address = be_u32 (address);
  180. cs = stm32_gen_cs(address);
  181. if (!stm32_send_command(stm, stm->cmd->rm)) return 0;
  182. assert(serial_write(stm->serial, &address, 4) == SERIAL_ERR_OK);
  183. stm32_send_byte(stm, cs);
  184. if (stm32_read_byte(stm) != STM32_ACK) return 0;
  185. i = len - 1;
  186. stm32_send_byte(stm, i);
  187. stm32_send_byte(stm, i ^ 0xFF);
  188. if (stm32_read_byte(stm) != STM32_ACK) return 0;
  189. assert(serial_read(stm->serial, data, len) == SERIAL_ERR_OK);
  190. return 1;
  191. }
  192. char stm32_write_memory(const stm32_t *stm, uint32_t address, uint8_t data[], unsigned int len) {
  193. uint8_t cs;
  194. unsigned int i;
  195. int c, extra;
  196. assert(len > 0 && len < 257);
  197. /* must be 32bit aligned */
  198. assert(address % 4 == 0);
  199. address = be_u32 (address);
  200. cs = stm32_gen_cs(address);
  201. /* send the address and checksum */
  202. if (!stm32_send_command(stm, stm->cmd->wm)) return 0;
  203. assert(serial_write(stm->serial, &address, 4) == SERIAL_ERR_OK);
  204. stm32_send_byte(stm, cs);
  205. if (stm32_read_byte(stm) != STM32_ACK) return 0;
  206. /* setup the cs and send the length */
  207. extra = len % 4;
  208. cs = len - 1 + extra;
  209. stm32_send_byte(stm, cs);
  210. /* write the data and build the checksum */
  211. for(i = 0; i < len; ++i)
  212. cs ^= data[i];
  213. assert(serial_write(stm->serial, data, len) == SERIAL_ERR_OK);
  214. /* write the alignment padding */
  215. for(c = 0; c < extra; ++c) {
  216. stm32_send_byte(stm, 0xFF);
  217. cs ^= 0xFF;
  218. }
  219. /* send the checksum */
  220. stm32_send_byte(stm, cs);
  221. return stm32_read_byte(stm) == STM32_ACK;
  222. }
  223. char stm32_wunprot_memory(const stm32_t *stm) {
  224. if (!stm32_send_command(stm, stm->cmd->uw)) return 0;
  225. if (!stm32_send_command(stm, 0x8C )) return 0;
  226. return 1;
  227. }
  228. char stm32_erase_memory(const stm32_t *stm, uint8_t spage, uint8_t pages) {
  229. if (!stm32_send_command(stm, stm->cmd->er)) {
  230. fprintf(stderr, "Can't initiate chip erase!\n");
  231. return 0;
  232. }
  233. /* The erase command reported by the bootloader is either 0x43 or 0x44 */
  234. /* 0x44 is Extended Erase, a 2 byte based protocol and needs to be handled differently. */
  235. if (stm->cmd->er == STM32_CMD_EE) {
  236. /* Not all chips using Extended Erase support mass erase */
  237. /* Currently known as not supporting mass erase is the Ultra Low Power STM32L15xx range */
  238. /* So if someone has not overridden the default, but uses one of these chips, take it out of */
  239. /* mass erase mode, so it will be done page by page. This maximum might not be correct either! */
  240. if (stm->pid == 0x416 && pages == 0xFF) pages = 0xF8; /* works for the STM32L152RB with 128Kb flash */
  241. if (pages == 0xFF) {
  242. stm32_send_byte(stm, 0xFF);
  243. stm32_send_byte(stm, 0xFF); // 0xFFFF the magic number for mass erase
  244. stm32_send_byte(stm, 0x00); // 0x00 the XOR of those two bytes as a checksum
  245. if (stm32_read_byte(stm) != STM32_ACK) {
  246. fprintf(stderr, "Mass erase failed. Try specifying the number of pages to be erased.\n");
  247. return 0;
  248. }
  249. return 1;
  250. }
  251. uint16_t pg_num;
  252. uint8_t pg_byte;
  253. uint8_t cs = 0;
  254. stm32_send_byte(stm, pages >> 8); // Number of pages to be erased, two bytes, MSB first
  255. stm32_send_byte(stm, pages & 0xFF);
  256. for (pg_num = 0; pg_num <= pages; pg_num++) {
  257. pg_byte = pg_num >> 8;
  258. cs ^= pg_byte;
  259. stm32_send_byte(stm, pg_byte);
  260. pg_byte = pg_num & 0xFF;
  261. cs ^= pg_byte;
  262. stm32_send_byte(stm, pg_byte);
  263. }
  264. stm32_send_byte(stm, 0x00); // Ought to need to hand over a valid checksum here...but 0 seems to work!
  265. if (stm32_read_byte(stm) != STM32_ACK) {
  266. fprintf(stderr, "Page-by-page erase failed. Check the maximum pages your device supports.\n");
  267. return 0;
  268. }
  269. return 1;
  270. }
  271. /* And now the regular erase (0x43) for all other chips */
  272. if (pages == 0xFF) {
  273. return stm32_send_command(stm, 0xFF);
  274. } else {
  275. uint8_t cs = 0;
  276. uint8_t pg_num;
  277. stm32_send_byte(stm, pages-1);
  278. cs ^= (pages-1);
  279. for (pg_num = spage; pg_num < (pages + spage); pg_num++) {
  280. stm32_send_byte(stm, pg_num);
  281. cs ^= pg_num;
  282. }
  283. stm32_send_byte(stm, cs);
  284. return stm32_read_byte(stm) == STM32_ACK;
  285. }
  286. }
  287. char stm32_go(const stm32_t *stm, uint32_t address) {
  288. uint8_t cs;
  289. address = be_u32 (address);
  290. cs = stm32_gen_cs(address);
  291. if (!stm32_send_command(stm, stm->cmd->go)) return 0;
  292. serial_write(stm->serial, &address, 4);
  293. serial_write(stm->serial, &cs , 1);
  294. return stm32_read_byte(stm) == STM32_ACK;
  295. }
  296. char stm32_reset_device(const stm32_t *stm) {
  297. /*
  298. since the bootloader does not have a reset command, we
  299. upload the stmreset program into ram and run it, which
  300. resets the device for us
  301. */
  302. uint32_t length = stmreset_length;
  303. unsigned char* pos = stmreset_binary;
  304. uint32_t address = stm->dev->ram_start;
  305. while(length > 0) {
  306. uint32_t w = length > 256 ? 256 : length;
  307. if (!stm32_write_memory(stm, address, pos, w))
  308. return 0;
  309. address += w;
  310. pos += w;
  311. length -= w;
  312. }
  313. return stm32_go(stm, stm->dev->ram_start);
  314. }