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
87 static int lpc288x_register_commands(struct command_context_s
*cmd_ctx
);
88 static int lpc288x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
89 static int lpc288x_erase(struct flash_bank_s
*bank
, int first
, int last
);
90 static int lpc288x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
91 static int lpc288x_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
);
92 static int lpc288x_probe(struct flash_bank_s
*bank
);
93 static int lpc288x_erase_check(struct flash_bank_s
*bank
);
94 static int lpc288x_protect_check(struct flash_bank_s
*bank
);
95 static int lpc288x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
96 static uint32_t lpc288x_wait_status_busy(flash_bank_t
*bank
, int timeout
);
97 static void lpc288x_load_timer(int erase
, struct target_s
*target
);
98 static void lpc288x_set_flash_clk(struct flash_bank_s
*bank
);
99 static uint32_t lpc288x_system_ready(struct flash_bank_s
*bank
);
101 flash_driver_t lpc288x_flash
=
104 .register_commands
= lpc288x_register_commands
,
105 .flash_bank_command
= lpc288x_flash_bank_command
,
106 .erase
= lpc288x_erase
,
107 .protect
= lpc288x_protect
,
108 .write
= lpc288x_write
,
109 .probe
= lpc288x_probe
,
110 .auto_probe
= lpc288x_probe
,
111 .erase_check
= lpc288x_erase_check
,
112 .protect_check
= lpc288x_protect_check
,
116 static int lpc288x_register_commands(struct command_context_s
*cmd_ctx
)
121 static uint32_t lpc288x_wait_status_busy(flash_bank_t
*bank
, int timeout
)
124 target_t
*target
= bank
->target
;
129 target_read_u32(target
, F_STAT
, &status
);
130 } while (((status
& FS_DONE
) == 0) && timeout
);
134 LOG_DEBUG("Timedout!");
135 return ERROR_FLASH_OPERATION_FAILED
;
140 /* Read device id register and fill in driver info structure */
141 static int lpc288x_read_part_info(struct flash_bank_s
*bank
)
143 lpc288x_flash_bank_t
*lpc288x_info
= bank
->driver_priv
;
144 target_t
*target
= bank
->target
;
150 if (lpc288x_info
->cidr
== 0x0102100A)
151 return ERROR_OK
; /* already probed, multiple probes may cause memory leak, not allowed */
153 /* Read and parse chip identification register */
154 target_read_u32(target
, DBGU_CIDR
, &cidr
);
156 if (cidr
!= 0x0102100A)
158 LOG_WARNING("Cannot identify target as an LPC288X (%08" PRIx32
")",cidr
);
159 return ERROR_FLASH_OPERATION_FAILED
;
162 lpc288x_info
->cidr
= cidr
;
163 lpc288x_info
->sector_size_break
= 0x000F0000;
164 lpc288x_info
->target_name
= "LPC288x";
166 /* setup the sector info... */
168 bank
->num_sectors
= 23;
169 bank
->sectors
= malloc(sizeof(flash_sector_t
) * 23);
171 for (i
= 0; i
< 15; i
++)
173 bank
->sectors
[i
].offset
= offset
;
174 bank
->sectors
[i
].size
= 64 * 1024;
175 offset
+= bank
->sectors
[i
].size
;
176 bank
->sectors
[i
].is_erased
= -1;
177 bank
->sectors
[i
].is_protected
= 1;
179 for (i
= 15; i
< 23; i
++)
181 bank
->sectors
[i
].offset
= offset
;
182 bank
->sectors
[i
].size
= 8 * 1024;
183 offset
+= bank
->sectors
[i
].size
;
184 bank
->sectors
[i
].is_erased
= -1;
185 bank
->sectors
[i
].is_protected
= 1;
191 static int lpc288x_protect_check(struct flash_bank_s
*bank
)
196 /* flash_bank LPC288x 0 0 0 0 <target#> <cclk> */
197 static int lpc288x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
199 lpc288x_flash_bank_t
*lpc288x_info
;
203 LOG_WARNING("incomplete flash_bank LPC288x configuration");
204 return ERROR_FLASH_BANK_INVALID
;
207 lpc288x_info
= malloc(sizeof(lpc288x_flash_bank_t
));
208 bank
->driver_priv
= lpc288x_info
;
210 /* part wasn't probed for info yet */
211 lpc288x_info
->cidr
= 0;
212 lpc288x_info
->cclk
= strtoul(args
[6], NULL
, 0);
217 /* The frequency is the AHB clock frequency divided by (CLK_DIV ×3) + 1.
218 * This must be programmed such that the Flash Programming clock frequency is 66 kHz ± 20%.
220 * 12000000/66000 = 182
222 static void lpc288x_set_flash_clk(struct flash_bank_s
*bank
)
225 lpc288x_flash_bank_t
*lpc288x_info
= bank
->driver_priv
;
226 clk_time
= (lpc288x_info
->cclk
/ 66000) / 3;
227 target_write_u32(bank
->target
, F_CTRL
, FC_CS
| FC_WEN
);
228 target_write_u32(bank
->target
, F_CLK_TIME
, clk_time
);
231 /* AHB tcyc (in ns) 83 ns
232 * LOAD_TIMER_ERASE FPT_TIME = ((400,000,000 / AHB tcyc (in ns)) - 2) / 512
233 * = 9412 (9500) (AN10548 9375)
234 * LOAD_TIMER_WRITE FPT_TIME = ((1,000,000 / AHB tcyc (in ns)) - 2) / 512
235 * = 23 (75) (AN10548 72 - is this wrong?)
236 * TODO: Sort out timing calcs ;) */
237 static void lpc288x_load_timer(int erase
, struct target_s
*target
)
239 if (erase
== LOAD_TIMER_ERASE
)
241 target_write_u32(target
, F_PROG_TIME
, FPT_ENABLE
| 9500);
245 target_write_u32(target
, F_PROG_TIME
, FPT_ENABLE
| 75);
249 static uint32_t lpc288x_system_ready(struct flash_bank_s
*bank
)
251 lpc288x_flash_bank_t
*lpc288x_info
= bank
->driver_priv
;
252 if (lpc288x_info
->cidr
== 0)
254 return ERROR_FLASH_BANK_NOT_PROBED
;
257 if (bank
->target
->state
!= TARGET_HALTED
)
259 LOG_ERROR("Target not halted");
260 return ERROR_TARGET_NOT_HALTED
;
265 static int lpc288x_erase_check(struct flash_bank_s
*bank
)
267 uint32_t status
= lpc288x_system_ready(bank
); /* probed? halted? */
268 if (status
!= ERROR_OK
)
270 LOG_INFO("Processor not halted/not probed");
277 static int lpc288x_erase(struct flash_bank_s
*bank
, int first
, int last
)
281 target_t
*target
= bank
->target
;
283 status
= lpc288x_system_ready(bank
); /* probed? halted? */
284 if (status
!= ERROR_OK
)
289 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
291 LOG_INFO("Bad sector range");
292 return ERROR_FLASH_SECTOR_INVALID
;
295 /* Configure the flash controller timing */
296 lpc288x_set_flash_clk(bank
);
298 for (sector
= first
; sector
<= last
; sector
++)
300 if (lpc288x_wait_status_busy(bank
, 1000) != ERROR_OK
)
302 return ERROR_FLASH_OPERATION_FAILED
;
305 lpc288x_load_timer(LOAD_TIMER_ERASE
,target
);
307 target_write_u32(target
, bank
->sectors
[sector
].offset
, 0x00);
309 target_write_u32(target
, F_CTRL
, FC_PROG_REQ
| FC_PROTECT
| FC_CS
);
311 if (lpc288x_wait_status_busy(bank
, 1000) != ERROR_OK
)
313 return ERROR_FLASH_OPERATION_FAILED
;
318 static int lpc288x_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
320 uint8_t page_buffer
[FLASH_PAGE_SIZE
];
321 uint32_t status
, source_offset
,dest_offset
;
322 target_t
*target
= bank
->target
;
323 uint32_t bytes_remaining
= count
;
324 uint32_t first_sector
, last_sector
, sector
, page
;
327 /* probed? halted? */
328 status
= lpc288x_system_ready(bank
);
329 if (status
!= ERROR_OK
)
334 /* Initialise search indices */
335 first_sector
= last_sector
= 0xffffffff;
337 /* validate the write range... */
338 for (i
= 0; i
< bank
->num_sectors
; i
++)
340 if ((offset
>= bank
->sectors
[i
].offset
) &&
341 (offset
< (bank
->sectors
[i
].offset
+ bank
->sectors
[i
].size
)) &&
342 (first_sector
== 0xffffffff))
345 /* all writes must start on a sector boundary... */
346 if (offset
% bank
->sectors
[i
].size
)
348 LOG_INFO("offset 0x%" PRIx32
" breaks required alignment 0x%" PRIx32
"", offset
, bank
->sectors
[i
].size
);
349 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
352 if (((offset
+ count
) > bank
->sectors
[i
].offset
) &&
353 ((offset
+ count
) <= (bank
->sectors
[i
].offset
+ bank
->sectors
[i
].size
)) &&
354 (last_sector
== 0xffffffff))
361 if (first_sector
== 0xffffffff || last_sector
== 0xffffffff)
363 LOG_INFO("Range check failed %" PRIx32
" %" PRIx32
"", offset
, count
);
364 return ERROR_FLASH_DST_OUT_OF_BANK
;
367 /* Configure the flash controller timing */
368 lpc288x_set_flash_clk(bank
);
370 /* initialise the offsets */
374 for (sector
= first_sector
; sector
<= last_sector
; sector
++)
376 for (page
= 0; page
< bank
->sectors
[sector
].size
/ FLASH_PAGE_SIZE
; page
++)
378 if (bytes_remaining
== 0)
381 memset(page_buffer
, 0xFF, FLASH_PAGE_SIZE
);
383 else if (bytes_remaining
< FLASH_PAGE_SIZE
)
385 count
= bytes_remaining
;
386 memset(page_buffer
, 0xFF, FLASH_PAGE_SIZE
);
387 memcpy(page_buffer
, &buffer
[source_offset
], count
);
391 count
= FLASH_PAGE_SIZE
;
392 memcpy(page_buffer
, &buffer
[source_offset
], count
);
395 /* Wait for flash to become ready */
396 if (lpc288x_wait_status_busy(bank
, 1000) != ERROR_OK
)
398 return ERROR_FLASH_OPERATION_FAILED
;
401 /* fill flash data latches with 1's */
402 target_write_u32(target
, F_CTRL
, FC_CS
| FC_SET_DATA
| FC_WEN
| FC_FUNC
);
404 target_write_u32(target
, F_CTRL
, FC_CS
| FC_WEN
| FC_FUNC
);
405 /*would be better to use the clean target_write_buffer() interface but
406 * it seems not to be a LOT slower....
407 * bulk_write_memory() is no quicker :(*/
409 if (target_write_memory(target
, offset
+ dest_offset
, 4, 128, page_buffer
) != ERROR_OK
)
411 LOG_ERROR("Write failed s %" PRIx32
" p %" PRIx32
"", sector
, page
);
412 return ERROR_FLASH_OPERATION_FAILED
;
415 if (target_write_buffer(target
, offset
+ dest_offset
, FLASH_PAGE_SIZE
, page_buffer
) != ERROR_OK
)
417 LOG_INFO("Write to flash buffer failed");
418 return ERROR_FLASH_OPERATION_FAILED
;
421 dest_offset
+= FLASH_PAGE_SIZE
;
422 source_offset
+= count
;
423 bytes_remaining
-= count
;
425 lpc288x_load_timer(LOAD_TIMER_WRITE
, target
);
427 target_write_u32(target
, F_CTRL
, FC_PROG_REQ
| FC_PROTECT
| FC_FUNC
| FC_CS
);
434 static int lpc288x_probe(struct flash_bank_s
*bank
)
436 /* we only deal with LPC2888 so flash config is fixed */
437 lpc288x_flash_bank_t
*lpc288x_info
= bank
->driver_priv
;
440 if (lpc288x_info
->cidr
!= 0)
442 return ERROR_OK
; /* already probed */
445 if (bank
->target
->state
!= TARGET_HALTED
)
447 LOG_ERROR("Target not halted");
448 return ERROR_TARGET_NOT_HALTED
;
451 retval
= lpc288x_read_part_info(bank
);
452 if (retval
!= ERROR_OK
)
457 static int lpc288x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
459 snprintf(buf
, buf_size
, "lpc288x flash driver");
463 static int lpc288x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
465 int lockregion
, status
;
467 target_t
*target
= bank
->target
;
469 /* probed? halted? */
470 status
= lpc288x_system_ready(bank
);
471 if (status
!= ERROR_OK
)
476 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
478 return ERROR_FLASH_SECTOR_INVALID
;
481 /* Configure the flash controller timing */
482 lpc288x_set_flash_clk(bank
);
484 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
488 /* write an odd value to base addy to protect... */
493 /* write an even value to base addy to unprotect... */
496 target_write_u32(target
, bank
->sectors
[lockregion
].offset
, value
);
497 target_write_u32(target
, F_CTRL
, FC_LOAD_REQ
| FC_PROTECT
| FC_WEN
| FC_FUNC
| FC_CS
);