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 ***************************************************************************/
36 #include <helper/binarybuffer.h>
39 #define LOAD_TIMER_ERASE 0
40 #define LOAD_TIMER_WRITE 1
42 #define FLASH_PAGE_SIZE 512
44 /* LPC288X control registers */
45 #define DBGU_CIDR 0x8000507C
46 /* LPC288X flash registers */
47 #define F_CTRL 0x80102000 /* Flash control register R/W 0x5 */
48 #define F_STAT 0x80102004 /* Flash status register RO 0x45 */
49 #define F_PROG_TIME 0x80102008 /* Flash program time register R/W 0 */
50 #define F_WAIT 0x80102010 /* Flash read wait state register R/W 0xC004 */
51 #define F_CLK_TIME 0x8010201C /* Flash clock divider for 66 kHz generation R/W 0 */
52 #define F_INTEN_CLR 0x80102FD8 /* Clear interrupt enable bits WO - */
53 #define F_INTEN_SET 0x80102FDC /* Set interrupt enable bits WO - */
54 #define F_INT_STAT 0x80102FE0 /* Interrupt status bits RO 0 */
55 #define F_INTEN 0x80102FE4 /* Interrupt enable bits RO 0 */
56 #define F_INT_CLR 0x80102FE8 /* Clear interrupt status bits WO */
57 #define F_INT_SET 0x80102FEC /* Set interrupt status bits WO - */
58 #define FLASH_PD 0x80005030 /* Allows turning off the Flash memory for power savings. R/W 1*/
59 #define FLASH_INIT 0x80005034 /* Monitors Flash readiness, such as recovery from Power Down mode. R/W -*/
63 #define FC_FUNC 0x0002
65 #define FC_RD_LATCH 0x0020
66 #define FC_PROTECT 0x0080
67 #define FC_SET_DATA 0x0400
68 #define FC_RSSL 0x0800
69 #define FC_PROG_REQ 0x1000
70 #define FC_CLR_BUF 0x4000
71 #define FC_LOAD_REQ 0x8000
73 #define FS_DONE 0x0001
74 #define FS_PROGGNT 0x0002
78 #define FPT_TIME_MASK 0x7FFF
80 #define FPT_ENABLE 0x8000
82 #define FW_WAIT_STATES_MASK 0x00FF
83 #define FW_SET_MASK 0xC000
86 #define FCT_CLK_DIV_MASK 0x0FFF
88 static uint32_t lpc288x_wait_status_busy(struct flash_bank
*bank
, int timeout
);
89 static void lpc288x_load_timer(int erase
, struct target
*target
);
90 static void lpc288x_set_flash_clk(struct flash_bank
*bank
);
91 static uint32_t lpc288x_system_ready(struct flash_bank
*bank
);
93 static uint32_t lpc288x_wait_status_busy(struct flash_bank
*bank
, int timeout
)
96 struct target
*target
= bank
->target
;
101 target_read_u32(target
, F_STAT
, &status
);
102 } while (((status
& FS_DONE
) == 0) && timeout
);
106 LOG_DEBUG("Timedout!");
107 return ERROR_FLASH_OPERATION_FAILED
;
112 /* Read device id register and fill in driver info structure */
113 static int lpc288x_read_part_info(struct flash_bank
*bank
)
115 struct lpc288x_flash_bank
*lpc288x_info
= bank
->driver_priv
;
116 struct target
*target
= bank
->target
;
122 if (lpc288x_info
->cidr
== 0x0102100A)
123 return ERROR_OK
; /* already probed, multiple probes may cause memory leak, not allowed */
125 /* Read and parse chip identification register */
126 target_read_u32(target
, DBGU_CIDR
, &cidr
);
128 if (cidr
!= 0x0102100A)
130 LOG_WARNING("Cannot identify target as an LPC288X (%08" PRIx32
")",cidr
);
131 return ERROR_FLASH_OPERATION_FAILED
;
134 lpc288x_info
->cidr
= cidr
;
135 lpc288x_info
->sector_size_break
= 0x000F0000;
136 lpc288x_info
->target_name
= "LPC288x";
138 /* setup the sector info... */
140 bank
->num_sectors
= 23;
141 bank
->sectors
= malloc(sizeof(struct flash_sector
) * 23);
143 for (i
= 0; i
< 15; i
++)
145 bank
->sectors
[i
].offset
= offset
;
146 bank
->sectors
[i
].size
= 64 * 1024;
147 offset
+= bank
->sectors
[i
].size
;
148 bank
->sectors
[i
].is_erased
= -1;
149 bank
->sectors
[i
].is_protected
= 1;
151 for (i
= 15; i
< 23; i
++)
153 bank
->sectors
[i
].offset
= offset
;
154 bank
->sectors
[i
].size
= 8 * 1024;
155 offset
+= bank
->sectors
[i
].size
;
156 bank
->sectors
[i
].is_erased
= -1;
157 bank
->sectors
[i
].is_protected
= 1;
163 static int lpc288x_protect_check(struct flash_bank
*bank
)
168 /* flash_bank LPC288x 0 0 0 0 <target#> <cclk> */
169 FLASH_BANK_COMMAND_HANDLER(lpc288x_flash_bank_command
)
171 struct lpc288x_flash_bank
*lpc288x_info
;
175 LOG_WARNING("incomplete flash_bank LPC288x configuration");
176 return ERROR_FLASH_BANK_INVALID
;
179 lpc288x_info
= malloc(sizeof(struct lpc288x_flash_bank
));
180 bank
->driver_priv
= lpc288x_info
;
182 /* part wasn't probed for info yet */
183 lpc288x_info
->cidr
= 0;
184 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[6], lpc288x_info
->cclk
);
189 /* The frequency is the AHB clock frequency divided by (CLK_DIV ×3) + 1.
190 * This must be programmed such that the Flash Programming clock frequency is 66 kHz ± 20%.
192 * 12000000/66000 = 182
194 static void lpc288x_set_flash_clk(struct flash_bank
*bank
)
197 struct lpc288x_flash_bank
*lpc288x_info
= bank
->driver_priv
;
198 clk_time
= (lpc288x_info
->cclk
/ 66000) / 3;
199 target_write_u32(bank
->target
, F_CTRL
, FC_CS
| FC_WEN
);
200 target_write_u32(bank
->target
, F_CLK_TIME
, clk_time
);
203 /* AHB tcyc (in ns) 83 ns
204 * LOAD_TIMER_ERASE FPT_TIME = ((400,000,000 / AHB tcyc (in ns)) - 2) / 512
205 * = 9412 (9500) (AN10548 9375)
206 * LOAD_TIMER_WRITE FPT_TIME = ((1,000,000 / AHB tcyc (in ns)) - 2) / 512
207 * = 23 (75) (AN10548 72 - is this wrong?)
208 * TODO: Sort out timing calcs ;) */
209 static void lpc288x_load_timer(int erase
, struct target
*target
)
211 if (erase
== LOAD_TIMER_ERASE
)
213 target_write_u32(target
, F_PROG_TIME
, FPT_ENABLE
| 9500);
217 target_write_u32(target
, F_PROG_TIME
, FPT_ENABLE
| 75);
221 static uint32_t lpc288x_system_ready(struct flash_bank
*bank
)
223 struct lpc288x_flash_bank
*lpc288x_info
= bank
->driver_priv
;
224 if (lpc288x_info
->cidr
== 0)
226 return ERROR_FLASH_BANK_NOT_PROBED
;
229 if (bank
->target
->state
!= TARGET_HALTED
)
231 LOG_ERROR("Target not halted");
232 return ERROR_TARGET_NOT_HALTED
;
237 static int lpc288x_erase_check(struct flash_bank
*bank
)
239 uint32_t status
= lpc288x_system_ready(bank
); /* probed? halted? */
240 if (status
!= ERROR_OK
)
242 LOG_INFO("Processor not halted/not probed");
249 static int lpc288x_erase(struct flash_bank
*bank
, int first
, int last
)
253 struct target
*target
= bank
->target
;
255 status
= lpc288x_system_ready(bank
); /* probed? halted? */
256 if (status
!= ERROR_OK
)
261 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
263 LOG_INFO("Bad sector range");
264 return ERROR_FLASH_SECTOR_INVALID
;
267 /* Configure the flash controller timing */
268 lpc288x_set_flash_clk(bank
);
270 for (sector
= first
; sector
<= last
; sector
++)
272 if (lpc288x_wait_status_busy(bank
, 1000) != ERROR_OK
)
274 return ERROR_FLASH_OPERATION_FAILED
;
277 lpc288x_load_timer(LOAD_TIMER_ERASE
,target
);
279 target_write_u32(target
, bank
->sectors
[sector
].offset
, 0x00);
281 target_write_u32(target
, F_CTRL
, FC_PROG_REQ
| FC_PROTECT
| FC_CS
);
283 if (lpc288x_wait_status_busy(bank
, 1000) != ERROR_OK
)
285 return ERROR_FLASH_OPERATION_FAILED
;
290 static int lpc288x_write(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
292 uint8_t page_buffer
[FLASH_PAGE_SIZE
];
293 uint32_t status
, source_offset
,dest_offset
;
294 struct target
*target
= bank
->target
;
295 uint32_t bytes_remaining
= count
;
296 uint32_t first_sector
, last_sector
, sector
, page
;
299 /* probed? halted? */
300 status
= lpc288x_system_ready(bank
);
301 if (status
!= ERROR_OK
)
306 /* Initialise search indices */
307 first_sector
= last_sector
= 0xffffffff;
309 /* validate the write range... */
310 for (i
= 0; i
< bank
->num_sectors
; i
++)
312 if ((offset
>= bank
->sectors
[i
].offset
) &&
313 (offset
< (bank
->sectors
[i
].offset
+ bank
->sectors
[i
].size
)) &&
314 (first_sector
== 0xffffffff))
317 /* all writes must start on a sector boundary... */
318 if (offset
% bank
->sectors
[i
].size
)
320 LOG_INFO("offset 0x%" PRIx32
" breaks required alignment 0x%" PRIx32
"", offset
, bank
->sectors
[i
].size
);
321 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
324 if (((offset
+ count
) > bank
->sectors
[i
].offset
) &&
325 ((offset
+ count
) <= (bank
->sectors
[i
].offset
+ bank
->sectors
[i
].size
)) &&
326 (last_sector
== 0xffffffff))
333 if (first_sector
== 0xffffffff || last_sector
== 0xffffffff)
335 LOG_INFO("Range check failed %" PRIx32
" %" PRIx32
"", offset
, count
);
336 return ERROR_FLASH_DST_OUT_OF_BANK
;
339 /* Configure the flash controller timing */
340 lpc288x_set_flash_clk(bank
);
342 /* initialise the offsets */
346 for (sector
= first_sector
; sector
<= last_sector
; sector
++)
348 for (page
= 0; page
< bank
->sectors
[sector
].size
/ FLASH_PAGE_SIZE
; page
++)
350 if (bytes_remaining
== 0)
353 memset(page_buffer
, 0xFF, FLASH_PAGE_SIZE
);
355 else if (bytes_remaining
< FLASH_PAGE_SIZE
)
357 count
= bytes_remaining
;
358 memset(page_buffer
, 0xFF, FLASH_PAGE_SIZE
);
359 memcpy(page_buffer
, &buffer
[source_offset
], count
);
363 count
= FLASH_PAGE_SIZE
;
364 memcpy(page_buffer
, &buffer
[source_offset
], count
);
367 /* Wait for flash to become ready */
368 if (lpc288x_wait_status_busy(bank
, 1000) != ERROR_OK
)
370 return ERROR_FLASH_OPERATION_FAILED
;
373 /* fill flash data latches with 1's */
374 target_write_u32(target
, F_CTRL
, FC_CS
| FC_SET_DATA
| FC_WEN
| FC_FUNC
);
376 target_write_u32(target
, F_CTRL
, FC_CS
| FC_WEN
| FC_FUNC
);
377 /*would be better to use the clean target_write_buffer() interface but
378 * it seems not to be a LOT slower....
379 * bulk_write_memory() is no quicker :(*/
381 if (target_write_memory(target
, offset
+ dest_offset
, 4, 128, page_buffer
) != ERROR_OK
)
383 LOG_ERROR("Write failed s %" PRIx32
" p %" PRIx32
"", sector
, page
);
384 return ERROR_FLASH_OPERATION_FAILED
;
387 if (target_write_buffer(target
, offset
+ dest_offset
, FLASH_PAGE_SIZE
, page_buffer
) != ERROR_OK
)
389 LOG_INFO("Write to flash buffer failed");
390 return ERROR_FLASH_OPERATION_FAILED
;
393 dest_offset
+= FLASH_PAGE_SIZE
;
394 source_offset
+= count
;
395 bytes_remaining
-= count
;
397 lpc288x_load_timer(LOAD_TIMER_WRITE
, target
);
399 target_write_u32(target
, F_CTRL
, FC_PROG_REQ
| FC_PROTECT
| FC_FUNC
| FC_CS
);
406 static int lpc288x_probe(struct flash_bank
*bank
)
408 /* we only deal with LPC2888 so flash config is fixed */
409 struct lpc288x_flash_bank
*lpc288x_info
= bank
->driver_priv
;
412 if (lpc288x_info
->cidr
!= 0)
414 return ERROR_OK
; /* already probed */
417 if (bank
->target
->state
!= TARGET_HALTED
)
419 LOG_ERROR("Target not halted");
420 return ERROR_TARGET_NOT_HALTED
;
423 retval
= lpc288x_read_part_info(bank
);
424 if (retval
!= ERROR_OK
)
429 static int lpc288x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
431 snprintf(buf
, buf_size
, "lpc288x flash driver");
435 static int lpc288x_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
437 int lockregion
, status
;
439 struct target
*target
= bank
->target
;
441 /* probed? halted? */
442 status
= lpc288x_system_ready(bank
);
443 if (status
!= ERROR_OK
)
448 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
450 return ERROR_FLASH_SECTOR_INVALID
;
453 /* Configure the flash controller timing */
454 lpc288x_set_flash_clk(bank
);
456 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
460 /* write an odd value to base addy to protect... */
465 /* write an even value to base addy to unprotect... */
468 target_write_u32(target
, bank
->sectors
[lockregion
].offset
, value
);
469 target_write_u32(target
, F_CTRL
, FC_LOAD_REQ
| FC_PROTECT
| FC_WEN
| FC_FUNC
| FC_CS
);
475 struct flash_driver lpc288x_flash
= {
477 .flash_bank_command
= lpc288x_flash_bank_command
,
478 .erase
= lpc288x_erase
,
479 .protect
= lpc288x_protect
,
480 .write
= lpc288x_write
,
481 .read
= default_flash_read
,
482 .probe
= lpc288x_probe
,
483 .auto_probe
= lpc288x_probe
,
484 .erase_check
= lpc288x_erase_check
,
485 .protect_check
= lpc288x_protect_check
,
486 .info
= lpc288x_info
,