Implement reading firmware on Horus via USB (#5442)
[opentx.git] / radio / src / targets / common / arm / stm32 / usbd_storage_msd.cpp
blobad3f90be4d40545c51f07ff105ec0bfaa0a4a1a2
1 /*
2 * Copyright (C) OpenTX
4 * Based on code named
5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 /* Includes ------------------------------------------------------------------*/
22 #include "opentx.h"
23 #include "FatFs/diskio.h"
24 #include "stamp.h"
26 #if defined(__cplusplus) && !defined(SIMU)
27 extern "C" {
28 #endif
30 #include "usbd_msc_mem.h"
31 #include "usb_conf.h"
33 enum MassstorageLuns {
34 STORAGE_SDCARD_LUN,
35 STORAGE_EEPROM_LUN,
36 STORAGE_LUN_NBR
39 /* USB Mass storage Standard Inquiry Data */
40 const unsigned char STORAGE_Inquirydata[] = { //36
41 /* LUN 0 */
42 0x00,
43 0x80,
44 0x02,
45 0x02,
46 (USBD_STD_INQUIRY_LENGTH - 5),
47 0x00,
48 0x00,
49 0x00,
50 USB_MANUFACTURER, /* Manufacturer : 8 bytes */
51 USB_PRODUCT, /* Product : 16 Bytes */
52 'R', 'a', 'd', 'i', 'o', ' ', ' ', ' ',
53 '1', '.', '0', '0', /* Version : 4 Bytes */
54 /* LUN 1 */
55 0x00,
56 0x80,
57 0x02,
58 0x02,
59 (USBD_STD_INQUIRY_LENGTH - 5),
60 0x00,
61 0x00,
62 0x00,
63 USB_MANUFACTURER, /* Manufacturer : 8 bytes */
64 USB_PRODUCT, /* Product : 16 Bytes */
65 'R', 'a', 'd', 'i', 'o', ' ', ' ', ' ',
66 '1', '.', '0' ,'0', /* Version : 4 Bytes */
69 #define RESERVED_SECTORS (1 /*Boot*/ + 2 /*Fat table */ + 1 /*Root dir*/ + 8 /* one cluster for firmware.txt */)
71 int32_t fat12Write(const uint8_t * buffer, uint16_t sector, uint16_t count);
72 int32_t fat12Read(uint8_t * buffer, uint16_t sector, uint16_t count );
74 int8_t STORAGE_Init (uint8_t lun);
76 int8_t STORAGE_GetCapacity (uint8_t lun,
77 uint32_t *block_num,
78 uint32_t *block_size);
80 int8_t STORAGE_IsReady (uint8_t lun);
82 int8_t STORAGE_IsWriteProtected (uint8_t lun);
84 int8_t STORAGE_Read (uint8_t lun,
85 uint8_t *buf,
86 uint32_t blk_addr,
87 uint16_t blk_len);
89 int8_t STORAGE_Write (uint8_t lun,
90 uint8_t *buf,
91 uint32_t blk_addr,
92 uint16_t blk_len);
94 int8_t STORAGE_GetMaxLun (void);
96 const USBD_STORAGE_cb_TypeDef USBD_MICRO_SDIO_fops = // modified my OpenTX
98 STORAGE_Init,
99 STORAGE_GetCapacity,
100 STORAGE_IsReady,
101 STORAGE_IsWriteProtected,
102 STORAGE_Read,
103 STORAGE_Write,
104 STORAGE_GetMaxLun,
105 (int8_t *)STORAGE_Inquirydata,
108 const USBD_STORAGE_cb_TypeDef * const USBD_STORAGE_fops = &USBD_MICRO_SDIO_fops; // modified my OpenTX
110 #if defined(__cplusplus) && !defined(SIMU)
112 #endif
114 int8_t STORAGE_Init (uint8_t lun)
116 NVIC_InitTypeDef NVIC_InitStructure;
117 NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
118 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;
119 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
120 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
121 NVIC_Init(&NVIC_InitStructure);
123 /* TODO if no SD ... if( SD_Init() != 0)
125 return (-1);
128 return (0);
132 * @brief return medium capacity and block size
133 * @param lun : logical unit number
134 * @param block_num : number of physical block
135 * @param block_size : size of a physical block
136 * @retval Status
138 int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint32_t *block_size)
140 if (lun == STORAGE_EEPROM_LUN) {
141 *block_size = BLOCK_SIZE;
142 #if defined(EEPROM)
143 *block_num = RESERVED_SECTORS + EEPROM_SIZE/BLOCK_SIZE + FLASHSIZE/BLOCK_SIZE;
144 #else
145 *block_num = RESERVED_SECTORS + FLASHSIZE/BLOCK_SIZE;
146 #endif
147 return 0;
150 if (!SD_CARD_PRESENT())
151 return -1;
153 *block_size = BLOCK_SIZE;
155 static DWORD sector_count = 0;
156 if (sector_count == 0) {
157 if (disk_ioctl(0, GET_SECTOR_COUNT, &sector_count) != RES_OK) {
158 sector_count = 0;
159 return -1;
163 *block_num = sector_count;
165 return 0;
168 uint8_t lunReady[STORAGE_LUN_NBR];
170 void usbPluggedIn()
172 lunReady[STORAGE_SDCARD_LUN] = 1;
173 lunReady[STORAGE_EEPROM_LUN] = 1;
177 * @brief check whether the medium is ready
178 * @param lun : logical unit number
179 * @retval Status
181 int8_t STORAGE_IsReady (uint8_t lun)
183 #if defined(EEPROM)
184 if (lun == STORAGE_EEPROM_LUN) {
185 return (lunReady[STORAGE_EEPROM_LUN] != 0) ? 0 : -1;
187 #endif
189 return (lunReady[STORAGE_SDCARD_LUN] != 0 && SD_CARD_PRESENT()) ? 0 : -1;
193 * @brief check whether the medium is write-protected
194 * @param lun : logical unit number
195 * @retval Status
197 int8_t STORAGE_IsWriteProtected (uint8_t lun)
199 return 0;
203 * @brief Read data from the medium
204 * @param lun : logical unit number
205 * @param buf : Pointer to the buffer to save data
206 * @param blk_addr : address of 1st block to be read
207 * @param blk_len : nmber of blocks to be read
208 * @retval Status
211 int8_t STORAGE_Read (uint8_t lun,
212 uint8_t *buf,
213 uint32_t blk_addr,
214 uint16_t blk_len)
216 WATCHDOG_SUSPEND(100/*1s*/);
218 if (lun == STORAGE_EEPROM_LUN) {
219 return (fat12Read(buf, blk_addr, blk_len) == 0) ? 0 : -1;
222 // read without cache
223 return (__disk_read(0, buf, blk_addr, blk_len) == RES_OK) ? 0 : -1;
226 * @brief Write data to the medium
227 * @param lun : logical unit number
228 * @param buf : Pointer to the buffer to write from
229 * @param blk_addr : address of 1st block to be written
230 * @param blk_len : nmber of blocks to be read
231 * @retval Status
234 int8_t STORAGE_Write (uint8_t lun,
235 uint8_t *buf,
236 uint32_t blk_addr,
237 uint16_t blk_len)
239 WATCHDOG_SUSPEND(100/*1s*/);
241 if (lun == STORAGE_EEPROM_LUN) {
242 return (fat12Write(buf, blk_addr, blk_len) == 0) ? 0 : -1;
245 // write without cache
246 return (__disk_write(0, buf, blk_addr, blk_len) == RES_OK) ? 0 : -1;
250 * @brief Return number of supported logical unit
251 * @param None
252 * @retval number of logical unit
255 int8_t STORAGE_GetMaxLun (void)
257 return STORAGE_LUN_NBR - 1;
261 /* Firmware.txt */
262 const char firmware_txt[] =
263 #if defined(BOOT)
264 "OpenTX Bootloader"
265 #else
266 "OpenTX Firmware"
267 #endif
268 " for " FLAVOUR "\r\n\r\n"
269 #if defined(BOOT)
270 "BOOTVER "
271 #else
272 "FWVERSION "
273 #endif
274 "opentx-" FLAVOUR "-" VERSION " (" GIT_STR ")\r\n"
275 "DATE " DATE "\r\n"
276 "TIME " TIME "\r\n"
277 "req SD ver " REQUIRED_SDCARD_VERSION "\r\n"
278 #if !defined(BOOT)
279 "BOOTVER "
280 #else
281 "FWVERSION "
282 #endif
285 //------------------------------------------------------------------------------
287 * FAT12 boot sector partition.
289 #if defined(EEPROM)
290 #define TOTALSECTORS (RESERVED_SECTORS + (EEPROM_SIZE/BLOCK_SIZE) + (FLASHSIZE/BLOCK_SIZE))
291 #else
292 #define TOTALSECTORS (RESERVED_SECTORS + (FLASHSIZE/BLOCK_SIZE))
293 #endif
294 const char g_FATboot[BLOCK_SIZE] =
296 0xeb, 0x3c, 0x90, // Jump instruction.
297 'O', 'p', 'e', 'n', 'T', 'x', 0x00, 0x00, // OEM Name
298 0x00, 0x02, // Bytes per sector
299 0x08, // Sectors per FS cluster.
300 0x01, 0x00, // Reserved sector count
302 0x01, // Number of FATs
303 0x10, 0x00, // Number of root directory entries
304 TOTALSECTORS & 0x00ff, (TOTALSECTORS & 0xff00) >> 8, // Total sectors
305 0xf8, // Media descriptor
306 0x02, 0x00, // Sectors per FAT table
307 0x20, 0x00, // Sectors per track
308 0x40, 0x00, // Number of heads
309 0x00, 0x00, 0x00, 0x00, // Number of hidden sectors
311 0x00, 0x00, 0x00, 0x00, // Large number of sectors.
312 0x00, // Physical drive number
313 0x00, // Reserved
314 0x29, // Extended boot signature
315 'O', 'T', 'x', 0xD1, // Disk ID (serial number)
316 'V', 'I', 'R', 'T', 'F', 'S', ' ', ' ', ' ', ' ', ' ', // Volume label
317 'F', 'A', 'T', '1', '2', ' ', ' ', ' ', // FAT file system type
318 0x00, 0x00, // OS boot code
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
326 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
353 // File Attributes
354 // 0 0x01 Read Only.
355 // 1 0x02 Hidden.
356 // 2 0x04 System.
357 // 3 0x08 Volume Label.
358 // 4 0x10 Subdirectory.
359 // 5 0x20 Archive.
360 // 6 0x40 Device.
361 // 7 0x80 Reserved.
363 typedef struct
365 uint8_t name[8];
366 uint8_t ext[3];
367 uint8_t attribute;
368 uint8_t reserved;
369 uint8_t create_time_ms;
370 uint16_t create_time;
371 uint16_t create_date;
372 uint16_t access_date;
373 uint16_t ea_index;
374 uint16_t modify_time;
375 uint16_t modify_date;
376 uint16_t start_cluster;
377 uint32_t file_size;
378 } FATDirEntry_t;
380 // First 16 FAT root directory entries (1 sector)
381 const FATDirEntry_t g_DIRroot[] =
384 { USB_PRODUCT },
385 { ' ', ' ', ' '},
386 0x08, // Volume
387 0x00,
388 0x00,
389 0x0000,
390 0x0000,
391 0x0000,
392 0x0000,
393 0x0000,
394 0x0000,
395 0x0000,
396 0x00000000
399 { 'F', 'I', 'R', 'M', 'W', 'A', 'R', 'E'},
400 { 'T', 'X', 'T'},
401 0x21, // Readonly+Archive
402 0x00,
403 0x3E,
404 0xA301,
405 0x3D55,
406 0x3D55,
407 0x0000,
408 0xA302,
409 0x3D55,
410 0x0002,
411 sizeof(firmware_txt) + strlen(getOtherVersion())
414 { 'F', 'I', 'R', 'M', 'W', 'A', 'R', 'E'},
415 { 'B', 'I', 'N'},
416 #if defined(BOOT)
417 0x20, // Archive
418 #else
419 0x21, // Readonly+Archive
420 #endif
421 0x00,
422 0x3E,
423 0xA301,
424 0x3D55,
425 0x3D55,
426 0x0000,
427 0xA302,
428 0x3D55,
429 0x0003,
430 FLASHSIZE
432 #if defined(EEPROM)
434 { 'E', 'E', 'P', 'R', 'O', 'M', ' ', ' '},
435 { 'B', 'I', 'N'},
436 0x20, // Archive
437 0x00,
438 0x3E,
439 0xA301,
440 0x3D55,
441 0x3D55,
442 0x0000,
443 0xA302,
444 0x3D55,
445 0x0003 + (FLASHSIZE/BLOCK_SIZE)/8,
446 EEPROM_SIZE
448 #endif
449 // Emty entries are 0x00, omitted here. Up to 16 entries can be defined here
452 static void writeByte(uint8_t *buffer, uint16_t sector, int byte, uint8_t value)
454 if (byte >= sector* BLOCK_SIZE && byte < (sector+1)* BLOCK_SIZE)
455 buffer[byte - sector*BLOCK_SIZE] = value;
458 static void pushCluster(uint8_t *buffer, uint16_t sector, uint16_t & cluster, int & rest, uint16_t value)
460 // boot sector is in front of FAT
461 sector= sector-1;
463 // First byte of the cluster
464 int startbyte = cluster *3/2;
465 if (cluster % 2 == 0) {
466 // First 12 bit half
467 rest = value >> 8;
468 writeByte(buffer, sector, startbyte, value & 0xff);
469 } else {
470 // second 12 bit half, write rest and next byte
471 writeByte(buffer, sector, startbyte, value << 4 | rest );
472 writeByte(buffer, sector, startbyte+1, (value >> 4) & 0xff);
474 cluster++;
477 // count is number of 512 byte sectors
478 int32_t fat12Read(uint8_t * buffer, uint16_t sector, uint16_t count)
480 while(count) {
481 memset(buffer, 0x00, BLOCK_SIZE);
482 if (sector == 0) {
483 memcpy(buffer, g_FATboot, sizeof(g_FATboot) ) ;
485 else if (sector == 1 || sector == 2) {
486 // FAT table. Generate on the fly to save the 1024 byte flash space
487 uint16_t cluster=0;
488 int rest;
489 pushCluster (buffer, sector, cluster, rest, (uint16_t) 0xFF8);
490 pushCluster (buffer, sector, cluster, rest, (uint16_t) 0xFFF);
492 // Entry for firmware.txt, exactly one cluster
493 pushCluster (buffer, sector, cluster, rest, (uint16_t) 0xFFF);
495 // Entry for firmware.bin
496 for (int i=0;i<FLASHSIZE/BLOCK_SIZE/8 -1;i++)
497 pushCluster (buffer, sector, cluster, rest, cluster+1);
498 pushCluster (buffer, sector, cluster, rest, (uint16_t) 0xFFF);
500 #if defined(EEPROM)
501 // Entry for eeprom.bin
502 for (int i=0;i<EEPROM_SIZE/BLOCK_SIZE/8 -1;i++)
503 pushCluster (buffer, sector, cluster, rest, cluster+1);
504 pushCluster (buffer, sector, cluster, rest, (uint16_t) 0xFFF);
505 #endif
507 // Ensure last cluster is written if it is the first half
508 pushCluster (buffer, sector, cluster, rest, (uint16_t) 0x000);
510 // Rest is 0x0 as per memset
512 else if (sector == 3) {
513 memcpy(buffer, g_DIRroot, sizeof(g_DIRroot) ) ;
515 else if (sector == 4)
517 memcpy(buffer, firmware_txt, sizeof(firmware_txt));
518 memcpy(buffer + sizeof(firmware_txt), getOtherVersion(), strlen(getOtherVersion()));
520 else if (sector < RESERVED_SECTORS)
522 // allocated to firmware.txt
524 else if (sector < RESERVED_SECTORS + (FLASHSIZE/BLOCK_SIZE )) {
525 uint32_t address;
526 address = sector - RESERVED_SECTORS;
527 address *= BLOCK_SIZE;
528 address += FIRMWARE_ADDRESS;
529 memcpy(buffer, (uint8_t *)address, BLOCK_SIZE);
531 #if defined(EEPROM)
532 else if (sector < RESERVED_SECTORS + (EEPROM_SIZE/BLOCK_SIZE) + (FLASHSIZE/BLOCK_SIZE)) {
533 eepromReadBlock(buffer, (sector - RESERVED_SECTORS - (FLASHSIZE/BLOCK_SIZE))*BLOCK_SIZE, BLOCK_SIZE);
535 #endif
536 buffer += BLOCK_SIZE ;
537 sector++ ;
538 count-- ;
540 return 0;
545 int32_t fat12Write(const uint8_t * buffer, uint16_t sector, uint16_t count)
547 enum FatWriteOperation {
548 FATWRITE_NONE,
549 FATWRITE_EEPROM,
550 FATWRITE_FIRMWARE
553 // Silence compiler warning that this is not used on X10
554 __attribute__((unused)) static uint8_t operation = FATWRITE_NONE;
556 TRACE("FAT12 Write(sector=%d, count=%d)", sector, count);
558 if (sector < RESERVED_SECTORS) {
559 // reserved, read-only
561 else if (sector < RESERVED_SECTORS + (FLASHSIZE/BLOCK_SIZE)) {
562 #if !defined(BOOT) // Don't allow overwrite of running firmware
563 return -1;
564 #else
565 // firmware
566 uint32_t address;
567 address = sector - RESERVED_SECTORS;
568 address *= BLOCK_SIZE;
569 address += FIRMWARE_ADDRESS;
570 while (count) {
571 for (uint32_t i=0; i<BLOCK_SIZE/FLASH_PAGESIZE; i++) {
572 if (address >= FIRMWARE_ADDRESS+BOOTLOADER_SIZE/*protect bootloader*/ && address <= FIRMWARE_ADDRESS+FLASHSIZE-FLASH_PAGESIZE) {
573 if (address == FIRMWARE_ADDRESS+BOOTLOADER_SIZE && isFirmwareStart(buffer)) {
574 TRACE("FIRMWARE start found in sector %d", sector);
575 operation = FATWRITE_FIRMWARE;
577 if (operation == FATWRITE_FIRMWARE) {
578 flashWrite((uint32_t *)address, (uint32_t *)buffer);
581 address += FLASH_PAGESIZE;
582 buffer += FLASH_PAGESIZE;
584 sector++;
585 count--;
586 if (sector-RESERVED_SECTORS >= (FLASHSIZE/BLOCK_SIZE)) {
587 TRACE("FIRMWARE end written at sector %d", sector-1);
588 operation = FATWRITE_NONE;
591 #endif
593 #if defined(EEPROM)
594 else if (sector < RESERVED_SECTORS + (EEPROM_SIZE/BLOCK_SIZE) + (FLASHSIZE/BLOCK_SIZE)) {
595 // eeprom
596 while (count) {
597 if (operation == FATWRITE_NONE && isEepromStart(buffer)) {
598 TRACE("EEPROM start found in sector %d", sector);
599 operation = FATWRITE_EEPROM;
601 if (operation == FATWRITE_EEPROM) {
602 eepromWriteBlock((uint8_t *)buffer, (sector-RESERVED_SECTORS-(FLASHSIZE/BLOCK_SIZE))*BLOCK_SIZE, BLOCK_SIZE);
604 buffer += BLOCK_SIZE;
605 sector++;
606 count--;
607 if (sector-RESERVED_SECTORS >= (EEPROM_SIZE/BLOCK_SIZE)+(FLASHSIZE/BLOCK_SIZE)) {
608 TRACE("EEPROM end written at sector %d", sector-1);
609 operation = FATWRITE_NONE;
613 #endif
614 return 0 ;