1 /***************************************************************************
2 * Copyright (C) 2008 by *
3 * Karl RobinSod <karl.robinsod@gmail.com> *
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. *
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. *
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 ***************************************************************************/
21 /***************************************************************************
22 * There are some things to notice
24 * You need to unprotect flash sectors each time you connect the OpenOCD
25 * Dumping 1MB takes about 60 Seconds
26 * Full erase (sectors 0-22 inclusive) takes 2-4 seconds
27 * Writing 1MB takes 88 seconds
29 ***************************************************************************/
35 #include "binarybuffer.h"
38 #define LOAD_TIMER_ERASE 0
39 #define LOAD_TIMER_WRITE 1
41 #define FLASH_PAGE_SIZE 512
43 /* LPC288X control registers */
44 #define DBGU_CIDR 0x8000507C
45 /* LPC288X flash registers */
46 #define F_CTRL 0x80102000 /* Flash control register R/W 0x5 */
47 #define F_STAT 0x80102004 /* Flash status register RO 0x45 */
48 #define F_PROG_TIME 0x80102008 /* Flash program time register R/W 0 */
49 #define F_WAIT 0x80102010 /* Flash read wait state register R/W 0xC004 */
50 #define F_CLK_TIME 0x8010201C /* Flash clock divider for 66 kHz generation R/W 0 */
51 #define F_INTEN_CLR 0x80102FD8 /* Clear interrupt enable bits WO - */
52 #define F_INTEN_SET 0x80102FDC /* Set interrupt enable bits WO - */
53 #define F_INT_STAT 0x80102FE0 /* Interrupt status bits RO 0 */
54 #define F_INTEN 0x80102FE4 /* Interrupt enable bits RO 0 */
55 #define F_INT_CLR 0x80102FE8 /* Clear interrupt status bits WO */
56 #define F_INT_SET 0x80102FEC /* Set interrupt status bits WO - */
57 #define FLASH_PD 0x80005030 /* Allows turning off the Flash memory for power savings. R/W 1*/
58 #define FLASH_INIT 0x80005034 /* Monitors Flash readiness, such as recovery from Power Down mode. R/W -*/
62 #define FC_FUNC 0x0002
64 #define FC_RD_LATCH 0x0020
65 #define FC_PROTECT 0x0080
66 #define FC_SET_DATA 0x0400
67 #define FC_RSSL 0x0800
68 #define FC_PROG_REQ 0x1000
69 #define FC_CLR_BUF 0x4000
70 #define FC_LOAD_REQ 0x8000
72 #define FS_DONE 0x0001
73 #define FS_PROGGNT 0x0002
77 #define FPT_TIME_MASK 0x7FFF
79 #define FPT_ENABLE 0x8000
81 #define FW_WAIT_STATES_MASK 0x00FF
82 #define FW_SET_MASK 0xC000
85 #define FCT_CLK_DIV_MASK 0x0FFF
88 static int lpc288x_register_commands(struct command_context_s
*cmd_ctx
);
89 static int lpc288x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
90 static int lpc288x_erase(struct flash_bank_s
*bank
, int first
, int last
);
91 static int lpc288x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
92 static int lpc288x_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
);
93 static int lpc288x_probe(struct flash_bank_s
*bank
);
94 static int lpc288x_erase_check(struct flash_bank_s
*bank
);
95 static int lpc288x_protect_check(struct flash_bank_s
*bank
);
96 static int lpc288x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
98 static uint32_t lpc288x_wait_status_busy(flash_bank_t
*bank
, int timeout
);
99 static void lpc288x_load_timer(int erase
, struct target_s
*target
);
100 static void lpc288x_set_flash_clk(struct flash_bank_s
*bank
);
101 static uint32_t lpc288x_system_ready(struct flash_bank_s
*bank
);
103 static uint32_t lpc288x_wait_status_busy(flash_bank_t
*bank
, int timeout
)
106 target_t
*target
= bank
->target
;
111 target_read_u32(target
, F_STAT
, &status
);
112 } while (((status
& FS_DONE
) == 0) && timeout
);
116 LOG_DEBUG("Timedout!");
117 return ERROR_FLASH_OPERATION_FAILED
;
122 /* Read device id register and fill in driver info structure */
123 static int lpc288x_read_part_info(struct flash_bank_s
*bank
)
125 lpc288x_flash_bank_t
*lpc288x_info
= bank
->driver_priv
;
126 target_t
*target
= bank
->target
;
132 if (lpc288x_info
->cidr
== 0x0102100A)
133 return ERROR_OK
; /* already probed, multiple probes may cause memory leak, not allowed */
135 /* Read and parse chip identification register */
136 target_read_u32(target
, DBGU_CIDR
, &cidr
);
138 if (cidr
!= 0x0102100A)
140 LOG_WARNING("Cannot identify target as an LPC288X (%08" PRIx32
")",cidr
);
141 return ERROR_FLASH_OPERATION_FAILED
;
144 lpc288x_info
->cidr
= cidr
;
145 lpc288x_info
->sector_size_break
= 0x000F0000;
146 lpc288x_info
->target_name
= "LPC288x";
148 /* setup the sector info... */
150 bank
->num_sectors
= 23;
151 bank
->sectors
= malloc(sizeof(flash_sector_t
) * 23);
153 for (i
= 0; i
< 15; i
++)
155 bank
->sectors
[i
].offset
= offset
;
156 bank
->sectors
[i
].size
= 64 * 1024;
157 offset
+= bank
->sectors
[i
].size
;
158 bank
->sectors
[i
].is_erased
= -1;
159 bank
->sectors
[i
].is_protected
= 1;
161 for (i
= 15; i
< 23; i
++)
163 bank
->sectors
[i
].offset
= offset
;
164 bank
->sectors
[i
].size
= 8 * 1024;
165 offset
+= bank
->sectors
[i
].size
;
166 bank
->sectors
[i
].is_erased
= -1;
167 bank
->sectors
[i
].is_protected
= 1;
173 static int lpc288x_protect_check(struct flash_bank_s
*bank
)
178 /* flash_bank LPC288x 0 0 0 0 <target#> <cclk> */
179 static int lpc288x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
181 lpc288x_flash_bank_t
*lpc288x_info
;
185 LOG_WARNING("incomplete flash_bank LPC288x configuration");
186 return ERROR_FLASH_BANK_INVALID
;
189 lpc288x_info
= malloc(sizeof(lpc288x_flash_bank_t
));
190 bank
->driver_priv
= lpc288x_info
;
192 /* part wasn't probed for info yet */
193 lpc288x_info
->cidr
= 0;
194 COMMAND_PARSE_NUMBER(u32
, args
[6], lpc288x_info
->cclk
);
199 /* The frequency is the AHB clock frequency divided by (CLK_DIV ×3) + 1.
200 * This must be programmed such that the Flash Programming clock frequency is 66 kHz ± 20%.
202 * 12000000/66000 = 182
204 static void lpc288x_set_flash_clk(struct flash_bank_s
*bank
)
207 lpc288x_flash_bank_t
*lpc288x_info
= bank
->driver_priv
;
208 clk_time
= (lpc288x_info
->cclk
/ 66000) / 3;
209 target_write_u32(bank
->target
, F_CTRL
, FC_CS
| FC_WEN
);
210 target_write_u32(bank
->target
, F_CLK_TIME
, clk_time
);
213 /* AHB tcyc (in ns) 83 ns
214 * LOAD_TIMER_ERASE FPT_TIME = ((400,000,000 / AHB tcyc (in ns)) - 2) / 512
215 * = 9412 (9500) (AN10548 9375)
216 * LOAD_TIMER_WRITE FPT_TIME = ((1,000,000 / AHB tcyc (in ns)) - 2) / 512
217 * = 23 (75) (AN10548 72 - is this wrong?)
218 * TODO: Sort out timing calcs ;) */
219 static void lpc288x_load_timer(int erase
, struct target_s
*target
)
221 if (erase
== LOAD_TIMER_ERASE
)
223 target_write_u32(target
, F_PROG_TIME
, FPT_ENABLE
| 9500);
227 target_write_u32(target
, F_PROG_TIME
, FPT_ENABLE
| 75);
231 static uint32_t lpc288x_system_ready(struct flash_bank_s
*bank
)
233 lpc288x_flash_bank_t
*lpc288x_info
= bank
->driver_priv
;
234 if (lpc288x_info
->cidr
== 0)
236 return ERROR_FLASH_BANK_NOT_PROBED
;
239 if (bank
->target
->state
!= TARGET_HALTED
)
241 LOG_ERROR("Target not halted");
242 return ERROR_TARGET_NOT_HALTED
;
247 static int lpc288x_erase_check(struct flash_bank_s
*bank
)
249 uint32_t status
= lpc288x_system_ready(bank
); /* probed? halted? */
250 if (status
!= ERROR_OK
)
252 LOG_INFO("Processor not halted/not probed");
259 static int lpc288x_erase(struct flash_bank_s
*bank
, int first
, int last
)
263 target_t
*target
= bank
->target
;
265 status
= lpc288x_system_ready(bank
); /* probed? halted? */
266 if (status
!= ERROR_OK
)
271 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
273 LOG_INFO("Bad sector range");
274 return ERROR_FLASH_SECTOR_INVALID
;
277 /* Configure the flash controller timing */
278 lpc288x_set_flash_clk(bank
);
280 for (sector
= first
; sector
<= last
; sector
++)
282 if (lpc288x_wait_status_busy(bank
, 1000) != ERROR_OK
)
284 return ERROR_FLASH_OPERATION_FAILED
;
287 lpc288x_load_timer(LOAD_TIMER_ERASE
,target
);
289 target_write_u32(target
, bank
->sectors
[sector
].offset
, 0x00);
291 target_write_u32(target
, F_CTRL
, FC_PROG_REQ
| FC_PROTECT
| FC_CS
);
293 if (lpc288x_wait_status_busy(bank
, 1000) != ERROR_OK
)
295 return ERROR_FLASH_OPERATION_FAILED
;
300 static int lpc288x_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
302 uint8_t page_buffer
[FLASH_PAGE_SIZE
];
303 uint32_t status
, source_offset
,dest_offset
;
304 target_t
*target
= bank
->target
;
305 uint32_t bytes_remaining
= count
;
306 uint32_t first_sector
, last_sector
, sector
, page
;
309 /* probed? halted? */
310 status
= lpc288x_system_ready(bank
);
311 if (status
!= ERROR_OK
)
316 /* Initialise search indices */
317 first_sector
= last_sector
= 0xffffffff;
319 /* validate the write range... */
320 for (i
= 0; i
< bank
->num_sectors
; i
++)
322 if ((offset
>= bank
->sectors
[i
].offset
) &&
323 (offset
< (bank
->sectors
[i
].offset
+ bank
->sectors
[i
].size
)) &&
324 (first_sector
== 0xffffffff))
327 /* all writes must start on a sector boundary... */
328 if (offset
% bank
->sectors
[i
].size
)
330 LOG_INFO("offset 0x%" PRIx32
" breaks required alignment 0x%" PRIx32
"", offset
, bank
->sectors
[i
].size
);
331 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
334 if (((offset
+ count
) > bank
->sectors
[i
].offset
) &&
335 ((offset
+ count
) <= (bank
->sectors
[i
].offset
+ bank
->sectors
[i
].size
)) &&
336 (last_sector
== 0xffffffff))
343 if (first_sector
== 0xffffffff || last_sector
== 0xffffffff)
345 LOG_INFO("Range check failed %" PRIx32
" %" PRIx32
"", offset
, count
);
346 return ERROR_FLASH_DST_OUT_OF_BANK
;
349 /* Configure the flash controller timing */
350 lpc288x_set_flash_clk(bank
);
352 /* initialise the offsets */
356 for (sector
= first_sector
; sector
<= last_sector
; sector
++)
358 for (page
= 0; page
< bank
->sectors
[sector
].size
/ FLASH_PAGE_SIZE
; page
++)
360 if (bytes_remaining
== 0)
363 memset(page_buffer
, 0xFF, FLASH_PAGE_SIZE
);
365 else if (bytes_remaining
< FLASH_PAGE_SIZE
)
367 count
= bytes_remaining
;
368 memset(page_buffer
, 0xFF, FLASH_PAGE_SIZE
);
369 memcpy(page_buffer
, &buffer
[source_offset
], count
);
373 count
= FLASH_PAGE_SIZE
;
374 memcpy(page_buffer
, &buffer
[source_offset
], count
);
377 /* Wait for flash to become ready */
378 if (lpc288x_wait_status_busy(bank
, 1000) != ERROR_OK
)
380 return ERROR_FLASH_OPERATION_FAILED
;
383 /* fill flash data latches with 1's */
384 target_write_u32(target
, F_CTRL
, FC_CS
| FC_SET_DATA
| FC_WEN
| FC_FUNC
);
386 target_write_u32(target
, F_CTRL
, FC_CS
| FC_WEN
| FC_FUNC
);
387 /*would be better to use the clean target_write_buffer() interface but
388 * it seems not to be a LOT slower....
389 * bulk_write_memory() is no quicker :(*/
391 if (target_write_memory(target
, offset
+ dest_offset
, 4, 128, page_buffer
) != ERROR_OK
)
393 LOG_ERROR("Write failed s %" PRIx32
" p %" PRIx32
"", sector
, page
);
394 return ERROR_FLASH_OPERATION_FAILED
;
397 if (target_write_buffer(target
, offset
+ dest_offset
, FLASH_PAGE_SIZE
, page_buffer
) != ERROR_OK
)
399 LOG_INFO("Write to flash buffer failed");
400 return ERROR_FLASH_OPERATION_FAILED
;
403 dest_offset
+= FLASH_PAGE_SIZE
;
404 source_offset
+= count
;
405 bytes_remaining
-= count
;
407 lpc288x_load_timer(LOAD_TIMER_WRITE
, target
);
409 target_write_u32(target
, F_CTRL
, FC_PROG_REQ
| FC_PROTECT
| FC_FUNC
| FC_CS
);
416 static int lpc288x_probe(struct flash_bank_s
*bank
)
418 /* we only deal with LPC2888 so flash config is fixed */
419 lpc288x_flash_bank_t
*lpc288x_info
= bank
->driver_priv
;
422 if (lpc288x_info
->cidr
!= 0)
424 return ERROR_OK
; /* already probed */
427 if (bank
->target
->state
!= TARGET_HALTED
)
429 LOG_ERROR("Target not halted");
430 return ERROR_TARGET_NOT_HALTED
;
433 retval
= lpc288x_read_part_info(bank
);
434 if (retval
!= ERROR_OK
)
439 static int lpc288x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
441 snprintf(buf
, buf_size
, "lpc288x flash driver");
445 static int lpc288x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
447 int lockregion
, status
;
449 target_t
*target
= bank
->target
;
451 /* probed? halted? */
452 status
= lpc288x_system_ready(bank
);
453 if (status
!= ERROR_OK
)
458 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
460 return ERROR_FLASH_SECTOR_INVALID
;
463 /* Configure the flash controller timing */
464 lpc288x_set_flash_clk(bank
);
466 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
470 /* write an odd value to base addy to protect... */
475 /* write an even value to base addy to unprotect... */
478 target_write_u32(target
, bank
->sectors
[lockregion
].offset
, value
);
479 target_write_u32(target
, F_CTRL
, FC_LOAD_REQ
| FC_PROTECT
| FC_WEN
| FC_FUNC
| FC_CS
);
485 flash_driver_t lpc288x_flash
= {
487 .flash_bank_command
= &lpc288x_flash_bank_command
,
488 .erase
= &lpc288x_erase
,
489 .protect
= &lpc288x_protect
,
490 .write
= &lpc288x_write
,
491 .probe
= &lpc288x_probe
,
492 .auto_probe
= &lpc288x_probe
,
493 .erase_check
= &lpc288x_erase_check
,
494 .protect_check
= &lpc288x_protect_check
,
495 .info
= &lpc288x_info
,