- added smoketest result for r657
[fw/openocd] / src / flash / lpc288x.c
1 /***************************************************************************
2  *   Copyright (C) 2008 by                                                             *
3  *   Karl RobinSod <karl.robinsod@gmail.com>                               *
4  *                                                                         *
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.                                   *
9  *                                                                         *
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.                          *
14  *                                                                         *
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  ***************************************************************************/
20
21 /***************************************************************************
22 * There are some things to notice
23 *
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
28 *
29  ***************************************************************************/
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "replacements.h"
35
36 #include "lpc288x.h"
37
38 #include "flash.h"
39 #include "target.h"
40 #include "log.h"
41 #include "binarybuffer.h"
42 #include "types.h"
43
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
47
48 #define LOAD_TIMER_ERASE    0
49 #define LOAD_TIMER_WRITE    1
50
51 #define FLASH_PAGE_SIZE     512
52
53 /* LPC288X control registers */
54 #define DBGU_CIDR     0x8000507C
55 /* LPC288X flash registers */
56 #define F_CTRL         0x80102000  /* Flash control register R/W 0x5 */
57 #define F_STAT         0x80102004  /* Flash status register RO 0x45 */
58 #define F_PROG_TIME 0x80102008  /* Flash program time register R/W 0 */
59 #define F_WAIT         0x80102010  /* Flash read wait state register R/W 0xC004 */
60 #define F_CLK_TIME     0x8010201C     /* Flash clock divider for 66 kHz generation R/W 0 */
61 #define F_INTEN_CLR 0x80102FD8     /* Clear interrupt enable bits WO - */
62 #define F_INTEN_SET 0x80102FDC  /* Set interrupt enable bits WO - */
63 #define F_INT_STAT  0x80102FE0  /* Interrupt status bits RO 0 */
64 #define F_INTEN     0x80102FE4    /* Interrupt enable bits RO 0 */
65 #define F_INT_CLR     0x80102FE8  /* Clear interrupt status bits WO */
66 #define F_INT_SET     0x80102FEC  /* Set interrupt status bits WO - */
67 #define FLASH_PD     0x80005030  /* Allows turning off the Flash memory for power savings. R/W 1*/
68 #define FLASH_INIT     0x80005034  /* Monitors Flash readiness, such as recovery from Power Down mode. R/W -*/
69
70 /* F_CTRL bits */
71 #define FC_CS         0x0001    
72 #define FC_FUNC     0x0002   
73 #define FC_WEN         0x0004   
74 #define FC_RD_LATCH 0x0020   
75 #define FC_PROTECT    0x0080   
76 #define FC_SET_DATA 0x0400   
77 #define FC_RSSL     0x0800   
78 #define FC_PROG_REQ 0x1000   
79 #define FC_CLR_BUF  0x4000   
80 #define FC_LOAD_REQ 0x8000   
81 /* F_STAT bits */
82 #define FS_DONE     0x0001   
83 #define FS_PROGGNT     0x0002   
84 #define FS_RDY         0x0004   
85 #define FS_ERR         0x0020   
86 /* F_PROG_TIME */
87 #define FPT_TIME_MASK    0x7FFF   
88
89 #define FPT_ENABLE         0x8000   
90 /* F_WAIT */
91 #define FW_WAIT_STATES_MASK    0x00FF
92 #define FW_SET_MASK            0xC000
93
94 /* F_CLK_TIME */
95 #define FCT_CLK_DIV_MASK    0x0FFF
96
97
98
99 int lpc288x_register_commands(struct command_context_s *cmd_ctx);
100 int lpc288x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
101 int lpc288x_erase(struct flash_bank_s *bank, int first, int last);
102 int lpc288x_protect(struct flash_bank_s *bank, int set, int first, int last);
103 int lpc288x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
104 int lpc288x_probe(struct flash_bank_s *bank);
105 int lpc288x_auto_probe(struct flash_bank_s *bank);
106 int lpc288x_erase_check(struct flash_bank_s *bank);
107 int lpc288x_protect_check(struct flash_bank_s *bank);
108 int lpc288x_info(struct flash_bank_s *bank, char *buf, int buf_size);
109 void lpc288x_set_flash_mode(flash_bank_t *bank, u8 flashplane, int mode);
110 u32 lpc288x_wait_status_busy(flash_bank_t *bank, int timeout);
111 void lpc288x_load_timer(int erase, struct target_s *target);
112 void lpc288x_set_flash_clk(struct flash_bank_s *bank);
113 u32 lpc288x_system_ready(struct flash_bank_s *bank);
114 int lpc288x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
115
116 flash_driver_t lpc288x_flash =
117 {
118     .name = "lpc288x",
119     .register_commands = lpc288x_register_commands,
120     .flash_bank_command = lpc288x_flash_bank_command,
121     .erase = lpc288x_erase,
122     .protect = lpc288x_protect,
123     .write = lpc288x_write,
124     .probe = lpc288x_probe,
125     .auto_probe = lpc288x_probe,
126     .erase_check = lpc288x_erase_check,
127     .protect_check = lpc288x_protect_check,
128     .info = lpc288x_info
129 };
130
131
132 int lpc288x_register_commands(struct command_context_s *cmd_ctx)
133 {
134     return ERROR_OK;
135 }
136
137
138
139 u32 lpc288x_wait_status_busy(flash_bank_t *bank, int timeout)
140 {
141     u32 status;
142     target_t *target = bank->target;
143     do
144     {
145         usleep(1000);
146         timeout--;
147         target_read_u32(target, F_STAT, &status);
148     }while (((status & FS_DONE) == 0) && timeout);
149
150     if(timeout == 0)
151     {
152         LOG_DEBUG("Timedout!");
153         return ERROR_FLASH_OPERATION_FAILED;
154     }
155     return ERROR_OK;
156 }
157
158 /* Read device id register and fill in driver info structure */
159 int lpc288x_read_part_info(struct flash_bank_s *bank)
160 {
161     lpc288x_flash_bank_t *lpc288x_info = bank->driver_priv;
162     target_t *target = bank->target;
163     u32 cidr, status;
164     int sectornum;
165
166     int i = 0;
167     u32 offset;
168
169     if (lpc288x_info->cidr == 0x0102100A)
170         return ERROR_OK; /* already probed, multiple probes may cause memory leak, not allowed */
171    
172     /* Read and parse chip identification register */
173     target_read_u32(target, DBGU_CIDR, &cidr);
174    
175     if (cidr != 0x0102100A)
176     {
177         LOG_WARNING("Cannot identify target as an LPC288X (%08X)",cidr);
178         return ERROR_FLASH_OPERATION_FAILED;
179     }
180
181     lpc288x_info->cidr                 = cidr;
182     lpc288x_info->sector_size_break = 0x000F0000;
183     lpc288x_info->target_name         = "LPC288x";
184
185     /* setup the sector info... */
186     offset = bank->base;
187     bank->num_sectors = 23;
188     bank->sectors = malloc(sizeof(flash_sector_t) * 23);
189
190     for (i = 0; i < 15; i++)
191     {
192         bank->sectors[i].offset = offset;
193         bank->sectors[i].size = 64 * 1024;
194         offset += bank->sectors[i].size;
195         bank->sectors[i].is_erased = -1;
196         bank->sectors[i].is_protected = 1;
197     }
198     for (i = 15; i < 23; i++)
199     {
200         bank->sectors[i].offset = offset;
201         bank->sectors[i].size = 8 * 1024;
202         offset += bank->sectors[i].size;
203         bank->sectors[i].is_erased = -1;
204         bank->sectors[i].is_protected = 1;
205     }
206
207     return ERROR_OK;
208 }
209
210 int lpc288x_protect_check(struct flash_bank_s *bank)
211 {
212     return ERROR_OK;
213 }
214
215 /* flash_bank LPC288x 0 0 0 0 <target#> <cclk>
216  */
217 int lpc288x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
218 {
219     lpc288x_flash_bank_t *lpc288x_info;
220     int i;
221    
222     if (argc < 6)
223     {
224         LOG_WARNING("incomplete flash_bank LPC288x configuration");
225         return ERROR_FLASH_BANK_INVALID;
226     }
227    
228     lpc288x_info = malloc(sizeof(lpc288x_flash_bank_t));
229     bank->driver_priv = lpc288x_info;
230    
231     /* part wasn't probed for info yet */
232     lpc288x_info->cidr = 0;
233     lpc288x_info->cclk = strtoul(args[6], NULL, 0);
234
235     return ERROR_OK;
236 }
237
238 /*
239 The frequency is the AHB clock frequency divided by (CLK_DIV Ã—
240 3) + 1. This must be programmed such that the Flash
241 Programming clock frequency is 66 kHz Â± 20%.
242     AHB = 12 MHz ?
243     12000000/66000 = 182
244     CLK_DIV = 60 ?
245 */
246 void lpc288x_set_flash_clk(struct flash_bank_s *bank)
247 {
248     u32 clk_time;
249     lpc288x_flash_bank_t *lpc288x_info = bank->driver_priv;
250     clk_time = (lpc288x_info->cclk / 66000) / 3;
251     target_write_u32(bank->target, F_CTRL, FC_CS | FC_WEN );
252     target_write_u32(bank->target, F_CLK_TIME, clk_time);
253 }
254
255 /*
256 AHB tcyc (in ns) 83 ns
257
258 LOAD_TIMER_ERASE    FPT_TIME     = ((400,000,000 / AHB tcyc (in ns)) - 2) / 512
259                                 = 9412 (9500) (AN10548 9375)
260 LOAD_TIMER_WRITE    FPT_TIME     = ((1,000,000 / AHB tcyc (in ns)) - 2) / 512
261                                 = 23 (75) (AN10548 72 - is this wrong?)
262                                
263 TODO: Sort out timing calcs ;)
264 */
265 void lpc288x_load_timer(int erase, struct target_s *target)
266 {
267     if(erase == LOAD_TIMER_ERASE)
268     {
269         target_write_u32(target, F_PROG_TIME, FPT_ENABLE | 9500);
270     }
271     else
272     {
273         target_write_u32(target, F_PROG_TIME, FPT_ENABLE | 75);
274     }
275 }
276
277
278
279 u32 lpc288x_system_ready(struct flash_bank_s *bank)
280 {
281     lpc288x_flash_bank_t *lpc288x_info = bank->driver_priv;
282     if (lpc288x_info->cidr == 0)
283     {
284         return ERROR_FLASH_BANK_NOT_PROBED;
285     }
286
287     if (bank->target->state != TARGET_HALTED)
288     {
289         return ERROR_TARGET_NOT_HALTED;
290     }
291     return ERROR_OK;
292 }
293
294 int lpc288x_erase_check(struct flash_bank_s *bank)
295 {
296     u32 buffer, test_bytes;
297     u32 addr, sector, i, status = lpc288x_system_ready(bank);    /* probed? halted? */
298     if(status != ERROR_OK)
299     {
300         LOG_INFO("Processor not halted/not probed");
301         return status;
302     }
303
304     return ERROR_OK;
305 }
306
307 int lpc288x_erase(struct flash_bank_s *bank, int first, int last)
308 {
309     u32 status;
310     int sector;
311     target_t *target = bank->target;
312
313     status = lpc288x_system_ready(bank);    /* probed? halted? */
314     if(status != ERROR_OK)
315     {
316         return status;
317     }
318    
319     if ((first < 0) || (last < first) || (last >= bank->num_sectors))
320     {
321         LOG_INFO("Bad sector range");
322         return ERROR_FLASH_SECTOR_INVALID;
323     }
324
325     /* Configure the flash controller timing */
326     lpc288x_set_flash_clk(bank);
327
328     for (sector = first; sector <= last; sector++)
329     {
330         if (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK)
331         {
332             return ERROR_FLASH_OPERATION_FAILED;
333         }
334
335         lpc288x_load_timer(LOAD_TIMER_ERASE,target);
336    
337         target_write_u32(    target,
338                             bank->sectors[sector].offset,
339                             0x00);
340        
341         target_write_u32(    target,
342                             F_CTRL,
343                             FC_PROG_REQ |
344                             FC_PROTECT    |
345                             FC_CS);
346     }
347     if (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK)
348     {
349         return ERROR_FLASH_OPERATION_FAILED;
350     }
351     return ERROR_OK;
352
353 }
354
355
356 int lpc288x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
357 {
358     u8 page_buffer[FLASH_PAGE_SIZE];
359     u32 i, status, source_offset,dest_offset;
360     target_t *target = bank->target;
361     u32 bytes_remaining = count;
362     u32 first_sector, last_sector, sector, page;
363
364     /* probed? halted? */
365     status = lpc288x_system_ready(bank);   
366     if(status != ERROR_OK)
367     {
368         return status;
369     }
370
371     /* Initialise search indices */
372     first_sector = last_sector = 0xffffffff;
373    
374     /* validate the write range... */
375     for(i = 0; i < bank->num_sectors; i++)
376     {
377         if((offset >= bank->sectors[i].offset) &&
378            (offset < (bank->sectors[i].offset + bank->sectors[i].size)) &&
379            (first_sector == 0xffffffff))
380         {
381            first_sector = i;
382            /* all writes must start on a sector boundary...  */
383            if (offset % bank->sectors[i].size)
384            {
385                LOG_INFO("offset 0x%x breaks required alignment 0x%x", offset, bank->sectors[i].size);
386                return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
387            }
388         }
389         if(((offset + count) > bank->sectors[i].offset) &&
390            ((offset + count) <= (bank->sectors[i].offset + bank->sectors[i].size)) &&
391            (last_sector == 0xffffffff))
392         {
393            last_sector = i;
394         }
395     }
396        
397     /* Range check... */
398     if (first_sector == 0xffffffff || last_sector == 0xffffffff)
399     {
400           LOG_INFO("Range check failed %x %x", offset, count);
401         return ERROR_FLASH_DST_OUT_OF_BANK;
402     }
403    
404     /* Configure the flash controller timing */
405     lpc288x_set_flash_clk(bank);   
406
407     /* initialise the offsets */
408     source_offset = 0;
409     dest_offset   = 0;
410    
411     for (sector=first_sector; sector<=last_sector; sector++)
412     {
413         for(page = 0; page < bank->sectors[sector].size / FLASH_PAGE_SIZE; page++)
414         {
415             if(bytes_remaining == 0)
416             {
417                 count = 0;
418                 memset(page_buffer, 0xFF, FLASH_PAGE_SIZE);
419             }
420             else if (bytes_remaining < FLASH_PAGE_SIZE)
421             {
422                 count = bytes_remaining;
423                 memset(page_buffer, 0xFF, FLASH_PAGE_SIZE);
424                 memcpy(page_buffer, &buffer[source_offset], count);
425             }
426             else
427             {
428                 count = FLASH_PAGE_SIZE;
429                 memcpy(page_buffer, &buffer[source_offset], count);
430             }
431
432             /* Wait for flash to become ready */
433             if (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK)
434             {
435                 return ERROR_FLASH_OPERATION_FAILED;
436             }
437            
438             /* fill flash data latches with 1's */
439             target_write_u32(target,     F_CTRL,
440                                         FC_CS             |
441                                         FC_SET_DATA        |
442                                         FC_WEN            |
443                                         FC_FUNC    );
444
445             target_write_u32(target,     F_CTRL,
446                                         FC_CS             |
447                                         FC_WEN            |
448                                         FC_FUNC    );
449             /*would be better to use the clean target_write_buffer() interface but
450               it seems not to be a LOT slower....
451               bulk_write_memory() is no quicker :(*/
452 #if 1
453             if (target->type->write_memory(target, offset + dest_offset, 4, 128, page_buffer) != ERROR_OK)
454             {
455                 LOG_ERROR("Write failed s %x p %x", sector, page);
456                 return ERROR_FLASH_OPERATION_FAILED;
457             }
458 #else
459             if(target_write_buffer(target, offset + dest_offset, FLASH_PAGE_SIZE, page_buffer) != ERROR_OK)
460             {
461                 LOG_INFO("Write to flash buffer failed");
462                 return ERROR_FLASH_OPERATION_FAILED;
463             }
464 #endif
465             dest_offset       += FLASH_PAGE_SIZE;
466             source_offset    += count;
467             bytes_remaining -= count;
468
469             lpc288x_load_timer(LOAD_TIMER_WRITE, target);
470            
471             target_write_u32(    target,
472                                 F_CTRL,
473                                 FC_PROG_REQ |
474                                 FC_PROTECT    |
475                                 FC_FUNC        |
476                                 FC_CS);
477            
478            
479         }           
480     }
481        
482     return ERROR_OK;
483 }
484
485
486 int lpc288x_probe(struct flash_bank_s *bank)
487 {
488     /* we only deal with LPC2888 so flash config is fixed
489      */
490     lpc288x_flash_bank_t *lpc288x_info = bank->driver_priv;
491     int retval;
492
493     if (lpc288x_info->cidr != 0)
494     {
495         return ERROR_OK; /* already probed */
496     }
497
498     if (bank->target->state != TARGET_HALTED)
499     {
500         return ERROR_TARGET_NOT_HALTED;
501     }
502
503     retval = lpc288x_read_part_info(bank);
504     if (retval != ERROR_OK)
505         return retval;
506    
507     return ERROR_OK;
508 }
509
510
511 int lpc288x_info(struct flash_bank_s *bank, char *buf, int buf_size)
512 {
513     snprintf(buf, buf_size, "lpc288x flash driver");
514     return ERROR_OK;
515 }
516
517 int lpc288x_protect(struct flash_bank_s *bank, int set, int first, int last)
518 {
519     int lockregion, status;
520     u32 value;
521     target_t *target = bank->target;
522    
523     /* probed? halted? */
524     status = lpc288x_system_ready(bank);   
525     if(status != ERROR_OK)
526     {
527         return status;
528     }
529    
530     if ((first < 0) || (last < first) || (last >= bank->num_sectors))
531     {
532         return ERROR_FLASH_SECTOR_INVALID;
533     }
534
535     /* Configure the flash controller timing */
536     lpc288x_set_flash_clk(bank);   
537
538     for (lockregion = first; lockregion <= last; lockregion++)
539     {
540         if(set)
541         {
542             /* write an odd value to base addy to protect... */
543             value = 0x01;
544         }
545         else
546         {
547             /* write an even value to base addy to unprotect... */
548             value = 0x00;
549         }
550         target_write_u32(    target,
551                             bank->sectors[lockregion].offset,
552                             value);
553        
554         target_write_u32(    target,
555                             F_CTRL,
556                             FC_LOAD_REQ |
557                             FC_PROTECT    |
558                             FC_WEN        |
559                             FC_FUNC        |
560                             FC_CS);
561     }
562    
563     return ERROR_OK;
564 }
565