/** * 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; }
/** * \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"); }
/** * \brief Write buffer within the eeprom * * \param address the address to where to write * \param buf pointer to the data * \param len the number of bytes to write */ void nvm_eeprom_erase_and_write_buffer(eeprom_addr_t address, const void *buf, uint16_t len) { while (len) { if (((address%EEPROM_PAGE_SIZE)==0) && (len>=EEPROM_PAGE_SIZE)) { // A full page can be written nvm_eeprom_load_page_to_buffer((uint8_t*)buf); nvm_eeprom_atomic_write_page(address/EEPROM_PAGE_SIZE); address += EEPROM_PAGE_SIZE; buf = (uint8_t*)buf + EEPROM_PAGE_SIZE; len -= EEPROM_PAGE_SIZE; } else { nvm_eeprom_write_byte(address++, *(uint8_t*)buf); buf = (uint8_t*)buf + 1; len--; } } }
/** * 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; }
/** * \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"); }
int main (void) { /* Insert system clock initialization code here (sysclk_init()). */ board_init(); sysclk_init(); ioport_init(); /* Insert application code here, after the board has been initialized. */ //Own variables bool running = true; bool error = false; uint8_t spi_counter = 0; //Testdata uint32_t testdata = 0; //Create command & data storage uint8_t commandUSART[NUMBER_CTRL_BYTES]; uint8_t commandSPI[NUMBER_CTRL_BYTES]; //Memory uint8_t write_page[EEPROM_PAGE_SIZE]; uint8_t read_page[EEPROM_PAGE_SIZE]; //Own inits init_led_pins(); //Boot sequence initiated switch_led(BOOT, true); init_usart_driver(PIN3_bm, PIN2_bm, &USART_data_Stepper, &USARTD0); init_usart_driver(PIN3_bm, PIN2_bm, &USART_data_PreAmp, &USARTC0); //Test blinking for(int i = 0; i < 10; i++) { blink_led(BOOT, 100); blink_led(RUNNING, 50); blink_led(RXTX, 50); blink_led(FAILURE, 100); blink_led(RXTX, 50); blink_led(RUNNING, 50); } //Load Stuff from memory, no clue what I should load memset(read_page, 0x0, EEPROM_PAGE_SIZE); nvm_eeprom_read_buffer(POSITION_ADDR, read_page, EEPROM_PAGE_SIZE); testdata = ((uint32_t)read_page[3] << 24) | ((uint32_t)read_page[2] << 16) | ((uint32_t)read_page[1] << 8) | read_page[0]; memset(read_page, 0x0, EEPROM_PAGE_SIZE); nvm_eeprom_read_buffer(SPEED_ADDR, read_page, EEPROM_PAGE_SIZE); //currentSpeed = ((uint32_t)read_page[0] << 24) | ((uint32_t)read_page[1] << 16) | ((uint32_t)read_page[2] << 8) | read_page[3]; memset(read_page, 0x0, EEPROM_PAGE_SIZE); //Boot sequence finished switch_led(BOOT, false); //Test of data if(testdata != 3) { switch_led(RXTX, true); //testdata = 10; } else switch_led(RUNNING, true); delay_ms(1000); testdata = 3; //End of test data; if(error != true) { memset(write_page, 0x0, EEPROM_PAGE_SIZE); write_page[3] = testdata >> 24; write_page[2] = testdata >> 16; write_page[1] = testdata >> 8; write_page[0] = testdata; nvm_eeprom_load_page_to_buffer(write_page); nvm_eeprom_atomic_write_page(POSITION_ADDR); memset(write_page, 0x0, EEPROM_PAGE_SIZE); write_page[3] = testdata >> 24; write_page[2] = testdata >> 16; write_page[1] = testdata >> 8; write_page[0] = testdata; nvm_eeprom_load_page_to_buffer(write_page); nvm_eeprom_atomic_write_page(POSITION_ADDR); memset(write_page, 0x0, EEPROM_PAGE_SIZE); switch_led(RUNNING, false); switch_led(RXTX, true); switch_led(BOOT, true); //Shutdown procedure can be executed }