aboutsummaryrefslogtreecommitdiff
path: root/projects/board-test
diff options
context:
space:
mode:
Diffstat (limited to 'projects/board-test')
-rw-r--r--projects/board-test/Makefile5
-rw-r--r--projects/board-test/fmc-perf.c39
-rw-r--r--projects/board-test/fmc-probe.c25
-rw-r--r--projects/board-test/fmc-test.c83
-rw-r--r--projects/board-test/keystore-perf.c197
-rw-r--r--projects/board-test/led-test.c1
-rw-r--r--projects/board-test/rtc-test.c75
-rw-r--r--projects/board-test/short-test.c1
-rw-r--r--projects/board-test/spiflash-perf.c249
-rw-r--r--projects/board-test/uart-test.c1
10 files changed, 537 insertions, 139 deletions
diff --git a/projects/board-test/Makefile b/projects/board-test/Makefile
index 9b1812f..45e75fc 100644
--- a/projects/board-test/Makefile
+++ b/projects/board-test/Makefile
@@ -1,4 +1,7 @@
-TEST = led-test short-test uart-test fmc-test fmc-perf fmc-probe rtc-test
+TEST = led-test short-test uart-test fmc-test fmc-perf fmc-probe
+ifeq (${BOARD},TARGET_CRYPTECH_ALPHA)
+TEST += rtc-test spiflash-perf keystore-perf
+endif
all: $(TEST:=.elf)
diff --git a/projects/board-test/fmc-perf.c b/projects/board-test/fmc-perf.c
index 0c753a7..5af0946 100644
--- a/projects/board-test/fmc-perf.c
+++ b/projects/board-test/fmc-perf.c
@@ -1,7 +1,6 @@
/*
* Test read/write performance of the fmc bus
*/
-#include "stm32f4xx_hal.h"
#include "stm-init.h"
#include "stm-led.h"
#include "stm-fmc.h"
@@ -32,14 +31,8 @@ static void sanity(void)
uint32_t rnd, data;
rnd = random();
- if (fmc_write_32(0, &rnd) != 0) {
- uart_send_string("fmc_write_32 failed\r\n");
- Error_Handler();
- }
- if (fmc_read_32(0, &data) != 0) {
- uart_send_string("fmc_read_32 failed\r\n");
- Error_Handler();
- }
+ fmc_write_32(0, rnd);
+ fmc_read_32(0, &data);
if (data != rnd) {
uart_send_string("Data bus fail: expected ");
uart_send_hex(rnd, 8);
@@ -57,11 +50,11 @@ static void _time_check(char *label, const uint32_t t0)
uint32_t t = HAL_GetTick() - t0;
uart_send_string(label);
- uart_send_integer(t / 1000, 0);
+ uart_send_integer(t / 1000, 1);
uart_send_char('.');
uart_send_integer(t % 1000, 3);
uart_send_string(" seconds, ");
- uart_send_integer(((1000 * TEST_NUM_ROUNDS) / t), 0);
+ uart_send_integer(((1000 * TEST_NUM_ROUNDS) / t), 1);
uart_send_string("/sec\r\n");
}
@@ -77,10 +70,7 @@ static void test_read(void)
uint32_t i, data;
for (i = 0; i < TEST_NUM_ROUNDS; ++i) {
- if (fmc_read_32(0, &data) != 0) {
- uart_send_string("fmc_read_32 failed\r\n");
- Error_Handler();
- }
+ fmc_read_32(0, &data);
}
}
@@ -89,33 +79,16 @@ static void test_write(void)
uint32_t i;
for (i = 0; i < TEST_NUM_ROUNDS; ++i) {
- if (fmc_write_32(0, &i) != 0) {
- uart_send_string("fmc_write_32 failed\r\n");
- Error_Handler();
- }
+ fmc_write_32(0, i);
}
}
int main(void)
{
stm_init();
-
- uart_send_string("Keep calm for Novena boot...\r\n");
-
- // Blink blue LED for six seconds to not upset the Novena at boot.
- led_on(LED_BLUE);
- for (int i = 0; i < 12; i++) {
- HAL_Delay(500);
- led_toggle(LED_BLUE);
- }
- led_off(LED_BLUE);
-
// initialize rng
MX_RNG_Init();
- // prepare fmc interface
- fmc_init();
-
sanity();
time_check("read ", test_read());
diff --git a/projects/board-test/fmc-probe.c b/projects/board-test/fmc-probe.c
index 55d3521..38897ab 100644
--- a/projects/board-test/fmc-probe.c
+++ b/projects/board-test/fmc-probe.c
@@ -2,7 +2,6 @@
* in other cases, it will be the core name and version strings.
*/
-#include "stm32f4xx_hal.h"
#include "stm-init.h"
#include "stm-led.h"
#include "stm-fmc.h"
@@ -22,37 +21,15 @@ static uint32_t read0(uint32_t addr)
{
uint32_t data;
- if (fmc_read_32(addr, &data) != 0) {
- uart_send_string("fmc_read_32 failed\r\n");
- Error_Handler();
- }
+ fmc_read_32(addr, &data);
return data;
}
int main(void)
{
- int i;
-
stm_init();
-
- uart_send_string("Keep calm for Novena boot...\r\n");
-
- // Blink blue LED for six seconds to not upset the Novena at boot.
- led_on(LED_BLUE);
- for (i = 0; i < 12; i++) {
- HAL_Delay(500);
- led_toggle(LED_BLUE);
- }
-
- // prepare fmc interface
- fmc_init();
-
- // turn on green led, turn off other leds
led_on(LED_GREEN);
- led_off(LED_YELLOW);
- led_off(LED_RED);
- led_off(LED_BLUE);
for (uint32_t addr = 0; addr < 0x00080000; addr += 4) {
uint32_t data = read0(addr);
diff --git a/projects/board-test/fmc-test.c b/projects/board-test/fmc-test.c
index bc5a768..bd30dd5 100644
--- a/projects/board-test/fmc-test.c
+++ b/projects/board-test/fmc-test.c
@@ -4,8 +4,7 @@
/*
This requires a special bitstream with a special test register.
- See core/platform/novena/fmc/rtl/novena_fmc_top.v, sections marked
- `ifdef test:
+ See core/platform/alpha/rtl/alpha_fmc_test.v:
//----------------------------------------------------------------
// Dummy Register
//
@@ -34,11 +33,11 @@
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
-#include "stm32f4xx_hal.h"
#include "stm-init.h"
#include "stm-led.h"
#include "stm-fmc.h"
#include "stm-uart.h"
+#include "stm-fpgacfg.h"
//------------------------------------------------------------------------------
// Defines
@@ -76,6 +75,7 @@ int test_fpga_address_bus(void);
// Defines
//------------------------------------------------------------------------------
#define TEST_NUM_ROUNDS 100000
+#define VERBOSE 0
//------------------------------------------------------------------------------
@@ -88,7 +88,7 @@ int main(void)
uart_send_string("Keep calm for FPGA bitstream loading...\r\n");
- // Blink blue LED until the FPGA reports it has loaded it's bitstream
+ // Blink blue LED until the FPGA reports it has loaded its bitstream
led_on(LED_BLUE);
while (! fpgacfg_check_done()) {
for (i = 0; i < 4; i++) {
@@ -100,9 +100,6 @@ int main(void)
// initialize rng
MX_RNG_Init();
- // prepare fmc interface
- fmc_init();
-
// turn on green led, turn off other leds
led_on(LED_GREEN);
led_off(LED_YELLOW);
@@ -120,11 +117,15 @@ int main(void)
// test address bus
addr_test_ok = test_fpga_address_bus();
- uart_send_string("Data: ");
- uart_send_integer(data_test_ok, 6);
- uart_send_string(", addr: ");
- uart_send_integer(addr_test_ok, 6);
- uart_send_string("\r\n");
+ if (VERBOSE ||
+ (data_test_ok != TEST_NUM_ROUNDS ||
+ addr_test_ok != TEST_NUM_ROUNDS)) {
+ uart_send_string("Data: ");
+ uart_send_integer(data_test_ok, 6);
+ uart_send_string(", addr: ");
+ uart_send_integer(addr_test_ok, 6);
+ uart_send_string("\r\n");
+ }
if (data_test_ok == TEST_NUM_ROUNDS &&
addr_test_ok == TEST_NUM_ROUNDS) {
@@ -140,11 +141,12 @@ int main(void)
}
uart_send_string("Success ");
- uart_send_integer(successful_runs, 0);
+ uart_send_integer(successful_runs, 1);
uart_send_string(", fail ");
- uart_send_integer(failed_runs, 0);
- uart_send_string("\r\n\r\n");
-
+ uart_send_integer(failed_runs, 1);
+ uart_send_string("\r\n");
+ if (VERBOSE)
+ uart_send_string("\r\n");
HAL_Delay(sleep);
}
@@ -156,7 +158,7 @@ int main(void)
int test_fpga_data_bus(void)
//------------------------------------------------------------------------------
{
- int c, ok;
+ int c;
uint32_t rnd, buf;
HAL_StatusTypeDef hal_result;
@@ -169,12 +171,10 @@ int test_fpga_data_bus(void)
if (hal_result != HAL_OK) break;
// write value to fpga at address 0
- ok = fmc_write_32(0, &rnd);
- if (ok != 0) break;
+ fmc_write_32(0, rnd);
// read value from fpga
- ok = fmc_read_32(0, &buf);
- if (ok != 0) break;
+ fmc_read_32(0, &buf);
// compare (abort testing in case of error)
if (buf != rnd)
@@ -197,13 +197,16 @@ int test_fpga_data_bus(void)
data_diff = buf;
data_diff ^= rnd;
- uart_send_string("Sample of data bus test data: expected ");
- uart_send_binary(rnd, 32);
- uart_send_string(", got ");
- uart_send_binary(buf, 32);
- uart_send_string(", diff ");
- uart_send_binary(data_diff, 32);
- uart_send_string("\r\n");
+ if (VERBOSE || data_diff) {
+ uart_send_string("Sample of data bus test data: expected ");
+ uart_send_binary(rnd, 32);
+ uart_send_string(", got ");
+ uart_send_binary(buf, 32);
+ uart_send_string(", diff ");
+ uart_send_binary(data_diff, 32);
+ uart_send_string("\r\n");
+ }
+
// return number of successful tests
return c;
}
@@ -213,7 +216,7 @@ int test_fpga_data_bus(void)
int test_fpga_address_bus(void)
//------------------------------------------------------------------------------
{
- int c, ok;
+ int c;
uint32_t rnd, buf;
HAL_StatusTypeDef hal_result;
@@ -234,12 +237,10 @@ int test_fpga_address_bus(void)
if (rnd == 0) continue;
// write dummy value to fpga at some non-zero address
- ok = fmc_write_32(rnd, &buf);
- if (ok != 0) break;
+ fmc_write_32(rnd, buf);
// read value from fpga
- ok = fmc_read_32(0, &buf);
- if (ok != 0) break;
+ fmc_read_32(0, &buf);
// fpga receives address of 32-bit word, while we need
// byte address here to compare
@@ -266,13 +267,15 @@ int test_fpga_address_bus(void)
addr_diff = buf;
addr_diff ^= rnd;
- uart_send_string("Sample of addr bus test data: expected ");
- uart_send_binary(rnd, 32);
- uart_send_string(", got ");
- uart_send_binary(buf, 32);
- uart_send_string(", diff ");
- uart_send_binary(addr_diff, 32);
- uart_send_string("\r\n");
+ if (VERBOSE || addr_diff) {
+ uart_send_string("Sample of addr bus test data: expected ");
+ uart_send_binary(rnd, 32);
+ uart_send_string(", got ");
+ uart_send_binary(buf, 32);
+ uart_send_string(", diff ");
+ uart_send_binary(addr_diff, 32);
+ uart_send_string("\r\n");
+ }
return c;
}
diff --git a/projects/board-test/keystore-perf.c b/projects/board-test/keystore-perf.c
new file mode 100644
index 0000000..c2aa4fb
--- /dev/null
+++ b/projects/board-test/keystore-perf.c
@@ -0,0 +1,197 @@
+/*
+ * Test read/write/erase performance of the flash keystore.
+ */
+
+#include "string.h"
+
+#include "stm-init.h"
+#include "stm-led.h"
+#include "stm-uart.h"
+#include "stm-keystore.h"
+
+/*
+ * 1. Read the entire flash by subsectors, ignoring data.
+ */
+static void test_read_data(void)
+{
+ uint8_t read_buf[KEYSTORE_SUBSECTOR_SIZE];
+ uint32_t i;
+ HAL_StatusTypeDef err;
+
+ for (i = 0; i < KEYSTORE_NUM_SUBSECTORS; ++i) {
+ err = keystore_read_data(i * KEYSTORE_SUBSECTOR_SIZE, read_buf, KEYSTORE_SUBSECTOR_SIZE);
+ if (err != HAL_OK) {
+ uart_send_string("ERROR: keystore_read_data returned ");
+ uart_send_integer(err, 1);
+ uart_send_string("\r\n");
+ break;
+ }
+ }
+}
+
+/*
+ * Read the flash data and verify it against a known pattern.
+ */
+static void _read_verify(uint8_t *vrfy_buf)
+{
+ uint8_t read_buf[KEYSTORE_SUBSECTOR_SIZE];
+ uint32_t i;
+ HAL_StatusTypeDef err;
+
+ for (i = 0; i < KEYSTORE_NUM_SUBSECTORS; ++i) {
+ err = keystore_read_data(i * KEYSTORE_SUBSECTOR_SIZE, read_buf, KEYSTORE_SUBSECTOR_SIZE);
+ if (err != HAL_OK) {
+ uart_send_string("ERROR: keystore_read_data returned ");
+ uart_send_integer(err, 1);
+ uart_send_string("\r\n");
+ break;
+ }
+ if (memcmp(read_buf, vrfy_buf, KEYSTORE_SUBSECTOR_SIZE) != 0) {
+ uart_send_string("ERROR: verify failed in subsector ");
+ uart_send_integer(i, 1);
+ uart_send_string("\r\n");
+ break;
+ }
+ }
+}
+
+/*
+ * 2a. Erase the entire flash by sectors.
+ */
+static void test_erase_sector(void)
+{
+ uint32_t i;
+ HAL_StatusTypeDef err;
+
+ for (i = 0; i < KEYSTORE_NUM_SECTORS; ++i) {
+ err = keystore_erase_sector(i);
+ if (err != HAL_OK) {
+ uart_send_string("ERROR: keystore_erase_sector returned ");
+ uart_send_integer(err, 1);
+ uart_send_string("\r\n");
+ break;
+ }
+ }
+}
+
+/*
+ * 2b. Erase the entire flash by subsectors.
+ */
+static void test_erase_subsector(void)
+{
+ uint32_t i;
+ HAL_StatusTypeDef err;
+
+ for (i = 0; i < KEYSTORE_NUM_SUBSECTORS; ++i) {
+ err = keystore_erase_subsector(i);
+ if (err != HAL_OK) {
+ uart_send_string("ERROR: keystore_erase_subsector returned ");
+ uart_send_integer(err, 1);
+ uart_send_string("\r\n");
+ break;
+ }
+ }
+}
+
+/*
+ * 2c. Read the entire flash, verify erasure.
+ */
+static void test_verify_erase(void)
+{
+ uint8_t vrfy_buf[KEYSTORE_SUBSECTOR_SIZE];
+ uint32_t i;
+
+ for (i = 0; i < sizeof(vrfy_buf); ++i)
+ vrfy_buf[i] = 0xFF;
+
+ _read_verify(vrfy_buf);
+}
+
+/*
+ * 3a. Write the entire flash with a pattern.
+ */
+static void test_write_data(void)
+{
+ uint8_t write_buf[KEYSTORE_SUBSECTOR_SIZE];
+ uint32_t i;
+ HAL_StatusTypeDef err;
+
+ for (i = 0; i < sizeof(write_buf); ++i)
+ write_buf[i] = i & 0xFF;
+
+ for (i = 0; i < KEYSTORE_NUM_SUBSECTORS; ++i) {
+ err = keystore_write_data(i * KEYSTORE_SUBSECTOR_SIZE, write_buf, KEYSTORE_SUBSECTOR_SIZE);
+ if (err != HAL_OK) {
+ uart_send_string("ERROR: keystore_write_data returned ");
+ uart_send_integer(err, 1);
+ uart_send_string(" for subsector ");
+ uart_send_integer(i, 1);
+ uart_send_string("\r\n");
+ break;
+ }
+ }
+}
+
+/*
+ * 3b. Read the entire flash, verify data.
+ */
+static void test_verify_write(void)
+{
+ uint8_t vrfy_buf[KEYSTORE_SUBSECTOR_SIZE];
+ uint32_t i;
+
+ for (i = 0; i < sizeof(vrfy_buf); ++i)
+ vrfy_buf[i] = i & 0xFF;
+
+ _read_verify(vrfy_buf);
+}
+
+static void _time_check(char *label, const uint32_t t0, uint32_t n_rounds)
+{
+ uint32_t t = HAL_GetTick() - t0;
+
+ uart_send_string(label);
+ uart_send_integer(t / 1000, 1);
+ uart_send_char('.');
+ uart_send_integer(t % 1000, 3);
+ uart_send_string(" sec");
+ if (n_rounds > 1) {
+ uart_send_string(" for ");
+ uart_send_integer(n_rounds, 1);
+ uart_send_string(" rounds, ");
+ uart_send_integer(t / n_rounds, 1);
+ uart_send_char('.');
+ uart_send_integer(((t % n_rounds) * 100) / n_rounds, 2);
+ uart_send_string(" ms each");
+ }
+ uart_send_string("\r\n");
+}
+
+#define time_check(_label_, _expr_, _n_) \
+ do { \
+ uint32_t _t = HAL_GetTick(); \
+ (_expr_); \
+ _time_check(_label_, _t, _n_); \
+ } while (0)
+
+int main(void)
+{
+ stm_init();
+
+ if (keystore_check_id() != HAL_OK) {
+ uart_send_string("ERROR: keystore_check_id failed\r\n");
+ return 0;
+ }
+
+ uart_send_string("Starting...\r\n");
+
+ time_check("read data ", test_read_data(), KEYSTORE_NUM_SUBSECTORS);
+ time_check("erase subsector ", test_erase_subsector(), KEYSTORE_NUM_SUBSECTORS);
+ time_check("erase sector ", test_erase_sector(), KEYSTORE_NUM_SECTORS);
+ time_check("verify erase ", test_verify_erase(), KEYSTORE_NUM_SUBSECTORS);
+ time_check("write data ", test_write_data(), KEYSTORE_NUM_SUBSECTORS);
+ time_check("verify write ", test_verify_write(), KEYSTORE_NUM_SUBSECTORS);
+
+ uart_send_string("Done.\r\n\r\n");
+ return 0;
+}
diff --git a/projects/board-test/led-test.c b/projects/board-test/led-test.c
index 7e72788..2ec7c9d 100644
--- a/projects/board-test/led-test.c
+++ b/projects/board-test/led-test.c
@@ -1,7 +1,6 @@
/*
* Blink the four LEDs on the rev01 board in a pattern.
*/
-#include "stm32f4xx_hal.h"
#include "stm-init.h"
#include "stm-led.h"
diff --git a/projects/board-test/rtc-test.c b/projects/board-test/rtc-test.c
index b8a7511..bbb297a 100644
--- a/projects/board-test/rtc-test.c
+++ b/projects/board-test/rtc-test.c
@@ -8,7 +8,6 @@
*/
#include <string.h>
-#include "stm32f4xx_hal.h"
#include "stm-init.h"
#include "stm-led.h"
#include "stm-uart.h"
@@ -23,18 +22,18 @@ uint32_t i;
uint32_t device_ready(uint16_t i2c_addr)
{
- uart_send_string2(STM_UART_MGMT, "Checking readiness of 0x");
- uart_send_number2(STM_UART_MGMT, i2c_addr, 4, 16);
- uart_send_string2(STM_UART_MGMT, "...");
+ uart_send_string("Checking readiness of 0x");
+ uart_send_hex(i2c_addr, 4);
+ uart_send_string("...");
if (rtc_device_ready(i2c_addr) == HAL_OK) {
- uart_send_string2(STM_UART_MGMT, "OK\r\n");
+ uart_send_string("OK\r\n");
return 1;
}
- uart_send_string2(STM_UART_MGMT, "Not ready (0x");
- uart_send_number2(STM_UART_MGMT, i, 4, 16);
- uart_send_string2(STM_UART_MGMT, ")\r\n");
+ uart_send_string("Not ready (0x");
+ uart_send_hex(i, 4);
+ uart_send_string(")\r\n");
return 0;
}
@@ -44,34 +43,34 @@ void send_byte(const uint16_t i2c_addr, const uint8_t value)
{
uint8_t ch = value;
- uart_send_string2(STM_UART_MGMT, "Sending ");
- uart_send_number2(STM_UART_MGMT, ch, 2, 16);
- uart_send_string2(STM_UART_MGMT, " to 0x");
- uart_send_number2(STM_UART_MGMT, i2c_addr, 4, 16);
- uart_send_string2(STM_UART_MGMT, "...");
+ uart_send_string("Sending ");
+ uart_send_hex(ch, 2);
+ uart_send_string(" to 0x");
+ uart_send_hex(i2c_addr, 4);
+ uart_send_string("...");
if (rtc_send_byte(i2c_addr, ch, 1000) != HAL_OK) {
- uart_send_string2(STM_UART_MGMT, "Timeout\r\n");
+ uart_send_string("Timeout\r\n");
Error_Handler();
}
- uart_send_string2(STM_UART_MGMT, "OK\r\n");
+ uart_send_string("OK\r\n");
}
void read_bytes (uint8_t *buf, const uint16_t i2c_addr, const uint8_t len)
{
- uart_send_string2(STM_UART_MGMT, "Reading ");
- uart_send_number2(STM_UART_MGMT, len, 3, 10);
- uart_send_string2(STM_UART_MGMT, " bytes from 0x");
- uart_send_number2(STM_UART_MGMT, i2c_addr, 4, 16);
- uart_send_string2(STM_UART_MGMT, "...");
+ uart_send_string("Reading ");
+ uart_send_integer(len, 1);
+ uart_send_string(" bytes from 0x");
+ uart_send_hex(i2c_addr, 4);
+ uart_send_string("...");
if (rtc_read_bytes(i2c_addr, buf, len, 1000) != HAL_OK) {
- uart_send_string2(STM_UART_MGMT, "Timeout\r\n");
+ uart_send_string("Timeout\r\n");
Error_Handler();
}
- uart_send_string2(STM_UART_MGMT, "OK\r\n");
+ uart_send_string("OK\r\n");
}
void request_data(uint8_t *buf, const uint16_t i2c_addr, const uint8_t offset, const uint8_t bytes)
@@ -85,8 +84,8 @@ void print_time()
request_data(buf, RTC_RTC_ADDR, RTC_TIME_OFFSET, RTC_TIME_BYTES);
for (i = 0; i < RTC_TIME_BYTES; i++) {
- uart_send_number2(STM_UART_MGMT, buf[i], 2, 16);
- uart_send_string2(STM_UART_MGMT, " ");
+ uart_send_hex(buf[i], 2);
+ uart_send_string(" ");
}
}
@@ -94,37 +93,37 @@ void dump_sram()
{
request_data(buf, RTC_RTC_ADDR, 0x0, RTC_SRAM_TOTAL_BYTES);
- uart_send_string2(STM_UART_MGMT, "SRAM contents:\r\n");
- uart_send_hexdump(STM_UART_MGMT, buf, 0, RTC_SRAM_TOTAL_BYTES);
+ uart_send_string("SRAM contents:\r\n");
+ uart_send_hexdump(buf, 0, RTC_SRAM_TOTAL_BYTES);
- uart_send_string2(STM_UART_MGMT, "\r\n");
+ uart_send_string("\r\n");
}
void dump_eeprom()
{
request_data(buf, RTC_EEPROM_ADDR, 0x0, RTC_EEPROM_TOTAL_BYTES);
- uart_send_string2(STM_UART_MGMT, "EEPROM contents:\r\n");
- uart_send_hexdump(STM_UART_MGMT, buf, 0, RTC_EEPROM_TOTAL_BYTES);
- uart_send_string2(STM_UART_MGMT, "\r\n");
+ uart_send_string("EEPROM contents:\r\n");
+ uart_send_hexdump(buf, 0, RTC_EEPROM_TOTAL_BYTES);
+ uart_send_string("\r\n");
request_data(buf, RTC_EEPROM_ADDR, RTC_EEPROM_EUI48_OFFSET, RTC_EEPROM_EUI48_BYTES);
- uart_send_string2(STM_UART_MGMT, "EEPROM EUI-48:\r\n");
- uart_send_hexdump(STM_UART_MGMT, buf, RTC_EEPROM_EUI48_OFFSET, RTC_EEPROM_EUI48_BYTES);
+ uart_send_string("EEPROM EUI-48:\r\n");
+ uart_send_hexdump(buf, RTC_EEPROM_EUI48_OFFSET, RTC_EEPROM_EUI48_BYTES);
- uart_send_string2(STM_UART_MGMT, "\r\n");
+ uart_send_string("\r\n");
}
void enable_oscillator()
{
- uart_send_string2(STM_UART_MGMT, "Enabling oscillator...\r\n");
+ uart_send_string("Enabling oscillator...\r\n");
if (rtc_enable_oscillator() != HAL_OK) {
- uart_send_string2(STM_UART_MGMT, "Timeout\r\n");
+ uart_send_string("Timeout\r\n");
Error_Handler();
}
- uart_send_string2(STM_UART_MGMT, "OK\r\n");
+ uart_send_string("OK\r\n");
}
@@ -132,7 +131,7 @@ int
main()
{
stm_init();
- uart_send_string2(STM_UART_MGMT, "\r\n\r\n*** Init done\r\n");
+ uart_send_string("\r\n\r\n*** Init done\r\n");
dump_sram();
dump_eeprom();
@@ -148,7 +147,7 @@ main()
print_time(buf);
- uart_send_string2(STM_UART_MGMT, "\r\n\r\n");
+ uart_send_string("\r\n\r\n");
HAL_GPIO_TogglePin(LED_PORT, LED_GREEN);
DELAY();
diff --git a/projects/board-test/short-test.c b/projects/board-test/short-test.c
index 27b8e7a..db0251b 100644
--- a/projects/board-test/short-test.c
+++ b/projects/board-test/short-test.c
@@ -5,7 +5,6 @@
* Toggles the BLUE LED slowly and the RED LED for every
* character sent.
*/
-#include "stm32f4xx_hal.h"
#include "stm-init.h"
#include "stm-led.h"
#include "stm-uart.h"
diff --git a/projects/board-test/spiflash-perf.c b/projects/board-test/spiflash-perf.c
new file mode 100644
index 0000000..36c6131
--- /dev/null
+++ b/projects/board-test/spiflash-perf.c
@@ -0,0 +1,249 @@
+/*
+ * Test read/write/erase performance of the N25Q128 SPI flash chip.
+ */
+
+#include "string.h"
+
+#include "stm-init.h"
+#include "stm-led.h"
+#include "stm-uart.h"
+#include "stm-keystore.h"
+#include "spiflash_n25q128.h"
+
+/*
+ * Use the keystore memory for testing, because it's less involved than
+ * using the FPGA configuration memory, and less work to restore it to a
+ * useful configuration.
+ *
+ * However, rather than using the stm-keystore abstractions, this version
+ * goes straight to the low-level API.
+ */
+
+extern struct spiflash_ctx keystore_ctx;
+static struct spiflash_ctx *ctx = &keystore_ctx;
+
+/*
+ * 1a. Read the entire flash by pages, ignoring data.
+ */
+static void test_read_page(void)
+{
+ uint8_t read_buf[N25Q128_PAGE_SIZE];
+ uint32_t i;
+ int err;
+
+ for (i = 0; i < N25Q128_NUM_PAGES; ++i) {
+ err = n25q128_read_page(ctx, i, read_buf);
+ if (err != HAL_OK) {
+ uart_send_string("ERROR: n25q128_read_page returned ");
+ uart_send_integer(err, 1);
+ uart_send_string("\r\n");
+ break;
+ }
+ }
+}
+
+/*
+ * 1b. Read the entire flash by subsectors, ignoring data.
+ */
+static void test_read_subsector(void)
+{
+ uint8_t read_buf[N25Q128_SUBSECTOR_SIZE];
+ uint32_t i;
+ int err;
+
+ for (i = 0; i < N25Q128_NUM_SUBSECTORS; ++i) {
+ err = n25q128_read_subsector(ctx, i, read_buf);
+ if (err != HAL_OK) {
+ uart_send_string("ERROR: n25q128_read_subsector returned ");
+ uart_send_integer(err, 1);
+ uart_send_string("\r\n");
+ break;
+ }
+ }
+}
+
+/*
+ * Read the flash data and verify it against a known pattern.
+ * It turns out that verification doesn't slow us down in any measurable
+ * way, because memcmp on 256 bytes is pretty inconsequential.
+ */
+static void _read_verify(uint8_t *vrfy_buf)
+{
+ uint8_t read_buf[N25Q128_PAGE_SIZE];
+ uint32_t i;
+ int err;
+
+ for (i = 0; i < N25Q128_NUM_PAGES; ++i) {
+ err = n25q128_read_page(ctx, i, read_buf);
+ if (err != HAL_OK) {
+ uart_send_string("ERROR: n25q128_read_page returned ");
+ uart_send_integer(err, 1);
+ uart_send_string("\r\n");
+ break;
+ }
+ if (memcmp(read_buf, vrfy_buf, N25Q128_PAGE_SIZE) != 0) {
+ uart_send_string("ERROR: verify failed in page ");
+ uart_send_integer(i, 1);
+ uart_send_string("\r\n");
+ break;
+ }
+ }
+}
+
+/*
+ * 2a. Erase the entire flash by sectors.
+ */
+static void test_erase_sector(void)
+{
+ uint32_t i;
+ int err;
+
+ for (i = 0; i < N25Q128_NUM_SECTORS; ++i) {
+ err = n25q128_erase_sector(ctx, i);
+ if (err != HAL_OK) {
+ uart_send_string("ERROR: n25q128_erase_sector returned ");
+ uart_send_integer(err, 1);
+ uart_send_string("\r\n");
+ break;
+ }
+ }
+}
+
+/*
+ * 2b. Erase the entire flash by subsectors.
+ */
+static void test_erase_subsector(void)
+{
+ uint32_t i;
+ int err;
+
+ for (i = 0; i < N25Q128_NUM_SUBSECTORS; ++i) {
+ err = n25q128_erase_subsector(ctx, i);
+ if (err != HAL_OK) {
+ uart_send_string("ERROR: n25q128_erase_subsector returned ");
+ uart_send_integer(err, 1);
+ uart_send_string("\r\n");
+ break;
+ }
+ }
+}
+
+/*
+ * 2c. Erase the entire flash in bulk.
+ */
+static void test_erase_bulk(void)
+{
+ int err;
+
+ err = n25q128_erase_bulk(ctx);
+ if (err != HAL_OK) {
+ uart_send_string("ERROR: n25q128_erase_bulk returned ");
+ uart_send_integer(err, 1);
+ uart_send_string("\r\n");
+ }
+}
+
+/*
+ * 2d. Read the entire flash, verify erasure.
+ */
+static void test_verify_erase(void)
+{
+ uint8_t vrfy_buf[N25Q128_PAGE_SIZE];
+ uint32_t i;
+
+ for (i = 0; i < sizeof(vrfy_buf); ++i)
+ vrfy_buf[i] = 0xFF;
+
+ _read_verify(vrfy_buf);
+}
+
+/*
+ * 3a. Write the entire flash with a pattern.
+ */
+static void test_write_page(void)
+{
+ uint8_t write_buf[N25Q128_PAGE_SIZE];
+ uint32_t i;
+ int err;
+
+ for (i = 0; i < sizeof(write_buf); ++i)
+ write_buf[i] = i & 0xFF;
+
+ for (i = 0; i < N25Q128_NUM_PAGES; ++i) {
+ err = n25q128_write_page(ctx, i, write_buf);
+ if (err != HAL_OK) {
+ uart_send_string("ERROR: n25q128_write_page returned ");
+ uart_send_integer(err, 1);
+ uart_send_string(" for page ");
+ uart_send_integer(i, 1);
+ uart_send_string("\r\n");
+ break;
+ }
+ }
+}
+
+/*
+ * 3b. Read the entire flash, verify data.
+ */
+static void test_verify_write(void)
+{
+ uint8_t vrfy_buf[N25Q128_PAGE_SIZE];
+ uint32_t i;
+
+ for (i = 0; i < sizeof(vrfy_buf); ++i)
+ vrfy_buf[i] = i & 0xFF;
+
+ _read_verify(vrfy_buf);
+}
+
+static void _time_check(char *label, const uint32_t t0, uint32_t n_rounds)
+{
+ uint32_t t = HAL_GetTick() - t0;
+
+ uart_send_string(label);
+ uart_send_integer(t / 1000, 1);
+ uart_send_char('.');
+ uart_send_integer(t % 1000, 3);
+ uart_send_string(" sec");
+ if (n_rounds > 1) {
+ uart_send_string(" for ");
+ uart_send_integer(n_rounds, 1);
+ uart_send_string(" rounds, ");
+ uart_send_integer(t / n_rounds, 1);
+ uart_send_char('.');
+ uart_send_integer(((t % n_rounds) * 100) / n_rounds, 2);
+ uart_send_string(" ms each");
+ }
+ uart_send_string("\r\n");
+}
+
+#define time_check(_label_, _expr_, _n_) \
+ do { \
+ uint32_t _t = HAL_GetTick(); \
+ (_expr_); \
+ _time_check(_label_, _t, _n_); \
+ } while (0)
+
+int main(void)
+{
+ stm_init();
+
+ if (n25q128_check_id(ctx) != HAL_OK) {
+ uart_send_string("ERROR: n25q128_check_id failed\r\n");
+ return 0;
+ }
+
+ uart_send_string("Starting...\r\n");
+
+ time_check("read page ", test_read_page(), N25Q128_NUM_PAGES);
+ time_check("read subsector ", test_read_subsector(), N25Q128_NUM_SUBSECTORS);
+ time_check("erase subsector ", test_erase_subsector(), N25Q128_NUM_SUBSECTORS);
+ time_check("erase sector ", test_erase_sector(), N25Q128_NUM_SECTORS);
+ time_check("erase bulk ", test_erase_bulk(), 1);
+ time_check("verify erase ", test_verify_erase(), N25Q128_NUM_PAGES);
+ time_check("write page ", test_write_page(), N25Q128_NUM_PAGES);
+ time_check("verify write ", test_verify_write(), N25Q128_NUM_PAGES);
+
+ uart_send_string("Done.\r\n\r\n");
+ return 0;
+}
diff --git a/projects/board-test/uart-test.c b/projects/board-test/uart-test.c
index be06863..9a56dee 100644
--- a/projects/board-test/uart-test.c
+++ b/projects/board-test/uart-test.c
@@ -6,7 +6,6 @@
* Toggles the BLUE LED slowly and the GREEN LED for every
* character sent.
*/
-#include "stm32f4xx_hal.h"
#include "stm-init.h"
#include "stm-led.h"
#include "stm-uart.h"