示例#1
0
/**
 * \brief Test EEPROM atomic write
 *
 * This test erases test page \ref TEST_ATOMIC_WRITE_PAGE, then writes the first
 * byte in the page buffer before flushing it -- this byte should then not be
 * written to the EEPROM -- and writing different values to the two successive
 * bytes. An atomic write is then executed before the write of the latter two
 * bytes is verified.
 *
 * \param test Current test case.
 */
static void run_eeprom_atomic_write_test(const struct test_case *test)
{
	uint8_t buffer[EEPROM_PAGE_SIZE];
	bool    success;

	nvm_eeprom_erase_page(TEST_ATOMIC_WRITE_PAGE);

	/* Load a dummy byte and then flush the buffer to remove the byte from
	 * the buffer. The byte should not be written to the EEPROM.
	 */
	nvm_eeprom_load_byte_to_buffer(0, 55);
	nvm_eeprom_flush_buffer();

	/* Load some additional bytes */
	set_buffer(buffer, EEPROM_ERASED);
	buffer[1] = 0xaa;
	buffer[2] = 0x19;
	nvm_eeprom_load_byte_to_buffer(1, buffer[1]);
	nvm_eeprom_load_byte_to_buffer(2, buffer[2]);
	/* Erase and then write page */
	nvm_eeprom_atomic_write_page(TEST_ATOMIC_WRITE_PAGE);

	success = is_eeprom_page_equal_to_buffer(TEST_ATOMIC_WRITE_PAGE, buffer);
	test_assert_true(test, success,
			"Page buffer flush, byte load or atomic write failed");
}
示例#2
0
/**
 * Test nvm_eeprom_erase_bytes_in_page() and
 * nvm_eeprom_erase_bytes_in_all_pages()
 *
 * Test procedure:
 * - Write two bytes into page TEST_ERASE_BYTES_PAGE_1 and
 *   TEST_ERASE_BYTES_PAGE_2
 * - Load value to page buffer in the address of the first byte
 * - Erase first byte of TEST_ERASE_BYTES_PAGE_1
 * - Verify that first byte is deleted in TEST_ERASE_BYTES_PAGE_1
 * - Load value to page buffer in the address of the first byte
 * - Erase first byte of all pages
 * - Verify that first byte is deleted in TEST_ERASE_BYTES_PAGE_2
 *
 * \return STATUS_OK if test succeeded, otherwise ERR_BAD_DATA
 */
static status_code_t test_erase_bytes(void)
{
	set_buffer(buffer, EEPROM_ERASED);
	buffer[0] = 0xaa;
	buffer[1] = 0xaf;

	/* Write two bytes into first page */
	nvm_eeprom_write_byte(TEST_ERASE_BYTES_PAGE_1 * EEPROM_PAGE_SIZE + 0, buffer[0]);
	nvm_eeprom_write_byte(TEST_ERASE_BYTES_PAGE_1 * EEPROM_PAGE_SIZE + 1, buffer[1]);

	/* Write two bytes into second page */
	nvm_eeprom_write_byte(TEST_ERASE_BYTES_PAGE_2 * EEPROM_PAGE_SIZE + 0, buffer[0]);
	nvm_eeprom_write_byte(TEST_ERASE_BYTES_PAGE_2 * EEPROM_PAGE_SIZE + 1, buffer[1]);

	/* Erase first byte of the first page */
	nvm_eeprom_load_byte_to_buffer(0, 0xff);
	nvm_eeprom_erase_bytes_in_page(TEST_ERASE_BYTES_PAGE_1);
	buffer[0] = EEPROM_ERASED;

	if (is_eeprom_page_equal_to_buffer(TEST_ERASE_BYTES_PAGE_1, buffer)) {
		/* Erase first byte of all pages */
		nvm_eeprom_load_byte_to_buffer(0, 0xff);
		nvm_eeprom_erase_bytes_in_all_pages();

		if (is_eeprom_page_equal_to_buffer(TEST_ERASE_BYTES_PAGE_2, buffer)) {
			return STATUS_OK;
		}
	}

	return ERR_BAD_DATA;
}
示例#3
0
/**
 * Test nvm_eeprom_load_byte_to_buffer(), nvm_eeprom_flush_buffer() and
 * nvm_eeprom_atomic_write_page()
 *
 * Test procedure:
 * - Erase the TEST_ATOMIC_WRITE_PAGE page.
 * - Load byte and then flush the buffer at one location.
 * - Load two more bytes at a different location.
 * - Write the page.
 * - Verify that only two bytes are written and the rest of the page is erased.
 *
 * \return STATUS_OK if test succeeded, otherwise ERR_BAD_DATA
 */
static status_code_t test_atomic_write(void)
{
	nvm_eeprom_erase_page(TEST_ATOMIC_WRITE_PAGE);

	/* Load a dummy byte and then flush the buffer to remove the byte from
	 * the buffer. The byte should not be written to the EEPROM.
	 */
	nvm_eeprom_load_byte_to_buffer(0, 55);
	nvm_eeprom_flush_buffer();

	/* Load some additional bytes */
	set_buffer(buffer, EEPROM_ERASED);
	buffer[1] = 0xaa;
	buffer[2] = 0x19;
	nvm_eeprom_load_byte_to_buffer(1, buffer[1]);
	nvm_eeprom_load_byte_to_buffer(2, buffer[2]);
	/* Erase and then write page */
	nvm_eeprom_atomic_write_page(TEST_ATOMIC_WRITE_PAGE);

	if (is_eeprom_page_equal_to_buffer(TEST_ATOMIC_WRITE_PAGE, buffer)) {
		return STATUS_OK;
	}

	return ERR_BAD_DATA;
}
示例#4
0
/**
 * \brief Write one byte to EEPROM using IO mapping.
 *
 * This function writes one byte to EEPROM using IO-mapped access.
 * This function will cancel all ongoing EEPROM page buffer loading
 * operations, if any.
 *
 * \param  address    EEPROM address (max EEPROM_SIZE)
 * \param  value      Byte value to write to EEPROM.
 */
void nvm_eeprom_write_byte(eeprom_addr_t address, uint8_t value)
{
	uint8_t old_cmd;

	Assert(address <= EEPROM_SIZE);
	/*  Flush buffer to make sure no unintentional data is written and load
	 *  the "Page Load" command into the command register.
	 */
	old_cmd = NVM.CMD;
	nvm_eeprom_flush_buffer();
	// Wait until NVM is ready
	nvm_wait_until_ready();
	nvm_eeprom_load_byte_to_buffer(address, value);

	// Set address to write to
	NVM.ADDR2 = 0x00;
	NVM.ADDR1 = (address >> 8) & 0xFF;
	NVM.ADDR0 = address & 0xFF;

	/*  Issue EEPROM Atomic Write (Erase&Write) command. Load command, write
	 *  the protection signature and execute command.
	 */
	NVM.CMD = NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc;
	nvm_exec();
	NVM.CMD = old_cmd;
}
示例#5
0
/**
 * \brief Fill temporary EEPROM page buffer with value.
 *
 * This fills the the EEPROM page buffers with a given value.
 * If memory mapped EEPROM is enabled, this function will not work.
 *
 * \note Only the lower part of the address is used to address the buffer.
 *       Therefore, no address parameter is needed. In the end, the data
 *       is written to the EEPROM page given by the address parameter to the
 *       EEPROM write page operation.
 *
 * \param  value Value to copy to the page buffer.
 */
void nvm_eeprom_fill_buffer_with_value(uint8_t value)
{
	nvm_eeprom_flush_buffer();
	// Wait until NVM is ready
	nvm_wait_until_ready();
	// Load multiple bytes into page buffer
	uint8_t i;
	for (i = 0; i < EEPROM_PAGE_SIZE; ++i) {
		nvm_eeprom_load_byte_to_buffer(i, value);
	}
}
示例#6
0
/**
 * \brief Load entire page into temporary EEPROM page buffer.
 *
 * This function loads an entire EEPROM page from an SRAM buffer to
 * the EEPROM page buffers. If memory mapped EEPROM is enabled, this
 * function will not work. Make sure that the buffer is flushed before
 * starting to load bytes.
 *
 * \note Only the lower part of the address is used to address the buffer.
 *       Therefore, no address parameter is needed. In the end, the data
 *       is written to the EEPROM page given by the address parameter to the
 *       EEPROM write page operation.
 *
 * \param  values   Pointer to SRAM buffer containing an entire page.
 */
void nvm_eeprom_load_page_to_buffer(const uint8_t *values)
{
	// Wait until NVM is ready
	nvm_wait_until_ready();

	// Load multiple bytes into page buffer
	uint8_t i;
	for (i = 0; i < EEPROM_PAGE_SIZE; ++i) {
		nvm_eeprom_load_byte_to_buffer(i, *values);
		++values;
	}
}
示例#7
0
/**
 * Test nvm_eeprom_split_write_page()
 *
 * Test procedure:
 * - Erase TEST_SPLIT_WRITE_PAGE page and then write 2 bytes
 *   to TEST_SPLIT_WRITE_PAGE by using an atomic write
 * - Write 1 additional byte at another location using a split write
 * - Verify that all 3 bytes written correctly and that the rest of the page
 *   is erased.
 *
 * \return STATUS_OK if test succeeded, otherwise ERR_BAD_DATA
 */
static status_code_t test_split_write(void)
{
	/* Erase and then program two bytes into the page */
	set_buffer(buffer, EEPROM_ERASED);
	buffer[1] = 0xaa;
	buffer[2] = 0x19;
	nvm_eeprom_load_byte_to_buffer(1, buffer[1]);
	nvm_eeprom_load_byte_to_buffer(2, buffer[2]);
	nvm_eeprom_atomic_write_page(TEST_SPLIT_WRITE_PAGE);

	/*
	 * Write another value to the EEPROM and then verify that all three bytes
	 * are present, ie. the split write does not delete the first two bytes.
	 */
	buffer[3] = 0xa7;
	nvm_eeprom_load_byte_to_buffer(3, buffer[3]);
	nvm_eeprom_split_write_page(TEST_SPLIT_WRITE_PAGE);

	if (is_eeprom_page_equal_to_buffer(TEST_SPLIT_WRITE_PAGE, buffer)) {
		return STATUS_OK;
	}

	return ERR_BAD_DATA;
}
示例#8
0
/**
 * \brief Test EEPROM byte erase
 *
 * This test writes two bytes to test pages \ref TEST_ERASE_BYTES_PAGE_1 and
 * \ref TEST_ERASE_BYTES_PAGE_2, then tries to erase one of them in the first
 * page before verifying the erase, then in all pages before verifying that the
 * second page was also erased.
 *
 * \param test Current test case.
 */
static void run_eeprom_erase_byte_test(const struct test_case *test)
{
	uint8_t buffer[EEPROM_PAGE_SIZE];
	bool    success;

	set_buffer(buffer, EEPROM_ERASED);
	buffer[0] = 0xaa;
	buffer[1] = 0xaf;

	/* Write two bytes into first page */
	nvm_eeprom_write_byte(TEST_ERASE_BYTES_PAGE_1 * EEPROM_PAGE_SIZE + 0,
			buffer[0]);
	nvm_eeprom_write_byte(TEST_ERASE_BYTES_PAGE_1 * EEPROM_PAGE_SIZE + 1,
			buffer[1]);

	/* Write two bytes into second page */
	nvm_eeprom_write_byte(TEST_ERASE_BYTES_PAGE_2 * EEPROM_PAGE_SIZE + 0,
			buffer[0]);
	nvm_eeprom_write_byte(TEST_ERASE_BYTES_PAGE_2 * EEPROM_PAGE_SIZE + 1,
			buffer[1]);

	/* Erase first byte of the first page */
	nvm_eeprom_load_byte_to_buffer(0, 0xff);
	nvm_eeprom_erase_bytes_in_page(TEST_ERASE_BYTES_PAGE_1);
	buffer[0] = EEPROM_ERASED;

	success = is_eeprom_page_equal_to_buffer(TEST_ERASE_BYTES_PAGE_1, buffer);
	test_assert_true(test, success, "Byte erase in single page failed");

	/* Erase first byte of all pages */
	nvm_eeprom_load_byte_to_buffer(0, 0xff);
	nvm_eeprom_erase_bytes_in_all_pages();

	success = is_eeprom_page_equal_to_buffer(TEST_ERASE_BYTES_PAGE_2, buffer);
	test_assert_true(test, success, "Byte erase in all pages failed");
}
示例#9
0
/**
 * \brief Test EEPROM split write
 *
 * This test writes two bytes to test page \ref TEST_SPLIT_WRITE_PAGE with an
 * atomic write operation, then writes a third byte to the same page with a
 * split write operation before verifying that the page contains all three
 * bytes.
 *
 * \param test Current test case.
 */
static void run_eeprom_split_write_test(const struct test_case *test)
{
	uint8_t buffer[EEPROM_PAGE_SIZE];
	bool    success;

	/* Erase and then program two bytes into the page */
	set_buffer(buffer, EEPROM_ERASED);
	buffer[1] = 0xaa;
	buffer[2] = 0x19;
	nvm_eeprom_load_byte_to_buffer(1, buffer[1]);
	nvm_eeprom_load_byte_to_buffer(2, buffer[2]);
	nvm_eeprom_atomic_write_page(TEST_SPLIT_WRITE_PAGE);

	/*
	 * Write another value to the EEPROM and then verify that all three bytes
	 * are present, ie. the split write does not delete the first two bytes.
	 */
	buffer[3] = 0xa7;
	nvm_eeprom_load_byte_to_buffer(3, buffer[3]);
	nvm_eeprom_split_write_page(TEST_SPLIT_WRITE_PAGE);

	success = is_eeprom_page_equal_to_buffer(TEST_SPLIT_WRITE_PAGE, buffer);
	test_assert_true(test, success, "Split write failed");
}