[Cryptech-Commits] [sw/stm32] branch no-rtos updated: Merge branch 'init_cleanup' into no-rtos

git at cryptech.is git at cryptech.is
Tue May 2 22:26:23 UTC 2017


This is an automated email from the git hooks/post-receive script.

paul at psgd.org pushed a commit to branch no-rtos
in repository sw/stm32.

The following commit(s) were added to refs/heads/no-rtos by this push:
     new 1175ff6  Merge branch 'init_cleanup' into no-rtos
1175ff6 is described below

commit 1175ff63f2a8c4762692551403862f9f0789aef8
Author: Paul Selkirk <paul at psgd.org>
AuthorDate: Tue May 2 17:10:02 2017 -0400

    Merge branch 'init_cleanup' into no-rtos
    
    Clean up Makefiles and initialization code.
---
 Makefile                            |  47 ++--
 projects/board-test/Makefile        |   5 +-
 projects/board-test/fmc-perf.c      |  15 --
 projects/board-test/fmc-probe.c     |  20 --
 projects/board-test/fmc-test.c      |   7 +-
 projects/board-test/led-test.c      |   1 -
 projects/board-test/rtc-test.c      |  70 ++---
 projects/board-test/short-test.c    |   1 -
 projects/board-test/uart-test.c     |   1 -
 projects/bootloader/Makefile        |   1 -
 projects/bootloader/bootloader.c    |   8 +-
 projects/cli-test/Makefile          |   1 -
 projects/cli-test/mgmt-test.c       |  12 -
 projects/cli-test/test_sdram.c      |   1 -
 projects/hsm/Makefile               |  14 +-
 projects/hsm/hsm.c                  |   4 -
 projects/hsm/mgmt-misc.c            |   6 +-
 projects/libhal-test/Makefile       |   3 -
 projects/libhal-test/main.c         |  11 -
 projects/rtos-test/Makefile         |  22 --
 projects/rtos-test/mutex-test.c     |  40 ---
 projects/rtos-test/semaphore-test.c |  34 ---
 projects/rtos-test/thread-test.c    |  24 --
 stm-flash.c                         |   3 +-
 stm-fmc.c                           | 176 ++++++-------
 stm-fmc.h                           |   4 +-
 stm-fpgacfg.c                       |  35 ++-
 stm-fpgacfg.h                       |   3 +-
 stm-init.c                          | 214 +++------------
 stm-keystore.c                      |  28 +-
 stm-keystore.h                      |   3 +-
 stm-rtc.c                           |  20 +-
 stm-rtc.h                           |   3 +-
 stm-sdram.c                         | 500 ++++++++++++++++--------------------
 stm-sdram.h                         |  95 ++++---
 stm-uart.c                          |  75 +++++-
 stm-uart.h                          |   2 +
 37 files changed, 608 insertions(+), 901 deletions(-)

diff --git a/Makefile b/Makefile
index 9f33437..d8c9593 100644
--- a/Makefile
+++ b/Makefile
@@ -27,32 +27,35 @@
 # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+# export all variables to child processes by default
+.EXPORT_ALL_VARIABLES:
+
 # absolute path, because we're going to be passing things to sub-makes
-export TOPLEVEL = $(abspath .)
-export CRYPTECH_ROOT = $(abspath ../..)
+TOPLEVEL = $(abspath .)
+CRYPTECH_ROOT = $(abspath ../..)
 
 # define board: dev-bridge or alpha
 BOARD = TARGET_CRYPTECH_ALPHA
 
-export LIBS_DIR = $(TOPLEVEL)/libraries
-export MBED_DIR = $(LIBS_DIR)/mbed
-export CMSIS_DIR = $(MBED_DIR)/targets/cmsis/TARGET_STM/TARGET_STM32F4
-export BOARD_DIR = $(CMSIS_DIR)/$(BOARD)
+LIBS_DIR = $(TOPLEVEL)/libraries
+MBED_DIR = $(LIBS_DIR)/mbed
+CMSIS_DIR = $(MBED_DIR)/targets/cmsis/TARGET_STM/TARGET_STM32F4
+BOARD_DIR = $(CMSIS_DIR)/$(BOARD)
 
-export LIBHAL_SRC = $(CRYPTECH_ROOT)/sw/libhal
-export LIBHAL_BLD = $(LIBS_DIR)/libhal
+LIBHAL_SRC = $(CRYPTECH_ROOT)/sw/libhal
+LIBHAL_BLD = $(LIBS_DIR)/libhal
 
-export LIBCLI_SRC = $(CRYPTECH_ROOT)/user/paul/libcli
-export LIBCLI_BLD = $(LIBS_DIR)/libcli
+LIBCLI_SRC = $(CRYPTECH_ROOT)/user/paul/libcli
+LIBCLI_BLD = $(LIBS_DIR)/libcli
 
-export LIBTFM_SRC = $(CRYPTECH_ROOT)/sw/thirdparty/libtfm
-export LIBTFM_BLD = $(LIBS_DIR)/libtfm
+LIBTFM_SRC = $(CRYPTECH_ROOT)/sw/thirdparty/libtfm
+LIBTFM_BLD = $(LIBS_DIR)/libtfm
 
-export LIBS = $(MBED_DIR)/libstmf4.a
+LIBS = $(MBED_DIR)/libstmf4.a
 
 # linker script
-export LDSCRIPT = $(BOARD_DIR)/TOOLCHAIN_GCC_ARM/STM32F429BI.ld
-export BOOTLOADER_LDSCRIPT = $(BOARD_DIR)/TOOLCHAIN_GCC_ARM/STM32F429BI_bootloader.ld
+LDSCRIPT = $(BOARD_DIR)/TOOLCHAIN_GCC_ARM/STM32F429BI.ld
+BOOTLOADER_LDSCRIPT = $(BOARD_DIR)/TOOLCHAIN_GCC_ARM/STM32F429BI_bootloader.ld
 
 # board-specific objects, to link into every project
 BOARD_OBJS = \
@@ -73,16 +76,15 @@ BOARD_OBJS += \
 	$(TOPLEVEL)/stm-sdram.o \
 	$(TOPLEVEL)/stm-flash.o
 endif
-export BOARD_OBJS
 
 # cross-building tools
 PREFIX=arm-none-eabi-
-export CC=$(PREFIX)gcc
-export AS=$(PREFIX)as
-export AR=$(PREFIX)ar
-export OBJCOPY=$(PREFIX)objcopy
-export OBJDUMP=$(PREFIX)objdump
-export SIZE=$(PREFIX)size
+CC=$(PREFIX)gcc
+AS=$(PREFIX)as
+AR=$(PREFIX)ar
+OBJCOPY=$(PREFIX)objcopy
+OBJDUMP=$(PREFIX)objdump
+SIZE=$(PREFIX)size
 
 # The Alpha is a development platform, so set GCC optimization to a
 # level suitable for debugging.  Recent versions of GCC have a special
@@ -111,7 +113,6 @@ CFLAGS += -I$(MBED_DIR)/targets/cmsis/TARGET_STM/TARGET_STM32F4
 CFLAGS += -I$(MBED_DIR)/targets/cmsis/TARGET_STM/TARGET_STM32F4/$(BOARD)
 CFLAGS += -I$(MBED_DIR)/targets/hal/TARGET_STM/TARGET_STM32F4
 CFLAGS += -I$(MBED_DIR)/targets/hal/TARGET_STM/TARGET_STM32F4/$(BOARD)
-export CFLAGS
 
 %.o : %.c
 	$(CC) $(CFLAGS) -c -o $@ $<
diff --git a/projects/board-test/Makefile b/projects/board-test/Makefile
index bb6a8cf..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 spiflash-perf keystore-perf
+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..5ed47ec 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"
@@ -99,23 +98,9 @@ static void test_write(void)
 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..5f7fdb5 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"
@@ -32,27 +31,8 @@ static uint32_t read0(uint32_t addr)
 
 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..c6a37e6 100644
--- a/projects/board-test/fmc-test.c
+++ b/projects/board-test/fmc-test.c
@@ -34,11 +34,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
@@ -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);
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..f1c2db1 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_string("SRAM contents:\r\n");
     uart_send_hexdump(STM_UART_MGMT, 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_string("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("\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_string("EEPROM EUI-48:\r\n");
     uart_send_hexdump(STM_UART_MGMT, 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,8 @@ int
 main()
 {
     stm_init();
-    uart_send_string2(STM_UART_MGMT, "\r\n\r\n*** Init done\r\n");
+    uart_set_default(STM_UART_MGMT);
+    uart_send_string("\r\n\r\n*** Init done\r\n");
 
     dump_sram();
     dump_eeprom();
@@ -148,7 +148,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/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"
diff --git a/projects/bootloader/Makefile b/projects/bootloader/Makefile
index fe96982..6c1012f 100644
--- a/projects/bootloader/Makefile
+++ b/projects/bootloader/Makefile
@@ -7,7 +7,6 @@ BOARD_OBJS = \
 	$(TOPLEVEL)/stm-fmc.o \
 	$(TOPLEVEL)/stm-uart.o \
 	$(TOPLEVEL)/spiflash_n25q128.o \
-	$(TOPLEVEL)/stm-fpgacfg.o \
 	$(TOPLEVEL)/stm-keystore.o \
 	$(TOPLEVEL)/stm-flash.o \
 	$(TOPLEVEL)/syscalls.o \
diff --git a/projects/bootloader/bootloader.c b/projects/bootloader/bootloader.c
index 683a498..c0f981f 100644
--- a/projects/bootloader/bootloader.c
+++ b/projects/bootloader/bootloader.c
@@ -38,7 +38,9 @@
 #include "stm-fmc.h"
 #include "dfu.h"
 
-#undef HAL_Delay
+/* stub these out to avoid linker error */
+void fpgacfg_init(void) { }
+void sdram_init(void) { }
 
 /* Linker symbols are strange in C. Make regular pointers for sanity. */
 __IO uint32_t *dfu_control = &CRYPTECH_DFU_CONTROL;
@@ -91,13 +93,11 @@ int should_dfu()
 /* Sleep for specified number of seconds -- used after bad PIN. */
 void hal_sleep(const unsigned seconds) { HAL_Delay(seconds * 1000); }
 
-int
-main()
+int main(void)
 {
     int status;
 
     stm_init();
-    fmc_init();
 
     uart_send_string2(STM_UART_MGMT, (char *) "\r\n\r\nThis is the bootloader speaking...");
 
diff --git a/projects/cli-test/Makefile b/projects/cli-test/Makefile
index 189a15d..e01b243 100644
--- a/projects/cli-test/Makefile
+++ b/projects/cli-test/Makefile
@@ -14,7 +14,6 @@ OBJS = \
 	test_sdram.o
 
 CFLAGS += -I$(LIBCLI_SRC) -I$(LIBHAL_SRC)
-CFLAGS += -I$(RTOS_DIR)/rtos -I$(RTOS_DIR)/rtx/TARGET_CORTEX_M
 
 LIBS += $(LIBCLI_BLD)/libcli.a $(LIBHAL_BLD)/libhal.a $(LIBTFM_BLD)/libtfm.a
 
diff --git a/projects/cli-test/mgmt-test.c b/projects/cli-test/mgmt-test.c
index 59f0b6e..1a22996 100644
--- a/projects/cli-test/mgmt-test.c
+++ b/projects/cli-test/mgmt-test.c
@@ -50,7 +50,6 @@
 static int cmd_test_sdram(struct cli_def *cli, const char *command, char *argv[], int argc)
 {
     // run external memory initialization sequence
-    HAL_StatusTypeDef status;
     int ok, num_cycles = 1, i, test_completed;
 
     if (argc == 1) {
@@ -59,13 +58,6 @@ static int cmd_test_sdram(struct cli_def *cli, const char *command, char *argv[]
 	if (num_cycles < 1) num_cycles = 1;
     }
 
-    cli_print(cli, "Initializing SDRAM");
-    status = sdram_init();
-    if (status != HAL_OK) {
-	cli_print(cli, "Failed initializing SDRAM: %i", (int) status);
-	return CLI_OK;
-    }
-
     for (i = 1; i <= num_cycles; i++) {
 	cli_print(cli, "Starting SDRAM test (%i/%i)", i, num_cycles);
 	test_completed = 0;
@@ -136,10 +128,6 @@ static int cmd_test_fmc(struct cli_def *cli, const char *command, char *argv[],
 	}
     }
 
-    // prepare fmc interface
-    cli_print(cli, "Initializing FMC interface");
-    fmc_init();
-
     // turn on green led, turn off other leds
     led_on(LED_GREEN);
     led_off(LED_YELLOW);
diff --git a/projects/cli-test/test_sdram.c b/projects/cli-test/test_sdram.c
index e720667..4961b94 100644
--- a/projects/cli-test/test_sdram.c
+++ b/projects/cli-test/test_sdram.c
@@ -31,7 +31,6 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-#include "stm32f4xx_hal.h"
 #include "stm-led.h"
 #include "stm-sdram.h"
 #include "test_sdram.h"
diff --git a/projects/hsm/Makefile b/projects/hsm/Makefile
index 59bad25..927c9f1 100644
--- a/projects/hsm/Makefile
+++ b/projects/hsm/Makefile
@@ -2,13 +2,13 @@ PROJ = hsm
 
 # objs in addition to $(PROJ).o
 OBJS =	mgmt-cli.o \
-	mgmt-firmware.c \
-	mgmt-bootloader.c \
-	mgmt-fpga.c \
-	mgmt-keystore.c \
-	mgmt-masterkey.c \
-	mgmt-misc.c \
-	mgmt-task.c \
+	mgmt-firmware.o \
+	mgmt-bootloader.o \
+	mgmt-fpga.o \
+	mgmt-keystore.o \
+	mgmt-masterkey.o \
+	mgmt-misc.o \
+	mgmt-task.o \
 	log.o
 
 BOARD_OBJS += $(TOPLEVEL)/task.o
diff --git a/projects/hsm/hsm.c b/projects/hsm/hsm.c
index 55c41db..8a8f441 100644
--- a/projects/hsm/hsm.c
+++ b/projects/hsm/hsm.c
@@ -397,11 +397,7 @@ int main(void)
 {
     stm_init();
     uart_set_default(STM_UART_MGMT);
-
     led_on(LED_GREEN);
-    /* Prepare FMC interface. */
-    fmc_init();
-    sdram_init();
 
     if (hal_rpc_server_init() != LIBHAL_OK)
         Error_Handler();
diff --git a/projects/hsm/mgmt-misc.c b/projects/hsm/mgmt-misc.c
index 1861304..ccd032b 100644
--- a/projects/hsm/mgmt-misc.c
+++ b/projects/hsm/mgmt-misc.c
@@ -60,7 +60,7 @@ int cli_receive_data(struct cli_def *cli, uint8_t *buf, size_t len, cli_data_cal
 
     cli_print(cli, "OK, write size (4 bytes), data in %li byte chunks, CRC-32 (4 bytes)", (uint32_t) n);
 
-    if (uart_receive_bytes(STM_UART_MGMT, (void *) &filesize, sizeof(filesize), 1000) != CMSIS_HAL_OK) {
+    if (uart_receive_bytes(STM_UART_MGMT, (void *) &filesize, sizeof(filesize), 2000) != CMSIS_HAL_OK) {
 	cli_print(cli, "Receive timed out");
 	goto fail;
     }
@@ -75,7 +75,7 @@ int cli_receive_data(struct cli_def *cli, uint8_t *buf, size_t len, cli_data_cal
 
 	if (filesize < n) n = filesize;
 
-	if (uart_receive_bytes(STM_UART_MGMT, (void *) buf, n, 1000) != CMSIS_HAL_OK) {
+	if (uart_receive_bytes(STM_UART_MGMT, (void *) buf, n, 2000) != CMSIS_HAL_OK) {
 	    cli_print(cli, "Receive timed out");
 	    goto fail;
 	}
@@ -96,7 +96,7 @@ int cli_receive_data(struct cli_def *cli, uint8_t *buf, size_t len, cli_data_cal
 
     my_crc = hal_crc32_finalize(my_crc);
     cli_print(cli, "Send CRC-32");
-    uart_receive_bytes(STM_UART_MGMT, (void *) &crc, sizeof(crc), 1000);
+    uart_receive_bytes(STM_UART_MGMT, (void *) &crc, sizeof(crc), 2000);
     cli_print(cli, "CRC-32 0x%x, calculated CRC 0x%x", (unsigned int) crc, (unsigned int) my_crc);
     if (crc == my_crc) {
 	cli_print(cli, "CRC checksum MATCHED");
diff --git a/projects/libhal-test/Makefile b/projects/libhal-test/Makefile
index 7aa8d3e..1a2106e 100644
--- a/projects/libhal-test/Makefile
+++ b/projects/libhal-test/Makefile
@@ -17,9 +17,6 @@ vpath %.c $(LIBHAL_SRC)/tests $(LIBHAL_SRC)/utils
 	$(OBJCOPY) -O binary $*.elf $*.bin
 	$(SIZE) $*.elf
 
-# don't automatically delete objects, to avoid a lot of unnecessary rebuilding
-.SECONDARY: $(BOARD_OBJS) $(LIBC_OBJS)
-
 clean:
 	rm -f *.o *.mo
 	rm -f *.elf
diff --git a/projects/libhal-test/main.c b/projects/libhal-test/main.c
index a40871b..fff8c38 100644
--- a/projects/libhal-test/main.c
+++ b/projects/libhal-test/main.c
@@ -43,18 +43,7 @@ extern void __main(void);
 int main(void)
 {
     stm_init();
-
-#ifdef TARGET_CRYPTECH_DEV_BRIDGE
-    // 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);
-#endif
     led_on(LED_GREEN);
-    fmc_init();
 
     __main();
 
diff --git a/projects/rtos-test/Makefile b/projects/rtos-test/Makefile
deleted file mode 100644
index 9e58a41..0000000
--- a/projects/rtos-test/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-TEST = thread-test semaphore-test mutex-test
-
-CFLAGS += -I$(RTOS_DIR)/rtos -I$(RTOS_DIR)/rtx/TARGET_CORTEX_M
-
-LIBS += $(RTOS_DIR)/librtos.a
-
-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/rtos-test/mutex-test.c b/projects/rtos-test/mutex-test.c
deleted file mode 100644
index 402f9ba..0000000
--- a/projects/rtos-test/mutex-test.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "cmsis_os.h"
-
-#include "stm-init.h"
-#include "stm-uart.h"
-
-osMutexId stdio_mutex;
-osMutexDef(stdio_mutex);
-
-void notify(const char* name, int state) {
-    osMutexWait(stdio_mutex, osWaitForever);
-    //printf("%s: %d\n\r", name, state);
-    uart_send_string(name);
-    uart_send_string(": ");
-    uart_send_integer(state, 1);
-    uart_send_string("\r\n");
-    osMutexRelease(stdio_mutex);
-}
-
-void test_thread(void const *args) {
-    while (1) {
-        notify((const char*)args, 0); osDelay(1000);
-        notify((const char*)args, 1); osDelay(1000);
-    }
-}
-
-void t2(void const *argument) {test_thread("Th 2");}
-osThreadDef(t2, osPriorityNormal, DEFAULT_STACK_SIZE);
-
-void t3(void const *argument) {test_thread("Th 3");}
-osThreadDef(t3, osPriorityNormal, DEFAULT_STACK_SIZE);
-
-int main() {
-    stm_init();
-    stdio_mutex = osMutexCreate(osMutex(stdio_mutex));
-
-    osThreadCreate(osThread(t2), NULL);
-    osThreadCreate(osThread(t3), NULL);
-
-    test_thread((void *)"Th 1");
-}
diff --git a/projects/rtos-test/semaphore-test.c b/projects/rtos-test/semaphore-test.c
deleted file mode 100644
index 3a3b5de..0000000
--- a/projects/rtos-test/semaphore-test.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "cmsis_os.h"
-
-#include "stm-init.h"
-#include "stm-uart.h"
-
-osSemaphoreId two_slots;
-osSemaphoreDef(two_slots);
-
-void test_thread(void const *name) {
-    while (1) {
-        osSemaphoreWait(two_slots, osWaitForever);
-        //printf("%s\n\r", (const char*)name);
-        uart_send_string((const char*)name);
-        uart_send_string("\r\n");
-        osDelay(1000);
-        osSemaphoreRelease(two_slots);
-    }
-}
-
-void t2(void const *argument) {test_thread("Th 2");}
-osThreadDef(t2, osPriorityNormal, DEFAULT_STACK_SIZE);
-
-void t3(void const *argument) {test_thread("Th 3");}
-osThreadDef(t3, osPriorityNormal, DEFAULT_STACK_SIZE);
-
-int main (void) {
-    stm_init();
-    two_slots = osSemaphoreCreate(osSemaphore(two_slots), 2);
-
-    osThreadCreate(osThread(t2), NULL);
-    osThreadCreate(osThread(t3), NULL);
-
-    test_thread((void *)"Th 1");
-}
diff --git a/projects/rtos-test/thread-test.c b/projects/rtos-test/thread-test.c
deleted file mode 100644
index 8b31a26..0000000
--- a/projects/rtos-test/thread-test.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include "cmsis_os.h"
-
-#include "stm-init.h"
-#include "stm-led.h"
-
-void led2_thread(void const *args)
-{
-    while (1) {
-        led_toggle(LED_BLUE);
-        osDelay(1000);
-    }
-}
-osThreadDef(led2_thread, osPriorityNormal, DEFAULT_STACK_SIZE);
-
-int main()
-{
-    stm_init();
-    osThreadCreate(osThread(led2_thread), NULL);
-    
-    while (1) {
-        led_toggle(LED_GREEN);
-        osDelay(500);
-    }
-}
diff --git a/stm-flash.c b/stm-flash.c
index 4456f44..99e09ee 100644
--- a/stm-flash.c
+++ b/stm-flash.c
@@ -33,9 +33,8 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "stm32f4xx_hal.h"
-#include "stm-flash.h"
 #include "stm-init.h"
+#include "stm-flash.h"
 
 
 /* Flash sector offsets from RM0090, Table 6. Flash module - 2 Mbyte dual bank organization */
diff --git a/stm-fmc.c b/stm-fmc.c
index 05d41b4..b202353 100644
--- a/stm-fmc.c
+++ b/stm-fmc.c
@@ -31,110 +31,20 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-#include "stm32f4xx_hal.h"
 #include "stm-init.h"
 #include "stm-fmc.h"
 
 
 static SRAM_HandleTypeDef _fmc_fpga_inst;
 
-static HAL_StatusTypeDef _fmc_init_params(void);
-
-HAL_StatusTypeDef fmc_init(void)
+void fmc_init(void)
 {
     static int initialized = 0;
-
-    if (initialized) {
-	return HAL_OK;
-    }
+    if (initialized) return;
     initialized = 1;
 
     // configure fmc pins
-    fmc_init_gpio();
-
-    // configure fmc registers
-    return _fmc_init_params();
-}
-
-
-static int _fmc_nwait_idle(void)
-{
-    int cnt;
-
-    // poll NWAIT (number of iterations is limited)
-    for (cnt=0; cnt<FMC_FPGA_NWAIT_MAX_POLL_TICKS; cnt++)
-    {
-        // read pin state
-        if (HAL_GPIO_ReadPin(FMC_GPIO_PORT_NWAIT, FMC_GPIO_PIN_NWAIT) == FMC_NWAIT_IDLE)
-            return 0;
-    }
-
-    return -1;
-}
-
-int fmc_write_32(uint32_t addr, uint32_t *data)
-{
-    // calculate target fpga address
-    uint32_t ptr = FMC_FPGA_BASE_ADDR + (addr & FMC_FPGA_ADDR_MASK);
-
-    __disable_irq();
-
-    int status =
-        // write data to fpga
-        (HAL_SRAM_Write_32b(&_fmc_fpga_inst, (uint32_t *)ptr, data, 1) != HAL_OK) ||
-        // wait for transaction to complete
-        _fmc_nwait_idle();
-
-    __enable_irq();
-
-    return status;
-}
-
-static inline int _fmc_read_32(uint32_t *ptr, uint32_t *data)
-{
-    return
-        // read data from fpga
-        (HAL_SRAM_Read_32b(&_fmc_fpga_inst, (uint32_t *)ptr, data, 1) != HAL_OK) ||
-        // wait for transaction to complete
-        _fmc_nwait_idle();
-
-}
-
-int fmc_read_32(uint32_t addr, uint32_t *data)
-{
-    // calculate target fpga address
-    uint32_t ptr = FMC_FPGA_BASE_ADDR + (addr & FMC_FPGA_ADDR_MASK);
-
-    /* Pavel says:
-     * The short story is like, on one hand STM32 has a dedicated FMC_NWAIT
-     * pin, that can be used in variable-latency data transfer mode. On the
-     * other hand STM32 also has a very nasty hardware bug associated with
-     * FMC_WAIT, that causes processor to freeze under certain conditions.
-     * Because of this FMC_NWAIT cannot be used and FPGA can't properly signal
-     * to STM32, when data transfer is done. Because of that we have to read
-     * two times.
-     */
-
-    /* Add some level of reentrancy protection. When running under a
-     * preemptive multitasker, with two threads banging on the fpga, we appear
-     * to sometimes read the wrong value. I think this is because the second
-     * read counts on the first read to put the correct value on the address
-     * bus.
-     */
-    __disable_irq();
-
-    int status =
-        _fmc_read_32((uint32_t *)ptr, data) ||
-        _fmc_read_32((uint32_t *)ptr, data);
-
-    __enable_irq();
-
-    return status;
-}
 
-
-void fmc_init_gpio(void)
-{
     GPIO_InitTypeDef GPIO_InitStruct;
 
     // enable fmc clock
@@ -168,11 +78,9 @@ void fmc_init_gpio(void)
 		| GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
     fmc_af_gpio(GPIOI, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3
 		| GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_9 | GPIO_PIN_10);
-}
 
+    // configure fmc registers
 
-static HAL_StatusTypeDef _fmc_init_params(void)
-{
     /*
      * fill internal fields
      */
@@ -254,5 +162,81 @@ static HAL_StatusTypeDef _fmc_init_params(void)
     fmc_timing.AccessMode = FMC_ACCESS_MODE_A;
 
     // initialize fmc
-    return HAL_SRAM_Init(&_fmc_fpga_inst, &fmc_timing, NULL);
+    HAL_SRAM_Init(&_fmc_fpga_inst, &fmc_timing, NULL);
+}
+
+
+static int _fmc_nwait_idle(void)
+{
+    int cnt;
+
+    // poll NWAIT (number of iterations is limited)
+    for (cnt=0; cnt<FMC_FPGA_NWAIT_MAX_POLL_TICKS; cnt++)
+    {
+        // read pin state
+        if (HAL_GPIO_ReadPin(FMC_GPIO_PORT_NWAIT, FMC_GPIO_PIN_NWAIT) == FMC_NWAIT_IDLE)
+            return 0;
+    }
+
+    return -1;
+}
+
+int fmc_write_32(uint32_t addr, uint32_t *data)
+{
+    // calculate target fpga address
+    uint32_t ptr = FMC_FPGA_BASE_ADDR + (addr & FMC_FPGA_ADDR_MASK);
+
+    __disable_irq();
+
+    int status =
+        // write data to fpga
+        (HAL_SRAM_Write_32b(&_fmc_fpga_inst, (uint32_t *)ptr, data, 1) != HAL_OK) ||
+        // wait for transaction to complete
+        _fmc_nwait_idle();
+
+    __enable_irq();
+
+    return status;
+}
+
+static inline int _fmc_read_32(uint32_t *ptr, uint32_t *data)
+{
+    return
+        // read data from fpga
+        (HAL_SRAM_Read_32b(&_fmc_fpga_inst, (uint32_t *)ptr, data, 1) != HAL_OK) ||
+        // wait for transaction to complete
+        _fmc_nwait_idle();
+
+}
+
+int fmc_read_32(uint32_t addr, uint32_t *data)
+{
+    // calculate target fpga address
+    uint32_t ptr = FMC_FPGA_BASE_ADDR + (addr & FMC_FPGA_ADDR_MASK);
+
+    /* Pavel says:
+     * The short story is like, on one hand STM32 has a dedicated FMC_NWAIT
+     * pin, that can be used in variable-latency data transfer mode. On the
+     * other hand STM32 also has a very nasty hardware bug associated with
+     * FMC_WAIT, that causes processor to freeze under certain conditions.
+     * Because of this FMC_NWAIT cannot be used and FPGA can't properly signal
+     * to STM32, when data transfer is done. Because of that we have to read
+     * two times.
+     */
+
+    /* Add some level of reentrancy protection. When running under a
+     * preemptive multitasker, with two threads banging on the fpga, we appear
+     * to sometimes read the wrong value. I think this is because the second
+     * read counts on the first read to put the correct value on the address
+     * bus.
+     */
+    __disable_irq();
+
+    int status =
+        _fmc_read_32((uint32_t *)ptr, data) ||
+        _fmc_read_32((uint32_t *)ptr, data);
+
+    __enable_irq();
+
+    return status;
 }
diff --git a/stm-fmc.h b/stm-fmc.h
index 8c37bd7..722c478 100644
--- a/stm-fmc.h
+++ b/stm-fmc.h
@@ -56,9 +56,7 @@
     HAL_GPIO_Init(port, &GPIO_InitStruct)
 
 
-extern HAL_StatusTypeDef fmc_init(void);
-extern void fmc_init_gpio(void);
-
+extern void fmc_init(void);
 extern int fmc_write_32(uint32_t addr, uint32_t *data);
 extern int fmc_read_32(uint32_t addr, uint32_t *data);
 
diff --git a/stm-fpgacfg.c b/stm-fpgacfg.c
index 10abc57..b2f09d0 100644
--- a/stm-fpgacfg.c
+++ b/stm-fpgacfg.c
@@ -33,15 +33,42 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "stm32f4xx_hal.h"
 #include "stm-fpgacfg.h"
 #include "stm-init.h"
 
-SPI_HandleTypeDef hspi_fpgacfg;
+static SPI_HandleTypeDef hspi_fpgacfg;
 
-struct spiflash_ctx fpgacfg_ctx = {&hspi_fpgacfg, PROM_CS_N_GPIO_Port, PROM_CS_N_Pin};
+static struct spiflash_ctx fpgacfg_ctx = {&hspi_fpgacfg, PROM_CS_N_GPIO_Port, PROM_CS_N_Pin};
 
-int fpgacfg_check_id()
+void fpgacfg_init(void)
+{
+    /* Give the FPGA access to it's bitstream ASAP (maybe this should actually
+     * be done in the application, before calling stm_init()).
+     */
+    fpgacfg_access_control(ALLOW_FPGA);
+
+    /* Set up GPIOs to manage access to the FPGA config memory.
+     * FPGACFG_GPIO_INIT is defined in stm-fpgacfg.h.
+     */
+    FPGACFG_GPIO_INIT();
+
+    /* SPI2 (FPGA config memory) init function */
+    hspi_fpgacfg.Instance = SPI2;
+    hspi_fpgacfg.Init.Mode = SPI_MODE_MASTER;
+    hspi_fpgacfg.Init.Direction = SPI_DIRECTION_2LINES;
+    hspi_fpgacfg.Init.DataSize = SPI_DATASIZE_8BIT;
+    hspi_fpgacfg.Init.CLKPolarity = SPI_POLARITY_LOW;
+    hspi_fpgacfg.Init.CLKPhase = SPI_PHASE_1EDGE;
+    hspi_fpgacfg.Init.NSS = SPI_NSS_SOFT;
+    hspi_fpgacfg.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
+    hspi_fpgacfg.Init.FirstBit = SPI_FIRSTBIT_MSB;
+    hspi_fpgacfg.Init.TIMode = SPI_TIMODE_DISABLE;
+    hspi_fpgacfg.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
+    hspi_fpgacfg.Init.CRCPolynomial = 10;
+    HAL_SPI_Init(&hspi_fpgacfg);
+}
+
+int fpgacfg_check_id(void)
 {
     return n25q128_check_id(&fpgacfg_ctx);
 }
diff --git a/stm-fpgacfg.h b/stm-fpgacfg.h
index 9baebc4..b31dee3 100644
--- a/stm-fpgacfg.h
+++ b/stm-fpgacfg.h
@@ -85,8 +85,7 @@ enum fpgacfg_reset {
     RESET_REGISTERS,
 };
 
-extern SPI_HandleTypeDef hspi_fpgacfg;
-
+extern void fpgacfg_init(void);
 extern int fpgacfg_check_id(void);
 extern int fpgacfg_write_data(uint32_t offset, const uint8_t *buf, const uint32_t len);
 extern int fpgacfg_erase_sector(uint32_t sector_offset);
diff --git a/stm-init.c b/stm-init.c
index 51b2ae7..d36bdff 100644
--- a/stm-init.c
+++ b/stm-init.c
@@ -33,7 +33,6 @@
   */
 
 /* Includes ------------------------------------------------------------------*/
-#include "stm32f4xx_hal.h"
 #include "stm-init.h"
 #ifdef HAL_GPIO_MODULE_ENABLED
 #include "stm-led.h"
@@ -48,6 +47,12 @@
 #include "stm-fpgacfg.h"
 #include "stm-keystore.h"
 #endif
+#ifdef HAL_SRAM_MODULE_ENABLED
+#include "stm-fmc.h"
+#endif
+#ifdef HAL_SDRAM_MODULE_ENABLED
+#include "stm-sdram.h"
+#endif
 
 /* Private variables ---------------------------------------------------------*/
 
@@ -55,20 +60,6 @@
 #ifdef HAL_GPIO_MODULE_ENABLED
 static void MX_GPIO_Init(void);
 #endif
-#ifdef HAL_UART_MODULE_ENABLED
-static void MX_USART1_UART_Init(void);
-static void MX_USART2_UART_Init(void);
-#endif
-#ifdef HAL_DMA_MODULE_ENABLED
-static void MX_DMA_Init(void);
-#endif
-#ifdef HAL_I2C_MODULE_ENABLED
-static void MX_I2C2_Init(void);
-#endif
-#ifdef HAL_SPI_MODULE_ENABLED
-static void MX_SPI1_Init(void);
-static void MX_SPI2_Init(void);
-#endif
 
 void stm_init(void)
 {
@@ -82,74 +73,34 @@ void stm_init(void)
   /* Initialize all configured peripherals */
 #ifdef HAL_GPIO_MODULE_ENABLED
   MX_GPIO_Init();
-  #ifdef HAL_SPI_MODULE_ENABLED
-  /* Give the FPGA access to it's bitstream ASAP (maybe this should actually
-   * be done in the application, before calling stm_init()).
-   */
-  fpgacfg_access_control(ALLOW_FPGA);
-  #endif
-#endif
-#ifdef HAL_DMA_MODULE_ENABLED
-  MX_DMA_Init();
 #endif
 #ifdef HAL_UART_MODULE_ENABLED
-  MX_USART1_UART_Init();
-  MX_USART2_UART_Init();
+  uart_init();
 #endif
 #ifdef HAL_I2C_MODULE_ENABLED
-  MX_I2C2_Init();
+  rtc_init();
 #endif
 #ifdef HAL_SPI_MODULE_ENABLED
-  MX_SPI1_Init();
-  MX_SPI2_Init();
+  fpgacfg_init();
+  keystore_init();
+#endif
+#ifdef TARGET_CRYPTECH_DEV_BRIDGE
+  // 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);
 #endif
-}
-
-
-#ifdef HAL_UART_MODULE_ENABLED
-/* USART1 init function */
-static void MX_USART1_UART_Init(void)
-{
-  huart_mgmt.Instance = USART1;
-  huart_mgmt.Init.BaudRate = USART_MGMT_BAUD_RATE;
-  huart_mgmt.Init.WordLength = UART_WORDLENGTH_8B;
-  huart_mgmt.Init.StopBits = UART_STOPBITS_1;
-  huart_mgmt.Init.Parity = UART_PARITY_NONE;
-  huart_mgmt.Init.Mode = UART_MODE_TX_RX;
-  huart_mgmt.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS;
-  huart_mgmt.Init.OverSampling = UART_OVERSAMPLING_16;
-
-#ifdef HAL_DMA_MODULE_ENABLED
-  __HAL_LINKDMA(&huart_mgmt, hdmarx, hdma_usart_mgmt_rx);
+#ifdef HAL_SRAM_MODULE_ENABLED
+  fmc_init();
 #endif
-
-  if (HAL_UART_Init(&huart_mgmt) != HAL_OK) {
-    /* Initialization Error */
-    Error_Handler();
-  }
-}
-/* USART2 init function */
-static void MX_USART2_UART_Init(void)
-{
-  huart_user.Instance = USART2;
-  huart_user.Init.BaudRate = USART_USER_BAUD_RATE;
-  huart_user.Init.WordLength = UART_WORDLENGTH_8B;
-  huart_user.Init.StopBits = UART_STOPBITS_1;
-  huart_user.Init.Parity = UART_PARITY_NONE;
-  huart_user.Init.Mode = UART_MODE_TX_RX;
-  huart_user.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS;
-  huart_user.Init.OverSampling = UART_OVERSAMPLING_16;
-
-#ifdef HAL_DMA_MODULE_ENABLED
-  __HAL_LINKDMA(&huart_user, hdmarx, hdma_usart_user_rx);
+#ifdef HAL_SDRAM_MODULE_ENABLED
+  sdram_init();
 #endif
-
-  if (HAL_UART_Init(&huart_user) != HAL_OK) {
-    /* Initialization Error */
-    Error_Handler();
-  }
 }
-#endif
+
 
 #ifdef HAL_GPIO_MODULE_ENABLED
 
@@ -161,101 +112,13 @@ static void MX_GPIO_Init(void)
 
   /* Configure LED GPIO pins */
   gpio_output(LED_PORT, LED_RED | LED_YELLOW | LED_GREEN | LED_BLUE, GPIO_PIN_RESET);
-
-#ifdef HAL_SPI_MODULE_ENABLED
-  /* Set up GPIOs to manage access to the FPGA config memory.
-   * FPGACFG_GPIO_INIT is defined in stm-fpgacfg.h.
-   */
-  FPGACFG_GPIO_INIT();
-  /* Set up GPIOs for the keystore memory.
-   * KEYSTORE_GPIO_INIT is defined in stm-keystore.h.
-   */
-  KEYSTORE_GPIO_INIT();
-#endif /* HAL_SPI_MODULE_ENABLED */
 }
-#undef gpio_output
 #endif
 
-
-#ifdef HAL_DMA_MODULE_ENABLED
-/**
- * Enable DMA controller clock
- */
-static void MX_DMA_Init(void)
-{
-    /* DMA controller clock enable */
-    __HAL_RCC_DMA2_CLK_ENABLE();
-    __HAL_RCC_DMA1_CLK_ENABLE();
-
-    /* DMA interrupt init */
-
-    /* USER UART RX */
-    HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
-    HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
-    /* MGMT UART RX */
-    HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
-    HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
-}
-#endif /* HAL_DMA_MODULE_ENABLED */
-
-
-#ifdef HAL_I2C_MODULE_ENABLED
-/* I2C2 init function (external RTC chip) */
-void MX_I2C2_Init(void)
-{
-    hi2c_rtc.Instance = I2C2;
-    hi2c_rtc.Init.ClockSpeed = 10000;
-    hi2c_rtc.Init.DutyCycle = I2C_DUTYCYCLE_2;
-    hi2c_rtc.Init.OwnAddress1 = 0;  /* Will operate as Master */
-    hi2c_rtc.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
-    hi2c_rtc.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
-    hi2c_rtc.Init.OwnAddress2 = 0;
-    hi2c_rtc.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
-    hi2c_rtc.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
-
-    if (HAL_I2C_Init(&hi2c_rtc) != HAL_OK) {
-        Error_Handler();
-    }
-}
+#ifdef CMSIS_RTOS
+#include "cmsis_os.h"
 #endif
 
-#ifdef HAL_SPI_MODULE_ENABLED
-/* SPI1 (keystore memory) init function */
-void MX_SPI1_Init(void)
-{
-    hspi_keystore.Instance = SPI1;
-    hspi_keystore.Init.Mode = SPI_MODE_MASTER;
-    hspi_keystore.Init.Direction = SPI_DIRECTION_2LINES;
-    hspi_keystore.Init.DataSize = SPI_DATASIZE_8BIT;
-    hspi_keystore.Init.CLKPolarity = SPI_POLARITY_LOW;
-    hspi_keystore.Init.CLKPhase = SPI_PHASE_1EDGE;
-    hspi_keystore.Init.NSS = SPI_NSS_SOFT;
-    hspi_keystore.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
-    hspi_keystore.Init.FirstBit = SPI_FIRSTBIT_MSB;
-    hspi_keystore.Init.TIMode = SPI_TIMODE_DISABLE;
-    hspi_keystore.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
-    hspi_keystore.Init.CRCPolynomial = 10;
-    HAL_SPI_Init(&hspi_keystore);
-}
-/* SPI2 (FPGA config memory) init function */
-void MX_SPI2_Init(void)
-{
-    hspi_fpgacfg.Instance = SPI2;
-    hspi_fpgacfg.Init.Mode = SPI_MODE_MASTER;
-    hspi_fpgacfg.Init.Direction = SPI_DIRECTION_2LINES;
-    hspi_fpgacfg.Init.DataSize = SPI_DATASIZE_8BIT;
-    hspi_fpgacfg.Init.CLKPolarity = SPI_POLARITY_LOW;
-    hspi_fpgacfg.Init.CLKPhase = SPI_PHASE_1EDGE;
-    hspi_fpgacfg.Init.NSS = SPI_NSS_SOFT;
-    hspi_fpgacfg.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
-    hspi_fpgacfg.Init.FirstBit = SPI_FIRSTBIT_MSB;
-    hspi_fpgacfg.Init.TIMode = SPI_TIMODE_DISABLE;
-    hspi_fpgacfg.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
-    hspi_fpgacfg.Init.CRCPolynomial = 10;
-    HAL_SPI_Init(&hspi_fpgacfg);
-}
-#endif /* HAL_SPI_MODULE_ENABLED */
-
 /**
  * @brief  This function is executed in case of error occurrence.
  * @param  None
@@ -266,29 +129,14 @@ void Error_Handler(void)
 #ifdef HAL_GPIO_MODULE_ENABLED
   HAL_GPIO_WritePin(LED_PORT, LED_RED, GPIO_PIN_SET);
 #endif
-  while (1) { ; }
-}
-
-#ifdef USE_FULL_ASSERT
-
-/**
-   * @brief Reports the name of the source file and the source line number
-   * where the assert_param error has occurred.
-   * @param file: pointer to the source file name
-   * @param line: assert_param error line source number
-   * @retval None
-   */
-void assert_failed(uint8_t* file, uint32_t line)
-{
-  /* USER CODE BEGIN 6 */
-  /* User can add his own implementation to report the file name and line number,
-    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
-  /* USER CODE END 6 */
+#ifdef CMSIS_RTOS
+  //osThreadSetPriority(osThreadGetId(), osPriorityIdle);
+  osThreadTerminate(osThreadGetId());
+#endif
 
+  while (1) { ; }
 }
 
-#endif
-
 /**
   * @}
   */
diff --git a/stm-keystore.c b/stm-keystore.c
index b941489..6bec008 100644
--- a/stm-keystore.c
+++ b/stm-keystore.c
@@ -32,14 +32,36 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "stm32f4xx_hal.h"
-#include "stm-keystore.h"
 #include "stm-init.h"
+#include "stm-keystore.h"
 
-SPI_HandleTypeDef hspi_keystore;
+static SPI_HandleTypeDef hspi_keystore;
 
 struct spiflash_ctx keystore_ctx = {&hspi_keystore, KSM_PROM_CS_N_GPIO_Port, KSM_PROM_CS_N_Pin};
 
+/* SPI1 (keystore memory) init function */
+void keystore_init(void)
+{
+    /* Set up GPIOs for the keystore memory.
+     * KEYSTORE_GPIO_INIT is defined in stm-keystore.h.
+     */
+    KEYSTORE_GPIO_INIT();
+
+    hspi_keystore.Instance = SPI1;
+    hspi_keystore.Init.Mode = SPI_MODE_MASTER;
+    hspi_keystore.Init.Direction = SPI_DIRECTION_2LINES;
+    hspi_keystore.Init.DataSize = SPI_DATASIZE_8BIT;
+    hspi_keystore.Init.CLKPolarity = SPI_POLARITY_LOW;
+    hspi_keystore.Init.CLKPhase = SPI_PHASE_1EDGE;
+    hspi_keystore.Init.NSS = SPI_NSS_SOFT;
+    hspi_keystore.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
+    hspi_keystore.Init.FirstBit = SPI_FIRSTBIT_MSB;
+    hspi_keystore.Init.TIMode = SPI_TIMODE_DISABLE;
+    hspi_keystore.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
+    hspi_keystore.Init.CRCPolynomial = 10;
+    HAL_SPI_Init(&hspi_keystore);
+}
+
 int keystore_check_id(void)
 {
     return n25q128_check_id(&keystore_ctx);
diff --git a/stm-keystore.h b/stm-keystore.h
index 419e12e..f660790 100644
--- a/stm-keystore.h
+++ b/stm-keystore.h
@@ -55,8 +55,7 @@
     gpio_output(KSM_PROM_CS_N_GPIO_Port, KSM_PROM_CS_N_Pin, GPIO_PIN_SET)
 
 
-extern SPI_HandleTypeDef hspi_keystore;
-
+extern void keystore_init(void);
 extern int keystore_check_id(void);
 extern int keystore_read_data(uint32_t offset, uint8_t *buf, const uint32_t len);
 extern int keystore_write_data(uint32_t offset, const uint8_t *buf, const uint32_t len);
diff --git a/stm-rtc.c b/stm-rtc.c
index 66e41e8..3118d23 100644
--- a/stm-rtc.c
+++ b/stm-rtc.c
@@ -32,11 +32,29 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "stm32f4xx_hal.h"
+#include "stm-init.h"
 #include "stm-rtc.h"
 
 I2C_HandleTypeDef hi2c_rtc;
 
+/* I2C2 init function (external RTC chip) */
+void rtc_init(void)
+{
+    hi2c_rtc.Instance = I2C2;
+    hi2c_rtc.Init.ClockSpeed = 10000;
+    hi2c_rtc.Init.DutyCycle = I2C_DUTYCYCLE_2;
+    hi2c_rtc.Init.OwnAddress1 = 0;  /* Will operate as Master */
+    hi2c_rtc.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
+    hi2c_rtc.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
+    hi2c_rtc.Init.OwnAddress2 = 0;
+    hi2c_rtc.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
+    hi2c_rtc.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
+
+    if (HAL_I2C_Init(&hi2c_rtc) != HAL_OK) {
+        Error_Handler();
+    }
+}
+
 HAL_StatusTypeDef rtc_device_ready(uint16_t i2c_addr)
 {
     return HAL_I2C_IsDeviceReady (&hi2c_rtc, i2c_addr, 10, 1000);
diff --git a/stm-rtc.h b/stm-rtc.h
index edbed9d..794ef2d 100644
--- a/stm-rtc.h
+++ b/stm-rtc.h
@@ -37,8 +37,7 @@
 
 #include "stm32f4xx_hal.h"
 
-extern I2C_HandleTypeDef hi2c_rtc;
-
+extern void rtc_init(void);
 extern HAL_StatusTypeDef rtc_device_ready(uint16_t i2c_addr);
 extern HAL_StatusTypeDef rtc_enable_oscillator();
 extern HAL_StatusTypeDef rtc_send_byte(const uint16_t i2c_addr, const uint8_t value, const uint16_t timeout);
diff --git a/stm-sdram.c b/stm-sdram.c
index 58773e9..3ad17f0 100644
--- a/stm-sdram.c
+++ b/stm-sdram.c
@@ -1,284 +1,216 @@
-/*
- * stm-sdram.c
- * -----------
- * Functions concerning the 2x512 Mbit SDRAM working memory.
- *
- * Copyright (c) 2016, NORDUnet A/S All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * - Redistributions of source code must retain the above copyright notice,
- *   this list of conditions and the following disclaimer.
- *
- * - 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.
- *
- * - Neither the name of the NORDUnet 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
- * HOLDER 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.
- */
-#include "stm32f4xx_hal.h"
-#include "stm-init.h"
-#include "stm-sdram.h"
-#include "stm-fmc.h"
-#include "stm-led.h"
-
-/* Mode Register Bits */
-#define SDRAM_MODEREG_BURST_LENGTH_1             ((uint16_t)0x0000)
-#define SDRAM_MODEREG_BURST_LENGTH_2             ((uint16_t)0x0001)
-#define SDRAM_MODEREG_BURST_LENGTH_4             ((uint16_t)0x0002)
-#define SDRAM_MODEREG_BURST_LENGTH_8             ((uint16_t)0x0004)
-
-#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL      ((uint16_t)0x0000)
-#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED     ((uint16_t)0x0008)
-
-#define SDRAM_MODEREG_CAS_LATENCY_2              ((uint16_t)0x0020)
-#define SDRAM_MODEREG_CAS_LATENCY_3              ((uint16_t)0x0030)
-
-#define SDRAM_MODEREG_OPERATING_MODE_STANDARD    ((uint16_t)0x0000)
-
-#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
-#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE     ((uint16_t)0x0200)
-
-SDRAM_HandleTypeDef hsdram1;
-SDRAM_HandleTypeDef hsdram2;
-
-static void _sdram_init_gpio(void);
-static HAL_StatusTypeDef _sdram_init_fmc(void);
-static HAL_StatusTypeDef _sdram_init_params(SDRAM_HandleTypeDef *sdram1, SDRAM_HandleTypeDef *sdram2);
-
-
-HAL_StatusTypeDef sdram_init(void)
-{
-    HAL_StatusTypeDef status;
-    static int initialized = 0;
-
-    if (initialized) {
-	return HAL_OK;
-    }
-    initialized = 1;
-
-    /* We rely on several things being set up by fmc_init() instead of duplicating all
-     * that code here for independent FPGA/SDRAM FMC setup. This means the FPGA<->STM32
-     * FMC bus can be used without the SDRAMs initialized, but the SDRAMs can't be
-     * initialized withouth the FPGA<->STM32 FMC bus being set up too.
-     */
-    fmc_init();
-
-    // configure FMC
-    _sdram_init_gpio();
-    status = _sdram_init_fmc();
-    if (status != HAL_OK) return status;
-
-    // configure SDRAM registers
-    status = _sdram_init_params(&hsdram1, &hsdram2);
-    if (status != HAL_OK) return status;
-
-    return HAL_OK;
-}
-
-static void _sdram_init_gpio(void)
-{
-    GPIO_InitTypeDef GPIO_InitStruct;
-
-    /* The bulk of the FMC GPIO pins are set up in fmc_init_gpio().
-     * This function just needs to enable the additional ones used
-     * with the SDRAMs.
-     */
-    fmc_af_gpio(GPIOB, GPIO_PIN_5 | GPIO_PIN_6);
-    fmc_af_gpio(GPIOC, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3);
-    fmc_af_gpio(GPIOE, GPIO_PIN_0 | GPIO_PIN_1);
-    fmc_af_gpio(GPIOF, GPIO_PIN_11);
-    fmc_af_gpio(GPIOG, GPIO_PIN_8 | GPIO_PIN_15);
-    fmc_af_gpio(GPIOI, GPIO_PIN_4 | GPIO_PIN_5);
-}
-
-static HAL_StatusTypeDef _sdram_init_fmc()
-{
-    HAL_StatusTypeDef status;
-    FMC_SDRAM_TimingTypeDef SdramTiming;
-
-    /*
-     * following settings are for -75E speed grade memory chip
-     * clocked at only 90 MHz instead of the rated 133 MHz
-     *
-     * ExitSelfRefreshDelay: 67 ns @ 90 MHz is 6.03 cycles, so in theory
-     *                       6 can be used here, but let's be on the safe side
-     *
-     * WriteRecoveryTime:    must be >= tRAS - tRCD (5 - 2 = 3 cycles),
-     *                       and >= tRC - tRCD - tRP (8 - 2 - 2 = 4 cycles)
-     */
-    SdramTiming.LoadToActiveDelay	= 2;	// tMRD
-    SdramTiming.ExitSelfRefreshDelay	= 7;    // (see above)
-    SdramTiming.SelfRefreshTime		= 5;	// should be >= tRAS (5 cycles)
-    SdramTiming.RowCycleDelay		= 8;	// tRC
-    SdramTiming.WriteRecoveryTime	= 4;	// (see above)
-    SdramTiming.RPDelay			= 2;	// tRP
-    SdramTiming.RCDDelay		= 2;	// tRCD
-
-    /*
-     * configure the first bank
-     */
-
-    // memory type
-    hsdram1.Instance = FMC_SDRAM_DEVICE;
-
-    // bank
-    hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
-
-    // settings for IS42S32160F
-    hsdram1.Init.ColumnBitsNumber	= FMC_SDRAM_COLUMN_BITS_NUM_9;
-    hsdram1.Init.RowBitsNumber		= FMC_SDRAM_ROW_BITS_NUM_13;
-    hsdram1.Init.MemoryDataWidth	= FMC_SDRAM_MEM_BUS_WIDTH_32;
-    hsdram1.Init.InternalBankNumber	= FMC_SDRAM_INTERN_BANKS_NUM_4;
-    hsdram1.Init.CASLatency		= FMC_SDRAM_CAS_LATENCY_2;
-
-    // write protection not needed
-    hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
-
-    // memory clock is 90 MHz (HCLK / 2)
-    hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
-
-    // read burst not needed
-    hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
-
-    // additional pipeline stages not neeed
-    hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
-
-    // call HAL layer
-    status = HAL_SDRAM_Init(&hsdram1, &SdramTiming);
-    if (status != HAL_OK) return status;
-
-    /*
-     * configure the second bank
-     */
-
-    // memory type
-    hsdram2.Instance = FMC_SDRAM_DEVICE;
-
-    // bank number
-    hsdram2.Init.SDBank = FMC_SDRAM_BANK2;
-
-    // settings for IS42S32160F
-    hsdram2.Init.ColumnBitsNumber	= FMC_SDRAM_COLUMN_BITS_NUM_9;
-    hsdram2.Init.RowBitsNumber		= FMC_SDRAM_ROW_BITS_NUM_13;
-    hsdram2.Init.MemoryDataWidth	= FMC_SDRAM_MEM_BUS_WIDTH_32;
-    hsdram2.Init.InternalBankNumber	= FMC_SDRAM_INTERN_BANKS_NUM_4;
-    hsdram2.Init.CASLatency		= FMC_SDRAM_CAS_LATENCY_2;
-
-    // write protection not needed
-    hsdram2.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
-
-    // memory clock is 90 MHz (HCLK / 2)
-    hsdram2.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
-
-    // read burst not needed
-    hsdram2.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
-
-    // additional pipeline stages not neeed
-    hsdram2.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
-
-    // call HAL layer
-    return HAL_SDRAM_Init(&hsdram2, &SdramTiming);
-}
-
-static HAL_StatusTypeDef _sdram_init_params(SDRAM_HandleTypeDef *sdram1, SDRAM_HandleTypeDef *sdram2)
-{
-    HAL_StatusTypeDef ok;			// status
-    FMC_SDRAM_CommandTypeDef cmd;		// command
-
-    /*
-     * enable clocking
-     */
-    cmd.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
-    cmd.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1_2;
-    cmd.AutoRefreshNumber = 1;
-    cmd.ModeRegisterDefinition = 0;
-
-    HAL_Delay(1);
-    ok = HAL_SDRAM_SendCommand(sdram1, &cmd, 1);
-    if (ok != HAL_OK) return ok;
-
-    /*
-     * precharge all banks
-     */
-    cmd.CommandMode = FMC_SDRAM_CMD_PALL;
-    cmd.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1_2;
-    cmd.AutoRefreshNumber = 1;
-    cmd.ModeRegisterDefinition = 0;
-
-    HAL_Delay(1);
-    ok = HAL_SDRAM_SendCommand(sdram1, &cmd, 1);
-    if (ok != HAL_OK) return ok;
-
-
-    /*
-     * send two auto-refresh commands in a row
-     */
-    cmd.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
-    cmd.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1_2;
-    cmd.AutoRefreshNumber = 1;
-    cmd.ModeRegisterDefinition = 0;
-
-    ok = HAL_SDRAM_SendCommand(sdram1, &cmd, 1);
-    if (ok != HAL_OK) return ok;
-
-    ok = HAL_SDRAM_SendCommand(sdram1, &cmd, 1);
-    if (ok != HAL_OK) return ok;
-
-
-    /*
-     * load mode register
-     */
-    cmd.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
-    cmd.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1_2;
-    cmd.AutoRefreshNumber = 1;
-    cmd.ModeRegisterDefinition =
-	SDRAM_MODEREG_BURST_LENGTH_1		|
-	SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL	|
-	SDRAM_MODEREG_CAS_LATENCY_2		|
-	SDRAM_MODEREG_OPERATING_MODE_STANDARD	|
-	SDRAM_MODEREG_WRITEBURST_MODE_SINGLE	;
-
-    ok = HAL_SDRAM_SendCommand(sdram1, &cmd, 1);
-    if (ok != HAL_OK) return ok;
-
-
-    /*
-     * set number of consequtive auto-refresh commands
-     * and program refresh rate
-     *
-     * RefreshRate = 64 ms / 8192 cyc = 7.8125 us/cyc
-     *
-     * RefreshCycles = 7.8125 us * 90 MHz = 703
-     *
-     * According to the formula on p.1665 of the reference manual,
-     * we also need to subtract 20 from the value, so the target
-     * refresh rate is 703 - 20 = 683.
-     */
-
-    ok = HAL_SDRAM_SetAutoRefreshNumber(sdram1, 8);
-    if (ok != HAL_OK) return ok;
-
-    HAL_SDRAM_ProgramRefreshRate(sdram1, 683);
-    if (ok != HAL_OK) return ok;
-
-    /*
-     * done
-     */
-    return HAL_OK;
-}
+/*
+ * stm-sdram.c
+ * -----------
+ * Functions concerning the 2x512 Mbit SDRAM working memory.
+ *
+ * Copyright (c) 2016, NORDUnet A/S All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ *
+ * - 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.
+ *
+ * - Neither the name of the NORDUnet 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
+ * HOLDER 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.
+ */
+#include "stm-init.h"
+#include "stm-sdram.h"
+#include "stm-fmc.h"
+#include "stm-led.h"
+
+/* Mode Register Bits */
+#define SDRAM_MODEREG_BURST_LENGTH_1             ((uint16_t)0x0000)
+#define SDRAM_MODEREG_BURST_LENGTH_2             ((uint16_t)0x0001)
+#define SDRAM_MODEREG_BURST_LENGTH_4             ((uint16_t)0x0002)
+#define SDRAM_MODEREG_BURST_LENGTH_8             ((uint16_t)0x0004)
+
+#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL      ((uint16_t)0x0000)
+#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED     ((uint16_t)0x0008)
+
+#define SDRAM_MODEREG_CAS_LATENCY_2              ((uint16_t)0x0020)
+#define SDRAM_MODEREG_CAS_LATENCY_3              ((uint16_t)0x0030)
+
+#define SDRAM_MODEREG_OPERATING_MODE_STANDARD    ((uint16_t)0x0000)
+
+#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
+#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE     ((uint16_t)0x0200)
+
+static SDRAM_HandleTypeDef hsdram1;
+static SDRAM_HandleTypeDef hsdram2;
+
+static void _sdram_init_gpio(void);
+static void _sdram_init_fmc(void);
+static void _sdram_init_params(void);
+
+void sdram_init(void)
+{
+    static int initialized = 0;
+    if (initialized) return;
+    initialized = 1;
+
+    /* We rely on several things being set up by fmc_init() instead of duplicating all
+     * that code here for independent FPGA/SDRAM FMC setup. This means the FPGA<->STM32
+     * FMC bus can be used without the SDRAMs initialized, but the SDRAMs can't be
+     * initialized withouth the FPGA<->STM32 FMC bus being set up too.
+     */
+    fmc_init();
+
+    /* configure FMC */
+    _sdram_init_gpio();
+    _sdram_init_fmc();
+
+    /* configure SDRAM registers */
+    _sdram_init_params();
+}
+
+static void _sdram_init_gpio(void)
+{
+    GPIO_InitTypeDef GPIO_InitStruct;
+
+    /* The bulk of the FMC GPIO pins are set up in fmc_init_gpio().
+     * This function just needs to enable the additional ones used
+     * with the SDRAMs.
+     */
+    fmc_af_gpio(GPIOB, GPIO_PIN_5 | GPIO_PIN_6);
+    fmc_af_gpio(GPIOC, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3);
+    fmc_af_gpio(GPIOE, GPIO_PIN_0 | GPIO_PIN_1);
+    fmc_af_gpio(GPIOF, GPIO_PIN_11);
+    fmc_af_gpio(GPIOG, GPIO_PIN_8 | GPIO_PIN_15);
+    fmc_af_gpio(GPIOI, GPIO_PIN_4 | GPIO_PIN_5);
+}
+
+static void _sdram_config_bank(SDRAM_HandleTypeDef *hsdram, uint32_t SDBank, FMC_SDRAM_TimingTypeDef *SdramTiming)
+{
+    /* memory type */
+    hsdram->Instance = FMC_SDRAM_DEVICE;
+
+    /* bank */
+    hsdram->Init.SDBank = SDBank;
+
+    /* settings for IS42S32160F */
+    hsdram->Init.ColumnBitsNumber	= FMC_SDRAM_COLUMN_BITS_NUM_9;
+    hsdram->Init.RowBitsNumber		= FMC_SDRAM_ROW_BITS_NUM_13;
+    hsdram->Init.MemoryDataWidth	= FMC_SDRAM_MEM_BUS_WIDTH_32;
+    hsdram->Init.InternalBankNumber	= FMC_SDRAM_INTERN_BANKS_NUM_4;
+    hsdram->Init.CASLatency		= FMC_SDRAM_CAS_LATENCY_2;
+
+    /* write protection not needed */
+    hsdram->Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
+
+    /* memory clock is 90 MHz (HCLK / 2) */
+    hsdram->Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
+
+    /* read burst not needed */
+    hsdram->Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
+
+    /* additional pipeline stages not neeed */
+    hsdram->Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
+
+    /* call HAL layer */
+    HAL_SDRAM_Init(hsdram, SdramTiming);
+}
+
+static void _sdram_init_fmc(void)
+{
+    FMC_SDRAM_TimingTypeDef SdramTiming;
+
+    /*
+     * following settings are for -75E speed grade memory chip
+     * clocked at only 90 MHz instead of the rated 133 MHz
+     *
+     * ExitSelfRefreshDelay: 67 ns @ 90 MHz is 6.03 cycles, so in theory
+     *                       6 can be used here, but let's be on the safe side
+     *
+     * WriteRecoveryTime:    must be >= tRAS - tRCD (5 - 2 = 3 cycles),
+     *                       and >= tRC - tRCD - tRP (8 - 2 - 2 = 4 cycles)
+     */
+    SdramTiming.LoadToActiveDelay	= 2;	// tMRD
+    SdramTiming.ExitSelfRefreshDelay	= 7;    // (see above)
+    SdramTiming.SelfRefreshTime		= 5;	// should be >= tRAS (5 cycles)
+    SdramTiming.RowCycleDelay		= 8;	// tRC
+    SdramTiming.WriteRecoveryTime	= 4;	// (see above)
+    SdramTiming.RPDelay			= 2;	// tRP
+    SdramTiming.RCDDelay		= 2;	// tRCD
+
+    /* configure the first bank */
+    _sdram_config_bank(&hsdram1, FMC_SDRAM_BANK1, &SdramTiming);
+
+    /* configure the second bank */
+    _sdram_config_bank(&hsdram2, FMC_SDRAM_BANK2, &SdramTiming);
+}
+
+static void _sdram_init_params(void)
+{
+    FMC_SDRAM_CommandTypeDef cmd;
+
+    /* enable clocking */
+    cmd.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
+    cmd.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1_2;
+    cmd.AutoRefreshNumber = 1;
+    cmd.ModeRegisterDefinition = 0;
+    HAL_Delay(1);
+    HAL_SDRAM_SendCommand(&hsdram1, &cmd, 1);
+
+    /* precharge all banks */
+    cmd.CommandMode = FMC_SDRAM_CMD_PALL;
+    cmd.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1_2;
+    cmd.AutoRefreshNumber = 1;
+    cmd.ModeRegisterDefinition = 0;
+    HAL_Delay(1);
+    HAL_SDRAM_SendCommand(&hsdram1, &cmd, 1);
+
+    /* send two auto-refresh commands in a row */
+    cmd.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
+    cmd.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1_2;
+    cmd.AutoRefreshNumber = 1;
+    cmd.ModeRegisterDefinition = 0;
+    HAL_SDRAM_SendCommand(&hsdram1, &cmd, 1);
+    HAL_SDRAM_SendCommand(&hsdram1, &cmd, 1);
+
+    /* load mode register */
+    cmd.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
+    cmd.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1_2;
+    cmd.AutoRefreshNumber = 1;
+    cmd.ModeRegisterDefinition =
+	SDRAM_MODEREG_BURST_LENGTH_1		|
+	SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL	|
+	SDRAM_MODEREG_CAS_LATENCY_2		|
+	SDRAM_MODEREG_OPERATING_MODE_STANDARD	|
+	SDRAM_MODEREG_WRITEBURST_MODE_SINGLE	;
+    HAL_SDRAM_SendCommand(&hsdram1, &cmd, 1);
+
+    /*
+     * set number of consequtive auto-refresh commands
+     * and program refresh rate
+     *
+     * RefreshRate = 64 ms / 8192 cyc = 7.8125 us/cyc
+     *
+     * RefreshCycles = 7.8125 us * 90 MHz = 703
+     *
+     * According to the formula on p.1665 of the reference manual,
+     * we also need to subtract 20 from the value, so the target
+     * refresh rate is 703 - 20 = 683.
+     */
+
+    HAL_SDRAM_SetAutoRefreshNumber(&hsdram1, 8);
+
+    HAL_SDRAM_ProgramRefreshRate(&hsdram1, 683);
+}
diff --git a/stm-sdram.h b/stm-sdram.h
index 8307ed3..88a7086 100644
--- a/stm-sdram.h
+++ b/stm-sdram.h
@@ -1,49 +1,46 @@
-/*
- * stm-sdram.h
- * -----------
- * Functions and defines concerning the 2x512 Mbit SDRAM working memory.
- *
- * Copyright (c) 2016, NORDUnet A/S All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * - Redistributions of source code must retain the above copyright notice,
- *   this list of conditions and the following disclaimer.
- *
- * - 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.
- *
- * - Neither the name of the NORDUnet 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
- * HOLDER 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.
- */
-#ifndef __STM32_SDRAM_H
-#define __STM32_SDRAM_H
-
-/* Base Addresses */
-#define SDRAM_BASEADDR_CHIP1			 ((uint32_t *)0xC0000000)
-#define SDRAM_BASEADDR_CHIP2			 ((uint32_t *)0xD0000000)
-
-/* Memory Size, 64 MBytes (512 Mbits) */
-#define SDRAM_SIZE				 0x4000000
-
-extern SDRAM_HandleTypeDef hsdram1;
-extern SDRAM_HandleTypeDef hsdram2;
-
-extern HAL_StatusTypeDef sdram_init(void);
-
-#endif
+/*
+ * stm-sdram.h
+ * -----------
+ * Functions and defines concerning the 2x512 Mbit SDRAM working memory.
+ *
+ * Copyright (c) 2016, NORDUnet A/S All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ *
+ * - 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.
+ *
+ * - Neither the name of the NORDUnet 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
+ * HOLDER 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.
+ */
+#ifndef __STM32_SDRAM_H
+#define __STM32_SDRAM_H
+
+/* Base Addresses */
+#define SDRAM_BASEADDR_CHIP1			 ((uint32_t *)0xC0000000)
+#define SDRAM_BASEADDR_CHIP2			 ((uint32_t *)0xD0000000)
+
+/* Memory Size, 64 MBytes (512 Mbits) */
+#define SDRAM_SIZE				 0x4000000
+
+extern void sdram_init(void);
+
+#endif
diff --git a/stm-uart.c b/stm-uart.c
index a670d76..ecec238 100644
--- a/stm-uart.c
+++ b/stm-uart.c
@@ -32,7 +32,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "stm32f4xx_hal.h"
+#include "stm-init.h"
 #include "stm-uart.h"
 
 #include <string.h>
@@ -45,6 +45,79 @@ DMA_HandleTypeDef hdma_usart_user_rx;
 
 static stm_uart_port_t default_uart = STM_UART_USER;
 
+#ifdef HAL_DMA_MODULE_ENABLED
+/**
+ * Enable DMA controller clock
+ */
+static void MX_DMA_Init(void)
+{
+    /* DMA controller clock enable */
+    __HAL_RCC_DMA2_CLK_ENABLE();
+    __HAL_RCC_DMA1_CLK_ENABLE();
+
+    /* DMA interrupt init */
+
+    /* USER UART RX */
+    HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
+    HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
+    /* MGMT UART RX */
+    HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
+    HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
+}
+#endif /* HAL_DMA_MODULE_ENABLED */
+
+/* USART1 init function */
+static void MX_USART1_UART_Init(void)
+{
+  huart_mgmt.Instance = USART1;
+  huart_mgmt.Init.BaudRate = USART_MGMT_BAUD_RATE;
+  huart_mgmt.Init.WordLength = UART_WORDLENGTH_8B;
+  huart_mgmt.Init.StopBits = UART_STOPBITS_1;
+  huart_mgmt.Init.Parity = UART_PARITY_NONE;
+  huart_mgmt.Init.Mode = UART_MODE_TX_RX;
+  huart_mgmt.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS;
+  huart_mgmt.Init.OverSampling = UART_OVERSAMPLING_16;
+
+#ifdef HAL_DMA_MODULE_ENABLED
+  __HAL_LINKDMA(&huart_mgmt, hdmarx, hdma_usart_mgmt_rx);
+#endif
+
+  if (HAL_UART_Init(&huart_mgmt) != HAL_OK) {
+    /* Initialization Error */
+    Error_Handler();
+  }
+}
+/* USART2 init function */
+static void MX_USART2_UART_Init(void)
+{
+  huart_user.Instance = USART2;
+  huart_user.Init.BaudRate = USART_USER_BAUD_RATE;
+  huart_user.Init.WordLength = UART_WORDLENGTH_8B;
+  huart_user.Init.StopBits = UART_STOPBITS_1;
+  huart_user.Init.Parity = UART_PARITY_NONE;
+  huart_user.Init.Mode = UART_MODE_TX_RX;
+  huart_user.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS;
+  huart_user.Init.OverSampling = UART_OVERSAMPLING_16;
+
+#ifdef HAL_DMA_MODULE_ENABLED
+  __HAL_LINKDMA(&huart_user, hdmarx, hdma_usart_user_rx);
+#endif
+
+  if (HAL_UART_Init(&huart_user) != HAL_OK) {
+    /* Initialization Error */
+    Error_Handler();
+  }
+}
+
+void uart_init(void)
+{
+#ifdef HAL_DMA_MODULE_ENABLED
+  MX_DMA_Init();
+#endif
+  MX_USART1_UART_Init();
+  MX_USART2_UART_Init();
+}
+
 void uart_set_default(stm_uart_port_t port)
 {
     if (port == STM_UART_USER || port == STM_UART_MGMT)
diff --git a/stm-uart.h b/stm-uart.h
index 3efd799..4d008c7 100644
--- a/stm-uart.h
+++ b/stm-uart.h
@@ -51,6 +51,8 @@ extern UART_HandleTypeDef huart_user;
 extern DMA_HandleTypeDef hdma_usart_mgmt_rx;
 extern DMA_HandleTypeDef hdma_usart_user_rx;
 
+extern void uart_init(void);
+
 extern void uart_set_default(stm_uart_port_t port);
 
 extern HAL_StatusTypeDef uart_send_char(uint8_t ch);

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Commits mailing list