SimonQian <simonqian@simonqian.com> AVR wip
[fw/openocd] / src / flash / avrf.c
1 /***************************************************************************\r
2  *   Copyright (C) 2009 by Simon Qian                                      *\r
3  *   SimonQian@SimonQian.com                                               *\r
4  *                                                                         *\r
5  *   This program is free software; you can redistribute it and/or modify  *\r
6  *   it under the terms of the GNU General Public License as published by  *\r
7  *   the Free Software Foundation; either version 2 of the License, or     *\r
8  *   (at your option) any later version.                                   *\r
9  *                                                                         *\r
10  *   This program is distributed in the hope that it will be useful,       *\r
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
13  *   GNU General Public License for more details.                          *\r
14  *                                                                         *\r
15  *   You should have received a copy of the GNU General Public License     *\r
16  *   along with this program; if not, write to the                         *\r
17  *   Free Software Foundation, Inc.,                                       *\r
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
19  ***************************************************************************/\r
20 #ifdef HAVE_CONFIG_H\r
21 #include "config.h"\r
22 #endif\r
23 \r
24 #include "replacements.h"\r
25 \r
26 #include "avrf.h"\r
27 #include "avrt.h"\r
28 #include "flash.h"\r
29 #include "target.h"\r
30 #include "log.h"\r
31 #include "algorithm.h"\r
32 #include "binarybuffer.h"\r
33 \r
34 #include <stdlib.h>\r
35 #include <string.h>\r
36 \r
37 /* AVR_JTAG_Instructions */\r
38 #define AVR_JTAG_INS_LEN                                                        4\r
39 // Public Instructions:\r
40 #define AVR_JTAG_INS_EXTEST                                                     0x00\r
41 #define AVR_JTAG_INS_IDCODE                                                     0x01\r
42 #define AVR_JTAG_INS_SAMPLE_PRELOAD                                     0x02\r
43 #define AVR_JTAG_INS_BYPASS                                                     0x0F\r
44 // AVR Specified Public Instructions:\r
45 #define AVR_JTAG_INS_AVR_RESET                                          0x0C\r
46 #define AVR_JTAG_INS_PROG_ENABLE                                        0x04\r
47 #define AVR_JTAG_INS_PROG_COMMANDS                                      0x05\r
48 #define AVR_JTAG_INS_PROG_PAGELOAD                                      0x06\r
49 #define AVR_JTAG_INS_PROG_PAGEREAD                                      0x07\r
50 \r
51 // Data Registers:\r
52 #define AVR_JTAG_REG_Bypass_Len                                         1\r
53 #define AVR_JTAG_REG_DeviceID_Len                                       32\r
54 \r
55 #define AVR_JTAG_REG_Reset_Len                                          1\r
56 #define AVR_JTAG_REG_JTAGID_Len                                         32\r
57 #define AVR_JTAG_REG_ProgrammingEnable_Len                      16\r
58 #define AVR_JTAG_REG_ProgrammingCommand_Len                     15\r
59 #define AVR_JTAG_REG_FlashDataByte_Len                          16\r
60 \r
61 avrf_type_t avft_chips_info[] = \r
62 {\r
63 //       name,                  chip_id,        flash_page_size,        flash_page_num, eeprom_page_size,       eeprom_page_num\r
64         {"atmega128",   0x9702,         256,                            512,                    8,                                      512},\r
65 };\r
66 \r
67 static int avrf_register_commands(struct command_context_s *cmd_ctx);\r
68 static int avrf_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);\r
69 static int avrf_erase(struct flash_bank_s *bank, int first, int last);\r
70 static int avrf_protect(struct flash_bank_s *bank, int set, int first, int last);\r
71 static int avrf_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);\r
72 static int avrf_probe(struct flash_bank_s *bank);\r
73 static int avrf_auto_probe(struct flash_bank_s *bank);\r
74 //static int avrf_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
75 static int avrf_protect_check(struct flash_bank_s *bank);\r
76 static int avrf_info(struct flash_bank_s *bank, char *buf, int buf_size);\r
77 \r
78 static int avrf_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
79 \r
80 extern int avr_jtag_sendinstr(jtag_tap_t *tap, u8 *ir_in, u8 ir_out);\r
81 extern int avr_jtag_senddat(jtag_tap_t *tap, u32 *dr_in, u32 dr_out, int len);\r
82 \r
83 extern int mcu_write_ir(jtag_tap_t *tap, u8 *ir_in, u8 *ir_out, int ir_len, int rti);\r
84 extern int mcu_write_dr(jtag_tap_t *tap, u8 *ir_in, u8 *ir_out, int dr_len, int rti);\r
85 extern int mcu_write_ir_u8(jtag_tap_t *tap, u8 *ir_in, u8 ir_out, int ir_len, int rti);\r
86 extern int mcu_write_dr_u8(jtag_tap_t *tap, u8 *ir_in, u8 ir_out, int dr_len, int rti);\r
87 extern int mcu_write_ir_u16(jtag_tap_t *tap, u16 *ir_in, u16 ir_out, int ir_len, int rti);\r
88 extern int mcu_write_dr_u16(jtag_tap_t *tap, u16 *ir_in, u16 ir_out, int dr_len, int rti);\r
89 extern int mcu_write_ir_u32(jtag_tap_t *tap, u32 *ir_in, u32 ir_out, int ir_len, int rti);\r
90 extern int mcu_write_dr_u32(jtag_tap_t *tap, u32 *ir_in, u32 ir_out, int dr_len, int rti);\r
91 extern int mcu_execute_queue(void);\r
92 \r
93 flash_driver_t avr_flash =\r
94 {\r
95         .name = "avr",\r
96         .register_commands = avrf_register_commands,\r
97         .flash_bank_command = avrf_flash_bank_command,\r
98         .erase = avrf_erase,\r
99         .protect = avrf_protect,\r
100         .write = avrf_write,\r
101         .probe = avrf_probe,\r
102         .auto_probe = avrf_auto_probe,\r
103         .erase_check = default_flash_mem_blank_check,\r
104         .protect_check = avrf_protect_check,\r
105         .info = avrf_info\r
106 };\r
107 \r
108 /* avr program functions */\r
109 static int avr_jtag_reset(avr_common_t *avr, u32 reset)\r
110 {\r
111         avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_AVR_RESET);\r
112         avr_jtag_senddat(avr->jtag_info.tap, NULL, reset ,AVR_JTAG_REG_Reset_Len);\r
113         \r
114         return ERROR_OK;\r
115 }\r
116 \r
117 static int avr_jtag_read_jtagid(avr_common_t *avr, u32 *id)\r
118 {\r
119         avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_IDCODE);\r
120         avr_jtag_senddat(avr->jtag_info.tap, id, 0, AVR_JTAG_REG_JTAGID_Len);\r
121         \r
122         return ERROR_OK;\r
123 }\r
124 \r
125 static int avr_jtagprg_enterprogmode(avr_common_t *avr)\r
126 {\r
127         avr_jtag_reset(avr, 1);\r
128         \r
129         avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_ENABLE);\r
130         avr_jtag_senddat(avr->jtag_info.tap, NULL, 0xA370, AVR_JTAG_REG_ProgrammingEnable_Len);\r
131         \r
132         return ERROR_OK;\r
133 }\r
134 \r
135 static int avr_jtagprg_leaveprogmode(avr_common_t *avr)\r
136 {\r
137         avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS);\r
138         avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2300, AVR_JTAG_REG_ProgrammingCommand_Len);\r
139         avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3300, AVR_JTAG_REG_ProgrammingCommand_Len);\r
140 \r
141         avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_ENABLE);\r
142         avr_jtag_senddat(avr->jtag_info.tap, NULL, 0, AVR_JTAG_REG_ProgrammingEnable_Len);\r
143 \r
144         avr_jtag_reset(avr, 0);\r
145         \r
146         return ERROR_OK;\r
147 }\r
148 \r
149 static int avr_jtagprg_chiperase(avr_common_t *avr)\r
150 {\r
151         u32 poll_value;\r
152         \r
153         avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS);\r
154         avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2380, AVR_JTAG_REG_ProgrammingCommand_Len);\r
155         avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3180, AVR_JTAG_REG_ProgrammingCommand_Len);\r
156         avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3380, AVR_JTAG_REG_ProgrammingCommand_Len);\r
157         avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3380, AVR_JTAG_REG_ProgrammingCommand_Len);\r
158         \r
159         do{\r
160                 poll_value = 0;\r
161                 avr_jtag_senddat(avr->jtag_info.tap, &poll_value, 0x3380, AVR_JTAG_REG_ProgrammingCommand_Len);\r
162                 if (ERROR_OK != mcu_execute_queue())\r
163                 {\r
164                         return ERROR_FAIL;\r
165                 }\r
166                 LOG_DEBUG("poll_value = 0x%04X", poll_value);\r
167         }while(!(poll_value & 0x0200));\r
168         \r
169         return ERROR_OK;\r
170 }\r
171 \r
172 static int avr_jtagprg_writeflashpage(avr_common_t *avr, u8 *page_buf, u32 buf_size, u32 addr, u32 page_size)\r
173 {\r
174         u32 i, poll_value;\r
175         \r
176         avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS);\r
177         avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2310, AVR_JTAG_REG_ProgrammingCommand_Len);\r
178         \r
179         // load addr high byte\r
180         avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x0700 | ((addr >> 9) & 0xFF), AVR_JTAG_REG_ProgrammingCommand_Len);\r
181         \r
182         // load addr low byte\r
183         avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x0300 | ((addr >> 1) & 0xFF), AVR_JTAG_REG_ProgrammingCommand_Len);\r
184         \r
185         avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_PAGELOAD);\r
186         \r
187         for (i = 0; i < page_size; i++)\r
188         {\r
189                 if (i < buf_size)\r
190                 {\r
191                         avr_jtag_senddat(avr->jtag_info.tap, NULL, page_buf[i], 8);\r
192                 }\r
193                 else\r
194                 {\r
195                         avr_jtag_senddat(avr->jtag_info.tap, NULL, 0xFF, 8);\r
196                 }\r
197         }\r
198         \r
199         avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS);\r
200         \r
201         avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3700, AVR_JTAG_REG_ProgrammingCommand_Len);\r
202         avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3500, AVR_JTAG_REG_ProgrammingCommand_Len);\r
203         avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3700, AVR_JTAG_REG_ProgrammingCommand_Len);\r
204         avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3700, AVR_JTAG_REG_ProgrammingCommand_Len);\r
205         \r
206         do{\r
207                 poll_value = 0;\r
208                 avr_jtag_senddat(avr->jtag_info.tap, &poll_value, 0x3700, AVR_JTAG_REG_ProgrammingCommand_Len);\r
209                 if (ERROR_OK != mcu_execute_queue())\r
210                 {\r
211                         return ERROR_FAIL;\r
212                 }\r
213                 LOG_DEBUG("poll_value = 0x%04X", poll_value);\r
214         }while(!(poll_value & 0x0200));\r
215         \r
216         return ERROR_OK;\r
217 }\r
218 \r
219 /* interface command */\r
220 static int avrf_register_commands(struct command_context_s *cmd_ctx)\r
221 {\r
222         command_t *avr_cmd = register_command(cmd_ctx, NULL, "avr", NULL, COMMAND_ANY, "avr flash specific commands");\r
223         \r
224         register_command(cmd_ctx, avr_cmd, "mass_erase", avrf_handle_mass_erase_command, COMMAND_EXEC,\r
225                                          "mass erase device");\r
226         \r
227         return ERROR_OK;\r
228 }\r
229 \r
230 static int avrf_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)\r
231 {\r
232         avrf_flash_bank_t *avrf_info;\r
233         \r
234         if (argc < 6)\r
235         {\r
236                 LOG_WARNING("incomplete flash_bank avr configuration");\r
237                 return ERROR_FLASH_BANK_INVALID;\r
238         }\r
239         \r
240         avrf_info = malloc(sizeof(avrf_flash_bank_t));\r
241         bank->driver_priv = avrf_info;\r
242         \r
243         avrf_info->probed = 0;\r
244         \r
245         return ERROR_OK;\r
246 }\r
247 \r
248 static int avrf_erase(struct flash_bank_s *bank, int first, int last)\r
249 {\r
250         LOG_INFO(__FUNCTION__);\r
251         return ERROR_OK;\r
252 }\r
253 \r
254 static int avrf_protect(struct flash_bank_s *bank, int set, int first, int last)\r
255 {\r
256         LOG_INFO(__FUNCTION__);\r
257         return ERROR_OK;\r
258 }\r
259 \r
260 static int avrf_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)\r
261 {\r
262         target_t *target = bank->target;\r
263         avr_common_t *avr = target->arch_info;\r
264         u32 cur_size, cur_buffer_size, page_size;\r
265         \r
266         if (bank->target->state != TARGET_HALTED)\r
267         {\r
268                 LOG_ERROR("Target not halted");\r
269                 return ERROR_TARGET_NOT_HALTED;\r
270         }\r
271         \r
272         page_size = bank->sectors[0].size;\r
273         if ((offset % page_size) != 0)\r
274         {\r
275                 LOG_WARNING("offset 0x%x breaks required %d-byte alignment", offset, page_size);\r
276                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;\r
277         }\r
278         \r
279         LOG_DEBUG("offset is 0x%08X", offset);\r
280         LOG_DEBUG("count is %d", count);\r
281         \r
282         if (ERROR_OK != avr_jtagprg_enterprogmode(avr))\r
283         {\r
284                 return ERROR_FAIL;\r
285         }\r
286         \r
287         cur_size = 0;\r
288         while(count > 0)\r
289         {\r
290                 if (count > page_size)\r
291                 {\r
292                         cur_buffer_size = page_size;\r
293                 }\r
294                 else\r
295                 {\r
296                         cur_buffer_size = count;\r
297                 }\r
298                 avr_jtagprg_writeflashpage(avr, buffer + cur_size, cur_buffer_size, offset + cur_size, page_size);\r
299                 count -= cur_buffer_size;\r
300                 cur_size += cur_buffer_size;\r
301                 \r
302                 keep_alive();\r
303         }\r
304         \r
305         return avr_jtagprg_leaveprogmode(avr);\r
306 }\r
307 \r
308 #define EXTRACT_MFG(X)  (((X) & 0xffe) >> 1)\r
309 #define EXTRACT_PART(X) (((X) & 0xffff000) >> 12)\r
310 #define EXTRACT_VER(X)  (((X) & 0xf0000000) >> 28)\r
311 static int avrf_probe(struct flash_bank_s *bank)\r
312 {\r
313         target_t *target = bank->target;\r
314         avrf_flash_bank_t *avrf_info = bank->driver_priv;\r
315         avr_common_t *avr = target->arch_info;\r
316         avrf_type_t *avr_info;\r
317         int i;\r
318         u32 device_id;\r
319         \r
320         if (bank->target->state != TARGET_HALTED)\r
321         {\r
322                 LOG_ERROR("Target not halted");\r
323                 return ERROR_TARGET_NOT_HALTED;\r
324         }\r
325 \r
326         avrf_info->probed = 0;\r
327         \r
328         avr_jtag_read_jtagid(avr, &device_id);\r
329         if (ERROR_OK != mcu_execute_queue())\r
330         {\r
331                 return ERROR_FAIL;\r
332         }\r
333         \r
334         LOG_INFO( "device id = 0x%08x", device_id );\r
335         if (EXTRACT_MFG(device_id) != 0x1F)\r
336         {\r
337                 LOG_ERROR("0x%X is invalid Manufacturer for avr, 0x%X is expected", EXTRACT_MFG(device_id), 0x1F);\r
338         }\r
339         \r
340         for (i = 0; i < (int)(sizeof(avft_chips_info) / sizeof(avft_chips_info[0])); i++)\r
341         {\r
342                 if (avft_chips_info[i].chip_id == EXTRACT_PART(device_id))\r
343                 {\r
344                         avr_info = &avft_chips_info[i];\r
345                         LOG_INFO("target device is %s", avr_info->name);\r
346                         break;\r
347                 }\r
348         }\r
349         \r
350         if (i < (int)(sizeof(avft_chips_info) / sizeof(avft_chips_info[0])))\r
351         {\r
352                 // chip found\r
353                 bank->base = 0x00000000;\r
354                 bank->size = (avr_info->flash_page_size * avr_info->flash_page_num);\r
355                 bank->num_sectors = avr_info->flash_page_num;\r
356                 bank->sectors = malloc(sizeof(flash_sector_t) * avr_info->flash_page_num);\r
357                 \r
358                 for (i = 0; i < avr_info->flash_page_num; i++)\r
359                 {\r
360                         bank->sectors[i].offset = i * avr_info->flash_page_size;\r
361                         bank->sectors[i].size = avr_info->flash_page_size;\r
362                         bank->sectors[i].is_erased = -1;\r
363                         bank->sectors[i].is_protected = 1;\r
364                 }\r
365                 \r
366                 avrf_info->probed = 1;\r
367                 return ERROR_OK;\r
368         }\r
369         else\r
370         {\r
371                 // chip not supported\r
372                 LOG_ERROR("0x%X is not support for avr", EXTRACT_PART(device_id));\r
373                 \r
374                 avrf_info->probed = 1;\r
375                 return ERROR_FAIL;\r
376         }\r
377 }\r
378 \r
379 static int avrf_auto_probe(struct flash_bank_s *bank)\r
380 {\r
381         avrf_flash_bank_t *avrf_info = bank->driver_priv;\r
382         if (avrf_info->probed)\r
383                 return ERROR_OK;\r
384         return avrf_probe(bank);\r
385 }\r
386 \r
387 static int avrf_protect_check(struct flash_bank_s *bank)\r
388 {\r
389         LOG_INFO(__FUNCTION__);\r
390         return ERROR_OK;\r
391 }\r
392 \r
393 static int avrf_info(struct flash_bank_s *bank, char *buf, int buf_size)\r
394 {\r
395         target_t *target = bank->target;\r
396         avr_common_t *avr = target->arch_info;\r
397         avrf_type_t *avr_info;\r
398         int i;\r
399         u32 device_id;\r
400         \r
401         if (bank->target->state != TARGET_HALTED)\r
402         {\r
403                 LOG_ERROR("Target not halted");\r
404                 return ERROR_TARGET_NOT_HALTED;\r
405         }\r
406         \r
407         avr_jtag_read_jtagid(avr, &device_id);\r
408         if (ERROR_OK != mcu_execute_queue())\r
409         {\r
410                 return ERROR_FAIL;\r
411         }\r
412         \r
413         LOG_INFO( "device id = 0x%08x", device_id );\r
414         if (EXTRACT_MFG(device_id) != 0x1F)\r
415         {\r
416                 LOG_ERROR("0x%X is invalid Manufacturer for avr, 0x%X is expected", EXTRACT_MFG(device_id), 0x1F);\r
417         }\r
418         \r
419         for (i = 0; i < (int)(sizeof(avft_chips_info) / sizeof(avft_chips_info[0])); i++)\r
420         {\r
421                 if (avft_chips_info[i].chip_id == EXTRACT_PART(device_id))\r
422                 {\r
423                         avr_info = &avft_chips_info[i];\r
424                         LOG_INFO("target device is %s", avr_info->name);\r
425                         \r
426                         return ERROR_OK;\r
427                 }\r
428         }\r
429         \r
430         if (i < (int)(sizeof(avft_chips_info) / sizeof(avft_chips_info[0])))\r
431         {\r
432                 // chip found\r
433                 snprintf(buf, buf_size, "%s - Rev: 0x%X", avr_info->name, EXTRACT_VER(device_id));\r
434                 return ERROR_OK;\r
435         }\r
436         else\r
437         {\r
438                 // chip not supported\r
439                 snprintf(buf, buf_size, "Cannot identify target as a avr\n");\r
440                 return ERROR_FLASH_OPERATION_FAILED;\r
441         }\r
442 }\r
443 \r
444 static int avrf_mass_erase(struct flash_bank_s *bank)\r
445 {\r
446         target_t *target = bank->target;\r
447         avr_common_t *avr = target->arch_info;\r
448         \r
449         if (target->state != TARGET_HALTED)\r
450         {\r
451                 LOG_ERROR("Target not halted");\r
452                 return ERROR_TARGET_NOT_HALTED;\r
453         }\r
454         \r
455         if ((ERROR_OK != avr_jtagprg_enterprogmode(avr))\r
456                 || (ERROR_OK != avr_jtagprg_chiperase(avr))\r
457                 || (ERROR_OK != avr_jtagprg_leaveprogmode(avr)))\r
458         {\r
459                 return ERROR_FAIL;\r
460         }\r
461         \r
462         return ERROR_OK;\r
463 }\r
464 \r
465 static int avrf_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
466 {\r
467         flash_bank_t *bank;\r
468         int i;\r
469         \r
470         if (argc < 1)\r
471         {\r
472                 command_print(cmd_ctx, "avr mass_erase <bank>");\r
473                 return ERROR_OK;        \r
474         }\r
475         \r
476         bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));\r
477         if (!bank)\r
478         {\r
479                 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);\r
480                 return ERROR_OK;\r
481         }\r
482         \r
483         if (avrf_mass_erase(bank) == ERROR_OK)\r
484         {\r
485                 /* set all sectors as erased */\r
486                 for (i = 0; i < bank->num_sectors; i++)\r
487                 {\r
488                         bank->sectors[i].is_erased = 1;\r
489                 }\r
490                 \r
491                 command_print(cmd_ctx, "avr mass erase complete");\r
492         }\r
493         else\r
494         {\r
495                 command_print(cmd_ctx, "avr mass erase failed");\r
496         }\r
497         \r
498         LOG_DEBUG(__FUNCTION__);\r
499         return ERROR_OK;\r
500 }\r