fix #46 complete uf2 writing using tud_msc_write10_complete_cb

This commit is contained in:
hathach 2019-02-22 00:21:34 +07:00
parent d9b275c321
commit 9ed3f5ea32
3 changed files with 29 additions and 25 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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);