comparison BootLoader/Src/externLogbookFlash_mini.c @ 1048:493a5903ec20 GasConsumption

Merge with 9d9d506a82d3162b6b2323819cc08652887d7dd4 (Bootloader)
author Ideenmodellierer
date Sat, 15 Nov 2025 19:29:44 +0100
parents aeafa631147d
children
comparison
equal deleted inserted replaced
1047:6fb16ca39125 1048:493a5903ec20
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>&copy; 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 /* Private types -------------------------------------------------------------*/
74 #define FLASHSTART 0x000000
75 //#define FLASHSTOP 0x01FFFFFF all 32 MB with 4byte addressing
76 #define FLASHSTOP 0x00FFFFFF
77 //#define FLASHSTOP 0x3FFFFF
78 #define RELEASE 1
79 #define HOLDCS 0
80
81 #define HEADER2OFFSET 0x400
82
83 typedef struct{
84 uint8_t IsBusy:1;
85 uint8_t IsWriteEnabled:1;
86 uint8_t BlockProtect0:1;
87 uint8_t BlockProtect1:1;
88 uint8_t BlockProtect2:1;
89 uint8_t BlockProtect3:1;
90 uint8_t IsAutoAddressIncMode:1;
91 uint8_t BlockProtectL:1;
92 } extFlashStatusUbit8_t;
93
94 typedef union{
95 extFlashStatusUbit8_t ub;
96 uint8_t uw;
97 } extFlashStatusBit8_Type;
98
99
100 /* Exported variables --------------------------------------------------------*/
101
102 /* Private variables ---------------------------------------------------------*/
103
104 static uint32_t actualAddress = 0;
105 static uint32_t preparedPageAddress = 0;
106 static uint32_t closeSectorAddress = 0;
107 static uint32_t actualPointerHeader = 0;
108 static uint32_t actualPointerSample = 0;
109 static uint32_t actualPointerDevicedata = DDSTART;
110 static uint32_t actualPointerVPM = 0;
111 static uint32_t actualPointerSettings = SETTINGSSTART;
112 static uint32_t actualPointerFirmware = 0;
113 static uint32_t actualPointerFirmware2 = 0;
114
115 /* Private function prototypes -----------------------------------------------*/
116 static void chip_unselect(void);
117 static void chip_select(void);
118 static void write_spi(uint8_t data, uint8_t unselect_CS_afterwards);
119 static uint8_t read_spi(uint8_t unselect_CS_afterwards);
120 static void write_address(uint8_t unselect_CS_afterwards);
121 static void Error_Handler_extflash(void);
122 static void wait_chip_not_busy(void);
123 static void ext_flash_incf_address(uint8_t type);
124 //void ext_flash_incf_address_ring(void);
125
126 static void ext_flash_erase4kB(void);
127 static void ext_flash_erase32kB(void);
128 static void ext_flash_erase64kB(void);
129 static uint8_t ext_flash_erase_if_on_page_start(void);
130
131 static void ef_write_block(uint8_t * sendByte, uint32_t length, uint8_t type, uint8_t do_not_erase);
132
133 static void ext_flash_read_block(uint8_t *getByte, uint8_t type);
134 static void ext_flash_read_block_multi(void *getByte, uint32_t size, uint8_t type);
135 static void ext_flash_read_block_stop(void);
136
137 static void ef_hw_rough_delay_us(uint32_t delayUs);
138 static void ef_erase_64K(uint32_t blocks);
139
140
141 /* Exported functions --------------------------------------------------------*/
142
143 void ext_flash_write_firmware(uint8_t *pSample1, uint32_t length1)//, uint8_t *pSample2, uint32_t length2)
144 {
145 general32to8_Type lengthTransform;
146
147 lengthTransform.u32 = length1;
148
149 actualPointerFirmware = FWSTART;
150 ef_write_block(lengthTransform.u8,4, EF_FIRMWARE, 1);
151 ef_write_block(pSample1,length1, EF_FIRMWARE, 1);
152
153 // if(length2)
154 // ef_write_block(pSample2,length2, EF_FIRMWARE, 1);
155 }
156
157 uint8_t ext_flash_read_firmware_version(char *text)
158 {
159 uint32_t backup = actualAddress;
160 uint8_t buffer[4];
161
162 // + 4 for length data, see ext_flash_write_firmware
163 actualAddress = FWSTART + 4 + 0x10000;
164 ext_flash_read_block_start();
165 ext_flash_read_block(&buffer[0], EF_FIRMWARE);
166 ext_flash_read_block(&buffer[1], EF_FIRMWARE);
167 ext_flash_read_block(&buffer[2], EF_FIRMWARE);
168 ext_flash_read_block(&buffer[3], EF_FIRMWARE);
169
170 ext_flash_read_block_stop();
171 actualAddress = backup;
172
173 uint8_t ptr = 0;
174 text[ptr++] = 'V';
175 ptr += gfx_number_to_string(2,0,&text[ptr],buffer[0] & 0x3F);
176 text[ptr++] = '.';
177 ptr += gfx_number_to_string(2,0,&text[ptr],buffer[1] & 0x3F);
178 text[ptr++] = '.';
179 ptr += gfx_number_to_string(2,0,&text[ptr],buffer[2] & 0x3F);
180 text[ptr++] = ' ';
181 if(buffer[3])
182 {
183 text[ptr++] = 'b';
184 text[ptr++] = 'e';
185 text[ptr++] = 't';
186 text[ptr++] = 'a';
187 text[ptr++] = ' ';
188 }
189 return ptr;
190 }
191
192
193 uint32_t ext_flash_read_firmware(uint8_t *pSample1, uint32_t max_length, uint8_t *magicByte)
194 {
195 uint32_t backup = actualAddress;
196 general32to8_Type lengthTransform;
197
198 actualAddress = FWSTART;
199 ext_flash_read_block_start();
200
201 ext_flash_read_block(&lengthTransform.u8[0], EF_FIRMWARE);
202 ext_flash_read_block(&lengthTransform.u8[1], EF_FIRMWARE);
203 ext_flash_read_block(&lengthTransform.u8[2], EF_FIRMWARE);
204 ext_flash_read_block(&lengthTransform.u8[3], EF_FIRMWARE);
205
206
207 if(lengthTransform.u32 == 0xFFFFFFFF)
208 {
209 lengthTransform.u32 = 0xFFFFFFFF;
210 }
211 else
212 if(lengthTransform.u32 > max_length)
213 {
214 lengthTransform.u32 = 0xFF000000;
215 }
216 else
217 {
218 for(uint32_t i = 0; i<lengthTransform.u32; i++)
219 {
220 ext_flash_read_block(&pSample1[i], EF_FIRMWARE);
221 }
222
223 }
224
225 ext_flash_read_block_stop();
226
227 if(magicByte)
228 {
229 *magicByte = pSample1[0x10000 + 0x3E]; // 0x3E == 62
230 }
231
232 actualAddress = backup;
233 return lengthTransform.u32;
234 }
235
236
237 void ext_flash_write_firmware2(uint32_t offset, uint8_t *pSample1, uint32_t length1, uint8_t *pSample2, uint32_t length2)
238 {
239 general32to8_Type lengthTransform, offsetTransform;
240
241 lengthTransform.u32 = length1 + length2;
242 offsetTransform.u32 = offset;
243
244 actualPointerFirmware2 = FWSTART2;
245 ef_write_block(lengthTransform.u8,4, EF_FIRMWARE2, 1);
246 ef_write_block(offsetTransform.u8,4, EF_FIRMWARE2, 1);
247 ef_write_block(pSample1,length1, EF_FIRMWARE2, 1);
248 if(length2)
249 ef_write_block(pSample2,length2, EF_FIRMWARE2, 1);
250 }
251
252
253 uint32_t ext_flash_read_firmware2(uint32_t *offset, uint8_t *pSample1, uint32_t max_length1, uint8_t *pSample2, uint32_t max_length2)
254 {
255 uint32_t backup = actualAddress;
256 uint32_t length1, length2;
257 general32to8_Type lengthTransform, offsetTransform;
258
259 actualAddress = FWSTART2;
260 ext_flash_read_block_start();
261
262 ext_flash_read_block(&lengthTransform.u8[0], EF_FIRMWARE2);
263 ext_flash_read_block(&lengthTransform.u8[1], EF_FIRMWARE2);
264 ext_flash_read_block(&lengthTransform.u8[2], EF_FIRMWARE2);
265 ext_flash_read_block(&lengthTransform.u8[3], EF_FIRMWARE2);
266
267 ext_flash_read_block(&offsetTransform.u8[0], EF_FIRMWARE2);
268 ext_flash_read_block(&offsetTransform.u8[1], EF_FIRMWARE2);
269 ext_flash_read_block(&offsetTransform.u8[2], EF_FIRMWARE2);
270 ext_flash_read_block(&offsetTransform.u8[3], EF_FIRMWARE2);
271
272 *offset = offsetTransform.u32;
273
274 if(lengthTransform.u32 == 0xFFFFFFFF)
275 {
276 lengthTransform.u32 = 0xFFFFFFFF;
277 }
278 else
279 if(lengthTransform.u32 > max_length1 + max_length2)
280 {
281 lengthTransform.u32 = 0xFF000000;
282 }
283 else
284 {
285 if(lengthTransform.u32 < max_length1)
286 {
287 length1 = lengthTransform.u32;
288 length2 = 0;
289 }
290 else
291 {
292 length1 = max_length1;
293 length2 = lengthTransform.u32 - max_length1;
294 }
295
296 if(pSample1)
297 {
298 for(uint32_t i = 0; i<length1; i++)
299 {
300 ext_flash_read_block(&pSample1[i], EF_FIRMWARE2);
301 }
302 if(pSample2)
303 {
304 for(uint32_t i = 0; i<length2; i++)
305 {
306 ext_flash_read_block(&pSample2[i], EF_FIRMWARE2);
307 }
308 }
309 }
310 else if(pSample2)
311 {
312 /* actualAddress += length1; do dummy read to get EEPROM to the correct address */
313 for(uint32_t i = 0; i<length1; i++)
314 {
315 ext_flash_read_block(&pSample2[0], EF_FIRMWARE2);
316 }
317 for(uint32_t i = 0; i<length2; i++)
318 {
319 ext_flash_read_block(&pSample2[i], EF_FIRMWARE2);
320 }
321 }
322 }
323 ext_flash_read_block_stop();
324 actualAddress = backup;
325 return lengthTransform.u32;
326 }
327
328
329 void ext_flash_read_fixed_16_devicedata_blocks_formated_128byte_total(uint8_t *buffer)
330 {
331 SDeviceLine data[16];
332 uint8_t tempLengthIngnore;
333 uint16_t count;
334 uint8_t transfer;
335
336 RTC_DateTypeDef Sdate;
337 RTC_TimeTypeDef Stime;
338
339 actualAddress = DDSTART;
340
341 ext_flash_read_block_start();
342 ext_flash_read_block(&tempLengthIngnore, EF_DEVICEDATA);
343 ext_flash_read_block(&tempLengthIngnore, EF_DEVICEDATA);
344
345 ext_flash_read_block_multi((uint8_t *)data,16*3*4, EF_DEVICEDATA);
346 ext_flash_read_block_stop();
347
348 count = 0;
349 for(int i=0;i<16;i++)
350 {
351 transfer = (data[i].value_int32 >> 24) & 0xFF;
352 buffer[count++] = transfer;
353 transfer = (data[i].value_int32 >> 16) & 0xFF;
354 buffer[count++] = transfer;
355 transfer = (data[i].value_int32 >> 8) & 0xFF;
356 buffer[count++] = transfer;
357 transfer = (data[i].value_int32) & 0xFF;
358 buffer[count++] = transfer;
359
360 translateDate(data[i].date_rtc_dr, &Sdate);
361 translateTime(data[i].time_rtc_tr, &Stime);
362 buffer[count++] = Sdate.Year;
363 buffer[count++] = Sdate.Month;
364 buffer[count++] = Sdate.Date;
365 buffer[count++] = Stime.Hours;
366 }
367 }
368
369 void ext_flash_erase_firmware(void)
370 {
371 uint32_t size, blocks_64k;
372
373 actualAddress = FWSTART;
374 size = 1 + FWSTOP - FWSTART;
375 blocks_64k = size / 0x10000;
376 ef_erase_64K(blocks_64k);
377 }
378
379 void ext_flash_erase_firmware2(void)
380 {
381 uint32_t size, blocks_64k;
382
383 actualAddress = FWSTART2;
384 size = 1 + FWSTOP2 - FWSTART2;
385 blocks_64k = size / 0x10000;
386 ef_erase_64K(blocks_64k);
387 }
388
389
390
391 static void ext_flash_erase4kB(void)
392 {
393 wait_chip_not_busy();
394 write_spi(0x06,RELEASE);/* WREN */
395 write_spi(0x20,HOLDCS);/* sector erase cmd */
396 write_address(RELEASE);
397 }
398
399 /* be careful - might not work with entire family and other products
400 * see page 14 of LOGBOOK_V3_S25FS-S_00-271247.pdf
401 */
402 static void ext_flash_erase32kB(void)
403 {
404 uint32_t actualAddress_backup;
405
406 actualAddress_backup = actualAddress;
407 actualAddress = 0;
408 wait_chip_not_busy();
409 write_spi(0x06,RELEASE);/* WREN */
410 write_spi(0xD8,HOLDCS);/* sector erase cmd */
411 write_address(RELEASE);
412 actualAddress = actualAddress_backup;
413 }
414
415
416 static void ext_flash_erase64kB(void)
417 {
418 wait_chip_not_busy();
419 write_spi(0x06,RELEASE);/* WREN */
420 write_spi(0xD8,HOLDCS);/* sector erase cmd */
421 write_address(RELEASE);
422 }
423
424
425 void ext_flash_read_block_start(void)
426 {
427 wait_chip_not_busy();
428 write_spi(0x03,HOLDCS); /* WREN */
429 write_address(HOLDCS);
430 }
431
432 /* 4KB, 32KB, 64 KB, not the upper 16 MB with 4 Byte address at the moment */
433 static uint8_t ext_flash_erase_if_on_page_start(void)
434 {
435 if(actualAddress < 0x00008000)
436 {
437 /* 4K Byte is 0x1000 */
438 if((actualAddress & 0xFFF) == 0)
439 {
440 ext_flash_erase4kB();
441 return 1;
442 }
443 }
444 else
445 if(actualAddress < 0x00010000)
446 {
447 /* 32K Byte is only one page */
448 if(actualAddress == 0x00010000)
449 {
450 ext_flash_erase32kB();
451 return 1;
452 }
453 }
454 else
455 {
456 /* 64K Byte is 0x10000 */
457 if((actualAddress & 0xFFFF) == 0)
458 {
459 if(preparedPageAddress == actualAddress) /* has page already been prepared before? (at the moment for samples only) */
460 {
461 preparedPageAddress = 0;
462
463 }
464 else
465 {
466 ext_flash_erase64kB();
467 }
468 return 1;
469 }
470 }
471
472 return 0;
473 }
474
475
476 static void ext_flash_read_block(uint8_t *getByte, uint8_t type)
477 {
478 *getByte = read_spi(HOLDCS);/* read data */
479 ext_flash_incf_address(type);
480 }
481
482
483 static void ext_flash_read_block_multi(void *getByte, uint32_t size, uint8_t type)
484 {
485 uint8_t *data;
486 data = getByte;
487
488 for(uint32_t i=0;i<size;i++)
489 {
490 data[i] = read_spi(HOLDCS);/* read data */
491 ext_flash_incf_address(type);
492 }
493 }
494
495
496 static void ext_flash_read_block_stop(void)
497 {
498 chip_unselect();
499 }
500
501
502 /* Private functions ---------------------------------------------------------*/
503
504 static void ef_write_block(uint8_t * sendByte, uint32_t length, uint8_t type, uint8_t do_not_erase)
505 {
506 uint32_t remaining_page_size, remaining_length, remaining_space_to_ring_end;
507 uint32_t i=0;
508
509 if(!length)
510 return;
511
512 uint32_t ringStart, ringStop;
513
514 switch(type)
515 {
516 case EF_HEADER:
517 actualAddress = actualPointerHeader;
518 ringStart = HEADERSTART;
519 ringStop = HEADERSTOP;
520 break;
521 case EF_SAMPLE:
522 actualAddress = actualPointerSample;
523 ringStart = SAMPLESTART;
524 ringStop = SAMPLESTOP;
525 break;
526 case EF_DEVICEDATA:
527 actualAddress = actualPointerDevicedata;
528 ringStart = DDSTART;
529 ringStop = DDSTOP;
530 break;
531 case EF_VPMDATA:
532 actualAddress = actualPointerVPM;
533 ringStart = VPMSTART;
534 ringStop = VPMSTOP;
535 break;
536 case EF_SETTINGS:
537 actualAddress = actualPointerSettings;
538 ringStart = SETTINGSSTART;
539 ringStop = SETTINGSSTOP;
540 break;
541 case EF_FIRMWARE:
542 actualAddress = actualPointerFirmware;
543 ringStart = FWSTART;
544 ringStop = FWSTOP;
545 break;
546 case EF_FIRMWARE2:
547 actualAddress = actualPointerFirmware2;
548 ringStart = FWSTART2;
549 ringStop = FWSTOP2;
550 break;
551 default:
552 ringStart = FLASHSTART;
553 ringStop = FLASHSTOP;
554 break;
555 }
556 /* safety */
557 if(actualAddress < ringStart)
558 actualAddress = ringStart;
559
560 if(do_not_erase == 0)
561 {
562 ext_flash_erase_if_on_page_start();
563 }
564
565 while( i<length)
566 {
567 ef_hw_rough_delay_us(5);
568 wait_chip_not_busy();
569 write_spi(0x06,RELEASE); /* WREN */
570 write_spi(0x02,HOLDCS); /* write cmd */
571 write_address(HOLDCS);
572
573 remaining_length = length - i;
574 remaining_page_size = 0xFF - (uint8_t)(actualAddress & 0xFF) +1;
575 remaining_space_to_ring_end = ringStop - actualAddress;
576
577 if(remaining_length >= 256)
578 {
579 remaining_length = 255; /* up to 256 bytes may be written in one burst. Last byte is written with release */
580 }
581 else
582 {
583 remaining_length--; /* last byte needed for release */
584 }
585 if(remaining_length >= (remaining_page_size) ) /* use 256 byte page and calculate number of bytes left */
586 {
587 remaining_length = remaining_page_size - 1;
588 }
589 if( (remaining_space_to_ring_end >= 256))
590 {
591 for(int j=0; j<remaining_length; j++)
592 {
593 write_spi(sendByte[i],HOLDCS);/* write data */
594 actualAddress++;
595 i++;
596 }
597 }
598 /* byte with RELEASE */
599 write_spi(sendByte[i],RELEASE);/* write data */
600 actualAddress++;
601 i++;
602
603 if(actualAddress > ringStop)
604 actualAddress = ringStart;
605
606 if(do_not_erase == 0)
607 ext_flash_erase_if_on_page_start();
608 }
609 switch(type)
610 {
611 case EF_HEADER:
612 actualPointerHeader = actualAddress;
613 break;
614 case EF_SAMPLE:
615 actualPointerSample = actualAddress;
616 break;
617 case EF_DEVICEDATA:
618 actualPointerDevicedata = actualAddress;
619 break;
620 case EF_VPMDATA:
621 actualPointerVPM = actualAddress;
622 break;
623 case EF_SETTINGS:
624 actualPointerSettings = actualAddress;
625 break;
626 case EF_FIRMWARE:
627 actualPointerFirmware = actualAddress;
628 break;
629 case EF_FIRMWARE2:
630 actualPointerFirmware2 = actualAddress;
631 break;
632 default:
633 break;
634 }
635 }
636
637
638 static void ef_erase_64K(uint32_t blocks)
639 {
640 for(uint32_t i = 0; i < blocks; i++)
641 {
642 wait_chip_not_busy();
643 write_spi(0x06,RELEASE);/* WREN */
644 write_spi(0xD8,HOLDCS);/* 64k erase cmd */
645 write_address(RELEASE);
646 actualAddress += 0x10000;
647 HAL_Delay(25);
648 }
649 }
650
651 static void chip_unselect(void)
652 {
653 HAL_GPIO_WritePin(EXTFLASH_CSB_GPIO_PORT,EXTFLASH_CSB_PIN,GPIO_PIN_SET); // chip select
654 }
655
656 static void chip_select(void)
657 {
658 HAL_GPIO_WritePin(EXTFLASH_CSB_GPIO_PORT,EXTFLASH_CSB_PIN,GPIO_PIN_RESET); // chip select
659 }
660
661 static uint8_t read_spi(uint8_t unselect_CS_afterwards)
662 {
663 uint8_t byte;
664
665 chip_select();
666
667 if(HAL_SPI_Receive(&hspiDisplay, &byte, 1, 10000) != HAL_OK)
668 Error_Handler_extflash();
669
670 while (HAL_SPI_GetState(&hspiDisplay) != HAL_SPI_STATE_READY)
671 {
672 }
673 if(unselect_CS_afterwards)
674 chip_unselect();
675
676 return byte;
677 }
678
679
680 static void write_spi(uint8_t data, uint8_t unselect_CS_afterwards)
681 {
682 chip_select();
683
684 if(HAL_SPI_Transmit(&hspiDisplay, &data, 1, 10000) != HAL_OK)
685 Error_Handler_extflash();
686
687 while (HAL_SPI_GetState(&hspiDisplay) != HAL_SPI_STATE_READY)
688 {
689 }
690 if(unselect_CS_afterwards)
691 chip_unselect();
692 }
693
694
695 static void write_address(uint8_t unselect_CS_afterwards)
696 {
697 uint8_t hi, med ,lo;
698
699 hi = (actualAddress >> 16) & 0xFF;
700 med = (actualAddress >> 8) & 0xFF;
701 lo = actualAddress & 0xFF;
702
703 write_spi(hi, HOLDCS);
704 write_spi(med, HOLDCS);
705 write_spi(lo, unselect_CS_afterwards);
706 }
707
708
709 static void wait_chip_not_busy(void)
710 {
711 uint8_t status;
712
713 chip_unselect();
714
715 write_spi(0x05,HOLDCS); /* RDSR */
716 status = read_spi(HOLDCS);/* read status */
717 while(status & 0x01)
718 {
719 HAL_Delay(1);
720 status = read_spi(HOLDCS);/* read status */
721 }
722 chip_unselect();
723 }
724
725
726 static void ext_flash_incf_address(uint8_t type)
727 {
728 uint32_t ringStart, ringStop;
729
730 actualAddress += 1;
731
732 switch(type)
733 {
734 case EF_HEADER:
735 ringStart = HEADERSTART;
736 ringStop = HEADERSTOP;
737 break;
738 case EF_SAMPLE:
739 ringStart = SAMPLESTART;
740 ringStop = SAMPLESTOP;
741 break;
742 case EF_DEVICEDATA:
743 ringStart = DDSTART;
744 ringStop = DDSTOP;
745 break;
746 case EF_VPMDATA:
747 ringStart = VPMSTART;
748 ringStop = VPMSTOP;
749 break;
750 case EF_SETTINGS:
751 ringStart = SETTINGSSTART;
752 ringStop = SETTINGSSTOP;
753 break;
754 case EF_FIRMWARE:
755 ringStart = FWSTART;
756 ringStop = FWSTOP;
757 break;
758 case EF_FIRMWARE2:
759 ringStart = FWSTART2;
760 ringStop = FWSTOP2;
761 break;
762 default:
763 ringStart = FLASHSTART;
764 ringStop = FLASHSTOP;
765 break;
766 }
767
768 if((actualAddress < ringStart) || (actualAddress > ringStop))
769 actualAddress = ringStart;
770 }
771
772 static void ef_hw_rough_delay_us(uint32_t delayUs)
773 {
774 if(!delayUs)
775 return;
776 delayUs*= 12;
777 while(delayUs--);
778 return;
779 }
780
781 static void Error_Handler_extflash(void)
782 {
783 while(1)
784 {
785 }
786 }
787
788 void ext_flash_CloseSector(void)
789 {
790 uint32_t actualAddressBackup = actualAddress;
791 int i=0;
792
793 if(closeSectorAddress != 0)
794 {
795 /* write some dummy bytes to the sector which is currently used for storing samples. This is done to "hide" problem if function is calles again */
796 actualAddress = closeSectorAddress;
797
798 wait_chip_not_busy();
799 write_spi(0x06,RELEASE); /* WREN */
800 write_spi(0x02,HOLDCS); /* write cmd */
801 write_address(HOLDCS);
802 for(i = 0; i<8; i++)
803 {
804 write_spi(0xA5,HOLDCS);/* write data */
805 actualAddress++;
806 }
807 /* byte with RELEASE */
808 write_spi(0xA5,RELEASE);/* write data */
809 actualAddress = actualAddressBackup;
810 closeSectorAddress = 0;
811 }
812 }
813
814
815 uint8_t ext_flash_erase_firmware_if_not_empty(void)
816 {
817 const uint8_t TESTSIZE_FW = 4;
818
819 uint8_t data[TESTSIZE_FW];
820 uint8_t notEmpty = 0;
821
822 actualAddress = FWSTART;
823 ext_flash_read_block_start();
824 for(int i = 0; i < TESTSIZE_FW; i++)
825 {
826 ext_flash_read_block(&data[i], EF_FIRMWARE);
827 if(data[i] != 0xFF)
828 notEmpty = 1;
829 }
830 ext_flash_read_block_stop();
831
832 if(notEmpty)
833 {
834 ext_flash_erase_firmware();
835 return 1;
836 }
837 else
838 return 0;
839 }
840
841 uint8_t ext_flash_erase_firmware2_if_not_empty(void)
842 {
843 const uint8_t TESTSIZE_FW = 4;
844
845 uint8_t data[TESTSIZE_FW];
846 uint8_t notEmpty = 0;
847
848 actualAddress = FWSTART2;
849 ext_flash_read_block_start();
850 for(int i = 0; i < TESTSIZE_FW; i++)
851 {
852 ext_flash_read_block(&data[i], EF_FIRMWARE2);
853 if(data[i] != 0xFF)
854 notEmpty = 1;
855 }
856 ext_flash_read_block_stop();
857
858 if(notEmpty)
859 {
860 ext_flash_erase_firmware2();
861 return 1;
862 }
863 else
864 return 0;
865 }