OpenOCD
lpc288x.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2008 by *
5  * Karl RobinSod <karl.robinsod@gmail.com> *
6  ***************************************************************************/
7 
8 /***************************************************************************
9 * There are some things to notice
10 *
11 * You need to unprotect flash sectors each time you connect the OpenOCD
12 * Dumping 1MB takes about 60 Seconds
13 * Full erase (sectors 0-22 inclusive) takes 2-4 seconds
14 * Writing 1MB takes 88 seconds
15 *
16  ***************************************************************************/
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20 
21 #include "imp.h"
22 #include <helper/binarybuffer.h>
23 
24 #define LOAD_TIMER_ERASE 0
25 #define LOAD_TIMER_WRITE 1
26 
27 #define FLASH_PAGE_SIZE 512
28 
29 /* LPC288X control registers */
30 #define DBGU_CIDR 0x8000507C
31 /* LPC288X flash registers */
32 #define F_CTRL 0x80102000 /* Flash control register R/W 0x5 */
33 #define F_STAT 0x80102004 /* Flash status register RO 0x45 */
34 #define F_PROG_TIME 0x80102008 /* Flash program time register R/W 0 */
35 #define F_WAIT 0x80102010 /* Flash read wait state register R/W 0xC004 */
36 #define F_CLK_TIME 0x8010201C /* Flash clock divider for 66 kHz generation R/W 0
37  **/
38 #define F_INTEN_CLR 0x80102FD8 /* Clear interrupt enable bits WO - */
39 #define F_INTEN_SET 0x80102FDC /* Set interrupt enable bits WO - */
40 #define F_INT_STAT 0x80102FE0 /* Interrupt status bits RO 0 */
41 #define F_INTEN 0x80102FE4 /* Interrupt enable bits RO 0 */
42 #define F_INT_CLR 0x80102FE8 /* Clear interrupt status bits WO */
43 #define F_INT_SET 0x80102FEC /* Set interrupt status bits WO - */
44 #define FLASH_PD 0x80005030 /* Allows turning off the Flash memory for power
45  *savings. R/W 1*/
46 #define FLASH_INIT 0x80005034 /* Monitors Flash readiness, such as recovery from
47  *Power Down mode. R/W -*/
48 
49 /* F_CTRL bits */
50 #define FC_CS 0x0001
51 #define FC_FUNC 0x0002
52 #define FC_WEN 0x0004
53 #define FC_RD_LATCH 0x0020
54 #define FC_PROTECT 0x0080
55 #define FC_SET_DATA 0x0400
56 #define FC_RSSL 0x0800
57 #define FC_PROG_REQ 0x1000
58 #define FC_CLR_BUF 0x4000
59 #define FC_LOAD_REQ 0x8000
60 /* F_STAT bits */
61 #define FS_DONE 0x0001
62 #define FS_PROGGNT 0x0002
63 #define FS_RDY 0x0004
64 #define FS_ERR 0x0020
65 /* F_PROG_TIME */
66 #define FPT_TIME_MASK 0x7FFF
67 
68 #define FPT_ENABLE 0x8000
69 /* F_WAIT */
70 #define FW_WAIT_STATES_MASK 0x00FF
71 #define FW_SET_MASK 0xC000
72 
73 /* F_CLK_TIME */
74 #define FCT_CLK_DIV_MASK 0x0FFF
75 
76 struct lpc288x_flash_bank {
77  uint32_t working_area;
79 
80  /* chip id register */
81  uint32_t cidr;
82  const char *target_name;
83  uint32_t cclk;
84 
85  uint32_t sector_size_break;
86 };
87 
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);
92 
93 static uint32_t lpc288x_wait_status_busy(struct flash_bank *bank, int timeout)
94 {
95  uint32_t status;
96  struct target *target = bank->target;
97  do {
98  alive_sleep(1);
99  timeout--;
101  } while (((status & FS_DONE) == 0) && timeout);
102 
103  if (timeout == 0) {
104  LOG_DEBUG("Timedout!");
106  }
107  return ERROR_OK;
108 }
109 
110 /* Read device id register and fill in driver info structure */
111 static int lpc288x_read_part_info(struct flash_bank *bank)
112 {
113  struct lpc288x_flash_bank *lpc288x_info = bank->driver_priv;
114  struct target *target = bank->target;
115  uint32_t cidr;
116 
117  int i = 0;
118  uint32_t offset;
119 
120  if (lpc288x_info->cidr == 0x0102100A)
121  return ERROR_OK;/* already probed, multiple probes may cause memory leak, not
122  *allowed */
123 
124  /* Read and parse chip identification register */
126 
127  if (cidr != 0x0102100A) {
128  LOG_WARNING("Cannot identify target as an LPC288X (%08" PRIx32 ")", cidr);
130  }
131 
132  lpc288x_info->cidr = cidr;
133  lpc288x_info->sector_size_break = 0x000F0000;
134  lpc288x_info->target_name = "LPC288x";
135 
136  /* setup the sector info... */
137  offset = bank->base;
138  bank->num_sectors = 23;
139  bank->sectors = malloc(sizeof(struct flash_sector) * 23);
140 
141  for (i = 0; i < 15; i++) {
142  bank->sectors[i].offset = offset;
143  bank->sectors[i].size = 64 * 1024;
144  offset += bank->sectors[i].size;
145  bank->sectors[i].is_erased = -1;
146  bank->sectors[i].is_protected = 1;
147  }
148  for (i = 15; i < 23; i++) {
149  bank->sectors[i].offset = offset;
150  bank->sectors[i].size = 8 * 1024;
151  offset += bank->sectors[i].size;
152  bank->sectors[i].is_erased = -1;
153  bank->sectors[i].is_protected = 1;
154  }
155 
156  return ERROR_OK;
157 }
158 
159 /* TODO: Revisit! Is it impossible to read protection status? */
160 static int lpc288x_protect_check(struct flash_bank *bank)
161 {
162  return ERROR_OK;
163 }
164 
165 /* flash_bank LPC288x 0 0 0 0 <target#> <cclk> */
166 FLASH_BANK_COMMAND_HANDLER(lpc288x_flash_bank_command)
167 {
168  struct lpc288x_flash_bank *lpc288x_info;
169 
170  if (CMD_ARGC < 6)
172 
173  lpc288x_info = malloc(sizeof(struct lpc288x_flash_bank));
174  bank->driver_priv = lpc288x_info;
175 
176  /* part wasn't probed for info yet */
177  lpc288x_info->cidr = 0;
178  COMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], lpc288x_info->cclk);
179 
180  return ERROR_OK;
181 }
182 
183 /* The frequency is the AHB clock frequency divided by (CLK_DIV ×3) + 1.
184  * This must be programmed such that the Flash Programming clock frequency is 66 kHz ± 20%.
185  * AHB = 12 MHz ?
186  * 12000000/66000 = 182
187  * CLK_DIV = 60 ? */
188 static void lpc288x_set_flash_clk(struct flash_bank *bank)
189 {
190  uint32_t clk_time;
191  struct lpc288x_flash_bank *lpc288x_info = bank->driver_priv;
192  clk_time = (lpc288x_info->cclk / 66000) / 3;
193  target_write_u32(bank->target, F_CTRL, FC_CS | FC_WEN);
194  target_write_u32(bank->target, F_CLK_TIME, clk_time);
195 }
196 
197 /* AHB tcyc (in ns) 83 ns
198  * LOAD_TIMER_ERASE FPT_TIME = ((400,000,000 / AHB tcyc (in ns)) - 2) / 512
199  * = 9412 (9500) (AN10548 9375)
200  * LOAD_TIMER_WRITE FPT_TIME = ((1,000,000 / AHB tcyc (in ns)) - 2) / 512
201  * = 23 (75) (AN10548 72 - is this wrong?)
202  * TODO: Sort out timing calcs ;) */
203 static void lpc288x_load_timer(int erase, struct target *target)
204 {
205  if (erase == LOAD_TIMER_ERASE)
207  else
209 }
210 
211 static uint32_t lpc288x_system_ready(struct flash_bank *bank)
212 {
213  struct lpc288x_flash_bank *lpc288x_info = bank->driver_priv;
214  if (lpc288x_info->cidr == 0)
216 
217  if (bank->target->state != TARGET_HALTED) {
218  LOG_ERROR("Target not halted");
220  }
221  return ERROR_OK;
222 }
223 
224 static int lpc288x_erase(struct flash_bank *bank, unsigned int first,
225  unsigned int last)
226 {
227  uint32_t status;
228  struct target *target = bank->target;
229 
230  status = lpc288x_system_ready(bank); /* probed? halted? */
231  if (status != ERROR_OK)
232  return status;
233 
234  if ((last < first) || (last >= bank->num_sectors)) {
235  LOG_INFO("Bad sector range");
237  }
238 
239  /* Configure the flash controller timing */
241 
242  for (unsigned int sector = first; sector <= last; sector++) {
243  if (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK)
245 
247 
248  target_write_u32(target, bank->sectors[sector].offset, 0x00);
249 
251  }
252  if (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK)
254  return ERROR_OK;
255 }
256 
257 static int lpc288x_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
258 {
259  uint8_t page_buffer[FLASH_PAGE_SIZE];
260  uint32_t status, source_offset, dest_offset;
261  struct target *target = bank->target;
262  uint32_t bytes_remaining = count;
263  uint32_t first_sector, last_sector, sector, page;
264 
265  /* probed? halted? */
267  if (status != ERROR_OK)
268  return status;
269 
270  /* Initialise search indices */
271  first_sector = last_sector = 0xffffffff;
272 
273  /* validate the write range... */
274  for (unsigned int i = 0; i < bank->num_sectors; i++) {
275  if ((offset >= bank->sectors[i].offset) &&
276  (offset < (bank->sectors[i].offset + bank->sectors[i].size)) &&
277  (first_sector == 0xffffffff)) {
278  first_sector = i;
279  /* all writes must start on a sector boundary... */
280  if (offset % bank->sectors[i].size) {
281  LOG_INFO(
282  "offset 0x%" PRIx32 " breaks required alignment 0x%" PRIx32 "",
283  offset,
284  bank->sectors[i].size);
286  }
287  }
288  if (((offset + count) > bank->sectors[i].offset) &&
289  ((offset + count) <= (bank->sectors[i].offset + bank->sectors[i].size)) &&
290  (last_sector == 0xffffffff))
291  last_sector = i;
292  }
293 
294  /* Range check... */
295  if (first_sector == 0xffffffff || last_sector == 0xffffffff) {
296  LOG_INFO("Range check failed %" PRIx32 " %" PRIx32 "", offset, count);
298  }
299 
300  /* Configure the flash controller timing */
302 
303  /* initialise the offsets */
304  source_offset = 0;
305  dest_offset = 0;
306 
307  for (sector = first_sector; sector <= last_sector; sector++) {
308  for (page = 0; page < bank->sectors[sector].size / FLASH_PAGE_SIZE; page++) {
309  if (bytes_remaining == 0) {
310  count = 0;
311  memset(page_buffer, 0xFF, FLASH_PAGE_SIZE);
312  } else if (bytes_remaining < FLASH_PAGE_SIZE) {
313  count = bytes_remaining;
314  memset(page_buffer, 0xFF, FLASH_PAGE_SIZE);
315  memcpy(page_buffer, &buffer[source_offset], count);
316  } else {
318  memcpy(page_buffer, &buffer[source_offset], count);
319  }
320 
321  /* Wait for flash to become ready */
322  if (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK)
324 
325  /* fill flash data latches with 1's */
327 
329 
330  if (target_write_buffer(target, offset + dest_offset, FLASH_PAGE_SIZE,
331  page_buffer) != ERROR_OK) {
332  LOG_INFO("Write to flash buffer failed");
334  }
335 
336  dest_offset += FLASH_PAGE_SIZE;
337  source_offset += count;
338  bytes_remaining -= count;
339 
341 
343  FC_CS);
344  }
345  }
346 
347  return ERROR_OK;
348 }
349 
350 static int lpc288x_probe(struct flash_bank *bank)
351 {
352  /* we only deal with LPC2888 so flash config is fixed */
353  struct lpc288x_flash_bank *lpc288x_info = bank->driver_priv;
354  int retval;
355 
356  if (lpc288x_info->cidr != 0)
357  return ERROR_OK;/* already probed */
358 
359  if (bank->target->state != TARGET_HALTED) {
360  LOG_ERROR("Target not halted");
362  }
363 
364  retval = lpc288x_read_part_info(bank);
365  if (retval != ERROR_OK)
366  return retval;
367  return ERROR_OK;
368 }
369 
370 static int lpc288x_protect(struct flash_bank *bank, int set, unsigned int first,
371  unsigned int last)
372 {
373  int status;
374  uint32_t value;
375  struct target *target = bank->target;
376 
377  /* probed? halted? */
379  if (status != ERROR_OK)
380  return status;
381 
382  if ((last < first) || (last >= bank->num_sectors))
384 
385  /* Configure the flash controller timing */
387 
388  for (unsigned int lockregion = first; lockregion <= last; lockregion++) {
389  if (set) {
390  /* write an odd value to base address to protect... */
391  value = 0x01;
392  } else {
393  /* write an even value to base address to unprotect... */
394  value = 0x00;
395  }
396  target_write_u32(target, bank->sectors[lockregion].offset, value);
398  FC_CS);
399  }
400 
401  return ERROR_OK;
402 }
403 
404 const struct flash_driver lpc288x_flash = {
405  .name = "lpc288x",
406  .flash_bank_command = lpc288x_flash_bank_command,
407  .erase = lpc288x_erase,
408  .protect = lpc288x_protect,
409  .write = lpc288x_write,
410  .read = default_flash_read,
411  .probe = lpc288x_probe,
412  .auto_probe = lpc288x_probe,
413  .erase_check = default_flash_blank_check,
414  .protect_check = lpc288x_protect_check,
415  .free_driver_priv = default_flash_free_driver_priv,
416 };
Support functions to access arbitrary bits in a byte array.
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:156
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:402
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:151
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
Definition: command.h:442
uint8_t bank
Definition: esirisc.c:135
#define ERROR_FLASH_SECTOR_INVALID
Definition: flash/common.h:29
#define ERROR_FLASH_BANK_NOT_PROBED
Definition: flash/common.h:35
#define ERROR_FLASH_OPERATION_FAILED
Definition: flash/common.h:30
#define ERROR_FLASH_DST_BREAKS_ALIGNMENT
Definition: flash/common.h:32
#define ERROR_FLASH_DST_OUT_OF_BANK
Definition: flash/common.h:31
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
void default_flash_free_driver_priv(struct flash_bank *bank)
Deallocates bank->driver_priv.
void alive_sleep(uint64_t ms)
Definition: log.c:456
#define LOG_WARNING(expr ...)
Definition: log.h:129
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_INFO(expr ...)
Definition: log.h:126
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:164
#define FC_PROG_REQ
Definition: lpc288x.c:54
static int lpc288x_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Definition: lpc288x.c:221
static void lpc288x_set_flash_clk(struct flash_bank *bank)
Definition: lpc288x.c:185
#define LOAD_TIMER_ERASE
Definition: lpc288x.c:24
#define FC_FUNC
Definition: lpc288x.c:48
#define F_CTRL
Definition: lpc288x.c:32
#define FPT_ENABLE
Definition: lpc288x.c:65
#define FC_PROTECT
Definition: lpc288x.c:51
#define FLASH_PAGE_SIZE
Definition: lpc288x.c:27
static void lpc288x_load_timer(int erase, struct target *target)
Definition: lpc288x.c:200
static uint32_t lpc288x_system_ready(struct flash_bank *bank)
Definition: lpc288x.c:208
#define FC_SET_DATA
Definition: lpc288x.c:52
#define LOAD_TIMER_WRITE
Definition: lpc288x.c:25
static int lpc288x_read_part_info(struct flash_bank *bank)
Definition: lpc288x.c:108
#define FC_WEN
Definition: lpc288x.c:49
#define F_CLK_TIME
Definition: lpc288x.c:36
static uint32_t lpc288x_wait_status_busy(struct flash_bank *bank, int timeout)
Definition: lpc288x.c:90
static int lpc288x_protect_check(struct flash_bank *bank)
Definition: lpc288x.c:157
static int lpc288x_probe(struct flash_bank *bank)
Definition: lpc288x.c:347
#define FC_LOAD_REQ
Definition: lpc288x.c:56
const struct flash_driver lpc288x_flash
Definition: lpc288x.c:401
static int lpc288x_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: lpc288x.c:254
#define F_PROG_TIME
Definition: lpc288x.c:34
#define DBGU_CIDR
Definition: lpc288x.c:30
#define F_STAT
Definition: lpc288x.c:33
#define FC_CS
Definition: lpc288x.c:47
#define FS_DONE
Definition: lpc288x.c:58
FLASH_BANK_COMMAND_HANDLER(lpc288x_flash_bank_command)
Definition: lpc288x.c:163
static int lpc288x_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
Definition: lpc288x.c:367
Provides details of a flash bank, available either on-chip or through a major interface.
Definition: nor/core.h:75
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
Definition: nor/driver.h:39
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
Definition: nor/driver.h:44
Describes the geometry and status of a single flash sector within a flash bank.
Definition: nor/core.h:28
uint32_t sector_size_break
Definition: lpc288x.c:82
const char * target_name
Definition: lpc288x.c:79
uint32_t cidr
Definition: lpc288x.c:78
uint32_t cclk
Definition: lpc288x.c:80
uint32_t working_area_size
Definition: lpc288x.c:75
uint32_t working_area
Definition: lpc288x.c:74
Definition: target.h:116
Definition: psoc6.c:83
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2342
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2641
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2550
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:790
@ TARGET_HALTED
Definition: target.h:56
uint8_t status[4]
Definition: vdebug.c:17
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t count[4]
Definition: vdebug.c:22