+int sector_print( void* buf, size_t sector, size_t chunks )
+{
+ uint8_t* start = (uint8_t*)buf + sector * USB_DFU_TRANSFER_SIZE;
+ uint8_t* end = (uint8_t*)buf + (sector + 1) * USB_DFU_TRANSFER_SIZE;
+ uint8_t* pos = start;
+
+ // Verify if sector erased
+ FTFL.fccob.read_1s_section.fcmd = FTFL_FCMD_READ_1s_SECTION;
+ FTFL.fccob.read_1s_section.addr = (uintptr_t)start;
+ FTFL.fccob.read_1s_section.margin = FTFL_MARGIN_NORMAL;
+ FTFL.fccob.read_1s_section.num_words = 250; // 2000 kB / 64 bits
+ int retval = ftfl_submit_cmd();
+
+#ifdef FLASH_DEBUG
+ print( NL );
+ print("Block ");
+ printHex( sector );
+ print(" ");
+ printHex( (size_t)start );
+ print(" -> ");
+ printHex( (size_t)end );
+ print(" Erased: ");
+ printHex( retval );
+ print( NL );
+#endif
+
+ // Display sector
+ for ( size_t line = 0; pos < end - 24; line++ )
+ {
+ // Each Line
+ printHex_op( (size_t)pos, 4 );
+ print(": ");
+
+ // Each 2 byte chunk
+ for ( size_t chunk = 0; chunk < chunks; chunk++ )
+ {
+ // Print out the two bytes (second one first)
+ printHex_op( *(pos + 1), 2 );
+ printHex_op( *pos, 2 );
+ print(" ");
+ pos += 2;
+ }
+
+ print( NL );
+ }
+
+ return retval;
+}
+
+static enum dfu_status setup_read( size_t off, size_t *len, void **buf )
+{
+ // Calculate starting address from offset
+ *buf = (void*)&_app_rom + (USB_DFU_TRANSFER_SIZE / 4) * off;
+
+ // Calculate length of transfer
+ /*
+ *len = *buf > (void*)(&_app_rom_end) - USB_DFU_TRANSFER_SIZE
+ ? 0 : USB_DFU_TRANSFER_SIZE;
+ */
+
+ // Check for error
+ /*
+ if ( *buf > (void*)&_app_rom_end )
+ return (DFU_STATUS_errADDRESS);
+ */
+
+ return (DFU_STATUS_OK);
+}
+