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, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
19 /***************************************************************************
20 * There are some things to notice
22 * You need to unprotect flash sectors each time you connect the OpenOCD
23 * Dumping 1MB takes about 60 Seconds
24 * Full erase (sectors 0-22 inclusive) takes 2-4 seconds
25 * Writing 1MB takes 88 seconds
27 ***************************************************************************/
33 #include <helper/binarybuffer.h>
35 #define LOAD_TIMER_ERASE 0
36 #define LOAD_TIMER_WRITE 1
38 #define FLASH_PAGE_SIZE 512
40 /* LPC288X control registers */
41 #define DBGU_CIDR 0x8000507C
42 /* LPC288X flash registers */
43 #define F_CTRL 0x80102000 /* Flash control register R/W 0x5 */
44 #define F_STAT 0x80102004 /* Flash status register RO 0x45 */
45 #define F_PROG_TIME 0x80102008 /* Flash program time register R/W 0 */
46 #define F_WAIT 0x80102010 /* Flash read wait state register R/W 0xC004 */
47 #define F_CLK_TIME 0x8010201C /* Flash clock divider for 66 kHz generation R/W 0
49 #define F_INTEN_CLR 0x80102FD8 /* Clear interrupt enable bits WO - */
50 #define F_INTEN_SET 0x80102FDC /* Set interrupt enable bits WO - */
51 #define F_INT_STAT 0x80102FE0 /* Interrupt status bits RO 0 */
52 #define F_INTEN 0x80102FE4 /* Interrupt enable bits RO 0 */
53 #define F_INT_CLR 0x80102FE8 /* Clear interrupt status bits WO */
54 #define F_INT_SET 0x80102FEC /* Set interrupt status bits WO - */
55 #define FLASH_PD 0x80005030 /* Allows turning off the Flash memory for power
57 #define FLASH_INIT 0x80005034 /* Monitors Flash readiness, such as recovery from
58 *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 struct lpc288x_flash_bank
{
88 uint32_t working_area
;
89 uint32_t working_area_size
;
91 /* chip id register */
93 const char *target_name
;
96 uint32_t sector_size_break
;
99 static uint32_t lpc288x_wait_status_busy(struct flash_bank
*bank
, int timeout
);
100 static void lpc288x_load_timer(int erase
, struct target
*target
);
101 static void lpc288x_set_flash_clk(struct flash_bank
*bank
);
102 static uint32_t lpc288x_system_ready(struct flash_bank
*bank
);
104 static uint32_t lpc288x_wait_status_busy(struct flash_bank
*bank
, int timeout
)
107 struct target
*target
= bank
->target
;
111 target_read_u32(target
, F_STAT
, &status
);
112 } while (((status
& FS_DONE
) == 0) && timeout
);
115 LOG_DEBUG("Timedout!");
116 return ERROR_FLASH_OPERATION_FAILED
;
121 /* Read device id register and fill in driver info structure */
122 static int lpc288x_read_part_info(struct flash_bank
*bank
)
124 struct lpc288x_flash_bank
*lpc288x_info
= bank
->driver_priv
;
125 struct target
*target
= bank
->target
;
131 if (lpc288x_info
->cidr
== 0x0102100A)
132 return ERROR_OK
;/* already probed, multiple probes may cause memory leak, not
135 /* Read and parse chip identification register */
136 target_read_u32(target
, DBGU_CIDR
, &cidr
);
138 if (cidr
!= 0x0102100A) {
139 LOG_WARNING("Cannot identify target as an LPC288X (%08" PRIx32
")", cidr
);
140 return ERROR_FLASH_OPERATION_FAILED
;
143 lpc288x_info
->cidr
= cidr
;
144 lpc288x_info
->sector_size_break
= 0x000F0000;
145 lpc288x_info
->target_name
= "LPC288x";
147 /* setup the sector info... */
149 bank
->num_sectors
= 23;
150 bank
->sectors
= malloc(sizeof(struct flash_sector
) * 23);
152 for (i
= 0; i
< 15; i
++) {
153 bank
->sectors
[i
].offset
= offset
;
154 bank
->sectors
[i
].size
= 64 * 1024;
155 offset
+= bank
->sectors
[i
].size
;
156 bank
->sectors
[i
].is_erased
= -1;
157 bank
->sectors
[i
].is_protected
= 1;
159 for (i
= 15; i
< 23; i
++) {
160 bank
->sectors
[i
].offset
= offset
;
161 bank
->sectors
[i
].size
= 8 * 1024;
162 offset
+= bank
->sectors
[i
].size
;
163 bank
->sectors
[i
].is_erased
= -1;
164 bank
->sectors
[i
].is_protected
= 1;
170 static int lpc288x_protect_check(struct flash_bank
*bank
)
175 /* flash_bank LPC288x 0 0 0 0 <target#> <cclk> */
176 FLASH_BANK_COMMAND_HANDLER(lpc288x_flash_bank_command
)
178 struct lpc288x_flash_bank
*lpc288x_info
;
181 return ERROR_COMMAND_SYNTAX_ERROR
;
183 lpc288x_info
= malloc(sizeof(struct lpc288x_flash_bank
));
184 bank
->driver_priv
= lpc288x_info
;
186 /* part wasn't probed for info yet */
187 lpc288x_info
->cidr
= 0;
188 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[6], lpc288x_info
->cclk
);
193 /* The frequency is the AHB clock frequency divided by (CLK_DIV ×3) + 1.
194 * This must be programmed such that the Flash Programming clock frequency is 66 kHz ± 20%.
196 * 12000000/66000 = 182
198 static void lpc288x_set_flash_clk(struct flash_bank
*bank
)
201 struct lpc288x_flash_bank
*lpc288x_info
= bank
->driver_priv
;
202 clk_time
= (lpc288x_info
->cclk
/ 66000) / 3;
203 target_write_u32(bank
->target
, F_CTRL
, FC_CS
| FC_WEN
);
204 target_write_u32(bank
->target
, F_CLK_TIME
, clk_time
);
207 /* AHB tcyc (in ns) 83 ns
208 * LOAD_TIMER_ERASE FPT_TIME = ((400,000,000 / AHB tcyc (in ns)) - 2) / 512
209 * = 9412 (9500) (AN10548 9375)
210 * LOAD_TIMER_WRITE FPT_TIME = ((1,000,000 / AHB tcyc (in ns)) - 2) / 512
211 * = 23 (75) (AN10548 72 - is this wrong?)
212 * TODO: Sort out timing calcs ;) */
213 static void lpc288x_load_timer(int erase
, struct target
*target
)
215 if (erase
== LOAD_TIMER_ERASE
)
216 target_write_u32(target
, F_PROG_TIME
, FPT_ENABLE
| 9500);
218 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)
225 return ERROR_FLASH_BANK_NOT_PROBED
;
227 if (bank
->target
->state
!= TARGET_HALTED
) {
228 LOG_ERROR("Target not halted");
229 return ERROR_TARGET_NOT_HALTED
;
234 static int lpc288x_erase_check(struct flash_bank
*bank
)
236 uint32_t status
= lpc288x_system_ready(bank
); /* probed? halted? */
237 if (status
!= ERROR_OK
) {
238 LOG_INFO("Processor not halted/not probed");
245 static int lpc288x_erase(struct flash_bank
*bank
, int first
, int last
)
249 struct target
*target
= bank
->target
;
251 status
= lpc288x_system_ready(bank
); /* probed? halted? */
252 if (status
!= ERROR_OK
)
255 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
)) {
256 LOG_INFO("Bad sector range");
257 return ERROR_FLASH_SECTOR_INVALID
;
260 /* Configure the flash controller timing */
261 lpc288x_set_flash_clk(bank
);
263 for (sector
= first
; sector
<= last
; sector
++) {
264 if (lpc288x_wait_status_busy(bank
, 1000) != ERROR_OK
)
265 return ERROR_FLASH_OPERATION_FAILED
;
267 lpc288x_load_timer(LOAD_TIMER_ERASE
, target
);
269 target_write_u32(target
, bank
->sectors
[sector
].offset
, 0x00);
271 target_write_u32(target
, F_CTRL
, FC_PROG_REQ
| FC_PROTECT
| FC_CS
);
273 if (lpc288x_wait_status_busy(bank
, 1000) != ERROR_OK
)
274 return ERROR_FLASH_OPERATION_FAILED
;
278 static int lpc288x_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
280 uint8_t page_buffer
[FLASH_PAGE_SIZE
];
281 uint32_t status
, source_offset
, dest_offset
;
282 struct target
*target
= bank
->target
;
283 uint32_t bytes_remaining
= count
;
284 uint32_t first_sector
, last_sector
, sector
, page
;
287 /* probed? halted? */
288 status
= lpc288x_system_ready(bank
);
289 if (status
!= ERROR_OK
)
292 /* Initialise search indices */
293 first_sector
= last_sector
= 0xffffffff;
295 /* validate the write range... */
296 for (i
= 0; i
< bank
->num_sectors
; i
++) {
297 if ((offset
>= bank
->sectors
[i
].offset
) &&
298 (offset
< (bank
->sectors
[i
].offset
+ bank
->sectors
[i
].size
)) &&
299 (first_sector
== 0xffffffff)) {
301 /* all writes must start on a sector boundary... */
302 if (offset
% bank
->sectors
[i
].size
) {
304 "offset 0x%" PRIx32
" breaks required alignment 0x%" PRIx32
"",
306 bank
->sectors
[i
].size
);
307 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
310 if (((offset
+ count
) > bank
->sectors
[i
].offset
) &&
311 ((offset
+ count
) <= (bank
->sectors
[i
].offset
+ bank
->sectors
[i
].size
)) &&
312 (last_sector
== 0xffffffff))
317 if (first_sector
== 0xffffffff || last_sector
== 0xffffffff) {
318 LOG_INFO("Range check failed %" PRIx32
" %" PRIx32
"", offset
, count
);
319 return ERROR_FLASH_DST_OUT_OF_BANK
;
322 /* Configure the flash controller timing */
323 lpc288x_set_flash_clk(bank
);
325 /* initialise the offsets */
329 for (sector
= first_sector
; sector
<= last_sector
; sector
++) {
330 for (page
= 0; page
< bank
->sectors
[sector
].size
/ FLASH_PAGE_SIZE
; page
++) {
331 if (bytes_remaining
== 0) {
333 memset(page_buffer
, 0xFF, FLASH_PAGE_SIZE
);
334 } else if (bytes_remaining
< FLASH_PAGE_SIZE
) {
335 count
= bytes_remaining
;
336 memset(page_buffer
, 0xFF, FLASH_PAGE_SIZE
);
337 memcpy(page_buffer
, &buffer
[source_offset
], count
);
339 count
= FLASH_PAGE_SIZE
;
340 memcpy(page_buffer
, &buffer
[source_offset
], count
);
343 /* Wait for flash to become ready */
344 if (lpc288x_wait_status_busy(bank
, 1000) != ERROR_OK
)
345 return ERROR_FLASH_OPERATION_FAILED
;
347 /* fill flash data latches with 1's */
348 target_write_u32(target
, F_CTRL
, FC_CS
| FC_SET_DATA
| FC_WEN
| FC_FUNC
);
350 target_write_u32(target
, F_CTRL
, FC_CS
| FC_WEN
| FC_FUNC
);
352 if (target_write_buffer(target
, offset
+ dest_offset
, FLASH_PAGE_SIZE
,
353 page_buffer
) != ERROR_OK
) {
354 LOG_INFO("Write to flash buffer failed");
355 return ERROR_FLASH_OPERATION_FAILED
;
358 dest_offset
+= FLASH_PAGE_SIZE
;
359 source_offset
+= count
;
360 bytes_remaining
-= count
;
362 lpc288x_load_timer(LOAD_TIMER_WRITE
, target
);
364 target_write_u32(target
, F_CTRL
, FC_PROG_REQ
| FC_PROTECT
| FC_FUNC
|
372 static int lpc288x_probe(struct flash_bank
*bank
)
374 /* we only deal with LPC2888 so flash config is fixed */
375 struct lpc288x_flash_bank
*lpc288x_info
= bank
->driver_priv
;
378 if (lpc288x_info
->cidr
!= 0)
379 return ERROR_OK
;/* already probed */
381 if (bank
->target
->state
!= TARGET_HALTED
) {
382 LOG_ERROR("Target not halted");
383 return ERROR_TARGET_NOT_HALTED
;
386 retval
= lpc288x_read_part_info(bank
);
387 if (retval
!= ERROR_OK
)
392 static int lpc288x_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
394 int lockregion
, status
;
396 struct target
*target
= bank
->target
;
398 /* probed? halted? */
399 status
= lpc288x_system_ready(bank
);
400 if (status
!= ERROR_OK
)
403 if ((first
< 0) || (last
< first
) || (last
>= bank
->num_sectors
))
404 return ERROR_FLASH_SECTOR_INVALID
;
406 /* Configure the flash controller timing */
407 lpc288x_set_flash_clk(bank
);
409 for (lockregion
= first
; lockregion
<= last
; lockregion
++) {
411 /* write an odd value to base addy to protect... */
414 /* write an even value to base addy to unprotect... */
417 target_write_u32(target
, bank
->sectors
[lockregion
].offset
, value
);
418 target_write_u32(target
, F_CTRL
, FC_LOAD_REQ
| FC_PROTECT
| FC_WEN
| FC_FUNC
|
425 struct flash_driver lpc288x_flash
= {
427 .flash_bank_command
= lpc288x_flash_bank_command
,
428 .erase
= lpc288x_erase
,
429 .protect
= lpc288x_protect
,
430 .write
= lpc288x_write
,
431 .read
= default_flash_read
,
432 .probe
= lpc288x_probe
,
433 .auto_probe
= lpc288x_probe
,
434 .erase_check
= lpc288x_erase_check
,
435 .protect_check
= lpc288x_protect_check
,
436 .free_driver_priv
= default_flash_free_driver_priv
,