add need_erase for flash_nrf5x. Only uf2 erase when flush, dfu serial (uart and cdc) will prepare erase in advance.
This commit is contained in:
		| @@ -433,7 +433,7 @@ uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet) | |||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|               flash_nrf5x_write(DFU_BANK_0_REGION_START+m_data_received, p_data, data_length); |               flash_nrf5x_write(DFU_BANK_0_REGION_START + m_data_received, p_data, data_length, false); | ||||||
|               pstorage_callback_handler(mp_storage_handle_active, PSTORAGE_STORE_OP_CODE, NRF_SUCCESS, (uint8_t *) p_data, data_length); |               pstorage_callback_handler(mp_storage_handle_active, PSTORAGE_STORE_OP_CODE, NRF_SUCCESS, (uint8_t *) p_data, data_length); | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -446,7 +446,7 @@ uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet) | |||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|               if ( !is_ota() ) flash_nrf5x_flush(); |               if ( !is_ota() ) flash_nrf5x_flush(false); | ||||||
|  |  | ||||||
|               // The entire image has been received. Return NRF_SUCCESS. |               // The entire image has been received. Return NRF_SUCCESS. | ||||||
|               err_code = NRF_SUCCESS; |               err_code = NRF_SUCCESS; | ||||||
|   | |||||||
| @@ -45,33 +45,31 @@ | |||||||
| static uint32_t _fl_addr = FLASH_CACHE_INVALID_ADDR; | static uint32_t _fl_addr = FLASH_CACHE_INVALID_ADDR; | ||||||
| static uint8_t _fl_buf[FLASH_PAGE_SIZE] __attribute__((aligned(4))); | static uint8_t _fl_buf[FLASH_PAGE_SIZE] __attribute__((aligned(4))); | ||||||
|  |  | ||||||
| void flash_nrf5x_flush(void) | void flash_nrf5x_flush (bool need_erase) | ||||||
| { | { | ||||||
|   if ( _fl_addr == FLASH_CACHE_INVALID_ADDR ) return; |   if ( _fl_addr == FLASH_CACHE_INVALID_ADDR ) return; | ||||||
|  |  | ||||||
|   if ( memcmp(_fl_buf, (void *) _fl_addr, FLASH_PAGE_SIZE) != 0 ) |   if ( memcmp(_fl_buf, (void *) _fl_addr, FLASH_PAGE_SIZE) != 0 ) | ||||||
|   { |   { | ||||||
| #ifdef NRF52840_XXAA |  | ||||||
|     // - 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. Note MSC uf2 | ||||||
|     // does not erase page in advance like dfu serial |     // does not erase page in advance like dfu serial | ||||||
|     nrf_nvmc_page_erase(_fl_addr); |     if ( need_erase ) nrf_nvmc_page_erase(_fl_addr); | ||||||
| #endif |  | ||||||
|     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); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   _fl_addr = FLASH_CACHE_INVALID_ADDR; |   _fl_addr = FLASH_CACHE_INVALID_ADDR; | ||||||
| } | } | ||||||
|  |  | ||||||
| void flash_nrf5x_write (uint32_t dst, void const *src, int len) | void flash_nrf5x_write (uint32_t dst, void const *src, int len, bool need_erase) | ||||||
| { | { | ||||||
|   uint32_t newAddr = dst & ~(FLASH_PAGE_SIZE - 1); |   uint32_t newAddr = dst & ~(FLASH_PAGE_SIZE - 1); | ||||||
|  |  | ||||||
|   if ( newAddr != _fl_addr ) |   if ( newAddr != _fl_addr ) | ||||||
|   { |   { | ||||||
|     flash_nrf5x_flush(); |     flash_nrf5x_flush(need_erase); | ||||||
|     _fl_addr = newAddr; |     _fl_addr = newAddr; | ||||||
|     memcpy(_fl_buf, (void *) newAddr, FLASH_PAGE_SIZE); |     memcpy(_fl_buf, (void *) newAddr, FLASH_PAGE_SIZE); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -46,9 +46,8 @@ | |||||||
|  extern "C" { |  extern "C" { | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| //void flash_erase(uint32_t page_addr); | void flash_nrf5x_write (uint32_t dst, void const *src, int len, bool need_erase); | ||||||
| void flash_nrf5x_write (uint32_t dst, void const *src, int len); | void flash_nrf5x_flush (bool need_erase); | ||||||
| void flash_nrf5x_flush(void); |  | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
|  } |  } | ||||||
|   | |||||||
| @@ -170,8 +170,12 @@ int main(void) | |||||||
|   // When updating SoftDevice, bootloader will reset before swapping SD |   // When updating SoftDevice, bootloader will reset before swapping SD | ||||||
|   if (bootloader_dfu_sd_in_progress()) |   if (bootloader_dfu_sd_in_progress()) | ||||||
|   { |   { | ||||||
|  |     led_blink_fast(true); | ||||||
|  |  | ||||||
|     APP_ERROR_CHECK( bootloader_dfu_sd_update_continue() ); |     APP_ERROR_CHECK( bootloader_dfu_sd_update_continue() ); | ||||||
|     APP_ERROR_CHECK( bootloader_dfu_sd_update_finalize() ); |     APP_ERROR_CHECK( bootloader_dfu_sd_update_finalize() ); | ||||||
|  |  | ||||||
|  |     led_blink_fast(false); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /*------------- Determine DFU mode (Serial, OTA, FRESET or normal) -------------*/ |   /*------------- Determine DFU mode (Serial, OTA, FRESET or normal) -------------*/ | ||||||
|   | |||||||
| @@ -51,8 +51,8 @@ typedef struct { | |||||||
| STATIC_ASSERT(sizeof(DirEntry) == 32); | STATIC_ASSERT(sizeof(DirEntry) == 32); | ||||||
|  |  | ||||||
| struct TextFile { | struct TextFile { | ||||||
|     const char name[11]; |   char const name[11]; | ||||||
|     const char *content; |   char const *content; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #define NUM_FAT_BLOCKS UF2_NUM_BLOCKS | #define NUM_FAT_BLOCKS UF2_NUM_BLOCKS | ||||||
| @@ -76,7 +76,7 @@ const char indexFile[] = // | |||||||
|     "</body>" |     "</body>" | ||||||
|     "</html>\n"; |     "</html>\n"; | ||||||
|  |  | ||||||
| static const struct TextFile info[] = { | static struct TextFile const info[] = { | ||||||
|     {.name = "INFO_UF2TXT", .content = infoUf2File}, |     {.name = "INFO_UF2TXT", .content = infoUf2File}, | ||||||
|     {.name = "INDEX   HTM", .content = indexFile}, |     {.name = "INDEX   HTM", .content = indexFile}, | ||||||
|     {.name = "CURRENT UF2"}, |     {.name = "CURRENT UF2"}, | ||||||
| @@ -97,7 +97,7 @@ static const struct TextFile info[] = { | |||||||
| #define START_ROOTDIR      (START_FAT1 + SECTORS_PER_FAT) | #define START_ROOTDIR      (START_FAT1 + SECTORS_PER_FAT) | ||||||
| #define START_CLUSTERS     (START_ROOTDIR + ROOT_DIR_SECTORS) | #define START_CLUSTERS     (START_ROOTDIR + ROOT_DIR_SECTORS) | ||||||
|  |  | ||||||
| static const FAT_BootBlock BootBlock = { | static FAT_BootBlock const BootBlock = { | ||||||
|     .JumpInstruction      = {0xeb, 0x3c, 0x90}, |     .JumpInstruction      = {0xeb, 0x3c, 0x90}, | ||||||
|     .OEMInfo              = "UF2 UF2 ", |     .OEMInfo              = "UF2 UF2 ", | ||||||
|     .SectorSize           = 512, |     .SectorSize           = 512, | ||||||
| @@ -133,7 +133,7 @@ static uint32_t get_flash_size(void) | |||||||
|       flash_sz = 256; |       flash_sz = 256; | ||||||
|     }else |     }else | ||||||
|     { |     { | ||||||
|       const bootloader_settings_t * boot_setting; |       bootloader_settings_t const * boot_setting; | ||||||
|       bootloader_util_settings_get(&boot_setting); |       bootloader_util_settings_get(&boot_setting); | ||||||
|  |  | ||||||
|       // if bank0 size is not valid, happens when flashed with jlink |       // if bank0 size is not valid, happens when flashed with jlink | ||||||
| @@ -150,7 +150,8 @@ static uint32_t get_flash_size(void) | |||||||
|   return flash_sz; |   return flash_sz; | ||||||
| } | } | ||||||
|  |  | ||||||
| void padded_memcpy(char *dst, const char *src, int len) { | void padded_memcpy (char *dst, char const *src, int len) | ||||||
|  | { | ||||||
|     for (int i = 0; i < len; ++i) { |     for (int i = 0; i < len; ++i) { | ||||||
|         if (*src) |         if (*src) | ||||||
|             *dst = *src++; |             *dst = *src++; | ||||||
| @@ -193,11 +194,11 @@ void read_block(uint32_t block_no, uint8_t *data) { | |||||||
|         sectionIdx -= START_ROOTDIR; |         sectionIdx -= START_ROOTDIR; | ||||||
|         if (sectionIdx == 0) { |         if (sectionIdx == 0) { | ||||||
|             DirEntry *d = (void *)data; |             DirEntry *d = (void *)data; | ||||||
|             padded_memcpy(d->name, (const char *)BootBlock.VolumeLabel, 11); |             padded_memcpy(d->name, (char const *) BootBlock.VolumeLabel, 11); | ||||||
|             d->attrs = 0x28; |             d->attrs = 0x28; | ||||||
|             for (int i = 0; i < NUM_INFO; ++i) { |             for (int i = 0; i < NUM_INFO; ++i) { | ||||||
|                 d++; |                 d++; | ||||||
|                 const struct TextFile *inf = &info[i]; |                 struct TextFile const *inf = &info[i]; | ||||||
|                 d->size = inf->content ? strlen(inf->content) : UF2_SIZE; |                 d->size = inf->content ? strlen(inf->content) : UF2_SIZE; | ||||||
|                 d->startCluster = i + 2; |                 d->startCluster = i + 2; | ||||||
|                 padded_memcpy(d->name, inf->name, 11); |                 padded_memcpy(d->name, inf->name, 11); | ||||||
| @@ -287,7 +288,7 @@ int write_block(uint32_t block_no, uint8_t *data, bool quiet/*, WriteState *stat | |||||||
|           led_blink_fast(true); |           led_blink_fast(true); | ||||||
|         } |         } | ||||||
|      |      | ||||||
|         flash_nrf5x_write(bl->targetAddr, bl->data, bl->payloadSize); |         flash_nrf5x_write(bl->targetAddr, bl->data, bl->payloadSize, true); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (state && bl->numBlocks) { |     if (state && bl->numBlocks) { | ||||||
| @@ -307,7 +308,7 @@ 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(); |                 flash_nrf5x_flush(true); | ||||||
|  |  | ||||||
|                 uf2_write_complete(state->numBlocks); |                 uf2_write_complete(state->numBlocks); | ||||||
|             } |             } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user