2 * Copyright © 2008 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 /* From SWRA124 section 3.1.6 */
23 static uint8_t flash_page[] = {
25 MOV_direct_data, P1DIR, 0x02,
26 MOV_direct_data, P1, 0xFF,
28 MOV_direct_data, FADDRH, 0,
29 #define FLASH_ADDR_HIGH 8
31 MOV_direct_data, FADDRL, 0,
32 #define FLASH_ADDR_LOW 11
34 MOV_DPTR_data16, 0, 0,
35 #define RAM_ADDR_HIGH 13
36 #define RAM_ADDR_LOW 14
39 #define FLASH_WORDS_HIGH 16
42 #define FLASH_WORDS_LOW 18
44 MOV_direct_data, FWT, 0x20,
45 #define FLASH_TIMING 21
47 MOV_direct_data, FCTL, FCTL_ERASE,
50 JB, ACC(FCTL_BUSY_BIT), 0xfb,
52 MOV_direct_data, P1, 0xfd,
54 MOV_direct_data, FCTL, FCTL_WRITE,
61 DJNZ_Rn_rel(5), 0xfa, /* writeWordLoop */
64 JB, ACC(FCTL_SWBSY_BIT), 0xfb, /* writeWaitLoop */
65 DJNZ_Rn_rel(6), 0xf1, /* writeLoop */
66 DJNZ_Rn_rel(7), 0xef, /* writeLoop */
68 MOV_direct_data, P1DIR, 0x00,
69 MOV_direct_data, P1, 0xFF,
73 #define FLASH_RAM 0xf000
75 static uint8_t flash_erase_page[] = {
76 3, MOV_direct_data, FADDRH, 0,
77 #define ERASE_PAGE_HIGH 3
79 3, MOV_direct_data, FADDRL, 0,
80 #define ERASE_PAGE_LOW 7
82 3, MOV_direct_data, FWT, 0x2A,
83 3, MOV_direct_data, FCTL, FCTL_ERASE,
87 static uint8_t flash_read_control[] = {
88 2, MOV_A_direct, FCTL,
92 static uint8_t flash_control_clear[] = {
93 3, MOV_direct_data, FCTL, 0,
94 2, MOV_A_direct, FCTL,
99 ccdbg_flash_erase_page(struct ccdbg *dbg, uint16_t addr)
101 uint16_t page_addr = addr >> 1;
103 uint8_t old[0x10], new[0x10];
106 ccdbg_read_memory(dbg, addr, old, 0x10);
107 flash_erase_page[ERASE_PAGE_HIGH] = page_addr >> 8;
108 flash_erase_page[ERASE_PAGE_LOW] = page_addr & 0xff;
109 status = ccdbg_execute(dbg, flash_erase_page);
110 printf("erase status 0x%02x\n", status);
112 status = ccdbg_execute(dbg, flash_read_control);
113 printf("fctl 0x%02x\n", status);
114 } while (status & FCTL_BUSY);
115 ccdbg_read_memory(dbg, addr, new, 0x10);
116 for (i = 0; i < 0x10; i++)
117 printf("0x%02x -> 0x%02x\n", old[i], new[i]);
118 status = ccdbg_execute(dbg, flash_control_clear);
119 printf("clear fctl 0x%02x\n", status);
123 static uint8_t flash_write[] = {
124 MOV_direct_data, P1DIR, 0x02,
125 MOV_direct_data, P1, 0xFD,
128 JB, ACC(FCTL_BUSY_BIT), 0xf1,
130 MOV_direct_data, FCTL, 0x20,
132 MOV_direct_data, FADDRH, 0,
133 #define WRITE_PAGE_HIGH 16
135 MOV_direct_data, FADDRL, 0,
136 #define WRITE_PAGE_LOW 19
138 MOV_direct_data, FCTL, FCTL_WRITE,
139 MOV_direct_data, FWDATA, 0,
140 #define WRITE_BYTE_0 25
141 MOV_direct_data, FWDATA, 0,
142 #define WRITE_BYTE_1 28
144 JB, ACC(FCTL_SWBSY_BIT), 0xf1,
146 MOV_direct_data, P1, 0xFF,
151 ccdbg_clock_init(struct ccdbg *dbg)
153 static uint8_t set_clkcon_fast[] = {
154 3, MOV_direct_data, CLKCON, 0x00,
158 static uint8_t get_sleep[] = {
159 2, MOV_A_direct, SLEEP,
165 ccdbg_execute(dbg, set_clkcon_fast);
167 status = ccdbg_execute(dbg, get_sleep);
168 } while (!(status & 0x40));
173 ccdbg_flash_write_word(struct ccdbg *dbg, uint16_t addr, uint8_t data[2])
175 uint16_t page_addr = addr >> 1;
180 flash_write[WRITE_PAGE_HIGH] = page_addr >> 8;
181 flash_write[WRITE_PAGE_LOW] = page_addr & 0xff;
182 flash_write[WRITE_BYTE_0] = data[0];
183 flash_write[WRITE_BYTE_1] = data[1];
184 printf("upload flash write\n");
185 ccdbg_write_memory(dbg, 0xf000, flash_write, sizeof(flash_write));
186 ccdbg_set_pc(dbg, 0xf000);
189 status = ccdbg_read_status(dbg);
190 printf("waiting for write 0x%02x\n", status);
191 if ((status & CC_STATUS_CPU_HALTED) != 0)
195 status = ccdbg_execute(dbg, flash_control_clear);
196 printf("clear fctl 0x%02x\n", status);
197 ccdbg_read_memory(dbg, addr, check, 2);
198 for (i = 0; i < 2; i++)
199 printf("0x%02x : 0x%02x\n", data[i], check[i]);
203 #define TIMERS_OFF 0x08
204 #define DMA_PAUSE 0x04
205 #define TIMER_SUSPEND 0x02
206 #define SEL_FLASH_INFO_PAGE 0x01
209 ccdbg_flash_lock(struct ccdbg *dbg, uint8_t lock)
213 uint8_t old[1], new[1];
215 config = ccdbg_rd_config(dbg);
216 ccdbg_wr_config(dbg, config|SEL_FLASH_INFO_PAGE);
219 ccdbg_flash_erase_page(dbg, 0);
220 ccdbg_read_memory(dbg, 0, old, 1);
221 ccdbg_flash_write_word(dbg, 0, bytes);
222 ccdbg_read_memory(dbg, 0, new, 1);
223 printf ("flash lock 0x%02x -> 0x%02x\n", old[0], new[0]);
224 ccdbg_wr_config(dbg, config & ~SEL_FLASH_INFO_PAGE);
229 ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image)
232 struct hex_image *test_image;
236 uint16_t flash_word_addr;
237 uint16_t flash_words;
242 ccdbg_clock_init(dbg);
243 if (image->address + image->length > 0x8000) {
244 fprintf(stderr, "cannot flash image from 0x%04x to 0x%04x\n",
245 image->address, image->address + image->length);
248 flash_word_addr = image->address >> 1;
249 if (flash_word_addr & 0x1ff) {
250 fprintf(stderr, "flash image must start on page boundary\n");
254 offset = ram_addr - image->address;
257 printf("Downloading flash to check\n");
258 test_image = ccdbg_read_hex_image(dbg, image->address, image->length);
259 if (!ccdbg_hex_image_equal(image, test_image)) {
261 fprintf(stderr, "Image not loaded\n");
262 for (i = 0;i < 0x10; i++)
263 printf ("0x%02x : 0x%02x\n", image->data[i], test_image->data[i]);
269 printf("Upload %d bytes at 0x%04x\n", image->length, ram_addr);
270 ccdbg_write_hex_image(dbg, image, offset);
271 printf("Verify %d bytes\n", image->length);
272 test_image = ccdbg_read_hex_image(dbg, ram_addr, image->length);
273 if (!ccdbg_hex_image_equal(image, test_image)) {
274 ccdbg_hex_image_free(test_image);
275 fprintf(stderr, "image verify failed\n");
278 ccdbg_hex_image_free(test_image);
279 flash_len = image->length + (image->length & 1);
280 flash_words = flash_len >> 1;
281 flash_prog = ram_addr + flash_len;
284 flash_page[FLASH_ADDR_HIGH] = flash_word_addr >> 8;
285 flash_page[FLASH_ADDR_LOW] = flash_word_addr & 0xff;
287 flash_page[RAM_ADDR_HIGH] = ram_addr >> 8;
288 flash_page[RAM_ADDR_LOW] = ram_addr & 0xff;
290 flash_page[FLASH_WORDS_HIGH] = flash_words >> 8;
291 flash_page[FLASH_WORDS_LOW] = flash_words & 0xff;
293 flash_page[FLASH_TIMING] = fwt;
295 printf("Upload %d flash program bytes to 0x%04x\n",
296 sizeof (flash_prog), flash_prog);
297 ccdbg_write_memory(dbg, flash_prog, flash_page, sizeof(flash_page));
298 ccdbg_set_pc(dbg, flash_prog);
299 pc = ccdbg_get_pc(dbg);
300 printf("Starting flash program at 0x%04x\n", pc);
301 status = ccdbg_resume(dbg);
302 printf("resume status is 0x%02x\n", status);
304 status = ccdbg_read_status(dbg);
305 printf("chip status is 0x%02x\n", status);
307 } while ((status & CC_STATUS_CPU_HALTED) == 0);