fix #46 complete uf2 writing using tud_msc_write10_complete_cb
This commit is contained in:
		| @@ -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. |     // - 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. |     // 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 |     // - nRF52840 dfu serial/uf2 are USB-based which are DMA and should have no problems. | ||||||
|     // does not erase page in advance like dfu serial |     // | ||||||
|  |     // Note: MSC uf2 does not erase page in advance like dfu serial | ||||||
|     if ( need_erase ) nrf_nvmc_page_erase(_fl_addr); |     if ( need_erase ) nrf_nvmc_page_erase(_fl_addr); | ||||||
|  |  | ||||||
|     nrf_nvmc_write_words(_fl_addr, (uint32_t *) _fl_buf, FLASH_PAGE_SIZE / 4); |     nrf_nvmc_write_words(_fl_addr, (uint32_t *) _fl_buf, FLASH_PAGE_SIZE / 4); | ||||||
|   | |||||||
| @@ -39,6 +39,8 @@ | |||||||
|  |  | ||||||
| #if CFG_TUD_MSC | #if CFG_TUD_MSC | ||||||
|  |  | ||||||
|  | #include "bootloader.h" | ||||||
|  |  | ||||||
| /*------------------------------------------------------------------*/ | /*------------------------------------------------------------------*/ | ||||||
| /* MACRO TYPEDEF CONSTANT ENUM | /* MACRO TYPEDEF CONSTANT ENUM | ||||||
|  *------------------------------------------------------------------*/ |  *------------------------------------------------------------------*/ | ||||||
| @@ -46,8 +48,10 @@ | |||||||
| /*------------------------------------------------------------------*/ | /*------------------------------------------------------------------*/ | ||||||
| /* UF2 | /* UF2 | ||||||
|  *------------------------------------------------------------------*/ |  *------------------------------------------------------------------*/ | ||||||
|  | static WriteState _wr_state = { 0 }; | ||||||
|  |  | ||||||
| void read_block(uint32_t block_no, uint8_t *data); | 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 | // 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; |   uint32_t count = 0; | ||||||
|   int wr_ret; |   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++; |     lba++; | ||||||
|     buffer += 512; |     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; |   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 tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) | ||||||
| { | { | ||||||
|   (void) lun; |   (void) lun; | ||||||
|   | |||||||
| @@ -119,8 +119,6 @@ static FAT_BootBlock const BootBlock = { | |||||||
| #define NRF_LOG_DEBUG(...) | #define NRF_LOG_DEBUG(...) | ||||||
| #define NRF_LOG_WARNING(...) | #define NRF_LOG_WARNING(...) | ||||||
|  |  | ||||||
| static WriteState _wr_state = { 0 }; |  | ||||||
|  |  | ||||||
| // get current.uf2 flash size in bytes, round up to 256 bytes | // get current.uf2 flash size in bytes, round up to 256 bytes | ||||||
| static uint32_t current_flash_size(void) | static uint32_t current_flash_size(void) | ||||||
| { | { | ||||||
| @@ -241,21 +239,6 @@ void read_block(uint32_t block_no, uint8_t *data) { | |||||||
| /* Write UF2 | /* 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 | /** Write an block | ||||||
|  * |  * | ||||||
|  * @return number of bytes processed, only 3 following values |  * @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 |  * 512 : write is successful | ||||||
|  *   0 : is busy with flashing, tinyusb stack will call write_block again with the same parameters later on |  *   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; |     UF2_Block *bl = (void *)data; | ||||||
|     WriteState* state = &_wr_state; |  | ||||||
|  |  | ||||||
|      NRF_LOG_DEBUG("Write magic: %x", bl->magicStart0); |      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) { |             if (state->numWritten >= state->numBlocks) { | ||||||
|                 // flush last blocks |                 // flush last blocks | ||||||
|                 flash_nrf5x_flush(true); |                 flash_nrf5x_flush(true); | ||||||
|  |  | ||||||
|                 uf2_write_complete(state->numBlocks); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         NRF_LOG_DEBUG("wr %d=%d (of %d)", state->numWritten, bl->blockNo, bl->numBlocks); |         NRF_LOG_DEBUG("wr %d=%d (of %d)", state->numWritten, bl->blockNo, bl->numBlocks); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user