void WriteApplicationPage(uint32_t address) { /*Set the correct settings and store critical registers before NVM-workaround*/ #ifdef WORKAROUND Prepare_to_Sleep(); #endif /*Assembly "function" to preform page write*/ nvm_flash_split_write_app_page(address); }
/** * Test nvm_flash_load_word_to_buffer(), nvm_flash_erase_app_page() and * nvm_flash_split_write_app_page(). * * Test procedure: * - Erase page in application table section. * - Verify the page is erased by comparing each word in flash. * - Write page to application table section * - Verify each byte written correctly by comparing each word in flash * * \return STATUS_OK if test succeeded, otherwise ERR_BAD_DATA */ static status_code_t test_split_write_app_table(void) { flash_addr_t page_addr; page_addr = APPTABLE_SECTION_START + 3 * FLASH_PAGE_SIZE; set_buffer(buffer, FLASH_ERASED); nvm_flash_erase_app_page(page_addr); if (!is_flash_page_equal_to_buffer(page_addr, buffer)) { return ERR_BAD_DATA; } fill_flash_page_buffer(buffer, 0x317A); nvm_flash_split_write_app_page(page_addr); if (!is_flash_page_equal_to_buffer(page_addr, buffer)) { return ERR_BAD_DATA; } return STATUS_OK; }
/** * \brief Erase and write specific parts of application flash section * * \param address the address to where to write * \param buf pointer to the data * \param len the number of bytes to write * \param b_blank_check if True then the page flash is checked before write * to run or not the erase page command. * * Set b_blank_check to false if all application flash is erased before. */ void nvm_flash_erase_and_write_buffer(flash_addr_t address, const void *buf, uint16_t len, bool b_blank_check) { uint16_t w_value; uint16_t page_pos; bool b_flag_erase; #if (FLASH_SIZE>0x10000) uint32_t page_address; uint32_t opt_address = address; #else uint16_t page_address; uint16_t opt_address = (uint16_t)address; #endif // Compute the start of the page to be modified page_address = opt_address-(opt_address%FLASH_PAGE_SIZE); // For each page while ( len ) { b_flag_erase = false; nvm_wait_until_ready(); for (page_pos=0; page_pos<FLASH_PAGE_SIZE; page_pos+=2 ) { if (b_blank_check) { // Read flash to know if the erase command is mandatory w_value = nvm_flash_read_word(page_address); if (w_value!=0xFFFF) { b_flag_erase = true; // The page is not empty } }else{ w_value = 0xFFFF; } // Update flash buffer if (len) { if (opt_address == page_address) { // The MSB of flash word must be changed // because the address is even len--; opt_address++; LSB(w_value)=*(uint8_t*)buf; buf=(uint8_t*)buf+1; } } if (len) { if (opt_address == (page_address+1)) { // The LSB of flash word must be changed // because the user buffer is not empty len--; opt_address++; MSB(w_value)=*(uint8_t*)buf; buf=(uint8_t*)buf+1; } } // Load flash buffer nvm_flash_load_word_to_buffer(page_address,w_value); page_address+=2; } // Write flash buffer if (b_flag_erase) { nvm_flash_atomic_write_app_page(page_address-FLASH_PAGE_SIZE); }else{ nvm_flash_split_write_app_page(page_address-FLASH_PAGE_SIZE); } } }