+void 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;
+
+ print( NL );
+ print("Block ");
+ printHex( sector );
+ print(" ");
+ printHex( (size_t)start );
+ print(" -> ");
+ printHex( (size_t)end );
+ print( NL );
+
+ // 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 );
+ }
+}
+
+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);
+}
+