/* * Copyright (C) 2015 Eistec AB * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ /** * @ingroup tests * @{ * * @file * @brief Test application for the SPI NVRAM driver * * @author Joakim NohlgÄrd #include #include #include "board.h" #include "xtimer.h" #include "periph/spi.h" #include "nvram-spi.h" #ifndef TEST_NVRAM_SPI_DEV #error "TEST_NVRAM_SPI_DEV not defined" #endif #ifndef TEST_NVRAM_SPI_CS #error "TEST_NVRAM_SPI_CS not defined" #endif #ifndef TEST_NVRAM_SPI_SIZE #error "TEST_NVRAM_SPI_SIZE not defined" #endif #ifndef TEST_NVRAM_SPI_ADDRESS_COUNT #error "TEST_NVRAM_SPI_ADDRESS_COUNT not defined" #endif #ifdef TEST_NVRAM_SPI_CONF #define SPI_CONF (TEST_NVRAM_SPI_CONF) #else #define SPI_CONF (SPI_CONF_FIRST_RISING) #endif #ifdef TEST_NVRAM_SPI_SPEED #define SPI_SPEED (TEST_NVRAM_SPI_SPEED) #else #define SPI_SPEED (SPI_SPEED_10MHZ) #endif /* This will only work on small memories. Modify if you need to test NVRAM * memories which do not fit inside free RAM */ static uint8_t buf_out[TEST_NVRAM_SPI_SIZE]; static uint8_t buf_in[TEST_NVRAM_SPI_SIZE]; /** * @brief xxd-like printing of a binary buffer */ static void print_buffer(const uint8_t * buf, size_t length) { static const unsigned int bytes_per_line = 16; static const unsigned int bytes_per_group = 2; unsigned long i = 0; while (i < length) { unsigned int col; for (col = 0; col < bytes_per_line; ++col) { /* Print hex data */ if (col == 0) { printf("\n%08lx: ", i); } else if ((col % bytes_per_group) == 0) { putchar(' '); } if ((i + col) < length) { printf("%02hhx", buf[i + col]); } else { putchar(' '); putchar(' '); } } putchar(' '); for (col = 0; col < bytes_per_line; ++col) { if ((i + col) < length) { /* Echo only printable chars */ if (isprint(buf[i + col])) { putchar(buf[i + col]); } else { putchar('.'); } } else { putchar(' '); } } i += bytes_per_line; } /* end with a newline */ puts(""); } /* weak PRNG for generating "random" test data */ static uint8_t lcg_rand8(void) { static const uint32_t a = 1103515245; static const uint32_t c = 12345; static uint32_t val = 123456; /* seed value */ val = val * a + c; return (val >> 16) & 0xff; } int main(void) { uint32_t i; nvram_spi_params_t spi_params = { .spi = TEST_NVRAM_SPI_DEV, .cs = TEST_NVRAM_SPI_CS, .address_count = TEST_NVRAM_SPI_ADDRESS_COUNT, }; nvram_t dev; uint32_t start_delay = 10; puts("NVRAM SPI test application starting..."); printf("Initializing SPI_%i... ", TEST_NVRAM_SPI_DEV); if (spi_init_master(TEST_NVRAM_SPI_DEV, SPI_CONF, SPI_SPEED_10MHZ) == 0) { puts("[OK]"); } else { puts("[Failed]\n"); return 1; } puts("Initializing NVRAM SPI device descriptor... "); if (nvram_spi_init(&dev, &spi_params, TEST_NVRAM_SPI_SIZE) == 0) { puts("[OK]"); } else { puts("[Failed]\n"); return 1; } puts("NVRAM SPI init done.\n"); puts("!!! This test will erase everything on the NVRAM !!!"); puts("!!! Unplug/reset/halt device now if this is not acceptable !!!"); puts("Waiting for 10 seconds before continuing..."); xtimer_sleep(start_delay); puts("Reading current memory contents..."); for (i = 0; i < TEST_NVRAM_SPI_SIZE; ++i) { if (dev.read(&dev, &buf_in[i], i, 1) != 1) { puts("[Failed]\n"); return 1; } } puts("[OK]"); puts("NVRAM contents before test:"); print_buffer(buf_in, sizeof(buf_in)); puts("Writing bytewise 0xFF to device"); memset(buf_out, 0xff, sizeof(buf_out)); for (i = 0; i < TEST_NVRAM_SPI_SIZE; ++i) { if (dev.write(&dev, &buf_out[i], i, 1) != 1) { puts("[Failed]\n"); return 1; } if (buf_out[i] != 0xff) { puts("nvram_spi_write modified *src!"); printf(" i = %08lx\n", (unsigned long) i); puts("[Failed]\n"); return 1; } } puts("Reading back blockwise"); memset(buf_in, 0x00, sizeof(buf_in)); if (dev.read(&dev, buf_in, 0, TEST_NVRAM_SPI_SIZE) != TEST_NVRAM_SPI_SIZE) { puts("[Failed]\n"); return 1; } puts("[OK]"); puts("Verifying contents..."); if (memcmp(buf_in, buf_out, TEST_NVRAM_SPI_SIZE) != 0) { puts("[Failed]\n"); return 1; } puts("[OK]"); puts("Writing blockwise address complement to device"); for (i = 0; i < TEST_NVRAM_SPI_SIZE; ++i) { buf_out[i] = (~(i)) & 0xff; } if (dev.write(&dev, buf_out, 0, TEST_NVRAM_SPI_SIZE) != TEST_NVRAM_SPI_SIZE) { puts("[Failed]\n"); return 1; } puts("[OK]"); puts("buf_out:"); print_buffer(buf_out, sizeof(buf_out)); puts("Reading back blockwise"); memset(buf_in, 0x00, sizeof(buf_in)); if (dev.read(&dev, buf_in, 0, TEST_NVRAM_SPI_SIZE) != TEST_NVRAM_SPI_SIZE) { puts("[Failed]\n"); return 1; } puts("[OK]"); puts("Verifying contents..."); if (memcmp(buf_in, buf_out, TEST_NVRAM_SPI_SIZE) != 0) { puts("buf_in:"); print_buffer(buf_in, sizeof(buf_in)); puts("[Failed]\n"); return 1; } puts("[OK]"); puts("Generating pseudo-random test data..."); for (i = 0; i < TEST_NVRAM_SPI_SIZE; ++i) { buf_out[i] = lcg_rand8(); } puts("buf_out:"); print_buffer(buf_out, sizeof(buf_out)); puts("Writing blockwise data to device"); if (dev.write(&dev, buf_out, 0, TEST_NVRAM_SPI_SIZE) != TEST_NVRAM_SPI_SIZE) { puts("[Failed]\n"); return 1; } puts("[OK]"); puts("Reading back blockwise"); memset(buf_in, 0x00, sizeof(buf_in)); if (dev.read(&dev, buf_in, 0, TEST_NVRAM_SPI_SIZE) != TEST_NVRAM_SPI_SIZE) { puts("[Failed]\n"); return 1; } puts("[OK]"); puts("Verifying contents..."); if (memcmp(buf_in, buf_out, TEST_NVRAM_SPI_SIZE) != 0) { puts("buf_in:"); print_buffer(buf_in, sizeof(buf_in)); puts("[Failed]\n"); return 1; } puts("[OK]"); puts("All tests passed!"); while(1); return 0; }