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 <helper/binarybuffer.h>
37 #define LOAD_TIMER_ERASE 0
38 #define LOAD_TIMER_WRITE 1
40 #define FLASH_PAGE_SIZE 512
42 /* LPC288X control registers */
43 #define DBGU_CIDR 0x8000507C
44 /* LPC288X flash registers */
45 #define F_CTRL 0x80102000 /* Flash control register R/W 0x5 */
46 #define F_STAT 0x80102004 /* Flash status register RO 0x45 */
47 #define F_PROG_TIME 0x80102008 /* Flash program time register R/W 0 */
48 #define F_WAIT 0x80102010 /* Flash read wait state register R/W 0xC004 */
49 #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
59 #define FLASH_INIT 0x80005034 /* Monitors Flash readiness, such as recovery from
60 *Power Down mode. R/W -*/
64 #define FC_FUNC 0x0002
66 #define FC_RD_LATCH 0x0020
67 #define FC_PROTECT 0x0080
68 #define FC_SET_DATA 0x0400
69 #define FC_RSSL 0x0800
70 #define FC_PROG_REQ 0x1000
71 #define FC_CLR_BUF 0x4000
72 #define FC_LOAD_REQ 0x8000
74 #define FS_DONE 0x0001
75 #define FS_PROGGNT 0x0002
79 #define FPT_TIME_MASK 0x7FFF
81 #define FPT_ENABLE 0x8000
83 #define FW_WAIT_STATES_MASK 0x00FF
84 #define FW_SET_MASK 0xC000
87 #define FCT_CLK_DIV_MASK 0x0FFF
89 struct lpc288x_flash_bank
{
90 uint32_t working_area
;
91 uint32_t working_area_size
;
93 /* chip id register */
95 const char *target_name
;
98 uint32_t sector_size_break
;
101 static uint32_t lpc288x_wait_status_busy(struct flash_bank
*bank
, int timeout
);
102 static void lpc288x_load_timer(int erase
, struct target
*target
);
103 static void lpc288x_set_flash_clk(struct flash_bank
*bank
);
104 static uint32_t lpc288x_system_ready(struct flash_bank
*bank
);
106 static uint32_t lpc288x_wait_status_busy(struct flash_bank
*bank
, int timeout
)
109 struct target
*target
= bank
->target
;
113 target_read_u32(target
, F_STAT
, &status
);
114 } while (((status
& FS_DONE
) == 0) && timeout
);
117 LOG_DEBUG("Timedout!");
118 return ERROR_FLASH_OPERATION_FAILED
;
123 /* Read device id register and fill in driver info structure */
124 static int lpc288x_read_part_info(struct flash_bank
*bank
)
126 struct lpc288x_flash_bank
*lpc288x_info
= bank
->driver_priv
;
127 struct target
*target
= bank
->target
;
133 if (lpc288x_info
->cidr
== 0x0102100A)
134 return ERROR_OK
;/* already probed, multiple probes may cause memory leak, not
137 /* Read and parse chip identification register */
138 target_read_u32(target
, DBGU_CIDR
, &cidr
);
140 if (cidr
!= 0x0102100A) {
141 LOG_WARNING("Cannot identify target as an LPC288X (%08" PRIx32
")", cidr
);
142 return ERROR_FLASH_OPERATION_FAILED
;
145 lpc288x_info
->cidr
= cidr
;
146 lpc288x_info
->sector_size_break
= 0x000F0000;
147 lpc288x_info
->target_name
= "LPC288x";
149 /* setup the sector info... */
151 bank
->num_sectors
= 23;
152 bank
->sectors
= malloc(sizeof(struct flash_sector
) * 23);
154 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
++) {
162 bank
->sectors
[i
].offset
= offset
;
163 bank
->sectors
[i
].size
= 8 * 1024;
164 offset
+= bank
->sectors
[i
].size
;
165 bank
->sectors
[i
].is_erased
= -1;
166 bank
->sectors
[i
].is_protected
= 1;
172 static int lpc288x_protect_check(struct flash_bank
*bank
)
177 /* flash_bank LPC288x 0 0 0 0 <target#> <cclk> */
178 FLASH_BANK_COMMAND_HANDLER(lpc288x_flash_bank_command
)
180 struct lpc288x_flash_bank
*lpc288x_info
;
183 return ERROR_COMMAND_SYNTAX_ERROR
;
185 lpc288x_info
= malloc(sizeof(struct lpc288x_flash_bank
));
186 bank
->driver_priv
= lpc288x_info
;
188 /* part wasn't probed for info yet */
189 lpc288x_info
->cidr
= 0;
190 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[6], lpc288x_info
->cclk
);
195 /* The frequency is the AHB clock frequency divided by (CLK_DIV ×3) + 1.
196 * This must be programmed such that the Flash Programming clock frequency is 66 kHz ± 20%.
198 * 12000000/66000 = 182
200 static void lpc288x_set_flash_clk(struct flash_bank
*bank
)
203 struct lpc288x_flash_bank
*lpc288x_info
= bank
->driver_priv
;
204 clk_time
= (lpc288x_info
->cclk
/ 66000) / 3;
205 target_write_u32(bank
->target
, F_CTRL
, FC_CS
| FC_WEN
);
206 target_write_u32(bank
->target
, F_CLK_TIME
, clk_time
);
209 /* AHB tcyc (in ns) 83 ns
210 * LOAD_TIMER_ERASE FPT_TIME = ((400,000,000 / AHB tcyc (in ns)) - 2) / 512
211 * = 9412 (9500) (AN10548 9375)
212 * LOAD_TIMER_WRITE FPT_TIME = ((1,000,000 / AHB tcyc (in ns)) - 2) / 512
213 * = 23 (75) (AN10548 72 - is this wrong?)
214 * TODO: Sort out timing calcs ;) */
215 static void lpc288x_load_timer(int erase
, struct target
*target
)
217 if (erase
== LOAD_TIMER_ERASE
)
218 target_write_u32(target
, F_PROG_TIME
, FPT_ENABLE
| 9500);
220 target_write_u32(target
, F_PROG_TIME
, FPT_ENABLE
| 75);
223 static uint32_t lpc288x_system_ready(struct flash_bank
*bank
)
225 struct lpc288x_flash_bank
*lpc288x_info
= bank
->driver_priv
;
226 if (lpc288x_info
->cidr
== 0)
227 return ERROR_FLASH_BANK_NOT_PROBED
;
229 if (bank
->target
->state
!= TARGET_HALTED
) {
230 LOG_ERROR("Target not halted");
231 return ERROR_TARGET_NOT_HALTED
;
236 static int lpc288x_erase_check(struct flash_bank
*bank
)
238 uint32_t status
= lpc288x_system_ready(bank
); /* probed? halted? */
239 if (status
!= ERROR_OK
) {
240 LOG_INFO("Processor not halted/not probed");
247 static int lpc288x_erase(struct flash_bank
*bank
, int first
, int last
)
251 struct target
*target
= bank
->target
;
253 status
= lpc288x_system_ready(bank
); /* probed? halted? */
254 if (status
!= ERROR_OK
)
257 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
)) {
258 LOG_INFO("Bad sector range");
259 return ERROR_FLASH_SECTOR_INVALID
;
262 /* Configure the flash controller timing */
263 lpc288x_set_flash_clk(bank
);
265 for (sector
= first
; sector
<= last
; sector
++) {
266 if (lpc288x_wait_status_busy(bank
, 1000) != ERROR_OK
)
267 return ERROR_FLASH_OPERATION_FAILED
;
269 lpc288x_load_timer(LOAD_TIMER_ERASE
, target
);
271 target_write_u32(target
, bank
->sectors
[sector
].offset
, 0x00);
273 target_write_u32(target
, F_CTRL
, FC_PROG_REQ
| FC_PROTECT
| FC_CS
);
275 if (lpc288x_wait_status_busy(bank
, 1000) != ERROR_OK
)
276 return ERROR_FLASH_OPERATION_FAILED
;
280 static int lpc288x_write(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
282 uint8_t page_buffer
[FLASH_PAGE_SIZE
];
283 uint32_t status
, source_offset
, dest_offset
;
284 struct target
*target
= bank
->target
;
285 uint32_t bytes_remaining
= count
;
286 uint32_t first_sector
, last_sector
, sector
, page
;
289 /* probed? halted? */
290 status
= lpc288x_system_ready(bank
);
291 if (status
!= ERROR_OK
)
294 /* Initialise search indices */
295 first_sector
= last_sector
= 0xffffffff;
297 /* validate the write range... */
298 for (i
= 0; i
< bank
->num_sectors
; i
++) {
299 if ((offset
>= bank
->sectors
[i
].offset
) &&
300 (offset
< (bank
->sectors
[i
].offset
+ bank
->sectors
[i
].size
)) &&
301 (first_sector
== 0xffffffff)) {
303 /* all writes must start on a sector boundary... */
304 if (offset
% bank
->sectors
[i
].size
) {
306 "offset 0x%" PRIx32
" breaks required alignment 0x%" PRIx32
"",
308 bank
->sectors
[i
].size
);
309 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
312 if (((offset
+ count
) > bank
->sectors
[i
].offset
) &&
313 ((offset
+ count
) <= (bank
->sectors
[i
].offset
+ bank
->sectors
[i
].size
)) &&
314 (last_sector
== 0xffffffff))
319 if (first_sector
== 0xffffffff || last_sector
== 0xffffffff) {
320 LOG_INFO("Range check failed %" PRIx32
" %" PRIx32
"", offset
, count
);
321 return ERROR_FLASH_DST_OUT_OF_BANK
;
324 /* Configure the flash controller timing */
325 lpc288x_set_flash_clk(bank
);
327 /* initialise the offsets */
331 for (sector
= first_sector
; sector
<= last_sector
; sector
++) {
332 for (page
= 0; page
< bank
->sectors
[sector
].size
/ FLASH_PAGE_SIZE
; page
++) {
333 if (bytes_remaining
== 0) {
335 memset(page_buffer
, 0xFF, FLASH_PAGE_SIZE
);
336 } else if (bytes_remaining
< FLASH_PAGE_SIZE
) {
337 count
= bytes_remaining
;
338 memset(page_buffer
, 0xFF, FLASH_PAGE_SIZE
);
339 memcpy(page_buffer
, &buffer
[source_offset
], count
);
341 count
= FLASH_PAGE_SIZE
;
342 memcpy(page_buffer
, &buffer
[source_offset
], count
);
345 /* Wait for flash to become ready */
346 if (lpc288x_wait_status_busy(bank
, 1000) != ERROR_OK
)
347 return ERROR_FLASH_OPERATION_FAILED
;
349 /* fill flash data latches with 1's */
350 target_write_u32(target
, F_CTRL
, FC_CS
| FC_SET_DATA
| FC_WEN
| FC_FUNC
);
352 target_write_u32(target
, F_CTRL
, FC_CS
| FC_WEN
| FC_FUNC
);
353 /*would be better to use the clean target_write_buffer() interface but
354 * it seems not to be a LOT slower....
355 * bulk_write_memory() is no quicker :(*/
357 if (target_write_memory(target
, offset
+ dest_offset
, 4, 128,
358 page_buffer
) != ERROR_OK
) {
359 LOG_ERROR("Write failed s %" PRIx32
" p %" PRIx32
"", sector
, page
);
360 return ERROR_FLASH_OPERATION_FAILED
;
363 if (target_write_buffer(target
, offset
+ dest_offset
, FLASH_PAGE_SIZE
,
364 page_buffer
) != ERROR_OK
) {
365 LOG_INFO("Write to flash buffer failed");
366 return ERROR_FLASH_OPERATION_FAILED
;
369 dest_offset
+= FLASH_PAGE_SIZE
;
370 source_offset
+= count
;
371 bytes_remaining
-= count
;
373 lpc288x_load_timer(LOAD_TIMER_WRITE
, target
);
375 target_write_u32(target
, F_CTRL
, FC_PROG_REQ
| FC_PROTECT
| FC_FUNC
|
383 static int lpc288x_probe(struct flash_bank
*bank
)
385 /* we only deal with LPC2888 so flash config is fixed */
386 struct lpc288x_flash_bank
*lpc288x_info
= bank
->driver_priv
;
389 if (lpc288x_info
->cidr
!= 0)
390 return ERROR_OK
;/* already probed */
392 if (bank
->target
->state
!= TARGET_HALTED
) {
393 LOG_ERROR("Target not halted");
394 return ERROR_TARGET_NOT_HALTED
;
397 retval
= lpc288x_read_part_info(bank
);
398 if (retval
!= ERROR_OK
)
403 static int lpc288x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
405 snprintf(buf
, buf_size
, "lpc288x flash driver");
409 static int lpc288x_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
411 int lockregion
, status
;
413 struct target
*target
= bank
->target
;
415 /* probed? halted? */
416 status
= lpc288x_system_ready(bank
);
417 if (status
!= ERROR_OK
)
420 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
421 return ERROR_FLASH_SECTOR_INVALID
;
423 /* Configure the flash controller timing */
424 lpc288x_set_flash_clk(bank
);
426 for (lockregion
= first
; lockregion
<= last
; lockregion
++) {
428 /* write an odd value to base addy to protect... */
431 /* write an even value to base addy to unprotect... */
434 target_write_u32(target
, bank
->sectors
[lockregion
].offset
, value
);
435 target_write_u32(target
, F_CTRL
, FC_LOAD_REQ
| FC_PROTECT
| FC_WEN
| FC_FUNC
|
442 struct flash_driver lpc288x_flash
= {
444 .flash_bank_command
= lpc288x_flash_bank_command
,
445 .erase
= lpc288x_erase
,
446 .protect
= lpc288x_protect
,
447 .write
= lpc288x_write
,
448 .read
= default_flash_read
,
449 .probe
= lpc288x_probe
,
450 .auto_probe
= lpc288x_probe
,
451 .erase_check
= lpc288x_erase_check
,
452 .protect_check
= lpc288x_protect_check
,
453 .info
= lpc288x_info
,