diff --git a/src/flash_nrf5x.c b/src/flash_nrf5x.c index bc13aa2..9145a31 100644 --- a/src/flash_nrf5x.c +++ b/src/flash_nrf5x.c @@ -53,8 +53,9 @@ void flash_nrf5x_flush (bool need_erase) { // - nRF52832 dfu via uart can miss incoming byte when erasing because cpu is blocked for > 2ms. // Since dfu_prepare_func_app_erase() already erase the page for us, we can skip it here. - // - nRF52840 dfu serial/uf2 are USB-based which are DMA and should have no problems. Note MSC uf2 - // does not erase page in advance like dfu serial + // - nRF52840 dfu serial/uf2 are USB-based which are DMA and should have no problems. + // + // Note: MSC uf2 does not erase page in advance like dfu serial if ( need_erase ) nrf_nvmc_page_erase(_fl_addr); nrf_nvmc_write_words(_fl_addr, (uint32_t *) _fl_buf, FLASH_PAGE_SIZE / 4); diff --git a/src/usb/msc_uf2.c b/src/usb/msc_uf2.c index a241055..4f9109a 100644 --- a/src/usb/msc_uf2.c +++ b/src/usb/msc_uf2.c @@ -39,6 +39,8 @@ #if CFG_TUD_MSC +#include "bootloader.h" + /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ @@ -46,8 +48,10 @@ /*------------------------------------------------------------------*/ /* UF2 *------------------------------------------------------------------*/ +static WriteState _wr_state = { 0 }; + void read_block(uint32_t block_no, uint8_t *data); -int write_block(uint32_t block_no, uint8_t *data, bool quiet/*, WriteState *state*/); +int write_block(uint32_t block_no, uint8_t *data, bool quiet, WriteState *state); //--------------------------------------------------------------------+ // tinyusb callbacks @@ -137,7 +141,7 @@ int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* uint32_t count = 0; int wr_ret; - while ( (count < bufsize) && ((wr_ret = write_block(lba, buffer, false)) > 0) ) + while ( (count < bufsize) && ((wr_ret = write_block(lba, buffer, false, &_wr_state)) > 0) ) { lba++; buffer += 512; @@ -148,6 +152,25 @@ int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* return (wr_ret < 0) ? bufsize : count; } +// Callback invoked when WRITE10 command is completed (status received and accepted by host). +void tud_msc_write10_complete_cb(uint8_t lun) +{ + // uf2 file writing is complete --> complete DFU process + if ( _wr_state.numBlocks && (_wr_state.numWritten >= _wr_state.numBlocks) ) + { + led_state(STATE_WRITING_FINISHED); + + dfu_update_status_t update_status; + + memset(&update_status, 0, sizeof(dfu_update_status_t )); + update_status.status_code = DFU_UPDATE_APP_COMPLETE; + update_status.app_crc = 0; // skip CRC checking with uf2 upgrade + update_status.app_size = _wr_state.numBlocks*256; + + bootloader_dfu_update_process(update_status); + } +} + void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) { (void) lun; diff --git a/src/usb/uf2/ghostfat.c b/src/usb/uf2/ghostfat.c index f4311cf..1f41c10 100644 --- a/src/usb/uf2/ghostfat.c +++ b/src/usb/uf2/ghostfat.c @@ -119,8 +119,6 @@ static FAT_BootBlock const BootBlock = { #define NRF_LOG_DEBUG(...) #define NRF_LOG_WARNING(...) -static WriteState _wr_state = { 0 }; - // get current.uf2 flash size in bytes, round up to 256 bytes static uint32_t current_flash_size(void) { @@ -241,21 +239,6 @@ void read_block(uint32_t block_no, uint8_t *data) { /* Write UF2 *------------------------------------------------------------------*/ -/** uf2 upgrade complete -> inform bootloader to update setting and reset */ -static void uf2_write_complete(uint32_t numBlocks) -{ - led_state(STATE_WRITING_FINISHED); - - dfu_update_status_t update_status; - - memset(&update_status, 0, sizeof(dfu_update_status_t )); - update_status.status_code = DFU_UPDATE_APP_COMPLETE; - update_status.app_crc = 0; // skip CRC checking with uf2 upgrade - update_status.app_size = numBlocks*256; - - bootloader_dfu_update_process(update_status); -} - /** Write an block * * @return number of bytes processed, only 3 following values @@ -263,9 +246,8 @@ static void uf2_write_complete(uint32_t numBlocks) * 512 : write is successful * 0 : is busy with flashing, tinyusb stack will call write_block again with the same parameters later on */ -int write_block(uint32_t block_no, uint8_t *data, bool quiet/*, WriteState *state*/) { +int write_block(uint32_t block_no, uint8_t *data, bool quiet, WriteState *state) { UF2_Block *bl = (void *)data; - WriteState* state = &_wr_state; NRF_LOG_DEBUG("Write magic: %x", bl->magicStart0); @@ -318,8 +300,6 @@ int write_block(uint32_t block_no, uint8_t *data, bool quiet/*, WriteState *stat if (state->numWritten >= state->numBlocks) { // flush last blocks flash_nrf5x_flush(true); - - uf2_write_complete(state->numBlocks); } } NRF_LOG_DEBUG("wr %d=%d (of %d)", state->numWritten, bl->blockNo, bl->numBlocks);