Mercurial > public > ostc4
annotate Discovery/Src/externLogbookFlash.c @ 311:ddbe8bed5096 cleanup-4
bugfix: make stopwatch and divetime run in sync
And this shows the fundamental issue in the difference between dive time and
stopwatch time. The dive time is constructed on the RTE, and rather
independently, the stopwatch time is constructed on CPU1.
This works rather well, but not perfect. This commit fixes things in
a relatively straightforward way. Instead of incrementing the stopwatch
locally on CPU1, simply use the same time data that is coming from the
RTE. Some logic was added to make this stopwatch resettable again.
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
author | Jan Mulder <jlmulder@xs4all.nl> |
---|---|
date | Wed, 29 May 2019 14:02:27 +0200 |
parents | c7e665e0b08f |
children | 2174fb133dbe |
rev | line source |
---|---|
38 | 1 /** |
2 ****************************************************************************** | |
3 * @copyright heinrichs weikamp | |
4 * @file externLogbookFlash.c | |
5 * @author heinrichs weikamp gmbh | |
6 * @date 07-Aug-2014 | |
7 * @version V0.0.4 | |
8 * @since 29-Sept-2015 | |
9 * @brief Main File to access the new 1.8 Volt Spansion S25FS256S 256 Mbit (32 Mbyte) | |
10 * @bug | |
11 * @warning | |
12 * | |
13 @verbatim | |
14 ============================================================================== | |
15 ##### Logbook Header (TOC) ##### | |
16 ============================================================================== | |
17 [..] Memory useage: | |
18 NEW: Spansion S25FS-S256S | |
19 | |
20 only 8x 4KB and 1x 32KB, remaining is 64KB or 256KB | |
21 Sector Size (kbyte) Sector Count Sector Range Address Range (Byte Address) Notes | |
22 4 8 SA00 00000000h-00000FFFh | |
23 : : | |
24 SA07 00007000h-00007FFFh | |
25 | |
26 32 1 SA08 00008000h-0000FFFFh | |
27 | |
28 64 511 SA09 00010000h-0001FFFFh | |
29 : : | |
30 SA519 01FF0000h-01FFFFFFh | |
31 OLD: | |
32 1kB each header | |
33 with predive header at beginning | |
34 and postdive header with 0x400 HEADER2OFFSET | |
35 4kB (one erase) has two dives with 4 headers total | |
36 total of 512 kB (with 256 header ids (8 bit)) | |
37 Size is 280 Byte (as of 25.Nov. 2014) | |
38 | |
39 [..] Output to PC / UART is postdive header | |
40 | |
41 [..] Block Protection Lock-Down is to erase logbook only | |
42 | |
43 [..] Timing (see page 137 of LOGBOOK_V3_S25FS-S_00-271247.pdf | |
44 bulk erase is 2 minutes typ., 6 minutes max. | |
45 | |
46 ============================================================================== | |
47 ##### DEMOMODE ##### | |
48 ============================================================================== | |
49 151215: ext_flash_write_settings() is DISABLED! | |
50 | |
51 ============================================================================== | |
52 ##### bug fixes ##### | |
53 ============================================================================== | |
54 150917: end in header and length of sample was one byte too long | |
55 as stated by Jef Driesen email 15.09.2015 | |
56 | |
57 @endverbatim | |
58 ****************************************************************************** | |
59 * @attention | |
60 * | |
61 * <h2><center>© COPYRIGHT(c) 2015 heinrichs weikamp</center></h2> | |
62 * | |
63 ****************************************************************************** | |
64 */ | |
65 | |
66 /* Includes ------------------------------------------------------------------*/ | |
67 #include "stm32f4xx_hal.h" | |
68 #include "externLogbookFlash.h" | |
69 #include "ostc.h" | |
70 #include "settings.h" | |
71 #include "gfx_engine.h" | |
72 | |
73 #ifndef BOOTLOADER_STANDALONE | |
74 #include "logbook.h" | |
75 #endif | |
76 | |
77 /* Private types -------------------------------------------------------------*/ | |
78 #define FLASHSTART 0x000000 | |
79 //#define FLASHSTOP 0x01FFFFFF all 32 MB with 4byte addressing | |
80 #define FLASHSTOP 0x00FFFFFF | |
81 //#define FLASHSTOP 0x3FFFFF | |
82 #define RELEASE 1 | |
83 #define HOLDCS 0 | |
84 | |
85 #define HEADER2OFFSET 0x400 | |
86 | |
87 typedef enum{ | |
88 EF_HEADER, | |
89 EF_SAMPLE, | |
90 EF_DEVICEDATA, | |
91 EF_VPMDATA, | |
92 EF_SETTINGS, | |
93 EF_FIRMWARE, | |
94 EF_FIRMWARE2, | |
95 }which_ring_enum; | |
96 | |
97 | |
98 typedef struct{ | |
99 uint8_t IsBusy:1; | |
100 uint8_t IsWriteEnabled:1; | |
101 uint8_t BlockProtect0:1; | |
102 uint8_t BlockProtect1:1; | |
103 uint8_t BlockProtect2:1; | |
104 uint8_t BlockProtect3:1; | |
105 uint8_t IsAutoAddressIncMode:1; | |
106 uint8_t BlockProtectL:1; | |
107 } extFlashStatusUbit8_t; | |
108 | |
109 typedef union{ | |
110 extFlashStatusUbit8_t ub; | |
111 uint8_t uw; | |
112 } extFlashStatusBit8_Type; | |
113 | |
114 | |
115 /* Exported variables --------------------------------------------------------*/ | |
116 | |
117 /* Private variables ---------------------------------------------------------*/ | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
118 static uint32_t actualAddress = 0; |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
119 static uint32_t entryPoint = 0; |
38 | 120 |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
121 static uint32_t actualPointerHeader = 0; |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
122 static uint32_t actualPointerSample = 0; |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
123 static uint32_t LengthLeftSampleRead = 0; |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
124 static uint32_t actualPointerDevicedata = 0; |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
125 static uint32_t actualPointerVPM = 0; |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
126 static uint32_t actualPointerSettings = 0; |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
127 static uint32_t actualPointerFirmware = 0; |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
128 static uint32_t actualPointerFirmware2 = 0; |
38 | 129 |
130 /* Private function prototypes -----------------------------------------------*/ | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
131 static void chip_unselect(void); |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
132 static void chip_select(void); |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
133 static void error_led_on(void); |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
134 static void error_led_off(void); |
38 | 135 |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
136 static void write_spi(uint8_t data, uint8_t unselect_CS_afterwards); |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
137 static uint8_t read_spi(uint8_t unselect_CS_afterwards); |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
138 static void write_address(uint8_t unselect_CS_afterwards); |
38 | 139 static void Error_Handler_extflash(void); |
140 static void wait_chip_not_busy(void); | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
141 static void ext_flash_incf_address(uint8_t type); |
38 | 142 //void ext_flash_incf_address_ring(void); |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
143 static void ext_flash_decf_address_ring(uint8_t type); |
38 | 144 |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
145 static void ext_flash_erase4kB(void); |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
146 static void ext_flash_erase32kB(void); |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
147 static void ext_flash_erase64kB(void); |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
148 static uint8_t ext_flash_erase_if_on_page_start(void); |
38 | 149 |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
150 static void ef_write_block(uint8_t * sendByte, uint32_t length, uint8_t type, uint8_t do_not_erase); |
38 | 151 |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
152 static void ext_flash_read_block(uint8_t *getByte, uint8_t type); |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
153 static void ext_flash_read_block_multi(void *getByte, uint32_t size, uint8_t type); |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
154 static void ext_flash_read_block_stop(void); |
38 | 155 |
156 static void ef_hw_rough_delay_us(uint32_t delayUs); | |
157 static void ef_erase_64K(uint32_t blocks); | |
158 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
159 static void ext_flash_overwrite_sample_without_erase(uint8_t *pSample, uint16_t length); |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
160 |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
161 static void ext_flash_disable_protection(void); |
38 | 162 |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
163 static _Bool ext_flash_test_remaining_space_of_page_empty(uint32_t pointer, uint16_t length); |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
164 static void ext_flash_set_to_begin_of_next_page(uint32_t *pointer, uint8_t type); |
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
165 static void ext_flash_find_start(void); |
38 | 166 |
167 | |
168 /* Exported functions --------------------------------------------------------*/ | |
169 | |
170 void ext_flash_write_firmware(uint8_t *pSample1, uint32_t length1)//, uint8_t *pSample2, uint32_t length2) | |
171 { | |
172 general32to8_Type lengthTransform; | |
173 | |
174 lengthTransform.u32 = length1; | |
175 | |
176 actualPointerFirmware = FWSTART; | |
177 ef_write_block(lengthTransform.u8,4, EF_FIRMWARE, 1); | |
178 ef_write_block(pSample1,length1, EF_FIRMWARE, 1); | |
179 | |
180 // if(length2) | |
181 // ef_write_block(pSample2,length2, EF_FIRMWARE, 1); | |
182 } | |
183 | |
184 uint8_t ext_flash_read_firmware_version(char *text) | |
185 { | |
186 uint32_t backup = actualAddress; | |
187 uint8_t buffer[4]; | |
188 | |
189 // + 4 for length data, see ext_flash_write_firmware | |
190 actualAddress = FWSTART + 4 + 0x10000; | |
191 ext_flash_read_block_start(); | |
192 ext_flash_read_block(&buffer[0], EF_FIRMWARE); | |
193 ext_flash_read_block(&buffer[1], EF_FIRMWARE); | |
194 ext_flash_read_block(&buffer[2], EF_FIRMWARE); | |
195 ext_flash_read_block(&buffer[3], EF_FIRMWARE); | |
196 | |
197 ext_flash_read_block_stop(); | |
198 actualAddress = backup; | |
199 | |
200 uint8_t ptr = 0; | |
201 text[ptr++] = 'V'; | |
202 ptr += gfx_number_to_string(2,0,&text[ptr],buffer[0] & 0x3F); | |
203 text[ptr++] = '.'; | |
204 ptr += gfx_number_to_string(2,0,&text[ptr],buffer[1] & 0x3F); | |
205 text[ptr++] = '.'; | |
206 ptr += gfx_number_to_string(2,0,&text[ptr],buffer[2] & 0x3F); | |
207 text[ptr++] = ' '; | |
208 if(buffer[3]) | |
209 { | |
210 text[ptr++] = 'b'; | |
211 text[ptr++] = 'e'; | |
212 text[ptr++] = 't'; | |
213 text[ptr++] = 'a'; | |
214 text[ptr++] = ' '; | |
215 } | |
216 return ptr; | |
217 } | |
218 | |
219 | |
220 uint32_t ext_flash_read_firmware(uint8_t *pSample1, uint32_t max_length, uint8_t *magicByte) | |
221 { | |
222 uint32_t backup = actualAddress; | |
223 general32to8_Type lengthTransform; | |
224 | |
225 actualAddress = FWSTART; | |
226 ext_flash_read_block_start(); | |
227 | |
228 ext_flash_read_block(&lengthTransform.u8[0], EF_FIRMWARE); | |
229 ext_flash_read_block(&lengthTransform.u8[1], EF_FIRMWARE); | |
230 ext_flash_read_block(&lengthTransform.u8[2], EF_FIRMWARE); | |
231 ext_flash_read_block(&lengthTransform.u8[3], EF_FIRMWARE); | |
232 | |
233 | |
234 if(lengthTransform.u32 == 0xFFFFFFFF) | |
235 { | |
236 lengthTransform.u32 = 0xFFFFFFFF; | |
237 } | |
238 else | |
239 if(lengthTransform.u32 > max_length) | |
240 { | |
241 lengthTransform.u32 = 0xFF000000; | |
242 } | |
243 else | |
244 { | |
245 for(uint32_t i = 0; i<lengthTransform.u32; i++) | |
246 { | |
247 ext_flash_read_block(&pSample1[i], EF_FIRMWARE); | |
248 } | |
249 | |
250 } | |
251 | |
252 ext_flash_read_block_stop(); | |
253 | |
254 if(magicByte) | |
255 { | |
256 *magicByte = pSample1[0x10000 + 0x3E]; // 0x3E == 62 | |
257 } | |
258 | |
259 actualAddress = backup; | |
260 return lengthTransform.u32; | |
261 } | |
262 | |
263 | |
264 void ext_flash_write_firmware2(uint32_t offset, uint8_t *pSample1, uint32_t length1, uint8_t *pSample2, uint32_t length2) | |
265 { | |
266 general32to8_Type lengthTransform, offsetTransform; | |
267 | |
268 lengthTransform.u32 = length1 + length2; | |
269 offsetTransform.u32 = offset; | |
270 | |
271 actualPointerFirmware2 = FWSTART2; | |
272 ef_write_block(lengthTransform.u8,4, EF_FIRMWARE2, 1); | |
273 ef_write_block(offsetTransform.u8,4, EF_FIRMWARE2, 1); | |
274 ef_write_block(pSample1,length1, EF_FIRMWARE2, 1); | |
275 if(length2) | |
276 ef_write_block(pSample2,length2, EF_FIRMWARE2, 1); | |
277 } | |
278 | |
279 | |
280 uint32_t ext_flash_read_firmware2(uint32_t *offset, uint8_t *pSample1, uint32_t max_length1, uint8_t *pSample2, uint32_t max_length2) | |
281 { | |
282 uint32_t backup = actualAddress; | |
283 uint32_t length1, length2; | |
284 general32to8_Type lengthTransform, offsetTransform; | |
285 | |
286 actualAddress = FWSTART2; | |
287 ext_flash_read_block_start(); | |
288 | |
289 ext_flash_read_block(&lengthTransform.u8[0], EF_FIRMWARE2); | |
290 ext_flash_read_block(&lengthTransform.u8[1], EF_FIRMWARE2); | |
291 ext_flash_read_block(&lengthTransform.u8[2], EF_FIRMWARE2); | |
292 ext_flash_read_block(&lengthTransform.u8[3], EF_FIRMWARE2); | |
293 | |
294 ext_flash_read_block(&offsetTransform.u8[0], EF_FIRMWARE2); | |
295 ext_flash_read_block(&offsetTransform.u8[1], EF_FIRMWARE2); | |
296 ext_flash_read_block(&offsetTransform.u8[2], EF_FIRMWARE2); | |
297 ext_flash_read_block(&offsetTransform.u8[3], EF_FIRMWARE2); | |
298 | |
299 *offset = offsetTransform.u32; | |
300 | |
301 if(lengthTransform.u32 == 0xFFFFFFFF) | |
302 { | |
303 lengthTransform.u32 = 0xFFFFFFFF; | |
304 } | |
305 else | |
306 if(lengthTransform.u32 > max_length1 + max_length2) | |
307 { | |
308 lengthTransform.u32 = 0xFF000000; | |
309 } | |
310 else | |
311 { | |
312 if(lengthTransform.u32 < max_length1) | |
313 { | |
314 length1 = lengthTransform.u32; | |
315 length2 = 0; | |
316 } | |
317 else | |
318 { | |
319 length1 = max_length1; | |
320 length2 = lengthTransform.u32 - max_length1; | |
321 } | |
322 | |
323 if(pSample1) | |
324 { | |
325 for(uint32_t i = 0; i<length1; i++) | |
326 { | |
327 ext_flash_read_block(&pSample1[i], EF_FIRMWARE2); | |
328 } | |
329 if(pSample2) | |
330 { | |
331 for(uint32_t i = 0; i<length2; i++) | |
332 { | |
333 ext_flash_read_block(&pSample2[i], EF_FIRMWARE2); | |
334 } | |
335 } | |
336 } | |
337 else if(pSample2) | |
338 { | |
339 actualAddress += length1; | |
340 for(uint32_t i = 0; i<length2; i++) | |
341 { | |
342 ext_flash_read_block(&pSample2[i], EF_FIRMWARE2); | |
343 } | |
344 } | |
345 } | |
346 ext_flash_read_block_stop(); | |
347 actualAddress = backup; | |
348 return lengthTransform.u32; | |
349 } | |
350 | |
351 | |
352 void ext_flash_read_fixed_16_devicedata_blocks_formated_128byte_total(uint8_t *buffer) | |
353 { | |
354 SDeviceLine data[16]; | |
355 uint8_t tempLengthIngnore; | |
356 uint16_t count; | |
357 uint8_t transfer; | |
358 | |
359 RTC_DateTypeDef Sdate; | |
360 RTC_TimeTypeDef Stime; | |
361 | |
362 actualAddress = DDSTART; | |
363 | |
364 ext_flash_read_block_start(); | |
365 ext_flash_read_block(&tempLengthIngnore, EF_DEVICEDATA); | |
366 ext_flash_read_block(&tempLengthIngnore, EF_DEVICEDATA); | |
367 | |
368 ext_flash_read_block_multi((uint8_t *)data,16*3*4, EF_DEVICEDATA); | |
369 ext_flash_read_block_stop(); | |
370 | |
371 count = 0; | |
372 for(int i=0;i<16;i++) | |
373 { | |
374 transfer = (data[i].value_int32 >> 24) & 0xFF; | |
375 buffer[count++] = transfer; | |
376 transfer = (data[i].value_int32 >> 16) & 0xFF; | |
377 buffer[count++] = transfer; | |
378 transfer = (data[i].value_int32 >> 8) & 0xFF; | |
379 buffer[count++] = transfer; | |
380 transfer = (data[i].value_int32) & 0xFF; | |
381 buffer[count++] = transfer; | |
382 | |
383 translateDate(data[i].date_rtc_dr, &Sdate); | |
384 translateTime(data[i].time_rtc_tr, &Stime); | |
385 buffer[count++] = Sdate.Year; | |
386 buffer[count++] = Sdate.Month; | |
387 buffer[count++] = Sdate.Date; | |
388 buffer[count++] = Stime.Hours; | |
389 } | |
390 } | |
391 | |
392 | |
393 #ifndef BOOTLOADER_STANDALONE | |
394 | |
395 void ext_flash_write_devicedata(void) | |
396 { | |
397 uint8_t *pData; | |
398 const uint16_t length = sizeof(SDevice); | |
399 uint8_t length_lo, length_hi; | |
400 uint8_t dataLength[2] = { 0 }; | |
401 | |
402 ext_flash_disable_protection(); | |
403 | |
404 pData = (uint8_t *)stateDeviceGetPointer(); | |
405 | |
406 actualPointerDevicedata = DDSTART; | |
407 | |
408 length_lo = (uint8_t)(length & 0xFF); | |
409 length_hi = (uint8_t)(length >> 8); | |
410 dataLength[0] = length_lo; | |
411 dataLength[1] = length_hi; | |
412 | |
413 ef_write_block(dataLength,2, EF_DEVICEDATA, 0); | |
414 ef_write_block(pData,length, EF_DEVICEDATA, 0); | |
415 } | |
416 | |
417 | |
418 uint16_t ext_flash_read_devicedata(uint8_t *buffer, uint16_t max_length) | |
419 { | |
420 uint16_t length; | |
421 uint8_t length_lo, length_hi; | |
422 | |
423 actualAddress = DDSTART; | |
424 | |
425 ext_flash_read_block_start(); | |
426 ext_flash_read_block(&length_lo, EF_DEVICEDATA); | |
427 ext_flash_read_block(&length_hi, EF_DEVICEDATA); | |
428 | |
429 length = (length_hi * 256) + length_lo; | |
430 | |
431 if(length > max_length) | |
432 return 0; | |
433 | |
434 ext_flash_read_block_multi(buffer,length,EF_DEVICEDATA); | |
435 ext_flash_read_block_stop(); | |
436 | |
437 return length; | |
438 } | |
439 | |
440 | |
441 void ext_flash_write_vpm(SVpm *vpmInput) | |
442 { | |
443 uint8_t *pData; | |
444 const uint16_t length = sizeof(SVpm); | |
445 | |
446 uint8_t length_lo, length_hi; | |
447 uint8_t dataLength[2] = { 0 }; | |
448 | |
449 pData = (uint8_t *)vpmInput; | |
450 | |
451 actualPointerVPM = VPMSTART; | |
452 | |
453 length_lo = (uint8_t)(length & 0xFF); | |
454 length_hi = (uint8_t)(length >> 8); | |
455 dataLength[0] = length_lo; | |
456 dataLength[1] = length_hi; | |
457 | |
458 ef_write_block(dataLength,2, EF_VPMDATA, 0); | |
459 ef_write_block(pData,length, EF_VPMDATA, 0); | |
460 } | |
461 | |
462 | |
463 int ext_flash_read_vpm(SVpm *vpmOutput) | |
464 { | |
465 uint8_t *pData; | |
466 const uint16_t length = sizeof(SVpm); | |
467 uint8_t length_lo, length_hi; | |
468 int output; | |
469 | |
470 actualAddress = VPMSTART; | |
471 | |
472 ext_flash_read_block_start(); | |
473 ext_flash_read_block(&length_lo, EF_VPMDATA); | |
474 ext_flash_read_block(&length_hi, EF_VPMDATA); | |
475 if((length_lo == (uint8_t)(length & 0xFF)) | |
476 &&(length_hi == (uint8_t)(length >> 8))) | |
477 { | |
478 pData = (uint8_t *)vpmOutput; | |
479 for(uint16_t i = 0; i < length; i++) | |
480 ext_flash_read_block(&pData[i], EF_VPMDATA); | |
481 output = length; | |
482 } | |
483 else | |
484 output = 0; | |
485 | |
486 ext_flash_read_block_stop(); | |
487 return output; | |
488 } | |
489 | |
490 #ifdef DEMOMODE | |
491 void ext_flash_write_settings(void) | |
492 { | |
493 return; | |
494 } | |
495 #else | |
496 void ext_flash_write_settings(void) | |
497 { | |
498 uint8_t *pData; | |
499 const uint16_t length = sizeof(SSettings); | |
500 uint8_t length_lo, length_hi; | |
501 uint8_t dataLength[2] = { 0 }; | |
502 | |
503 ext_flash_disable_protection(); | |
504 | |
505 if(stateRealGetPointer()->lastKnownBatteryPercentage) | |
506 { | |
507 settingsGetPointer()->lastKnownBatteryPercentage = stateRealGetPointer()->lastKnownBatteryPercentage; | |
508 } | |
509 settingsGetPointer()->backup_localtime_rtc_tr = stateRealGetPointer()->lifeData.timeBinaryFormat; | |
510 settingsGetPointer()->backup_localtime_rtc_dr = stateRealGetPointer()->lifeData.dateBinaryFormat; | |
511 | |
512 pData = (uint8_t *)settingsGetPointer(); | |
513 | |
514 actualPointerSettings = SETTINGSSTART; | |
515 | |
516 length_lo = (uint8_t)(length & 0xFF); | |
517 length_hi = (uint8_t)(length >> 8); | |
518 dataLength[0] = length_lo; | |
519 dataLength[1] = length_hi; | |
520 | |
521 ef_write_block(dataLength,2, EF_SETTINGS, 0); | |
522 ef_write_block(pData,length, EF_SETTINGS, 0); | |
523 // ext_flash_enable_protection(); | |
524 } | |
525 #endif | |
526 | |
527 | |
528 /* CHANGES 150929 hw | |
529 * this now allows to read old settings too | |
530 * but make sure that everything is fixed in | |
531 * set_new_settings_missing_in_ext_flash | |
532 * new settings should be fine as they are added | |
533 * and loaded before calling this function | |
534 */ | |
535 uint8_t ext_flash_read_settings(void) | |
536 { | |
537 uint8_t returnValue = HAL_BUSY; | |
538 uint8_t *pData; | |
539 const uint16_t lengthStandardNow = sizeof(SSettings); | |
540 uint8_t length_lo, length_hi; | |
541 uint16_t lengthOnEEPROM; | |
542 uint32_t header; | |
543 SSettings *pSettings = settingsGetPointer(); | |
544 | |
545 actualAddress = SETTINGSSTART; | |
546 | |
547 ext_flash_read_block_start(); | |
548 ext_flash_read_block(&length_lo, EF_SETTINGS); | |
549 ext_flash_read_block(&length_hi, EF_SETTINGS); | |
550 | |
551 lengthOnEEPROM = length_hi * 256; | |
552 lengthOnEEPROM += length_lo; | |
553 if(lengthOnEEPROM <= lengthStandardNow) | |
554 { | |
555 ext_flash_read_block_multi(&header, 4, EF_SETTINGS); | |
556 if((header <= pSettings->header) && (header >= pSettings->updateSettingsAllowedFromHeader)) | |
557 { | |
558 returnValue = HAL_OK; | |
559 pSettings->header = header; | |
560 pData = (uint8_t *)pSettings + 4; /* header */ | |
561 for(uint16_t i = 0; i < (lengthOnEEPROM-4); i++) | |
562 ext_flash_read_block(&pData[i], EF_SETTINGS); | |
563 } | |
564 else | |
565 { | |
566 returnValue = HAL_ERROR; | |
567 } | |
568 } | |
569 ext_flash_read_block_stop(); | |
570 return returnValue; | |
571 } | |
572 | |
573 | |
574 | |
575 | |
576 /* ext_flash_start_new_dive_log_and_set_actualPointerSample | |
577 * prepares the write sample pointer | |
578 * to be used by ext_flash_write_sample() | |
579 * to be set in the * pHeaderPreDive | |
580 * for write with ext_flash_create_new_dive_log() and ext_flash_close_new_dive_log() | |
581 */ | |
582 void ext_flash_start_new_dive_log_and_set_actualPointerSample(uint8_t *pHeaderPreDive) | |
583 { | |
584 convert_Type data; | |
585 SSettings *settings = settingsGetPointer(); | |
586 | |
587 /* new 5. Jan. 2015 */ | |
588 actualPointerSample = settings->logFlashNextSampleStartAddress; | |
589 | |
590 if(!ext_flash_test_remaining_space_of_page_empty(actualPointerSample, 4)) | |
591 ext_flash_set_to_begin_of_next_page(&actualPointerSample, EF_SAMPLE); | |
592 | |
593 if((actualPointerSample < SAMPLESTART) || (actualPointerSample > SAMPLESTOP)) | |
594 actualPointerSample = SAMPLESTART; | |
595 | |
596 data.u32bit = actualPointerSample; | |
597 pHeaderPreDive[2] = data.u8bit.byteLow; | |
598 pHeaderPreDive[3] = data.u8bit.byteMidLow; | |
599 pHeaderPreDive[4] = data.u8bit.byteMidHigh; | |
600 /* to start sample writing and header etc. pp. */ | |
601 ext_flash_disable_protection_for_logbook(); | |
602 } | |
603 | |
604 | |
605 /* ext_flash_create_new_dive_log | |
606 * uses the first header without HEADER2OFFSET | |
607 * for the header it is not important to be complete | |
608 * and can be reconstructed | |
609 * ext_flash_start_new_dive_log_and_set_actualPointerSample() | |
610 * has to be called before to set the actualPointerSample | |
611 * in the header | |
612 * the following func writes to header to the ext_flash | |
613 */ | |
614 void ext_flash_create_new_dive_log(uint8_t *pHeaderPreDive) | |
615 { | |
616 SSettings *settings; | |
617 uint8_t id, id_next; | |
618 uint8_t header1, header2; | |
619 | |
620 settings = settingsGetPointer(); | |
621 id = settings->lastDiveLogId; | |
622 | |
623 actualAddress = HEADERSTART + (0x800 * id); | |
624 ext_flash_read_block_start(); | |
625 ext_flash_read_block(&header1, EF_SAMPLE); | |
626 ext_flash_read_block(&header2, EF_SAMPLE); | |
627 ext_flash_read_block_stop(); | |
628 | |
629 if((header1 == 0xFA) && (header2 == 0xFA)) | |
630 { | |
631 id += 1; /* 0-255, auto rollover */ | |
632 if(id & 1) | |
633 { | |
634 actualAddress = HEADERSTART + (0x800 * id); | |
635 ext_flash_read_block_start(); | |
636 ext_flash_read_block(&header1, EF_SAMPLE); | |
637 ext_flash_read_block(&header2, EF_SAMPLE); | |
638 ext_flash_read_block_stop(); | |
639 if((header1 == 0xFA) && (header2 == 0xFA)) | |
640 id += 1; | |
641 } | |
642 } | |
643 else | |
644 { | |
645 id = 0; | |
646 } | |
647 | |
648 /* delete next header */ | |
649 id_next = id + 1; | |
650 actualPointerHeader = HEADERSTART + (0x800 * id_next); | |
651 ef_write_block(0,0, EF_HEADER, 0); | |
652 | |
653 settings->lastDiveLogId = id; | |
654 actualPointerHeader = HEADERSTART + (0x800 * id); | |
655 | |
656 if(pHeaderPreDive != 0) | |
657 ef_write_block(pHeaderPreDive,HEADERSIZE, EF_HEADER, 0); | |
658 } | |
659 | |
660 | |
661 void ext_flash_close_new_dive_log(uint8_t *pHeaderPostDive ) | |
662 { | |
663 SSettings * settings = settingsGetPointer(); | |
664 uint8_t id; | |
665 convert_Type startAddress; | |
666 convert_Type data; | |
667 uint32_t backup; | |
668 | |
669 uint8_t sampleData[3]; | |
670 actualAddress = actualPointerSample; | |
671 sampleData[0] = 0xFD; | |
672 sampleData[1] = 0xFD; | |
673 ext_flash_write_sample(sampleData, 2); | |
674 | |
675 /* end of sample data, pointing to the last sample 0xFD | |
676 */ | |
677 actualAddress = actualPointerSample; // change hw 17.09.2015 | |
678 ext_flash_decf_address_ring(EF_SAMPLE); // 17.09.2015: this decf actualAddress only!! | |
679 actualPointerSample = actualAddress; // change hw 17.09.2015 | |
680 data.u32bit = actualPointerSample; | |
681 | |
682 pHeaderPostDive[5] = data.u8bit.byteLow; | |
683 pHeaderPostDive[6] = data.u8bit.byteMidLow; | |
684 pHeaderPostDive[7] = data.u8bit.byteMidHigh; | |
685 | |
686 /* take data written before, calculate length and write | |
687 SLogbookHeader has different order: length (byte# 8,9,10) prior to profile version (byte# 11) | |
688 */ | |
689 startAddress.u8bit.byteLow = pHeaderPostDive[2]; | |
690 startAddress.u8bit.byteMidLow = pHeaderPostDive[3]; | |
691 startAddress.u8bit.byteMidHigh = pHeaderPostDive[4]; | |
692 startAddress.u8bit.byteHigh = 0; | |
693 | |
694 if(startAddress.u32bit < actualPointerSample) | |
695 data.u32bit = 1 + actualPointerSample - startAddress.u32bit; | |
696 else | |
697 data.u32bit = 2 + (actualPointerSample - SAMPLESTART) + (SAMPLESTOP - startAddress.u32bit); | |
698 | |
699 pHeaderPostDive[8] = data.u8bit.byteLow; | |
700 pHeaderPostDive[9] = data.u8bit.byteMidLow; | |
701 pHeaderPostDive[10] = data.u8bit.byteMidHigh; | |
702 | |
703 /* set id and write post-dive-header | |
704 */ | |
705 id = settings->lastDiveLogId; | |
706 actualPointerHeader = HEADERSTART + (0x800 * id) + HEADER2OFFSET; | |
707 | |
708 ef_write_block(pHeaderPostDive,HEADERSIZE, EF_HEADER, 0); | |
709 | |
710 /* write length at beginning of sample | |
711 and write proper beginning for next dive to actualPointerSample | |
712 */ | |
713 backup = actualPointerSample; | |
714 actualPointerSample = startAddress.u32bit; // is still 0xFF | |
715 sampleData[0] = data.u8bit.byteLow; | |
716 sampleData[1] = data.u8bit.byteMidLow; | |
717 sampleData[2] = data.u8bit.byteMidHigh; | |
718 ext_flash_overwrite_sample_without_erase(sampleData, 3); | |
719 | |
720 actualAddress = backup; | |
721 ext_flash_incf_address(EF_SAMPLE); | |
722 actualPointerSample = actualAddress; | |
723 ext_flash_enable_protection(); | |
724 } | |
725 | |
726 | |
727 void ext_flash_write_sample(uint8_t *pSample, uint16_t length) | |
728 { | |
729 ef_write_block(pSample,length, EF_SAMPLE, 0); | |
730 | |
731 SSettings *settings = settingsGetPointer(); | |
732 settings->logFlashNextSampleStartAddress = actualPointerSample; | |
733 } | |
734 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
735 static void ext_flash_overwrite_sample_without_erase(uint8_t *pSample, uint16_t length) |
38 | 736 { |
737 ef_write_block(pSample,length, EF_SAMPLE, 1); | |
738 } | |
739 | |
740 | |
741 uint8_t ext_flash_count_dive_headers(void) | |
742 { | |
743 uint8_t id = 0; | |
744 uint8_t counter = 0; | |
745 uint16_t headerStartData = 0x0000; | |
746 | |
747 id = settingsGetPointer()->lastDiveLogId; | |
748 | |
749 do | |
750 { | |
751 actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET; | |
752 ext_flash_read_block_start(); | |
753 ext_flash_read_block_multi((uint8_t *)&headerStartData, 2, EF_HEADER); | |
754 ext_flash_read_block_stop(); | |
755 counter++; | |
756 id -=1; | |
757 } while((headerStartData == 0xFAFA) && (counter < 255)); | |
758 return (counter - 1); | |
759 } | |
760 | |
761 | |
762 void ext_flash_read_dive_header(uint8_t *pHeaderToFill, uint8_t StepBackwards) | |
763 { | |
764 SSettings *settings; | |
765 uint8_t id; | |
766 uint16_t i; | |
767 | |
768 settings = settingsGetPointer(); | |
769 id = settings->lastDiveLogId; | |
770 id -= StepBackwards; /* 0-255, auto rollover */ | |
771 | |
772 actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET; | |
773 ext_flash_read_block_start(); | |
774 for(i = 0; i < HEADERSIZE; i++) | |
775 ext_flash_read_block(&pHeaderToFill[i], EF_HEADER); | |
776 ext_flash_read_block_stop(); | |
777 | |
778 } | |
779 | |
780 void ext_flash_read_dive_header2(uint8_t *pHeaderToFill, uint8_t id, _Bool bOffset) | |
781 { | |
782 | |
783 uint16_t i; | |
784 actualAddress = HEADERSTART + (0x800 * id) ; | |
785 | |
786 if(bOffset) | |
787 actualAddress += HEADER2OFFSET; | |
788 ext_flash_read_block_start(); | |
789 for(i = 0; i < HEADERSIZE; i++) | |
790 ext_flash_read_block(&pHeaderToFill[i], EF_HEADER); | |
791 ext_flash_read_block_stop(); | |
792 } | |
793 | |
794 | |
795 uint32_t ext_flash_read_dive_raw_with_double_header_1K(uint8_t *data, uint32_t max_size, uint8_t StepBackwards) | |
796 { | |
797 if(max_size < 0x800) | |
798 return 0; | |
799 | |
800 uint8_t id; | |
801 convert_Type dataStart, dataEnd; | |
802 uint32_t LengthAll = 0; | |
803 | |
804 id = settingsGetPointer()->lastDiveLogId; | |
805 id -= StepBackwards; /* 0-255, auto rollover */ | |
806 | |
807 // clear data | |
808 for(int i=0;i<0x800;i++) | |
809 data[i] = 0xFF; | |
810 | |
811 // copy primary/pre-dive | |
812 actualAddress = HEADERSTART + (0x800 * id); | |
813 ext_flash_read_block_start(); | |
814 for(int i = 0; i < HEADERSIZE; i++) | |
815 ext_flash_read_block(&data[i], EF_HEADER); | |
816 ext_flash_read_block_stop(); | |
817 | |
818 // copy main/secondary/post-dive | |
819 actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET; | |
820 ext_flash_read_block_start(); | |
821 for(int i = 0x400; i < HEADERSIZE+0x400; i++) | |
822 ext_flash_read_block(&data[i], EF_HEADER); | |
823 ext_flash_read_block_stop(); | |
824 | |
825 // data | |
826 | |
827 dataStart.u8bit.byteHigh = 0; | |
828 dataStart.u8bit.byteLow = data[0x402]; | |
829 dataStart.u8bit.byteMidLow = data[0x403]; | |
830 dataStart.u8bit.byteMidHigh = data[0x404]; | |
831 | |
832 dataEnd.u8bit.byteHigh = 0; | |
833 dataEnd.u8bit.byteLow = data[0x405]; | |
834 dataEnd.u8bit.byteMidLow = data[0x406]; | |
835 dataEnd.u8bit.byteMidHigh = data[0x407]; | |
836 | |
837 actualPointerSample = dataStart.u32bit; | |
838 if(dataEnd.u32bit >= dataStart.u32bit) | |
839 LengthAll = 1 + dataEnd.u32bit - dataStart.u32bit; | |
840 else | |
841 LengthAll = 2 + (dataStart.u32bit - SAMPLESTART) + (SAMPLESTOP - dataEnd.u32bit); | |
842 | |
843 LengthAll += 0x800; | |
844 | |
845 if(LengthAll > max_size) | |
846 return 0x800; | |
847 | |
848 actualAddress = actualPointerSample; | |
849 ext_flash_read_block_start(); | |
850 for(uint32_t i = 0x800; i < LengthAll; i++) | |
851 ext_flash_read_block(&data[i], EF_SAMPLE); | |
852 ext_flash_read_block_stop(); | |
853 return LengthAll; | |
854 } | |
855 | |
856 void ext_flash_write_dive_raw_with_double_header_1K(uint8_t *data, uint32_t length) | |
857 { | |
858 convert_Type dataStart, dataEnd; | |
859 SLogbookHeader headerTemp; | |
860 | |
861 // set actualPointerSample and get pointer to sample storage and disable flash write protect | |
862 ext_flash_start_new_dive_log_and_set_actualPointerSample((uint8_t *)&headerTemp); | |
863 | |
864 dataStart.u8bit.byteHigh = 0; | |
865 dataStart.u8bit.byteLow = headerTemp.pBeginProfileData[0]; | |
866 dataStart.u8bit.byteMidLow = headerTemp.pBeginProfileData[1]; | |
867 dataStart.u8bit.byteMidHigh = headerTemp.pBeginProfileData[2]; | |
868 | |
869 dataEnd.u32bit = dataStart.u32bit + length - 0x801; | |
870 if(dataEnd.u32bit > SAMPLESTOP) | |
871 dataEnd.u32bit -= SAMPLESTOP + SAMPLESTART - 1; | |
872 | |
873 data[0x002] = data[0x402] = dataStart.u8bit.byteLow; | |
874 data[0x003] = data[0x403] = dataStart.u8bit.byteMidLow; | |
875 data[0x004] = data[0x404] = dataStart.u8bit.byteMidHigh; | |
876 data[0x005] = data[0x405] = dataEnd.u8bit.byteLow; | |
877 data[0x006] = data[0x406] = dataEnd.u8bit.byteMidLow; | |
878 data[0x007] = data[0x407] = dataEnd.u8bit.byteMidHigh; | |
879 | |
880 // set actualPointerHeader to next free header and update lastDiveLogId | |
881 ext_flash_create_new_dive_log(0); | |
882 | |
883 // copy header data | |
884 ef_write_block(data,0x800,EF_HEADER, 1); | |
885 | |
886 // copy sample data | |
887 ef_write_block(&data[0x800], length-0x800, EF_SAMPLE, 1); | |
888 | |
889 // update logFlashNextSampleStartAddress | |
890 settingsGetPointer()->logFlashNextSampleStartAddress = actualPointerSample; | |
891 } | |
892 | |
893 | |
894 // =============================================================================== | |
895 // ext_flash_read_header_memory | |
896 /// @brief This function returns the entire header space 1:1 | |
897 /// @date 04-April-2016 | |
898 /// | |
899 /// @param *data 256KB output | |
900 // =============================================================================== | |
901 void ext_flash_read_header_memory(uint8_t *data) | |
902 { | |
903 actualAddress = HEADERSTART; | |
904 actualPointerHeader = actualAddress; | |
905 ext_flash_read_block_start(); | |
906 for(int i=0;i<8;i++) | |
907 ext_flash_read_block_multi(&data[0x8000 * i], 0x8000, EF_HEADER); | |
908 ext_flash_read_block_stop(); | |
909 } | |
910 | |
911 | |
912 // =============================================================================== | |
913 // ext_flash_read_header_memory | |
914 /// @brief This function erases and overwrites the entire logbook header block | |
915 /// @date 04-April-2016 | |
916 /// | |
917 /// @param *data 256KB input of header memory 1:1 | |
918 // =============================================================================== | |
919 void ext_flash_write_header_memory(uint8_t *data) | |
920 { | |
921 actualAddress = HEADERSTART; | |
922 actualPointerHeader = actualAddress; | |
923 ef_write_block(data, 0x40000, EF_HEADER, 0); | |
924 } | |
925 | |
926 | |
927 void ext_flash_open_read_sample(uint8_t StepBackwards, uint32_t *totalNumberOfBytes) | |
928 { | |
929 SSettings *settings = settingsGetPointer(); | |
930 uint8_t id; | |
931 convert_Type dataStart, dataEnd; | |
932 uint8_t header1, header2; | |
933 | |
934 id = settings->lastDiveLogId; | |
935 id -= StepBackwards; /* 0-255, auto rollover */ | |
936 # | |
937 actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET; | |
938 actualPointerHeader = actualAddress; | |
939 | |
940 ext_flash_read_block_start(); | |
941 /* little endian */ | |
942 ext_flash_read_block(&header1, EF_HEADER); | |
943 ext_flash_read_block(&header2, EF_HEADER); | |
944 dataStart.u8bit.byteHigh = 0; | |
945 ext_flash_read_block(&dataStart.u8bit.byteLow, EF_HEADER); | |
946 ext_flash_read_block(&dataStart.u8bit.byteMidLow, EF_HEADER); | |
947 ext_flash_read_block(&dataStart.u8bit.byteMidHigh, EF_HEADER); | |
948 dataEnd.u8bit.byteHigh = 0; | |
949 ext_flash_read_block(&dataEnd.u8bit.byteLow, EF_HEADER); | |
950 ext_flash_read_block(&dataEnd.u8bit.byteMidLow, EF_HEADER); | |
951 ext_flash_read_block(&dataEnd.u8bit.byteMidHigh, EF_HEADER); | |
952 ext_flash_read_block_stop(); | |
953 | |
954 actualPointerSample = dataStart.u32bit; | |
955 if(dataEnd.u32bit >= dataStart.u32bit) | |
956 LengthLeftSampleRead = 1 + dataEnd.u32bit - dataStart.u32bit; | |
957 else | |
958 LengthLeftSampleRead = 2 + (dataStart.u32bit - SAMPLESTART) + (SAMPLESTOP - dataEnd.u32bit); | |
959 *totalNumberOfBytes = LengthLeftSampleRead; | |
960 | |
961 actualAddress = actualPointerSample; | |
962 ext_flash_read_block_start(); | |
963 } | |
964 | |
965 | |
966 void ext_flash_read_next_sample_part(uint8_t *pSample, uint8_t length) | |
967 { | |
968 for(uint16_t i = 0; i < length; i++) | |
969 ext_flash_read_block(&pSample[i], EF_SAMPLE); | |
970 } | |
971 | |
972 | |
973 void ext_flash_close_read_sample(void) | |
974 { | |
975 actualPointerSample = actualAddress; | |
976 ext_flash_read_block_stop(); | |
977 } | |
978 | |
979 | |
980 void ext_flash_set_entry_point(void) | |
981 { | |
982 entryPoint = actualAddress; | |
983 } | |
984 | |
985 | |
986 void ext_flash_reopen_read_sample_at_entry_point(void) | |
987 { | |
988 error_led_on(); | |
989 chip_unselect(); | |
990 wait_chip_not_busy(); | |
991 | |
992 actualAddress = entryPoint; | |
993 ext_flash_read_block_start(); | |
994 error_led_off(); | |
995 } | |
996 | |
997 /* | |
998 uint8_t ext_flash_point_to_64k_block_in_headerSpace(uint8_t logId) | |
999 { | |
1000 uint32_t pointerToData = logId * 0x800; | |
1001 | |
1002 return pointerToData / 0x10000; | |
1003 } | |
1004 */ | |
1005 | |
1006 | |
1007 // =============================================================================== | |
1008 // ext_flash_repair_dive_numbers_starting_count_helper | |
1009 /// @brief | |
1010 /// @date 22-June-2016 | |
1011 | |
1012 // =============================================================================== | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1013 static uint16_t ext_flash_repair_dive_numbers_starting_count_helper(uint8_t *data, uint8_t *change64k, uint16_t startNumber, uint8_t lastLogId) |
38 | 1014 { |
1015 const uint32_t headerStep = 0x800; | |
1016 uint8_t actualLogId = 0; | |
1017 uint16_t oldNumber = 0; | |
1018 uint16_t actualNumber = 0; | |
1019 SLogbookHeader *ptrLogbookHeader = 0; | |
1020 | |
1021 if(startNumber == 0) | |
1022 return 0; | |
1023 | |
1024 actualNumber = startNumber - 1; | |
1025 | |
282 | 1026 // where is the oldest dive (Which is now getting startNumber) |
38 | 1027 // use first header for ease (without HEADER2OFFSET for end of dive header) |
1028 // compare for lastLogId to prevent endless loop | |
1029 | |
1030 if(*(uint16_t*)&data[lastLogId * headerStep] != 0xFAFA) | |
1031 return 0; | |
1032 | |
1033 actualLogId = lastLogId - 1; | |
1034 while((*(uint16_t*)&data[actualLogId * headerStep] == 0xFAFA) && (actualLogId != lastLogId)) | |
1035 { | |
1036 actualLogId--; | |
1037 } | |
1038 | |
1039 // now pointing to one behind the last | |
1040 while(actualLogId != lastLogId) | |
1041 { | |
1042 actualLogId++; | |
1043 actualNumber++; | |
1044 ptrLogbookHeader = (SLogbookHeader *)&data[actualLogId * headerStep]; | |
1045 | |
1046 oldNumber = ptrLogbookHeader->diveNumber; | |
1047 if(oldNumber != actualNumber) | |
1048 { | |
1049 // change64k[ext_flash_point_to_64k_block_in_headerSpace(actualLogId )] = 1; | |
1050 change64k[(actualLogId * 0x800)/0x10000] = 1; | |
1051 ptrLogbookHeader->diveNumber = actualNumber; | |
1052 ptrLogbookHeader = (SLogbookHeader *)(&data[actualLogId * headerStep] + HEADER2OFFSET); | |
1053 ptrLogbookHeader->diveNumber = actualNumber; | |
1054 } | |
1055 } | |
1056 | |
1057 return actualNumber; | |
1058 } | |
1059 | |
1060 // =============================================================================== | |
1061 // ext_flash_repair_SPECIAL_dive_numbers_starting_count_with | |
1062 /// @brief This function | |
1063 /// @date 04-April-2016 | |
282 | 1064 /// problem (160621): 64K blocks (32 dives) in the new flash memory chip |
1065 /// This block needs to be deleted | |
1066 /// these where only 4KB block before | |
38 | 1067 /// @output endCount, last diveNumber |
1068 | |
1069 // =============================================================================== | |
1070 uint16_t ext_flash_repair_SPECIAL_dive_numbers_starting_count_with(uint16_t startCount) | |
1071 { | |
1072 uint32_t logCopyDataPtr = 0; | |
1073 uint8_t *data; | |
1074 uint16_t lastCount; | |
282 | 1075 uint8_t listOfChanged64kBlocks[8]; // 32 dives each 64K |
38 | 1076 |
1077 logCopyDataPtr = getFrame(97); | |
1078 data = (uint8_t *)logCopyDataPtr; | |
1079 | |
1080 for(int i=0;i<8;i++) | |
1081 listOfChanged64kBlocks[i] = 0; | |
1082 | |
1083 actualAddress = HEADERSTART; | |
1084 ext_flash_read_block_start(); | |
1085 ext_flash_read_block_multi(data,0x100000,EF_HEADER); | |
1086 ext_flash_read_block_stop(); | |
1087 | |
1088 lastCount = ext_flash_repair_dive_numbers_starting_count_helper(data, listOfChanged64kBlocks, startCount, settingsGetPointer()->lastDiveLogId); | |
1089 | |
1090 for(int i=0;i<8;i++) | |
1091 { | |
1092 if(listOfChanged64kBlocks[i] != 0) | |
1093 { | |
1094 actualPointerHeader = HEADERSTART + (i * 0x10000); | |
1095 ef_write_block(&data[i * 0x10000], 0x10000, EF_HEADER, 0); | |
1096 } | |
1097 } | |
1098 | |
1099 releaseFrame(97,logCopyDataPtr); | |
1100 if(settingsGetPointer()->totalDiveCounter < lastCount) | |
1101 { | |
1102 settingsGetPointer()->totalDiveCounter = lastCount; | |
1103 } | |
1104 return lastCount; | |
1105 } | |
1106 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1107 /* |
38 | 1108 void OLD_ext_flash_repair_SPECIAL_dive_numbers_starting_count_with(uint16_t startCount) |
1109 { | |
1110 uint16_t counterStorage[256]; | |
1111 uint8_t start = 0xFF; | |
1112 uint32_t logCopyDataPtr = 0; | |
1113 uint8_t *data; | |
1114 uint8_t startAbsolute = 0; | |
1115 int16_t count = 0; | |
1116 _Bool repair = 0; | |
1117 uint8_t startBackup = 0; | |
1118 | |
1119 SLogbookHeader tempLogbookHeader; | |
1120 SLogbookHeader *ptrHeaderInData1a; | |
1121 SLogbookHeader *ptrHeaderInData1b; | |
1122 SLogbookHeader *ptrHeaderInData2a; | |
1123 SLogbookHeader *ptrHeaderInData2b; | |
1124 | |
1125 logCopyDataPtr = getFrame(97); | |
1126 data = (uint8_t *)logCopyDataPtr; | |
1127 ptrHeaderInData1a = (SLogbookHeader *)logCopyDataPtr; | |
1128 ptrHeaderInData1b = (SLogbookHeader *)(logCopyDataPtr + HEADER2OFFSET); | |
1129 ptrHeaderInData2a = (SLogbookHeader *)(logCopyDataPtr + 0x800); | |
1130 ptrHeaderInData2b = (SLogbookHeader *)(logCopyDataPtr + 0x800 + HEADER2OFFSET); | |
1131 | |
1132 // get data | |
1133 for(int StepBackwards = 0; StepBackwards < 255; StepBackwards++) | |
1134 { | |
1135 logbook_getHeader(StepBackwards, &tempLogbookHeader); | |
1136 counterStorage[StepBackwards+1] = tempLogbookHeader.diveNumber; | |
1137 if(tempLogbookHeader.diveHeaderStart == 0xFAFA) | |
1138 start = StepBackwards; | |
1139 else | |
1140 break; | |
1141 } | |
1142 | |
1143 if(start == 0xFF) | |
1144 return; | |
1145 | |
1146 count = start + 1; | |
1147 startAbsolute = settingsGetPointer()->lastDiveLogId; | |
1148 | |
1149 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1150 |
38 | 1151 if(start%2) |
1152 { | |
1153 if(counterStorage[start] != startCount) | |
1154 { | |
1155 // clear data | |
1156 for(int i=0;i<0x800*2;i++) | |
1157 data[i] = 0xFF; | |
1158 | |
1159 uint8_t id = settingsGetPointer()->lastDiveLogId; | |
1160 id -= start; // 0-255, auto rollover | |
1161 | |
1162 // copy primary/pre-dive | |
1163 actualAddress = HEADERSTART + (0x800 * id); | |
1164 ext_flash_read_block_start(); | |
1165 for(int i = 0; i < HEADERSIZE; i++) | |
1166 ext_flash_read_block(&data[i], EF_HEADER); | |
1167 ext_flash_read_block_stop(); | |
1168 | |
1169 // copy main/secondary/post-dive | |
1170 actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET; | |
1171 ext_flash_read_block_start(); | |
1172 for(int i = 0x400; i < HEADERSIZE+0x400; i++) | |
1173 ext_flash_read_block(&data[i], EF_HEADER); | |
1174 ext_flash_read_block_stop(); | |
1175 | |
1176 // repair | |
1177 ptrHeaderInData2a->diveNumber = startCount; | |
1178 ptrHeaderInData2b->diveNumber = startCount; | |
1179 startCount++; | |
1180 | |
1181 // write | |
1182 actualAddress = HEADERSTART + (0x800 * (id-1)); | |
1183 ef_write_block(data,0x800*2,EF_HEADER, 0); | |
1184 } | |
1185 start--; | |
1186 } | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1187 |
38 | 1188 // for(int count = start; count > -1; count -= 2) |
1189 | |
1190 while(count > 0) | |
1191 { | |
1192 // clear data | |
1193 for(int i=0;i<0x1000;i++) | |
1194 data[i] = 0xFF; | |
1195 | |
1196 repair = 0; | |
1197 | |
1198 startBackup = startAbsolute; | |
1199 | |
1200 if(startAbsolute%2) // 0x800 to 0x1000 | |
1201 { | |
1202 // copy second pre-dive | |
1203 actualAddress = HEADERSTART + (0x800 * startAbsolute); | |
1204 ext_flash_read_block_start(); | |
1205 for(int i = 0x800; i < HEADERSIZE+0x800; i++) | |
1206 ext_flash_read_block(&data[i], EF_HEADER); | |
1207 ext_flash_read_block_stop(); | |
1208 | |
1209 // copy second post-dive | |
1210 actualAddress = HEADERSTART + HEADER2OFFSET + (0x800 * startAbsolute); | |
1211 ext_flash_read_block_start(); | |
1212 for(int i = 0xC00; i < HEADERSIZE+0xC00; i++) | |
1213 ext_flash_read_block(&data[i], EF_HEADER); | |
1214 ext_flash_read_block_stop(); | |
1215 | |
1216 if(counterStorage[count] != startCount) | |
1217 { | |
1218 ptrHeaderInData2a->diveNumber = startCount; | |
1219 ptrHeaderInData2b->diveNumber = startCount; | |
1220 repair = 1; | |
1221 } | |
1222 startCount += 1; | |
1223 | |
1224 startAbsolute -= 1; | |
1225 count -= 1; | |
1226 | |
1227 if(count > 0) | |
1228 { | |
1229 // copy first pre-dive | |
1230 actualAddress = HEADERSTART + (0x800 * startAbsolute); | |
1231 ext_flash_read_block_start(); | |
1232 for(int i = 0; i < HEADERSIZE; i++) | |
1233 ext_flash_read_block(&data[i], EF_HEADER); | |
1234 ext_flash_read_block_stop(); | |
1235 | |
1236 // copy first post-dive | |
1237 actualAddress = HEADERSTART + (0x800 * startAbsolute); | |
1238 ext_flash_read_block_start(); | |
1239 for(int i = 0x400; i < HEADERSIZE+0x400; i++) | |
1240 ext_flash_read_block(&data[i], EF_HEADER); | |
1241 ext_flash_read_block_stop(); | |
1242 | |
1243 if(counterStorage[count] != startCount) | |
1244 { | |
1245 ptrHeaderInData1a->diveNumber = startCount; | |
1246 ptrHeaderInData1b->diveNumber = startCount; | |
1247 repair = 1; | |
1248 } | |
1249 startCount += 1; | |
1250 | |
1251 startAbsolute -= 1; | |
1252 count -= 1; | |
1253 } | |
1254 } | |
1255 else | |
1256 { | |
1257 // copy first pre-dive | |
1258 actualAddress = HEADERSTART + (0x800 * startAbsolute); | |
1259 ext_flash_read_block_start(); | |
1260 for(int i = 0; i < HEADERSIZE; i++) | |
1261 ext_flash_read_block(&data[i], EF_HEADER); | |
1262 ext_flash_read_block_stop(); | |
1263 | |
1264 // copy first post-dive | |
1265 actualAddress = HEADERSTART + (0x800 * startAbsolute); | |
1266 ext_flash_read_block_start(); | |
1267 for(int i = 0x400; i < HEADERSIZE+0x400; i++) | |
1268 ext_flash_read_block(&data[i], EF_HEADER); | |
1269 ext_flash_read_block_stop(); | |
1270 | |
1271 if(counterStorage[count] != startCount) | |
1272 { | |
1273 ptrHeaderInData1a->diveNumber = startCount; | |
1274 ptrHeaderInData1b->diveNumber = startCount; | |
1275 repair = 1; | |
1276 } | |
1277 startCount += 1; | |
1278 | |
1279 startAbsolute -= 1; | |
1280 count -= 1; | |
1281 } | |
1282 | |
1283 // write | |
1284 if(repair) | |
1285 { | |
1286 actualPointerHeader = HEADERSTART + (0x1000 * startBackup%2); | |
1287 ef_write_block(data,0x1000,EF_HEADER, 0); | |
1288 } | |
1289 } | |
1290 releaseFrame(97,logCopyDataPtr); | |
1291 settingsGetPointer()->totalDiveCounter = startCount; | |
1292 } | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1293 */ |
38 | 1294 |
1295 // =============================================================================== | |
1296 // ext_flash_repair_dive_log | |
1297 /// @brief This function | |
1298 /// does set | |
1299 /// logFlashNextSampleStartAddress | |
1300 /// and | |
1301 /// lastDiveLogId | |
1302 /// | |
1303 void ext_flash_repair_dive_log(void) | |
1304 { | |
1305 uint8_t header1, header2; | |
1306 convert_Type dataStart; | |
1307 | |
1308 for(int id = 0; id < 255;id++) | |
1309 { | |
1310 actualAddress = HEADERSTART + (0x800 * id); | |
1311 ext_flash_read_block_start(); | |
1312 ext_flash_read_block(&header1, EF_HEADER); | |
1313 ext_flash_read_block(&header2, EF_HEADER); | |
1314 dataStart.u8bit.byteHigh = 0; | |
1315 ext_flash_read_block(&dataStart.u8bit.byteLow, EF_HEADER); | |
1316 ext_flash_read_block(&dataStart.u8bit.byteMidLow, EF_HEADER); | |
1317 ext_flash_read_block(&dataStart.u8bit.byteMidHigh, EF_HEADER); | |
1318 ext_flash_read_block_stop(); | |
1319 if((header1 == 0xFA) && (header2 == 0xFA)) | |
1320 { | |
1321 actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET; | |
1322 ext_flash_read_block_start(); | |
1323 ext_flash_read_block(&header1, EF_HEADER); | |
1324 ext_flash_read_block(&header2, EF_HEADER); | |
1325 ext_flash_read_block_stop(); | |
1326 if((header1 != 0xFA) || (header2 != 0xFA)) | |
1327 { | |
1328 actualPointerSample = dataStart.u32bit; | |
1329 actualAddress = actualPointerSample; | |
1330 logbook_recover_brokenlog(id); | |
1331 SSettings *settings = settingsGetPointer(); | |
1332 settings->logFlashNextSampleStartAddress = actualPointerSample; | |
1333 } | |
1334 } | |
1335 } | |
1336 ext_flash_find_start(); | |
1337 } | |
1338 | |
1339 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1340 static void ext_flash_find_start(void) |
38 | 1341 { |
1342 uint8_t id; | |
1343 uint8_t header1, header2; | |
1344 convert_Type dataStart, dataEnd; | |
1345 | |
1346 for(id = 0; id < 255;id++) | |
1347 { | |
1348 actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET; | |
1349 ext_flash_read_block_start(); | |
1350 ext_flash_read_block(&header1, EF_HEADER); | |
1351 ext_flash_read_block(&header2, EF_HEADER); | |
1352 dataStart.u8bit.byteHigh = 0; | |
1353 ext_flash_read_block(&dataStart.u8bit.byteLow, EF_HEADER); | |
1354 ext_flash_read_block(&dataStart.u8bit.byteMidLow, EF_HEADER); | |
1355 ext_flash_read_block(&dataStart.u8bit.byteMidHigh, EF_HEADER); | |
1356 ext_flash_read_block_stop(); | |
1357 if((header1 == 0xFF) && (header2 == 0xFF)) | |
1358 { | |
1359 break; | |
1360 } | |
1361 } | |
1362 id--; | |
1363 SSettings *settings = settingsGetPointer(); | |
1364 settings->lastDiveLogId = id; | |
1365 | |
1366 actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET; | |
1367 actualPointerHeader = actualAddress; | |
1368 | |
1369 ext_flash_read_block_start(); | |
1370 | |
1371 ext_flash_read_block(&header1, EF_HEADER); | |
1372 ext_flash_read_block(&header2, EF_HEADER); | |
1373 dataStart.u8bit.byteHigh = 0; | |
1374 ext_flash_read_block(&dataStart.u8bit.byteLow, EF_HEADER); | |
1375 ext_flash_read_block(&dataStart.u8bit.byteMidLow, EF_HEADER); | |
1376 ext_flash_read_block(&dataStart.u8bit.byteMidHigh, EF_HEADER); | |
1377 dataEnd.u8bit.byteHigh = 0; | |
1378 ext_flash_read_block(&dataEnd.u8bit.byteLow, EF_HEADER); | |
1379 ext_flash_read_block(&dataEnd.u8bit.byteMidLow, EF_HEADER); | |
1380 ext_flash_read_block(&dataEnd.u8bit.byteMidHigh, EF_HEADER); | |
1381 ext_flash_read_block_stop(); | |
1382 | |
1383 //Find free space | |
1384 if((header1 == 0xFA) && (header2 == 0xFA)) | |
1385 { | |
1386 uint8_t uiRead = 0; | |
1387 int countFF = 0; | |
1388 //End of last complete dive | |
1389 actualPointerSample = dataEnd.u32bit ; | |
1390 actualAddress = actualPointerSample; | |
1391 //Check if there are samples of dives with less than half a minute | |
1392 while(true) | |
1393 { | |
1394 ext_flash_read_block_start(); | |
1395 ext_flash_read_block(&uiRead, EF_SAMPLE); | |
1396 if(uiRead == 0xFF) | |
1397 countFF++; | |
1398 else | |
1399 countFF = 0; | |
1400 | |
1401 | |
1402 | |
1403 if(countFF == 10) | |
1404 { | |
1405 actualAddress -= 10; | |
1406 break; | |
1407 } | |
1408 | |
1409 //New page: clear | |
1410 if(ext_flash_erase_if_on_page_start()) | |
1411 break; | |
1412 } | |
1413 // Set new start address | |
1414 actualPointerSample = actualAddress; | |
1415 settings->logFlashNextSampleStartAddress = actualPointerSample; | |
1416 } | |
1417 else | |
1418 { | |
1419 settings->logFlashNextSampleStartAddress = SAMPLESTART; | |
1420 } | |
1421 } | |
1422 | |
1423 | |
1424 #endif | |
1425 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1426 static void ext_flash_disable_protection(void) |
38 | 1427 { |
1428 /* | |
1429 extFlashStatusBit8_Type status; | |
1430 | |
1431 status.uw = 0; | |
1432 | |
1433 wait_chip_not_busy(); | |
1434 write_spi(0x50,RELEASE); // EWSR | |
1435 write_spi(0x01,HOLDCS); // WRSR | |
1436 write_spi(status.uw,RELEASE); // new status | |
1437 */ | |
1438 } | |
1439 | |
1440 | |
1441 void ext_flash_disable_protection_for_logbook(void) | |
1442 { | |
1443 /* | |
1444 extFlashStatusBit8_Type status; | |
1445 | |
1446 status.uw = 0; | |
1447 status.ub.BlockProtect0 = 1; | |
1448 status.ub.BlockProtect1 = 0; | |
1449 status.ub.BlockProtect2 = 1; | |
1450 status.ub.BlockProtect3 = 0; // not set in OSTC3. Why? | |
1451 | |
1452 wait_chip_not_busy(); | |
1453 write_spi(0x50,RELEASE); // EWSR | |
1454 write_spi(0x01,HOLDCS); // WRSR | |
1455 write_spi(status.uw,RELEASE); // new status | |
1456 */ | |
1457 } | |
1458 | |
1459 | |
1460 void ext_flash_enable_protection(void) | |
1461 { | |
1462 /* | |
1463 extFlashStatusBit8_Type status; | |
1464 | |
1465 status.uw = 0; | |
1466 status.ub.BlockProtect0 = 1; | |
1467 status.ub.BlockProtect1 = 1; | |
1468 status.ub.BlockProtect2 = 1; | |
1469 status.ub.BlockProtect3 = 1; // not set in OSTC3. Why? | |
1470 | |
1471 wait_chip_not_busy(); | |
1472 write_spi(0x50,RELEASE); // EWSR | |
1473 write_spi(0x01,HOLDCS); // WRSR | |
1474 write_spi(status.uw,RELEASE); // new status | |
1475 */ | |
1476 } | |
1477 | |
1478 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1479 /*void ext_flash_erase_chip(void) |
38 | 1480 { |
1481 wait_chip_not_busy(); | |
1482 write_spi(0x06,RELEASE); | |
1483 write_spi(0x60,RELEASE); | |
1484 wait_chip_not_busy(); | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1485 }*/ |
38 | 1486 |
1487 void ext_flash_erase_firmware(void) | |
1488 { | |
1489 uint32_t size, blocks_64k; | |
1490 | |
1491 actualAddress = FWSTART; | |
1492 size = 1 + FWSTOP - FWSTART; | |
1493 blocks_64k = size / 0x10000; | |
1494 ef_erase_64K(blocks_64k); | |
1495 } | |
1496 | |
1497 void ext_flash_erase_firmware2(void) | |
1498 { | |
1499 uint32_t size, blocks_64k; | |
1500 | |
1501 actualAddress = FWSTART2; | |
1502 size = 1 + FWSTOP2 - FWSTART2; | |
1503 blocks_64k = size / 0x10000; | |
1504 ef_erase_64K(blocks_64k); | |
1505 } | |
1506 | |
1507 | |
1508 | |
1509 void ext_flash_erase_logbook(void) | |
1510 { | |
1511 uint32_t size, blocks_64k; | |
1512 | |
1513 ext_flash_disable_protection_for_logbook(); | |
1514 | |
1515 actualAddress = SAMPLESTART; | |
1516 size = 1 + SAMPLESTOP - SAMPLESTART; | |
1517 blocks_64k = size / 0x10000; | |
1518 ef_erase_64K(blocks_64k); | |
1519 | |
1520 actualAddress = HEADERSTART; | |
1521 size = 1 + HEADERSTOP - HEADERSTART; | |
1522 blocks_64k = size / 0x10000; | |
1523 ef_erase_64K(blocks_64k); | |
1524 | |
1525 ext_flash_enable_protection(); | |
1526 } | |
1527 | |
1528 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1529 static void ext_flash_erase4kB(void) |
38 | 1530 { |
1531 wait_chip_not_busy(); | |
1532 write_spi(0x06,RELEASE);/* WREN */ | |
1533 write_spi(0x20,HOLDCS);/* sector erase cmd */ | |
1534 write_address(RELEASE); | |
1535 } | |
1536 | |
282 | 1537 /* be careful - might not work with entire family and other products |
38 | 1538 * see page 14 of LOGBOOK_V3_S25FS-S_00-271247.pdf |
1539 */ | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1540 static void ext_flash_erase32kB(void) |
38 | 1541 { |
1542 uint32_t actualAddress_backup; | |
1543 | |
1544 actualAddress_backup = actualAddress; | |
1545 actualAddress = 0; | |
1546 wait_chip_not_busy(); | |
1547 write_spi(0x06,RELEASE);/* WREN */ | |
1548 write_spi(0xD8,HOLDCS);/* sector erase cmd */ | |
1549 write_address(RELEASE); | |
1550 actualAddress = actualAddress_backup; | |
1551 } | |
1552 | |
1553 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1554 static void ext_flash_erase64kB(void) |
38 | 1555 { |
1556 wait_chip_not_busy(); | |
1557 write_spi(0x06,RELEASE);/* WREN */ | |
1558 write_spi(0xD8,HOLDCS);/* sector erase cmd */ | |
1559 write_address(RELEASE); | |
1560 } | |
1561 | |
1562 | |
1563 void ext_flash_read_block_start(void) | |
1564 { | |
1565 wait_chip_not_busy(); | |
1566 write_spi(0x03,HOLDCS); /* WREN */ | |
1567 write_address(HOLDCS); | |
1568 } | |
1569 | |
1570 /* 4KB, 32KB, 64 KB, not the upper 16 MB with 4 Byte address at the moment */ | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1571 static uint8_t ext_flash_erase_if_on_page_start(void) |
38 | 1572 { |
1573 if(actualAddress < 0x00008000) | |
1574 { | |
1575 /* 4K Byte is 0x1000 */ | |
1576 if((actualAddress & 0xFFF) == 0) | |
1577 { | |
1578 ext_flash_erase4kB(); | |
1579 return 1; | |
1580 } | |
1581 } | |
1582 else | |
1583 if(actualAddress < 0x00010000) | |
1584 { | |
1585 /* 32K Byte is only one page */ | |
1586 if(actualAddress == 0x00010000) | |
1587 { | |
1588 ext_flash_erase32kB(); | |
1589 return 1; | |
1590 } | |
1591 } | |
1592 else | |
1593 { | |
1594 /* 64K Byte is 0x10000 */ | |
1595 if((actualAddress & 0xFFFF) == 0) | |
1596 { | |
1597 ext_flash_erase64kB(); | |
1598 return 1; | |
1599 } | |
1600 } | |
1601 return 0; | |
1602 } | |
1603 | |
1604 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1605 static void ext_flash_read_block(uint8_t *getByte, uint8_t type) |
38 | 1606 { |
1607 *getByte = read_spi(HOLDCS);/* read data */ | |
1608 ext_flash_incf_address(type); | |
1609 } | |
1610 | |
1611 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1612 static void ext_flash_read_block_multi(void *getByte, uint32_t size, uint8_t type) |
38 | 1613 { |
1614 uint8_t *data; | |
1615 data = getByte; | |
1616 | |
1617 for(uint32_t i=0;i<size;i++) | |
1618 { | |
1619 data[i] = read_spi(HOLDCS);/* read data */ | |
1620 ext_flash_incf_address(type); | |
1621 } | |
1622 } | |
1623 | |
1624 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1625 static void ext_flash_read_block_stop(void) |
38 | 1626 { |
1627 chip_unselect(); | |
1628 } | |
1629 | |
1630 | |
1631 /* Private functions ---------------------------------------------------------*/ | |
1632 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1633 static void ef_write_block(uint8_t * sendByte, uint32_t length, uint8_t type, uint8_t do_not_erase) |
38 | 1634 { |
1635 uint32_t remaining_page_size, remaining_length, remaining_space_to_ring_end; | |
1636 | |
1637 if(!length) | |
1638 return; | |
1639 | |
1640 uint32_t ringStart, ringStop; | |
1641 | |
1642 switch(type) | |
1643 { | |
1644 case EF_HEADER: | |
1645 actualAddress = actualPointerHeader; | |
1646 ringStart = HEADERSTART; | |
1647 ringStop = HEADERSTOP; | |
1648 break; | |
1649 case EF_SAMPLE: | |
1650 actualAddress = actualPointerSample; | |
1651 ringStart = SAMPLESTART; | |
1652 ringStop = SAMPLESTOP; | |
1653 break; | |
1654 case EF_DEVICEDATA: | |
1655 actualAddress = actualPointerDevicedata; | |
1656 ringStart = DDSTART; | |
1657 ringStop = DDSTOP; | |
1658 break; | |
1659 case EF_VPMDATA: | |
1660 actualAddress = actualPointerVPM; | |
1661 ringStart = VPMSTART; | |
1662 ringStop = VPMSTOP; | |
1663 break; | |
1664 case EF_SETTINGS: | |
1665 actualAddress = actualPointerSettings; | |
1666 ringStart = SETTINGSSTART; | |
1667 ringStop = SETTINGSSTOP; | |
1668 break; | |
1669 case EF_FIRMWARE: | |
1670 actualAddress = actualPointerFirmware; | |
1671 ringStart = FWSTART; | |
1672 ringStop = FWSTOP; | |
1673 break; | |
1674 case EF_FIRMWARE2: | |
1675 actualAddress = actualPointerFirmware2; | |
1676 ringStart = FWSTART2; | |
1677 ringStop = FWSTOP2; | |
1678 break; | |
1679 default: | |
1680 ringStart = FLASHSTART; | |
1681 ringStop = FLASHSTOP; | |
1682 break; | |
1683 } | |
1684 /* safety */ | |
1685 if(actualAddress < ringStart) | |
1686 actualAddress = ringStart; | |
1687 | |
1688 if(do_not_erase == 0) | |
1689 ext_flash_erase_if_on_page_start(); | |
1690 | |
1691 for(uint32_t i=0;i<length;i++) | |
1692 { | |
1693 ef_hw_rough_delay_us(5); | |
1694 wait_chip_not_busy(); | |
1695 write_spi(0x06,RELEASE); /* WREN */ | |
1696 write_spi(0x02,HOLDCS); /* write cmd */ | |
1697 write_address(HOLDCS); | |
1698 | |
1699 remaining_length = length - i; | |
1700 remaining_page_size = actualAddress & 0xFF; | |
1701 remaining_space_to_ring_end = ringStop - actualAddress; | |
1702 | |
1703 if((remaining_page_size == 0) && (remaining_length >= 256) && (remaining_space_to_ring_end >= 256)) | |
1704 { | |
1705 for(int j=0; j<255; j++) | |
1706 { | |
1707 write_spi(sendByte[i],HOLDCS);/* write data */ | |
1708 actualAddress++; | |
1709 i++; | |
1710 } | |
1711 } | |
1712 /* byte with RELEASE */ | |
1713 write_spi(sendByte[i],RELEASE);/* write data */ | |
1714 actualAddress++; | |
1715 if(actualAddress > ringStop) | |
1716 actualAddress = ringStart; | |
1717 if(do_not_erase == 0) | |
1718 ext_flash_erase_if_on_page_start(); | |
1719 } | |
1720 switch(type) | |
1721 { | |
1722 case EF_HEADER: | |
1723 actualPointerHeader = actualAddress; | |
1724 break; | |
1725 case EF_SAMPLE: | |
1726 actualPointerSample = actualAddress; | |
1727 break; | |
1728 case EF_DEVICEDATA: | |
1729 actualPointerDevicedata = actualAddress; | |
1730 break; | |
1731 case EF_VPMDATA: | |
1732 actualPointerVPM = actualAddress; | |
1733 break; | |
1734 case EF_SETTINGS: | |
1735 actualPointerSettings = actualAddress; | |
1736 break; | |
1737 case EF_FIRMWARE: | |
1738 actualPointerFirmware = actualAddress; | |
1739 break; | |
1740 case EF_FIRMWARE2: | |
1741 actualPointerFirmware2 = actualAddress; | |
1742 break; | |
1743 default: | |
1744 break; | |
1745 } | |
1746 } | |
1747 | |
1748 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1749 static _Bool ext_flash_test_remaining_space_of_page_empty(uint32_t pointer, uint16_t length) |
38 | 1750 { |
1751 if((pointer & 0xFFF) == 0) | |
1752 return 1; | |
1753 | |
1754 uint32_t backup = actualAddress; | |
1755 uint8_t data; | |
1756 uint32_t size_to_page_end; | |
1757 | |
1758 size_to_page_end = 0x1000 - (pointer & 0xFFF); | |
1759 if(length > size_to_page_end) | |
1760 length = size_to_page_end; | |
1761 | |
1762 actualAddress = pointer; | |
1763 ext_flash_read_block_start(); | |
1764 | |
1765 for(uint16_t i = 0; i<length; i++) | |
1766 { | |
1767 ext_flash_read_block(&data, 255); // 255 = ENTIRE FLASH | |
1768 if(data != 0xFF) | |
1769 { | |
1770 ext_flash_read_block_stop(); | |
1771 actualAddress = backup; | |
1772 return 0; | |
1773 } | |
1774 } | |
1775 ext_flash_read_block_stop(); | |
1776 actualAddress = backup; | |
1777 return 1; | |
1778 } | |
1779 | |
1780 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1781 static void ext_flash_set_to_begin_of_next_page(uint32_t *pointer, uint8_t type) |
38 | 1782 { |
1783 uint32_t ringStart, ringStop; | |
1784 | |
1785 switch(type) | |
1786 { | |
1787 case EF_HEADER: | |
1788 ringStart = HEADERSTART; | |
1789 ringStop = HEADERSTOP; | |
1790 break; | |
1791 case EF_SAMPLE: | |
1792 ringStart = SAMPLESTART; | |
1793 ringStop = SAMPLESTOP; | |
1794 break; | |
1795 case EF_DEVICEDATA: | |
1796 ringStart = DDSTART; | |
1797 ringStop = DDSTOP; | |
1798 break; | |
1799 case EF_VPMDATA: | |
1800 ringStart = VPMSTART; | |
1801 ringStop = VPMSTOP; | |
1802 break; | |
1803 case EF_SETTINGS: | |
1804 ringStart = SETTINGSSTART; | |
1805 ringStop = SETTINGSSTOP; | |
1806 break; | |
1807 default: | |
1808 ringStart = FLASHSTART; | |
1809 ringStop = FLASHSTOP; | |
1810 break; | |
1811 } | |
1812 | |
1813 *pointer = (*pointer & 0xFFF) + 0x1000; | |
1814 | |
1815 if((*pointer < ringStart) || (*pointer >= ringStop)) | |
1816 *pointer = ringStart; | |
1817 } | |
1818 | |
1819 | |
1820 static void ef_erase_64K(uint32_t blocks) | |
1821 { | |
1822 for(uint32_t i = 0; i < blocks; i++) | |
1823 { | |
1824 wait_chip_not_busy(); | |
1825 write_spi(0x06,RELEASE);/* WREN */ | |
1826 write_spi(0xD8,HOLDCS);/* 64k erase cmd */ | |
1827 write_address(RELEASE); | |
1828 actualAddress += 0x10000; | |
1829 HAL_Delay(25); | |
1830 } | |
1831 } | |
1832 | |
1833 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1834 static void chip_unselect(void) |
38 | 1835 { |
1836 HAL_GPIO_WritePin(EXTFLASH_CSB_GPIO_PORT,EXTFLASH_CSB_PIN,GPIO_PIN_SET); // chip select | |
1837 } | |
1838 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1839 static void chip_select(void) |
38 | 1840 { |
1841 HAL_GPIO_WritePin(EXTFLASH_CSB_GPIO_PORT,EXTFLASH_CSB_PIN,GPIO_PIN_RESET); // chip select | |
1842 } | |
1843 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1844 static void error_led_on(void) |
38 | 1845 { |
1846 HAL_GPIO_WritePin(OSCILLOSCOPE_GPIO_PORT,OSCILLOSCOPE_PIN,GPIO_PIN_SET); | |
1847 } | |
1848 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1849 static void error_led_off(void) |
38 | 1850 { |
1851 HAL_GPIO_WritePin(OSCILLOSCOPE_GPIO_PORT,OSCILLOSCOPE_PIN,GPIO_PIN_RESET); | |
1852 } | |
1853 | |
1854 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1855 static uint8_t read_spi(uint8_t unselect_CS_afterwards) |
38 | 1856 { |
1857 uint8_t byte; | |
1858 | |
1859 chip_select(); | |
1860 | |
1861 if(HAL_SPI_Receive(&hspiDisplay, &byte, 1, 10000) != HAL_OK) | |
1862 Error_Handler_extflash(); | |
1863 | |
1864 while (HAL_SPI_GetState(&hspiDisplay) != HAL_SPI_STATE_READY) | |
1865 { | |
1866 } | |
1867 if(unselect_CS_afterwards) | |
1868 chip_unselect(); | |
1869 | |
1870 return byte; | |
1871 } | |
1872 | |
1873 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1874 static void write_spi(uint8_t data, uint8_t unselect_CS_afterwards) |
38 | 1875 { |
1876 chip_select(); | |
1877 | |
1878 if(HAL_SPI_Transmit(&hspiDisplay, &data, 1, 10000) != HAL_OK) | |
1879 Error_Handler_extflash(); | |
1880 | |
1881 while (HAL_SPI_GetState(&hspiDisplay) != HAL_SPI_STATE_READY) | |
1882 { | |
1883 } | |
1884 if(unselect_CS_afterwards) | |
1885 chip_unselect(); | |
1886 } | |
1887 | |
1888 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1889 static void write_address(uint8_t unselect_CS_afterwards) |
38 | 1890 { |
1891 uint8_t hi, med ,lo; | |
1892 | |
1893 hi = (actualAddress >> 16) & 0xFF; | |
1894 med = (actualAddress >> 8) & 0xFF; | |
1895 lo = actualAddress & 0xFF; | |
1896 | |
1897 write_spi(hi, HOLDCS); | |
1898 write_spi(med, HOLDCS); | |
1899 write_spi(lo, unselect_CS_afterwards); | |
1900 } | |
1901 | |
1902 | |
1903 static void wait_chip_not_busy(void) | |
1904 { | |
1905 uint8_t status; | |
1906 | |
1907 chip_unselect(); | |
1908 | |
1909 write_spi(0x05,HOLDCS); /* RDSR */ | |
1910 status = read_spi(HOLDCS);/* read status */ | |
1911 while(status & 0x01) | |
1912 { | |
1913 HAL_Delay(1); | |
1914 status = read_spi(HOLDCS);/* read status */ | |
1915 } | |
1916 chip_unselect(); | |
1917 } | |
1918 | |
1919 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1920 static void ext_flash_incf_address(uint8_t type) |
38 | 1921 { |
1922 uint32_t ringStart, ringStop; | |
1923 | |
1924 actualAddress += 1; | |
1925 | |
1926 switch(type) | |
1927 { | |
1928 case EF_HEADER: | |
1929 ringStart = HEADERSTART; | |
1930 ringStop = HEADERSTOP; | |
1931 break; | |
1932 case EF_SAMPLE: | |
1933 ringStart = SAMPLESTART; | |
1934 ringStop = SAMPLESTOP; | |
1935 break; | |
1936 case EF_DEVICEDATA: | |
1937 ringStart = DDSTART; | |
1938 ringStop = DDSTOP; | |
1939 break; | |
1940 case EF_VPMDATA: | |
1941 ringStart = VPMSTART; | |
1942 ringStop = VPMSTOP; | |
1943 break; | |
1944 case EF_SETTINGS: | |
1945 ringStart = SETTINGSSTART; | |
1946 ringStop = SETTINGSSTOP; | |
1947 break; | |
1948 case EF_FIRMWARE: | |
1949 ringStart = FWSTART; | |
1950 ringStop = FWSTOP; | |
1951 break; | |
1952 case EF_FIRMWARE2: | |
1953 ringStart = FWSTART2; | |
1954 ringStop = FWSTOP2; | |
1955 break; | |
1956 default: | |
1957 ringStart = FLASHSTART; | |
1958 ringStop = FLASHSTOP; | |
1959 break; | |
1960 } | |
1961 | |
1962 if((actualAddress < ringStart) || (actualAddress > ringStop)) | |
1963 actualAddress = ringStart; | |
1964 } | |
1965 | |
1966 | |
268
1b9847d40e81
cleanup: make things static where possible.
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
1967 static void ext_flash_decf_address_ring(uint8_t type) |
38 | 1968 { |
1969 uint32_t ringStart, ringStop; | |
1970 | |
1971 switch(type) | |
1972 { | |
1973 case EF_HEADER: | |
1974 ringStart = HEADERSTART; | |
1975 ringStop = HEADERSTOP; | |
1976 break; | |
1977 case EF_SAMPLE: | |
1978 ringStart = SAMPLESTART; | |
1979 ringStop = SAMPLESTOP; | |
1980 break; | |
1981 case EF_DEVICEDATA: | |
1982 ringStart = DDSTART; | |
1983 ringStop = DDSTOP; | |
1984 break; | |
1985 case EF_VPMDATA: | |
1986 ringStart = VPMSTART; | |
1987 ringStop = VPMSTOP; | |
1988 break; | |
1989 case EF_SETTINGS: | |
1990 ringStart = SETTINGSSTART; | |
1991 ringStop = SETTINGSSTOP; | |
1992 break; | |
1993 case EF_FIRMWARE: | |
1994 ringStart = FWSTART; | |
1995 ringStop = FWSTOP; | |
1996 break; | |
1997 case EF_FIRMWARE2: | |
1998 ringStart = FWSTART2; | |
1999 ringStop = FWSTOP2; | |
2000 break; | |
2001 default: | |
2002 ringStart = FLASHSTART; | |
2003 ringStop = FLASHSTOP; | |
2004 break; | |
2005 } | |
2006 | |
2007 if((actualAddress <= ringStart) || (actualAddress > ringStop)) | |
2008 actualAddress = ringStop; | |
2009 else | |
2010 actualAddress -= 1; | |
2011 } | |
2012 | |
2013 | |
2014 static void ef_hw_rough_delay_us(uint32_t delayUs) | |
2015 { | |
2016 if(!delayUs) | |
2017 return; | |
2018 delayUs*= 12; | |
2019 while(delayUs--); | |
2020 return; | |
2021 } | |
2022 | |
2023 static void Error_Handler_extflash(void) | |
2024 { | |
2025 while(1) | |
2026 { | |
2027 } | |
2028 } | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
2029 /* |
38 | 2030 uint8_t ext_flash_erase_firmware_if_not_empty(void) |
2031 { | |
2032 const uint8_t TESTSIZE_FW = 4; | |
2033 | |
2034 uint8_t data[TESTSIZE_FW]; | |
2035 uint8_t notEmpty = 0; | |
2036 | |
2037 actualAddress = FWSTART; | |
2038 ext_flash_read_block_start(); | |
2039 for(int i = 0; i < TESTSIZE_FW; i++) | |
2040 { | |
2041 ext_flash_read_block(&data[i], EF_FIRMWARE); | |
2042 if(data[i] != 0xFF) | |
2043 notEmpty = 1; | |
2044 } | |
2045 ext_flash_read_block_stop(); | |
2046 | |
2047 if(notEmpty) | |
2048 { | |
2049 ext_flash_erase_firmware(); | |
2050 return 1; | |
2051 } | |
2052 else | |
2053 return 0; | |
2054 } | |
2055 | |
2056 uint8_t ext_flash_erase_firmware2_if_not_empty(void) | |
2057 { | |
2058 const uint8_t TESTSIZE_FW = 4; | |
2059 | |
2060 uint8_t data[TESTSIZE_FW]; | |
2061 uint8_t notEmpty = 0; | |
2062 | |
2063 actualAddress = FWSTART2; | |
2064 ext_flash_read_block_start(); | |
2065 for(int i = 0; i < TESTSIZE_FW; i++) | |
2066 { | |
2067 ext_flash_read_block(&data[i], EF_FIRMWARE2); | |
2068 if(data[i] != 0xFF) | |
2069 notEmpty = 1; | |
2070 } | |
2071 ext_flash_read_block_stop(); | |
2072 | |
2073 if(notEmpty) | |
2074 { | |
2075 ext_flash_erase_firmware2(); | |
2076 return 1; | |
2077 } | |
2078 else | |
2079 return 0; | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
38
diff
changeset
|
2080 }*/ |