/** * Test nvm_user_sig_write_buffer(). * * Test procedure: * - Erase and write to user signature row with some known values * - Write other values to user signature row with automatic erasing disabled * - Verify contents is NOT equal to buffer * * \return STATUS_OK if test succeeded, otherwise ERR_BAD_DATA */ static status_code_t test_write_no_erase(void) { // Clear memory buffer set_buffer(buffer, FLASH_ERASED); // Set some test values buffer[0] = 0xAA; buffer[1] = 0xEE; buffer[2] = 0xAA; buffer[3] = 0xEE; // Erase and write data to user signature row: nvm_user_sig_write_buffer(TEST_ADDR, &buffer, BUFFER_SIZE, true); // Clear memory buffer set_buffer(buffer, FLASH_ERASED); // Set some other test values buffer[0] = 0xCA; buffer[1] = 0xFE; buffer[2] = 0xBA; buffer[3] = 0xBE; // Write test values to user signature row without erasing: nvm_user_sig_write_buffer(TEST_ADDR, &buffer, BUFFER_SIZE, false); // Verify that contents is not equal: if (is_user_sig_equal_to_buffer(TEST_ADDR, buffer, BUFFER_SIZE)) { return ERR_BAD_DATA; } return STATUS_OK; }
status_code_t nvm_write_char(mem_type_t mem, uint32_t address, uint8_t data) { switch (mem) { case INT_FLASH: nvm_flash_erase_and_write_buffer((flash_addr_t)address, (const void *)&data, 1, true); break; case INT_USERPAGE: nvm_user_sig_write_buffer((flash_addr_t)address, (const void *)&data, 1, true); break; case INT_EEPROM: nvm_eeprom_write_byte((eeprom_addr_t)address, data); break; #if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX) case AT45DBX: if (!at45dbx_write_byte_open(address)) { return ERR_BAD_ADDRESS; } at45dbx_write_byte(data); at45dbx_write_close(); #endif default: return ERR_INVALID_ARG; } return STATUS_OK; }
/** * Test nvm_user_sig_read_buffer(). * * Test procedure: * - Write to user signature row * - Read back with nvm_user_sig_read_buffer(). * - Verify contents * * \return STATUS_OK if test succeeded, otherwise ERR_BAD_DATA */ static status_code_t test_read(void) { uint8_t i; uint8_t mybuffer[BUFFER_SIZE]; // Clear memory buffer set_buffer(buffer, FLASH_ERASED); // Set some test values buffer[0] = 0xB0; buffer[1] = 0x0B; buffer[2] = 0xB0; buffer[3] = 0x0B; buffer[4] = 0xB0; buffer[5] = 0x0B; // Erase and write test values to user signature row nvm_user_sig_write_buffer(TEST_ADDR, &buffer, BUFFER_SIZE, true); // Read back nvm_user_sig_read_buffer(TEST_ADDR, mybuffer, BUFFER_SIZE); // Verify for (i=0; i < BUFFER_SIZE; i++) { if (buffer[i] != mybuffer[i]) { return ERR_BAD_DATA; } } return STATUS_OK; }
/** \brief Write a buffer to non-volatile RAM * * This routine writes \c count Bytes to the NVRAM destination pointed * to by \c dst from the source buffer pointed to by \c src. * * \param dst the write destination in the NVRAM address space * \param src the source buffer in program data memory space * \param count the number of Bytes to write * * \return Nothing. */ void nvram_write(nvram_addr_t dst, const void *src, size_t count) { #if XMEGA nvm_wait_until_ready(); nvm_user_sig_write_buffer((flash_addr_t)(dst + SENSOR_NVM_OFFSET), src, count, true); /* check for blank, erase if needed */ #elif UC3 const bool erase_page = true; volatile void *const flash_addr = (volatile void *)(dst + SENSOR_NVM_BASE + SENSOR_NVM_OFFSET); sysclk_enable_pbb_module(SYSCLK_FLASH_REGS); (void)flash_memcpy(flash_addr, src, count, erase_page); sysclk_disable_pbb_module(SYSCLK_FLASH_REGS); #endif }
/** * Test nvm_user_sig_write_buffer(). * * Test procedure: * - Write to user signature row with automatic erasing enabled * - Verify contents is equal to buffer * * \return STATUS_OK if test succeeded, otherwise ERR_BAD_DATA */ static status_code_t test_write_and_erase(void) { // Clear memory buffer set_buffer(buffer, FLASH_ERASED); // Set some test values buffer[0] = 84; buffer[1] = 101; buffer[2] = 115; buffer[3] = 116; // Write test values to user signature row nvm_user_sig_write_buffer(TEST_ADDR, &buffer, BUFFER_SIZE, true); if (is_user_sig_equal_to_buffer(TEST_ADDR, buffer, BUFFER_SIZE)) { return STATUS_OK; } return ERR_BAD_DATA; }
status_code_t nvm_write(mem_type_t mem, uint32_t address, void *buffer, uint32_t len) { switch (mem) { case INT_FLASH: nvm_flash_erase_and_write_buffer((flash_addr_t)address, (const void *)buffer, len, true); break; case INT_USERPAGE: nvm_user_sig_write_buffer((flash_addr_t)address, (const void *)buffer, len, true); break; case INT_EEPROM: nvm_eeprom_erase_and_write_buffer((eeprom_addr_t)address, (const void *)buffer, len); break; #if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX) case AT45DBX: { uint32_t sector = address / AT45DBX_SECTOR_SIZE; if (!at45dbx_write_sector_open(sector)) { return ERR_BAD_ADDRESS; } at45dbx_write_sector_from_ram((const void *)buffer); at45dbx_write_close(); } break; #endif default: return ERR_INVALID_ARG; } return STATUS_OK; }