From 79b1ba7104dba52dbfacf11a07305702889f440b Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Mon, 11 Apr 2016 14:44:44 -0400 Subject: Reorganize Makefile and directory structure, because it's messy, and it's about to get messier. --- projects/board-test/Makefile | 18 +++ projects/board-test/fmc-perf.c | 126 ++++++++++++++++++++ projects/board-test/fmc-test.c | 240 +++++++++++++++++++++++++++++++++++++++ projects/board-test/led-test.c | 33 ++++++ projects/board-test/short-test.c | 205 +++++++++++++++++++++++++++++++++ projects/board-test/uart-test.c | 34 ++++++ 6 files changed, 656 insertions(+) create mode 100644 projects/board-test/Makefile create mode 100644 projects/board-test/fmc-perf.c create mode 100644 projects/board-test/fmc-test.c create mode 100644 projects/board-test/led-test.c create mode 100644 projects/board-test/short-test.c create mode 100644 projects/board-test/uart-test.c (limited to 'projects/board-test') diff --git a/projects/board-test/Makefile b/projects/board-test/Makefile new file mode 100644 index 0000000..21f24c9 --- /dev/null +++ b/projects/board-test/Makefile @@ -0,0 +1,18 @@ +TEST = led-test short-test uart-test fmc-test fmc-perf + +all: $(TEST:=.elf) + +%.elf: %.o $(BOARD_OBJS) $(LIBS) + $(CC) $(CFLAGS) $^ -o $@ -T$(LDSCRIPT) -g -Wl,-Map=$*.map + $(OBJCOPY) -O ihex $*.elf $*.hex + $(OBJCOPY) -O binary $*.elf $*.bin + $(OBJDUMP) -St $*.elf >$*.lst + $(SIZE) $*.elf + +clean: + rm -f *.o + rm -f *.elf + rm -f *.hex + rm -f *.bin + rm -f *.map + rm -f *.lst diff --git a/projects/board-test/fmc-perf.c b/projects/board-test/fmc-perf.c new file mode 100644 index 0000000..0c753a7 --- /dev/null +++ b/projects/board-test/fmc-perf.c @@ -0,0 +1,126 @@ +/* + * Test read/write performance of the fmc bus + */ +#include "stm32f4xx_hal.h" +#include "stm-init.h" +#include "stm-led.h" +#include "stm-fmc.h" +#include "stm-uart.h" + +#define TEST_NUM_ROUNDS 2000000 + +RNG_HandleTypeDef rng_inst; + +static void MX_RNG_Init(void) +{ + rng_inst.Instance = RNG; + HAL_RNG_Init(&rng_inst); +} + +static uint32_t random(void) +{ + uint32_t rnd; + if (HAL_RNG_GenerateRandomNumber(&rng_inst, &rnd) != HAL_OK) { + uart_send_string("HAL_RNG_GenerateRandomNumber failed\r\n"); + Error_Handler(); + } + return rnd; +} + +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(); + } + if (data != rnd) { + uart_send_string("Data bus fail: expected "); + uart_send_hex(rnd, 8); + uart_send_string(", got "); + uart_send_hex(data, 8); + uart_send_string(", diff "); + uart_send_hex(data ^ rnd, 8); + uart_send_string("\r\n"); + Error_Handler(); + } +} + +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_char('.'); + uart_send_integer(t % 1000, 3); + uart_send_string(" seconds, "); + uart_send_integer(((1000 * TEST_NUM_ROUNDS) / t), 0); + uart_send_string("/sec\r\n"); +} + +#define time_check(_label_, _expr_) \ + do { \ + uint32_t _t = HAL_GetTick(); \ + (_expr_); \ + _time_check(_label_, _t); \ + } while (0) + +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(); + } + } +} + +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(); + } + } +} + +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()); + time_check("write ", test_write()); + + uart_send_string("Done.\r\n\r\n"); + return 0; +} diff --git a/projects/board-test/fmc-test.c b/projects/board-test/fmc-test.c new file mode 100644 index 0000000..cf17087 --- /dev/null +++ b/projects/board-test/fmc-test.c @@ -0,0 +1,240 @@ +//------------------------------------------------------------------------------ +// main.c +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ +#include "stm32f4xx_hal.h" +#include "stm-init.h" +#include "stm-led.h" +#include "stm-fmc.h" +#include "stm-uart.h" + +//------------------------------------------------------------------------------ +// Defines +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Macros +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Variables +//------------------------------------------------------------------------------ +RNG_HandleTypeDef rng_inst; + +// FT: "I changed some interesting-to-look-at-in-the-debugger values to be +// volatile, so that my compiler wouldn't optimize/obscure them." + +volatile uint32_t data_diff = 0; +volatile uint32_t addr_diff = 0; + + +//------------------------------------------------------------------------------ +// Prototypes +//------------------------------------------------------------------------------ +/* XXX move this to stm-rng.[ch] */ +static void MX_RNG_Init(void); + +int test_fpga_data_bus(void); +int test_fpga_address_bus(void); + + +//------------------------------------------------------------------------------ +// Defines +//------------------------------------------------------------------------------ +#define TEST_NUM_ROUNDS 100000 + + +//------------------------------------------------------------------------------ +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); + } + + // 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); + led_off(LED_RED); + led_off(LED_BLUE); + + // vars + volatile int data_test_ok = 0, addr_test_ok = 0, successful_runs = 0, failed_runs = 0, sleep = 0; + + // main loop (test, until an error is detected) + while (1) + { + // test data bus + data_test_ok = test_fpga_data_bus(); + // 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 (data_test_ok == TEST_NUM_ROUNDS && + addr_test_ok == TEST_NUM_ROUNDS) { + // toggle yellow led to indicate, that we are alive + led_toggle(LED_YELLOW); + + successful_runs++; + sleep = 100; + } else { + led_on(LED_RED); + failed_runs++; + sleep = 2000; + } + + uart_send_string("Success "); + uart_send_integer(successful_runs, 0); + uart_send_string(", fail "); + uart_send_integer(failed_runs, 0); + uart_send_string("\r\n\r\n"); + + HAL_Delay(sleep); + } + + // should never reach this line +} + + +//------------------------------------------------------------------------------ +int test_fpga_data_bus(void) +//------------------------------------------------------------------------------ +{ + int c, ok; + uint32_t rnd, buf; + HAL_StatusTypeDef hal_result; + + // run some rounds of data bus test + for (c=0; cIDR & GPIO_Test_Pins); + + if (! read) { + /* No unexpected pins read as HIGH */ + return 0; + } + + led_on(LED_RED); + + uart_send_string("Wrote "); + uart_send_binary(wrote_value, 16); + + uart_send_string(" to port GPIO"); + uart_send_char(wrote_port); + + uart_send_string(", read "); + uart_send_binary(read, 16); + + uart_send_string(" from GPIO"); + uart_send_char(port); + + uart_send_string("\r\n"); + + return 1; +} + +void test_for_shorts(char port, GPIO_TypeDef* GPIOx, uint16_t GPIO_Test_Pins) +{ + GPIO_InitTypeDef GPIO_InitStruct; + uint16_t i, fail = 0, Test_Pin, read; + + configure_all_as_input(GPIOB, GPIOB_PINS); + configure_all_as_input(GPIOD, GPIOD_PINS); + configure_all_as_input(GPIOE, GPIOE_PINS); + configure_all_as_input(GPIOF, GPIOF_PINS); + configure_all_as_input(GPIOG, GPIOG_PINS); + configure_all_as_input(GPIOH, GPIOH_PINS); + configure_all_as_input(GPIOI, GPIOI_PINS); + + check_no_input('B', GPIOB, GPIOB_PINS, 'x', 0); + check_no_input('D', GPIOD, GPIOD_PINS, 'x', 0); + check_no_input('E', GPIOE, GPIOE_PINS, 'x', 0); + check_no_input('F', GPIOF, GPIOF_PINS, 'x', 0); + check_no_input('G', GPIOG, GPIOG_PINS, 'x', 0); + check_no_input('H', GPIOH, GPIOH_PINS, 'x', 0); + check_no_input('I', GPIOI, GPIOI_PINS, 'x', 0); + + for (i = 0; i < 31; i++) { + Test_Pin = 1 << i; + if (! (GPIO_Test_Pins & Test_Pin)) continue; + + configure_all_as_input(GPIOx, GPIO_Test_Pins); + + /* Change one pin to output */ + GPIO_InitStruct.Pin = Test_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_LOW; + HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); + + HAL_GPIO_WritePin(GPIOx, Test_Pin, GPIO_PIN_SET); + + /* Slight delay after setting the output pin. Without this, the Test_Pin + bit might read as zero, as it is only sampled once every AHB1 clock cycle. + Reference manual DM00031020 section 8.3.1. + */ + HAL_Delay(1); + + /* Read all input GPIOs from port at once. XXX check all pins, not just GPIO_Test_Pins? */ + read = GPIOx->IDR & GPIO_Test_Pins; + + if (read == Test_Pin) { + /* No unexpected pins read as HIGH */ + led_toggle(LED_GREEN); + } else { + led_on(LED_RED); + uart_send_string("GPIO"); + uart_send_char(port); + + uart_send_string(" exp "); + uart_send_binary(Test_Pin, 16); + + uart_send_string(" got "); + uart_send_binary(read, 16); + + uart_send_string(" diff "); + uart_send_binary(read ^ Test_Pin, 16); + + uart_send_string("\r\n"); + + fail++; + } + + /* Check there is no input on any of the other GPIO ports (adjacent pins might live on different ports) */ + if (port != 'B') fail += check_no_input('B', GPIOB, GPIOB_PINS, port, Test_Pin); + if (port != 'D') fail += check_no_input('D', GPIOD, GPIOD_PINS, port, Test_Pin); + if (port != 'E') fail += check_no_input('E', GPIOE, GPIOE_PINS, port, Test_Pin); + if (port != 'F') fail += check_no_input('F', GPIOF, GPIOF_PINS, port, Test_Pin); + if (port != 'G') fail += check_no_input('G', GPIOG, GPIOG_PINS, port, Test_Pin); + if (port != 'H') fail += check_no_input('H', GPIOH, GPIOH_PINS, port, Test_Pin); + if (port != 'I') fail += check_no_input('I', GPIOI, GPIOI_PINS, port, Test_Pin); + + HAL_GPIO_WritePin(GPIOx, Test_Pin, GPIO_PIN_RESET); + } + + if (fail) { + uart_send_string("\r\n"); + } +} diff --git a/projects/board-test/uart-test.c b/projects/board-test/uart-test.c new file mode 100644 index 0000000..8fe7795 --- /dev/null +++ b/projects/board-test/uart-test.c @@ -0,0 +1,34 @@ +/* + * Test code that just sends the letters 'a' to 'z' over and + * over again using USART2. + * + * 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" + +#define DELAY() HAL_Delay(100) + +int +main() +{ + uint8_t c = 'a'; + + stm_init(); + + while (1) + { + HAL_GPIO_TogglePin(LED_PORT, LED_RED); + + uart_send_char(c); + DELAY(); + + if (c++ == 'z') { + c = 'a'; + HAL_GPIO_TogglePin(LED_PORT, LED_BLUE); + } + } +} -- cgit v1.2.3