Paparazzi UAS  v4.2.2_stable-4-gcc32f65
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
settings_arch.c
Go to the documentation of this file.
1 /*
2  * Paparazzi persistent settings low level flash routines lpc21
3  *
4  * Copyright (C) 2011 Martin Mueller <martinmm@pfump.org>
5  *
6  * This file is part of Paparazzi.
7  *
8  * Paparazzi is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * Paparazzi is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Paparazzi; see the file COPYING. If not, write to
20  * the Free Software Foundation, 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  *
23  */
24 
25 /*
26  LPC2148 flash data is located in the last available page
27 
28  0x00000000: Paparazzi bootloader (16k)
29  0x00004000: Paparazzi code (480k)
30  0x0007C000: persistent settings (4k)
31  0x0007D000: Philips/NXP bootloader (12k)
32 
33  data flash_addr
34  data_size flash_end - FSIZ
35  checksum flash_end - FCHK
36 
37  LPC21: minimum write size 256 bytes, endurance 100k cycles,
38  max sector erase time 400ms, max prog time 1ms per 256 bytes
39 */
40 
41 #include "subsystems/settings.h"
42 
43 #include "LPC21xx.h"
44 #include BOARD_CONFIG
45 #include "armVIC.h"
46 
47 #define IAP_LOCATION 0x7FFFFFF1
48 
49 #define IAP_PREPARE_SECTORS 50
50 #define IAP_COPY_RAM_TO_FLASH 51
51 #define IAP_ERASE_SECTORS 52
52 #define IAP_BLANK_CHECK_SECTORS 53
53 #define IAP_READ_PART_ID 54
54 #define IAP_COMPARE 56
55 
56 /* we have to operate on 256 byte flash boundaries */
57 #define BOUND 256
58 
59 #define FSIZ 8
60 #define FCHK 4
61 
62 typedef void (*IAP)(uint32_t[], uint32_t[]);
63 
64 typedef struct {
69 } FlashInfo;
70 
71 static uint32_t pflash_checksum(uint32_t ptr, uint32_t size);
72 static int32_t flash_detect(FlashInfo* flash);
73 static int32_t pflash_erase_page(FlashInfo* flash);
75  uint32_t dest,
76  uint32_t src);
78  uint32_t src,
79  uint32_t size,
80  uint32_t chksum);
81 
82 
84  uint32_t i, sum = 0;
85 
86  /* do it cheap for now */
87  for (i=0; i<size; i++) {
88  sum += *(uint8_t*) (ptr+i);
89  }
90 
91  return sum;
92 }
93 
94 static int32_t flash_detect(FlashInfo* flash) {
95  uint32_t command[5], result[3];
96  IAP iap_entry;
97 
98  iap_entry = (IAP) IAP_LOCATION;
99 
100  /* get part ID */
101  command[0] = IAP_READ_PART_ID;
102  disableIRQ();
103  iap_entry(command, result);
104  enableIRQ();
105  if (result[0] != 0) return result[0];
106 
107  switch (result[1]) {
108  /* LPC2141, 32k Flash, 8k RAM */
109  case 0x0402FF01:
110  /* LPC2142, 64k Flash, 16k RAM */
111  case 0x0402FF11:
112  /* LPC2144, 128k Flash, 16k RAM */
113  case 0x0402FF12:
114  /* LPC2146, 256k Flash, 32k+8k RAM */
115  case 0x0402FF23:
116  {
117  return -1;
118  break;
119  }
120  /* have LPC2148 support only */
121  /* LPC2148, 512k Flash, 32k+8k RAM */
122  case 0x0402FF25:
123  {
124  flash->page_size = 0x1000;
125  flash->page_nr = 26;
126  flash->addr = 0x7C000;
127  break;
128  }
129  default: return -1;
130  }
131 
132  return 0;
133 }
134 
136  uint32_t command[5], result[3];
137  IAP iap_entry;
138 
139  iap_entry = (IAP) IAP_LOCATION;
140 
141  /* prepare page/sector */
142  command[0] = IAP_PREPARE_SECTORS;
143  command[1] = flash->page_nr;
144  command[2] = flash->page_nr;
145  disableIRQ();
146  iap_entry(command, result);
147  enableIRQ();
148  if (result[0] != 0) return result[0];
149 
150  /* erase page/sector */
151  command[0] = IAP_ERASE_SECTORS;
152  command[1] = flash->page_nr;
153  command[2] = flash->page_nr;
154  disableIRQ();
155  iap_entry(command, result);
156  enableIRQ();
157  if (result[0] != 0) return result[0];
158 
159  /* verify erase */
160  command[0] = IAP_BLANK_CHECK_SECTORS;
161  command[1] = flash->page_nr;
162  command[2] = flash->page_nr;
163  iap_entry(command, result);
164  if (result[0] != 0) return result[0];
165 
166  return 0;
167 }
168 
170  uint32_t dest,
171  uint32_t src) {
172  uint32_t command[5], result[3];
173  IAP iap_entry;
174 
175  iap_entry = (IAP) IAP_LOCATION;
176 
177  /* prepare page/sector */
178  command[0] = IAP_PREPARE_SECTORS;
179  command[1] = flash->page_nr;
180  command[2] = flash->page_nr;
181  disableIRQ();
182  iap_entry(command, result);
183  enableIRQ();
184  if (result[0] != 0) return result[0];
185 
186  /* flash from ram */
187  command[0] = IAP_COPY_RAM_TO_FLASH;
188  command[1] = dest;
189  command[2] = src;
190  command[3] = BOUND;
191  command[4] = CCLK/1000;
192  disableIRQ();
193  iap_entry(command, result);
194  enableIRQ();
195  if (result[0] != 0) return result[0];
196 
197  return 0;
198 }
199 
201  uint32_t src,
202  uint32_t size,
203  uint32_t chksum) {
204  uint32_t data[BOUND/4], i, j, ret;
205  uint32_t ptr = (uint32_t) &data;
206 
207  /* erase */
208  if ((ret = pflash_erase_page(flash))) return ret;
209 
210  /* write data in arrays */
211  for (i=0; i<size; i+=BOUND) {
212  /* copy data to aligned memory */
213  for (j=0; j<BOUND; j++) {
214  *(uint8_t*) (ptr+j) = *(uint8_t*) (src+i+j);
215  }
216  if (i == flash->page_size - BOUND) {
217  data[(BOUND-FSIZ)/4] = size;
218  data[(BOUND-FCHK)/4] = chksum;
219  }
220  if ((ret = pflash_program_array(flash, flash->addr+i, ptr))) return ret;
221  }
222 
223  /* last array */
224  if (i <= flash->page_size - BOUND) {
225  data[(BOUND-FSIZ)/4] = size;
226  data[(BOUND-FCHK)/4] = chksum;
227  if ((ret = pflash_program_array(flash,
228  flash->addr+flash->page_size-BOUND,
229  ptr)))
230  return ret;
231  }
232 
233  /* verify data */
234  for (i=0; i<size; i++) {
235  if ((*(uint8_t*) (flash->addr+i)) != (*(uint8_t*) (src+i))) return -2;
236  }
237  if (*(uint32_t*) (flash->addr+flash->page_size-FSIZ) != size) return -3;
238  if (*(uint32_t*) (flash->addr+flash->page_size-FCHK) != chksum) return -4;
239 
240  return 0;
241 }
242 
244  FlashInfo flash_info;
245 
246  if (flash_detect(&flash_info)) return -1;
247  if ((size > flash_info.page_size-FSIZ) || (size == 0)) return -2;
248 
249  return pflash_program_bytes(&flash_info,
250  ptr,
251  size,
252  pflash_checksum(ptr, size));
253 }
254 
256  FlashInfo flash;
257  uint32_t i;
258 
259  /* check parameters */
260  if (flash_detect(&flash)) return -1;
261  if ((size > flash.page_size-FSIZ) || (size == 0)) return -2;
262 
263  /* check consistency */
264  if (size != *(uint32_t*)(flash.addr+flash.page_size-FSIZ)) return -3;
265  if (pflash_checksum(flash.addr, size) !=
266  *(uint32_t*)(flash.addr+flash.page_size-FCHK))
267  return -4;
268 
269  /* copy data */
270  for (i=0; i<size; i++) {
271  *(uint8_t*) (ptr+i) = *(uint8_t*) (flash.addr+i);
272  }
273 
274  return 0;
275 }
#define IAP_PREPARE_SECTORS
Definition: settings_arch.c:49
#define IAP_READ_PART_ID
Definition: settings_arch.c:53
uint32_t page_nr
Definition: settings_arch.c:67
static int32_t pflash_erase_page(FlashInfo *flash)
uint32_t addr
Definition: settings_arch.c:65
#define IAP_BLANK_CHECK_SECTORS
Definition: settings_arch.c:52
static int32_t flash_detect(FlashInfo *flash)
Definition: settings_arch.c:94
int32_t persistent_read(uint32_t ptr, uint32_t size)
void(* IAP)(uint32_t[], uint32_t[])
Definition: settings_arch.c:62
#define BOUND
Definition: settings_arch.c:57
#define FSIZ
Definition: settings_arch.c:59
unsigned enableIRQ(void)
Definition: armVIC.c:51
unsigned long uint32_t
Definition: types.h:18
static int32_t pflash_program_array(FlashInfo *flash, uint32_t dest, uint32_t src)
signed long int32_t
Definition: types.h:19
#define CCLK
Definition: lpcSCB.h:93
unsigned char uint8_t
Definition: types.h:14
unsigned disableIRQ(void)
Definition: armVIC.c:33
#define IAP_ERASE_SECTORS
Definition: settings_arch.c:51
static uint32_t pflash_checksum(uint32_t ptr, uint32_t size)
Definition: settings_arch.c:83
static int32_t pflash_program_bytes(FlashInfo *flash, uint32_t src, uint32_t size, uint32_t chksum)
#define IAP_COPY_RAM_TO_FLASH
Definition: settings_arch.c:50
uint32_t page_size
Definition: settings_arch.c:68
#define FCHK
Definition: settings_arch.c:60
uint32_t total_size
Definition: settings_arch.c:66
int32_t persistent_write(uint32_t ptr, uint32_t size)
#define IAP_LOCATION
Definition: settings_arch.c:47