From 9278e9bafd96105b64f9946eb94f5618f01649d3 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Thu, 29 Oct 2015 15:42:29 -0400 Subject: add libhal tests, some cleanup (some mess-making) --- Makefile | 55 ++++++++---- bin/debug | 7 +- fmc-test.c | 240 ------------------------------------------------- hal_io_fmc.c | 25 +++++- include/stm-fmc.h | 7 +- include/stm-uart.h | 8 +- led-test.c | 33 ------- libc/printf.c | 26 ++++-- libc/syscalls.c | 195 ++++++++++++++++++++++++++++++++++++++++ main.c | 17 ++++ self-test/fmc-test.c | 240 +++++++++++++++++++++++++++++++++++++++++++++++++ self-test/led-test.c | 33 +++++++ self-test/short-test.c | 205 ++++++++++++++++++++++++++++++++++++++++++ self-test/uart-test.c | 34 +++++++ short-test.c | 205 ------------------------------------------ src/stm-fmc.c | 1 + src/stm-init.c | 21 ----- src/stm-uart.c | 53 ++++++++--- uart-test.c | 34 ------- 19 files changed, 855 insertions(+), 584 deletions(-) delete mode 100644 fmc-test.c delete mode 100644 led-test.c create mode 100644 libc/syscalls.c create mode 100644 main.c create mode 100644 self-test/fmc-test.c create mode 100644 self-test/led-test.c create mode 100644 self-test/short-test.c create mode 100644 self-test/uart-test.c delete mode 100644 short-test.c delete mode 100644 uart-test.c diff --git a/Makefile b/Makefile index 6f665f5..42acc00 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,6 @@ -PROJS = fmc-test led-test short-test uart-test +SELF-TESTS = fmc-test led-test short-test uart-test fmc-probe + +LIBHAL-TESTS = test-hash test-aes-key-wrap test-pbkdf2 #test-ecdsa test-rsa # put your *.o targets here, make should handle the rest! SRCS = stm32f4xx_hal_msp.c stm32f4xx_it.c stm-fmc.c stm-init.c stm-uart.c @@ -36,16 +38,18 @@ export OBJCOPY=$(PREFIX)objcopy export OBJDUMP=$(PREFIX)objdump export SIZE=$(PREFIX)size -CFLAGS = -ggdb -O2 -Wall -Wextra -Warray-bounds +#CFLAGS = -ggdb -O2 -Wall -Wextra -Warray-bounds +CFLAGS = -ggdb -O2 -Wall -Warray-bounds CFLAGS += -mcpu=cortex-m4 -mthumb -mlittle-endian -mthumb-interwork CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 CFLAGS += $(STDPERIPH_SETTINGS) CFLAGS += -ffunction-sections -fdata-sections CFLAGS += -Wl,--gc-sections +CFLAGS += -std=c99 ################################################### -vpath %.c src +vpath %.c src self-test vpath %.a $(STD_PERIPH_LIB) CFLAGS += -I include -I $(STD_PERIPH_LIB) -I $(STD_PERIPH_LIB)/CMSIS/Device/ST/STM32F4xx/Include @@ -55,38 +59,59 @@ OBJS = $(patsubst %.s,%.o, $(patsubst %.c,%.o, $(SRCS))) ################################################### -.PHONY: libstmf4 proj libhal libtfm lib +.PHONY: lib self-test -LIBS = libstmf4 libtfm libhal +LIBS = $(STD_PERIPH_LIB)/libstmf4.a libhal/libhal.a thirdparty/libtfm/libtfm.a -all: lib proj +all: lib self-test libhal-tests init: git submodule update --init --recursive lib: $(LIBS) -libstmf4: +export CFLAGS + +$(STD_PERIPH_LIB)/libstmf4.a: $(MAKE) -C $(STD_PERIPH_LIB) STDPERIPH_SETTINGS="$(STDPERIPH_SETTINGS) -I $(PWD)/include" -libtfm: - ${MAKE} -C thirdparty/libtfm PREFIX=$(PREFIX) +thirdparty/libtfm/libtfm.a: + $(MAKE) -C thirdparty/libtfm PREFIX=$(PREFIX) -libhal: hal_io_fmc.o - ${MAKE} -C libhal IO_OBJ=../hal_io_fmc.o libhal.a +libhal/libhal.a: hal_io_fmc.o thirdparty/libtfm/libtfm.a + $(MAKE) -C libhal IO_OBJ=../hal_io_fmc.o libhal.a -proj: $(PROJS:=.elf) +self-test: $(SELF-TESTS:=.elf) -%.elf: %.o $(OBJS) - $(CC) $(CFLAGS) $^ -o $@ -L$(STD_PERIPH_LIB) -lstmf4 -L$(LDSCRIPT_INC) -T$(MCU_LINKSCRIPT) -g -Wl,-Map=$*.map +%.elf: %.o $(OBJS) $(STD_PERIPH_LIB)/libstmf4.a + $(CC) $(CFLAGS) $^ -o $@ -L$(LDSCRIPT_INC) -T$(MCU_LINKSCRIPT) -g -Wl,-Map=$*.map $(OBJCOPY) -O ihex $*.elf $*.hex $(OBJCOPY) -O binary $*.elf $*.bin $(OBJDUMP) -St $*.elf >$*.lst $(SIZE) $*.elf +libhal-tests: $(LIBHAL-TESTS:=.bin) + +vpath %.c libhal/tests +CFLAGS += -I libhal + +# .mo extension for files with main() that need to be wrapped as __main() +%.mo: %.c + $(CC) -c $(CFLAGS) -Dmain=__main -o $@ $< + +vpath %.c libc +%.bin: %.mo main.o syscalls.o printf.o $(OBJS) $(LIBS) + $(CC) $(CFLAGS) $^ -o $*.elf -L$(LDSCRIPT_INC) -T$(MCU_LINKSCRIPT) -g -Wl,-Map=$*.map + $(OBJCOPY) -O ihex $*.elf $*.hex + $(OBJCOPY) -O binary $*.elf $*.bin + $(OBJDUMP) -St $*.elf >$*.lst + $(SIZE) $*.elf + +.SECONDARY: $(OBJS) *.mo main.o syscalls.o + clean: find ./ -name '*~' | xargs rm -f - rm -f $(OBJS) + rm -f $(OBJS) *.o *.mo rm -f *.elf rm -f *.hex rm -f *.bin diff --git a/bin/debug b/bin/debug index f6ede81..983b9bb 100755 --- a/bin/debug +++ b/bin/debug @@ -2,6 +2,11 @@ PROJ="${1?'project'}" -GDB=arm-none-eabi-gdb +OPENOCD=openocd +OPENOCD_PROC_FILE=/usr/share/openocd/scripts/board/st_nucleo_f401re.cfg +$OPENOCD -f $OPENOCD_BOARD_DIR/$OPENOCD_PROC_FILE & +GDB=arm-none-eabi-gdb $GDB -ex "target remote localhost:3333" -ex "set remote hardware-breakpoint-limit 6" -ex "set remote hardware-watchpoint-limit 4" $PROJ.elf + +kill -9 $(pidof $OPENOCD) diff --git a/fmc-test.c b/fmc-test.c deleted file mode 100644 index 0e8ff39..0000000 --- a/fmc-test.c +++ /dev/null @@ -1,240 +0,0 @@ -//------------------------------------------------------------------------------ -// 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, 100000); - uart_send_string(", addr: "); - uart_send_integer(addr_test_ok, 100000); - 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; c> 8) + + ((w & 0xff000000) >> 24); +} +#define ntohl htonl + static hal_error_t init(void) { if (!inited) { @@ -56,11 +67,17 @@ static hal_error_t init(void) } /* Translate cryptech register number to FMC address. - * This is a lot simpler than EIM, just shift the register number. + * + * register number format: + * 3 bits segment selector + * 5 bits core selector (6 bits in native eim) + * 8 bits register selector + * + * sss ccccc rrrrrrrr => sss 0 ccccc rrrrrrrr 00 */ static off_t fmc_offset(off_t offset) { - return (offset << 2); + return ((offset & ~0x1fff) << 3) + ((offset & 0x1fff) << 2); } void hal_io_set_debug(int onoff) @@ -94,7 +111,7 @@ hal_error_t hal_io_write(off_t offset, const uint8_t *buf, size_t len) offset = fmc_offset(offset); for (; len > 0; offset += 4, buf += 4, len -= 4) { uint32_t val; - val = *(uint32_t *)buf; + val = htonl(*(uint32_t *)buf); fmc_write_32(offset, &val); } @@ -117,7 +134,7 @@ hal_error_t hal_io_read(off_t offset, uint8_t *buf, size_t len) for (; rlen > 0; offset += 4, rbuf += 4, rlen -= 4) { uint32_t val; fmc_read_32(offset, &val); - *(uint32_t *)rbuf = val; + *(uint32_t *)rbuf = ntohl(val); } dump("read ", buf, len); diff --git a/include/stm-fmc.h b/include/stm-fmc.h index 196d65e..cf9b77e 100644 --- a/include/stm-fmc.h +++ b/include/stm-fmc.h @@ -2,12 +2,7 @@ // stm-fmc.h //------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// Headers -//------------------------------------------------------------------------------ -#include "stm32f4xx_hal.h" - +#include //------------------------------------------------------------------------------ // Prototypes diff --git a/include/stm-uart.h b/include/stm-uart.h index 43df882..62b2efd 100644 --- a/include/stm-uart.h +++ b/include/stm-uart.h @@ -5,14 +5,12 @@ #define USART2_BAUD_RATE 115200 -#if 0 /* XXX moved [back] to stm-init.c */ extern void MX_USART2_UART_Init(void); -#endif -extern void uart_send_binary(uint32_t num, uint8_t bits); +extern void uart_send_char(uint8_t ch); extern void uart_send_string(char *s); +extern void uart_send_binary(uint32_t num, uint8_t bits); extern void uart_send_integer(uint32_t data, uint32_t mag); - -extern UART_HandleTypeDef huart2; +extern void uart_send_hex(uint32_t num, uint8_t digits); #endif /* __STM32_DEV_BRIDGE_UART_H */ diff --git a/led-test.c b/led-test.c deleted file mode 100644 index 5e4401f..0000000 --- a/led-test.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Blink the four LEDs on the rev01 board in a pattern. - */ -#include "stm32f4xx_hal.h" -#include "stm-init.h" -#include "stm-led.h" - -#define DELAY() HAL_Delay(125) - -void toggle_led(uint32_t times, uint32_t led_pin) -{ - uint32_t i; - - for (i = 0; i < times; i++) { - HAL_GPIO_TogglePin(LED_PORT, led_pin); - DELAY(); - } -} - -int -main() -{ - stm_init(); - - while (1) - { - toggle_led(2, LED_BLUE); - toggle_led(2, LED_GREEN); - toggle_led(2, LED_YELLOW); - toggle_led(2, LED_RED); - } - -} diff --git a/libc/printf.c b/libc/printf.c index 78f210a..695fcd7 100644 --- a/libc/printf.c +++ b/libc/printf.c @@ -47,6 +47,7 @@ mod: N near ptr DONE *****************************************************************************/ #include /* strlen() */ #include /* stdout, putchar(), fputs() (but not printf() :) */ +#undef putchar #if 1 #include /* va_list, va_start(), va_arg(), va_end() */ @@ -93,15 +94,9 @@ typedef void *va_list; #define PR_WS 0x20 /* PR_SG set and num was < 0 */ #define PR_LZ 0x40 /* pad left with '0' instead of ' ' */ #define PR_FP 0x80 /* pointers are far */ -#if 0 -/* largest number handled is 2^32-1, lowest radix handled is 8. -2^32-1 in base 8 has 11 digits (add 5 for trailing NUL and for slop) */ -#define PR_BUFLEN 16 -#else /* largest number handled is 2^64-1, lowest radix handled is 8. 2^64-1 in base 8 has 22 digits (add 2 for trailing NUL and for slop) */ #define PR_BUFLEN 24 -#endif typedef int (*fnptr_t)(unsigned c, void **helper); /***************************************************************************** @@ -410,3 +405,22 @@ int main(void) return 0; } #endif + +/***************************************************************************** +2015-10-29 pselkirk for cryptech +*****************************************************************************/ +/* gcc decides that a plain string with no formatting is best handled by puts() */ +int puts(const char *s) +{ + return printf("%s\n", s); +} + +/* transmit characters to the uart */ +#include "stm-uart.h" +int putchar(int c) +{ + if (c == '\n') + uart_send_char('\r'); + uart_send_char((uint8_t) c); + return c; +} diff --git a/libc/syscalls.c b/libc/syscalls.c new file mode 100644 index 0000000..9212763 --- /dev/null +++ b/libc/syscalls.c @@ -0,0 +1,195 @@ +/**************************************************************************** +* Copyright (c) 2009 by Michael Fischer. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. Neither the name of the author nor the names of its contributors may +* be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +**************************************************************************** +* History: +* +* 28.03.09 mifi First Version, based on the original syscall.c from +* newlib version 1.17.0 +****************************************************************************/ + +/* 2015-10-29 pselkirk for cryptech: + * Changed asm to __asm for c99 compatibility. + * Added _exit, _kill, and _getpid from mifi's 2013 revision. + */ + +#include +#include +#include +#include +#include + +/***************************************************************************/ + +int _read_r (struct _reent *r, int file, char * ptr, int len) +{ + r = r; + file = file; + ptr = ptr; + len = len; + + errno = EINVAL; + return -1; +} + +/***************************************************************************/ + +int _lseek_r (struct _reent *r, int file, int ptr, int dir) +{ + r = r; + file = file; + ptr = ptr; + dir = dir; + + return 0; +} + +/***************************************************************************/ + +int _write_r (struct _reent *r, int file, char * ptr, int len) +{ + r = r; + file = file; + ptr = ptr; + +#if 0 + int index; + + /* For example, output string by UART */ + for(index=0; index stack_ptr) + { + /* Some of the libstdc++-v3 tests rely upon detecting + out of memory errors, so do not abort here. */ +#if 0 + extern void abort (void); + + _write (1, "_sbrk: Heap and stack collision\n", 32); + + abort (); +#else + errno = ENOMEM; + return (caddr_t) -1; +#endif + } + + heap_end += incr; + + return (caddr_t) prev_heap_end; +} + +/***************************************************************************/ + +int _fstat_r (struct _reent *r, int file, struct stat * st) +{ + r = r; + file = file; + + memset (st, 0, sizeof (* st)); + st->st_mode = S_IFCHR; + return 0; +} + +/***************************************************************************/ + +int _isatty_r(struct _reent *r, int fd) +{ + r = r; + fd = fd; + + return 1; +} + +/***************************************************************************/ + +void _exit (int a) +{ + a = a; + + while(1) {}; +} + +/***************************************************************************/ + +int _kill (int a, int b) +{ + a = a; + b = b; + + return 0; +} + +/***************************************************************************/ + +int _getpid(int a) +{ + a = a; + + return 0; +} + +/*** EOF ***/ + + diff --git a/main.c b/main.c new file mode 100644 index 0000000..feec344 --- /dev/null +++ b/main.c @@ -0,0 +1,17 @@ +/* A wrapper for test programs that contain main() (currently libhal/tests). + * We compile them with -Dmain=__main, so we can do stm setup first. + */ + +#include "stm-init.h" +#include "stm-uart.h" + +void main(void) +{ + stm_init(); + fmc_init(); + while(1) { + __main(); + uart_send_string("\r\n"); + HAL_Delay(2000); + } +} diff --git a/self-test/fmc-test.c b/self-test/fmc-test.c new file mode 100644 index 0000000..0e8ff39 --- /dev/null +++ b/self-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, 100000); + uart_send_string(", addr: "); + uart_send_integer(addr_test_ok, 100000); + 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/self-test/uart-test.c b/self-test/uart-test.c new file mode 100644 index 0000000..8fe7795 --- /dev/null +++ b/self-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); + } + } +} diff --git a/short-test.c b/short-test.c deleted file mode 100644 index 6dd97f4..0000000 --- a/short-test.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * 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" - -void test_for_shorts(char port, GPIO_TypeDef* GPIOx, uint16_t GPIO_Test_Pins); - -//------------------------------------------------------------------------------ -// Defines -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -// Macros -//------------------------------------------------------------------------------ - -/* These are all the pins used by the FMC interface */ -#define GPIOB_PINS (GPIO_PIN_7) - -#define GPIOD_PINS (GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 \ - |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15 \ - |GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_3|GPIO_PIN_4 \ - |GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7) - -#define GPIOE_PINS (GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7 \ - |GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 \ - |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15) - -#define GPIOF_PINS (GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 \ - |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_12|GPIO_PIN_13 \ - |GPIO_PIN_14|GPIO_PIN_15) - -#define GPIOG_PINS (GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 \ - |GPIO_PIN_4|GPIO_PIN_5) - -#define GPIOH_PINS (GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 \ - |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15) - -#define GPIOI_PINS (GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_0|GPIO_PIN_1 \ - |GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_6|GPIO_PIN_7) - -int -main() -{ - stm_init(); - - // enable gpio clocks - __GPIOA_CLK_ENABLE(); - __GPIOB_CLK_ENABLE(); - __GPIOD_CLK_ENABLE(); - __GPIOE_CLK_ENABLE(); - __GPIOF_CLK_ENABLE(); - __GPIOG_CLK_ENABLE(); - __GPIOH_CLK_ENABLE(); - __GPIOI_CLK_ENABLE(); - - while (1) { - HAL_GPIO_TogglePin(LED_PORT, LED_GREEN); - HAL_UART_Transmit(&huart2, (uint8_t *) "\r\n\r\n\r\n\r\n\r\n", 10, 0x1); - - test_for_shorts('B', GPIOB, GPIOB_PINS); - test_for_shorts('D', GPIOD, GPIOD_PINS); - test_for_shorts('E', GPIOE, GPIOE_PINS); - test_for_shorts('F', GPIOF, GPIOF_PINS); - test_for_shorts('G', GPIOG, GPIOG_PINS); - test_for_shorts('H', GPIOH, GPIOH_PINS); - test_for_shorts('I', GPIOI, GPIOI_PINS); - led_toggle(LED_BLUE); - HAL_Delay(2000); - } -} - -void configure_all_as_input(GPIO_TypeDef* GPIOx, uint16_t GPIO_Test_Pins) -{ - GPIO_InitTypeDef GPIO_InitStruct; - - /* Configure all pins as input. XXX do all pins (0xffff) instead of just GPIO_Test_Pins? */ - GPIO_InitStruct.Pin = GPIO_Test_Pins; - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Pull = GPIO_PULLDOWN; - GPIO_InitStruct.Speed = GPIO_SPEED_LOW; - HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); -} - -uint8_t check_no_input(char port, GPIO_TypeDef* GPIOx, uint16_t GPIO_Test_Pins, char wrote_port, uint16_t wrote_value) -{ - uint16_t read; - - /* Read all pins from port at once. XXX check all pins, not just GPIO_Test_Pins? */ - read = (GPIOx->IDR & GPIO_Test_Pins); - - if (! read) { - /* No unexpected pins read as HIGH */ - return 0; - } - - led_on(LED_RED); - - HAL_UART_Transmit(&huart2, (uint8_t *) "Wrote ", 6, 0x1); - uart_send_binary(wrote_value, 16); - - HAL_UART_Transmit(&huart2, (uint8_t *) " to port GPIO", 13, 0x1); - HAL_UART_Transmit(&huart2, (uint8_t *) &wrote_port, 1, 0x1); - - HAL_UART_Transmit(&huart2, (uint8_t *) ", read ", 7, 0x1); - uart_send_binary(read, 16); - - HAL_UART_Transmit(&huart2, (uint8_t *) " from GPIO", 10, 0x1); - HAL_UART_Transmit(&huart2, (uint8_t *) &port, 1, 0x1); - - HAL_UART_Transmit(&huart2, (uint8_t *) "\r\n", 2, 0x1); - - 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); - HAL_UART_Transmit(&huart2, (uint8_t *) "GPIO", 4, 0x1); - HAL_UART_Transmit(&huart2, (uint8_t *) &port, 1, 0x1); - - HAL_UART_Transmit(&huart2, (uint8_t *) " exp ", 5, 0x1); - uart_send_binary(Test_Pin, 16); - - HAL_UART_Transmit(&huart2, (uint8_t *) " got ", 5, 0x1); - uart_send_binary(read, 16); - - HAL_UART_Transmit(&huart2, (uint8_t *) " diff ", 6, 0x1); - uart_send_binary(read ^ Test_Pin, 16); - - HAL_UART_Transmit(&huart2, (uint8_t *) "\r\n", 2, 0x1); - - 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) { - HAL_UART_Transmit(&huart2, (uint8_t *) "\r\n", 2, 0x1); - } -} diff --git a/src/stm-fmc.c b/src/stm-fmc.c index bc214d8..19b7fdc 100644 --- a/src/stm-fmc.c +++ b/src/stm-fmc.c @@ -7,6 +7,7 @@ // Headers //------------------------------------------------------------------------------ #include "stm-fmc.h" +#include "stm32f4xx_hal.h" //------------------------------------------------------------------------------ diff --git a/src/stm-init.c b/src/stm-init.c index 01a68e4..f8610cd 100644 --- a/src/stm-init.c +++ b/src/stm-init.c @@ -39,15 +39,12 @@ #include "stm-fmc.h" #include "stm-uart.h" -UART_HandleTypeDef huart2; - /* Private variables ---------------------------------------------------------*/ static GPIO_InitTypeDef GPIO_InitStruct; /* Private function prototypes -----------------------------------------------*/ static void SystemClock_Config(void); static void MX_GPIO_Init(void); -static void MX_USART2_UART_Init(void); void stm_init(void) { @@ -130,24 +127,6 @@ static void old_SystemClock_Config(void) } #endif -/* USART2 init function */ -static void MX_USART2_UART_Init(void) -{ - huart2.Instance = USART2; - huart2.Init.BaudRate = USART2_BAUD_RATE; - huart2.Init.WordLength = UART_WORDLENGTH_8B; - huart2.Init.StopBits = UART_STOPBITS_1; - huart2.Init.Parity = UART_PARITY_NONE; - huart2.Init.Mode = UART_MODE_TX_RX; - huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; - huart2.Init.OverSampling = UART_OVERSAMPLING_16; - - if (HAL_UART_Init(&huart2) != HAL_OK) { - /* Initialization Error */ - Error_Handler(); - } -} - /** Configure pins as * Analog * Input diff --git a/src/stm-uart.c b/src/stm-uart.c index 61ba910..61f3e5b 100644 --- a/src/stm-uart.c +++ b/src/stm-uart.c @@ -4,7 +4,7 @@ #include -UART_HandleTypeDef huart2; +static UART_HandleTypeDef huart2; extern void Error_Handler(); @@ -13,7 +13,6 @@ extern void Error_Handler(); /* Private function prototypes -----------------------------------------------*/ -#if 0 /* XXX moved [back] to stm-init.c */ /* USART2 init function */ void MX_USART2_UART_Init(void) { @@ -31,12 +30,21 @@ void MX_USART2_UART_Init(void) Error_Handler(); } } -#endif + +void uart_send_char(uint8_t ch) +{ + HAL_UART_Transmit(&huart2, &ch, 1, 0x1); +} + +void uart_send_string(char *s) +{ + HAL_UART_Transmit(&huart2, (uint8_t *) s, strlen(s), 0x1); +} void uart_send_binary(uint32_t num, uint8_t bits) { uint32_t i; - unsigned char ch; + uint8_t ch; bits--; /* bits 4 should give i = 1000, not 10000 */ @@ -46,26 +54,21 @@ void uart_send_binary(uint32_t num, uint8_t bits) if (num & i) { ch = '1'; } - - HAL_UART_Transmit(&huart2, (uint8_t *) &ch, 1, 0x1); + uart_send_char(ch); i = i >> 1; } } -void uart_send_string(char *s) -{ - HAL_UART_Transmit(&huart2, (uint8_t *) s, strlen(s), 0x1); -} - +/* XXX this takes a mask, not a number of digits */ void uart_send_integer(uint32_t data, uint32_t mag) { uint32_t i, t; - unsigned char ch; + uint8_t ch; if (! mag) { /* Find magnitude */ if (data < 10) { ch = '0' + data; - HAL_UART_Transmit(&huart2, (uint8_t *) &ch, 1, 0x1); + uart_send_char(ch); return; } @@ -79,7 +82,29 @@ void uart_send_integer(uint32_t data, uint32_t mag) { for (i = mag; i; i /= 10) { t = (data / i); ch = '0' + t; - HAL_UART_Transmit(&huart2, (uint8_t *) &ch, 1, 0x1); + uart_send_char(ch); data -= (t * i); } } + +void uart_send_hex(uint32_t num, uint8_t digits) +{ + uint8_t ch; + uint32_t mask; + + mask = 0x0FL << ((digits - 1) * 4); + + if (digits == 0 || digits > 8) + digits = 8; + + while (digits) { + ch = (num & mask) >> ((digits - 1) * 4); + if (ch < 10) + ch += '0'; + else + ch += 'A' - 10; + uart_send_char(ch); + --digits; + mask >>= 4; + } +} diff --git a/uart-test.c b/uart-test.c deleted file mode 100644 index 0f8926a..0000000 --- a/uart-test.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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); - - HAL_UART_Transmit(&huart2, (uint8_t *) &c, 1, 0x1); - DELAY(); - - if (c++ == 'z') { - c = 'a'; - HAL_GPIO_TogglePin(LED_PORT, LED_BLUE); - } - } -} -- cgit v1.2.3