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