Paparazzi UAS  v5.18.0_stable
Paparazzi is a free software Unmanned Aircraft System.
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 {
86  uint32_t i, sum = 0;
87 
88  /* do it cheap for now */
89  for (i = 0; i < size; i++) {
90  sum += *(uint8_t *)(ptr + i);
91  }
92 
93  return sum;
94 }
95 
97 {
98  uint32_t command[5], result[3];
99  IAP iap_entry;
100 
101  iap_entry = (IAP) IAP_LOCATION;
102 
103  /* get part ID */
104  command[0] = IAP_READ_PART_ID;
105  disableIRQ();
106  iap_entry(command, result);
107  enableIRQ();
108  if (result[0] != 0) { return result[0]; }
109 
110  switch (result[1]) {
111  /* LPC2141, 32k Flash, 8k RAM */
112  case 0x0402FF01:
113  /* LPC2142, 64k Flash, 16k RAM */
114  case 0x0402FF11:
115  /* LPC2144, 128k Flash, 16k RAM */
116  case 0x0402FF12:
117  /* LPC2146, 256k Flash, 32k+8k RAM */
118  case 0x0402FF23: {
119  return -1;
120  break;
121  }
122  /* have LPC2148 support only */
123  /* LPC2148, 512k Flash, 32k+8k RAM */
124  case 0x0402FF25: {
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 {
138  uint32_t command[5], result[3];
139  IAP iap_entry;
140 
141  iap_entry = (IAP) IAP_LOCATION;
142 
143  /* prepare page/sector */
144  command[0] = IAP_PREPARE_SECTORS;
145  command[1] = flash->page_nr;
146  command[2] = flash->page_nr;
147  disableIRQ();
148  iap_entry(command, result);
149  enableIRQ();
150  if (result[0] != 0) { return result[0]; }
151 
152  /* erase page/sector */
153  command[0] = IAP_ERASE_SECTORS;
154  command[1] = flash->page_nr;
155  command[2] = flash->page_nr;
156  disableIRQ();
157  iap_entry(command, result);
158  enableIRQ();
159  if (result[0] != 0) { return result[0]; }
160 
161  /* verify erase */
162  command[0] = IAP_BLANK_CHECK_SECTORS;
163  command[1] = flash->page_nr;
164  command[2] = flash->page_nr;
165  iap_entry(command, result);
166  if (result[0] != 0) { return result[0]; }
167 
168  return 0;
169 }
170 
172  uint32_t dest,
173  uint32_t src)
174 {
175  uint32_t command[5], result[3];
176  IAP iap_entry;
177 
178  iap_entry = (IAP) IAP_LOCATION;
179 
180  /* prepare page/sector */
181  command[0] = IAP_PREPARE_SECTORS;
182  command[1] = flash->page_nr;
183  command[2] = flash->page_nr;
184  disableIRQ();
185  iap_entry(command, result);
186  enableIRQ();
187  if (result[0] != 0) { return result[0]; }
188 
189  /* flash from ram */
190  command[0] = IAP_COPY_RAM_TO_FLASH;
191  command[1] = dest;
192  command[2] = src;
193  command[3] = BOUND;
194  command[4] = CCLK / 1000;
195  disableIRQ();
196  iap_entry(command, result);
197  enableIRQ();
198  if (result[0] != 0) { return result[0]; }
199 
200  return 0;
201 }
202 
204  uint32_t src,
205  uint32_t size,
206  uint32_t chksum)
207 {
208  uint32_t data[BOUND / 4], i, j, ret;
209  uint32_t ptr = (uint32_t) &data;
210 
211  /* erase */
212  if ((ret = pflash_erase_page(flash))) { return ret; }
213 
214  /* write data in arrays */
215  for (i = 0; i < size; i += BOUND) {
216  /* copy data to aligned memory */
217  for (j = 0; j < BOUND; j++) {
218  *(uint8_t *)(ptr + j) = *(uint8_t *)(src + i + j);
219  }
220  if (i == flash->page_size - BOUND) {
221  data[(BOUND - FSIZ) / 4] = size;
222  data[(BOUND - FCHK) / 4] = chksum;
223  }
224  if ((ret = pflash_program_array(flash, flash->addr + i, ptr))) { return ret; }
225  }
226 
227  /* last array */
228  if (i <= flash->page_size - BOUND) {
229  data[(BOUND - FSIZ) / 4] = size;
230  data[(BOUND - FCHK) / 4] = chksum;
231  if ((ret = pflash_program_array(flash,
232  flash->addr + flash->page_size - BOUND,
233  ptr))) {
234  return ret;
235  }
236  }
237 
238  /* verify data */
239  for (i = 0; i < size; i++) {
240  if ((*(uint8_t *)(flash->addr + i)) != (*(uint8_t *)(src + i))) { return -2; }
241  }
242  if (*(uint32_t *)(flash->addr + flash->page_size - FSIZ) != size) { return -3; }
243  if (*(uint32_t *)(flash->addr + flash->page_size - FCHK) != chksum) { return -4; }
244 
245  return 0;
246 }
247 
249 {
250  FlashInfo flash_info;
251 
252  if (flash_detect(&flash_info)) { return -1; }
253  if ((size > flash_info.page_size - FSIZ) || (size == 0)) { return -2; }
254 
255  return pflash_program_bytes(&flash_info,
256  (uint32_t)ptr,
257  size,
258  pflash_checksum((uint32_t)ptr, size));
259 }
260 
262 {
263  FlashInfo flash;
264  uint32_t i;
265 
266  /* check parameters */
267  if (flash_detect(&flash)) { return -1; }
268  if ((size > flash.page_size - FSIZ) || (size == 0)) { return -2; }
269 
270  /* check consistency */
271  if (size != *(uint32_t *)(flash.addr + flash.page_size - FSIZ)) { return -3; }
272  if (pflash_checksum(flash.addr, size) !=
273  *(uint32_t *)(flash.addr + flash.page_size - FCHK)) {
274  return -4;
275  }
276 
277  /* copy data */
278  for (i = 0; i < size; i++) {
279  *(uint8_t *)((uint32_t)ptr + i) = *(uint8_t *)(flash.addr + i);
280  }
281 
282  return 0;
283 }
284 
286 {
287  FlashInfo flash;
288 
289  if (flash_detect(&flash)) { return -1; }
290 
291  return pflash_erase_page(&flash);
292 }
FlashInfo::page_size
uint32_t page_size
Definition: settings_arch.c:69
disableIRQ
unsigned disableIRQ(void)
Definition: armVIC.c:33
pflash_program_bytes
static int32_t pflash_program_bytes(FlashInfo *flash, uint32_t src, uint32_t size, uint32_t chksum)
Definition: settings_arch.c:203
pflash_program_array
static int32_t pflash_program_array(FlashInfo *flash, uint32_t dest, uint32_t src)
Definition: settings_arch.c:171
IAP_BLANK_CHECK_SECTORS
#define IAP_BLANK_CHECK_SECTORS
Definition: settings_arch.c:53
settings.h
armVIC.h
LPC21xx.h
IAP_ERASE_SECTORS
#define IAP_ERASE_SECTORS
Definition: settings_arch.c:52
uint32_t
unsigned long uint32_t
Definition: types.h:18
pflash_erase_page
static int32_t pflash_erase_page(FlashInfo *flash)
Definition: settings_arch.c:136
BOUND
#define BOUND
Definition: settings_arch.c:58
FSIZ
#define FSIZ
Definition: settings_arch.c:60
FlashInfo::addr
uint32_t addr
Definition: settings_arch.c:66
persistent_clear
int32_t persistent_clear(void)
Definition: settings_arch.c:74
persistent_write
int32_t persistent_write(void *ptr, uint32_t size)
Definition: settings_arch.c:33
uint8_t
unsigned char uint8_t
Definition: types.h:14
IAP_PREPARE_SECTORS
#define IAP_PREPARE_SECTORS
Definition: settings_arch.c:50
FlashInfo::page_nr
uint32_t page_nr
Definition: settings_arch.c:68
enableIRQ
unsigned enableIRQ(void)
Definition: armVIC.c:51
IAP
void(* IAP)(uint32_t[], uint32_t[])
Definition: settings_arch.c:63
IAP_COPY_RAM_TO_FLASH
#define IAP_COPY_RAM_TO_FLASH
Definition: settings_arch.c:51
int32_t
signed long int32_t
Definition: types.h:19
FCHK
#define FCHK
Definition: settings_arch.c:61
flash_detect
static int32_t flash_detect(FlashInfo *flash)
Definition: settings_arch.c:96
IAP_READ_PART_ID
#define IAP_READ_PART_ID
Definition: settings_arch.c:54
persistent_read
int32_t persistent_read(void *ptr, uint32_t size)
Definition: settings_arch.c:38
CCLK
#define CCLK
Definition: lpcSCB.h:93
FlashInfo::total_size
uint32_t total_size
Definition: settings_arch.c:67
IAP_LOCATION
#define IAP_LOCATION
Definition: settings_arch.c:48
pflash_checksum
static uint32_t pflash_checksum(uint32_t ptr, uint32_t size)
Definition: settings_arch.c:84
FlashInfo
Definition: settings_arch.c:65
dest
static uint8_t dest[]
Definition: w5100.c:99