commit 1678f27084400f39b41adccc3089d38a26b1597f
Author: Simon Welzel <simonwelzel@live.de>
Date:   Thu Jan 24 17:22:04 2019 +0100

    Re-Added files to a newer version of AMiRo-OS

diff --git a/Makefile b/Makefile
index 3125a9e..7edd321 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 ################################################################################
 # AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
 # (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
+# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
 #                                                                              #
 # This program is free software: you can redistribute it and/or modify         #
 # it under the terms of the GNU General Public License as published by         #
@@ -26,7 +26,7 @@
 define HELP_TEXT
 ################################################################################
 #                                                                              #
-# Copyright (c) 2016..2018  Thomas Schöpping                                   #
+# Copyright (c) 2016..2019  Thomas Schöpping                                   #
 #                                                                              #
 # This is free software; see the source for copying conditions. There is NO    #
 # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  #
@@ -48,15 +48,17 @@ ARGUMENTS:
   all:
       Builds the binaries for all modules.
 
-  flash:
-      Flashes all binaries to the hardware.
-      If the binaries do not exist, they are created beforehand.
+  <module>:
+      Builds the binary only for the specified module.
+
+  flash_<module>:
+      Builds the binary for the specified module and flashes it to the hardware.
 
   clean:
       Deletes all temporary and binary files of all modules.
 
-  <module>:
-      Builds the binary only for the specified module.
+  clean_<module>:
+      Deletes all temporary and binary files of the specified module.
 
 
 EXAMPLES:
@@ -69,17 +71,19 @@ EXAMPLES:
       This command will generate the binary files for the two modules
       DiWheelDrive (version 1.1) and LightRing (version 1.0).
 
-  >$$ make flash -j
-      This command will first build all missing binary files and flash all
-      modules as soon as the binaries are ready.
+  >$$ make all -j
+      This command will first build missing binary files for all modules that
+      are found in the 'modules/' folder.
       By the additional argument '-j' the build process will be parallelized.
 
-  >$$ make clean && make all && make flash
-      This command will first clean all thee projects. In a second step the
-      binaries for all modules are build from scratch. Finally all modules are
-      updated with the latest software.
-      The following command can be used as a shorter and faster version:
-          >$$ make clean && make flash -j
+  >$$ make flash_DiWheelDrive_1-1
+      This command will build the binary for the DiWheelDrive module
+      (version 1.1) only if required, and flash it to the hardware.
+
+  >$$ make clean; make all; make flash_DiWheelDrive_1-1
+      This command will first clean all projects. In a second step the binaries
+      for all modules are build from scratch. Finally the DiWheelDrive module
+      (version 1.1) is updated with the latest software.
 
 ################################################################################
 endef
diff --git a/README.txt b/README.txt
index 83fa2b4..3088068 100644
--- a/README.txt
+++ b/README.txt
@@ -4,7 +4,7 @@ embedded devices developed by Giovanni di Sirio; see <http://chibios.org>) as
 system kernel and extends it with platform specific configurations and further
 functionalities and abstractions.
 
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 (a complete list of all authors is given below)
 
 This program is free software: you can redistribute it and/or modify
@@ -55,23 +55,28 @@ the source code, and flash it to the AMiRo modules.
 
 CONTENTS:
 
-  1  Required software
+  1  Required Software
     1.1  Git
     1.2  Bootloader & Tools
     1.3  System Kernel
     1.4  Low-Level Drivers
-  2  Recommended software
+  2  Recommended Software
     2.1  gtkterm and hterm
     2.2  QtCreator IDE
     2.3  Doxygen & Graphviz
-  3  Building and flashing
+  3  Building and Flashing
+  4  Developer Guides
+    4.1  Adding a New Module
+    4.2  Handling a Custom I/O Event in the Main Thread
+    4.3  Implementing a New Low-Level Driver
+    4.4  Writing a Unit Test
 
 ================================================================================
 
 
 
 1 - REQUIRED SOFTWARE
----------------------
+=====================
 
 In order to compile the source code, you need to install the GNU ARM Embedded
 Toolchain. Since this project uses GNU Make for configuring and calling the
@@ -107,8 +112,8 @@ Since AMiRo-OS uses ChibiOS as underlying system kernel, you need to acquire a
 copy of it as well. For the sake of compatibility, it is included in AMiRo-OS as
 a Git submodule. It is highly recommended to use the ./setup.sh script for
 initialization. Moreover, you have to apply the patches to ChibiOS in order to
-make AMiRo-OS work properly. It is recommended to use the .setup.sh script for this
-purpose.
+make AMiRo-OS work properly. It is recommended to use the .setup.sh script for
+this purpose.
 If you would like to use a different kernel, you can add a subfolder in the
 ./kernel/ directory and adapt the scripts and operating system source code.
 
@@ -116,16 +121,16 @@ If you would like to use a different kernel, you can add a subfolder in the
 1.4 Low-Level Drivers
 ---------------------
 
-Any required low-level drivers for the AMiRo hardware is available in an
+Any required low-level drivers for the AMiRo hardware are available in an
 additional project: AMiRo-LLD. It is included as a Git subodule and can be
 initialized via the ./setup.sh script.
 
 
 
 2 - RECOMMENDED SOFTWARE
-------------------------
+========================
 
-AMiRo-OS can take advanatge of an installed bootloader, which is recommended for
+AMiRo-OS can take advantage of an installed bootloader, which is recommended for
 the best experience. In order to use all features of AMiRo-OS it is also
 recommended to install either the 'hterm' or 'gtkterm' application for accessing
 the robot. To ease further development, this project offers support for the
@@ -157,6 +162,11 @@ For hterm you need to configure the tool analogously. With either tool the robot
 can be reset by toggling the RTS signal on and off again, and you can access the
 system shell of AMiRo-OS. If you need legacy support for older version of
 AMiRo-BLT, you can replace the port value by '/dev/ttyUSB0'.
+Advanced users can use several connections to multiple modules simultaneously.
+Each additional programmer will be available as '/dev/ttyAMiRo<N>' (and
+'/dev/USB<N>' respectively) with <N> being an integer number starting from zero.
+Please note: Those interfaces are ordered by the time when they have been
+detected by the operating system.
 
 
 2.2 - QtCreator IDE
@@ -178,7 +188,7 @@ default versions for your system. Ubuntu users should simply run
 
 
 3 - BUILDING AND FLASHING
--------------------------
+=========================
 
 Each time you modify any part of AMiRo-OS, you need to recompile the whole
 project for the according AMiRo module. Therefore you can use the ./Makefile by
@@ -198,5 +208,218 @@ either to the DiWheelDrive or the PowerManagement module for flashing the
 operating system. All other modules are powered off after reset so that only
 these two offer a running bootloader, which is required for flashing.
 
+
+
+4 - DEVELOPER GUIDES
+====================
+
+Due to the complexity of AMiRo-OS it can be quite troublesome to get started
+with the framework at the beginning. The guides in this chapter will help you
+getting things done, without thorough knowledge of the software structure.
+Whereas the textual descriptions of the guides provide additional informatio
+about the underlying concepts and mechanisms, a short summary is provided at the
+end of each chapter.
+
+
+4.1  Adding a New Module
+------------------------
+
+The very first thing to do when adding a new module to support AMiRo-OS is to
+create an according folder in the modules/ directory. The name of this folder
+should be as unambiguous as possible (e.g. containing name and version number).
+All files, which directly depent on the hardware, and thus are not portable,
+belong here. Conversely, any code that can be reused on diferent hardware must
+not be put in the module folder.
+
+In a second step you have to initialize all requried files (see below) in the
+newlly created module directory. It is recommended to use another module as
+template for your configuration:
+- alldconf.h
+  Configuration header for the AMiRo-LLD project, which is part of AMiRo-OS.
+- aosconf.h
+  Configuration header for the AMiRo-OS project.
+- board.h & board.c
+  Contains definitions of GPIO names and initialization setting of those, as
+  well as initialization functions.
+- chconf.h
+  Configuration header for the ChibiOS/RT system kernel. There are probably only
+  very few configurations one here, since most settings depend on the content of
+  aosconf.h and are handled module unspecific in modules/aos_chconf.h
+- halconf.h
+  Configuration header for ChibiOS/HAL (hardware abstraction layer).
+- Makefile
+  The GNU make script to build and flash AMiRo-OS for the module.
+- mcuconf.h
+  Configuration file for ChibiOS/JAL to initialize the microcontroller (MCU). It
+  is recommended to check the kernel/ChibiOS/demos/ directory for an example
+  using the according MCU and copy the mcuconf.h from there. Depending on your
+  hardware you may have to modify it nevertheless, though.
+- module.h & module.c
+  These files act as some sort of container, where all module specific aliases
+  for interfaces and GPIOs, configurations, hooks, low-level drivers, and unit
+  tests are defined. These are most probably the most comprehensive files in the
+  module folder.
+- <mcu>.ld
+  Linker script, defining the memory layout and region aliases. It is
+  recommended to check ChibiOS (kernel/ChibiOS/os/common/startup/) whether a
+  linker script for the according MCU already exists.
+
+Since all these files are specific to the module hardware, youl will have to
+modify the contents according to your setup in a third step. Most settings are
+described in detail within the configuration files, but for others you will have
+to consult the datasheet of your MCU and even take a closer look at how certain
+settings are used in other modules.
+
+Finally, you need to build and flash the project. The compiler might even help
+you getting everything set up correctly. Take time to understand compilation
+errors and warning and get rid of all of those (warnings should not be ignored
+since they are hints that something might be amiss and the program will not act
+as intended).
+
+Summing up, you have to
+1) create a module directory.
+2) initialize all files (use an existing module or a ChibiOS demo as template).
+3) configure all files according to your hardware setup and preferences.
+4) compile, flash and check for issues.
+
+4.2  Handling a Custom I/O Event in the Main Thread
+---------------------------------------------------
+
+In order to handle custom I/O events in the main thread, AMiRo-OS offers several
+hooks to be used. First of all, you need to configure and enable the interrupt
+in the according GPIO. This can be done by implementing the
+MODULE_INIT_INTERRUPTS() hook in the module.h file. For information how to use
+this hook, please have a look at existing modules. In the end, the interrupt
+callback functions has to emit an I/O event with the according bit in the flags
+mask set (like the _intCallback() function in aos_system.c). As result, whenever
+a rising or falling edge (depends on configuration) is detected on that GPIO,
+the interrupt service routine is executed and hence an I/O event is fired, which
+can be catched by any thread in the system.
+
+Next, you have to configure the main thread to whitelist the event flag (all I/O
+events are blacklisted by default). While system relevant events like power down
+are whitelisted by the OS, any custom events need to be added exl´plicitely.
+This is done via the optional AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK macro, which
+should be defined in the module.h file. Example:
+
+  #define AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK                \
+    (AOS_IOEVENT_FLAG(padX) | AOS_IOEVENT_FLAG(padY) | AOS_IOEVENT_FLAG(padZ))
+
+When AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK has been defined correctly, the main
+thread will be notified by the according events and execute its event handling
+routine. Hence you have to implement another macro in module.h to handle the
+custom event(s) appropriately: MODULE_MAIN_LOOP_IO_EVENT(eventflags). As you can
+see, the variable 'eventflags' is propagated to the hook. This variable is a
+mask, that allows to identify the GPIO pad(s), which caused the event, by the
+bits set. Following the example above, you can check which GPIOs have caused
+events by using if-clauses in the implementation of the hook:
+
+  #define MODULE_MAIN_LOOP_IO_EVENT(eventflags) {           \
+    if (eventflags & AOS_IOEVENT_FLAG(padX)) {              \
+      /* handle event */                                    \
+    }                                                       \
+    if (eventflags & (AOS_IOEVENT_FLAG(padY) |              \
+          AOS_IOEVENT_FLAG(padZ))) {                        \
+      /* handle combined event */                           \
+    }                                                       \
+  }
+
+Summing up, you have to
+1) configure and enable the GPIO interrupt.
+2) define the AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK macro.
+3) implement the MODULE_MAIN_LOOP_IO_EVENT(eventflags) hook.
+
+4.3  Implementing a New Low-Level Driver
+----------------------------------------
+
+In the AMiRo-OS framework, low-level drivers are located in the additional Git
+project AMiRo-LLD, which is included in AMiRo-OS as Git submodule at
+periphery-lld/AMiRo-LLD/ and acts similar to a static library. When adding a new
+low-level driver to the framework, you have to implement it, providing a
+(single) header file in periphery-lld/AMiRo-LLD/include/ and the required C
+sources in periphery-lld/AMiRo-LLD/source/. By convention, all filenames use the
+prefix 'alld_' to avoid ambiguities. Furthermore, files should be named by the
+exact designation of the hardware (e.g. 'alld_vcnl4020' instead of
+'alld_proximitysensor'). Since AMiRo-LLD is intended to be usable with other
+operating systems than AMiRo-OS, it provides an interface for accessing
+communication interfaces and basic functionalities of the operating system. On
+the one hand, several types are defined in periphery-lld/AMiRo-LLD/periphALtypes.h.
+The interface functions, on the other hand, are defined by AMiRo-LLD (cf.
+periphery-lld/AMiRo-LLD/templates/periphAL.h), but implemented by the operating
+system (cf. periphery-lld/periphAL.h). For the implementation of the driver, you
+must only use those types and functions to interact with the operating system.
+If you need further functionality, which is not provided by the interface yet,
+you are encouraged to extend periphAL.
+
+Furthermore, all files must define a guard, so that the whole driver is
+disabled, when the guard is not set explicitely. These guard again are named
+following a convention, but instead of explaning it here, just have a look at
+one of the existing drivers and look for lines like
+
+  #if defined(AMIROLLD_CFG_USE_VCNL4020) || defined(__DOXYGEN__)
+
+With these guards in place, the driver will be omitted by default and needs to
+be enabled explicitely. In order to do so, you need to add an according #define
+in the alldconf.h file of any module, which shall use the new driver.
+
+Now the new driver is available and enabled, but not actually used yet.
+Therefore you have to add according memory structures to the module.h and
+module.c files - just have a look at existing modules how this is done. In some
+cases you will have to configure additional interrupts and/or alter the
+configuration of a communication interface (e.g. I²C). Once again, you should
+take a look at existing modules and search the module.h for the hooks
+MODULE_INIT_INTERRUPTS() and MODULE_INIT_PERIPHERY_COMM().
+
+Finally, you will probably want to validate your implementation via a unit test.
+How this can be done is explained in detail in the next guide.
+
+Summing up, you have to
+1) implement the driver in AMiRo-LLD using periphAL only.
+2) fence all code in all files by a guard.
+3) set the guard in alldconf.h to enable the driver.
+4) add the driver to a module.
+5) configure interrupts and interfaces as required.
+6) write a unit test.
+
+4.4  Writing a Unit Test
+------------------------
+
+AMiRo-OS provides a unit test framework for conventient testing and the ability
+to opt-out all unit tests via the aosconf.h configuration file. There is also a
+dedicated folder, where all unit test code belongs to. In case you want to
+implement a unit test for a newly developed low-level driver, you should use the
+folders unittests/periphery-lld/inc and unittests/periphery-lld/src
+respectively. As with the low-level drivers, unit test files should use a prefix
+in their name, namely 'ut_' and all code should be fenced via guards that
+disable it by default (have a look at existing unit tests). Before you implement
+a vast test, however, it is highly recommended to start with some sceleton code
+(just copy an existing unit test, scoop out the test function, and rename
+according variables etc.) and make it compile and run.
+
+After you have initialized the unit test sceleton, you have to add the according
+aos_unittest_t (cf. core/inc/aos_unittest.h) object to the module.h and module.c
+files. These objects again require an shell command, so the unit test can be run
+via the AMiRo-OS shell. As with existing unit tests, this shell command callback
+function as well as any further required data should be implemented directly in
+module.c, so it not accessable from any other context. In most cases this
+callback function is trivial, anyway.
+
+In order to make the shell command, which executes the unit test, available in
+shell so a user can run it, it has to be associated with the shell. AMiRo-OS
+provides the hook MODULE_INIT_TESTS() for this purpose, which has to be
+implemented in the module.h file. Once again I recommend to have a look at an
+existing module, how to use this hook.
+
+Since the execution pipeline is set up now, you can fille your unit test with
+life. Remember that the test is executed by the shell thread, so you can access
+any functionality of the system, but might encounter race conditions, depending
+on what other applications run concurrently.
+
+Summing up, you have to
+1) initialize a unit test sceleton in the unittests/ folder.
+2) introduce an according object and configuration in module.h and module.c.
+3) associate the shell command to a shell via the hook in module.h.
+4) implement the full unit test in the prevously created sceleton files.
+
 ================================================================================
 
diff --git a/amiroos.h b/amiroos.h
index a333890..a07c76c 100644
--- a/amiroos.h
+++ b/amiroos.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/bootloader/bootloader.mk b/bootloader/bootloader.mk
index 75f2b72..c7171bf 100644
--- a/bootloader/bootloader.mk
+++ b/bootloader/bootloader.mk
@@ -1,7 +1,7 @@
 ################################################################################
 # AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
 # (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
+# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
 #                                                                              #
 # This program is free software: you can redistribute it and/or modify         #
 # it under the terms of the GNU General Public License as published by         #
diff --git a/bootloader/bootloadersetup.sh b/bootloader/bootloadersetup.sh
index d47a5a3..491c25f 100755
--- a/bootloader/bootloadersetup.sh
+++ b/bootloader/bootloadersetup.sh
@@ -263,6 +263,40 @@ function setLogFile {
   return 0
 }
 
+### check whether commands are available #######################################
+# Checks whether the specified commands are available and can be executed.
+#
+# usage:      checkCommand [<command> <command> ...]
+# arguments:  <command>
+#                 Name of the command to check.
+# return:     0
+#                 All requested commands are available.
+#             >0
+#                 Number of requested commands that were not found.
+#             -1
+#                 No argument given.
+#
+function checkCommands {
+  local status=0
+
+  # return if no argument was specified
+  if [ $# -eq 0 ]; then
+    return -1
+  fi
+
+  # check all specified commands
+  while [ $# -gt 0 ]; do
+    command -v $1 &>/dev/null
+    if [ $? -ne 0 ]; then
+      printWarning "Command '$1' not available.\n"
+      status=$((status + 1))
+    fi
+    shift 1
+  done
+
+  return $status
+}
+
 ################################################################################
 # SPECIFIC FUNCTIONS                                                           #
 ################################################################################
@@ -329,6 +363,8 @@ function printHelp {
 #                 Warning: Arborted by user.
 #             -1
 #                 Error: Unexpected user input.
+#             -2
+#                 Error: Missing dependencies.
 #
 function initAmiroBlt {
   printInfo "initializing AMiRo-BLT submodule...\n"
@@ -354,6 +390,13 @@ function initAmiroBlt {
     esac
   fi
 
+  # check dependencies
+  checkCommands git
+  if [ $? -ne 0 ]; then
+    printError "Missing dependencies detected.\n"
+    return -2
+  fi
+
   # initialize submodule to default branch
   cd $bootloaderdir
   git submodule update --init $amirobltdir 2>&1 | tee -a $LOG_FILE
@@ -412,13 +455,30 @@ function amiroBltSetup {
 #
 # usage:      wipeAmiroBlt
 # arguments:  n/a
-# return:     n/a
+# return:     0
+#                 No error or warning occurred.
+#             1
+#                 Warning: AMiRo-BLT Git submodule already empty
+#             2
+#                 Warning: Aborted by user.
+#             -1
+#                 Error: Unexpected input occurred
+#             -2
+#                 Error: Missing dependencies.
+#
 function wipeAmiroBlt {
   printInfo "reset and wipe Git submodule $amirobltdir\n"
   local userdir=$(pwd)
   local bootloaderdir=$(dirname $(realpath ${BASH_SOURCE[0]}))
   local amirobltdir=${bootloaderdir}/AMiRo-BLT
 
+  # check dependencies
+  checkCommands git
+  if [ $? -ne 0 ]; then
+    printError "Missing dependencies detected.\n"
+    return -2
+  fi
+
   # if the AMiRo-BLT folder is empty
   if [ -z "$(ls -A $amirobltdir)" ]; then
     printWarning "$amirobltdir is already empty\n"
diff --git a/core/core.mk b/core/core.mk
index 9bc01a8..c647a16 100644
--- a/core/core.mk
+++ b/core/core.mk
@@ -1,7 +1,7 @@
 ################################################################################
 # AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
 # (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
+# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
 #                                                                              #
 # This program is free software: you can redistribute it and/or modify         #
 # it under the terms of the GNU General Public License as published by         #
@@ -30,15 +30,8 @@ AMIROOS_CORE_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
 AMIROOSCOREINC = $(AMIROOS_CORE_DIR)inc
 
 # C source files
-AMIROOSCORECSRC = $(AMIROOS_CORE_DIR)src/aos_debug.c \
-                  $(AMIROOS_CORE_DIR)src/aos_iostream.c \
-                  $(AMIROOS_CORE_DIR)src/aos_shell.c \
-                  $(AMIROOS_CORE_DIR)src/aos_system.c \
-                  $(AMIROOS_CORE_DIR)src/aos_thread.c \
-                  $(AMIROOS_CORE_DIR)src/aos_time.c \
-                  $(AMIROOS_CORE_DIR)src/aos_timer.c \
-                  $(AMIROOS_CORE_DIR)src/aos_unittest.c
+AMIROOSCORECSRC = $(wildcard $(AMIROOS_CORE_DIR)src/*.c)
 
 # C++ source files
-AMIROOSCORECPPSRC = $(AMIROOS_CORE_DIR)src/aos_main.cpp
+AMIROOSCORECPPSRC = $(wildcard $(AMIROOS_CORE_DIR)src/*.c?*)
 
diff --git a/core/inc/aos_confcheck.h b/core/inc/aos_confcheck.h
index 5d67b08..252bcbb 100644
--- a/core/inc/aos_confcheck.h
+++ b/core/inc/aos_confcheck.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -49,40 +49,45 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
   #error "AMIROOS_CFG_MAIN_LOOP_TIMEOUT not defined in aosconf.h"
 #endif
 
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
-
 /*
  * SSSP parameters and options
  */
 
-#ifndef AMIROOS_CFG_SSSP_MASTER
-  #error "AMIROOS_CFG_SSSP_MASTER not defined in aosconf.h"
+#ifndef AMIROOS_CFG_SSSP_ENABLE
+  #error "AMIROOS_CFG_SSSP_ENABLE not defined in aosconf.h"
 #endif
 
-#ifndef AMIROOS_CFG_SSSP_STACK_START
-  #error "AMIROOS_CFG_SSSP_STACK_START not defined in aosconf.h"
-#endif
+# if (AMIROOS_CFG_SSSP_ENABLE == true)
 
-#ifndef AMIROOS_CFG_SSSP_STACK_END
-  #error "AMIROOS_CFG_SSSP_STACK_END not defined in aosconf.h"
-#endif
+  #ifndef AMIROOS_CFG_SSSP_MASTER
+    #error "AMIROOS_CFG_SSSP_MASTER not defined in aosconf.h"
+  #endif
 
-#if (AMIROOS_CFG_SSSP_STACK_START == true) && (AMIROOS_CFG_SSSP_STACK_END == true)
-  #warning "AMIROOS_CFG_SSSP_STACK_START and AMIROOS_CFG_SSSP_STACK_END both enabled in aosconf.h"
-  #if (AMIROOS_CFG_SSSP_MASTER != true)
-    #error "AMIROOS_CFG_SSSP_MASTER must be enabled in this case"
+  #ifndef AMIROOS_CFG_SSSP_STACK_START
+    #error "AMIROOS_CFG_SSSP_STACK_START not defined in aosconf.h"
   #endif
-#endif
 
-#ifndef AMIROOS_CFG_SSSP_SIGNALDELAY
-  #error "AMIROOS_CFG_SSSP_SIGNALDELAY not defined in aosconf.h"
-#endif
+  #ifndef AMIROOS_CFG_SSSP_STACK_END
+    #error "AMIROOS_CFG_SSSP_STACK_END not defined in aosconf.h"
+  #endif
 
-#ifndef AMIROOS_CFG_SSSP_SYSSYNCPERIOD
-  #error "AMIROOS_CFG_SSSP_SYSSYNCPERIOD not defined in aosconf.h"
-#endif
+  #if (AMIROOS_CFG_SSSP_STACK_START == true) && (AMIROOS_CFG_SSSP_STACK_END == true)
+    #warning "AMIROOS_CFG_SSSP_STACK_START and AMIROOS_CFG_SSSP_STACK_END both enabled in aosconf.h"
+    #if (AMIROOS_CFG_SSSP_MASTER != true)
+      #error "AMIROOS_CFG_SSSP_MASTER must be enabled in this case"
+    #endif
+  #endif
+
+  #ifndef AMIROOS_CFG_SSSP_SIGNALDELAY
+    #error "AMIROOS_CFG_SSSP_SIGNALDELAY not defined in aosconf.h"
+  #endif
+
+  #ifndef AMIROOS_CFG_SSSP_SYSSYNCPERIOD
+    #error "AMIROOS_CFG_SSSP_SYSSYNCPERIOD not defined in aosconf.h"
+  #endif
 
 #endif
+
 /*
  * System shell options
  */
diff --git a/core/inc/aos_debug.h b/core/inc/aos_debug.h
index 56a33ba..79fcf42 100644
--- a/core/inc/aos_debug.h
+++ b/core/inc/aos_debug.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/core/inc/aos_iostream.h b/core/inc/aos_iostream.h
index 2c71571..0cfbba4 100644
--- a/core/inc/aos_iostream.h
+++ b/core/inc/aos_iostream.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/core/inc/aos_shell.h b/core/inc/aos_shell.h
index 1cf5eee..9d7ebc0 100644
--- a/core/inc/aos_shell.h
+++ b/core/inc/aos_shell.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/core/inc/aos_system.h b/core/inc/aos_system.h
index 89fbe33..7db756a 100644
--- a/core/inc/aos_system.h
+++ b/core/inc/aos_system.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -27,6 +27,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifndef _AMIROOS_SYSTEM_H_
 #define _AMIROOS_SYSTEM_H_
 
+#include <time.h>
 #include <aos_iostream.h>
 #include <amiro-lld.h>
 #include <aos_shell.h>
@@ -63,7 +64,19 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #define AOS_SYSTEM_EVENTFLAGS_RESTART           (AOS_SYSTEM_EVENTFLAGS_SHUTDOWN | (eventflags_t)(1 << 4))
 
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
+/**
+ * @brief   Enumerator to identify shutdown types.
+ */
+typedef enum aos_shutdown {
+  AOS_SHUTDOWN_NONE,            /**< Default value if no shutdown action was initiated */
+  AOS_SHUTDOWN_PASSIVE,         /**< Passive shutdown (initiated by another module). */
+  AOS_SHUTDOWN_HIBERNATE,       /**< Active shutdown to hibernate mode. */
+  AOS_SHUTDOWN_DEEPSLEEP,       /**< Active shutdown to deepsleep mode. */
+  AOS_SHUTDOWN_TRANSPORTATION,  /**< Active shutdown to transportation mode. */
+  AOS_SHUTDOWN_RESTART,         /**< Active saystem restart request. */
+} aos_shutdown_t;
+
+#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
 
 /**
  * @brief   Major version of the implemented SSSP.
@@ -81,22 +94,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #define AOS_SYSTEM_SSSP_TIMEOUT                 (10 * AMIROOS_CFG_SSSP_SIGNALDELAY)
 
-#endif
-
-/**
- * @brief   Enumerator to identify shutdown types.
- */
-typedef enum aos_shutdown {
-  AOS_SHUTDOWN_NONE,            /**< Default value if no shutdown action was initiated */
-  AOS_SHUTDOWN_PASSIVE,         /**< Passive shutdown (initiated by another module). */
-  AOS_SHUTDOWN_HIBERNATE,       /**< Active shutdown to hibernate mode. */
-  AOS_SHUTDOWN_DEEPSLEEP,       /**< Active shutdown to deepsleep mode. */
-  AOS_SHUTDOWN_TRANSPORTATION,  /**< Active shutdown to transportation mode. */
-  AOS_SHUTDOWN_RESTART,         /**< Active saystem restart request. */
-} aos_shutdown_t;
-
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
-
 /**
  * @brief   Enumerator of the several stages of SSSP.
  */
@@ -119,21 +116,18 @@ typedef enum aos_ssspstage {
   AOS_SSSP_SHUTDOWN_3   = 0x38, /**< Identifier of SSSP shutdown phase stage 3. */
 } aos_ssspstage_t;
 
-#endif
-
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
 /**
  * @brief   Type to represent module IDs.
  */
 typedef uint16_t aos_ssspmoduleid_t;
-#endif
 
+#endif /* AMIROOS_CFG_SSSP_ENABLE == true */
 
 /**
  * @brief   AMiRo-OS base system structure.
  */
 typedef struct aos_system {
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
+#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
   /**
    * @brief   SSSP relevant data.
    */
@@ -150,7 +144,8 @@ typedef struct aos_system {
      */
     aos_ssspmoduleid_t moduleId;
   } sssp;
-#endif
+#endif /* AMIROOS_CFG_SSSP_ENABLE == true */
+
   /**
    * @brief   System I/O stream.
    */
@@ -202,7 +197,7 @@ extern "C" {
   void aosSysInit(void);
 #endif
   void aosSysStart(void);
-  #if (AMIROOS_CFG_SSSP_ENABLE == true)
+#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined (__DOXYGEN__)
   eventmask_t aosSysSsspStartupOsInitSyncCheck(event_listener_t* syncEvtListener);
 #endif
   void aosSysGetUptimeX(aos_timestamp_t* ut);
diff --git a/core/inc/aos_thread.h b/core/inc/aos_thread.h
index c08ec00..613ab54 100644
--- a/core/inc/aos_thread.h
+++ b/core/inc/aos_thread.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -99,7 +99,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 extern "C" {
 #endif
   void aosThdSleepUntilS(const aos_timestamp_t* t);
-#if (CH_DBG_FILL_THREADS == TRUE)
+#if (AMIROOS_CFG_DBG == true) && (CH_DBG_FILL_THREADS == TRUE)
   size_t aosThdGetStackPeakUtilization(thread_t* thread);
 #endif
 #ifdef __cplusplus
@@ -240,6 +240,8 @@ static inline void aosThdSleepUntil(const aos_timestamp_t* t)
   return;
 }
 
+#if (AMIROOS_CFG_DBG == true) || defined(__DOXYGEN__)
+
 /**
  * @brief   Retrieve the stack size of a specific thread in bytes.
  *
@@ -263,6 +265,8 @@ static inline size_t aosThdGetStacksize(thread_t* thread)
          ((size_t)PORT_GUARD_PAGE_SIZE + sizeof(struct port_intctx) + sizeof(struct port_extctx) + (size_t)PORT_INT_REQUIRED_STACK);
 }
 
+#endif /* AMIROOS_CFG_DBG == true */
+
 #endif /* _AMIROOS_THREAD_H_ */
 
 /** @} */
diff --git a/core/inc/aos_time.h b/core/inc/aos_time.h
index 284af13..39f9196 100644
--- a/core/inc/aos_time.h
+++ b/core/inc/aos_time.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/core/inc/aos_timer.h b/core/inc/aos_timer.h
index 495c741..4dade54 100644
--- a/core/inc/aos_timer.h
+++ b/core/inc/aos_timer.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/core/inc/aos_types.h b/core/inc/aos_types.h
index 4154884..6925a0a 100644
--- a/core/inc/aos_types.h
+++ b/core/inc/aos_types.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -28,6 +28,11 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define _AMIROOS_TYPES_H_
 
 /**
+ * @brief   Converts a GPIO pad number to a unique event flag.
+ */
+#define AOS_IOEVENT_FLAG(pad)                   ((eventflags_t)1 << pad)
+
+/**
  * @brief   Error codes used in AMiRo-OS.
  */
 typedef enum {
diff --git a/core/inc/aos_unittest.h b/core/inc/aos_unittest.h
index 3900bac..5efea26 100644
--- a/core/inc/aos_unittest.h
+++ b/core/inc/aos_unittest.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/core/src/aos_debug.c b/core/src/aos_debug.c
index f4e5dbe..4153558 100644
--- a/core/src/aos_debug.c
+++ b/core/src/aos_debug.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/core/src/aos_iostream.c b/core/src/aos_iostream.c
index 548eae2..75df0a1 100644
--- a/core/src/aos_iostream.c
+++ b/core/src/aos_iostream.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/core/src/aos_main.cpp b/core/src/aos_main.cpp
index 9fb60dd..654be93 100644
--- a/core/src/aos_main.cpp
+++ b/core/src/aos_main.cpp
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -61,7 +61,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #define DELAYEVENT_MASK                         EVENT_MASK(4)
 
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
+#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
 
 /**
  * @brief   CAN message identifier for initialization of the SSSP stack initialization sequence.
@@ -78,7 +78,14 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #define SSSP_STACKINIT_CANMSGID_ABORT           0x001
 
-#endif
+#else /* AMIROOS_CFG_SSSP_ENABLE == false */
+
+/**
+ * @brief   Default shutdown mode if SSSP is unavailable.
+ */
+#define AOS_SHUTDOWN_DEFAULT                    AOS_SHUTDOWN_DEEPSLEEP
+
+#endif /* AMIROOS_CFG_SSSP_ENABLE */
 
 /**
  * @brief   CAN message identifier for calender synchronization message.
@@ -106,8 +113,8 @@ static AosIOChannel _stdiochannel;
  * @brief   I/O shell channel for the programmer interface.
  */
 static AosShellChannel _stdshellchannel;
-#endif
-#endif
+#endif /* AMIROOS_CFG_SHELL_ENABLE == true */
+#endif /* defined(MODULE_HAL_PROGIF) */
 
 /*
  * hook to add further static variables
@@ -125,16 +132,15 @@ AMIROOS_CFG_MAIN_EXTRA_STATIC_VARIABLES
 static inline void _unexpectedEventError(const eventmask_t mask, const eventflags_t flags)
 {
 #if (AMIROOS_CFG_DBG == true)
-    aosprintf("CTRL: unexpected/unknown event received. mask: 0x%08X; flags: 0x%08X\n", mask, flags);
+  aosprintf("CTRL: unexpected/unknown event received. mask: 0x%08X; flags: 0x%08X\n", mask, flags);
 #else
-    (void)(mask);
-    (void)(flags);
+  (void)(mask);
+  (void)(flags);
 #endif
-    return;
+  return;
 }
 
-
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
+#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
 /**
  * @brief   Callback function to be used during SSSP stack initialization sequence.
  *
@@ -142,15 +148,16 @@ static inline void _unexpectedEventError(const eventmask_t mask, const eventflag
  */
 static void _ssspTimerCallback(void* par)
 {
-    aosDbgCheck(par != NULL);
+  aosDbgCheck(par != NULL);
 
-    chSysLockFromISR();
-    chEvtBroadcastI((event_source_t*)par);
-    chSysUnlockFromISR();
+  chSysLockFromISR();
+  chEvtBroadcastI((event_source_t*)par);
+  chSysUnlockFromISR();
 
-    return;
+  return;
 }
-#endif
+#endif /* AMIROOS_CFG_SSSP_ENABLE == true */
+
 /**
  * @brief   Helper function to serialize data.
  *
@@ -160,14 +167,14 @@ static void _ssspTimerCallback(void* par)
  */
 inline void _serialize(uint8_t* dst, const uint64_t src, const uint8_t n)
 {
-    aosDbgCheck(dst != NULL);
-    aosDbgCheck(n > 0 && n <= 8);
+  aosDbgCheck(dst != NULL);
+  aosDbgCheck(n > 0 && n <= 8);
 
-    for (uint8_t byte = 0; byte < n; ++byte) {
-        dst[byte] = (uint8_t)((src >> (byte * 8)) & 0xFF);
-    }
+  for (uint8_t byte = 0; byte < n; ++byte) {
+    dst[byte] = (uint8_t)((src >> (byte * 8)) & 0xFF);
+  }
 
-    return;
+  return;
 }
 
 /**
@@ -180,15 +187,15 @@ inline void _serialize(uint8_t* dst, const uint64_t src, const uint8_t n)
  */
 inline uint64_t _deserialize(uint8_t* src, const uint8_t n)
 {
-    aosDbgCheck(src != NULL);
-    aosDbgCheck(n > 0 && n <= 8);
+  aosDbgCheck(src != NULL);
+  aosDbgCheck(n > 0 && n <= 8);
 
-    uint64_t result = 0;
-    for (uint8_t byte = 0; byte < n; ++byte) {
-        result |= ((uint64_t)src[byte]) << (byte * 8);
-    }
+  uint64_t result = 0;
+  for (uint8_t byte = 0; byte < n; ++byte) {
+    result |= ((uint64_t)src[byte]) << (byte * 8);
+  }
 
-    return result;
+  return result;
 }
 
 /**
@@ -210,17 +217,17 @@ inline uint64_t _deserialize(uint8_t* src, const uint8_t n)
  */
 inline uint64_t _TM2U64(struct tm* src)
 {
-    aosDbgCheck(src != NULL);
-
-    return (((uint64_t)(src->tm_sec  & 0x0000003F) << (0))               |
-            ((uint64_t)(src->tm_min  & 0x0000003F) << (6))               |
-            ((uint64_t)(src->tm_hour & 0x0000001F) << (12))              |
-            ((uint64_t)(src->tm_mday & 0x0000001F) << (17))              |
-            ((uint64_t)(src->tm_mon  & 0x0000000F) << (22))              |
-            ((uint64_t)(src->tm_year & 0x00FFFFFF) << (26))              |
-            ((uint64_t)(src->tm_wday & 0x00000007) << (50))              |
-            ((uint64_t)(src->tm_yday & 0x000001FF) << (53))              |
-            ((uint64_t)((src->tm_isdst == 0) ? 0 : (src->tm_isdst > 0) ? 1 : 2) << (62)));
+  aosDbgCheck(src != NULL);
+
+  return (((uint64_t)(src->tm_sec  & 0x0000003F) << (0))               |
+          ((uint64_t)(src->tm_min  & 0x0000003F) << (6))               |
+          ((uint64_t)(src->tm_hour & 0x0000001F) << (12))              |
+          ((uint64_t)(src->tm_mday & 0x0000001F) << (17))              |
+          ((uint64_t)(src->tm_mon  & 0x0000000F) << (22))              |
+          ((uint64_t)(src->tm_year & 0x00FFFFFF) << (26))              |
+          ((uint64_t)(src->tm_wday & 0x00000007) << (50))              |
+          ((uint64_t)(src->tm_yday & 0x000001FF) << (53))              |
+          ((uint64_t)((src->tm_isdst == 0) ? 0 : (src->tm_isdst > 0) ? 1 : 2) << (62)));
 }
 
 /**
@@ -233,21 +240,22 @@ inline uint64_t _TM2U64(struct tm* src)
  */
 inline void _U642TM(struct tm* dst, const uint64_t src)
 {
-    aosDbgCheck(dst != NULL);
-
-    dst->tm_sec  = (src >> 0)  & 0x0000003F;
-    dst->tm_min  = (src >> 6)  & 0x0000003F;
-    dst->tm_hour = (src >> 12) & 0x0000001F;
-    dst->tm_mday = (src >> 17) & 0x0000001F;
-    dst->tm_mon  = (src >> 22) & 0x0000000F;
-    dst->tm_year = (src >> 26) & 0x00FFFFFF;
-    dst->tm_wday = (src >> 50) & 0x00000007;
-    dst->tm_yday = (src >> 53) & 0x000001FF;
-    dst->tm_isdst = (((src >> 62) & 0x03) == 0) ? 0 : (((src >> 62) & 0x03) > 0) ? 1 : -1;
-
-    return;
+  aosDbgCheck(dst != NULL);
+
+  dst->tm_sec  = (src >> 0)  & 0x0000003F;
+  dst->tm_min  = (src >> 6)  & 0x0000003F;
+  dst->tm_hour = (src >> 12) & 0x0000001F;
+  dst->tm_mday = (src >> 17) & 0x0000001F;
+  dst->tm_mon  = (src >> 22) & 0x0000000F;
+  dst->tm_year = (src >> 26) & 0x00FFFFFF;
+  dst->tm_wday = (src >> 50) & 0x00000007;
+  dst->tm_yday = (src >> 53) & 0x000001FF;
+  dst->tm_isdst = (((src >> 62) & 0x03) == 0) ? 0 : (((src >> 62) & 0x03) > 0) ? 1 : -1;
+
+  return;
 }
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
+
+#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
 /**
  * @brief   Implementation of the SSSP module stack initialization sequence (startup phase 3).
  *
@@ -257,67 +265,68 @@ inline void _U642TM(struct tm* dst, const uint64_t src)
  */
 aos_shutdown_t _ssspModuleStackInitialization(void)
 {
-    // local types
-    /**
+  // local types
+  /**
    * @brief   States for the internal state machine to implement SSSP startup stage 3.
    */
-    typedef enum {
-        STAGE_3_1,                  /**< Initiation of SSSP startup stage 3. */
-        STAGE_3_2,                  /**< Starting the sequence and broadcasting the first ID. */
-        STAGE_3_3_WAITFORFIRSTID,   /**< Waiting for first ID after initiation. */
-        STAGE_3_3_WAITFORIDORSIG,   /**< Waiting for next ID or activation of neighbor signal. */
-        STAGE_3_3_WAITFORID,        /**< Waiting for next ID (after the module has set its own ID). */
-        STAGE_3_4_FINISH,           /**< Successful finish of stage 3. */
-        STAGE_3_4_ABORT_ACTIVE,     /**< Aborting stage 3 (active). */
-        STAGE_3_4_ABORT,            /**< Aborting stage 3 (passive). */
-    } sssp_modulestackinitstage_t;
-
-    typedef struct {
-        bool loop     : 1;
-        bool wfe      : 1;
-        bool wfe_next : 1;
-    } flags_t;
-
-    // local variables
-    aos_shutdown_t shutdown = AOS_SHUTDOWN_NONE;
-    sssp_modulestackinitstage_t stage = STAGE_3_1;
-    eventmask_t eventmask = 0;
-    eventflags_t ioflags;
-    event_source_t eventSourceTimeout;
-    event_source_t eventSourceDelay;
-    event_listener_t eventListenerTimeout;
-    event_listener_t eventListenerDelay;
-    event_listener_t eventListenerCan;
-    virtual_timer_t timerTimeout;
-    virtual_timer_t timerDelay;
-    CANTxFrame canTxFrame;
-    CANRxFrame canRxFrame;
+  typedef enum {
+    STAGE_3_1,                  /**< Initiation of SSSP startup stage 3. */
+    STAGE_3_2,                  /**< Starting the sequence and broadcasting the first ID. */
+    STAGE_3_3_WAITFORFIRSTID,   /**< Waiting for first ID after initiation. */
+    STAGE_3_3_WAITFORIDORSIG,   /**< Waiting for next ID or activation of neighbor signal. */
+    STAGE_3_3_WAITFORID,        /**< Waiting for next ID (after the module has set its own ID). */
+    STAGE_3_4_FINISH,           /**< Successful finish of stage 3. */
+    STAGE_3_4_ABORT_ACTIVE,     /**< Aborting stage 3 (active). */
+    STAGE_3_4_ABORT,            /**< Aborting stage 3 (passive). */
+  } sssp_modulestackinitstage_t;
+
+  typedef struct {
+    bool loop     : 1;
+    bool wfe      : 1;
+    bool wfe_next : 1;
+  } flags_t;
+
+  // local variables
+  aos_shutdown_t shutdown = AOS_SHUTDOWN_NONE;
+  sssp_modulestackinitstage_t stage = STAGE_3_1;
+  eventmask_t eventmask = 0;
+  eventflags_t ioflags = 0;
+  event_source_t eventSourceTimeout;
+  event_source_t eventSourceDelay;
+  event_listener_t eventListenerTimeout;
+  event_listener_t eventListenerDelay;
+  event_listener_t eventListenerCan;
+  virtual_timer_t timerTimeout;
+  virtual_timer_t timerDelay;
+  CANTxFrame canTxFrame;
+  CANRxFrame canRxFrame;
 #if (AMIROOS_CFG_SSSP_STACK_START != true) || (AMIROOS_CFG_DBG == true)
-    aos_ssspmoduleid_t lastid = 0;
-#endif
-    flags_t flags;
-
-    // initialize local varibles
-    chEvtObjectInit(&eventSourceTimeout);
-    chEvtObjectInit(&eventSourceDelay);
-    chVTObjectInit(&timerTimeout);
-    chVTObjectInit(&timerDelay);
-    canTxFrame.RTR = CAN_RTR_DATA;
-    canTxFrame.IDE = CAN_IDE_STD;
-    flags.loop = true;
-    flags.wfe = false; // do not wait for events in the initial iteration of the FSM loop
-    flags.wfe_next = true;
-
-    // initialize system variables
-    aos.sssp.stage = AOS_SSSP_STARTUP_3_1;
-    aos.sssp.moduleId = 0;
-
-    // listen to events (timout, delay, CAN receive)
-    chEvtRegisterMask(&eventSourceTimeout, &eventListenerTimeout, TIMEOUTEVENT_MASK);
-    chEvtRegisterMask(&eventSourceDelay, &eventListenerDelay, DELAYEVENT_MASK);
-    chEvtRegisterMask(&MODULE_HAL_CAN.rxfull_event, &eventListenerCan, CANEVENT_MASK);
-
-    /*
+  aos_ssspmoduleid_t lastid = 0;
+#endif
+  flags_t flags;
+  aos_timestamp_t uptime;
+
+  // initialize local varibles
+  chEvtObjectInit(&eventSourceTimeout);
+  chEvtObjectInit(&eventSourceDelay);
+  chVTObjectInit(&timerTimeout);
+  chVTObjectInit(&timerDelay);
+  canTxFrame.RTR = CAN_RTR_DATA;
+  canTxFrame.IDE = CAN_IDE_STD;
+  flags.loop = true;
+  flags.wfe = false; // do not wait for events in the initial iteration of the FSM loop
+  flags.wfe_next = true;
+
+  // initialize system variables
+  aos.sssp.stage = AOS_SSSP_STARTUP_3_1;
+  aos.sssp.moduleId = 0;
+
+  // listen to events (timout, delay, CAN receive)
+  chEvtRegisterMask(&eventSourceTimeout, &eventListenerTimeout, TIMEOUTEVENT_MASK);
+  chEvtRegisterMask(&eventSourceDelay, &eventListenerDelay, DELAYEVENT_MASK);
+  chEvtRegisterMask(&MODULE_HAL_CAN.rxfull_event, &eventListenerCan, CANEVENT_MASK);
+
+  /*
    * FSM in a loop.
    *
    * This is a fully event-based FSM for the module stack initialization
@@ -344,894 +353,905 @@ aos_shutdown_t _ssspModuleStackInitialization(void)
    *  delays:     Depending on the current state, delays are required by SSSP
    *              for timing of the sequential activation of signals.
    */
-    aosDbgPrintf("SSSP stack initialization sequence:\n");
-    while (flags.loop) {
+  aosDbgPrintf("SSSP stack initialization sequence:\n");
+  while (flags.loop) {
 #if (AMIROOS_CFG_DBG == true)
-        switch (stage) {
-        case STAGE_3_1:
-            aosDbgPrintf(">>> 3-1\n");
-            break;
-        case STAGE_3_2:
-            aosDbgPrintf(">>> 3-2\n");
-            break;
-        case STAGE_3_3_WAITFORFIRSTID:
-            aosDbgPrintf(">>> 3-3 (1st ID)\n");
-            break;
-        case STAGE_3_3_WAITFORIDORSIG:
-            aosDbgPrintf(">>> 3-3 (ID/sig)\n");
-            break;
-        case STAGE_3_3_WAITFORID:
-            aosDbgPrintf(">>> 3-3 (ID)\n");
-            break;
-        case STAGE_3_4_FINISH:
-            aosDbgPrintf(">>> 3-4 (finish)\n");
-            break;
-        case STAGE_3_4_ABORT_ACTIVE:
-            aosDbgPrintf(">>> 3-4 (active abort)\n");
-            break;
-        case STAGE_3_4_ABORT:
-            aosDbgPrintf(">>> 3-4 (abort)\n");
-            break;
-        }
+    switch (stage) {
+      case STAGE_3_1:
+        aosDbgPrintf(">>> 3-1\n");
+        break;
+      case STAGE_3_2:
+        aosDbgPrintf(">>> 3-2\n");
+        break;
+      case STAGE_3_3_WAITFORFIRSTID:
+        aosDbgPrintf(">>> 3-3 (1st ID)\n");
+        break;
+      case STAGE_3_3_WAITFORIDORSIG:
+        aosDbgPrintf(">>> 3-3 (ID/sig)\n");
+        break;
+      case STAGE_3_3_WAITFORID:
+        aosDbgPrintf(">>> 3-3 (ID)\n");
+        break;
+      case STAGE_3_4_FINISH:
+        aosDbgPrintf(">>> 3-4 (finish)\n");
+        break;
+      case STAGE_3_4_ABORT_ACTIVE:
+        aosDbgPrintf(">>> 3-4 (active abort)\n");
+        break;
+      case STAGE_3_4_ABORT:
+        aosDbgPrintf(">>> 3-4 (abort)\n");
+        break;
+    }
 #endif
 
-        // reset wfe flag for the next iteration
-        flags.wfe_next = true;
+    // reset wfe flag for the next iteration
+    flags.wfe_next = true;
 
-        // waiting for events may be skipped
-        if (flags.wfe) {
-            // wait for any event to occur
-            aosDbgPrintf("WFE...");
-            eventmask = chEvtWaitAnyTimeout(ALL_EVENTS, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT));
-            aosDbgPrintf("\t0x%08X", eventmask);
-        } else {
-            aosDbgPrintf("WFE skipped");
-        }
-        aos_timestamp_t uptime;
-        aosSysGetUptime(&uptime);
-        aosDbgPrintf("\t%04ums\n", (uint32_t)(uptime / 1000));
+    // waiting for events (may be skipped)
+    if (flags.wfe) {
+      // wait for any event to occur
+      aosDbgPrintf("WFE...");
+      eventmask = chEvtWaitAnyTimeout(ALL_EVENTS, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT));
+      aosDbgPrintf("\t0x%08X", eventmask);
+    } else {
+      aosDbgPrintf("WFE skipped");
+      eventmask = 0;
+    }
+    aosSysGetUptime(&uptime);
+    aosDbgPrintf("\t%04ums\n", (uint32_t)(uptime / MICROSECONDS_PER_MILLISECOND));
 
-        /*
+    /*
      * execute some general tasks and high priority events
      */
-        // no event occurred at all
-        if ((flags.wfe) && (eventmask == 0)) {
-            aosDbgPrintf("ERR: no evt\n");
-            // enforce timeout event
-            chEvtBroadcast(&eventSourceTimeout);
-            continue;
-        }
-        // if an IO event occurred
-        if (eventmask & _eventListenerIO.events) {
-            ioflags = chEvtGetAndClearFlags(&_eventListenerIO);
-            aosDbgPrintf("INFO: IO evt (0x%08X)\n", ioflags);
-            // a power-down event occurred
-            if (ioflags & MODULE_SSSP_EVENTFLAGS_PD) {
-                aosDbgPrintf("PD evt\n");
-                // deactivate S and UP
-                apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
+    // no event occurred at all
+    if ((flags.wfe) && (eventmask == 0)) {
+      aosDbgPrintf("ERR: no evt\n");
+      // enforce timeout event
+      chEvtBroadcast(&eventSourceTimeout);
+      continue;
+    }
+    // if an IO event occurred
+    if (eventmask & _eventListenerIO.events) {
+      ioflags = chEvtGetAndClearFlags(&_eventListenerIO);
+      aosDbgPrintf("INFO: IO evt (0x%08X)\n", ioflags);
+      // a power-down event occurred
+      if (ioflags & MODULE_SSSP_EVENTFLAGS_PD) {
+        aosDbgPrintf("PD evt\n");
+        // deactivate S and UP
+        aosDbgPrintf("disabling S\n");
+        apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
 #if (AMIROOS_CFG_SSSP_STACK_END != true)
-                apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_OFF);
-#endif
-                // set shutdown flag and exit the loop
-                shutdown = AOS_SHUTDOWN_PASSIVE;
-                break;
-            }
-            // the S signal was deactivated
-            if (ioflags & MODULE_SSSP_EVENTFLAGS_SYNC) {
-                apalControlGpioState_t sstate;
-                apalControlGpioGet(&moduleSsspGpioSync, &sstate);
-                if (sstate == APAL_GPIO_OFF) {
-                    aosDbgPrintf("-S evt\n");
-                    // either finish or abort
-                    if ((stage == STAGE_3_3_WAITFORID) && (aos.sssp.moduleId != 0)) {
-                        stage = STAGE_3_4_FINISH;
-                    } else if (stage != STAGE_3_4_ABORT) {
-                        stage = STAGE_3_4_ABORT_ACTIVE;
-                    }
-                }
-            }
+        aosDbgPrintf("disabling UP\n");
+        apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_OFF);
+#endif
+        // set shutdown flag and exit the loop
+        shutdown = AOS_SHUTDOWN_PASSIVE;
+        break;
+      }
+      // the S signal was deactivated
+      if (ioflags & MODULE_SSSP_EVENTFLAGS_SYNC) {
+        apalControlGpioState_t sstate;
+        apalControlGpioGet(&moduleSsspGpioSync, &sstate);
+        if (sstate == APAL_GPIO_ON) {
+          aosDbgPrintf("S evt (enabled)\n");
+        } else {
+          aosDbgPrintf("S evt (disabled)\n");
+          // either finish or abort
+          if ((stage == STAGE_3_3_WAITFORID) && (aos.sssp.moduleId != 0)) {
+            stage = STAGE_3_4_FINISH;
+          } else if (stage != STAGE_3_4_ABORT) {
+            stage = STAGE_3_4_ABORT_ACTIVE;
+          }
         }
-        // an OS event occurred
-        if (eventmask & _eventListenerOS.events) {
-            aosDbgPrintf("WARN: OS evt\n");
-            // get the flags
-            eventflags_t oseventflags = chEvtGetAndClearFlags(&_eventListenerOS);
-            // there should be no OS events at this point
+      }
+    }
+    // an OS event occurred
+    if (eventmask & _eventListenerOS.events) {
+      aosDbgPrintf("WARN: OS evt\n");
+      // get the flags
+      eventflags_t oseventflags = chEvtGetAndClearFlags(&_eventListenerOS);
+      // there should be no OS events at this point
 #ifdef MODULE_SSSP_STARTUP_3_OSEVENT_HOOK
-            MODULE_SSSP_STARTUP_3_OSEVENT_HOOK(eventmask, eventflags);
+      MODULE_SSSP_STARTUP_3_OSEVENT_HOOK(eventmask, eventflags);
 #else
-            _unexpectedEventError(eventmask, oseventflags);
+      _unexpectedEventError(eventmask, oseventflags);
 #endif
-        }
-        // if a CAN event occurred
-        if ((eventmask & eventListenerCan.events)) {
-            // fetch message
-            if (flags.wfe) {
-                canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canRxFrame, TIME_IMMEDIATE);
-                aosDbgPrintf("CAN <- 0x%03X\n", canRxFrame.SID);
-            }
-            // identify and handle abort messgaes
-            if (canRxFrame.SID == SSSP_STACKINIT_CANMSGID_ABORT) {
-                stage = STAGE_3_4_ABORT;
-            }
-            // warn if a unexpected message was received
-            else if ((canRxFrame.SID != SSSP_STACKINIT_CANMSGID_INIT) &&
-                     (canRxFrame.SID != SSSP_STACKINIT_CANMSGID_MODULEID)) {
-                aosDbgPrintf("WARN: unknown msg\n");
-            }
-            // any further pending messages are fetched at the end of the loop
-        }
-        // if a timeout event occurred
-        if (eventmask & eventListenerTimeout.events) {
-            // is handled at the end of the loop (or must be cleared by FSM)
-        }
-        // if a delay event occurred
-        if (eventmask & eventListenerDelay.events) {
-            // is handled by FSM
-        }
+    }
+    // if a CAN event occurred
+    if ((eventmask & eventListenerCan.events)) {
+      aosDbgPrintf("CAN evt\n");
+      // fetch message
+      if (flags.wfe) {
+        canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canRxFrame, TIME_IMMEDIATE);
+        aosDbgPrintf("CAN <- 0x%03X\n", canRxFrame.SID);
+      }
+      // identify and handle abort messgaes
+      if (canRxFrame.SID == SSSP_STACKINIT_CANMSGID_ABORT) {
+        stage = STAGE_3_4_ABORT;
+      }
+      // warn if a unexpected message was received
+      else if ((canRxFrame.SID != SSSP_STACKINIT_CANMSGID_INIT) &&
+               (canRxFrame.SID != SSSP_STACKINIT_CANMSGID_MODULEID)) {
+        aosDbgPrintf("WARN: unknown msg\n");
+      }
+      // any further pending messages are fetched at the end of the loop
+    }
+    // if a timeout event occurred
+    if (eventmask & eventListenerTimeout.events) {
+      aosDbgPrintf("timeout evt\n");
+      // is handled at the end of the loop (or must be cleared by FSM)
+    }
+    // if a delay event occurred
+    if (eventmask & eventListenerDelay.events) {
+      aosDbgPrintf("delay evt\n");
+      // is handled by FSM
+    }
 
-        /*
+    /*
      * this is the actual FSM
      */
-        switch (stage) {
-        case STAGE_3_1:
-        {
-            aos.sssp.stage = AOS_SSSP_STARTUP_3_1;
+    switch (stage) {
+      case STAGE_3_1:
+      {
+        aos.sssp.stage = AOS_SSSP_STARTUP_3_1;
 
-            // there was no event at all (skipped wfe)
-            if (eventmask == 0 && flags.wfe == false) {
+        // there was no event at all (skipped wfe)
+        if (eventmask == 0 && flags.wfe == false) {
 #if (AMIROOS_CFG_SSSP_MASTER == true)
-                // initialize the stage by transmitting an according CAN message
-                aosDbgPrintf("CAN -> init\n");
-                canTxFrame.DLC = 0;
-                canTxFrame.SID = SSSP_STACKINIT_CANMSGID_INIT;
-                if (canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_IMMEDIATE) != MSG_OK) {
-                    chEvtBroadcast(&eventSourceTimeout);
-                    break;
-                }
-                // activate S
-                aosDbgPrintf("S+\n");
-                apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_ON);
+          // initialize the stage by transmitting an according CAN message
+          aosDbgPrintf("CAN -> init\n");
+          canTxFrame.DLC = 0;
+          canTxFrame.SID = SSSP_STACKINIT_CANMSGID_INIT;
+          if (canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_IMMEDIATE) != MSG_OK) {
+            chEvtBroadcast(&eventSourceTimeout);
+            break;
+          }
+          // activate S
+          aosDbgPrintf("enabling S\n");
+          apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_ON);
 #if (AMIROOS_CFG_SSSP_STACK_START == true)
-                // proceed immediately
-                stage = STAGE_3_2;
-                flags.wfe_next = false;
+          // proceed immediately
+          stage = STAGE_3_2;
+          flags.wfe_next = false;
 #else
-                // set the timeout timer
-                chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
-                // proceed
-                stage = STAGE_3_3_WAITFORFIRSTID;
+          // set the timeout timer
+          chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
+          // proceed
+          stage = STAGE_3_3_WAITFORFIRSTID;
 #endif
 #else
-                // set the timeout timer
-                chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
+          // set the timeout timer
+          chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
 #endif
-            }
+        }
 
 #if (AMIROOS_CFG_SSSP_MASTER != true)
-            // a CAN message was received
-            else if (eventmask & eventListenerCan.events) {
-                // if an initiation message was received
-                if (canRxFrame.DLC == 0 &&
-                        canRxFrame.RTR == CAN_RTR_DATA &&
-                        canRxFrame.IDE == CAN_IDE_STD &&
-                        canRxFrame.SID == SSSP_STACKINIT_CANMSGID_INIT) {
-                    aosDbgPrintf("init msg\n");
-                    // reset the timeout timer and clear pending flags
-                    chVTReset(&timerTimeout);
-                    chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
-                    eventmask &= ~(eventListenerTimeout.events);
-                    // activate S
-                    aosDbgPrintf("S+\n");
-                    apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_ON);
+        // a CAN message was received
+        else if (eventmask & eventListenerCan.events) {
+          // if an initiation message was received
+          if (canRxFrame.DLC == 0 &&
+              canRxFrame.RTR == CAN_RTR_DATA &&
+              canRxFrame.IDE == CAN_IDE_STD &&
+              canRxFrame.SID == SSSP_STACKINIT_CANMSGID_INIT) {
+            aosDbgPrintf("init msg\n");
+            // reset the timeout timer and clear pending flags
+            chVTReset(&timerTimeout);
+            chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
+            eventmask &= ~(eventListenerTimeout.events);
+            // activate S
+            aosDbgPrintf("enabling S\n");
+            apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_ON);
 #if (AMIROOS_CFG_SSSP_STACK_START == true)
-                    // proceed
-                    stage = STAGE_3_2;
-                    flags.wfe_next = false;
+            // proceed
+            stage = STAGE_3_2;
+            flags.wfe_next = false;
 #else
-                    // set the timeout timer
-                    chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
-                    // proceed
-                    stage = STAGE_3_3_WAITFORFIRSTID;
+            // set the timeout timer
+            chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
+            // proceed
+            stage = STAGE_3_3_WAITFORFIRSTID;
 #endif
-                }
-            }
+          }
+        }
 #endif
 
-            break;
-        } /* end of STAGE_3_1 */
+        break;
+      } /* end of STAGE_3_1 */
 
-        case STAGE_3_2:
-        {
+      case STAGE_3_2:
+      {
 #if (AMIROOS_CFG_SSSP_STACK_START == true)
-            aos.sssp.stage = AOS_SSSP_STARTUP_3_2;
-
-            // if this stage was just entered
-            if (flags.wfe == false) {
-                // set the module ID
-                aos.sssp.moduleId = 1;
-                // broadcast module ID
-                aosDbgPrintf("CAN -> ID (%u)\n", aos.sssp.moduleId);
-                canTxFrame.DLC = 4;
-                canTxFrame.SID = SSSP_STACKINIT_CANMSGID_MODULEID;
-                _serialize(canTxFrame.data8, aos.sssp.moduleId, 4);
-                if (canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_IMMEDIATE) != MSG_OK) {
-                    chEvtBroadcast(&eventSourceTimeout);
-                    break;
-                }
+        aos.sssp.stage = AOS_SSSP_STARTUP_3_2;
+
+        // if this stage was just entered
+        if (flags.wfe == false) {
+          // set the module ID
+          aos.sssp.moduleId = 1;
+          // broadcast module ID
+          aosDbgPrintf("CAN -> ID (%u)\n", aos.sssp.moduleId);
+          canTxFrame.DLC = 4;
+          canTxFrame.SID = SSSP_STACKINIT_CANMSGID_MODULEID;
+          _serialize(canTxFrame.data8, aos.sssp.moduleId, 4);
+          if (canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_IMMEDIATE) != MSG_OK) {
+            chEvtBroadcast(&eventSourceTimeout);
+            break;
+          }
 #if (AMIROOS_CFG_SSSP_STACK_START != true) || (AMIROOS_CFG_DBG == true)
-                lastid = aos.sssp.moduleId;
+          lastid = aos.sssp.moduleId;
 #endif
 #if (AMIROOS_CFG_SSSP_STACK_END == true)
-                // sequence is already over
-                // deactivate S
-                aosDbgPrintf("S-\n");
-                apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
-                // proceed
-                stage = STAGE_3_3_WAITFORID;
+          // sequence is already over
+          // deactivate S
+          aosDbgPrintf("disabling S\n");
+          apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
+          // proceed
+          stage = STAGE_3_3_WAITFORID;
 #else
-                // set the delay timer so the UP signal is activated later
-                chVTSet(&timerDelay, chTimeUS2I(AMIROOS_CFG_SSSP_SIGNALDELAY), _ssspTimerCallback, &eventSourceDelay);
+          // set the delay timer so the UP signal is activated later
+          chVTSet(&timerDelay, chTimeUS2I(AMIROOS_CFG_SSSP_SIGNALDELAY), _ssspTimerCallback, &eventSourceDelay);
 #endif
-            }
+        }
 
-            // if a delay event occurred
-            if (eventmask & eventListenerDelay.events) {
-                // activate UP
-                aosDbgPrintf("UP+\n");
-                apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_ON);
-                // deactivate S
-                aosDbgPrintf("S-\n");
-                apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
-                // explicitely clear timeout event flag
-                chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
-                eventmask &= ~(eventListenerTimeout.events);
-                // proceed
-                stage = STAGE_3_3_WAITFORID;
-            }
+        // if a delay event occurred
+        if (eventmask & eventListenerDelay.events) {
+          // activate UP
+          aosDbgPrintf("enabling UP\n");
+          apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_ON);
+          // deactivate S
+          aosDbgPrintf("disabling S\n");
+          apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
+          // explicitely clear timeout event flag
+          chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
+          eventmask &= ~(eventListenerTimeout.events);
+          // proceed
+          stage = STAGE_3_3_WAITFORID;
+        }
 #endif
 
-            break;
-        } /* end of STAGE_3_2 */
+        break;
+      } /* end of STAGE_3_2 */
 
-        case STAGE_3_3_WAITFORFIRSTID:
-        {
+      case STAGE_3_3_WAITFORFIRSTID:
+      {
 #if (AMIROOS_CFG_SSSP_STACK_START != true)
-            aos.sssp.stage = AOS_SSSP_STARTUP_3_3;
-
-            // a CAN message was received
-            if (eventmask & eventListenerCan.events) {
-                // if an ID message was received
-                if (canRxFrame.DLC == 4 &&
-                        canRxFrame.RTR == CAN_RTR_DATA &&
-                        canRxFrame.IDE == CAN_IDE_STD &&
-                        canRxFrame.SID == SSSP_STACKINIT_CANMSGID_MODULEID) {
-                    aosDbgPrintf("ID (%u)\n", (uint32_t)_deserialize(canRxFrame.data8, 4));
-                    // validate received ID
-                    if (lastid < _deserialize(canRxFrame.data8, 4)) {
-                        // store received ID
-                        lastid = _deserialize(canRxFrame.data8, 4);
-                        // restart timeout timer
-                        chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
-                        // proceed
-                        stage = STAGE_3_3_WAITFORIDORSIG;
-                    } else {
-                        aosDbgPrintf("ERR: invalid ID\n");
-                        // abort
-                        stage = STAGE_3_4_ABORT_ACTIVE;
-                        flags.wfe_next = false;
-                    }
-                    // explicitely clear timeout event flag
-                    chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
-                    eventmask &= ~(eventListenerTimeout.events);
-                }
+        aos.sssp.stage = AOS_SSSP_STARTUP_3_3;
+
+        // a CAN message was received
+        if (eventmask & eventListenerCan.events) {
+          // if an ID message was received
+          if (canRxFrame.DLC == 4 &&
+              canRxFrame.RTR == CAN_RTR_DATA &&
+              canRxFrame.IDE == CAN_IDE_STD &&
+              canRxFrame.SID == SSSP_STACKINIT_CANMSGID_MODULEID) {
+            aosDbgPrintf("ID (%u)\n", (uint32_t)_deserialize(canRxFrame.data8, 4));
+            // validate received ID
+            if (lastid < _deserialize(canRxFrame.data8, 4)) {
+              // store received ID
+              lastid = _deserialize(canRxFrame.data8, 4);
+              // restart timeout timer
+              chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
+              // proceed
+              stage = STAGE_3_3_WAITFORIDORSIG;
+            } else {
+              aosDbgPrintf("ERR: invalid ID\n");
+              // abort
+              stage = STAGE_3_4_ABORT_ACTIVE;
+              flags.wfe_next = false;
             }
+            // explicitely clear timeout event flag
+            chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
+            eventmask &= ~(eventListenerTimeout.events);
+          }
+        }
 #endif
-            break;
-        } /* end of STAGE_3_3_WAITFORFIRSTID */
+        break;
+      } /* end of STAGE_3_3_WAITFORFIRSTID */
 
-        case STAGE_3_3_WAITFORIDORSIG:
-        {
+      case STAGE_3_3_WAITFORIDORSIG:
+      {
 #if (AMIROOS_CFG_SSSP_STACK_START != true)
-            aos.sssp.stage = AOS_SSSP_STARTUP_3_3;
-
-            // a CAN message was received
-            if (eventmask & eventListenerCan.events) {
-                // if an ID message was received
-                if (canRxFrame.DLC == 4 &&
-                        canRxFrame.RTR == CAN_RTR_DATA &&
-                        canRxFrame.IDE == CAN_IDE_STD &&
-                        canRxFrame.SID == SSSP_STACKINIT_CANMSGID_MODULEID) {
-                    aosDbgPrintf("ID (%u)\n", (uint32_t)_deserialize(canRxFrame.data8, 4));
-                    // validate received ID
-                    if (lastid < _deserialize(canRxFrame.data8, 4)) {
-                        // store received ID
-                        lastid = _deserialize(canRxFrame.data8, 4);
-                        // restart timeout timer
-                        chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
-                    } else {
-                        aosDbgPrintf("ERR: invalid ID\n");
-                        // abort
-                        stage = STAGE_3_4_ABORT_ACTIVE;
-                        flags.wfe_next = false;
-                    }
-                    // explicitely clear timeout event flag
-                    chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
-                    eventmask &= ~(eventListenerTimeout.events);
-                }
+        aos.sssp.stage = AOS_SSSP_STARTUP_3_3;
+
+        // a CAN message was received
+        if (eventmask & eventListenerCan.events) {
+          // if an ID message was received
+          if (canRxFrame.DLC == 4 &&
+              canRxFrame.RTR == CAN_RTR_DATA &&
+              canRxFrame.IDE == CAN_IDE_STD &&
+              canRxFrame.SID == SSSP_STACKINIT_CANMSGID_MODULEID) {
+            aosDbgPrintf("ID (%u)\n", (uint32_t)_deserialize(canRxFrame.data8, 4));
+            // validate received ID
+            if (lastid < _deserialize(canRxFrame.data8, 4)) {
+              // store received ID
+              lastid = _deserialize(canRxFrame.data8, 4);
+              // restart timeout timer
+              chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
+            } else {
+              aosDbgPrintf("ERR: invalid ID\n");
+              // abort
+              stage = STAGE_3_4_ABORT_ACTIVE;
+              flags.wfe_next = false;
             }
+            // explicitely clear timeout event flag
+            chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
+            eventmask &= ~(eventListenerTimeout.events);
+          }
+        }
 
-            // if an IO event was received (DN signal)
-            if ((eventmask & _eventListenerIO.events) && (ioflags & MODULE_SSSP_EVENTFLAGS_DN)) {
-                aosDbgPrintf("DN <-\n");
-                // reset timeout timer
-                chVTReset(&timerTimeout);
-                chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
-                eventmask &= ~(eventListenerTimeout.events);
-                // increment and broadcast ID
-                aos.sssp.moduleId = lastid + 1;
-                aosDbgPrintf("CAN -> ID (%u)\n", aos.sssp.moduleId);
-                canTxFrame.DLC = 4;
-                canTxFrame.SID = SSSP_STACKINIT_CANMSGID_MODULEID;
-                _serialize(canTxFrame.data8, aos.sssp.moduleId, 4);
-                if (canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_IMMEDIATE) != MSG_OK) {
-                    chEvtBroadcast(&eventSourceTimeout);
-                    break;
-                }
-                // set delay timer
-                chVTSet(&timerDelay, chTimeUS2I(AMIROOS_CFG_SSSP_SIGNALDELAY), _ssspTimerCallback, &eventSourceDelay);
-            }
+        // if an IO event was received (DN signal)
+        if ((eventmask & _eventListenerIO.events) && (ioflags & MODULE_SSSP_EVENTFLAGS_DN)) {
+          aosDbgPrintf("DN evt\n");
+          // reset timeout timer
+          chVTReset(&timerTimeout);
+          chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
+          eventmask &= ~(eventListenerTimeout.events);
+          // increment and broadcast ID
+          aos.sssp.moduleId = lastid + 1;
+          aosDbgPrintf("CAN -> ID (%u)\n", aos.sssp.moduleId);
+          canTxFrame.DLC = 4;
+          canTxFrame.SID = SSSP_STACKINIT_CANMSGID_MODULEID;
+          _serialize(canTxFrame.data8, aos.sssp.moduleId, 4);
+          if (canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_IMMEDIATE) != MSG_OK) {
+            chEvtBroadcast(&eventSourceTimeout);
+            break;
+          }
+          // set delay timer
+          chVTSet(&timerDelay, chTimeUS2I(AMIROOS_CFG_SSSP_SIGNALDELAY), _ssspTimerCallback, &eventSourceDelay);
+        }
 
-            // if a delay event occurred
-            if (eventmask & eventListenerDelay.events) {
+        // if a delay event occurred
+        if (eventmask & eventListenerDelay.events) {
 #if (AMIROOS_CFG_SSSP_STACK_END != true)
-                // activate UP
-                aosDbgPrintf("UP+\n");
-                apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_ON);
-#endif
-                // deactivate S
-                aosDbgPrintf("S-\n");
-                apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
-                // reset the timeout timer
-                chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
-                chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
-                eventmask &= ~(eventListenerTimeout.events);
-                // proceed
-                stage = STAGE_3_3_WAITFORID;
-            }
+          // activate UP
+          aosDbgPrintf("enabling UP\n");
+          apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_ON);
+#endif
+          // deactivate S
+          aosDbgPrintf("disabling S\n");
+          apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
+          // reset the timeout timer
+          chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
+          chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
+          eventmask &= ~(eventListenerTimeout.events);
+          // proceed
+          stage = STAGE_3_3_WAITFORID;
+        }
 #endif
 
-            break;
-        } /* end of STAGE_3_3_WAITFORIDORSIG */
+        break;
+      } /* end of STAGE_3_3_WAITFORIDORSIG */
 
-        case STAGE_3_3_WAITFORID:
-        {
-            aos.sssp.stage = AOS_SSSP_STARTUP_3_3;
+      case STAGE_3_3_WAITFORID:
+      {
+        aos.sssp.stage = AOS_SSSP_STARTUP_3_3;
 
 #if (AMIROOS_CFG_SSSP_STACK_END != true)
-            // a CAN message was received
-            if (eventmask & eventListenerCan.events) {
-                // if an ID message was received
-                if (canRxFrame.DLC == 4 &&
-                        canRxFrame.RTR == CAN_RTR_DATA &&
-                        canRxFrame.IDE == CAN_IDE_STD &&
-                        canRxFrame.SID == SSSP_STACKINIT_CANMSGID_MODULEID) {
+        // a CAN message was received
+        if (eventmask & eventListenerCan.events) {
+          // if an ID message was received
+          if (canRxFrame.DLC == 4 &&
+              canRxFrame.RTR == CAN_RTR_DATA &&
+              canRxFrame.IDE == CAN_IDE_STD &&
+              canRxFrame.SID == SSSP_STACKINIT_CANMSGID_MODULEID) {
 #if (AMIROOS_CFG_SSSP_STACK_START != true) || (AMIROOS_CFG_DBG == true)
-                    // Plausibility of the received ID is not checked at this point but is done by other modules still in a previous stage.
-                    lastid = _deserialize(canRxFrame.data8, 4);
-                    aosDbgPrintf("ID (%u)\n", lastid);
-#endif
-                    // restart timeout timer
-                    chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
-                    chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
-                    eventmask &= ~(eventListenerTimeout.events);
-                }
-            }
+            // Plausibility of the received ID is not checked at this point but is done by other modules still in a previous stage.
+            lastid = _deserialize(canRxFrame.data8, 4);
+            aosDbgPrintf("ID (%u)\n", lastid);
+#endif
+            // restart timeout timer
+            chVTSet(&timerTimeout, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceTimeout);
+            chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
+            eventmask &= ~(eventListenerTimeout.events);
+          }
+        }
 #endif
 
-            break;
-        } /* end of STAGE_3_3_WAITFORID */
-
-        case STAGE_3_4_FINISH:
-        {
-            aos.sssp.stage = AOS_SSSP_STARTUP_3_4;
-
-            // if an IO event was received (S signal)
-            if ((eventmask & _eventListenerIO.events) && (ioflags & MODULE_SSSP_EVENTFLAGS_SYNC)) {
-                // reset the timeout timer
-                chVTReset(&timerTimeout);
-                chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
-                eventmask &= ~(eventListenerTimeout.events);
-                //set the delay timer
-                chVTSet(&timerDelay, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceDelay);
-            }
+        break;
+      } /* end of STAGE_3_3_WAITFORID */
 
-            // if a CAN event was received
-            if (eventmask & eventListenerCan.events) {
-                // if an abort message was received
-                if (canRxFrame.SID == SSSP_STACKINIT_CANMSGID_ABORT) {
-                    aosDbgPrintf("abort msg\n");
-                    // reset the delay timer
-                    chVTReset(&timerDelay);
-                    chEvtWaitAnyTimeout(eventListenerDelay.events, TIME_IMMEDIATE);
-                    eventmask &= ~(eventListenerDelay.events);
-                    // proceed
-                    stage = STAGE_3_4_ABORT;
-                }
-            }
+      case STAGE_3_4_FINISH:
+      {
+        aos.sssp.stage = AOS_SSSP_STARTUP_3_4;
 
-            // if a delay timer event occurred
-            if (eventmask & eventListenerDelay.events) {
-                aosDbgPrintf("sequence sucessful\n");
-                // sequence finished sucessfully
-                flags.loop = false;
-            }
+        // if an IO event was received (S signal)
+        if ((eventmask & _eventListenerIO.events) && (ioflags & MODULE_SSSP_EVENTFLAGS_SYNC)) {
+          // reset the timeout timer
+          chVTReset(&timerTimeout);
+          chEvtWaitAnyTimeout(eventListenerTimeout.events, TIME_IMMEDIATE);
+          eventmask &= ~(eventListenerTimeout.events);
+          //set the delay timer
+          chVTSet(&timerDelay, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT), _ssspTimerCallback, &eventSourceDelay);
+        }
 
-            break;
-        } /* end of STAGE_3_4_FINISH */
-
-        case STAGE_3_4_ABORT_ACTIVE:
-        {
-            aos.sssp.stage = AOS_SSSP_STARTUP_3_4;
-
-            // emit abort message
-            canTxFrame.DLC = 0;
-            canTxFrame.SID = SSSP_STACKINIT_CANMSGID_ABORT;
-            canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_INFINITE);
-            aosDbgPrintf("CAN -> abort\n");
-            // clear timeout flag
-            eventmask &= ~(eventListenerTimeout.events);
-            // proceed immediately
+        // if a CAN event was received
+        if (eventmask & eventListenerCan.events) {
+          // if an abort message was received
+          if (canRxFrame.SID == SSSP_STACKINIT_CANMSGID_ABORT) {
+            aosDbgPrintf("abort msg\n");
+            // reset the delay timer
+            chVTReset(&timerDelay);
+            chEvtWaitAnyTimeout(eventListenerDelay.events, TIME_IMMEDIATE);
+            eventmask &= ~(eventListenerDelay.events);
+            // proceed
             stage = STAGE_3_4_ABORT;
-            flags.wfe_next = false;
-            break;
-        } /* end of STAGE_3_4_ABORT_ACTIVE */
-
-        case STAGE_3_4_ABORT:
-        {
-            aos.sssp.stage = AOS_SSSP_STARTUP_3_4;
-
-            // deactivate S
-            aosDbgPrintf("S-\n");
-            apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
-            // invalidate module ID
-            aos.sssp.moduleId = 0;
-
-            // if an IO event was received (S signal)
-            if ((eventmask & _eventListenerIO.events) && (ioflags & MODULE_SSSP_EVENTFLAGS_SYNC)) {
-                aosDbgPrintf("sequence aborted\n");
-                // exit the sequence
-                flags.loop = false;
-            }
-
-            break;
-        } /* end of STAGE_3_4_ABORT */
+          }
         }
 
-        // fetch pending CAN message (if any)
-        if ((eventmask & eventListenerCan.events) && (canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canRxFrame, TIME_IMMEDIATE) == MSG_OK)) {
-            aosDbgPrintf("CAN <- 0x%03X\n", canRxFrame.SID);
-            flags.wfe_next = false;
+        // if a delay timer event occurred
+        if (eventmask & eventListenerDelay.events) {
+          aosDbgPrintf("sequence sucessful\n");
+          // sequence finished sucessfully
+          flags.loop = false;
         }
 
-        // handle unhandled timeout events
-        if (eventmask & eventListenerTimeout.events) {
-            aosDbgPrintf("ERR: timeout evt\n");
-            // abort
-            flags.wfe_next = false;
-            stage = STAGE_3_4_ABORT_ACTIVE;
+        break;
+      } /* end of STAGE_3_4_FINISH */
+
+      case STAGE_3_4_ABORT_ACTIVE:
+      {
+        aos.sssp.stage = AOS_SSSP_STARTUP_3_4;
+
+        // emit abort message
+        canTxFrame.DLC = 0;
+        canTxFrame.SID = SSSP_STACKINIT_CANMSGID_ABORT;
+        canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canTxFrame, TIME_INFINITE);
+        aosDbgPrintf("CAN -> abort\n");
+        // clear timeout flag
+        eventmask &= ~(eventListenerTimeout.events);
+        // proceed immediately
+        stage = STAGE_3_4_ABORT;
+        flags.wfe_next = false;
+        break;
+      } /* end of STAGE_3_4_ABORT_ACTIVE */
+
+      case STAGE_3_4_ABORT:
+      {
+        aos.sssp.stage = AOS_SSSP_STARTUP_3_4;
+
+        // deactivate S
+        aosDbgPrintf("disabling SYNC\n");
+        apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
+        // invalidate module ID
+        aos.sssp.moduleId = 0;
+
+        // if an IO event was received (S signal)
+        if ((eventmask & _eventListenerIO.events) && (ioflags & MODULE_SSSP_EVENTFLAGS_SYNC)) {
+          aosDbgPrintf("sequence aborted\n");
+          // exit the sequence
+          flags.loop = false;
         }
 
-        // apply wfe value for next iteration
-        flags.wfe = flags.wfe_next;
-    } /* end of FSM loop */
-    aosDbgPrintf("\n");
+        break;
+      } /* end of STAGE_3_4_ABORT */
+    } /* end of switch(stage) */
 
-    // unregister all events (timeout, delay, CAN receive)
-    chEvtUnregister(&eventSourceTimeout, &eventListenerTimeout);
-    chEvtUnregister(&eventSourceDelay, &eventListenerDelay);
-    chEvtUnregister(&MODULE_HAL_CAN.rxfull_event, &eventListenerCan);
-    // clear any pending events (timeout, delay, CAN receive)
-    chEvtWaitAllTimeout(TIMEOUTEVENT_MASK | DELAYEVENT_MASK | CANEVENT_MASK, TIME_IMMEDIATE);
+    // fetch pending CAN message (if any)
+    if ((eventmask & eventListenerCan.events) && (canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canRxFrame, TIME_IMMEDIATE) == MSG_OK)) {
+      aosDbgPrintf("CAN <- 0x%03X\n", canRxFrame.SID);
+      flags.wfe_next = false;
+    }
+
+    // handle unhandled timeout events
+    if (eventmask & eventListenerTimeout.events) {
+      aosDbgPrintf("ERR: timeout evt\n");
+      // abort
+      flags.wfe_next = false;
+      stage = STAGE_3_4_ABORT_ACTIVE;
+    }
 
-    // reset all control signals
+    // apply wfe value for next iteration
+    flags.wfe = flags.wfe_next;
+  } /* end of FSM loop */
+
+  // unregister all events (timeout, delay, CAN receive)
+  chEvtUnregister(&eventSourceTimeout, &eventListenerTimeout);
+  chEvtUnregister(&eventSourceDelay, &eventListenerDelay);
+  chEvtUnregister(&MODULE_HAL_CAN.rxfull_event, &eventListenerCan);
+  // clear any pending events (timeout, delay, CAN receive)
+  chEvtWaitAllTimeout(TIMEOUTEVENT_MASK | DELAYEVENT_MASK | CANEVENT_MASK, TIME_IMMEDIATE);
+
+  // reset all control signals
 #if (AMIROOS_CFG_SSSP_STACK_END != true)
-    apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_OFF);
+  aosDbgPrintf("disabling UP\n");
+  apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_OFF);
 #endif
-    apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
+  aosDbgPrintf("disabling S\n");
+  apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
+  aosSysGetUptime(&uptime);
+  aosDbgPrintf("done\t%04ums\n", (uint32_t)(uptime / MICROSECONDS_PER_MILLISECOND));
 
-    return shutdown;
+  return shutdown;
 }
-#endif
+#endif /* AMIROOS_CFG_SSSP_ENABLE == true */
+
 /**
  * @brief   Application entry point.
  */
 int main(void)
 {
-    // local variables
-    eventmask_t eventmask = 0;
-    eventflags_t eventflags = 0;
-    aos_shutdown_t shutdown = AOS_SHUTDOWN_NONE;
+  // local variables
+  eventmask_t eventmask = 0;
+  eventflags_t eventflags = 0;
+  eventflags_t ioeventflagsmask = AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK;
+  aos_shutdown_t shutdown = AOS_SHUTDOWN_NONE;
 #if defined(AMIROOS_CFG_MAIN_EXTRA_THREAD_VARIABLES)
-    AMIROOS_CFG_MAIN_EXTRA_THREAD_VARIABLES
-        #endif
-
-            /*
-           * ##########################################################################
-           * # system initialization                                                  #
-           * ##########################################################################
-           */
-
-        #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_0)
-        #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_0_ARGS)
-            AMIROOS_CFG_MAIN_INIT_HOOK_0(AMIROOS_CFG_MAIN_INIT_HOOK_0_ARGS);
+  AMIROOS_CFG_MAIN_EXTRA_THREAD_VARIABLES
+#endif
+
+  /*
+   * ##########################################################################
+   * # system initialization                                                  #
+   * ##########################################################################
+   */
+
+#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_0)
+#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_0_ARGS)
+  AMIROOS_CFG_MAIN_INIT_HOOK_0(AMIROOS_CFG_MAIN_INIT_HOOK_0_ARGS);
 #else
-            AMIROOS_CFG_MAIN_INIT_HOOK_0();
+  AMIROOS_CFG_MAIN_INIT_HOOK_0();
 #endif
 #endif
 
-    /* hardware, kernel, and operating system initialization */
-    // ChibiOS/HAL and custom hal additions (if any)
-    halInit();
+  /* hardware, kernel, and operating system initialization */
+  // ChibiOS/HAL and custom hal additions (if any)
+  halInit();
 #ifdef MODULE_INIT_HAL_EXTRA
-    MODULE_INIT_HAL_EXTRA();
+  MODULE_INIT_HAL_EXTRA();
 #endif
 
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_1)
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS)
-    AMIROOS_CFG_MAIN_INIT_HOOK_1(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS);
+  AMIROOS_CFG_MAIN_INIT_HOOK_1(AMIROOS_CFG_MAIN_INIT_HOOK_1_ARGS);
 #else
-    AMIROOS_CFG_MAIN_INIT_HOOK_1();
+  AMIROOS_CFG_MAIN_INIT_HOOK_1();
 #endif
 #endif
 
-    // ChibiOS/RT kernel and custom kernel additions (if any)
-    chSysInit();
+  // ChibiOS/RT kernel and custom kernel additions (if any)
+  chSysInit();
 #ifdef MODULE_INIT_KERNEL_EXTRA
-    MODULE_INIT_KERNEL_EXTRA();
+  MODULE_INIT_KERNEL_EXTRA();
 #endif
 
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_2)
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS)
-    AMIROOS_CFG_MAIN_INIT_HOOK_2(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS);
+  AMIROOS_CFG_MAIN_INIT_HOOK_2(AMIROOS_CFG_MAIN_INIT_HOOK_2_ARGS);
 #else
-    AMIROOS_CFG_MAIN_INIT_HOOK_2();
+  AMIROOS_CFG_MAIN_INIT_HOOK_2();
 #endif
 #endif
 
-    // AMiRo-OS and custom OS additions (if any)
+  // AMiRo-OS and custom OS additions (if any)
 #if (AMIROOS_CFG_SHELL_ENABLE == true)
-    aosSysInit(moduleShellPrompt);
+  aosSysInit(moduleShellPrompt);
 #else
-    aosSysInit();
+  aosSysInit();
 #endif
 #ifdef MODULE_INIT_OS_EXTRA
-    MODULE_INIT_OS_EXTRA();
+  MODULE_INIT_OS_EXTRA();
 #endif
 
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_3)
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS)
-    AMIROOS_CFG_MAIN_INIT_HOOK_3(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS);
+  AMIROOS_CFG_MAIN_INIT_HOOK_3(AMIROOS_CFG_MAIN_INIT_HOOK_3_ARGS);
 #else
-    AMIROOS_CFG_MAIN_INIT_HOOK_3();
+  AMIROOS_CFG_MAIN_INIT_HOOK_3();
 #endif
 #endif
 
 #if (AMIROOS_CFG_TESTS_ENABLE == true)
 #if defined(MODULE_INIT_TESTS)
-    MODULE_INIT_TESTS();
+  MODULE_INIT_TESTS();
 #else
-#warning "MODULE_INIT_TESTS not defined"
+  #warning "MODULE_INIT_TESTS() not defined"
 #endif
 #endif
 
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_4)
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS)
-    AMIROOS_CFG_MAIN_INIT_HOOK_4(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS);
+  AMIROOS_CFG_MAIN_INIT_HOOK_4(AMIROOS_CFG_MAIN_INIT_HOOK_4_ARGS);
 #else
-    AMIROOS_CFG_MAIN_INIT_HOOK_4();
+  AMIROOS_CFG_MAIN_INIT_HOOK_4();
 #endif
 #endif
 
+  /* event associations */
 #if (AMIROOS_CFG_SSSP_ENABLE == true)
-    /* event associations */
-#if (AMIROOS_CFG_SSSP_STACK_START == true) && (AMIROOS_CFG_SSSP_STACK_END == true)
-    chEvtRegisterMaskWithFlags(&aos.events.io, &_eventListenerIO, IOEVENT_MASK, MODULE_SSSP_EVENTFLAGS_PD | MODULE_SSSP_EVENTFLAGS_SYNC);
-#elif (AMIROOS_CFG_SSSP_STACK_START == true)
-    chEvtRegisterMaskWithFlags(&aos.events.io, &_eventListenerIO, IOEVENT_MASK, MODULE_SSSP_EVENTFLAGS_PD | MODULE_SSSP_EVENTFLAGS_SYNC | MODULE_SSSP_EVENTFLAGS_UP);
-#elif (AMIROOS_CFG_SSSP_STACK_END == true)
-    chEvtRegisterMaskWithFlags(&aos.events.io, &_eventListenerIO, IOEVENT_MASK, MODULE_SSSP_EVENTFLAGS_PD | MODULE_SSSP_EVENTFLAGS_SYNC | MODULE_SSSP_EVENTFLAGS_DN);
-#else
-    chEvtRegisterMaskWithFlags(&aos.events.io, &_eventListenerIO, IOEVENT_MASK, MODULE_SSSP_EVENTFLAGS_PD | MODULE_SSSP_EVENTFLAGS_SYNC | MODULE_SSSP_EVENTFLAGS_DN | MODULE_SSSP_EVENTFLAGS_UP);
+  ioeventflagsmask |= MODULE_SSSP_EVENTFLAGS_PD | MODULE_SSSP_EVENTFLAGS_SYNC;
+#if (AMIROOS_CFG_SSSP_STACK_START != true)
+  ioeventflagsmask |= MODULE_SSSP_EVENTFLAGS_DN;
 #endif
-#endif // end of AMIROOS_CFG_SSSP_ENABLE condition
-    chEvtRegisterMask(&aos.events.os, &_eventListenerOS, OSEVENT_MASK);
+#if (AMIROOS_CFG_SSSP_STACK_END != true)
+  ioeventflagsmask |= MODULE_SSSP_EVENTFLAGS_UP;
+#endif
+#endif /* AMIROOS_CFG_SSSP_ENABLE == true */
+  if (ioeventflagsmask != 0) {
+    chEvtRegisterMaskWithFlags(&aos.events.io, &_eventListenerIO, IOEVENT_MASK, ioeventflagsmask);
+  }
+  chEvtRegisterMask(&aos.events.os, &_eventListenerOS, OSEVENT_MASK);
 
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_5)
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS)
-    AMIROOS_CFG_MAIN_INIT_HOOK_5(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS);
+  AMIROOS_CFG_MAIN_INIT_HOOK_5(AMIROOS_CFG_MAIN_INIT_HOOK_5_ARGS);
 #else
-    AMIROOS_CFG_MAIN_INIT_HOOK_5();
+  AMIROOS_CFG_MAIN_INIT_HOOK_5();
 #endif
 #endif
 
-    /* periphery communication initialization */
-    // CAN (mandatory)
-    canStart(&MODULE_HAL_CAN, &moduleHalCanConfig);
-
-    // module specific initialization (if any)
+  /* periphery communication initialization */
+  // CAN (mandatory)
+  canStart(&MODULE_HAL_CAN, &moduleHalCanConfig);
+  // module specific initialization (if any)
 #ifdef MODULE_INIT_PERIPHERY_COMM
-    MODULE_INIT_PERIPHERY_COMM();
+  MODULE_INIT_PERIPHERY_COMM();
 #endif
-    // user interface (if any)
+  // user interface (if any)
 #ifdef MODULE_HAL_PROGIF
-    aosIOChannelInit(&_stdiochannel, (BaseAsynchronousChannel*)&MODULE_HAL_PROGIF);
-    aosIOChannelOutputEnable(&_stdiochannel);
-    aosIOStreamAddChannel(&aos.iostream, &_stdiochannel);
+  aosIOChannelInit(&_stdiochannel, (BaseAsynchronousChannel*)&MODULE_HAL_PROGIF);
+  aosIOChannelOutputEnable(&_stdiochannel);
+  aosIOStreamAddChannel(&aos.iostream, &_stdiochannel);
 #if (AMIROOS_CFG_SHELL_ENABLE == true)
-    aosShellChannelInit(&_stdshellchannel, (BaseAsynchronousChannel*)&MODULE_HAL_PROGIF);
-    aosShellChannelInputEnable(&_stdshellchannel);
-    aosShellChannelOutputEnable(&_stdshellchannel);
-    aosShellStreamAddChannel(&aos.shell.stream, &_stdshellchannel);
+  aosShellChannelInit(&_stdshellchannel, (BaseAsynchronousChannel*)&MODULE_HAL_PROGIF);
+  aosShellChannelInputEnable(&_stdshellchannel);
+  aosShellChannelOutputEnable(&_stdshellchannel);
+  aosShellStreamAddChannel(&aos.shell.stream, &_stdshellchannel);
 #endif
 #endif
 
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_6)
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_6_ARGS)
-    AMIROOS_CFG_MAIN_INIT_HOOK_6(AMIROOS_CFG_MAIN_INIT_HOOK_6_ARGS);
+  AMIROOS_CFG_MAIN_INIT_HOOK_6(AMIROOS_CFG_MAIN_INIT_HOOK_6_ARGS);
 #else
-    AMIROOS_CFG_MAIN_INIT_HOOK_6();
-#endif
-#endif
-    //  for (unsigned int hase = 0; hase < 10; ++hase) {
-    //      //toggle LED
-    //      palClearLine(LINE_LED_GREEN);
-    //      chThdSleepMilliseconds(1500);
-    //      palSetLine(LINE_LED_GREEN);
-    //      chThdSleepMilliseconds(500);
-    //  }
-    //  chprintf((BaseSequentialStream*)&SD2, "Hallo Welt!\n");
-
-    /* module is ready -> print welcome prompt */
-    aosprintf("\n");
-    aosprintf("######################################################################\n");
-    aosprintf("# AMiRo-OS is an operating system designed for the Autonomous Mini   #\n");
-    aosprintf("# Robot (AMiRo) platform.                                            #\n");
-    aosprintf("# Copyright (C) 2016..2018  Thomas Schöpping et al.                  #\n");
-    aosprintf("#                                                                    #\n");
-    aosprintf("# This is free software; see the source for copying conditions.      #\n");
-    aosprintf("# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR  #\n");
-    aosprintf("# A PARTICULAR PURPOSE.                                              #\n");
-    aosprintf("# The development of this software was supported by the Excellence   #\n");
-    aosprintf("# Cluster EXC 227 Cognitive Interaction Technology. The Excellence   #\n");
-    aosprintf("# Cluster EXC 227 is a grant of the Deutsche Forschungsgemeinschaft  #\n");
-    aosprintf("# (DFG) in the context of the German Excellence Initiative.          #\n");
-    aosprintf("######################################################################\n");
-    aosprintf("\n");
+  AMIROOS_CFG_MAIN_INIT_HOOK_6();
+#endif
+#endif
+
+  /* module is ready -> print welcome prompt */
+  aosprintf("\n");
+  aosprintf("######################################################################\n");
+  aosprintf("# AMiRo-OS is an operating system designed for the Autonomous Mini   #\n");
+  aosprintf("# Robot (AMiRo) platform.                                            #\n");
+  aosprintf("# Copyright (C) 2016..2019  Thomas Schöpping et al.                  #\n");
+  aosprintf("#                                                                    #\n");
+  aosprintf("# This is free software; see the source for copying conditions.      #\n");
+  aosprintf("# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR  #\n");
+  aosprintf("# A PARTICULAR PURPOSE.                                              #\n");
+  aosprintf("# The development of this software was supported by the Excellence   #\n");
+  aosprintf("# Cluster EXC 227 Cognitive Interaction Technology. The Excellence   #\n");
+  aosprintf("# Cluster EXC 227 is a grant of the Deutsche Forschungsgemeinschaft  #\n");
+  aosprintf("# (DFG) in the context of the German Excellence Initiative.          #\n");
+  aosprintf("######################################################################\n");
+  aosprintf("\n");
 
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_7)
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_7_ARGS)
-    AMIROOS_CFG_MAIN_INIT_HOOK_7(AMIROOS_CFG_MAIN_INIT_HOOK_7_ARGS);
+  AMIROOS_CFG_MAIN_INIT_HOOK_7(AMIROOS_CFG_MAIN_INIT_HOOK_7_ARGS);
 #else
-    AMIROOS_CFG_MAIN_INIT_HOOK_7();
-#endif //AMIROOS_CFG_MAIN_INIT_HOOK_7
-#endif //AMIROOS_CFG_MAIN_INIT_HOOK_7_ARGS
+  AMIROOS_CFG_MAIN_INIT_HOOK_7();
+#endif
+#endif
 
 #if (AMIROOS_CFG_SSSP_ENABLE == true)
-    /* SSSP startup OS synchronization phase (end of startup stage 2) */
-    while ((shutdown == AOS_SHUTDOWN_NONE) && (eventmask = aosSysSsspStartupOsInitSyncCheck(&_eventListenerIO)) != 0) {
-        /*
+  /* SSSP startup OS synchronization phase (end of startup stage 2) */
+  while ((shutdown == AOS_SHUTDOWN_NONE) && (eventmask = aosSysSsspStartupOsInitSyncCheck(&_eventListenerIO)) != 0) {
+    /*
      * This code is executed if the received event was not about the SYS_SYNC control signal.
      * The returned event could be caused by any listener (not only the argument).
      */
-        // IO event
-        if (eventmask & _eventListenerIO.events) {
-            eventflags = chEvtGetAndClearFlags(&_eventListenerIO);
-            // PD event
-            if (eventflags & MODULE_SSSP_EVENTFLAGS_PD) {
-                shutdown = AOS_SHUTDOWN_PASSIVE;
-            } else {
+    // IO event
+    if (eventmask & _eventListenerIO.events) {
+      eventflags = chEvtGetAndClearFlags(&_eventListenerIO);
+      // PD event
+      if (eventflags & MODULE_SSSP_EVENTFLAGS_PD) {
+        shutdown = AOS_SHUTDOWN_PASSIVE;
+      } else {
 #ifdef MODULE_SSSP_STARTUP_2_2_IOEVENT_HOOK
-                MODULE_SSSP_STARTUP_2_2_IOEVENT_HOOK(eventmask, eventflags);
+        MODULE_SSSP_STARTUP_2_2_IOEVENT_HOOK(eventmask, eventflags);
 #else
-                // ignore any other IO events
+        // ignore any other IO events
 #endif
-
-            }
-
-        }
-        // OS event
-        else if (eventmask & _eventListenerOS.events) {
-            eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
-            _unexpectedEventError(eventmask, eventflags);
-        }
-        // unknown event
-        else {
-            _unexpectedEventError(eventmask, 0);
-        }
+      }
     }
-#endif //AMIROOS_CFG_SSSP_ENABLE
-    /*
+    // OS event
+    else if (eventmask & _eventListenerOS.events) {
+      eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
+      _unexpectedEventError(eventmask, eventflags);
+    }
+    // unknown event
+    else {
+      _unexpectedEventError(eventmask, 0);
+    }
+  }
+
+  /*
    * There must be no delays at this point, thus no hook is allowed.
    */
 
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
-    /* SSSP startup stage 3 (module stack initialization) */
-    if (shutdown == AOS_SHUTDOWN_NONE) {
-        shutdown = _ssspModuleStackInitialization();
-    }
-#endif //AMIROOS_CFG_SSSP_ENABLE
+  /* SSSP startup stage 3 (module stack initialization) */
+  if (shutdown == AOS_SHUTDOWN_NONE) {
+    shutdown = _ssspModuleStackInitialization();
+  }
+#endif /* AMIROOS_CFG_SSSP_ENABLE == true */
 
-    /*
+  /*
    * There must be no delays at this point, thus no hook is allowed.
    */
+
 #if (AMIROOS_CFG_SSSP_ENABLE == true)
-    /* synchronize calendars */
-    if (shutdown == AOS_SHUTDOWN_NONE) {
+  /* synchronize calendars */
+  if (shutdown == AOS_SHUTDOWN_NONE) {
 #if (AMIROOS_CFG_SSSP_MASTER == true)
-        CANTxFrame frame;
-        struct tm t;
-        uint64_t encoded;
-
-        frame.DLC = 8;
-        frame.RTR = CAN_RTR_DATA;
-        frame.IDE = CAN_IDE_STD;
-        frame.SID = CALENDERSYNC_CANMSGID;
-
-        aosDbgPrintf("transmitting current date/time...\t");
-        // get current date & time
-        aosSysGetDateTime(&t);
-        // encode
-        encoded = _TM2U64(&t);
-        // serialize
-        _serialize(frame.data8, encoded, 8);
-        // transmit
-        canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &frame, TIME_IMMEDIATE);
-
-        aosDbgPrintf("done\n");
+    CANTxFrame frame;
+    struct tm t;
+    uint64_t encoded;
+
+    frame.DLC = 8;
+    frame.RTR = CAN_RTR_DATA;
+    frame.IDE = CAN_IDE_STD;
+    frame.SID = CALENDERSYNC_CANMSGID;
+
+    aosDbgPrintf("transmitting current date/time...\t");
+    // get current date & time
+    aosSysGetDateTime(&t);
+    // encode
+    encoded = _TM2U64(&t);
+    // serialize
+    _serialize(frame.data8, encoded, 8);
+    // transmit
+    canTransmitTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &frame, TIME_IMMEDIATE);
+
+    aosDbgPrintf("done\n");
+#else /* AMIROOS_CFG_SSSP_MASTER == false */
+    CANRxFrame frame;
+    uint64_t encoded;
+    struct tm t;
+
+    aosDbgPrintf("receiving current date/time...\t");
+    // receive message
+#if (AMIROOS_CFG_DBG == true)
+    // increase timeout in debug mode due to additional delays introduced by the many prinf() calls
+    if (canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &frame, chTimeUS2I(10 * AOS_SYSTEM_SSSP_TIMEOUT)) == MSG_OK) {
 #else
-        CANRxFrame frame;
-        uint64_t encoded;
-        struct tm t;
-
-        aosDbgPrintf("receiving current date/time...\t");
-        // receive message
-        if (canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &frame, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT)) == MSG_OK) {
-            // validate message
-            if (frame.DLC == 8 &&
-                    frame.RTR == CAN_RTR_DATA &&
-                    frame.IDE == CAN_IDE_STD &&
-                    frame.SID == CALENDERSYNC_CANMSGID) {
-                // deserialize
-                encoded = _deserialize(frame.data8, 8);
-                // decode
-                _U642TM(&t, encoded);
-                // set current date & time
-                aosSysSetDateTime(&t);
-                aosDbgPrintf("success\n");
-            } else {
-                aosDbgPrintf("fail (invalid message)\n");
-            }
-        } else {
-            aosDbgPrintf("fail (timeout)\n");
-        }
-#endif //AMIROOS_CFG_SSSP_MASTER
-        aosDbgPrintf("\n");
+    if (canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &frame, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT)) == MSG_OK) {
+#endif
+      // validate message
+      if (frame.DLC == 8 &&
+          frame.RTR == CAN_RTR_DATA &&
+          frame.IDE == CAN_IDE_STD &&
+          frame.SID == CALENDERSYNC_CANMSGID) {
+        // deserialize
+        encoded = _deserialize(frame.data8, 8);
+        // decode
+        _U642TM(&t, encoded);
+        // set current date & time
+        aosSysSetDateTime(&t);
+        aosDbgPrintf("success\n");
+      } else {
+        aosDbgPrintf("fail (invalid message)\n");
+      }
+    } else {
+      aosDbgPrintf("fail (timeout)\n");
     }
-#endif //AMIROOS_CFG_SSSP_ENABLE
-aosprintf("Line 1123\n");
-#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_8)
+#endif /* AMIROOS_CFG_SSSP_MASTER == false */
+    aosDbgPrintf("\n");
+  }
+#endif /* AMIROOS_CFG_SSSP_ENABLE == true */
 
+#if defined(AMIROOS_CFG_MAIN_INIT_HOOK_8)
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_8_ARGS)
-    AMIROOS_CFG_MAIN_INIT_HOOK_8(AMIROOS_CFG_MAIN_INIT_HOOK_8_ARGS);
+  AMIROOS_CFG_MAIN_INIT_HOOK_8(AMIROOS_CFG_MAIN_INIT_HOOK_8_ARGS);
 #else
-    AMIROOS_CFG_MAIN_INIT_HOOK_8();
-#endif //AMIROOS_CFG_MAIN_INIT_HOOK_8_ARGS
+  AMIROOS_CFG_MAIN_INIT_HOOK_8();
+#endif
 #endif
 
-
-
-    aosprintf("aosSysStart \n");
-    /* completely start AMiRo-OS */
-    if (shutdown == AOS_SHUTDOWN_NONE) {
-        aosSysStart();
-    }
-    aosprintf("aosSysStart done \n");
+  /* completely start AMiRo-OS */
+  if (shutdown == AOS_SHUTDOWN_NONE) {
+    aosSysStart();
+  }
 
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_9)
 #if defined(AMIROOS_CFG_MAIN_INIT_HOOK_9_ARGS)
-    AMIROOS_CFG_MAIN_INIT_HOOK_9(AMIROOS_CFG_MAIN_INIT_HOOK_9_ARGS);
+  AMIROOS_CFG_MAIN_INIT_HOOK_9(AMIROOS_CFG_MAIN_INIT_HOOK_9_ARGS);
 #else
-    AMIROOS_CFG_MAIN_INIT_HOOK_9();
+  AMIROOS_CFG_MAIN_INIT_HOOK_9();
 #endif
 #endif
 
-    /*
+  /*
    * ##########################################################################
    * # infinite loop                                                          #
    * ##########################################################################
    */
 
-    // sleep until a shutdown event is received
-    while (shutdown == AOS_SHUTDOWN_NONE) {
-        // wait for an event
+  // sleep until a shutdown event is received
+  while (shutdown == AOS_SHUTDOWN_NONE) {
+    // wait for an event
 #if (AMIROOS_CFG_MAIN_LOOP_TIMEOUT != 0)
-        eventmask = chEvtWaitOneTimeout(ALL_EVENTS, chTimeUS2I(AMIROOS_CFG_MAIN_LOOP_TIMEOUT));
+    eventmask = chEvtWaitOneTimeout(ALL_EVENTS, chTimeUS2I(AMIROOS_CFG_MAIN_LOOP_TIMEOUT));
 #else
-        eventmask = chEvtWaitOne(ALL_EVENTS);
+    eventmask = chEvtWaitOne(ALL_EVENTS);
 #endif
 
 #if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_0)
 #if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_0_ARGS)
-        AMIROOS_CFG_MAIN_LOOP_HOOK_0(AMIROOS_CFG_MAIN_LOOP_HOOK_0_ARGS);
+    AMIROOS_CFG_MAIN_LOOP_HOOK_0(AMIROOS_CFG_MAIN_LOOP_HOOK_0_ARGS);
 #else
-        AMIROOS_CFG_MAIN_LOOP_HOOK_0();
+    AMIROOS_CFG_MAIN_LOOP_HOOK_0();
 #endif
 #endif
 
-
-        switch (eventmask) {
-        // if this was an I/O event
-        case IOEVENT_MASK:
-            // evaluate flags
-            eventflags = chEvtGetAndClearFlags(&_eventListenerIO);
-            // PD event
+    switch (eventmask) {
+      // if this was an I/O event
+      case IOEVENT_MASK:
+        // evaluate flags
+        eventflags = chEvtGetAndClearFlags(&_eventListenerIO);
 #if (AMIROOS_CFG_SSSP_ENABLE == true)
-            if (eventflags & MODULE_SSSP_EVENTFLAGS_PD) {
-                shutdown = AOS_SHUTDOWN_PASSIVE;
-            }
+        // PD event
+        if (eventflags & MODULE_SSSP_EVENTFLAGS_PD) {
+          shutdown = AOS_SHUTDOWN_PASSIVE;
+        }
+        // all other events
+#ifdef MODULE_MAIN_LOOP_IO_EVENT
+        else {
+          MODULE_MAIN_LOOP_IO_EVENT(eventflags);
+        }
 #endif
-            // all other events
+#else /* AMIROOS_CFG_SSSP_ENABLE == false */
 #ifdef MODULE_MAIN_LOOP_IO_EVENT
-            else {
-                MODULE_MAIN_LOOP_IO_EVENT(eventmask, eventflags);
-            }
+        MODULE_MAIN_LOOP_IO_EVENT(eventflags);
 #endif
-            break;
+#endif /* AMIROOS_CFG_SSSP_ENABLE */
+        break;
 
-            // if this was an OS event
-        case OSEVENT_MASK:
-            // evaluate flags
-            eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
-            switch (eventflags) {
-            case AOS_SYSTEM_EVENTFLAGS_HIBERNATE:
-                shutdown = AOS_SHUTDOWN_HIBERNATE;
-                break;
-            case AOS_SYSTEM_EVENTFLAGS_DEEPSLEEP:
-                shutdown = AOS_SHUTDOWN_DEEPSLEEP;
-                break;
-            case AOS_SYSTEM_EVENTFLAGS_TRANSPORTATION:
-                shutdown = AOS_SHUTDOWN_TRANSPORTATION;
-                break;
-            case AOS_SYSTEM_EVENTFLAGS_RESTART:
-                shutdown = AOS_SHUTDOWN_RESTART;
-                break;
-            default:
-                _unexpectedEventError(eventmask, eventflags);
-                break;
-            }
+      // if this was an OS event
+      case OSEVENT_MASK:
+        // evaluate flags
+        eventflags = chEvtGetAndClearFlags(&_eventListenerOS);
+        switch (eventflags) {
+#if (AMIROOS_CFG_SSSP_ENABLE == true)
+          case AOS_SYSTEM_EVENTFLAGS_HIBERNATE:
+            shutdown = AOS_SHUTDOWN_HIBERNATE;
             break;
-
-            // if this was any other event (should be impossible to occur)
-        default:
-            eventflags = 0;
+          case AOS_SYSTEM_EVENTFLAGS_DEEPSLEEP:
+            shutdown = AOS_SHUTDOWN_DEEPSLEEP;
+            break;
+          case AOS_SYSTEM_EVENTFLAGS_TRANSPORTATION:
+            shutdown = AOS_SHUTDOWN_TRANSPORTATION;
+            break;
+          case AOS_SYSTEM_EVENTFLAGS_RESTART:
+            shutdown = AOS_SHUTDOWN_RESTART;
+            break;
+#else /* AMIROOS_CFG_SSSP_ENABLE == false */
+          case AOS_SYSTEM_EVENTFLAGS_SHUTDOWN:
+            shutdown = AOS_SHUTDOWN_DEFAULT;
+            break;
+#endif /* AMIROOS_CFG_SSSP_ENABLE */
+          default:
             _unexpectedEventError(eventmask, eventflags);
             break;
         }
+        break;
+
+      // if this was any other event (should be impossible to occur)
+      default:
+        eventflags = 0;
+#if (AMIROOS_CFG_MAIN_LOOP_TIMEOUT == 0)
+        _unexpectedEventError(eventmask, eventflags);
+#endif
+        break;
+    }
 
 #if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1)
 #if defined(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS)
-        AMIROOS_CFG_MAIN_LOOP_HOOK_1(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS);
+    AMIROOS_CFG_MAIN_LOOP_HOOK_1(AMIROOS_CFG_MAIN_LOOP_HOOK_1_ARGS);
 #else
-        AMIROOS_CFG_MAIN_LOOP_HOOK_1();
+    AMIROOS_CFG_MAIN_LOOP_HOOK_1();
 #endif
 #endif
+  }
 
-    }
-//#endif //DEBUG
-    aosprintf("Line 1224\n");
-    /*
+  /*
    * ##########################################################################
    * # system shutdown                                                        #
    * ##########################################################################
@@ -1245,8 +1265,8 @@ aosprintf("Line 1123\n");
 #endif
 #endif
 
-    // initialize/acknowledge shutdown
-    aosSysShutdownInit(shutdown);
+  // initialize/acknowledge shutdown
+  aosSysShutdownInit(shutdown);
 
 #if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1)
 #if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_1_ARGS)
@@ -1256,8 +1276,8 @@ aosprintf("Line 1123\n");
 #endif
 #endif
 
-    // stop system threads
-    aosSysStop();
+  // stop system threads
+  aosSysStop();
 
 #if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2)
 #if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_2_ARGS)
@@ -1267,8 +1287,8 @@ aosprintf("Line 1123\n");
 #endif
 #endif
 
-    // deinitialize system
-    aosSysDeinit();
+  // deinitialize system
+  aosSysDeinit();
 
 #if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3)
 #if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_3_ARGS)
@@ -1278,11 +1298,11 @@ aosprintf("Line 1123\n");
 #endif
 #endif
 
-    /* stop all periphery communication */
-    // CAN (mandatory)
-    canStop(&MODULE_HAL_CAN);
+  /* stop all periphery communication */
+  // CAN (mandatory)
+  canStop(&MODULE_HAL_CAN);
 #ifdef MODULE_SHUTDOWN_PERIPHERY_COMM
-    MODULE_SHUTDOWN_PERIPHERY_COMM();
+  MODULE_SHUTDOWN_PERIPHERY_COMM();
 #endif
 
 #if defined(AMIROOS_CFG_MAIN_SHUTDOWN_HOOK_4)
@@ -1293,10 +1313,10 @@ aosprintf("Line 1123\n");
 #endif
 #endif
 
-    // finally hand over to bootloader
-    aosSysShutdownFinal(shutdown);
+  // finally hand over to bootloader
+  aosSysShutdownFinal(shutdown);
 
-    /*
+  /*
    * ##########################################################################
    * # after shutdown/restart                                                 #
    * ##########################################################################
@@ -1306,8 +1326,8 @@ aosprintf("Line 1123\n");
    *       which subsystems should NOT be shut down.
    */
 
-    // return an error, since this code should not be executed
-    return -1;
+  // return an error, since this code should not be executed
+  return -1;
 }
 
 /** @} */
diff --git a/core/src/aos_shell.c b/core/src/aos_shell.c
index e524faf..bf990b8 100644
--- a/core/src/aos_shell.c
+++ b/core/src/aos_shell.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -270,7 +270,6 @@ typedef enum charmatch {
  */
 static void _printPrompt(aos_shell_t* shell)
 {
-
   aosDbgCheck(shell != NULL);
 
   // print some time informattion before prompt if configured
@@ -312,6 +311,7 @@ static void _printPrompt(aos_shell_t* shell)
   } else {
     chprintf((BaseSequentialStream*)&shell->stream, "%>$ ");
   }
+
   return;
 }
 
diff --git a/core/src/aos_system.c b/core/src/aos_system.c
index f475d0d..e40d1ec 100644
--- a/core/src/aos_system.c
+++ b/core/src/aos_system.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -79,23 +79,19 @@ static aos_timestamp_t _uptime;
  */
 static systime_t _synctime;
 
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
-#if (AMIROOS_CFG_SSSP_MASTER == true) || defined(__DOXYGEN__)
+#if ((AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER == true)) || defined(__DOXYGEN__)
 /**
  * @brief   Timer to drive the SYS_SYNC signal for system wide time synchronization according to SSSP.
  */
 static virtual_timer_t _syssynctimer;
 
-#endif
-
 /**
  * @brief   Last uptime of system wide time synchronization.
  */
 static aos_timestamp_t _syssynctime;
 #endif
 
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
-#if ((AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__)
+#if ((AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)) || defined(__DOXYGEN__)
 /**
  * @brief   Offset between local clock and system wide synchronization signal.
  */
@@ -105,8 +101,7 @@ static float _syssyncskew;
  * @brief   Weighting factor for the low-pass filter used for calculating the @p _syssyncskew value.
  */
 #define SYSTEM_SYSSYNCSKEW_LPFACTOR   (0.1f / AOS_SYSTEM_TIME_RESOLUTION)
-#endif
-#endif
+#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true) */
 
 #if (AMIROOS_CFG_SHELL_ENABLE == true) || defined(__DOXYGEN__)
 /**
@@ -146,7 +141,11 @@ static aos_shellcommand_t _shellcmd_config = {
  * @brief   Shell command to shutdown the system.
  */
 static aos_shellcommand_t _shellcmd_shutdown = {
+#if (AMIROOS_CFG_SSSP_ENABLE == true)
   /* name     */ "system:shutdown",
+#else
+  /* name     */ "module:shutdown",
+#endif
   /* callback */ _shellcmd_shutdowncb,
   /* next     */ NULL,
 };
@@ -242,7 +241,11 @@ static void _printSystemInfo(BaseSequentialStream* stream)
 
   // print static information about module and operating system
   _printSystemInfoSeparator(stream, '=', SYSTEM_INFO_WIDTH);
+#ifdef BOARD_VERSION
   _printSystemInfoLine(stream, "Module", SYSTEM_INFO_NAMEWIDTH, "%s (v%s)", BOARD_NAME, BOARD_VERSION);
+#else
+  _printSystemInfoLine(stream, "Module", SYSTEM_INFO_NAMEWIDTH, "%s", BOARD_NAME);
+#endif
 #ifdef PLATFORM_NAME
   _printSystemInfoLine(stream, "Platform", SYSTEM_INFO_NAMEWIDTH, "%s", PLATFORM_NAME);
 #endif
@@ -253,6 +256,8 @@ static void _printSystemInfo(BaseSequentialStream* stream)
   _printSystemInfoSeparator(stream, '-', SYSTEM_INFO_WIDTH);
 #if (AMIROOS_CFG_SSSP_ENABLE == true)
   _printSystemInfoLine(stream, "AMiRo-OS" , SYSTEM_INFO_NAMEWIDTH, "%u.%u.%u %s (SSSP %u.%u)", AMIROOS_VERSION_MAJOR, AMIROOS_VERSION_MINOR, AMIROOS_VERSION_PATCH, AMIROOS_RELEASE_TYPE, AOS_SYSTEM_SSSP_VERSION_MAJOR, AOS_SYSTEM_SSSP_VERSION_MINOR);
+#else
+  _printSystemInfoLine(stream, "AMiRo-OS" , SYSTEM_INFO_NAMEWIDTH, "%u.%u.%u %s", AMIROOS_VERSION_MAJOR, AMIROOS_VERSION_MINOR, AMIROOS_VERSION_PATCH, AMIROOS_RELEASE_TYPE);
 #endif
   _printSystemInfoLine(stream, "AMiRo-LLD" , SYSTEM_INFO_NAMEWIDTH, "%u.%u.%u %s (periphAL %u.%u)", AMIRO_LLD_VERSION_MAJOR, AMIRO_LLD_VERSION_MINOR, AMIRO_LLD_VERSION_PATCH, AMIRO_LLD_RELEASE_TYPE, PERIPHAL_VERSION_MAJOR, PERIPHAL_VERSION_MINOR);
   _printSystemInfoLine(stream, "ChibiOS/RT" , SYSTEM_INFO_NAMEWIDTH, "%u.%u.%u %s", CH_KERNEL_MAJOR, CH_KERNEL_MINOR, CH_KERNEL_PATCH, (CH_KERNEL_STABLE == 1) ? "stable" : "non-stable");
@@ -264,7 +269,6 @@ static void _printSystemInfo(BaseSequentialStream* stream)
   // print static information about the bootloader
   _printSystemInfoSeparator(stream, '-', SYSTEM_INFO_WIDTH);
   if (BL_CALLBACK_TABLE_ADDRESS->magicNumber == BL_MAGIC_NUMBER) {
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
     _printSystemInfoLine(stream, "AMiRo-BLT", SYSTEM_INFO_NAMEWIDTH, "%u.%u.%u %s (SSSP %u.%u)", BL_CALLBACK_TABLE_ADDRESS->vBootloader.major, BL_CALLBACK_TABLE_ADDRESS->vBootloader.minor, BL_CALLBACK_TABLE_ADDRESS->vBootloader.patch,
                          (BL_CALLBACK_TABLE_ADDRESS->vBootloader.identifier == BL_VERSION_ID_AMiRoBLT_Release) ? "stable" :
                          (BL_CALLBACK_TABLE_ADDRESS->vBootloader.identifier == BL_VERSION_ID_AMiRoBLT_ReleaseCandidate) ? "release candidate" :
@@ -273,7 +277,7 @@ static void _printSystemInfo(BaseSequentialStream* stream)
                          (BL_CALLBACK_TABLE_ADDRESS->vBootloader.identifier == BL_VERSION_ID_AMiRoBLT_PreAlpha) ? "pre-alpha" :
                          "<release type unknown>",
                          BL_CALLBACK_TABLE_ADDRESS->vSSSP.major, BL_CALLBACK_TABLE_ADDRESS->vSSSP.minor);
-
+#if (AMIROOS_CFG_SSSP_ENABLE == true)
     if (BL_CALLBACK_TABLE_ADDRESS->vSSSP.major != AOS_SYSTEM_SSSP_VERSION_MAJOR) {
       if (stream) {
         chprintf(stream, "WARNING: Bootloader and AMiRo-OS implement incompatible SSSP versions!\n");
@@ -293,7 +297,7 @@ static void _printSystemInfo(BaseSequentialStream* stream)
 
   // print dynamic information about the module
   _printSystemInfoSeparator(stream, '-', SYSTEM_INFO_WIDTH);
-  #if (AMIROOS_CFG_SSSP_ENABLE == true)
+#if (AMIROOS_CFG_SSSP_ENABLE == true)
   if (aos.sssp.moduleId != 0) {
     _printSystemInfoLine(stream, "Module ID", SYSTEM_INFO_NAMEWIDTH, "%u", aos.sssp.moduleId);
   } else {
@@ -508,22 +512,23 @@ static int _shellcmd_infocb(BaseSequentialStream* stream, int argc, char* argv[]
   chprintf(stream, "%10u seconds\n", (uint8_t)(uptime % MICROSECONDS_PER_MINUTE / MICROSECONDS_PER_SECOND));
   chprintf(stream, "%10u milliseconds\n", (uint16_t)(uptime % MICROSECONDS_PER_SECOND / MICROSECONDS_PER_MILLISECOND));
   chprintf(stream, "%10u microseconds\n", (uint16_t)(uptime % MICROSECONDS_PER_MILLISECOND / MICROSECONDS_PER_MICROSECOND));
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
-#if (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)
+#if (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)
   chprintf(stream, "SSSP synchronization offset: %.3fus per %uus\n", _syssyncskew, AMIROOS_CFG_SSSP_SYSSYNCPERIOD);
 #endif /* AMIROOS_CFG_SSSP_MASTER != true && AMIROOS_CFG_PROFILE == true */
   _printSystemInfoSeparator(stream, '=', SYSTEM_INFO_WIDTH);
-#endif
+
 #if (AMIROOS_CFG_SHELL_ENABLE == true)
   // print shell info
   chprintf(stream, "System shell information:\n");
   chprintf(stream, "\tnumber of commands:      %u\n", aosShellCountCommands(&aos.shell));
   chprintf(stream, "\tmaximum line width:      %u characters\n", aos.shell.linesize);
   chprintf(stream, "\tmaximum #arguments:      %u\n", aos.shell.arglistsize);
+#if (AMIROOS_CFG_DBG == true)
   chprintf(stream, "\tshell thread stack size: %u bytes\n", aosThdGetStacksize(aos.shell.thread));
 #if (CH_DBG_FILL_THREADS == TRUE)
   chprintf(stream, "\tstack peak utilization:  %u bytes (%.2f%%)\n", aosThdGetStackPeakUtilization(aos.shell.thread), (float)aosThdGetStackPeakUtilization(aos.shell.thread) / (float)aosThdGetStacksize(aos.shell.thread) * 100.0f);
 #endif /* CH_DBG_FILL_THREADS == TRUE */
+#endif /* AMIROOS_CFG_DBG == true */
   _printSystemInfoSeparator(stream, '=', SYSTEM_INFO_WIDTH);
 #endif /* AMIROOS_CFG_SHELL_ENABLE == true */
 
@@ -545,6 +550,7 @@ static int _shellcmd_shutdowncb(BaseSequentialStream* stream, int argc, char* ar
 {
   aosDbgCheck(stream != NULL);
 
+#if (AMIROOS_CFG_SSSP_ENABLE == true)
   // print help text
   if (argc != 2 || strcmp(argv[1], "--help") == 0) {
     chprintf(stream, "Usage: %s OPTION\n", argv[0]);
@@ -592,6 +598,14 @@ static int _shellcmd_shutdowncb(BaseSequentialStream* stream, int argc, char* ar
       return AOS_INVALID_ARGUMENTS;
     }
   }
+#else /* AMIROOS_CFG_SSSP_ENABLE == false */
+  (void)argv;
+  (void)argc;
+
+  chEvtBroadcastFlags(&aos.events.os, AOS_SYSTEM_EVENTFLAGS_SHUTDOWN);
+  chThdTerminate(chThdGetSelfX());
+  return AOS_OK;
+#endif /* AMIROOS_CFG_SSSP_ENABLE */
 }
 
 #if (AMIROOS_CFG_TESTS_ENABLE == true) || defined(__DOXYGEN__)
@@ -618,6 +632,9 @@ static int _shellcmd_kerneltestcb(BaseSequentialStream* stream, int argc, char*
 #endif /* AMIROOS_CFG_TESTS_ENABLE == true */
 #endif /* AMIROOS_CFG_SHELL_ENABLE == true */
 
+// suppress warning in case no interrupt GPIOs are defined
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-function"
 /**
  * @brief   Generic callback function for GPIO interrupts.
  *
@@ -628,14 +645,14 @@ static void _intCallback(void* args)
   aosDbgCheck((args != NULL) && (*((iopadid_t*)args) < sizeof(eventflags_t) * 8));
 
   chSysLockFromISR();
-  chEvtBroadcastFlagsI(&aos.events.io, (eventflags_t)1 << *((iopadid_t*)args));
+  chEvtBroadcastFlagsI(&aos.events.io, AOS_IOEVENT_FLAG(*((iopadid_t*)args)));
   chSysUnlockFromISR();
 
   return;
 }
+#pragma GCC diagnostic pop
 
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
-#if (AMIROOS_CFG_SSSP_MASTER != true) || defined(__DOXYGEN__)
+#if ((AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true)) || defined(__DOXYGEN__)
 /**
  * @brief   Callback function for the Sync signal interrupt.
  *
@@ -672,13 +689,12 @@ static void _signalSyncCallback(void *args)
     }
   }
   // broadcast event
-  chEvtBroadcastFlagsI(&aos.events.io, (eventflags_t)1 << *((iopadid_t*)args));
+  chEvtBroadcastFlagsI(&aos.events.io, AOS_IOEVENT_FLAG(*((iopadid_t*)args)));
   chSysUnlockFromISR();
 
   return;
 }
-#endif
-#endif
+#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER != true) */
 
 /**
  * @brief   Callback function for the uptime accumulation timer.
@@ -701,8 +717,8 @@ static void _uptimeCallback(void* par)
 
   return;
 }
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
-#if (AMIROOS_CFG_SSSP_MASTER == true) || defined (__DOXYGEN__)
+
+#if ((AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER == true)) || defined (__DOXYGEN__)
 /**
  * @brief   Periodic system synchronization callback function.
  * @details Toggles the SYS_SYNC signal and reconfigures the system synchronization timer.
@@ -736,8 +752,7 @@ static void _sysSyncTimerCallback(void* par)
 
   return;
 }
-#endif
-#endif
+#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_MASTER == true) */
 
 /**
  * @brief   AMiRo-OS system initialization.
@@ -756,9 +771,9 @@ void aosSysInit(void)
 
   /* set local variables */
   chVTObjectInit(&_systimer);
+#if (AMIROOS_CFG_SSSP_ENABLE == true)
   _synctime = 0;
   _uptime = 0;
-  #if (AMIROOS_CFG_SSSP_ENABLE == true)
 #if (AMIROOS_CFG_SSSP_MASTER == true)
   chVTObjectInit(&_syssynctimer);
   _syssynctime = 0;
@@ -766,10 +781,17 @@ void aosSysInit(void)
 #if (AMIROOS_CFG_SSSP_MASTER != true) && (AMIROOS_CFG_PROFILE == true)
   _syssyncskew = 0.0f;
 #endif
-#endif
+#else /* AMIROOS_CFG_SSSP_ENABLE == false */
+  // start the uptime counter
+  chSysLock();
+  _synctime = chVTGetSystemTimeX();
+  _uptime = 0;
+  chVTSetI(&_systimer, SYSTIMER_PERIOD, &_uptimeCallback, NULL);
+  chSysUnlock();
+#endif /* AMIROOS_CFG_SSSP_ENABLE */
 
-  #if (AMIROOS_CFG_SSSP_ENABLE == true)
   /* initialize aos configuration */
+#if (AMIROOS_CFG_SSSP_ENABLE == true)
   aos.sssp.stage = AOS_SSSP_STARTUP_2_1;
   aos.sssp.moduleId = 0;
 #endif
@@ -778,8 +800,8 @@ void aosSysInit(void)
   chEvtObjectInit(&aos.events.os);
 
   /* interrupt setup */
+#if (AMIROOS_CFG_SSSP_ENABLE == true)
   // PD signal
-  #if (AMIROOS_CFG_SSSP_ENABLE == true)
   palSetPadCallback(moduleSsspGpioPd.gpio->port, moduleSsspGpioPd.gpio->pad, _intCallback, &moduleSsspGpioPd.gpio->pad);
   palEnablePadEvent(moduleSsspGpioPd.gpio->port, moduleSsspGpioPd.gpio->pad, APAL2CH_EDGE(moduleSsspGpioPd.meta.edge));
   // SYNC signal
@@ -799,7 +821,7 @@ void aosSysInit(void)
   palSetPadCallback(moduleSsspGpioUp.gpio->port, moduleSsspGpioUp.gpio->pad, _intCallback, &moduleSsspGpioUp.gpio->pad);
   palEnablePadEvent(moduleSsspGpioUp.gpio->port, moduleSsspGpioUp.gpio->pad, APAL2CH_EDGE(moduleSsspGpioUp.meta.edge));
 #endif
-#endif
+#endif /* AMIROOS_CFG_SSSP_ENABLE == true */
 #ifdef MODULE_INIT_INTERRUPTS
   // further interrupt signals
   MODULE_INIT_INTERRUPTS();
@@ -821,7 +843,7 @@ void aosSysInit(void)
 #if (AMIROOS_CFG_TESTS_ENABLE == true)
   aosShellAddCommand(&aos.shell, &_shellcmd_kerneltest);
 #endif
-#endif
+#endif /* AMIROOS_CFG_SHELL_ENABLE == true */
 
   return;
 }
@@ -847,7 +869,7 @@ inline void aosSysStart(void)
     chSysUnlock();
   }
 #endif
-#endif
+#endif /* AMIROOS_CFG_SSSP_ENABLE == true */
 
   // print system information;
   _printSystemInfo((BaseSequentialStream*)&aos.iostream);
@@ -864,7 +886,8 @@ inline void aosSysStart(void)
 
   return;
 }
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
+
+#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
 /**
  * @brief   Implements the SSSP startup synchronization step.
  *
@@ -915,7 +938,7 @@ eventmask_t aosSysSsspStartupOsInitSyncCheck(event_listener_t* syncEvtListener)
     return m;
   }
 }
-#endif
+#endif /* AMIROOS_CFG_SSSP_ENABLE == true */
 
 /**
  * @brief   Retrieves the system uptime.
@@ -983,15 +1006,15 @@ void aosSysShutdownInit(aos_shutdown_t shutdown)
   // update the system SSSP stage
   aos.sssp.stage = AOS_SSSP_SHUTDOWN_1_1;
 
-  // activate the SYS_PD control signal only, if this module initiated the shutdown
   chSysLock();
+  // activate the SYS_PD control signal only, if this module initiated the shutdown
   if (shutdown != AOS_SHUTDOWN_PASSIVE) {
     apalControlGpioSet(&moduleSsspGpioPd, APAL_GPIO_ON);
   }
   // activate the SYS_SYNC signal
   apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_ON);
   chSysUnlock();
-#endif
+#endif /* AMIROOS_CFG_SSSP_ENABLE == true */
 
   switch (shutdown) {
     case AOS_SHUTDOWN_PASSIVE:
@@ -1014,15 +1037,17 @@ void aosSysShutdownInit(aos_shutdown_t shutdown)
       chEvtBroadcastFlags(&aos.events.os, AOS_SYSTEM_EVENTFLAGS_RESTART);
       aosprintf("restarting system...\n");
       break;
-   // must never occur
-   case AOS_SHUTDOWN_NONE:
-   default:
+    // must never occur
+    case AOS_SHUTDOWN_NONE:
+    default:
       break;
   }
+
 #if (AMIROOS_CFG_SSSP_ENABLE == true)
   // update the system SSSP stage
   aos.sssp.stage = AOS_SSSP_SHUTDOWN_1_2;
 #endif
+
   return;
 }
 
@@ -1060,32 +1085,41 @@ void aosSysShutdownFinal(aos_shutdown_t shutdown)
   // disable all interrupts
   irqDeinit();
 
-  #if (AMIROOS_CFG_SSSP_ENABLE == true)
+#if (AMIROOS_CFG_SSSP_ENABLE == true)
   // update the system SSSP stage
   aos.sssp.stage = AOS_SSSP_SHUTDOWN_1_3;
 #endif
 
-  // call bootloader callback depending on arguments
-  switch (shutdown) {
-    case AOS_SHUTDOWN_PASSIVE:
-      BL_CALLBACK_TABLE_ADDRESS->cbHandleShutdownRequest();
-      break;
-    case AOS_SHUTDOWN_HIBERNATE:
-      BL_CALLBACK_TABLE_ADDRESS->cbShutdownHibernate();
-      break;
-    case AOS_SHUTDOWN_DEEPSLEEP:
-      BL_CALLBACK_TABLE_ADDRESS->cbShutdownDeepsleep();
-      break;
-    case AOS_SHUTDOWN_TRANSPORTATION:
-      BL_CALLBACK_TABLE_ADDRESS->cbShutdownTransportation();
-      break;
-    case AOS_SHUTDOWN_RESTART:
-      BL_CALLBACK_TABLE_ADDRESS->cbShutdownRestart();
-      break;
-    // must never occur
-    case AOS_SHUTDOWN_NONE:
-    default:
-      break;
+  // validate bootloader
+  if ((BL_CALLBACK_TABLE_ADDRESS->magicNumber == BL_MAGIC_NUMBER) &&
+      (BL_CALLBACK_TABLE_ADDRESS->vBootloader.major == BL_VERSION_MAJOR) &&
+      (BL_CALLBACK_TABLE_ADDRESS->vBootloader.minor >= BL_VERSION_MINOR)) {
+    // call bootloader callback depending on arguments
+    switch (shutdown) {
+      case AOS_SHUTDOWN_PASSIVE:
+        BL_CALLBACK_TABLE_ADDRESS->cbHandleShutdownRequest();
+        break;
+      case AOS_SHUTDOWN_HIBERNATE:
+        BL_CALLBACK_TABLE_ADDRESS->cbShutdownHibernate();
+        break;
+      case AOS_SHUTDOWN_DEEPSLEEP:
+        BL_CALLBACK_TABLE_ADDRESS->cbShutdownDeepsleep();
+        break;
+      case AOS_SHUTDOWN_TRANSPORTATION:
+        BL_CALLBACK_TABLE_ADDRESS->cbShutdownTransportation();
+        break;
+      case AOS_SHUTDOWN_RESTART:
+        BL_CALLBACK_TABLE_ADDRESS->cbShutdownRestart();
+        break;
+      // must never occur
+      case AOS_SHUTDOWN_NONE:
+      default:
+        break;
+    }
+  } else {
+    // fallback if bootloader was found to be invalid
+    aosprintf("Bootloader incompatible or not available!\n");
+    chThdSleep(TIME_INFINITE);
   }
 
   return;
diff --git a/core/src/aos_thread.c b/core/src/aos_thread.c
index e08fe72..ecd3e58 100644
--- a/core/src/aos_thread.c
+++ b/core/src/aos_thread.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -57,7 +57,7 @@ void aosThdSleepUntilS(const aos_timestamp_t* t)
   return;
 }
 
-#if (CH_DBG_FILL_THREADS == TRUE) || defined(__DOXYGEN__)
+#if ((AMIROOS_CFG_DBG == true) && (CH_DBG_FILL_THREADS == TRUE)) || defined(__DOXYGEN__)
 /**
  * @brief   Calculate the peak stack utilization for a specific thread so far in bytes.
  *
@@ -81,6 +81,6 @@ size_t aosThdGetStackPeakUtilization(thread_t* thread)
 
   return util;
 }
-#endif /* CH_DBG_FILL_THREADS == TRUE */
+#endif /* (AMIROOS_CFG_DBG == true) && (CH_DBG_FILL_THREADS == TRUE) */
 
 /** @} */
diff --git a/core/src/aos_time.c b/core/src/aos_time.c
index e637810..677733c 100644
--- a/core/src/aos_time.c
+++ b/core/src/aos_time.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/core/src/aos_timer.c b/core/src/aos_timer.c
index 1a7a4fc..d29e9bf 100644
--- a/core/src/aos_timer.c
+++ b/core/src/aos_timer.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/core/src/aos_unittest.c b/core/src/aos_unittest.c
index 8dd8fa3..d436894 100644
--- a/core/src/aos_unittest.c
+++ b/core/src/aos_unittest.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/doc/AMiRo-OS.uml b/doc/AMiRo-OS.uml
index de66b38..2b745ab 100644
--- a/doc/AMiRo-OS.uml
+++ b/doc/AMiRo-OS.uml
@@ -1,6 +1,6 @@
 /'
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/doc/dox/blt.dox b/doc/dox/blt.dox
index 604c865..2e8d3fe 100644
--- a/doc/dox/blt.dox
+++ b/doc/dox/blt.dox
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/doc/dox/configs.dox b/doc/dox/configs.dox
index 9d7c077..dda7f7f 100644
--- a/doc/dox/configs.dox
+++ b/doc/dox/configs.dox
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/doc/dox/core.dox b/doc/dox/core.dox
index b2157e3..1bd0e9e 100644
--- a/doc/dox/core.dox
+++ b/doc/dox/core.dox
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/doc/dox/kernel.dox b/doc/dox/kernel.dox
index b86640f..21d5651 100644
--- a/doc/dox/kernel.dox
+++ b/doc/dox/kernel.dox
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/doc/dox/modules.dox b/doc/dox/modules.dox
index dcd6576..c836d4a 100644
--- a/doc/dox/modules.dox
+++ b/doc/dox/modules.dox
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/kernel/kernelsetup.sh b/kernel/kernelsetup.sh
index 5bf200c..f8aced8 100755
--- a/kernel/kernelsetup.sh
+++ b/kernel/kernelsetup.sh
@@ -1,7 +1,7 @@
 ################################################################################
 # AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
 # (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
+# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
 #                                                                              #
 # This program is free software: you can redistribute it and/or modify         #
 # it under the terms of the GNU General Public License as published by         #
@@ -263,6 +263,40 @@ function setLogFile {
   return 0
 }
 
+### check whether commands are available #######################################
+# Checks whether the specified commands are available and can be executed.
+#
+# usage:      checkCommand [<command> <command> ...]
+# arguments:  <command>
+#                 Name of the command to check.
+# return:     0
+#                 All requested commands are available.
+#             >0
+#                 Number of requested commands that were not found.
+#             -1
+#                 No argument given.
+#
+function checkCommands {
+  local status=0
+
+  # return if no argument was specified
+  if [ $# -eq 0 ]; then
+    return -1
+  fi
+
+  # check all specified commands
+  while [ $# -gt 0 ]; do
+    command -v $1 &>/dev/null
+    if [ $? -ne 0 ]; then
+      printWarning "Command '$1' not available.\n"
+      status=$((status + 1))
+    fi
+    shift 1
+  done
+
+  return $status
+}
+
 ################################################################################
 # SPECIFIC FUNCTIONS                                                           #
 ################################################################################
@@ -281,7 +315,7 @@ function printWelcomeText {
   printf "#                                                                    #\n"
   printf "######################################################################\n"
   printf "#                                                                    #\n"
-  printf "# Copyright (c) 2016..2018  Thomas Schöpping                         #\n"
+  printf "# Copyright (c) 2016..2019  Thomas Schöpping                         #\n"
   printf "#                                                                    #\n"
   printf "# This is free software; see the source for copying conditions.      #\n"
   printf "# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR  #\n"
@@ -333,6 +367,8 @@ function printHelp {
 #                 Warning: Aborted by user.
 #             -1
 #                 Error: Unexpected user input.
+#             -1
+#                 Error: Missing dependency.
 #
 function initChibiOS {
   printInfo "initializing ChibiOS submodule...\n"
@@ -358,6 +394,13 @@ function initChibiOS {
     esac
   fi
 
+  # check dependencies
+  checkCommands git
+  if [ $? -ne 0 ]; then
+    printError "Missing dependencies detected.\n"
+    return -2
+  fi
+
   # initialize submodule to default branch
   cd $kerneldir
   git submodule update --init $chibiosdir 2>&1 | tee -a $LOG_FILE
@@ -403,6 +446,13 @@ function patchChibiOS {
   local chibiosdir=${kerneldir}/ChibiOS
   local git_branch_patched="AMiRo-OS"
 
+  # check dependencies
+  checkCommands git
+  if [ $? -ne 0 ]; then
+    printError "Missing dependencies detected.\n"
+    return -2
+  fi
+
   # if the ChibiOS folder is empty
   if [ -z "$(ls -A $chibiosdir)" ]; then
     printWarning "$chibiosdir is empty. Please initialize first.\n"
@@ -615,6 +665,13 @@ function wipeChibiOS {
   local chibiosdir=${kerneldir}/ChibiOS
   local git_branch_patched="AMiRo-OS"
 
+  # check dependencies
+  checkCommands git
+  if [ $? -ne 0 ]; then
+    printError "Missing dependencies detected.\n"
+    return -2
+  fi
+
   # if the ChibiOS folder is empty
   if [ -z "$(ls -A $chibiosdir)" ]; then
     printInfo "$chibiosdir is alread empty\n"
diff --git a/modules/DiWheelDrive_1-1/Makefile b/modules/DiWheelDrive_1-1/Makefile
index fb1b80a..a3635a0 100644
--- a/modules/DiWheelDrive_1-1/Makefile
+++ b/modules/DiWheelDrive_1-1/Makefile
@@ -1,7 +1,7 @@
 ################################################################################
 # AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
 # (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
+# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
 #                                                                              #
 # This program is free software: you can redistribute it and/or modify         #
 # it under the terms of the GNU General Public License as published by         #
@@ -119,12 +119,13 @@ PROJECT := $(patsubst $(abspath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))..
 include ../../kernel/kernel.mk
 CHIBIOS := $(AMIROOS_KERNEL)
 AMIROOS = ../..
+# Licensing files
+include $(CHIBIOS)/os/license/license.mk
 # Startup files
 include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f1xx.mk
 # HAL-OSAL files
 include $(CHIBIOS)/os/hal/hal.mk
 include $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/platform.mk
-include ./board.mk
 include $(CHIBIOS)/os/hal/osal/rt/osal.mk
 # RTOS files
 include $(CHIBIOS)/os/rt/rt.mk
@@ -132,6 +133,7 @@ include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk
 # Other files (optional).
 include $(CHIBIOS)/test/lib/test.mk
 include $(CHIBIOS)/test/rt/rt_test.mk
+include $(CHIBIOS)/test/oslib/oslib_test.mk
 # AMiRo-BLT files
 include ../../bootloader/bootloader.mk
 # AMiRo-LLD files
@@ -142,17 +144,17 @@ include $(AMIROOS)/core/core.mk
 include $(AMIROOS)/unittests/unittests.mk
 
 # Define linker script file here
-LDSCRIPT= $(BOARDLD)/STM32F103xE.ld
+LDSCRIPT= STM32F103xE.ld
 
 # C sources that can be compiled in ARM or THUMB mode depending on the global
 # setting.
-CSRC = $(STARTUPSRC) \
+CSRC = $(LICSRC) \
+       $(STARTUPSRC) \
        $(KERNSRC) \
        $(PORTSRC) \
        $(OSALSRC) \
        $(HALSRC) \
        $(PLATFORMSRC) \
-       $(BOARDSRC) \
        $(MODULESCSRC) \
        $(TESTSRC) \
        $(PERIPHERYLLDCSRC) \
@@ -161,12 +163,14 @@ CSRC = $(STARTUPSRC) \
        $(CHIBIOS)/os/various/evtimer.c \
        $(CHIBIOS)/os/various/syscalls.c \
        $(CHIBIOS)/os/hal/lib/streams/chprintf.c \
+       board.c \
        module.c \
        $(APPSCSRC)
 
 # C++ sources that can be compiled in ARM or THUMB mode depending on the global
 # setting.
 CPPSRC = $(AMIROOSCORECPPSRC) \
+         $(CHIBIOS)/os/various/cpp_wrappers/syscalls_cpp.cpp \
          $(APPSCPPSRC)
 
 # C sources to be compiled in ARM mode regardless of the global setting.
@@ -196,14 +200,13 @@ ASMXSRC = $(STARTUPASM) \
           $(OSALASM) \
           $(APPSASMXSRC)
 
-INCDIR = $(CHIBIOS)/os/license \
+INCDIR = $(LICINC) \
          $(STARTUPINC) \
          $(KERNINC) \
          $(PORTINC) \
          $(OSALINC) \
          $(HALINC) \
          $(PLATFORMINC) \
-         $(BOARDINC) \
          $(MODULESINC) \
          $(TESTINC) \
          $(BOOTLOADERINC) \
@@ -290,8 +293,30 @@ ULIBS +=
 # End of user defines                                                          #
 ################################################################################
 
+################################################################################
+# Start of targets section                                                     #
+#                                                                              #
 
+# all and its dependencies
+BUILDDIR = ./build
 RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC
 include $(RULESPATH)/rules.mk
 
-include ../flash.mk
+# flash
+include $(AMIROOS)/bootloader/bootloader.mk
+FLASH_MODULES = $(PROJECT)
+FLASH_FILES = $(BUILDDIR)/$(PROJECT).$(FLASHTOOL_EXT)
+
+flash: $(FLASH_FILES)
+	$(info )
+ifeq ($(FLASHTOOL),SerialBoot)
+	$(info Flashing ($(FLASHTOOL)):)
+	$(FLASHTOOL_CMD) $(FLASHTOOL_ARGS)
+else
+	$(info ERROR: unable to flash the module (SerialBoot unavailable))
+endif
+
+#                                                                              #
+# End of targets section                                                       #
+################################################################################
+
diff --git a/modules/DiWheelDrive_1-1/STM32F103xE.ld b/modules/DiWheelDrive_1-1/STM32F103xE.ld
index f15bd0a..0bf757f 100644
--- a/modules/DiWheelDrive_1-1/STM32F103xE.ld
+++ b/modules/DiWheelDrive_1-1/STM32F103xE.ld
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/modules/DiWheelDrive_1-1/alldconf.h b/modules/DiWheelDrive_1-1/alldconf.h
index 6b0dba5..25da4eb 100644
--- a/modules/DiWheelDrive_1-1/alldconf.h
+++ b/modules/DiWheelDrive_1-1/alldconf.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/modules/DiWheelDrive_1-1/aosconf.h b/modules/DiWheelDrive_1-1/aosconf.h
index 90a1d04..5f2d2f6 100644
--- a/modules/DiWheelDrive_1-1/aosconf.h
+++ b/modules/DiWheelDrive_1-1/aosconf.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 /**
- * @file    
+ * @file
  * @brief   AMiRo-OS Configuration file for the DiWheelDrive v1.1 module.
  * @details Contains the application specific AMiRo-OS settings.
  *
@@ -79,6 +79,16 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #endif
 
 /**
+ * @brief   Mask for the control thread to listen to certain IO events.
+ * @note    Any mandatory events (e.g. for SSSP) are enabled implicitely despite this configuration.
+ */
+#if !defined(OS_CFG_MAIN_LOOP_IOEVENT_MASK)
+  #define AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK    0
+#else
+  #define AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK    OS_CFG_MAIN_LOOP_IOEVENT_MASK
+#endif
+
+/**
  * @brief   Timeout value when waiting for events in the main loop in microseconds.
  * @details A value of 0 deactivates the timeout.
  */
@@ -101,7 +111,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  * @brief   Flag to enable SSSP.
  */
 #if !defined(OS_CFG_SSSP_ENABLE)
-  #define AMIROOS_CFG_SSSP_ENABLE               false
+  #define AMIROOS_CFG_SSSP_ENABLE               true
 #else
   #define AMIROOS_CFG_SSSP_ENABLE               OS_CFG_SSSP_ENABLE
 #endif
diff --git a/modules/DiWheelDrive_1-1/board.c b/modules/DiWheelDrive_1-1/board.c
index 7a7d01d..0ef0984 100644
--- a/modules/DiWheelDrive_1-1/board.c
+++ b/modules/DiWheelDrive_1-1/board.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/modules/DiWheelDrive_1-1/board.h b/modules/DiWheelDrive_1-1/board.h
index 533cffc..43ff04e 100644
--- a/modules/DiWheelDrive_1-1/board.h
+++ b/modules/DiWheelDrive_1-1/board.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/modules/DiWheelDrive_1-1/board.mk b/modules/DiWheelDrive_1-1/board.mk
deleted file mode 100644
index b84c338..0000000
--- a/modules/DiWheelDrive_1-1/board.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-################################################################################
-# AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
-# (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
-#                                                                              #
-# This program is free software: you can redistribute it and/or modify         #
-# it under the terms of the GNU General Public License as published by         #
-# the Free Software Foundation, either version 3 of the License, or            #
-# (at your option) any later version.                                          #
-#                                                                              #
-# This program is distributed in the hope that it will be useful,              #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                #
-# GNU General Public License for more details.                                 #
-#                                                                              #
-# You should have received a copy of the GNU General Public License            #
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.        #
-#                                                                              #
-# This research/work was supported by the Cluster of Excellence Cognitive      #
-# Interaction Technology 'CITEC' (EXC 277) at Bielefeld University, which is   #
-# funded by the German Research Foundation (DFG).                              #
-################################################################################
-
-
-
-# absolute path to this directory
-BOARD_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
-
-# include paths
-BOARDINC = $(BOARD_DIR)
-
-# C source files
-BOARDSRC = $(BOARD_DIR)board.c
-
-# linker path
-BOARDLD = $(BOARD_DIR)
diff --git a/modules/DiWheelDrive_1-1/chconf.h b/modules/DiWheelDrive_1-1/chconf.h
index e141f6d..6149771 100644
--- a/modules/DiWheelDrive_1-1/chconf.h
+++ b/modules/DiWheelDrive_1-1/chconf.h
@@ -1,6 +1,6 @@
 /*
  * AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
- * Copyright (C) 2016..2018  Thomas Schöpping et al.
+ * Copyright (C) 2016..2019  Thomas Schöpping et al.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/modules/DiWheelDrive_1-1/halconf.h b/modules/DiWheelDrive_1-1/halconf.h
index cfbc471..6019113 100644
--- a/modules/DiWheelDrive_1-1/halconf.h
+++ b/modules/DiWheelDrive_1-1/halconf.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -196,13 +196,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define HAL_USE_WDG                         FALSE
 #endif
 
-/**
- * @brief   Enables the QEI subsystem.
- */
-#if !defined(HAL_USE_QEI) || defined(__DOXYGEN__)
-#define HAL_USE_QEI                         TRUE
-#endif
-
 /*===========================================================================*/
 /* PAL driver related settings.                                              */
 /*===========================================================================*/
diff --git a/modules/DiWheelDrive_1-1/mcuconf.h b/modules/DiWheelDrive_1-1/mcuconf.h
index d79b32c..f13ecc6 100644
--- a/modules/DiWheelDrive_1-1/mcuconf.h
+++ b/modules/DiWheelDrive_1-1/mcuconf.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/modules/DiWheelDrive_1-1/module.c b/modules/DiWheelDrive_1-1/module.c
index 07b0e72..94edb1b 100644
--- a/modules/DiWheelDrive_1-1/module.c
+++ b/modules/DiWheelDrive_1-1/module.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -438,7 +438,9 @@ VCNL4020Driver moduleLldProximity = {
 #include <string.h>
 #include <chprintf.h>
 
-/* A3906 (motor driver) */
+/*
+ * A3906 (motor driver)
+ */
 static int _utShellCmdCb_AlldA3906(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -480,7 +482,9 @@ aos_unittest_t moduleUtAlldA3906  = {
   /* data           */ &_utA3906Data,
 };
 
-/* AT24C01BN (EEPROM) */
+/*
+ * AT24C01BN (EEPROM)
+ */
 static int _utShellCmdCb_AlldAt24c01bn(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -504,7 +508,9 @@ aos_unittest_t moduleUtAlldAt24c01bn = {
   /* data           */ &_utAt24c01bnData,
 };
 
-/* HMC5883L (compass) */
+/*
+ * HMC5883L (compass)
+ */
 static int _utShellCmdCb_AlldHmc5883l(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -530,7 +536,9 @@ aos_unittest_t moduleUtAlldHmc5883l = {
   /* data           */ &_utHmc5883lData,
 };
 
-/* INA219 (power monitor) */
+/*
+ * INA219 (power monitor)
+ */
 static int _utShellCmdCb_AlldIna219(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -556,7 +564,9 @@ aos_unittest_t moduleUtAlldIna219 = {
   /* data           */ &_utIna219Data,
 };
 
-/* L3G4200D (gyroscope) */
+/*
+ * L3G4200D (gyroscope)
+ */
 static int _utShellCmdCb_AlldL3g4200d(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -584,7 +594,9 @@ aos_unittest_t moduleUtAlldL3g4200d = {
   /* data           */ &_utL3g4200dData,
 };
 
-/* Status LED */
+/*
+ * Status LED
+ */
 static int _utShellCmdCb_AlldLed(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -604,7 +616,9 @@ aos_unittest_t moduleUtAlldLed = {
   /* data           */ &moduleLldStatusLed,
 };
 
-/* LIS331DLH (accelerometer) */
+/*
+ * LIS331DLH (accelerometer)
+ */
 static int _utShellCmdCb_AlldLis331dlh(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -632,7 +646,9 @@ aos_unittest_t moduleUtAlldLis331dlh = {
   /* data           */ &_utLis331dlhData,
 };
 
-/* LTC4412 (power path controller) */
+/*
+ * LTC4412 (power path controller)
+ */
 static int _utShellCmdCb_AlldLtc4412(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -652,7 +668,9 @@ aos_unittest_t moduleUtAlldLtc4412 = {
   /* data           */ &moduleLldPowerPathController,
 };
 
-/* PCA9544A (I2C multiplexer) */
+/*
+ * PCA9544A (I2C multiplexer)
+ */
 static int _utShellCmdCb_AlldPca9544a(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -676,7 +694,9 @@ aos_unittest_t moduleUtAlldPca9544a = {
   /* data           */ &_utPca9544aData,
 };
 
-/* TPS62113 (step-down converter) */
+/*
+ * TPS62113 (step-down converter)
+ */
 static int _utShellCmdCb_AlldTps62113(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -696,7 +716,9 @@ aos_unittest_t moduleUtAlldTps62113 = {
   /* data           */ &moduleLldStepDownConverterVdrive,
 };
 
-/* VCNL4020 (proximity sensor) */
+/*
+ * VCNL4020 (proximity sensor)
+ */
 static void _utAlldVcnl4020_disableInterrupt(VCNL4020Driver* vcnl)
 {
   uint8_t intstatus;
diff --git a/modules/DiWheelDrive_1-1/module.h b/modules/DiWheelDrive_1-1/module.h
index 421668f..966d1ee 100644
--- a/modules/DiWheelDrive_1-1/module.h
+++ b/modules/DiWheelDrive_1-1/module.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -243,52 +243,52 @@ extern ROMCONST apalControlGpio_t moduleGpioSysWarmrst;
 /**
  * @brief   Event flag to be set on a SYS_SYNC interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_SYSSYNC          ((eventflags_t)1 << GPIOC_SYS_INT_N)
+#define MODULE_OS_IOEVENTFLAGS_SYSSYNC          AOS_IOEVENT_FLAG(GPIOC_SYS_INT_N)
 
 /**
  * @brief   Event flag to be set on a SYS_WARMRST interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_SYSWARMRST       ((eventflags_t)1 << GPIOD_SYS_WARMRST_N)
+#define MODULE_OS_IOEVENTFLAGS_SYSWARMRST       AOS_IOEVENT_FLAG(GPIOD_SYS_WARMRST_N)
 
 /**
  * @brief   Event flag to be set on a PATH_DCSTAT interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_PATHDCSTAT       ((eventflags_t)1 << GPIOC_PATH_DCEN)
+#define MODULE_OS_IOEVENTFLAGS_PATHDCSTAT       AOS_IOEVENT_FLAG(GPIOC_PATH_DCEN)
 
 /**
  * @brief   Event flag to be set on a COMPASS_DRDY interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_COMPASSDRDY      ((eventflags_t)1 << GPIOB_COMPASS_DRDY)
+#define MODULE_OS_IOEVENTFLAGS_COMPASSDRDY      AOS_IOEVENT_FLAG(GPIOB_COMPASS_DRDY)
 
 /**
  * @brief   Event flag to be set on a SYS_PD interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_SYSPD            ((eventflags_t)1 << GPIOC_SYS_PD_N)
+#define MODULE_OS_IOEVENTFLAGS_SYSPD            AOS_IOEVENT_FLAG(GPIOC_SYS_PD_N)
 
 /**
  * @brief   Event flag to be set on a SYS_REG_EN interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_SYSREGEN         ((eventflags_t)1 << GPIOC_SYS_REG_EN)
+#define MODULE_OS_IOEVENTFLAGS_SYSREGEN         AOS_IOEVENT_FLAG(GPIOC_SYS_REG_EN)
 
 /**
  * @brief   Event flag to be set on a IR_INT interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_IRINT            ((eventflags_t)1 << GPIOB_IR_INT)
+#define MODULE_OS_IOEVENTFLAGS_IRINT            AOS_IOEVENT_FLAG(GPIOB_IR_INT)
 
 /**
  * @brief   Event flag to be set on a GYRO_DRDY interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_GYRODRDY         ((eventflags_t)1 << GPIOB_GYRO_DRDY)
+#define MODULE_OS_IOEVENTFLAGS_GYRODRDY         AOS_IOEVENT_FLAG(GPIOB_GYRO_DRDY)
 
 /**
  * @brief   Event flag to be set on a SYS_UART_UP interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_SYSUARTUP        ((eventflags_t)1 << GPIOB_SYS_UART_UP)
+#define MODULE_OS_IOEVENTFLAGS_SYSUARTUP        AOS_IOEVENT_FLAG(GPIOB_SYS_UART_UP)
 
 /**
  * @brief   Event flag to be set on a ACCEL_INT interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_ACCELINT         ((eventflags_t)1 << GPIOB_ACCEL_INT_N)
+#define MODULE_OS_IOEVENTFLAGS_ACCELINT         AOS_IOEVENT_FLAG(GPIOB_ACCEL_INT_N)
 
 #if (AMIROOS_CFG_SHELL_ENABLE == true) || defined(__DOXYGEN__)
 /**
diff --git a/modules/LightRing_1-0/Makefile b/modules/LightRing_1-0/Makefile
index fb1b80a..a3635a0 100644
--- a/modules/LightRing_1-0/Makefile
+++ b/modules/LightRing_1-0/Makefile
@@ -1,7 +1,7 @@
 ################################################################################
 # AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
 # (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
+# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
 #                                                                              #
 # This program is free software: you can redistribute it and/or modify         #
 # it under the terms of the GNU General Public License as published by         #
@@ -119,12 +119,13 @@ PROJECT := $(patsubst $(abspath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))..
 include ../../kernel/kernel.mk
 CHIBIOS := $(AMIROOS_KERNEL)
 AMIROOS = ../..
+# Licensing files
+include $(CHIBIOS)/os/license/license.mk
 # Startup files
 include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f1xx.mk
 # HAL-OSAL files
 include $(CHIBIOS)/os/hal/hal.mk
 include $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/platform.mk
-include ./board.mk
 include $(CHIBIOS)/os/hal/osal/rt/osal.mk
 # RTOS files
 include $(CHIBIOS)/os/rt/rt.mk
@@ -132,6 +133,7 @@ include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk
 # Other files (optional).
 include $(CHIBIOS)/test/lib/test.mk
 include $(CHIBIOS)/test/rt/rt_test.mk
+include $(CHIBIOS)/test/oslib/oslib_test.mk
 # AMiRo-BLT files
 include ../../bootloader/bootloader.mk
 # AMiRo-LLD files
@@ -142,17 +144,17 @@ include $(AMIROOS)/core/core.mk
 include $(AMIROOS)/unittests/unittests.mk
 
 # Define linker script file here
-LDSCRIPT= $(BOARDLD)/STM32F103xE.ld
+LDSCRIPT= STM32F103xE.ld
 
 # C sources that can be compiled in ARM or THUMB mode depending on the global
 # setting.
-CSRC = $(STARTUPSRC) \
+CSRC = $(LICSRC) \
+       $(STARTUPSRC) \
        $(KERNSRC) \
        $(PORTSRC) \
        $(OSALSRC) \
        $(HALSRC) \
        $(PLATFORMSRC) \
-       $(BOARDSRC) \
        $(MODULESCSRC) \
        $(TESTSRC) \
        $(PERIPHERYLLDCSRC) \
@@ -161,12 +163,14 @@ CSRC = $(STARTUPSRC) \
        $(CHIBIOS)/os/various/evtimer.c \
        $(CHIBIOS)/os/various/syscalls.c \
        $(CHIBIOS)/os/hal/lib/streams/chprintf.c \
+       board.c \
        module.c \
        $(APPSCSRC)
 
 # C++ sources that can be compiled in ARM or THUMB mode depending on the global
 # setting.
 CPPSRC = $(AMIROOSCORECPPSRC) \
+         $(CHIBIOS)/os/various/cpp_wrappers/syscalls_cpp.cpp \
          $(APPSCPPSRC)
 
 # C sources to be compiled in ARM mode regardless of the global setting.
@@ -196,14 +200,13 @@ ASMXSRC = $(STARTUPASM) \
           $(OSALASM) \
           $(APPSASMXSRC)
 
-INCDIR = $(CHIBIOS)/os/license \
+INCDIR = $(LICINC) \
          $(STARTUPINC) \
          $(KERNINC) \
          $(PORTINC) \
          $(OSALINC) \
          $(HALINC) \
          $(PLATFORMINC) \
-         $(BOARDINC) \
          $(MODULESINC) \
          $(TESTINC) \
          $(BOOTLOADERINC) \
@@ -290,8 +293,30 @@ ULIBS +=
 # End of user defines                                                          #
 ################################################################################
 
+################################################################################
+# Start of targets section                                                     #
+#                                                                              #
 
+# all and its dependencies
+BUILDDIR = ./build
 RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC
 include $(RULESPATH)/rules.mk
 
-include ../flash.mk
+# flash
+include $(AMIROOS)/bootloader/bootloader.mk
+FLASH_MODULES = $(PROJECT)
+FLASH_FILES = $(BUILDDIR)/$(PROJECT).$(FLASHTOOL_EXT)
+
+flash: $(FLASH_FILES)
+	$(info )
+ifeq ($(FLASHTOOL),SerialBoot)
+	$(info Flashing ($(FLASHTOOL)):)
+	$(FLASHTOOL_CMD) $(FLASHTOOL_ARGS)
+else
+	$(info ERROR: unable to flash the module (SerialBoot unavailable))
+endif
+
+#                                                                              #
+# End of targets section                                                       #
+################################################################################
+
diff --git a/modules/LightRing_1-0/STM32F103xE.ld b/modules/LightRing_1-0/STM32F103xE.ld
index 48c7de1..0df70c0 100644
--- a/modules/LightRing_1-0/STM32F103xE.ld
+++ b/modules/LightRing_1-0/STM32F103xE.ld
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/modules/LightRing_1-0/alldconf.h b/modules/LightRing_1-0/alldconf.h
index 5a1f657..d92ce44 100644
--- a/modules/LightRing_1-0/alldconf.h
+++ b/modules/LightRing_1-0/alldconf.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/modules/LightRing_1-0/aosconf.h b/modules/LightRing_1-0/aosconf.h
index 4fc1157..8c97bc0 100644
--- a/modules/LightRing_1-0/aosconf.h
+++ b/modules/LightRing_1-0/aosconf.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -79,6 +79,16 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #endif
 
 /**
+ * @brief   Mask for the control thread to listen to certain IO events.
+ * @note    Any mandatory events (e.g. for SSSP) are enabled implicitely despite this configuration.
+ */
+#if !defined(OS_CFG_MAIN_LOOP_IOEVENT_MASK)
+  #define AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK    0
+#else
+  #define AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK    OS_CFG_MAIN_LOOP_IOEVENT_MASK
+#endif
+
+/**
  * @brief   Timeout value when waiting for events in the main loop in microseconds.
  * @details A value of 0 deactivates the timeout.
  */
@@ -101,7 +111,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  * @brief   Flag to enable SSSP.
  */
 #if !defined(OS_CFG_SSSP_ENABLE)
-  #define AMIROOS_CFG_SSSP_ENABLE               false
+  #define AMIROOS_CFG_SSSP_ENABLE               true
 #else
   #define AMIROOS_CFG_SSSP_ENABLE               OS_CFG_SSSP_ENABLE
 #endif
diff --git a/modules/LightRing_1-0/board.c b/modules/LightRing_1-0/board.c
index 41a9663..badb34a 100644
--- a/modules/LightRing_1-0/board.c
+++ b/modules/LightRing_1-0/board.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/modules/LightRing_1-0/board.h b/modules/LightRing_1-0/board.h
index a8858ec..57fa0d5 100644
--- a/modules/LightRing_1-0/board.h
+++ b/modules/LightRing_1-0/board.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/modules/LightRing_1-0/board.mk b/modules/LightRing_1-0/board.mk
deleted file mode 100644
index b84c338..0000000
--- a/modules/LightRing_1-0/board.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-################################################################################
-# AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
-# (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
-#                                                                              #
-# This program is free software: you can redistribute it and/or modify         #
-# it under the terms of the GNU General Public License as published by         #
-# the Free Software Foundation, either version 3 of the License, or            #
-# (at your option) any later version.                                          #
-#                                                                              #
-# This program is distributed in the hope that it will be useful,              #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                #
-# GNU General Public License for more details.                                 #
-#                                                                              #
-# You should have received a copy of the GNU General Public License            #
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.        #
-#                                                                              #
-# This research/work was supported by the Cluster of Excellence Cognitive      #
-# Interaction Technology 'CITEC' (EXC 277) at Bielefeld University, which is   #
-# funded by the German Research Foundation (DFG).                              #
-################################################################################
-
-
-
-# absolute path to this directory
-BOARD_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
-
-# include paths
-BOARDINC = $(BOARD_DIR)
-
-# C source files
-BOARDSRC = $(BOARD_DIR)board.c
-
-# linker path
-BOARDLD = $(BOARD_DIR)
diff --git a/modules/LightRing_1-0/chconf.h b/modules/LightRing_1-0/chconf.h
index ee17c0a..5b323a3 100644
--- a/modules/LightRing_1-0/chconf.h
+++ b/modules/LightRing_1-0/chconf.h
@@ -1,6 +1,6 @@
 /*
  * AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
- * Copyright (C) 2016..2018  Thomas Schöpping et al.
+ * Copyright (C) 2016..2019  Thomas Schöpping et al.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/modules/LightRing_1-0/halconf.h b/modules/LightRing_1-0/halconf.h
index 8cba6d5..207b282 100644
--- a/modules/LightRing_1-0/halconf.h
+++ b/modules/LightRing_1-0/halconf.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -196,13 +196,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define HAL_USE_WDG                         FALSE
 #endif
 
-/**
- * @brief   Enables the QEI subsystem.
- */
-#if !defined(HAL_USE_QEI) || defined(__DOXYGEN__)
-#define HAL_USE_QEI                         FALSE
-#endif
-
 /*===========================================================================*/
 /* PAL driver related settings.                                              */
 /*===========================================================================*/
diff --git a/modules/LightRing_1-0/mcuconf.h b/modules/LightRing_1-0/mcuconf.h
index 6983b1d..511f2f1 100644
--- a/modules/LightRing_1-0/mcuconf.h
+++ b/modules/LightRing_1-0/mcuconf.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/modules/LightRing_1-0/module.c b/modules/LightRing_1-0/module.c
index d74ad6f..a928c98 100644
--- a/modules/LightRing_1-0/module.c
+++ b/modules/LightRing_1-0/module.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -280,7 +280,9 @@ TPS2051BDriver moduleLldPowerSwitchLaser = {
 /*===========================================================================*/
 #if (AMIROOS_CFG_TESTS_ENABLE == true) || defined(__DOXYGEN__)
 
-/* EEPROM (AT24C01BN) */
+/*
+ * EEPROM (AT24C01BN)
+ */
 static int _utShellCmdCb_AlldAt24c01bn(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -304,7 +306,9 @@ aos_unittest_t moduleUtAlldAt24c01bn = {
   /* data           */ &_utAt24c01bnData,
 };
 
-/* LED PWM driver (TLD5947) */
+/*
+ * LED PWM driver (TLD5947)
+ */
 static int _utShellCmdCb_Tlc5947(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -324,7 +328,9 @@ aos_unittest_t moduleUtAlldTlc5947 = {
   /* data           */ &moduleLldLedPwm,
 };
 
-/* power switch (Laser) */
+/*
+ * power switch (Laser)
+ */
 static int _utShellCmdCb_Tps2051bdbv(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
diff --git a/modules/LightRing_1-0/module.h b/modules/LightRing_1-0/module.h
index d730304..8e949b7 100644
--- a/modules/LightRing_1-0/module.h
+++ b/modules/LightRing_1-0/module.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -158,32 +158,32 @@ extern ROMCONST apalControlGpio_t moduleGpioSysSync;
 /**
  * @brief   Event flag to be set on a LASER_OC interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_LASEROC          ((eventflags_t)1 << GPIOB_LASER_OC_N)
+#define MODULE_OS_IOEVENTFLAGS_LASEROC          AOS_IOEVENT_FLAG(GPIOB_LASER_OC_N)
 
 /**
  * @brief   Event flag to be set on a SYS_UART_DN interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_SYSUARTDN        ((eventflags_t)1 << GPIOB_SYS_UART_DN)
+#define MODULE_OS_IOEVENTFLAGS_SYSUARTDN        AOS_IOEVENT_FLAG(GPIOB_SYS_UART_DN)
 
 /**
  * @brief   Event flag to be set on a WL_GDO2 interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_WLGDO2           ((eventflags_t)1 << GPIOB_WL_GDO2)
+#define MODULE_OS_IOEVENTFLAGS_WLGDO2           AOS_IOEVENT_FLAG(GPIOB_WL_GDO2)
 
 /**
  * @brief   Event flag to be set on a WL_GDO0 interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_WLGDO0           ((eventflags_t)1 << GPIOB_WL_GDO0)
+#define MODULE_OS_IOEVENTFLAGS_WLGDO0           AOS_IOEVENT_FLAG(GPIOB_WL_GDO0)
 
 /**
  * @brief   Event flag to be set on a SYS_PD interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_SYSPD            ((eventflags_t)1 << GPIOC_SYS_PD_N)
+#define MODULE_OS_IOEVENTFLAGS_SYSPD            AOS_IOEVENT_FLAG(GPIOC_SYS_PD_N)
 
 /**
  * @brief   Event flag to be set on a SYS_SYNC interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_SYSSYNC          ((eventflags_t)1 << GPIOD_SYS_INT_N)
+#define MODULE_OS_IOEVENTFLAGS_SYSSYNC          AOS_IOEVENT_FLAG(GPIOD_SYS_INT_N)
 
 #if (AMIROOS_CFG_SHELL_ENABLE == true) || defined(__DOXYGEN__)
 /**
diff --git a/modules/Makefile b/modules/Makefile
index 843a136..a0f893c 100644
--- a/modules/Makefile
+++ b/modules/Makefile
@@ -1,7 +1,7 @@
 ################################################################################
 # AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
 # (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
+# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
 #                                                                              #
 # This program is free software: you can redistribute it and/or modify         #
 # it under the terms of the GNU General Public License as published by         #
diff --git a/modules/PowerManagement_1-1/Makefile b/modules/PowerManagement_1-1/Makefile
index 30ed50a..cb3ee38 100644
--- a/modules/PowerManagement_1-1/Makefile
+++ b/modules/PowerManagement_1-1/Makefile
@@ -1,7 +1,7 @@
 ################################################################################
 # AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
 # (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
+# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
 #                                                                              #
 # This program is free software: you can redistribute it and/or modify         #
 # it under the terms of the GNU General Public License as published by         #
@@ -119,12 +119,13 @@ PROJECT := $(patsubst $(abspath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))..
 include ../../kernel/kernel.mk
 CHIBIOS := $(AMIROOS_KERNEL)
 AMIROOS = ../..
+# Licensing files
+include $(CHIBIOS)/os/license/license.mk
 # Startup files
 include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f4xx.mk
 # HAL-OSAL files
 include $(CHIBIOS)/os/hal/hal.mk
 include $(CHIBIOS)/os/hal/ports/STM32/STM32F4xx/platform.mk
-include ./board.mk
 include $(CHIBIOS)/os/hal/osal/rt/osal.mk
 # RTOS files
 include $(CHIBIOS)/os/rt/rt.mk
@@ -132,6 +133,7 @@ include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk
 # Other files (optional).
 include $(CHIBIOS)/test/lib/test.mk
 include $(CHIBIOS)/test/rt/rt_test.mk
+include $(CHIBIOS)/test/oslib/oslib_test.mk
 # AMiRo-BLT files
 include ../../bootloader/bootloader.mk
 # AMiRo-LLD files
@@ -142,17 +144,17 @@ include $(AMIROOS)/core/core.mk
 include $(AMIROOS)/unittests/unittests.mk
 
 # Define linker script file here
-LDSCRIPT= $(BOARDLD)/STM32F405xG.ld
+LDSCRIPT= STM32F405xG.ld
 
 # C sources that can be compiled in ARM or THUMB mode depending on the global
 # setting.
-CSRC = $(STARTUPSRC) \
+CSRC = $(LICSRC) \
+       $(STARTUPSRC) \
        $(KERNSRC) \
        $(PORTSRC) \
        $(OSALSRC) \
        $(HALSRC) \
        $(PLATFORMSRC) \
-       $(BOARDSRC) \
        $(MODULESCSRC) \
        $(TESTSRC) \
        $(PERIPHERYLLDCSRC) \
@@ -161,12 +163,14 @@ CSRC = $(STARTUPSRC) \
        $(CHIBIOS)/os/various/evtimer.c \
        $(CHIBIOS)/os/various/syscalls.c \
        $(CHIBIOS)/os/hal/lib/streams/chprintf.c \
+       board.c \
        module.c \
        $(APPSCSRC)
 
 # C++ sources that can be compiled in ARM or THUMB mode depending on the global
 # setting.
 CPPSRC = $(AMIROOSCORECPPSRC) \
+         $(CHIBIOS)/os/various/cpp_wrappers/syscalls_cpp.cpp \
          $(APPSCPPSRC)
 
 # C sources to be compiled in ARM mode regardless of the global setting.
@@ -196,14 +200,13 @@ ASMXSRC = $(STARTUPASM) \
           $(OSALASM) \
           $(APPSASMXSRC)
 
-INCDIR = $(CHIBIOS)/os/license \
+INCDIR = $(LICINC) \
          $(STARTUPINC) \
          $(KERNINC) \
          $(PORTINC) \
          $(OSALINC) \
          $(HALINC) \
          $(PLATFORMINC) \
-         $(BOARDINC) \
          $(MODULESINC) \
          $(TESTINC) \
          $(BOOTLOADERINC) \
@@ -290,8 +293,30 @@ ULIBS +=
 # End of user defines                                                          #
 ################################################################################
 
+################################################################################
+# Start of targets section                                                     #
+#                                                                              #
 
+# all and its dependencies
+BUILDDIR = ./build
 RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC
 include $(RULESPATH)/rules.mk
 
-include ../flash.mk
+# flash
+include $(AMIROOS)/bootloader/bootloader.mk
+FLASH_MODULES = $(PROJECT)
+FLASH_FILES = $(BUILDDIR)/$(PROJECT).$(FLASHTOOL_EXT)
+
+flash: $(FLASH_FILES)
+	$(info )
+ifeq ($(FLASHTOOL),SerialBoot)
+	$(info Flashing ($(FLASHTOOL)):)
+	$(FLASHTOOL_CMD) $(FLASHTOOL_ARGS)
+else
+	$(info ERROR: unable to flash the module (SerialBoot unavailable))
+endif
+
+#                                                                              #
+# End of targets section                                                       #
+################################################################################
+
diff --git a/modules/PowerManagement_1-1/STM32F405xG.ld b/modules/PowerManagement_1-1/STM32F405xG.ld
index 14d0805..339cd14 100644
--- a/modules/PowerManagement_1-1/STM32F405xG.ld
+++ b/modules/PowerManagement_1-1/STM32F405xG.ld
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/modules/PowerManagement_1-1/alldconf.h b/modules/PowerManagement_1-1/alldconf.h
index f6b5cb6..e54b22f 100644
--- a/modules/PowerManagement_1-1/alldconf.h
+++ b/modules/PowerManagement_1-1/alldconf.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -43,6 +43,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #define AMIROLLD_CFG_TIME_SIZE          32
 
+// required to differentiate between various sensor rings
+#include <board.h>
+
 /**
  * @brief   Enable flag for the AT24C01BN-SH-B EEPROM.
  */
@@ -69,6 +72,23 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define AMIROLLD_CFG_USE_LED
 
 /**
+ * @brief   Enable flag for the PKLCS1212E4001 buzzer.
+ */
+#define AMIROLLD_CFG_USE_PKLCS1212E4001
+
+/**
+ * @brief   Enable flag for the TPS2051BDBV power switch.
+ */
+#define AMIROLLD_CFG_USE_TPS2051BDBV
+
+/**
+ * @brief   Enable flag for the TPS62113 step-down converter.
+ */
+#define AMIROLLD_CFG_USE_TPS62113
+
+#if (BOARD_SENSORRING == BOARD_PROXIMITYSENSOR) || defined(__DOXYGEN__)
+
+/**
  * @brief   Enable flag for the MPR121 touch sensor.
  */
 #define AMIROLLD_CFG_USE_MPR121
@@ -79,24 +99,39 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define AMIROLLD_CFG_USE_PCA9544A
 
 /**
- * @brief   Enable flag for the PKLCS1212E4001 buzzer.
+ * @brief   Enable flag for the VCNL4020 proximity sensor.
  */
-#define AMIROLLD_CFG_USE_PKLCS1212E4001
+#define AMIROLLD_CFG_USE_VCNL4020
+
+#endif /* BOARD_SENSORRING == BOARD_PROXIMITYSENSOR */
+
+#if (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L0X) || defined(__DOXYGEN__)
 
 /**
- * @brief   Enable flag for the TPS2051BDBV power switch.
+ * @brief   Enable flag for the PCAL6524 GPIO extender
  */
-#define AMIROLLD_CFG_USE_TPS2051BDBV
+#define AMIROLLD_CFG_USE_PCAL6524
 
 /**
- * @brief   Enable flag for the TPS62113 step-down converter.
+ * @brief   Enable flag for the AT42Q1050 touch sensor.
  */
-#define AMIROLLD_CFG_USE_TPS62113
+#define AMIROLLD_CFG_USE_AT42QT1050
+
+#endif /* BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L0X */
+
+#if (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L1X) || defined(__DOXYGEN__)
 
 /**
- * @brief   Enable flag for the VCNL4020 proximity sensor.
+ * @brief   Enable flag for the PCAL6524 GPIO extender
  */
-#define AMIROLLD_CFG_USE_VCNL4020
+#define AMIROLLD_CFG_USE_PCAL6524
+
+/**
+ * @brief   Enable flag for the AT42Q1050 touch sensor.
+ */
+#define AMIROLLD_CFG_USE_AT42QT1050
+
+#endif /* BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L1X */
 
 #endif /* _ALLDCONF_H_ */
 
diff --git a/modules/PowerManagement_1-1/aosconf.h b/modules/PowerManagement_1-1/aosconf.h
index 070a6fb..91a190d 100644
--- a/modules/PowerManagement_1-1/aosconf.h
+++ b/modules/PowerManagement_1-1/aosconf.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 /**
- * @file    
+ * @file
  * @brief   AMiRo-OS Configuration file for the PowerManagement v1.1 module.
  * @details Contains the application specific AMiRo-OS settings.
  *
@@ -79,6 +79,16 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #endif
 
 /**
+ * @brief   Mask for the control thread to listen to certain IO events.
+ * @note    Any mandatory events (e.g. for SSSP) are enabled implicitely despite this configuration.
+ */
+#if !defined(OS_CFG_MAIN_LOOP_IOEVENT_MASK)
+  #define AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK    0
+#else
+  #define AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK    OS_CFG_MAIN_LOOP_IOEVENT_MASK
+#endif
+
+/**
  * @brief   Timeout value when waiting for events in the main loop in microseconds.
  * @details A value of 0 deactivates the timeout.
  */
@@ -101,7 +111,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  * @brief   Flag to enable SSSP.
  */
 #if !defined(OS_CFG_SSSP_ENABLE)
-  #define AMIROOS_CFG_SSSP_ENABLE               false
+  #define AMIROOS_CFG_SSSP_ENABLE               true
 #else
   #define AMIROOS_CFG_SSSP_ENABLE               OS_CFG_SSSP_ENABLE
 #endif
diff --git a/modules/PowerManagement_1-1/board.c b/modules/PowerManagement_1-1/board.c
index db3a4de..d1b1965 100644
--- a/modules/PowerManagement_1-1/board.c
+++ b/modules/PowerManagement_1-1/board.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/modules/PowerManagement_1-1/board.h b/modules/PowerManagement_1-1/board.h
index ba05342..6161e19 100644
--- a/modules/PowerManagement_1-1/board.h
+++ b/modules/PowerManagement_1-1/board.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -81,6 +81,19 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define STM32F4xx_AF_EVENTOUT           15U
 
 /*
+ * Identifiers for the several sensor rings, which can be attached to the PowerManagement v1.1 module.
+ */
+#define BOARD_NOSENSORRING              0
+#define BOARD_PROXIMITYSENSOR           1
+#define BOARD_DISTANCESENSOR_VL53L0X    2
+#define BOARD_DISTANCESENSOR_VL53L1X    3
+
+/*
+ * Configuration macro to define which type of sensor ring is attached.
+ */
+#define BOARD_SENSORRING                  BOARD_PROXIMITYSENSOR
+
+/*
  * IO pins assignments.
  */
 #define GPIOA_WKUP                      0U
diff --git a/modules/PowerManagement_1-1/board.mk b/modules/PowerManagement_1-1/board.mk
deleted file mode 100644
index b84c338..0000000
--- a/modules/PowerManagement_1-1/board.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-################################################################################
-# AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
-# (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
-#                                                                              #
-# This program is free software: you can redistribute it and/or modify         #
-# it under the terms of the GNU General Public License as published by         #
-# the Free Software Foundation, either version 3 of the License, or            #
-# (at your option) any later version.                                          #
-#                                                                              #
-# This program is distributed in the hope that it will be useful,              #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                #
-# GNU General Public License for more details.                                 #
-#                                                                              #
-# You should have received a copy of the GNU General Public License            #
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.        #
-#                                                                              #
-# This research/work was supported by the Cluster of Excellence Cognitive      #
-# Interaction Technology 'CITEC' (EXC 277) at Bielefeld University, which is   #
-# funded by the German Research Foundation (DFG).                              #
-################################################################################
-
-
-
-# absolute path to this directory
-BOARD_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
-
-# include paths
-BOARDINC = $(BOARD_DIR)
-
-# C source files
-BOARDSRC = $(BOARD_DIR)board.c
-
-# linker path
-BOARDLD = $(BOARD_DIR)
diff --git a/modules/PowerManagement_1-1/chconf.h b/modules/PowerManagement_1-1/chconf.h
index 6297a3f..b59fac8 100644
--- a/modules/PowerManagement_1-1/chconf.h
+++ b/modules/PowerManagement_1-1/chconf.h
@@ -1,6 +1,6 @@
 /*
  * AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
- * Copyright (C) 2016..2018  Thomas Schöpping et al.
+ * Copyright (C) 2016..2019  Thomas Schöpping et al.
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/modules/PowerManagement_1-1/halconf.h b/modules/PowerManagement_1-1/halconf.h
index 55bf2de..ade89d8 100644
--- a/modules/PowerManagement_1-1/halconf.h
+++ b/modules/PowerManagement_1-1/halconf.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -196,13 +196,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define HAL_USE_WDG                         FALSE
 #endif
 
-/**
- * @brief   Enables the QEI subsystem.
- */
-#if !defined(HAL_USE_QEI) || defined(__DOXYGEN__)
-#define HAL_USE_QEI                         FALSE
-#endif
-
 /*===========================================================================*/
 /* PAL driver related settings.                                              */
 /*===========================================================================*/
diff --git a/modules/PowerManagement_1-1/mcuconf.h b/modules/PowerManagement_1-1/mcuconf.h
index b09231c..6f94c38 100644
--- a/modules/PowerManagement_1-1/mcuconf.h
+++ b/modules/PowerManagement_1-1/mcuconf.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/modules/PowerManagement_1-1/module.c b/modules/PowerManagement_1-1/module.c
index 6fdd530..11fa65f 100644
--- a/modules/PowerManagement_1-1/module.c
+++ b/modules/PowerManagement_1-1/module.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -65,13 +65,13 @@ CANConfig moduleHalCanConfig = {
   /* btr  */ CAN_BTR_SJW(1) | CAN_BTR_TS2(3) | CAN_BTR_TS1(15) | CAN_BTR_BRP(1),
 };
 
-I2CConfig moduleHalI2cProxPm18Pm33GaugeRearConfig = {
+I2CConfig moduleHalI2cSrPm18Pm33GaugeRearConfig = {
   /* I²C mode   */ OPMODE_I2C,
   /* frequency  */ 400000, // TODO: replace with some macro (-> ChibiOS/HAL)
   /* duty cycle */ FAST_DUTY_CYCLE_2,
 };
 
-I2CConfig moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig = {
+I2CConfig moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig = {
   /* I²C mode   */ OPMODE_I2C,
   /* frequency  */ 400000, // TODO: replace with some macro (-> ChibiOS/HAL)
   /* duty cycle */ FAST_DUTY_CYCLE_2,
@@ -149,8 +149,19 @@ ROMCONST apalControlGpio_t moduleGpioIrInt1 = {
   /* GPIO */ &_gpioIrInt1,
   /* meta */ {
     /* direction      */ APAL_GPIO_DIRECTION_INPUT,
+#if (BOARD_SENSORRING == BOARD_PROXIMITYSENSOR)
     /* active state   */ (VCNL4020_LLD_INT_EDGE == APAL_GPIO_EDGE_RISING) ? APAL_GPIO_ACTIVE_HIGH : APAL_GPIO_ACTIVE_LOW,
     /* interrupt edge */ VCNL4020_LLD_INT_EDGE,
+#elif (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L0X)
+    /* active state   */ (PCAL6524_LLD_INT_EDGE == APAL_GPIO_EDGE_RISING) ? APAL_GPIO_ACTIVE_HIGH : APAL_GPIO_ACTIVE_LOW,
+    /* interrupt edge */ PCAL6524_LLD_INT_EDGE,
+#elif (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L1X)
+    /* active state   */ (PCAL6524_LLD_INT_EDGE == APAL_GPIO_EDGE_RISING) ? APAL_GPIO_ACTIVE_HIGH : APAL_GPIO_ACTIVE_LOW,
+    /* interrupt edge */ PCAL6524_LLD_INT_EDGE,
+#else
+    /* active state   */ APAL_GPIO_ACTIVE_LOW,
+    /* interrupt edge */ APAL_GPIO_EDGE_NONE,
+#endif
   },
 };
 
@@ -341,8 +352,19 @@ ROMCONST apalControlGpio_t moduleGpioIrInt2 = {
   /* GPIO */ &_gpioIrInt2,
   /* meta */ {
     /* direction      */ APAL_GPIO_DIRECTION_INPUT,
+#if (BOARD_SENSORRING == BOARD_PROXIMITYSENSOR)
     /* active state   */ (VCNL4020_LLD_INT_EDGE == APAL_GPIO_EDGE_RISING) ? APAL_GPIO_ACTIVE_HIGH : APAL_GPIO_ACTIVE_LOW,
     /* interrupt edge */ VCNL4020_LLD_INT_EDGE,
+#elif (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L0X)
+    /* active state   */ (PCAL6524_LLD_INT_EDGE == APAL_GPIO_EDGE_RISING) ? APAL_GPIO_ACTIVE_HIGH : APAL_GPIO_ACTIVE_LOW,
+    /* interrupt edge */ PCAL6524_LLD_INT_EDGE,
+#elif (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L1X)
+    /* active state   */ (PCAL6524_LLD_INT_EDGE == APAL_GPIO_EDGE_RISING) ? APAL_GPIO_ACTIVE_HIGH : APAL_GPIO_ACTIVE_LOW,
+    /* interrupt edge */ PCAL6524_LLD_INT_EDGE,
+#else
+    /* active state   */ APAL_GPIO_ACTIVE_LOW,
+    /* interrupt edge */ APAL_GPIO_EDGE_NONE,
+#endif
   },
 };
 
@@ -357,8 +379,19 @@ ROMCONST apalControlGpio_t moduleGpioTouchInt = {
   /* GPIO */ &_gpioTouchInt,
   /* meta */ {
     /* direction      */ APAL_GPIO_DIRECTION_INPUT,
+#if (BOARD_SENSORRING == BOARD_PROXIMITYSENSOR)
     /* active state   */ (MPR121_LLD_INT_EDGE == APAL_GPIO_EDGE_RISING) ? APAL_GPIO_ACTIVE_HIGH : APAL_GPIO_ACTIVE_LOW,
     /* interrupt edge */ MPR121_LLD_INT_EDGE,
+#elif (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L0X)
+    /* active state   */ (AT42QT1050_LLD_INT_EDGE == APAL_GPIO_EDGE_RISING) ? APAL_GPIO_ACTIVE_HIGH : APAL_GPIO_ACTIVE_LOW,
+    /* interrupt edge */ AT42QT1050_LLD_INT_EDGE,
+#elif (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L1X)
+    /* active state   */ (AT42QT1050_LLD_INT_EDGE == APAL_GPIO_EDGE_RISING) ? APAL_GPIO_ACTIVE_HIGH : APAL_GPIO_ACTIVE_LOW,
+    /* interrupt edge */ AT42QT1050_LLD_INT_EDGE,
+#else
+    /* active state   */ APAL_GPIO_ACTIVE_LOW,
+    /* interrupt edge */ APAL_GPIO_EDGE_NONE,
+#endif
   },
 };
 
@@ -520,7 +553,7 @@ ROMCONST char* moduleShellPrompt = "PowerManagement";
 #endif
 
 /** @} */
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
+
 /*===========================================================================*/
 /**
  * @name Startup Shutdown Synchronization Protocol (SSSP)
@@ -529,7 +562,6 @@ ROMCONST char* moduleShellPrompt = "PowerManagement";
 /*===========================================================================*/
 
 /** @} */
-#endif
 
 /*===========================================================================*/
 /**
@@ -539,7 +571,7 @@ ROMCONST char* moduleShellPrompt = "PowerManagement";
 /*===========================================================================*/
 
 AT24C01BNDriver moduleLldEeprom = {
-  /* I2C driver   */ &MODULE_HAL_I2C_PROX_PM42_PM50_PMVDD_EEPROM_TOUCH_GAUGEFRONT,
+  /* I2C driver   */ &MODULE_HAL_I2C_SR_PM42_PM50_PMVDD_EEPROM_GAUGEFRONT,
   /* I2C address  */ AT24C01BN_LLD_I2C_ADDR_FIXED,
 };
 
@@ -554,47 +586,47 @@ BQ24103ADriver moduleLldBatteryChargerRear = {
 };
 
 BQ27500Driver moduleLldFuelGaugeFront = {
-  /* I2C driver         */ &MODULE_HAL_I2C_PROX_PM42_PM50_PMVDD_EEPROM_TOUCH_GAUGEFRONT,
+  /* I2C driver         */ &MODULE_HAL_I2C_SR_PM42_PM50_PMVDD_EEPROM_GAUGEFRONT,
   /* battery low GPIO   */ &moduleGpioGaugeBatLow1,
   /* battery good GPIO  */ &moduleGpioGaugeBatGd1,
 };
 
 BQ27500Driver moduleLldFuelGaugeRear = {
-  /* I2C driver         */ &MODULE_HAL_I2C_PROX_PM18_PM33_GAUGEREAR,
+  /* I2C driver         */ &MODULE_HAL_I2C_SR_PM18_PM33_GAUGEREAR,
   /* battery low GPIO   */ &moduleGpioGaugeBatLow2,
   /* battery good GPIO  */ &moduleGpioGaugeBatGd2,
 };
 
 INA219Driver moduleLldPowerMonitorVdd = {
-  /* I2C Driver       */ &MODULE_HAL_I2C_PROX_PM42_PM50_PMVDD_EEPROM_TOUCH_GAUGEFRONT,
+  /* I2C Driver       */ &MODULE_HAL_I2C_SR_PM42_PM50_PMVDD_EEPROM_GAUGEFRONT,
   /* I²C address      */ INA219_LLD_I2C_ADDR_A0 | INA219_LLD_I2C_ADDR_A1,
   /* current LSB (uA) */ 0x00u,
   /* configuration    */ NULL,
 };
 
 INA219Driver moduleLldPowerMonitorVio18 = {
-  /* I2C Driver       */ &MODULE_HAL_I2C_PROX_PM18_PM33_GAUGEREAR,
+  /* I2C Driver       */ &MODULE_HAL_I2C_SR_PM18_PM33_GAUGEREAR,
   /* I²C address      */ INA219_LLD_I2C_ADDR_A1,
   /* current LSB (uA) */ 0x00u,
   /* configuration    */ NULL,
 };
 
 INA219Driver moduleLldPowerMonitorVio33 = {
-  /* I2C Driver       */ &MODULE_HAL_I2C_PROX_PM18_PM33_GAUGEREAR,
+  /* I2C Driver       */ &MODULE_HAL_I2C_SR_PM18_PM33_GAUGEREAR,
   /* I²C address      */ INA219_LLD_I2C_ADDR_FIXED,
   /* current LSB (uA) */ 0x00u,
   /* configuration    */ NULL,
 };
 
 INA219Driver moduleLldPowerMonitorVsys42 = {
-  /* I2C Driver       */ &MODULE_HAL_I2C_PROX_PM42_PM50_PMVDD_EEPROM_TOUCH_GAUGEFRONT,
+  /* I2C Driver       */ &MODULE_HAL_I2C_SR_PM42_PM50_PMVDD_EEPROM_GAUGEFRONT,
   /* I²C address      */ INA219_LLD_I2C_ADDR_FIXED,
   /* current LSB (uA) */ 0x00u,
   /* configuration    */ NULL,
 };
 
 INA219Driver moduleLldPowerMonitorVio50 = {
-  /* I2C Driver       */ &MODULE_HAL_I2C_PROX_PM42_PM50_PMVDD_EEPROM_TOUCH_GAUGEFRONT,
+  /* I2C Driver       */ &MODULE_HAL_I2C_SR_PM42_PM50_PMVDD_EEPROM_GAUGEFRONT,
   /* I²C address      */ INA219_LLD_I2C_ADDR_A1,
   /* current LSB (uA) */ 0x00u,
   /* configuration    */ NULL,
@@ -604,32 +636,74 @@ LEDDriver moduleLldStatusLed = {
   /* LED GPIO */ &moduleGpioLed,
 };
 
+TPS62113Driver moduleLldStepDownConverter = {
+  /* Power enable GPIO */ &moduleGpioPowerEn,
+};
+
+#if (BOARD_SENSORRING == BOARD_PROXIMITYSENSOR) || defined(__DOXYGEN__)
+
 MPR121Driver moduleLldTouch = {
-  /* I²C Driver */ &MODULE_HAL_I2C_PROX_PM42_PM50_PMVDD_EEPROM_TOUCH_GAUGEFRONT,
+  /* I²C Driver */ &MODULE_HAL_I2C_SR_PM42_PM50_PMVDD_EEPROM_GAUGEFRONT,
 };
 
 PCA9544ADriver moduleLldI2cMultiplexer1 = {
-  /* I²C driver   */ &MODULE_HAL_I2C_PROX_PM18_PM33_GAUGEREAR,
+  /* I²C driver   */ &MODULE_HAL_I2C_SR_PM18_PM33_GAUGEREAR,
   /* I²C address  */ PCA9544A_LLD_I2C_ADDR_A0 | PCA9544A_LLD_I2C_ADDR_A1 | PCA9544A_LLD_I2C_ADDR_A2,
 };
 
 PCA9544ADriver moduleLldI2cMultiplexer2 = {
-  /* I²C driver   */ &MODULE_HAL_I2C_PROX_PM42_PM50_PMVDD_EEPROM_TOUCH_GAUGEFRONT,
+  /* I²C driver   */ &MODULE_HAL_I2C_SR_PM42_PM50_PMVDD_EEPROM_GAUGEFRONT,
   /* I²C address  */ PCA9544A_LLD_I2C_ADDR_A0 | PCA9544A_LLD_I2C_ADDR_A1 | PCA9544A_LLD_I2C_ADDR_A2,
 };
 
-TPS62113Driver moduleLldStepDownConverter = {
-  /* Power enable GPIO */ &moduleGpioPowerEn,
-};
-
 VCNL4020Driver moduleLldProximity1 = {
-  /* I²C Driver */ &MODULE_HAL_I2C_PROX_PM18_PM33_GAUGEREAR,
+  /* I²C Driver */ &MODULE_HAL_I2C_SR_PM18_PM33_GAUGEREAR,
 };
 
 VCNL4020Driver moduleLldProximity2 = {
-  /* I²C Driver */ &MODULE_HAL_I2C_PROX_PM42_PM50_PMVDD_EEPROM_TOUCH_GAUGEFRONT,
+  /* I²C Driver */ &MODULE_HAL_I2C_SR_PM42_PM50_PMVDD_EEPROM_GAUGEFRONT,
+};
+
+#endif /* BOARD_SENSORRING == BOARD_PROXIMITYSENSOR */
+
+#if (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L0X) || defined(__DOXYGEN__)
+
+PCAL6524Driver moduleLldGpioExtender1 = {
+  /* I²C driver   */ &MODULE_HAL_I2C_SR_PM18_PM33_GAUGEREAR,
+  /* I²C address  */ PCAL6524_LLD_I2C_ADDR_VDD,
+};
+
+PCAL6524Driver moduleLldGpioExtender2 = {
+  /* I²C driver   */ &MODULE_HAL_I2C_SR_PM42_PM50_PMVDD_EEPROM_GAUGEFRONT,
+  /* I²C address  */ PCAL6524_LLD_I2C_ADDR_VDD,
+};
+
+AT42QT1050Driver moduleLldTouch = {
+  /* I²C driver   */ &MODULE_HAL_I2C_SR_PM42_PM50_PMVDD_EEPROM_GAUGEFRONT,
+  /* I²C address  */ AT42QT1050_LLD_I2C_ADDRSEL_LOW,
+};
+
+#endif /* BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L0X */
+
+#if (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L1X) || defined(__DOXYGEN__)
+
+PCAL6524Driver moduleLldGpioExtender1 = {
+  /* I²C driver   */ &MODULE_HAL_I2C_SR_PM18_PM33_GAUGEREAR,
+  /* I²C address  */ PCAL6524_LLD_I2C_ADDR_VDD,
+};
+
+PCAL6524Driver moduleLldGpioExtender2 = {
+  /* I²C driver   */ &MODULE_HAL_I2C_SR_PM42_PM50_PMVDD_EEPROM_GAUGEFRONT,
+  /* I²C address  */ PCAL6524_LLD_I2C_ADDR_VDD,
+};
+
+AT42QT1050Driver moduleLldTouch = {
+  /* I²C driver   */ &MODULE_HAL_I2C_SR_PM42_PM50_PMVDD_EEPROM_GAUGEFRONT,
+  /* I²C address  */ AT42QT1050_LLD_I2C_ADDRSEL_LOW,
 };
 
+#endif /* BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L1X */
+
 /** @} */
 
 /*===========================================================================*/
@@ -641,7 +715,9 @@ VCNL4020Driver moduleLldProximity2 = {
 #if (AMIROOS_CFG_TESTS_ENABLE == true) || defined(__DOXYGEN__)
 #include <string.h>
 
-/* ADC  */
+/*
+ * ADC
+ */
 static int _utShellCmdCb_Adc(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -665,7 +741,9 @@ aos_unittest_t moduleUtAdcVsys = {
   /* data           */ &_utAdcVsysData,
 };
 
-/* AT24C01BN-SH-B (EEPROM) */
+/*
+ * AT24C01BN-SH-B (EEPROM)
+ */
 static int _utShellCmdCb_AlldAt24c01bn(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -689,7 +767,9 @@ aos_unittest_t moduleUtAlldAt24c01bn = {
   /* data           */ &_utAlldAt24c01bnData,
 };
 
-/* BQ24103A (battery charger) */
+/*
+ * BQ24103A (battery charger)
+ */
 static int _utShellCmdCb_AlldBq24103a(BaseSequentialStream* stream, int argc, char* argv[])
 {
   // local variables
@@ -739,7 +819,9 @@ aos_unittest_t moduleUtAlldBq24103a = {
   /* data           */ NULL,
 };
 
-/* BQ27500 (fuel gauge) */
+/*
+ * BQ27500 (fuel gauge)
+ */
 static int _utShellCmdCb_AlldBq27500(BaseSequentialStream* stream, int argc, char* argv[])
 {
   // evaluate arguments
@@ -782,7 +864,9 @@ aos_unittest_t moduleUtAlldBq27500 = {
   /* data           */ &_utAlldBq27500Data,
 };
 
-/* BQ27500 (fuel gauge) in combination with BQ24103A (battery charger) */
+/*
+ * BQ27500 (fuel gauge) in combination with BQ24103A (battery charger)
+ */
 static int _utShellCmdCb_AlldBq27500Bq24103a(BaseSequentialStream* stream, int argc, char* argv[])
 {
   // evaluate arguments
@@ -830,7 +914,9 @@ aos_unittest_t moduleUtAlldBq27500Bq24103a = {
   /* data           */ &_utAlldBq27500Bq24103aData,
 };
 
-/* INA219 (power monitor) */
+/*
+ * INA219 (power monitor)
+ */
 static int _utShellCmdCb_AlldIna219(BaseSequentialStream* stream, int argc, char* argv[])
 {
   // evaluate arguments
@@ -909,7 +995,9 @@ aos_unittest_t moduleUtAlldIna219 = {
   /* data           */ &_utAlldIna219Data,
 };
 
-/* Status LED */
+/*
+ * Status LED
+ */
 static int _utShellCmdCb_AlldLed(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -929,76 +1017,9 @@ aos_unittest_t moduleUtAlldLed = {
   /* data           */ &moduleLldStatusLed,
 };
 
-/* MPR121 (touch sensor) */
-static int _utShellCmdCb_AlldMpr121(BaseSequentialStream* stream, int argc, char* argv[])
-{
-  (void)argc;
-  (void)argv;
-  aosUtRun(stream, &moduleUtAlldMpr121, NULL);
-  return AOS_OK;
-}
-static ut_mpr121data_t _utAlldMpr121Data= {
-  /* MPR121 driver  */ &moduleLldTouch,
-  /* timeout        */ MICROSECONDS_PER_SECOND,
-  /* event source   */ &aos.events.io,
-  /* event flags    */ MODULE_OS_IOEVENTFLAGS_TOUCHINT,
-};
-aos_unittest_t moduleUtAlldMpr121 = {
-  /* name           */ "MPR121",
-  /* info           */ "touch sensor",
-  /* test function  */ utAlldMpr121Func,
-  /* shell command  */ {
-    /* name     */ "unittest:Touch",
-    /* callback */ _utShellCmdCb_AlldMpr121,
-    /* next     */ NULL,
-  },
-  /* data           */ &_utAlldMpr121Data,
-};
-
-/* PCA9544A (I2C multiplexer) */
-static int _utShellCmdCb_AlldPca5944a(BaseSequentialStream* stream, int argc, char* argv[])
-{
-  // evaluate arguments
-  if (argc == 2) {
-    if (strcmp(argv[1], "#1") == 0) {
-      ((ut_pca9544adata_t*)moduleUtAlldPca9544a.data)->driver = &moduleLldI2cMultiplexer1;
-      aosUtRun(stream, &moduleUtAlldPca9544a, "I2C bus #1");
-      ((ut_pca9544adata_t*)moduleUtAlldPca9544a.data)->driver = NULL;
-      return AOS_OK;
-    }
-    else if (strcmp(argv[1], "#2") == 0) {
-      ((ut_pca9544adata_t*)moduleUtAlldPca9544a.data)->driver = &moduleLldI2cMultiplexer2;
-      aosUtRun(stream, &moduleUtAlldPca9544a, "I2C bus #2");
-      ((ut_pca9544adata_t*)moduleUtAlldPca9544a.data)->driver = NULL;
-      return AOS_OK;
-    }
-  }
-  // print help
-  chprintf(stream, "Usage: %s OPTION\n", argv[0]);
-  chprintf(stream, "Options:\n");
-  chprintf(stream, "  #1\n");
-  chprintf(stream, "    Test the multiplexer on the I2C bus #1.\n");
-  chprintf(stream, "  #2\n");
-  chprintf(stream, "    Test the multiplexer on the I2C bus #2.\n");
-  return AOS_INVALID_ARGUMENTS;
-}
-static ut_pca9544adata_t _utAlldPca9544aData = {
-  /* driver   */ NULL,
-  /* timeout  */ MICROSECONDS_PER_SECOND,
-};
-aos_unittest_t moduleUtAlldPca9544a = {
-  /* name           */ "PCA9544A",
-  /* info           */ "I2C multiplexer",
-  /* test function  */ utAlldPca9544aFunc,
-  /* shell command  */ {
-    /* name     */ "unittest:I2CMultiplexer",
-    /* callback */ _utShellCmdCb_AlldPca5944a,
-    /* next     */ NULL,
-  },
-  /* data           */ &_utAlldPca9544aData,
-};
-
-/* PKLCS1212E4001 (buzzer) */
+/*
+ * PKLCS1212E4001 (buzzer)
+ */
 static int _utShellCmdCb_AlldPklcs1212e4001(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -1022,7 +1043,9 @@ aos_unittest_t moduleUtAlldPklcs1212e4001 = {
   /* data           */ &_utAlldPklcs1212e4001Data,
 };
 
-/* TPS62113 (stop-down converter) */
+/*
+ * TPS62113 (stop-down converter)
+ */
 static int _utShellCmdCb_AlldTps62113(BaseSequentialStream* stream, int argc, char* argv[])
 {
   // Although there are four TPS62113 on the PCB, they all share the same input signal.
@@ -1044,7 +1067,9 @@ aos_unittest_t moduleUtAlldTps62113 = {
   /* data           */ &moduleLldStepDownConverter,
 };
 
-/* TPS62113 (step-donw converter) in combination with INA219 (power monitor) */
+/*
+ * TPS62113 (step-donw converter) in combination with INA219 (power monitor)
+ */
 static int _utShellCmdCb_AlldTps62113Ina219(BaseSequentialStream* stream, int argc, char* argv[])
 {
   (void)argc;
@@ -1069,7 +1094,84 @@ aos_unittest_t moduleUtAlldTps62113Ina219 = {
   /* data           */ &_utAlldTps62113Ina219Data,
 };
 
-/* VCNL4020 (proximity sensor) */
+#if (BOARD_SENSORRING == BOARD_PROXIMITYSENSOR) || defined(__DOXYGEN__)
+
+/*
+ * MPR121 (touch sensor)
+ */
+static int _utShellCmdCb_AlldMpr121(BaseSequentialStream* stream, int argc, char* argv[])
+{
+  (void)argc;
+  (void)argv;
+  aosUtRun(stream, &moduleUtAlldMpr121, NULL);
+  return AOS_OK;
+}
+static ut_mpr121data_t _utAlldMpr121Data= {
+  /* MPR121 driver  */ &moduleLldTouch,
+  /* timeout        */ MICROSECONDS_PER_SECOND,
+  /* event source   */ &aos.events.io,
+  /* event flags    */ MODULE_OS_IOEVENTFLAGS_TOUCHINT,
+};
+aos_unittest_t moduleUtAlldMpr121 = {
+  /* name           */ "MPR121",
+  /* info           */ "touch sensor",
+  /* test function  */ utAlldMpr121Func,
+  /* shell command  */ {
+    /* name     */ "unittest:Touch",
+    /* callback */ _utShellCmdCb_AlldMpr121,
+    /* next     */ NULL,
+  },
+  /* data           */ &_utAlldMpr121Data,
+};
+
+/*
+ * PCA9544A (I2C multiplexer)
+ */
+static int _utShellCmdCb_AlldPca5944a(BaseSequentialStream* stream, int argc, char* argv[])
+{
+  // evaluate arguments
+  if (argc == 2) {
+    if (strcmp(argv[1], "#1") == 0) {
+      ((ut_pca9544adata_t*)moduleUtAlldPca9544a.data)->driver = &moduleLldI2cMultiplexer1;
+      aosUtRun(stream, &moduleUtAlldPca9544a, "I2C bus #1");
+      ((ut_pca9544adata_t*)moduleUtAlldPca9544a.data)->driver = NULL;
+      return AOS_OK;
+    }
+    else if (strcmp(argv[1], "#2") == 0) {
+      ((ut_pca9544adata_t*)moduleUtAlldPca9544a.data)->driver = &moduleLldI2cMultiplexer2;
+      aosUtRun(stream, &moduleUtAlldPca9544a, "I2C bus #2");
+      ((ut_pca9544adata_t*)moduleUtAlldPca9544a.data)->driver = NULL;
+      return AOS_OK;
+    }
+  }
+  // print help
+  chprintf(stream, "Usage: %s OPTION\n", argv[0]);
+  chprintf(stream, "Options:\n");
+  chprintf(stream, "  #1\n");
+  chprintf(stream, "    Test the multiplexer on the I2C bus #1.\n");
+  chprintf(stream, "  #2\n");
+  chprintf(stream, "    Test the multiplexer on the I2C bus #2.\n");
+  return AOS_INVALID_ARGUMENTS;
+}
+static ut_pca9544adata_t _utAlldPca9544aData = {
+  /* driver   */ NULL,
+  /* timeout  */ MICROSECONDS_PER_SECOND,
+};
+aos_unittest_t moduleUtAlldPca9544a = {
+  /* name           */ "PCA9544A",
+  /* info           */ "I2C multiplexer",
+  /* test function  */ utAlldPca9544aFunc,
+  /* shell command  */ {
+    /* name     */ "unittest:I2CMultiplexer",
+    /* callback */ _utShellCmdCb_AlldPca5944a,
+    /* next     */ NULL,
+  },
+  /* data           */ &_utAlldPca9544aData,
+};
+
+/*
+ * VCNL4020 (proximity sensor)
+ */
 static void _utAlldVcnl4020_disableInterrupt(VCNL4020Driver* vcnl)
 {
   uint8_t intstatus;
@@ -1215,6 +1317,162 @@ aos_unittest_t moduleUtAlldVcnl4020 = {
   /* data           */ &_utAlldVcnl4020Data,
 };
 
+#endif /* BOARD_SENSORRING == BOARD_PROXIMITYSENSOR */
+
+#if (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L0X) || defined(__DOXYGEN__)
+
+/*
+ * PCAL6524 (GPIO extender)
+ */
+static int _utShellCmdCb_AlldPcal6524(BaseSequentialStream* stream, int argc, char* argv[])
+{
+  // evaluate arguments
+  if (argc == 2) {
+    if (strcmp(argv[1], "#1") == 0) {
+      ((ut_pcal6524data_t*)moduleUtAlldPcal6524.data)->pcal6524d = &moduleLldGpioExtender1;
+      aosUtRun(stream, &moduleUtAlldPcal6524, "I2C bus #1");
+      ((ut_pcal6524data_t*)moduleUtAlldPcal6524.data)->pcal6524d = NULL;
+      return AOS_OK;
+    }
+    else if (strcmp(argv[1], "#2") == 0) {
+      ((ut_pcal6524data_t*)moduleUtAlldPcal6524.data)->pcal6524d = &moduleLldGpioExtender2;
+      aosUtRun(stream, &moduleUtAlldPcal6524, "I2C bus #2");
+      ((ut_pcal6524data_t*)moduleUtAlldPcal6524.data)->pcal6524d = NULL;
+      return AOS_OK;
+    }
+  }
+  // print help
+  chprintf(stream, "Usage: %s OPTION\n", argv[0]);
+  chprintf(stream, "Options:\n");
+  chprintf(stream, "  #1\n");
+  chprintf(stream, "    Test the GPIO extender on the I2C bus #1.\n");
+  chprintf(stream, "  #2\n");
+  chprintf(stream, "    Test the GPIO extender on the I2C bus #2.\n");
+  return AOS_INVALID_ARGUMENTS;
+}
+static ut_pcal6524data_t _utAlldPcal6524Data = {
+  /* driver   */ NULL,
+  /* timeout  */ MICROSECONDS_PER_SECOND,
+};
+aos_unittest_t moduleUtAlldPcal6524 = {
+  /* name           */ "PCAL6524",
+  /* info           */ "GPIO extender",
+  /* test function  */ utAlldPcal6524Func,
+  /* shell command  */ {
+    /* name     */ "unittest:GPIOExtender",
+    /* callback */ _utShellCmdCb_AlldPcal6524,
+    /* next     */ NULL,
+  },
+  /* data           */ &_utAlldPcal6524Data,
+};
+
+/*
+ * AT42QT1050 (touch sensor)
+ */
+static int _utShellCmdCb_AlldAt42qt1050(BaseSequentialStream* stream, int argc, char* argv[])
+{
+  (void)argc;
+  (void)argv;
+  aosUtRun(stream, &moduleUtAlldAt42qt1050, NULL);
+  return AOS_OK;
+}
+static ut_at42qt1050data_t _utAlldMpr121Data= {
+  /* AT42QT1050 driver  */ &moduleLldTouch,
+  /* timeout            */ MICROSECONDS_PER_SECOND,
+  /* event source       */ &aos.events.io,
+  /* event flags        */ MODULE_OS_IOEVENTFLAGS_TOUCHINT,
+};
+aos_unittest_t moduleUtAlldAt42qt1050 = {
+  /* name           */ "AT42QT1050",
+  /* info           */ "touch sensor",
+  /* test function  */ utAlldAt42qt1050Func,
+  /* shell command  */ {
+    /* name     */ "unittest:Touch",
+    /* callback */ _utShellCmdCb_AlldAt42qt1050,
+    /* next     */ NULL,
+  },
+  /* data           */ &_utAlldMpr121Data,
+};
+
+#endif /* BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L0X */
+
+#if (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L1X) || defined(__DOXYGEN__)
+
+/*
+ * PCAL6524 (GPIO extender)
+ */
+static int _utShellCmdCb_AlldPcal6524(BaseSequentialStream* stream, int argc, char* argv[])
+{
+  // evaluate arguments
+  if (argc == 2) {
+    if (strcmp(argv[1], "#1") == 0) {
+      ((ut_pcal6524data_t*)moduleUtAlldPcal6524.data)->pcal6524d = &moduleLldGpioExtender1;
+      aosUtRun(stream, &moduleUtAlldPcal6524, "I2C bus #1");
+      ((ut_pcal6524data_t*)moduleUtAlldPcal6524.data)->pcal6524d = NULL;
+      return AOS_OK;
+    }
+    else if (strcmp(argv[1], "#2") == 0) {
+      ((ut_pcal6524data_t*)moduleUtAlldPcal6524.data)->pcal6524d = &moduleLldGpioExtender2;
+      aosUtRun(stream, &moduleUtAlldPcal6524, "I2C bus #2");
+      ((ut_pcal6524data_t*)moduleUtAlldPcal6524.data)->pcal6524d = NULL;
+      return AOS_OK;
+    }
+  }
+  // print help
+  chprintf(stream, "Usage: %s OPTION\n", argv[0]);
+  chprintf(stream, "Options:\n");
+  chprintf(stream, "  #1\n");
+  chprintf(stream, "    Test the GPIO extender on the I2C bus #1.\n");
+  chprintf(stream, "  #2\n");
+  chprintf(stream, "    Test the GPIO extender on the I2C bus #2.\n");
+  return AOS_INVALID_ARGUMENTS;
+}
+static ut_pcal6524data_t _utAlldPcal6524Data = {
+  /* driver   */ NULL,
+  /* timeout  */ MICROSECONDS_PER_SECOND,
+};
+aos_unittest_t moduleUtAlldPcal6524 = {
+  /* name           */ "PCAL6524",
+  /* info           */ "GPIO extender",
+  /* test function  */ utAlldPcal6524Func,
+  /* shell command  */ {
+    /* name     */ "unittest:GPIOExtender",
+    /* callback */ _utShellCmdCb_AlldPcal6524,
+    /* next     */ NULL,
+  },
+  /* data           */ &_utAlldPcal6524Data,
+};
+
+/*
+ * AT42QT1050 (touch sensor)
+ */
+static int _utShellCmdCb_AlldAt42qt1050(BaseSequentialStream* stream, int argc, char* argv[])
+{
+  (void)argc;
+  (void)argv;
+  aosUtRun(stream, &moduleUtAlldAt42qt1050, NULL);
+  return AOS_OK;
+}
+static ut_at42qt1050data_t _utAlldMpr121Data= {
+  /* AT42QT1050 driver  */ &moduleLldTouch,
+  /* timeout            */ MICROSECONDS_PER_SECOND,
+  /* event source       */ &aos.events.io,
+  /* event flags        */ MODULE_OS_IOEVENTFLAGS_TOUCHINT,
+};
+aos_unittest_t moduleUtAlldAt42qt1050 = {
+  /* name           */ "AT42QT1050",
+  /* info           */ "touch sensor",
+  /* test function  */ utAlldAt42qt1050Func,
+  /* shell command  */ {
+    /* name     */ "unittest:Touch",
+    /* callback */ _utShellCmdCb_AlldAt42qt1050,
+    /* next     */ NULL,
+  },
+  /* data           */ &_utAlldMpr121Data,
+};
+
+#endif /* BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L1X */
+
 #endif /* AMIROOS_CFG_TESTS_ENABLE == true */
 
 /** @} */
diff --git a/modules/PowerManagement_1-1/module.h b/modules/PowerManagement_1-1/module.h
index 1d25a2b..b561cf5 100644
--- a/modules/PowerManagement_1-1/module.h
+++ b/modules/PowerManagement_1-1/module.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -34,32 +34,32 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 /*===========================================================================*/
 
-/*
+/**
  * @brief Makro to store data in the core coupled memory (ccm).
  *        Example:
  *        int compute_buffer[128] CCM_RAM;
  *
  * @note The ccm is not connected to any bus system.
  */
-#define CCM_RAM                                 __attribute__((section(".ram4"), aligned(4)))
+#define CCM_RAM(...)                            __attribute__((section(".ram4"), ##__VA_ARGS__))
 
-/*
+/**
  * @brief Makro to store data in the ethernet memory (eth).
  *        Example:
  *        int dma_buffer[128] ETH_RAM;
  *
  * @note The eth is a dedicated memory block with its own DMA controller.
  */
-#define ETH_RAM                                 __attribute__((section(".ram2"), aligned(4)))
+#define ETH_RAM(...)                            __attribute__((section(".ram2"), ##__VA_ARGS__))
 
-/*
+/**
  * @brief Makro to store data in the backup memory (bckp).
  *        Example:
  *        int backup_buffer[128] BCKP_RAM;
  *
  * @note The eth is a dedicated memory block with its own DMA controller.
  */
-#define BCKP_RAM                                __attribute__((section(".ram5"), aligned(4)))
+#define BCKP_RAM(...)                           __attribute__((section(".ram5"), ##__VA_ARGS__))
 
 /** @} */
 
@@ -92,24 +92,58 @@ extern ADCConversionGroup moduleHalAdcVsysConversionGroup;
 extern CANConfig moduleHalCanConfig;
 
 /**
- * @brief   I2C driver to access multiplexer, proximity sensors 1 to 4, power monitors for VIO1.8 and VIO 3.3, and fuel gauge (rear battery).
+ * @brief   I2C driver to access the sensor ring, power monitors for VIO1.8 and VIO3.3, and fuel gauge (rear battery).
+ * @details Depending on the attached sensor ring, the devices connected to this bus vary:
+ *          ProximitySensor:
+ *            - I2C multiplexer (PCA9544A)
+ *            - proximity sensors (VCNL4020) #1 - #4
+ *          DistanceSensor (VL53L0X):
+ *            TODO
+ *          DistanceSensor (VL53L1X):
+ *            TODO
  */
-#define MODULE_HAL_I2C_PROX_PM18_PM33_GAUGEREAR I2CD1
+#define MODULE_HAL_I2C_SR_PM18_PM33_GAUGEREAR   I2CD1
 
 /**
- * @brief   Configuration for the multiplexer, proximity sensors 1 to 4, power monitors for VIO1.8 and VIO 3.3, and fuel gauge (rear battery) I2C driver.
+ * @brief   Configuration for the sensor ring, power monitors for VIO1.8 and VIO3.3, and fuel gauge (rear battery) I2C driver.
+ * @details Depending on the attached sensor ring, the devices connected to this bus vary:
+ *          ProximitySensor:
+ *            - I2C multiplexer (PCA9544A)
+ *            - proximity sensors (VCNL4020) #1 - #4
+ *          DistanceSensor (VL53L0X):
+ *            TODO
+ *          DistanceSensor (VL53L1X):
+ *            TODO
  */
-extern I2CConfig moduleHalI2cProxPm18Pm33GaugeRearConfig;
+extern I2CConfig moduleHalI2cSrPm18Pm33GaugeRearConfig;
 
 /**
- * @brief   I2C driver to access multiplexer, proximity sensors 5 to 8, power monitors for VSYS4.2, VIO 5.0 and VDD, EEPROM, touch sensor, and fuel gauge (front battery).
+ * @brief   I2C driver to access the sensor ring, power monitors for VSYS4.2, VIO5.0 and VDD, EEPROM, and fuel gauge (front battery).
+ * @details Depending on the attached sensor ring, the devices connected to this bus vary:
+ *          ProximitySensor:
+ *            - I2C multiplexer (PCA9544A)
+ *            - proximity sensors (VCNL4020) #1 - #4
+ *            - touch sensor (MPR121)
+ *          DistanceSensor (VL53L0X):
+ *            TODO
+ *          DistanceSensor (VL53L1X):
+ *            TODO
  */
-#define MODULE_HAL_I2C_PROX_PM42_PM50_PMVDD_EEPROM_TOUCH_GAUGEFRONT I2CD2
+#define MODULE_HAL_I2C_SR_PM42_PM50_PMVDD_EEPROM_GAUGEFRONT I2CD2
 
 /**
- * @brief   Configuration for the multiplexer, proximity sensors 1 to 4, power monitors for VIO1.8 and VIO 3.3, and fuel gauge (rear battery) I2C driver.
+ * @brief   Configuration for the sensor ring, power monitors for VSYS4.2, VIO5.0 and VDD, EEPROM, and fuel gauge (front battery) I2C driver.
+ * @details Depending on the attached sensor ring, the devices connected to this bus vary:
+ *          ProximitySensor:
+ *            - I2C multiplexer (PCA9544A)
+ *            - proximity sensors (VCNL4020) #1 - #4
+ *            - touch sensor (MPR121)
+ *          DistanceSensor (VL53L0X):
+ *            TODO
+ *          DistanceSensor (VL53L1X):
+ *            TODO
  */
-extern I2CConfig moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig;
+extern I2CConfig moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig;
 
 /**
  * @brief   PWM driver for the buzzer.
@@ -149,7 +183,7 @@ extern SerialConfig moduleHalProgIfConfig;
  * @{
  */
 /*===========================================================================*/
-#include <amiro-lld.h>
+#include <periphALtypes.h>
 
 /**
  * @brief   SYS_REG_EN output signal GPIO.
@@ -283,72 +317,72 @@ extern ROMCONST apalControlGpio_t moduleGpioChargeEn2;
 /**
  * @brief   Event flag to be set on a IR_INT1 / CHARGE_STAT1A interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_IRINT1           ((eventflags_t)1 << GPIOB_IR_INT1_N)
+#define MODULE_OS_IOEVENTFLAGS_IRINT1           AOS_IOEVENT_FLAG(GPIOB_IR_INT1_N)
 
 /**
  * @brief   Event flag to be set on a GAUGE_BATLOW1 interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_GAUGEBATLOW1     ((eventflags_t)1 << GPIOC_GAUGE_BATLOW1)
+#define MODULE_OS_IOEVENTFLAGS_GAUGEBATLOW1     AOS_IOEVENT_FLAG(GPIOC_GAUGE_BATLOW1)
 
 /**
  * @brief   Event flag to be set on a GAUGE_BATGD1 interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_GAUGEBATGD1      ((eventflags_t)1 << GPIOC_GAUGE_BATGD1_N)
+#define MODULE_OS_IOEVENTFLAGS_GAUGEBATGD1      AOS_IOEVENT_FLAG(GPIOC_GAUGE_BATGD1_N)
 
 /**
  * @brief   Event flag to be set on a SYS_UART_DN interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_SYSUARTDN        ((eventflags_t)1 << GPIOB_SYS_UART_DN)
+#define MODULE_OS_IOEVENTFLAGS_SYSUARTDN        AOS_IOEVENT_FLAG(GPIOB_SYS_UART_DN)
 
 /**
  * @brief   Event flag to be set on a IR_INT2 / CHARGE_STAT2A interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_IRINT2           ((eventflags_t)1 << GPIOC_IR_INT2_N)
+#define MODULE_OS_IOEVENTFLAGS_IRINT2           AOS_IOEVENT_FLAG(GPIOC_IR_INT2_N)
 
 /**
  * @brief   Event flag to be set on a TOUCH_INT interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_TOUCHINT         ((eventflags_t)1 << GPIOC_TOUCH_INT_N)
+#define MODULE_OS_IOEVENTFLAGS_TOUCHINT         AOS_IOEVENT_FLAG(GPIOC_TOUCH_INT_N)
 
 /**
  * @brief   Event flag to be set on a GAUGE_BATLOW2 interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_GAUGEBATLOW2     ((eventflags_t)1 << GPIOB_GAUGE_BATLOW2)
+#define MODULE_OS_IOEVENTFLAGS_GAUGEBATLOW2     AOS_IOEVENT_FLAG(GPIOB_GAUGE_BATLOW2)
 
 /**
  * @brief   Event flag to be set on a GAUGE_BATGD2 interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_GAUGEBATGD2      ((eventflags_t)1 << GPIOB_GAUGE_BATGD2_N)
+#define MODULE_OS_IOEVENTFLAGS_GAUGEBATGD2      AOS_IOEVENT_FLAG(GPIOB_GAUGE_BATGD2_N)
 
 /**
  * @brief   Event flag to be set on a PATH_DC interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_PATHDC           ((eventflags_t)1 << GPIOC_PATH_DC)
+#define MODULE_OS_IOEVENTFLAGS_PATHDC           AOS_IOEVENT_FLAG(GPIOC_PATH_DC)
 
 /**
  * @brief   Event flag to be set on a SYS_SPI_DIR interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_SYSSPIDIR        ((eventflags_t)1 << GPIOC_SYS_SPI_DIR)
+#define MODULE_OS_IOEVENTFLAGS_SYSSPIDIR        AOS_IOEVENT_FLAG(GPIOC_SYS_SPI_DIR)
 
 /**
  * @brief   Event flag to be set on a SYS_SYNC interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_SYSSYNC          ((eventflags_t)1 << GPIOC_SYS_INT_N)
+#define MODULE_OS_IOEVENTFLAGS_SYSSYNC          AOS_IOEVENT_FLAG(GPIOC_SYS_INT_N)
 
 /**
  * @brief   Event flag to be set on a SYS_PD interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_SYSPD            ((eventflags_t)1 << GPIOC_SYS_PD_N)
+#define MODULE_OS_IOEVENTFLAGS_SYSPD            AOS_IOEVENT_FLAG(GPIOC_SYS_PD_N)
 
 /**
  * @brief   Event flag to be set on a SYS_WARMRST interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_SYSWARMRST       ((eventflags_t)1 << GPIOC_SYS_WARMRST_N)
+#define MODULE_OS_IOEVENTFLAGS_SYSWARMRST       AOS_IOEVENT_FLAG(GPIOC_SYS_WARMRST_N)
 
 /**
  * @brief   Event flag to be set on a SYS_UART_UP interrupt.
  */
-#define MODULE_OS_IOEVENTFLAGS_SYSUARTUP        ((eventflags_t)1 << GPIOB_SYS_UART_UP)
+#define MODULE_OS_IOEVENTFLAGS_SYSUARTUP        AOS_IOEVENT_FLAG(GPIOB_SYS_UART_UP)
 
 #if (AMIROOS_CFG_SHELL_ENABLE == true) || defined(__DOXYGEN__)
 /**
@@ -377,9 +411,9 @@ extern ROMCONST char* moduleShellPrompt;
   /* GAUGE_BATGD1 */                                                          \
   palSetPadCallback(moduleGpioGaugeBatGd1.gpio->port, moduleGpioGaugeBatGd1.gpio->pad, _intCallback, &moduleGpioGaugeBatGd1.gpio->pad); \
   palEnablePadEvent(moduleGpioGaugeBatGd1.gpio->port, moduleGpioGaugeBatGd1.gpio->pad, APAL2CH_EDGE(moduleGpioGaugeBatGd1.meta.edge));  \
-  /* IR_INT1 */                                                               \
-  palSetPadCallback(moduleGpioIrInt2.gpio->port, moduleGpioIrInt2.gpio->pad, _intCallback, &moduleGpioIrInt1.gpio->pad); \
-  palEnablePadEvent(moduleGpioIrInt2.gpio->port, moduleGpioIrInt2.gpio->pad, APAL2CH_EDGE(moduleGpioIrInt1.meta.edge));  \
+  /* IR_INT2 */                                                               \
+  palSetPadCallback(moduleGpioIrInt2.gpio->port, moduleGpioIrInt2.gpio->pad, _intCallback, &moduleGpioIrInt2.gpio->pad); \
+  palEnablePadEvent(moduleGpioIrInt2.gpio->port, moduleGpioIrInt2.gpio->pad, APAL2CH_EDGE(moduleGpioIrInt2.meta.edge));  \
   /* TOUCH_INT */                                                             \
   palSetPadCallback(moduleGpioTouchInt.gpio->port, moduleGpioTouchInt.gpio->pad, _intCallback, &moduleGpioTouchInt.gpio->pad); \
   palEnablePadEvent(moduleGpioTouchInt.gpio->port, moduleGpioTouchInt.gpio->pad, APAL2CH_EDGE(moduleGpioTouchInt.meta.edge));  \
@@ -405,36 +439,49 @@ extern ROMCONST char* moduleShellPrompt;
   aosShellAddCommand(&aos.shell, &moduleUtAlldBq27500.shellcmd);              \
   aosShellAddCommand(&aos.shell, &moduleUtAlldBq27500Bq24103a.shellcmd);      \
   aosShellAddCommand(&aos.shell, &moduleUtAlldIna219.shellcmd);               \
-  aosShellAddCommand(&aos.shell, &moduleUtAlldMpr121.shellcmd);               \
-  aosShellAddCommand(&aos.shell, &moduleUtAlldPca9544a.shellcmd);             \
   aosShellAddCommand(&aos.shell, &moduleUtAlldPklcs1212e4001.shellcmd);       \
   aosShellAddCommand(&aos.shell, &moduleUtAlldLed.shellcmd);                  \
   aosShellAddCommand(&aos.shell, &moduleUtAlldTps62113.shellcmd);             \
   aosShellAddCommand(&aos.shell, &moduleUtAlldTps62113Ina219.shellcmd);       \
-  aosShellAddCommand(&aos.shell, &moduleUtAlldVcnl4020.shellcmd);             \
+  MODULE_INIT_TEST_SENSORRING();                                              \
 }
+#if (BOARD_SENSORRING == BOARD_PROXIMITYSENSOR) || defined(__DOXYGEN__)
+  #define MODULE_INIT_TEST_SENSORRING() {                                     \
+    aosShellAddCommand(&aos.shell, &moduleUtAlldPca9544a.shellcmd);           \
+    aosShellAddCommand(&aos.shell, &moduleUtAlldMpr121.shellcmd);             \
+    aosShellAddCommand(&aos.shell, &moduleUtAlldVcnl4020.shellcmd);           \
+  }
+#elif (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L0X) || defined(__DOXYGEN__)
+  #define MODULE_INIT_TEST_SENSORRING() {                                     \
+    aosShellAddCommand(&aos.shell, &moduleUtAlldPcal6524.shellcmd);           \
+    aosShellAddCommand(&aos.shell, &moduleUtAlldAt42qt1050.shellcmd);         \
+  }
+#elif (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L1X) || defined(__DOXYGEN__)
+  #define MODULE_INIT_TEST_SENSORRING() {                                     \
+    aosShellAddCommand(&aos.shell, &moduleUtAlldPcal6524.shellcmd);           \
+    aosShellAddCommand(&aos.shell, &moduleUtAlldAt42qt1050.shellcmd);         \
+  }
+#else
+  #define MODULE_INIT_TEST_SENSORRING()         {}
+#endif
 
 /**
  * @brief   Periphery communication interfaces initialization hook.
  */
 #define MODULE_INIT_PERIPHERY_COMM() {                                        \
+  MODULE_INIT_PERIPHERY_COMM_SENSORRING();                                    \
   /* serial driver */                                                         \
   sdStart(&MODULE_HAL_PROGIF, &moduleHalProgIfConfig);                        \
   /* I2C */                                                                   \
-  moduleHalI2cProxPm18Pm33GaugeRearConfig.clock_speed = (PCA9544A_LLD_I2C_MAXFREQUENCY < moduleHalI2cProxPm18Pm33GaugeRearConfig.clock_speed) ? PCA9544A_LLD_I2C_MAXFREQUENCY : moduleHalI2cProxPm18Pm33GaugeRearConfig.clock_speed;  \
-  moduleHalI2cProxPm18Pm33GaugeRearConfig.clock_speed = (VCNL4020_LLD_I2C_MAXFREQUENCY < moduleHalI2cProxPm18Pm33GaugeRearConfig.clock_speed) ? VCNL4020_LLD_I2C_MAXFREQUENCY : moduleHalI2cProxPm18Pm33GaugeRearConfig.clock_speed;  \
-  moduleHalI2cProxPm18Pm33GaugeRearConfig.clock_speed = (INA219_LLD_I2C_MAXFREQUENCY < moduleHalI2cProxPm18Pm33GaugeRearConfig.clock_speed) ? INA219_LLD_I2C_MAXFREQUENCY : moduleHalI2cProxPm18Pm33GaugeRearConfig.clock_speed;  \
-  moduleHalI2cProxPm18Pm33GaugeRearConfig.clock_speed = (BQ27500_LLD_I2C_MAXFREQUENCY < moduleHalI2cProxPm18Pm33GaugeRearConfig.clock_speed) ? BQ27500_LLD_I2C_MAXFREQUENCY : moduleHalI2cProxPm18Pm33GaugeRearConfig.clock_speed;  \
-  moduleHalI2cProxPm18Pm33GaugeRearConfig.duty_cycle = (moduleHalI2cProxPm18Pm33GaugeRearConfig.clock_speed <= 100000) ? STD_DUTY_CYCLE : FAST_DUTY_CYCLE_2;  \
-  i2cStart(&MODULE_HAL_I2C_PROX_PM18_PM33_GAUGEREAR, &moduleHalI2cProxPm18Pm33GaugeRearConfig); \
-  moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed = (PCA9544A_LLD_I2C_MAXFREQUENCY < moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed) ? PCA9544A_LLD_I2C_MAXFREQUENCY : moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed; \
-  moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed = (VCNL4020_LLD_I2C_MAXFREQUENCY < moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed) ? VCNL4020_LLD_I2C_MAXFREQUENCY : moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed; \
-  moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed = (INA219_LLD_I2C_MAXFREQUENCY < moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed) ? INA219_LLD_I2C_MAXFREQUENCY : moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed; \
-  moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed = (AT24C01BN_LLD_I2C_MAXFREQUENCY < moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed) ? AT24C01BN_LLD_I2C_MAXFREQUENCY : moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed; \
-  moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed = (MPR121_LLD_I2C_MAXFREQUENCY < moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed) ? MPR121_LLD_I2C_MAXFREQUENCY : moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed; \
-  moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed = (BQ27500_LLD_I2C_MAXFREQUENCY < moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed) ? BQ27500_LLD_I2C_MAXFREQUENCY : moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed; \
-  moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.duty_cycle = (moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig.clock_speed <= 100000) ? STD_DUTY_CYCLE : FAST_DUTY_CYCLE_2;  \
-  i2cStart(&MODULE_HAL_I2C_PROX_PM42_PM50_PMVDD_EEPROM_TOUCH_GAUGEFRONT, &moduleHalI2cProxPm42Pm50PmVddEepromTouchGaugeFrontConfig);  \
+  moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed = (INA219_LLD_I2C_MAXFREQUENCY < moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed) ? INA219_LLD_I2C_MAXFREQUENCY : moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed;  \
+  moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed = (BQ27500_LLD_I2C_MAXFREQUENCY < moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed) ? BQ27500_LLD_I2C_MAXFREQUENCY : moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed;  \
+  moduleHalI2cSrPm18Pm33GaugeRearConfig.duty_cycle = (moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed <= 100000) ? STD_DUTY_CYCLE : FAST_DUTY_CYCLE_2;  \
+  i2cStart(&MODULE_HAL_I2C_SR_PM18_PM33_GAUGEREAR, &moduleHalI2cSrPm18Pm33GaugeRearConfig); \
+  moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed = (INA219_LLD_I2C_MAXFREQUENCY < moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed) ? INA219_LLD_I2C_MAXFREQUENCY : moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed; \
+  moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed = (AT24C01BN_LLD_I2C_MAXFREQUENCY < moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed) ? AT24C01BN_LLD_I2C_MAXFREQUENCY : moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed; \
+  moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed = (BQ27500_LLD_I2C_MAXFREQUENCY < moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed) ? BQ27500_LLD_I2C_MAXFREQUENCY : moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed; \
+  moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.duty_cycle = (moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed <= 100000) ? STD_DUTY_CYCLE : FAST_DUTY_CYCLE_2;  \
+  i2cStart(&MODULE_HAL_I2C_SR_PM42_PM50_PMVDD_EEPROM_GAUGEFRONT, &moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig);  \
   /* ADC */                                                                   \
   adcStart(&MODULE_HAL_ADC_VSYS, NULL);                                       \
   /* PWM */                                                                   \
@@ -444,6 +491,29 @@ extern ROMCONST char* moduleShellPrompt;
   moduleHalPwmBuzzerConfig.period = moduleHalPwmBuzzerConfig.frequency / PKLCS1212E4001_LLD_FREQUENCY_SPEC; \
   pwmStart(&MODULE_HAL_PWM_BUZZER, &moduleHalPwmBuzzerConfig);                \
 }
+#if (BOARD_SENSORRING == BOARD_PROXIMITYSENSOR) || defined(__DOXYGEN__)
+  #define MODULE_INIT_PERIPHERY_COMM_SENSORRING() {                           \
+    moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed = (PCA9544A_LLD_I2C_MAXFREQUENCY < moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed) ? PCA9544A_LLD_I2C_MAXFREQUENCY : moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed;  \
+    moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed = (VCNL4020_LLD_I2C_MAXFREQUENCY < moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed) ? VCNL4020_LLD_I2C_MAXFREQUENCY : moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed;  \
+    moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed = (PCA9544A_LLD_I2C_MAXFREQUENCY < moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed) ? PCA9544A_LLD_I2C_MAXFREQUENCY : moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed; \
+    moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed = (VCNL4020_LLD_I2C_MAXFREQUENCY < moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed) ? VCNL4020_LLD_I2C_MAXFREQUENCY : moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed; \
+    moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed = (MPR121_LLD_I2C_MAXFREQUENCY < moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed) ? MPR121_LLD_I2C_MAXFREQUENCY : moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed; \
+  }
+#elif (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L0X) || defined(__DOXYGEN__)
+  #define MODULE_INIT_PERIPHERY_COMM_SENSORRING() {                           \
+    moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed = (PCAL6524_LLD_I2C_MAXFREQUENCY < moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed) ? PCAL6524_LLD_I2C_MAXFREQUENCY : moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed;  \
+    moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed = (PCAL6524_LLD_I2C_MAXFREQUENCY < moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed) ? PCAL6524_LLD_I2C_MAXFREQUENCY : moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed;  \
+    moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed = (AT42QT1050_LLD_I2C_MAXFREQUENCY < moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed) ? AT42QT1050_LLD_I2C_MAXFREQUENCY : moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed;  \
+  }
+#elif (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L1X) || defined(__DOXYGEN__)
+  #define MODULE_INIT_PERIPHERY_COMM_SENSORRING() {                           \
+    moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed = (PCAL6524_LLD_I2C_MAXFREQUENCY < moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed) ? PCAL6524_LLD_I2C_MAXFREQUENCY : moduleHalI2cSrPm18Pm33GaugeRearConfig.clock_speed;  \
+    moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed = (PCAL6524_LLD_I2C_MAXFREQUENCY < moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed) ? PCAL6524_LLD_I2C_MAXFREQUENCY : moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed;  \
+    moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed = (AT42QT1050_LLD_I2C_MAXFREQUENCY < moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed) ? AT42QT1050_LLD_I2C_MAXFREQUENCY : moduleHalI2cSrPm42Pm50PmVddEepromGaugeFrontConfig.clock_speed;  \
+  }
+#else
+  #define MODULE_INIT_PERIPHERY_COMM_SENSORRING() {}
+#endif
 
 /**
  * @brief   Periphery communication interface deinitialization hook.
@@ -454,14 +524,13 @@ extern ROMCONST char* moduleShellPrompt;
   /* ADC */                                                                   \
   adcStop(&MODULE_HAL_ADC_VSYS);                                              \
   /* I2C */                                                                   \
-  i2cStop(&MODULE_HAL_I2C_PROX_PM18_PM33_GAUGEREAR);                          \
-  i2cStop(&MODULE_HAL_I2C_PROX_PM42_PM50_PMVDD_EEPROM_TOUCH_GAUGEFRONT);      \
+  i2cStop(&MODULE_HAL_I2C_SR_PM18_PM33_GAUGEREAR);                            \
+  i2cStop(&MODULE_HAL_I2C_SR_PM42_PM50_PMVDD_EEPROM_GAUGEFRONT);              \
   /* don't stop the serial driver so messages can still be printed */         \
 }
 
 /** @} */
 
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
 /*===========================================================================*/
 /**
  * @name Startup Shutdown Synchronization Protocol (SSSP)
@@ -511,7 +580,6 @@ extern ROMCONST char* moduleShellPrompt;
 
 /** @} */
 
-#endif
 /*===========================================================================*/
 /**
  * @name Low-level drivers
@@ -523,11 +591,8 @@ extern ROMCONST char* moduleShellPrompt;
 #include <alld_bq27500.h>
 #include <alld_ina219.h>
 #include <alld_led.h>
-#include <alld_mpr121.h>
-#include <alld_pca9544a.h>
 #include <alld_pklcs1212e4001.h>
 #include <alld_tps62113.h>
-#include <alld_vcnl4020.h>
 
 /**
  * @brief   EEPROM driver.
@@ -585,35 +650,87 @@ extern INA219Driver moduleLldPowerMonitorVio50;
 extern LEDDriver moduleLldStatusLed;
 
 /**
+ * @brief   Step down converter driver.
+ * @note    Although there multiple TPS62113, those are completely identical from driver few (share the same signals).
+ */
+extern TPS62113Driver moduleLldStepDownConverter;
+
+#if (BOARD_SENSORRING == BOARD_PROXIMITYSENSOR) || defined(__DOXYGEN__)
+
+#include <alld_mpr121.h>
+#include <alld_pca9544a.h>
+#include <alld_vcnl4020.h>
+
+/**
  * @brief   Touch sensor driver.
  */
 extern MPR121Driver moduleLldTouch;
 
 /**
- * @brief   I2C multiplexer (I2C 1) driver.
+ * @brief   I2C multiplexer (I2C #1) driver.
  */
 extern PCA9544ADriver moduleLldI2cMultiplexer1;
 
 /**
- * @brief   I2C multiplexer (I2C 2) driver.
+ * @brief   I2C multiplexer (I2C #2) driver.
  */
 extern PCA9544ADriver moduleLldI2cMultiplexer2;
 
 /**
- * @brief   Step down converter driver.
- * @note    Although there multiple TPS62113, those are completely identical from driver few (share the same signals).
+ * @brief   Proximity sensor (I2C #1) driver.
  */
-extern TPS62113Driver moduleLldStepDownConverter;
+extern VCNL4020Driver moduleLldProximity1;
 
 /**
- * @brief   Proximity sensor (I2C 1) driver.
+ * @brief   Proximity sensor (I2C #2) driver.
  */
-extern VCNL4020Driver moduleLldProximity1;
+extern VCNL4020Driver moduleLldProximity2;
+
+#endif /* BOARD_SENSORRING == BOARD_PROXIMITYSENSOR */
+
+#if (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L0X) || defined(__DOXYGEN__)
+
+#include <alld_pcal6524.h>
+#include <alld_at42qt1050.h>
 
 /**
- * @brief   Proximity sensor (I2C 2) driver.
+ * @brief   GPIO extender (I2C #1) driver.
  */
-extern VCNL4020Driver moduleLldProximity2;
+extern PCAL6524Driver moduleLldGpioExtender1;
+
+/**
+ * @brief   GPIO extender (I2C #2) driver.
+ */
+extern PCAL6524Driver moduleLldGpioExtender2;
+
+/**
+ * @brief   Touch sensor driver.
+ */
+extern AT42QT1050Driver moduleLldTouch;
+
+#endif /* BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L0X */
+
+#if (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L1X) || defined(__DOXYGEN__)
+
+#include <alld_pcal6524.h>
+#include <alld_at42qt1050.h>
+
+/**
+ * @brief   GPIO extender (I2C #1) driver.
+ */
+extern PCAL6524Driver moduleLldGpioExtender1;
+
+/**
+ * @brief   GPIO extender (I2C #2) driver.
+ */
+extern PCAL6524Driver moduleLldGpioExtender2;
+
+/**
+ * @brief   Touch sensor driver.
+ */
+extern AT42QT1050Driver moduleLldTouch;
+
+#endif /* BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L1X */
 
 /** @} */
 
@@ -631,12 +748,9 @@ extern VCNL4020Driver moduleLldProximity2;
 #include <ut_alld_bq27500_bq24103a.h>
 #include <ut_alld_ina219.h>
 #include <ut_alld_led.h>
-#include <ut_alld_mpr121.h>
-#include <ut_alld_pca9544a.h>
 #include <ut_alld_pklcs1212e4001.h>
 #include <ut_alld_tps62113.h>
 #include <ut_alld_tps62113_ina219.h>
-#include <ut_alld_vcnl4020.h>
 
 /**
  * @brief   ADC unit test object.
@@ -674,6 +788,27 @@ extern aos_unittest_t moduleUtAlldIna219;
 extern aos_unittest_t moduleUtAlldLed;
 
 /**
+ * @brief   PKLCS1212E4001 (buzzer) unit test object.
+ */
+extern aos_unittest_t moduleUtAlldPklcs1212e4001;
+
+/**
+ * @brief   TPS62113 (step-down converter) unit test object.
+ */
+extern aos_unittest_t moduleUtAlldTps62113;
+
+/**
+ * @brief   TPS62113 (step-sown converter) in combination with INA219 (power monitor) unit test object.
+ */
+extern aos_unittest_t moduleUtAlldTps62113Ina219;
+
+#if (BOARD_SENSORRING == BOARD_PROXIMITYSENSOR) || defined(__DOXYGEN__)
+
+#include <ut_alld_mpr121.h>
+#include <ut_alld_pca9544a.h>
+#include <ut_alld_vcnl4020.h>
+
+/**
  * @brief   MPR121 (touch sensor) unit test object.
  */
 extern aos_unittest_t moduleUtAlldMpr121;
@@ -684,24 +819,45 @@ extern aos_unittest_t moduleUtAlldMpr121;
 extern aos_unittest_t moduleUtAlldPca9544a;
 
 /**
- * @brief   PKLCS1212E4001 (buzzer) unit test object.
+ * @brief   VCNL4020 (proximity sensor) unit test object.
  */
-extern aos_unittest_t moduleUtAlldPklcs1212e4001;
+extern aos_unittest_t moduleUtAlldVcnl4020;
+
+#endif /* BOARD_SENSORRING == BOARD_PROXIMITYSENSOR */
+
+#if (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L0X) || defined(__DOXYGEN__)
+
+#include <ut_alld_pcal6524.h>
+#include <ut_alld_at42qt1050.h>
 
 /**
- * @brief   TPS62113 (step-down converter) unit test object.
+ * @brief   PCAL6524 (GPIO extender) unit test object.
  */
-extern aos_unittest_t moduleUtAlldTps62113;
+extern aos_unittest_t moduleUtAlldPcal6524;
 
 /**
- * @brief   TPS62113 (step-sown converter) in combination with INA219 (power monitor) unit test object.
+ * @brief   AT42QT1050 (touch sensor) unit test object.
  */
-extern aos_unittest_t moduleUtAlldTps62113Ina219;
+extern aos_unittest_t moduleUtAlldAt42qt1050;
+
+#endif /* BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L0X */
+
+#if (BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L1X) || defined(__DOXYGEN__)
+
+#include <ut_alld_pcal6524.h>
+#include <ut_alld_at42qt1050.h>
 
 /**
- * @brief   VCNL4020 (proximity sensor) unit test object.
+ * @brief   PCAL6524 (GPIO extender) unit test object.
  */
-extern aos_unittest_t moduleUtAlldVcnl4020;
+extern aos_unittest_t moduleUtAlldPcal6524;
+
+/**
+ * @brief   AT42QT1050 (touch sensor) unit test object.
+ */
+extern aos_unittest_t moduleUtAlldAt42qt1050;
+
+#endif /* BOARD_SENSORRING == BOARD_DISTANCESENSOR_VL53L1X */
 
 #endif /* AMIROOS_CFG_TESTS_ENABLE == true */
 
diff --git a/modules/RT-STM32L476RG-NUCLEO64/Makefile b/modules/RT-STM32L476RG-NUCLEO64/Makefile
index ef574f5..bbf57ef 100644
--- a/modules/RT-STM32L476RG-NUCLEO64/Makefile
+++ b/modules/RT-STM32L476RG-NUCLEO64/Makefile
@@ -1,7 +1,7 @@
 ################################################################################
 # AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
 # (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
+# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
 #                                                                              #
 # This program is free software: you can redistribute it and/or modify         #
 # it under the terms of the GNU General Public License as published by         #
@@ -119,12 +119,13 @@ PROJECT := $(patsubst $(abspath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))..
 include ../../kernel/kernel.mk
 CHIBIOS := $(AMIROOS_KERNEL)
 AMIROOS = ../..
+# Licensing files
+include $(CHIBIOS)/os/license/license.mk
 # Startup files
 include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32l4xx.mk
 # HAL-OSAL files
 include $(CHIBIOS)/os/hal/hal.mk
 include $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/platform.mk
-include ./board.mk
 include $(CHIBIOS)/os/hal/osal/rt/osal.mk
 # RTOS files
 include $(CHIBIOS)/os/rt/rt.mk
@@ -132,6 +133,7 @@ include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk
 # Other files (optional).
 include $(CHIBIOS)/test/lib/test.mk
 include $(CHIBIOS)/test/rt/rt_test.mk
+include $(CHIBIOS)/test/oslib/oslib_test.mk
 # AMiRo-BLT files
 include ../../bootloader/bootloader.mk
 # AMiRo-LLD files
@@ -142,17 +144,17 @@ include $(AMIROOS)/core/core.mk
 include $(AMIROOS)/unittests/unittests.mk
 
 # Define linker script file here
-LDSCRIPT= $(BOARDLD)/STM32L476xG.ld
+LDSCRIPT= STM32L476xG.ld
 
 # C sources that can be compiled in ARM or THUMB mode depending on the global
 # setting.
-CSRC = $(STARTUPSRC) \
+CSRC = $(LICSRC) \
+       $(STARTUPSRC) \
        $(KERNSRC) \
        $(PORTSRC) \
        $(OSALSRC) \
        $(HALSRC) \
        $(PLATFORMSRC) \
-       $(BOARDSRC) \
        $(MODULESCSRC) \
        $(TESTSRC) \
        $(PERIPHERYLLDCSRC) \
@@ -161,12 +163,14 @@ CSRC = $(STARTUPSRC) \
        $(CHIBIOS)/os/various/evtimer.c \
        $(CHIBIOS)/os/various/syscalls.c \
        $(CHIBIOS)/os/hal/lib/streams/chprintf.c \
+       board.c \
        module.c \
        $(APPSCSRC)
 
 # C++ sources that can be compiled in ARM or THUMB mode depending on the global
 # setting.
 CPPSRC = $(AMIROOSCORECPPSRC) \
+         $(CHIBIOS)/os/various/cpp_wrappers/syscalls_cpp.cpp \
          $(APPSCPPSRC)
 
 # C sources to be compiled in ARM mode regardless of the global setting.
@@ -196,14 +200,13 @@ ASMXSRC = $(STARTUPASM) \
           $(OSALASM) \
           $(APPSASMXSRC)
 
-INCDIR = $(CHIBIOS)/os/license \
+INCDIR = $(LICINC) \
          $(STARTUPINC) \
          $(KERNINC) \
          $(PORTINC) \
          $(OSALINC) \
          $(HALINC) \
          $(PLATFORMINC) \
-         $(BOARDINC) \
          $(MODULESINC) \
          $(TESTINC) \
          $(BOOTLOADERINC) \
@@ -290,8 +293,16 @@ ULIBS +=
 # End of user defines                                                          #
 ################################################################################
 
+################################################################################
+# Start of targets section                                                     #
+#                                                                              #
 
+# all and its dependencies
+BUILDDIR = ./build
 RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC
 include $(RULESPATH)/rules.mk
 
-include ../flash.mk
+#                                                                              #
+# End of targets section                                                       #
+################################################################################
+
diff --git a/modules/RT-STM32L476RG-NUCLEO64/alldconf.h b/modules/RT-STM32L476RG-NUCLEO64/alldconf.h
index 68a961c..52e1837 100644
--- a/modules/RT-STM32L476RG-NUCLEO64/alldconf.h
+++ b/modules/RT-STM32L476RG-NUCLEO64/alldconf.h
@@ -42,6 +42,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *          By definition time is represented at microsecond precision.
  */
 #define AMIROLLD_CFG_TIME_SIZE          32
+#define AMIROLLD_CFG_USE_MPU6050
 
 #endif /* _ALLDCONF_H_ */
 
diff --git a/modules/RT-STM32L476RG-NUCLEO64/halconf.h b/modules/RT-STM32L476RG-NUCLEO64/halconf.h
index 2ee374c..37ccfc5 100644
--- a/modules/RT-STM32L476RG-NUCLEO64/halconf.h
+++ b/modules/RT-STM32L476RG-NUCLEO64/halconf.h
@@ -86,7 +86,7 @@
  * @brief   Enables the I2C subsystem.
  */
 #if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
-#define HAL_USE_I2C                         FALSE
+#define HAL_USE_I2C                         TRUE
 #endif
 
 /**
diff --git a/modules/RT-STM32L476RG-NUCLEO64/mcuconf.h b/modules/RT-STM32L476RG-NUCLEO64/mcuconf.h
index 45cbec2..1176a8e 100644
--- a/modules/RT-STM32L476RG-NUCLEO64/mcuconf.h
+++ b/modules/RT-STM32L476RG-NUCLEO64/mcuconf.h
@@ -114,7 +114,7 @@
 #define STM32_ADC_COMPACT_SAMPLES           FALSE
 #define STM32_ADC_USE_ADC1                  FALSE
 #define STM32_ADC_USE_ADC2                  FALSE
-#define STM32_ADC_USE_ADC3                  FALSE
+#define STM32_ADC_USE_ADC3                  TRUE // turned on
 #define STM32_ADC_ADC1_DMA_STREAM           STM32_DMA_STREAM_ID(1, 1)
 #define STM32_ADC_ADC2_DMA_STREAM           STM32_DMA_STREAM_ID(1, 2)
 #define STM32_ADC_ADC3_DMA_STREAM           STM32_DMA_STREAM_ID(1, 3)
@@ -178,7 +178,7 @@
  */
 #define STM32_I2C_USE_I2C1                  FALSE
 #define STM32_I2C_USE_I2C2                  FALSE
-#define STM32_I2C_USE_I2C3                  FALSE
+#define STM32_I2C_USE_I2C3                  TRUE
 #define STM32_I2C_BUSY_TIMEOUT              50
 #define STM32_I2C_I2C1_RX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 7)
 #define STM32_I2C_I2C1_TX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 6)
diff --git a/modules/RT-STM32L476RG-NUCLEO64/module.c b/modules/RT-STM32L476RG-NUCLEO64/module.c
index c3f4d92..c15f57e 100644
--- a/modules/RT-STM32L476RG-NUCLEO64/module.c
+++ b/modules/RT-STM32L476RG-NUCLEO64/module.c
@@ -71,4 +71,36 @@ ROMCONST char* moduleShellPrompt = "STM32L476-DevBoard";
 #endif
 
 
+MPU6050Driver moduleLldMpu6050 = {
+  /* I2C Driver       */ &MODULE_HAL_I2C_MPU6050,
+  /* I²C address      */ 0x68,
+  /* current LSB (uA) */ 0x00u,
+  /* configuration    */ NULL,
+};
+
+/* MPU6050 */
+static int _utShellCmdCb_AlldMpu6050(BaseSequentialStream* stream, int argc, char* argv[])
+{
+  (void)argc;
+  (void)argv;
+  aosUtRun(stream, &moduleUtAlldMpu6050, NULL);
+  return AOS_OK;
+}
+
+static ut_mpu6050data_t _utAlldMpu6050Data = {
+   /* driver */ &moduleLldMpu6050,
+  /* timeout  */ MICROSECONDS_PER_SECOND,
+};
+aos_unittest_t moduleUtAlldMpu6050 = {
+  /* name           */ "MPU6050",
+  /* info           */ "accelerometer and gyroscope",
+  /* test function  */ utAlldMpu6050Func,
+  /* shell command  */ {
+    /* name     */ "unittest:Accelerometer&Gyroscope",
+    /* callback */ _utShellCmdCb_AlldMpu6050,
+    /* next     */ NULL,
+  },
+  /* data           */ &_utAlldMpu6050Data
+};
+
 /** @} */
diff --git a/modules/RT-STM32L476RG-NUCLEO64/module.h b/modules/RT-STM32L476RG-NUCLEO64/module.h
index 5d57ca0..c2f20f0 100644
--- a/modules/RT-STM32L476RG-NUCLEO64/module.h
+++ b/modules/RT-STM32L476RG-NUCLEO64/module.h
@@ -87,6 +87,16 @@ extern CANConfig moduleHalCanConfig;
 #define MODULE_HAL_PROGIF                       SD2
 
 /**
+ * @brief   I2C driver to access multiplexer, proximity sensors 5 to 8, power monitors for VSYS4.2, VIO 5.0 and VDD, EEPROM, touch sensor, and fuel gauge (front battery).
+ */
+#define MODULE_HAL_I2C_MPU6050 I2CD3
+
+/**
+ * @brief   Configuration for the multiplexer, proximity sensors 1 to 4, power monitors for VIO1.8 and VIO 3.3, and fuel gauge (rear battery) I2C driver.
+ */
+extern I2CConfig moduleHalI2cMpu6050Config;
+
+/**
  * @brief   Configuration for the programmer serial interface driver.
  */
 extern SerialConfig moduleHalProgIfConfig;
@@ -197,6 +207,7 @@ extern ROMCONST apalControlGpio_t moduleGpioBtRst;
 
 /** @} */
 
+
 /*===========================================================================*/
 /**
  * @name AMiRo-OS core configurations
@@ -259,6 +270,28 @@ extern ROMCONST apalControlGpio_t moduleGpioBtRst;
 extern ROMCONST char* moduleShellPrompt;
 #endif
 
+/**
+ * @brief   Unit test initialization hook.
+ */
+#define MODULE_INIT_TESTS() {                                                 \
+  /* add unit-test shell commands */                                          \
+  aosShellAddCommand(&aos.shell, &moduleUtAlldMpu6050.shellcmd);              \
+}
+
+#include <alld_mpu6050.h>
+
+/**
+ * @brief   Accelerometer (MPU6050) driver.
+ */
+extern MPU6050Driver moduleLldMpu6050;
+
+#include <ut_alld_mpu6050.h>
+
+/**
+ * @brief   MPU6050 unit test object.
+ */
+extern aos_unittest_t moduleUtAlldMpu6050;
+
 #endif /* _AMIROOS_MODULE_H_ */
 
 /** @} */
diff --git a/modules/aos_chconf.h b/modules/aos_chconf.h
index 6645802..c01d2f9 100644
--- a/modules/aos_chconf.h
+++ b/modules/aos_chconf.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/modules/flash.mk b/modules/flash.mk
deleted file mode 100644
index 7c29958..0000000
--- a/modules/flash.mk
+++ /dev/null
@@ -1,48 +0,0 @@
-################################################################################
-# AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
-# (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
-#                                                                              #
-# This program is free software: you can redistribute it and/or modify         #
-# it under the terms of the GNU General Public License as published by         #
-# the Free Software Foundation, either version 3 of the License, or            #
-# (at your option) any later version.                                          #
-#                                                                              #
-# This program is distributed in the hope that it will be useful,              #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                #
-# GNU General Public License for more details.                                 #
-#                                                                              #
-# You should have received a copy of the GNU General Public License            #
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.        #
-#                                                                              #
-# This research/work was supported by the Cluster of Excellence Cognitive      #
-# Interaction Technology 'CITEC' (EXC 277) at Bielefeld University, which is   #
-# funded by the German Research Foundation (DFG).                              #
-################################################################################
-
-
-
-# the path to this makefile
-FLASH_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
-
-include $(FLASH_DIR)../bootloader/bootloader.mk
-
-# the files to flash
-ifdef PROJECT
-  FLASH_MODULES = $(PROJECT)
-  FLASH_FILES = build/$(PROJECT).$(FLASHTOOL_EXT)
-else
-  FLASH_MODULES = $(MODULES)
-  FLASH_FILES = $(foreach module,$(MODULES),$(module)/build/$(module).$(FLASHTOOL_EXT))
-endif
-
-flash: $(FLASH_FILES)
-	$(info )
-ifeq ($(FLASHTOOL),SerialBoot)
-	$(info Flashing ($(FLASHTOOL)):)
-	$(FLASHTOOL_CMD) $(FLASHTOOL_ARGS)
-else
-	$(info ERROR: unable to flash the module (SerialBoot unavailable))
-endif
-
diff --git a/modules/modules.mk b/modules/modules.mk
index b5a1957..7567637 100644
--- a/modules/modules.mk
+++ b/modules/modules.mk
@@ -1,7 +1,7 @@
 ################################################################################
 # AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
 # (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
+# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
 #                                                                              #
 # This program is free software: you can redistribute it and/or modify         #
 # it under the terms of the GNU General Public License as published by         #
diff --git a/periphery-lld/periphAL.h b/periphery-lld/periphAL.h
index e4bfa92..a19dba2 100644
--- a/periphery-lld/periphAL.h
+++ b/periphery-lld/periphAL.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/periphery-lld/periphery-lld.mk b/periphery-lld/periphery-lld.mk
index a8eac6c..b8c37eb 100644
--- a/periphery-lld/periphery-lld.mk
+++ b/periphery-lld/periphery-lld.mk
@@ -1,7 +1,7 @@
 ################################################################################
 # AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
 # (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
+# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
 #                                                                              #
 # This program is free software: you can redistribute it and/or modify         #
 # it under the terms of the GNU General Public License as published by         #
diff --git a/periphery-lld/peripherylldsetup.sh b/periphery-lld/peripherylldsetup.sh
index 914470b..ecd28bc 100755
--- a/periphery-lld/peripherylldsetup.sh
+++ b/periphery-lld/peripherylldsetup.sh
@@ -1,7 +1,7 @@
 ################################################################################
 # AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
 # (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
+# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
 #                                                                              #
 # This program is free software: you can redistribute it and/or modify         #
 # it under the terms of the GNU General Public License as published by         #
@@ -263,6 +263,40 @@ function setLogFile {
   return 0
 }
 
+### check whether commands are available #######################################
+# Checks whether the specified commands are available and can be executed.
+#
+# usage:      checkCommand [<command> <command> ...]
+# arguments:  <command>
+#                 Name of the command to check.
+# return:     0
+#                 All requested commands are available.
+#             >0
+#                 Number of requested commands that were not found.
+#             -1
+#                 No argument given.
+#
+function checkCommands {
+  local status=0
+
+  # return if no argument was specified
+  if [ $# -eq 0 ]; then
+    return -1
+  fi
+
+  # check all specified commands
+  while [ $# -gt 0 ]; do
+    command -v $1 &>/dev/null
+    if [ $? -ne 0 ]; then
+      printWarning "Command '$1' not available.\n"
+      status=$((status + 1))
+    fi
+    shift 1
+  done
+
+  return $status
+}
+
 ################################################################################
 # SPECIFIC FUNCTIONS                                                           #
 ################################################################################
@@ -281,7 +315,7 @@ function printWelcomeText {
   printf "#                                                                    #\n"
   printf "######################################################################\n"
   printf "#                                                                    #\n"
-  printf "# Copyright (c) 2016..2018  Thomas Schöpping                         #\n"
+  printf "# Copyright (c) 2016..2019  Thomas Schöpping                         #\n"
   printf "#                                                                    #\n"
   printf "# This is free software; see the source for copying conditions.      #\n"
   printf "# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR  #\n"
@@ -327,6 +361,8 @@ function printHelp {
 #                 Warning: Arborted by user.
 #             -1
 #                 Error: Unexpected user input.
+#             -2
+#                 Error: Missing dependencies.
 #
 function initAmiroLld {
   printInfo "initializing AMiRo-LLD submodule...\n"
@@ -352,6 +388,13 @@ function initAmiroLld {
     esac
   fi
 
+  # check dependencies
+  checkCommands git
+  if [ $? -ne 0 ]; then
+    printError "Missing dependencies detected.\n"
+    return -2
+  fi
+
   # initialize submodule to default branch
   cd $peripheryllddir
   git submodule update --init $amirollddir 2>&1 | tee -a $LOG_FILE
@@ -381,13 +424,30 @@ function initAmiroLld {
 #
 # usage:      wipeAmiroLld
 # arguments:  n/a
-# return:     n/a
+# return:     0
+#                 No error or warning occurred.
+#             1
+#                 Warning: AMiRo-LLD Git submodule already empty
+#             2
+#                 Warning: Aborted by user.
+#             -1
+#                 Error: Unexpected input occurred.
+#             -2
+#                 Error: Missing dependencies.
+#
 function wipeAmiroLld {
   printInfo "reset and wipe Git submodule $amirollddir\n"
   local userdir=$(pwd)
   local peripheryllddir=$(dirname $(realpath ${BASH_SOURCE[0]}))
   local amirollddir=${peripheryllddir}/AMiRo-LLD
 
+  # check dependencies
+  checkCommands git
+  if [ $? -ne 0 ]; then
+    printError "Missing dependencies detected.\n"
+    return -2
+  fi
+
   # if the AMiRo-LLD folder is empty
   if [ -z "$(ls -A $amirollddir)" ]; then
     printWarning "$amirollddir is already empty\n"
diff --git a/setup.sh b/setup.sh
index 036bdc4..bf8b54b 100755
--- a/setup.sh
+++ b/setup.sh
@@ -1,7 +1,7 @@
 ################################################################################
 # AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
 # (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
+# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
 #                                                                              #
 # This program is free software: you can redistribute it and/or modify         #
 # it under the terms of the GNU General Public License as published by         #
@@ -263,6 +263,40 @@ function setLogFile {
   return 0
 }
 
+### check whether commands are available #######################################
+# Checks whether the specified commands are available and can be executed.
+#
+# usage:      checkCommand [<command> <command> ...]
+# arguments:  <command>
+#                 Name of the command to check.
+# return:     0
+#                 All requested commands are available.
+#             >0
+#                 Number of requested commands that were not found.
+#             -1
+#                 No argument given.
+#
+function checkCommands {
+  local status=0
+
+  # return if no argument was specified
+  if [ $# -eq 0 ]; then
+    return -1
+  fi
+
+  # check all specified commands
+  while [ $# -gt 0 ]; do
+    command -v $1 &>/dev/null
+    if [ $? -ne 0 ]; then
+      printWarning "Command '$1' not available.\n"
+      status=$((status + 1))
+    fi
+    shift 1
+  done
+
+  return $status
+}
+
 ################################################################################
 # SPECIFIC FUNCTIONS                                                           #
 ################################################################################
@@ -281,7 +315,7 @@ function printWelcomeText {
   printf "#                                                                    #\n"
   printf "######################################################################\n"
   printf "#                                                                    #\n"
-  printf "# Copyright (c) 2016..2018  Thomas Schöpping                         #\n"
+  printf "# Copyright (c) 2016..2019  Thomas Schöpping                         #\n"
   printf "#                                                                    #\n"
   printf "# This is free software; see the source for copying conditions.      #\n"
   printf "# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR  #\n"
diff --git a/tools/ide/QtCreator/QtCreatorSetup.sh b/tools/ide/QtCreator/QtCreatorSetup.sh
index e62fbb0..afd3685 100755
--- a/tools/ide/QtCreator/QtCreatorSetup.sh
+++ b/tools/ide/QtCreator/QtCreatorSetup.sh
@@ -1,7 +1,7 @@
 ################################################################################
 # AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
 # (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
+# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
 #                                                                              #
 # This program is free software: you can redistribute it and/or modify         #
 # it under the terms of the GNU General Public License as published by         #
@@ -263,6 +263,40 @@ function setLogFile {
   return 0
 }
 
+### check whether commands are available #######################################
+# Checks whether the specified commands are available and can be executed.
+#
+# usage:      checkCommand [<command> <command> ...]
+# arguments:  <command>
+#                 Name of the command to check.
+# return:     0
+#                 All requested commands are available.
+#             >0
+#                 Number of requested commands that were not found.
+#             -1
+#                 No argument given.
+#
+function checkCommands {
+  local status=0
+
+  # return if no argument was specified
+  if [ $# -eq 0 ]; then
+    return -1
+  fi
+
+  # check all specified commands
+  while [ $# -gt 0 ]; do
+    command -v $1 &>/dev/null
+    if [ $? -ne 0 ]; then
+      printWarning "Command '$1' not available.\n"
+      status=$((status + 1))
+    fi
+    shift 1
+  done
+
+  return $status
+}
+
 ################################################################################
 # SPECIFIC FUNCTIONS                                                           #
 ################################################################################
@@ -281,7 +315,7 @@ function printWelcomeText {
   printf "#                                                                    #\n"
   printf "######################################################################\n"
   printf "#                                                                    #\n"
-  printf "# Copyright (c) 2016..2018  Thomas Schöpping                         #\n"
+  printf "# Copyright (c) 2016..2019  Thomas Schöpping                         #\n"
   printf "#                                                                    #\n"
   printf "# This is free software; see the source for copying conditions.      #\n"
   printf "# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR  #\n"
@@ -303,22 +337,18 @@ function printWelcomeText {
 #
 function printHelp {
   printInfo "printing help text\n"
-  printf "usage:    $(basename ${BASH_SOURCE[0]}) [-h|--help] [-c|--clean] [-w|--wipe] [--LightRing] [--PowerManagement] [--DiWheelDrive] [-a|--all] [-q|--quit] [--log=<file>]\n"
+  printf "usage:    $(basename ${BASH_SOURCE[0]}) [-h|--help] [--module=<module>] [-a|--all] [-c|--clean] [-w|--wipe] [-q|--quit] [--log=<file>]\n"
   printf "\n"
   printf "options:  -h, --help\n"
   printf "              Print this help text.\n"
+  printf "          --module=<module>\n"
+  printf "              Create project for a single module.\n"
+  printf "          -a, --all\n"
+  printf "              Create projects for all modules.\n"
   printf "          -c, --clean\n"
   printf "              Delete project files.\n"
   printf "          -w, --wipe\n"
   printf "              Delete project and .user files.\n"
-  printf "          --LightRing\n"
-  printf "              Create project for the LightRing module.\n"
-  printf "          --PowerManagement\n"
-  printf "              Create project for the PowerManagement module.\n"
-  printf "          --DiWheelDrive\n"
-  printf "              Create project for the DiWheelDrive module.\n"
-  printf "          -a, --all\n"
-  printf "              Create projects for all modules.\n"
   printf "          -q, --quit\n"
   printf "              Quit the script.\n"
   printf "          --log=<file>\n"
@@ -374,97 +404,36 @@ function retrieveGccIncludeDir {
   fi
 }
 
-### delete project files #######################################################
-# Deletes all project files and optionally .user files, too.
+### detect available modules ###################################################
+# Detect all avalable modules supported by AMiRo-OS.
 #
-# usage:      deleteProjects [-p|--path=<path>] [-o|--out=<var>] [-w|-wipe]
-# arguments:  -p, --path <path>
-#                 Path where to delete the project files.
-#             -o, --out <var>
-#                 Variable to store the path to.
-#             -w, --wipe
-#                 Delete .user files as well.
-# return:
-#  -  0: no error
-#  -  1: warning: function aborted by user
-#  - -1: error: unexpected user input
-function deleteProjects {
-  local projectdir=""
-  local outvar=""
-  local wipe=false
+# usage:      detectModules <modulearray>
+# arguments:  <modulearray>
+#                 Array variable to store all detected modules to.
+# return:     n/a
+#
+function detectModules {
+  local modulesdir=$(realpath $(dirname $(realpath ${BASH_SOURCE[0]}))/../../../modules)
+  local modules_detected=()
 
-  # parse arguments
-  local otherargs=()
-  while [ $# -gt 0 ]; do
-    if ( parseIsOption $1 ); then
-      case "$1" in
-        -p=*|--path=*)
-          projectdir=$(realpath "${1#*=}"); shift 1;;
-        -p|--path)
-          projectdir=$(realpath "$2"); shift 2;;
-        -o=*|--out=*)
-          outvar=${1#*=}; shift 1;;
-        -o|--out)
-          outvar=$2; shift 2;;
-        -w|--wipe)
-          wipe=true; shift 1;;
-        *)
-          printError "invalid option: $1\n"; shift 1;;
-      esac
-    else
-      otherargs+=("$1")
-      shift 1
-    fi
+  # detect all available modules (via directories)
+  for dir in $(ls -d ${modulesdir}/*/); do
+    modules_detected[${#modules_detected[@]}]=$(basename $dir)
   done
 
-  # print message
-  if [ $wipe != true ]; then
-    printInfo "deleting all QtCreator project files (*.includes, *.files, *.config, and *.creator)\n"
-  else
-    printInfo "deleting all QtCreator project files (*.includes, *.files, *.config, *.creator, and *.user)\n"
-  fi
-
-  # read project directory if required
-  if [ -z "$projectdir" ]; then
-    getProjectDir projectdir
-  fi
-
-  # remove all project files
-  rm ${projectdir}/LightRing.includes 2>&1 | tee -a $LOG_FILE
-  rm ${projectdir}/PowerManagement.includes 2>&1 | tee -a $LOG_FILE
-  rm ${projectdir}/DiWheelDrive.includes 2>&1 | tee -a $LOG_FILE
-
-  rm ${projectdir}/LightRing.files 2>&1 | tee -a $LOG_FILE
-  rm ${projectdir}/PowerManagement.files 2>&1 | tee -a $LOG_FILE
-  rm ${projectdir}/DiWheelDrive.files 2>&1 | tee -a $LOG_FILE
-
-  rm ${projectdir}/LightRing.config 2>&1 | tee -a $LOG_FILE
-  rm ${projectdir}/PowerManagement.config 2>&1 | tee -a $LOG_FILE
-  rm ${projectdir}/DiWheelDrive.config 2>&1 | tee -a $LOG_FILE
-
-  rm ${projectdir}/LightRing.creator 2>&1 | tee -a $LOG_FILE
-  rm ${projectdir}/PowerManagement.creator 2>&1 | tee -a $LOG_FILE
-  rm ${projectdir}/DiWheelDrive.creator 2>&1 | tee -a $LOG_FILE
-
-  if [ $wipe == true ]; then
-    rm ${projectdir}/LightRing.creator.user 2>&1 | tee -a $LOG_FILE
-    rm ${projectdir}/PowerManagement.creator.user 2>&1 | tee -a $LOG_FILE
-    rm ${projectdir}/DiWheelDrive.creator.user 2>&1 | tee -a $LOG_FILE
-  fi
-
-  # store the path to the output variable, if required
-  if [ ! -z "$outvar" ]; then
-    eval $outvar="$projectdir"
-  fi
-
-  return 0
+  # set the output variable
+  eval "$1=(${modules_detected[*]})"
 }
 
-### create LightRing project files #############################################
-# Create project files for the LightRing module.
+### create project files for a single module ###################################
+# Create project files for a single module.
 #
-# usage:      createLightRingProject [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
-# arguments:  -p, --path <path>
+# usage:      createModuleProject <modules> [-m|--module=<module>] [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
+# arguments:  <modules>
+#                 Array containing all modules available.
+#             -m, --module <module>
+#                 Name (folder name) of the module for which project files shall be generated.
+#             -p, --path <path>
 #                 Path where to create the project files.
 #             --gcc=<path>
 #                 Path to the GCC include directory.
@@ -472,21 +441,47 @@ function deleteProjects {
 #                 Variable to store the path to.
 #             --gccout=<var>
 #                 Variable to store the path to the GCC include directory to.
+#                 If this optional arguments is absent, ths function will ask for user input.
 # return:     0
 #                 No error or warning occurred.
+#             1
+#                 Aborted by user.
+#             -1
+#                 No modules available.
+#             -2
+#                 The specified <module> could not be found.
+#             -3
+#                 Parsing the project for the specified module failed.
+#             -4
+#                 Missing dependencies.
 #
-function createLightRingProject {
+function createModuleProject {
   local userdir=$(pwd)
+  local modulesdir=$(realpath $(dirname $(realpath ${BASH_SOURCE[0]}))/../../../modules)
+  local modules=("${!1}")
+  local module=""
+  local moduleidx=""
   local projectdir=""
   local gccincludedir=""
   local outvar=""
   local gccoutvar=""
 
+  # check dependencies
+  checkCommands make
+  if [ $? -ne 0 ]; then
+    printError "Missing dependencies detected.\n"
+    return -4
+  fi
+
   # parse arguments
   local otherargs=()
   while [ $# -gt 0 ]; do
     if ( parseIsOption $1 ); then
       case "$1" in
+        -m=*|--module=*)
+          module="${1#*=}"; shift 1;;
+        -m|--module)
+          module="$2"; shift 2;;
         -p=*|--path=*)
           projectdir=$(realpath "${1#*=}"); shift 1;;
         -p|--path)
@@ -512,71 +507,175 @@ function createLightRingProject {
     fi
   done
 
-  # print message
-  printInfo "creating QtCreator project files for the LightRing module...\n"
+  # sanity check for the modules variable
+  if [ -z "${modules[*]}" ]; then
+    printError "no modules available\n"
+    return -1
+  fi
+
+  # select module
+  if [ -z $module ]; then
+    # list all available modules
+    printInfo "choose a module or type 'A' to abort:\n"
+    for (( idx=0; idx<${#modules[@]}; ++idx )); do
+      printf "%4u: %s\n" $(($idx + 1)) "${modules[$idx]}"
+    done
+    # read user input
+    printLog "read user selection\n"
+    local userinput=""
+    while [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^[Aa]$ ]]; do
+      read -p "your selection: " -e userinput
+      printLog "user selection: $userinput\n"
+      if [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^[Aa]$ ]]; then
+        printWarning "Please enter an integer between 1 and ${#modules[@]} or 'A' to abort.\n"
+      fi
+    done
+    if [[ "$userinput" =~ ^[Aa]$ ]]; then
+      printWarning "aborted by user\n"
+      return 1
+    fi
+    # store selection
+    moduleidx=$(($userinput - 1))
+    module="${modules[$moduleidx]}"
+    printf "\n"
+  else
+    # search all modules for the selected one
+    for (( idx=0; idx<${#modules[@]}; ++idx )); do
+      if [ "${modules[$idx]}" = "$module" ]; then
+        moduleidx=$idx
+        break
+      fi
+    done
+    # error if the module could not be found
+    if [ -z $moduleidx ]; then
+      printError "module ($module) not available\n"
+      return -2
+    fi
+  fi
 
   # read absolute project directory if required
   if [ -z "$projectdir" ]; then
     getProjectDir projectdir
+    printf "\n"
+  fi
+
+  # check for existing project files
+  local projectfiles="$(find ${projectdir} -maxdepth 1 -type f | grep -E "${module}\.(includes|files|config|creator)$")"
+  IFS=$'\n'; projectfiles=($projectfiles); unset IFS
+  if [ ! -z "${projectfiles[*]}" ]; then
+    printWarning "The following files will be overwritten:\n"
+    for pfile in ${projectfiles[@]}; do
+      printWarning "\t$(basename $pfile)\n"
+    done
+    local userinput=""
+    printInfo "Continue and overwrite? [y/n]\n"
+    readUserInput "YyNn" userinput
+    case "$userinput" in
+      Y|y)
+        ;;
+      N|n)
+        printWarning "Project generation for ${module} module aborted by user\n"
+        return 1
+        ;;
+      *)
+        printError "unexpected input: ${userinput}\n"; return -999;;
+    esac
+    printf "\n"
   fi
 
-  # retrieve absolute GCC include dir
+  # print message
+  printInfo "generating QtCreator project files for the $module module...\n"
+
+  # retrieve absolute GCC include path
   if [ -z "$gccincludedir" ]; then
     retrieveGccIncludeDir gccincludedir
   fi
 
-  # move to project directory
-  cd $projectdir
+  # change to project directory
+  cd "$projectdir"
 
-  # AMiRo-OS, ChibiOS, AMiRo-BLT and AMiRo-LLD relative root directories
+  # run make, but only run the GCC preprocessor and produce no binaries
   local amiroosrootdir=$(realpath $(dirname ${BASH_SOURCE[0]})/../../..)
-  local chibiosrootdir=$(realpath ${amiroosrootdir}/kernel/ChibiOS)
-  local amirobltrootdir=$(realpath ${amiroosrootdir}/bootloader/AMiRo-BLT)
-  local amirolldrootdir=$(realpath ${amiroosrootdir}/periphery-lld/AMiRo-LLD)
-
-  # generate a file that contains all subdirectories as includes (but ignore hidden and documentation directories)
-  find $gccincludedir -type d > ${projectdir}/LightRing.includes
-  echo $amiroosrootdir >> ${projectdir}/LightRing.includes
-  find $amiroosrootdir/modules -type d | grep -v "/doc\|/build\|/.dep\|/PowerManagement\|/DiWheelDrive" >> ${projectdir}/LightRing.includes
-  find $amiroosrootdir/core -type d >> ${projectdir}/LightRing.includes
-  find $amiroosrootdir/unittests -type d >> ${projectdir}/LightRing.includes
-  find $chibiosrootdir -type d | grep -E "/os/common/abstractions/cmsis_os$" >> ${projectdir}/LightRing.includes
-  find $chibiosrootdir -type d | grep -E "/os/common/ext/CMSIS/(include|ST/STM32F1xx)$" >> ${projectdir}/LightRing.includes
-  find $chibiosrootdir -type d | grep -E "/os/common/oslib/(include|src)$" >> ${projectdir}/LightRing.includes
-  find $chibiosrootdir -type d | grep -E "/os/common/ports/ARMCMx(/compilers/GCC)?$" >> ${projectdir}/LightRing.includes
-  find $chibiosrootdir -type d | grep -E "/os/common/startup/ARMCMx/(compilers/GCC|devices/STM32F1xx)$" >> ${projectdir}/LightRing.includes
-  find $chibiosrootdir -type d | grep -E "/os/hal/(include|src)$" >> ${projectdir}/LightRing.includes
-  find $chibiosrootdir -type d | grep -E "/os/hal/lib/streams" >> ${projectdir}/LightRing.includes
-  find $chibiosrootdir -type d | grep -E "/os/hal/osal/(lib|rt)$" >> ${projectdir}/LightRing.includes
-  find $chibiosrootdir -type d | grep -E "/os/hal/ports/(common/ARMCMx|STM32/(LLD/(CANv1|DACv1|DMAv1|EXTIv1|GPIOv1|I2Cv1|RTCv1|SDIOv1|SPIv1|TIMv1|USARTv1|USBv1|xWDGv1)|STM32F1xx))$" >> ${projectdir}/LightRing.includes
-  find $chibiosrootdir -type d | grep -E "/os/license$" >> ${projectdir}/LightRing.includes
-  find $chibiosrootdir -type d | grep -E "/os/rt/(include|src)$" >> ${projectdir}/LightRing.includes
-  find $chibiosrootdir -type d | grep -E "/test/(lib|rt/source/test)$" >> ${projectdir}/LightRing.includes
-  find $amirobltrootdir -type d | grep -E "/Target/Source/AMiRo$" >> ${projectdir}/LightRing.includes
-  echo "$(realpath ${amirolldrootdir}/..)" >> ${projectdir}/LightRing.includes
-  find $amirolldrootdir -type d | grep -v "/doc" >> ${projectdir}/LightRing.includes
-  # generate a file that specifies all files
-  echo -n "" > ${projectdir}/LightRing.files
-  for path in `cat ${projectdir}/LightRing.includes`; do
-    find $path -maxdepth 1 -type f \( ! -iname ".*" \) |
-      grep -Ev "^.*((/arm-none-eabi/)|(PowerManagement)|(DiWheelDrive)).*$" |
-      grep -E  "^.*(\.s|\.S|\.h|\.c|\.hpp|\.cpp|\.tpp|\.ld)$" |
-      grep -Ev "^${chibiosrootdir}/os/common/ext/CMSIS/ST/STM32F1xx/((stm32f1[^0x])|(stm32f10[^3])|(stm32f103[^x])|(stm32f103x[^e])).*$" |
-      grep -Ev "^${chibiosrootdir}/os/common/ext/CMSIS/include/((core_[^c])|(core_c[^m])|(core_cm[^3A-Za-z])|(cmsis_[^g])|(cmsis_g[^c]|(cmsis_gc[^c])))" |
-      grep -Ev "^${chibiosrootdir}/os/common/ports/ARMCMx/chcore_v[^7]m.*$" |
-      grep -Ev "^${chibiosrootdir}/os/common/ports/ARMCMx/compilers/GCC/.*_v[^7]m.*$" |
-      grep -Ev "^${chibiosrootdir}/os/common/startup/ARMCMx/compilers/GCC/.*_v[^7]m.*$" |
-      grep -Ev "^${chibiosrootdir}/os/hal/ports/STM32/STM32F1xx/.*f10[^3].*$" |
-      grep -Ev "^${amirobltrootdir}/Target/Source/AMiRo/helper.*$" >> ${projectdir}/LightRing.files;
+  local sourcefiles=()
+  local sourcefile=""
+  local parse_state="WAIT_FOR_INCLUDE_OR_COMPILE"
+  # capture all output from make and GCC and append the return value of make as last line
+  printInfo "processing project (this may take a while)...\n"
+  local rawout=$(make --directory ${amiroosrootdir}/modules/${module} --always-make USE_OPT="-v -E -H" USE_VERBOSE_COMPILE="no" OUTFILES="" 2>&1 && echo $?)
+  # check whether the make call was successfull
+  if [[ $(echo "${rawout}" | tail -n 1) != "0" ]]; then
+    printError "executing 'make' in module directory failed\n"
+    cd "$userdir"
+    return -3
+  else
+    # cleanup
+    make --directory ${amiroosrootdir}/modules/${module} clean &>/dev/null
+  fi
+  # extract file names from raw output
+  IFS=$'\n'; rawout=($rawout); unset IFS
+  for line in "${rawout[@]}"; do
+    case $parse_state in
+      WAIT_FOR_INCLUDE_OR_COMPILE)
+        # lines stating included files look like:
+        # ... <../relative/path/to/file>
+        if [[ "$line" =~ ^\.+[[:blank:]].+\..+$ ]]; then
+          sourcefile=${line##* }
+          if [[ ! "$sourcefile" =~ ^/ ]]; then
+            sourcefile=$(realpath ${amiroosrootdir}/modules/${module}/${sourcefile})
+          fi
+          sourcefiles[${#sourcefiles[@]}]="$sourcefile"
+        # whenever the next source file is processed, a message appears like:
+        # Compining <filnemame>
+        elif [[ "$line" =~ ^Compiling[[:blank:]].+\..+$ ]]; then
+          printf "."
+          sourcefile=${line##* }
+          parse_state="WAIT_FOR_COMPILERCALL"
+        fi;;
+      WAIT_FOR_COMPILERCALL)
+        # wait for the actual call of the compiler to retrieve the full path to the source file
+        if [[ "$line" == *${sourcefile}* ]]; then
+          line="${line%%${sourcefile}*}${sourcefile}"
+          sourcefile=${line##* }
+          sourcefile=$(realpath ${amiroosrootdir}/modules/${module}/${line##* })
+          sourcefiles[${#sourcefiles[@]}]="$sourcefile"
+          parse_state="WAIT_FOR_INCLUDE_OR_COMPILE"
+        fi;;
+    esac
+  done
+  unset rawout
+  printf "\n"
+  # sort and remove duplicates
+  IFS=$'\n'; sourcefiles=($(sort --unique <<< "${sourcefiles[*]}")); unset IFS
+
+  # extract include paths
+  local includes=()
+  for source in ${sourcefiles[*]}; do
+    includes[${#includes[@]}]="$(dirname ${source})"
+  done
+  # sort and remove duplicates
+  IFS=$'\n'; includes=($(sort --unique <<< "${includes[*]}")); unset IFS
+
+  # generate the .files file, containing all source files
+  echo "" > ${projectdir}/${module}.includes
+  for inc in ${includes[*]}; do
+    echo "$inc" >> ${projectdir}/${module}.includes
+  done
+  # generate the .incldues file, containing all include paths
+  echo "" > ${projectdir}/${module}.files
+  for source in ${sourcefiles[*]}; do
+    # skip GCC files
+    if [[ ! "$source" =~ .*/gcc.* ]]; then
+      echo "$source" >> ${projectdir}/${module}.files
+    fi
   done
-  # generate a default project configuration file if none exists so far
-  if [ ! -f ${projectdir}/LightRing.config ]; then
-    echo "// Add predefined macros for your project here. For example:" > ${projectdir}/LightRing.config
-    echo "// #define YOUR_CONFIGURATION belongs here" >> ${projectdir}/LightRing.config
+  # generate a default project configuration file if it doesn't exist yet
+  if [ ! -f ${projectdir}/${module}.config ]; then
+    echo "// Add predefined macros for your project here. For example:" > ${projectdir}/${module}.config
+    echo "// #define YOUR_CONFIGURATION belongs here" >> ${projectdir}/${module}.config
   fi
-  # generate a default .creator file if none exists so far
-  if [ ! -f ${projectdir}/LightRing}.creator ]; then
-    echo "[general]" > ${projectdir}/LightRing.creator
+  # generate a default .creator file if it doesn't exist yet
+  if [ ! -f ${projectdir}/${module}.creator ]; then
+    echo "[general]" > ${projectdir}/${module}.creator
   fi
 
   # go back to user directory
@@ -593,11 +692,13 @@ function createLightRingProject {
   return 0
 }
 
-### create PowerManagement project files #######################################
-# Create project files for the PowerManagement module.
+### create project files for all modules #######################################
+# Create project files for all modules.
 #
-# usage:      createPowerManagementProject [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
-# arguments:  -p, --path <path>
+# usage:      createAllProjects <modules> [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
+# arguments:  <modules>
+#                 Array containing all modules available.
+#             -p, --path <path>
 #                 Path where to create the project files.
 #             --gcc=<path>
 #                 Path to the GCC include directory.
@@ -605,11 +706,16 @@ function createLightRingProject {
 #                 Variable to store the path to.
 #             --gccout=<var>
 #                 Variable to store the path to the GCC include directory to.
+#                 If this optional arguments is absent, ths function will ask for user input.
 # return:     0
 #                 No error or warning occurred.
+#             1
+#                 Aborted by user.
+#             -1
+#                 No modules available.
 #
-function createPowerManagementProject {
-  local userdir=$(pwd)
+function createAllProjects {
+  local modules=("${!1}")
   local projectdir=""
   local gccincludedir=""
   local outvar=""
@@ -645,107 +751,92 @@ function createPowerManagementProject {
     fi
   done
 
-  # print message
-  printInfo "creating QtCreator project files for the PowerManagement module...\n"
+  # sanity check for the modules variable
+  if [ -z "${modules[*]}" ]; then
+    printError "no modules available\n"
+    return -1
+  fi
 
   # read absolute project directory if required
   if [ -z "$projectdir" ]; then
     getProjectDir projectdir
   fi
 
-  # retrieve absolute GCC include dir
-  if [ -z "$gccincludedir" ]; then
-    retrieveGccIncludeDir gccincludedir
-  fi
-
-  # move to project directory
-  cd $projectdir
-
-  # AMiRo-OS, ChibiOS, AMiRo-BLT and AMiRo-LLD relative root directories
-  local amiroosrootdir=$(realpath $(dirname ${BASH_SOURCE[0]})/../../..)
-  local chibiosrootdir=$(realpath ${amiroosrootdir}/kernel/ChibiOS)
-  local amirobltrootdir=$(realpath ${amiroosrootdir}/bootloader/AMiRo-BLT)
-  local amirolldrootdir=$(realpath ${amiroosrootdir}/periphery-lld/AMiRo-LLD)
-
-  # generate a file that contains all subdirectories as includes (but ignore hidden and documentation directories)
-  find $gccincludedir -type d > ${projectdir}/PowerManagement.includes
-  echo $amiroosrootdir >> ${projectdir}/PowerManagement.includes
-  find $amiroosrootdir/modules -type d | grep -v "/doc\|/build\|/.dep\|/LightRing\|/DiWheelDrive" >> ${projectdir}/PowerManagement.includes
-  find $amiroosrootdir/core -type d >> ${projectdir}/PowerManagement.includes
-  find $amiroosrootdir/unittests -type d >> ${projectdir}/PowerManagement.includes
-  find $chibiosrootdir -type d | grep -E "/os/common/abstractions/cmsis_os$" >> ${projectdir}/PowerManagement.includes
-  find $chibiosrootdir -type d | grep -E "/os/common/ext/CMSIS/(include|ST/STM32F4xx)$" >> ${projectdir}/PowerManagement.includes
-  find $chibiosrootdir -type d | grep -E "/os/common/oslib/(include|src)$" >> ${projectdir}/PowerManagement.includes
-  find $chibiosrootdir -type d | grep -E "/os/common/ports/ARMCMx(/compilers/GCC)?$" >> ${projectdir}/PowerManagement.includes
-  find $chibiosrootdir -type d | grep -E "/os/common/startup/ARMCMx/(compilers/GCC|devices/STM32F4xx)$" >> ${projectdir}/PowerManagement.includes
-  find $chibiosrootdir -type d | grep -E "/os/hal/(include|src)$" >> ${projectdir}/PowerManagement.includes
-  find $chibiosrootdir -type d | grep -E "/os/hal/lib/streams" >> ${projectdir}/PowerManagement.includes
-  find $chibiosrootdir -type d | grep -E "/os/hal/osal/(lib|rt)$" >> ${projectdir}/PowerManagement.includes
-  find $chibiosrootdir -type d | grep -E "/os/hal/ports/(common/ARMCMx|STM32/(LLD/(ADCv2|CANv1|DACv1|DMAv2|EXTIv1|GPIOv2|I2Cv1|MACv1|OTGv1|RTCv2|SDIOv1|SPIv1|TIMv1|USARTv1|USBv1|xWDGv1)|STM32F4xx))$" >> ${projectdir}/PowerManagement.includes
-  find $chibiosrootdir -type d | grep -E "/os/license$" >> ${projectdir}/PowerManagement.includes
-  find $chibiosrootdir -type d | grep -E "/os/rt/(include|src)$" >> ${projectdir}/PowerManagement.includes
-  find $chibiosrootdir -type d | grep -E "/test/(lib|rt/source/test)$" >> ${projectdir}/PowerManagement.includes
-  find $amirobltrootdir -type d | grep -E "/Target/Source/AMiRo$" >> ${projectdir}/PowerManagement.includes
-  echo "$(realpath ${amirolldrootdir}/..)" >> ${projectdir}/PowerManagement.includes
-  find $amirolldrootdir -type d | grep -v "/doc" >> ${projectdir}/PowerManagement.includes
-  # generate a file that specifies all files
-  echo -n "" > ${projectdir}/PowerManagement.files
-  for path in `cat ${projectdir}/PowerManagement.includes`; do
-    find $path -maxdepth 1 -type f \( ! -iname ".*" \) |
-      grep -Ev "^.*((/arm-none-eabi/)|(LightRing)|(DiWheelDrive)).*$" |
-      grep -E  "^.*(\.s|\.S|\.h|\.c|\.hpp|\.cpp|\.tpp|\.ld)$" |
-      grep -Ev "^${chibiosrootdir}/os/common/ext/CMSIS/ST/STM32F4xx/((stm32f4[^0x])|(stm32f40[^5])).*$" |
-      grep -Ev "^${chibiosrootdir}/os/common/ext/CMSIS/include/((core_[^c])|(core_c[^m])|(core_cm[^4A-Za-z])|(cmsis_[^g])|(cmsis_g[^c]|(cmsis_gc[^c])))" |
-      grep -Ev "^${chibiosrootdir}/os/common/ports/ARMCMx/chcore_v[^7]m.*$" |
-      grep -Ev "^${chibiosrootdir}/os/common/ports/ARMCMx/compilers/GCC/.*_v[^7]m.*$" |
-      grep -Ev "^${chibiosrootdir}/os/common/startup/ARMCMx/compilers/GCC/.*_v[^7]m.*$" |
-      grep -Ev "^${amirobltrootdir}/Target/Source/AMiRo/helper.*$" >> ${projectdir}/PowerManagement.files;
+  # check for existing project files
+  local projectfiles=()
+  for module in ${modules[@]}; do
+    local pfiles="$(find ${projectdir} -maxdepth 1 -type f | grep -E "${module}\.(includes|files|config|creator)$")"
+    IFS=$'\n'; pfiles=($pfiles); unset IFS
+    projectfiles=( ${projectfiles[*]} ${pfiles[*]} )
   done
-  # generate a default project configuration file if none exists so far
-  if [ ! -f ${projectdir}/PowerManagement.config ]; then
-    echo "// Add predefined macros for your project here. For example:" > ${projectdir}/PowerManagement.config
-    echo "// #define YOUR_CONFIGURATION belongs here" >> ${projectdir}/PowerManagement.config
-  fi
-  # generate a default .creator file if none exists so far
-  if [ ! -f ${projectdir}/PowerManagement.creator ]; then
-    echo "[general]" > ${projectdir}/PowerManagement.creator
+  if [ ! -z "${projectfiles[*]}" ]; then
+    printWarning "The following files will be removed:\n"
+    for pfile in ${projectfiles[@]}; do
+      printWarning "\t$(basename $pfile)\n"
+    done
+    local userinput=""
+    printInfo "Continue and overwrite? [y/n]\n"
+    readUserInput "YyNn" userinput
+    case "${userinput}" in
+      Y|y)
+        for pfile in ${projectfiles[*]}; do
+          rm "$pfile"
+        done
+        ;;
+      N|n)
+        printWarning "Project generation aborted by user\n"
+        return 1
+        ;;
+      *)
+        printError "unexpected input: ${userinput}\n"
+        return 999
+        ;;
+    esac
   fi
 
-  # go back to user directory
-  cd $userdir
+  # print message
+  printf "\n"
+  printInfo "generating QtCreator project files for all modules...\n"
 
-  # fill the output variables
-  if [ ! -z "$outvar" ]; then
-    eval $outvar="$projectdir"
-  fi
-  if [ ! -z "$gccoutvar" ]; then
-    eval $gccoutvar="$gccincludedir"
+  # retrieve absolute GCC include path
+  if [ -z "$gccincludedir" ]; then
+    retrieveGccIncludeDir gccincludedir
   fi
 
+  # iterate over all modules
+  local retval=1
+  for module in ${modules[@]}; do
+    if [ $retval != 0 ]; then
+      printf "\n"
+    fi
+    createModuleProject modules[@] --module="$module" --path="$projectdir" --gcc="$gccincludedir"
+    retval=$?
+  done
+
   return 0
 }
 
-### create DiWheelDrive project files ##########################################
-# Create project files for the DiWheelDrive module.
+### delete project files #######################################################
+# Deletes all project files and optionally .user files, too.
 #
-# usage:      createDiWheelDriveProject [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
+# usage:      deleteProjects [-p|--path=<path>] [-m|--module=<module>] [-o|--out=<var>] [-w|-wipe]
 # arguments:  -p, --path <path>
-#                 Path where to create the project files.
-#             --gcc=<path>
-#                 Path to the GCC include directory.
+#                 Path where to delete the project files.
+#             -m, --module <module>
+#                 Module name for which the project files shall be deleted.
 #             -o, --out <var>
 #                 Variable to store the path to.
-#             --gccout=<var>
-#                 Variable to store the path to the GCC include directory to.
-# return:     0
-#                 No error or warning occurred.
+#             -w, --wipe
+#                 Delete .user files as well.
+# return:
+#  -  0: no error
 #
-function createDiWheelDriveProject {
-  local userdir=$(pwd)
+function deleteProjects {
+  local modulename=""
   local projectdir=""
-  local gccincludedir=""
   local outvar=""
-  local gccoutvar=""
+  local wipe=false
+  local files=""
 
   # parse arguments
   local otherargs=()
@@ -756,18 +847,16 @@ function createDiWheelDriveProject {
           projectdir=$(realpath "${1#*=}"); shift 1;;
         -p|--path)
           projectdir=$(realpath "$2"); shift 2;;
-        --gcc=*)
-          gccincludedir=$(realpath "${1#*=}"); shift 1;;
-        --gcc)
-          gccincludedir=$(realpath "$2"); shift 2;;
+        -m=*|--module=*)
+          modulename="${1#*=}"; shift 1;;
+        -m|--module)
+          modulename="${2}"; shift 2;;
         -o=*|--out=*)
           outvar=${1#*=}; shift 1;;
         -o|--out)
           outvar=$2; shift 2;;
-        --gccout=*)
-          gccoutvar=$(realpath "${1#*=}"); shift 1;;
-        --gccout)
-          gccoutvar=$(realpath "$2"); shift 2;;
+        -w|--wipe)
+          wipe=true; shift 1;;
         *)
           printError "invalid option: $1\n"; shift 1;;
       esac
@@ -777,111 +866,39 @@ function createDiWheelDriveProject {
     fi
   done
 
-  # print message
-  printInfo "creating QtCreator project files for the DiWheelDrive module...\n"
-
   # read absolute project directory if required
   if [ -z "$projectdir" ]; then
     getProjectDir projectdir
   fi
 
-  # retrieve absolute GCC include dir
-  if [ -z "$gccincludedir" ]; then
-    retrieveGccIncludeDir gccincludedir
-  fi
-
-  # move to project directory
-  cd $projectdir
-
-  # AMiRo-OS, ChibiOS, AMiRo-BLT and AMiRo-LLD relative root directories
-  local amiroosrootdir=$(realpath $(dirname ${BASH_SOURCE[0]})/../../..)
-  local chibiosrootdir=$(realpath ${amiroosrootdir}/kernel/ChibiOS)
-  local amirobltrootdir=$(realpath ${amiroosrootdir}/bootloader/AMiRo-BLT)
-  local amirolldrootdir=$(realpath ${amiroosrootdir}/periphery-lld/AMiRo-LLD)
-
-  # generate a file that contains all subdirectories as includes (but ignore hidden and documentation directories)
-  find $gccincludedir -type d > ${projectdir}/DiWheelDrive.includes
-  echo $amiroosrootdir >> ${projectdir}/DiWheelDrive.includes
-  find $amiroosrootdir/modules -type d | grep -v "/doc\|/build\|/.dep\|/LightRing\|/PowerManagement" >> ${projectdir}/DiWheelDrive.includes
-  find $amiroosrootdir/core -type d >> ${projectdir}/DiWheelDrive.includes
-  find $amiroosrootdir/unittests -type d >> ${projectdir}/DiWheelDrive.includes
-  find $chibiosrootdir -type d | grep -E "/os/common/abstractions/cmsis_os$" >> ${projectdir}/DiWheelDrive.includes
-  find $chibiosrootdir -type d | grep -E "/os/common/ext/CMSIS/(include|ST/STM32F1xx)$" >> ${projectdir}/DiWheelDrive.includes
-  find $chibiosrootdir -type d | grep -E "/os/common/oslib/(include|src)$" >> ${projectdir}/DiWheelDrive.includes
-  find $chibiosrootdir -type d | grep -E "/os/common/ports/ARMCMx(/compilers/GCC)?$" >> ${projectdir}/DiWheelDrive.includes
-  find $chibiosrootdir -type d | grep -E "/os/common/startup/ARMCMx/(compilers/GCC|devices/STM32F1xx)$" >> ${projectdir}/DiWheelDrive.includes
-  find $chibiosrootdir -type d | grep -E "/os/hal/(include|src)$" >> ${projectdir}/DiWheelDrive.includes
-  find $chibiosrootdir -type d | grep -E "/os/hal/lib/streams" >> ${projectdir}/DiWheelDrive.includes
-  find $chibiosrootdir -type d | grep -E "/os/hal/osal/(lib|rt)$" >> ${projectdir}/DiWheelDrive.includes
-  find $chibiosrootdir -type d | grep -E "/os/hal/ports/(common/ARMCMx|STM32/(LLD/(CANv1|DACv1|DMAv1|EXTIv1|GPIOv1|I2Cv1|RTCv1|SDIOv1|SPIv1|TIMv1|USARTv1|USBv1|xWDGv1)|STM32F1xx))$" >> ${projectdir}/DiWheelDrive.includes
-  find $chibiosrootdir -type d | grep -E "/os/license$" >> ${projectdir}/DiWheelDrive.includes
-  find $chibiosrootdir -type d | grep -E "/os/rt/(include|src)$" >> ${projectdir}/DiWheelDrive.includes
-  find $chibiosrootdir -type d | grep -E "/test/(lib|rt/source/test)$" >> ${projectdir}/DiWheelDrive.includes
-  find $amirobltrootdir -type d | grep -E "/Target/Source/AMiRo$" >> ${projectdir}/DiWheelDrive.includes
-  echo "$(realpath ${amirolldrootdir}/..)" >> ${projectdir}/DiWheelDrive.includes
-  find $amirolldrootdir -type d | grep -v "/doc" >> ${projectdir}/DiWheelDrive.includes
-  # generate a file that specifies all files
-  echo -n "" > ${projectdir}/DiWheelDrive.files
-  for path in `cat ${projectdir}/DiWheelDrive.includes`; do
-    find $path -maxdepth 1 -type f \( ! -iname ".*" \) |
-      grep -Ev "^.*((/arm-none-eabi/)|(LightRing)|(PowerManagement)).*$" |
-      grep -E  "^.*(\.s|\.S|\.h|\.c|\.hpp|\.cpp|\.tpp|\.ld)$" |
-      grep -Ev "^${chibiosrootdir}/os/common/ext/CMSIS/ST/STM32F1xx/((stm32f1[^0x])|(stm32f10[^3])|(stm32f103[^x])|(stm32f103x[^e])).*$" |
-      grep -Ev "^${chibiosrootdir}/os/common/ext/CMSIS/include/((core_[^c])|(core_c[^m])|(core_cm[^3A-Za-z])|(cmsis_[^g])|(cmsis_g[^c]|(cmsis_gc[^c])))" |
-      grep -Ev "^${chibiosrootdir}/os/common/ports/ARMCMx/chcore_v[^7]m.*$" |
-      grep -Ev "^${chibiosrootdir}/os/common/ports/ARMCMx/compilers/GCC/.*_v[^7]m.*$" |
-      grep -Ev "^${chibiosrootdir}/os/common/startup/ARMCMx/compilers/GCC/.*_v[^7]m.*$" |
-      grep -Ev "^${chibiosrootdir}/os/hal/ports/STM32/STM32F1xx/.*f10[^3].*$" |
-      grep -Ev "^${amirobltrootdir}/Target/Source/AMiRo/helper.*$" >> ${projectdir}/DiWheelDrive.files;
-  done
-  # generate a default project configuration file if none exists so far
-  if [ ! -f ${projectdir}/DiWheelDrive.config ]; then
-    echo "// Add predefined macros for your project here. For example:" > ${projectdir}/DiWheelDrive.config
-    echo "// #define YOUR_CONFIGURATION belongs here" >> ${projectdir}/DiWheelDrive.config
+  # list all files to be deleted
+  if [ -z "$modulename" ]; then
+    if [ $wipe != true ]; then
+      files=$(find "${projectdir}" -maxdepth 1 -type f | grep -E "^.+\.(includes|files|config|creator)$")
+    else
+      files=$(find "${projectdir}" -maxdepth 1 -type f | grep -E "^.+\.(includes|files|config|creator|creator\.user)$")
+    fi
+  else
+    if [ $wipe != true ]; then
+      files=$(find "${projectdir}" -maxdepth 1 -type f | grep -E "^.${modulename}\.(includes|files|config|creator)$")
+    else
+      files=$(find "${projectdir}" -maxdepth 1 -type f | grep -E "^.${modulename}\.(includes|files|config|creator|creator\.user)$")
+    fi
   fi
-  # generate a default .creator file if none exists so far
-  if [ ! -f ${projectdir}/DiWheelDrive.creator ]; then
-    echo "[general]" > ${projectdir}/DiWheelDrive.creator
+  if [ ! -z "$files" ]; then
+    printInfo "Deleting the following files:\n"
+    while read line; do
+      printInfo "\t$(basename ${line})\n"
+      rm ${line} 2>&1 | tee -a $LOG_FILE
+    done <<< "${files}"
+  else
+    printInfo "No project files found\n"
   fi
 
-  # go back to user directory
-  cd $userdir
-
-  # fill the output variables
+  # store the path to the output variable, if required
   if [ ! -z "$outvar" ]; then
     eval $outvar="$projectdir"
   fi
-  if [ ! -z "$gccoutvar" ]; then
-    eval $gccoutvar="$gccincludedir"
-  fi
-
-  return 0
-}
-
-### create project files for all modules #######################################
-# Create project files for all modules.
-#
-# usage:      createAllProjects
-# arguments:  n/a
-# return:     0
-#                 No error or warning occurred.
-#
-function createAllProjects {
-  # print message
-  printInfo "creating QtCreator project files for the DiWheelDrive module...\n"
-
-  # read project directory
-  local projectdir=""
-  getProjectDir projectdir
-  printInfo "files will be created in $projectdir\n"
-
-  # retrieve gcc-arm-none-eabi include dir
-  retrieveGccIncludeDir gccincludedir
-
-  # create projects
-  createLightRingProject --path="$projectdir" --gcc="$gccincludedir"
-  createPowerManagementProject --path="$projectdir" --gcc="$gccincludedir"
-  createDiWheelDriveProject --path="$projectdir" --gcc="$gccincludedir"
 
   return 0
 }
@@ -936,6 +953,22 @@ function main {
   # log script name
   printLog "this is $(realpath ${BASH_SOURCE[0]})\n"
 
+  # detect available modules and inform user
+  local modules=()
+  detectModules modules
+  case "${#modules[@]}" in
+    0)
+      printInfo "no module has been detected\n";;
+    1)
+      printInfo "1 module has been detected:\n";;
+    *)
+      printInfo "${#modules[@]} modules have been detected:\n"
+  esac
+  for (( idx=0; idx<${#modules[@]}; ++idx )); do
+    printInfo "  - ${modules[$idx]}\n"
+  done
+  printf "\n"
+
   # parse arguments
   local otherargs=()
   while [ $# -gt 0 ]; do
@@ -943,18 +976,16 @@ function main {
       case "$1" in
         -h|--help) # already handled; ignore
           shift 1;;
+        -m=*|--module=*)
+          createModuleProject modules[@] --module="${1#*=}"; printf "\n"; shift 1;;
+        -m*|--module*)
+           createModuleProject modules[@] --module="${2}"; printf "\n"; shift 2;;
+        -a|--all)
+           createAllProjects modules[@]; shift 1;;
         -c|--clean)
           deleteProjects; printf "\n"; shift 1;;
         -w|--wipe)
           deleteProjects --wipe; printf "\n"; shift 1;;
-        --LightRing)
-          createLightRingProject; printf "\n"; shift 1;;
-        --PowerManagement)
-          createPowerManagementProject; printf "\n"; shift 1;;
-        --DiWheelDrive)
-          createDiWheelDriveProject; printf "\n"; shift 1;;
-        -a|--all)
-          createAllProjects; printf "\n"; shift 1;;
         -q|--quit)
           quitScript; shift 1;;
         --log=*|--LOG=*) # already handled; ignore
@@ -977,31 +1008,25 @@ function main {
     # main menu info prompt and selection
     printInfo "QtCreator setup main menu\n"
     printf "Please select one of the following actions:\n"
-    printf "  [C] - clean project files\n"
-    printf "  [W] - wipe project and .user files\n"
-    printf "  [L] - create a project for the LightRing module\n"
-    printf "  [P] - create a project for the PowerManagement module\n"
-    printf "  [D] - create a project for the DiWheelDrive module\n"
+    printf "  [M] - create a project for a single module\n"
     printf "  [A] - create a project for all modules\n"
+    printf "  [C] - clean all project files\n"
+    printf "  [W] - wipe all project and .user files\n"
     printf "  [Q] - quit this setup\n"
     local userinput=""
-    readUserInput "CcWwLlPpDdAaQq" userinput
+    readUserInput "MmAaCcWwQq" userinput
     printf "\n"
 
     # evaluate user selection
     case "$userinput" in
+      M|m)
+        createModuleProject modules[@]; printf "\n";;
+      A|a)
+        createAllProjects modules[@]; printf "\n";;
       C|c)
         deleteProjects; printf "\n";;
       W|w)
         deleteProjects --wipe; printf "\n";;
-      L|l)
-        createLightRingProject; printf "\n";;
-      P|p)
-        createPowerManagementProject; printf "\n";;
-      D|d)
-        createDiWheelDriveProject; printf "\n";;
-      A|a)
-        createAllProjects; printf "\n";;
       Q|q)
         quitScript;;
       *) # sanity check (exit with error)
diff --git a/tools/ide/QtCreator/README.txt b/tools/ide/QtCreator/README.txt
index 1c6e9d4..446630b 100644
--- a/tools/ide/QtCreator/README.txt
+++ b/tools/ide/QtCreator/README.txt
@@ -1,7 +1,7 @@
 AMiRo-OS support the QtCreator IDE and provides tools and manuals to setup the
 according project files.
 
-Copyright (C) 2016..2018  Thomas Schöpping
+Copyright (C) 2016..2019  Thomas Schöpping
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/tools/ide/idesetup.sh b/tools/ide/idesetup.sh
index eef3902..bfb77db 100755
--- a/tools/ide/idesetup.sh
+++ b/tools/ide/idesetup.sh
@@ -1,7 +1,7 @@
 ################################################################################
 # AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
 # (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
+# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
 #                                                                              #
 # This program is free software: you can redistribute it and/or modify         #
 # it under the terms of the GNU General Public License as published by         #
@@ -263,6 +263,40 @@ function setLogFile {
   return 0
 }
 
+### check whether commands are available #######################################
+# Checks whether the specified commands are available and can be executed.
+#
+# usage:      checkCommand [<command> <command> ...]
+# arguments:  <command>
+#                 Name of the command to check.
+# return:     0
+#                 All requested commands are available.
+#             >0
+#                 Number of requested commands that were not found.
+#             -1
+#                 No argument given.
+#
+function checkCommands {
+  local status=0
+
+  # return if no argument was specified
+  if [ $# -eq 0 ]; then
+    return -1
+  fi
+
+  # check all specified commands
+  while [ $# -gt 0 ]; do
+    command -v $1 &>/dev/null
+    if [ $? -ne 0 ]; then
+      printWarning "Command '$1' not available.\n"
+      status=$((status + 1))
+    fi
+    shift 1
+  done
+
+  return $status
+}
+
 ################################################################################
 # SPECIFIC FUNCTIONS                                                           #
 ################################################################################
@@ -281,7 +315,7 @@ function printWelcomeText {
   printf "#                                                                    #\n"
   printf "######################################################################\n"
   printf "#                                                                    #\n"
-  printf "# Copyright (c) 2016..2018  Thomas Schöpping                         #\n"
+  printf "# Copyright (c) 2016..2019  Thomas Schöpping                         #\n"
   printf "#                                                                    #\n"
   printf "# This is free software; see the source for copying conditions.      #\n"
   printf "# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR  #\n"
diff --git a/unittests/lld/inc/ut_lld_adc.h b/unittests/lld/inc/ut_lld_adc.h
index b3cae14..183c415 100644
--- a/unittests/lld/inc/ut_lld_adc.h
+++ b/unittests/lld/inc/ut_lld_adc.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/lld/src/ut_lld_adc.c b/unittests/lld/src/ut_lld_adc.c
index 05721f7..cb09a71 100644
--- a/unittests/lld/src/ut_lld_adc.c
+++ b/unittests/lld/src/ut_lld_adc.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/inc/ut_alld_a3906.h b/unittests/periphery-lld/inc/ut_alld_a3906.h
index 145d21c..7ac34e9 100644
--- a/unittests/periphery-lld/inc/ut_alld_a3906.h
+++ b/unittests/periphery-lld/inc/ut_alld_a3906.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/inc/ut_alld_at24c01bn-sh-b.h b/unittests/periphery-lld/inc/ut_alld_at24c01bn-sh-b.h
index 1ed579e..3957713 100644
--- a/unittests/periphery-lld/inc/ut_alld_at24c01bn-sh-b.h
+++ b/unittests/periphery-lld/inc/ut_alld_at24c01bn-sh-b.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/inc/ut_alld_bq24103a.h b/unittests/periphery-lld/inc/ut_alld_bq24103a.h
index 889ce22..7bca55a 100644
--- a/unittests/periphery-lld/inc/ut_alld_bq24103a.h
+++ b/unittests/periphery-lld/inc/ut_alld_bq24103a.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/inc/ut_alld_bq27500.h b/unittests/periphery-lld/inc/ut_alld_bq27500.h
index 9818639..1c3682d 100644
--- a/unittests/periphery-lld/inc/ut_alld_bq27500.h
+++ b/unittests/periphery-lld/inc/ut_alld_bq27500.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/inc/ut_alld_bq27500_bq24103a.h b/unittests/periphery-lld/inc/ut_alld_bq27500_bq24103a.h
index 58836ce..7cd7069 100644
--- a/unittests/periphery-lld/inc/ut_alld_bq27500_bq24103a.h
+++ b/unittests/periphery-lld/inc/ut_alld_bq27500_bq24103a.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/inc/ut_alld_dw1000.h b/unittests/periphery-lld/inc/ut_alld_dw1000.h
index 43f98eb..8e002c4 100755
--- a/unittests/periphery-lld/inc/ut_alld_dw1000.h
+++ b/unittests/periphery-lld/inc/ut_alld_dw1000.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -16,8 +16,8 @@ You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _AMIROOS_UT_DW1000_LLD_HPP_
-#define _AMIROOS_UT_DW1000_LLD_HPP_
+#ifndef _AMIROOS_UT_DW1000_LLD_H_
+#define _AMIROOS_UT_DW1000_LLD_H_
 
 #include <aos_unittest.h>
 #include <amiro-lld.h>
@@ -37,4 +37,4 @@ extern "C" {
 
 #endif /* (AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_USE_DW1000) */
 
-#endif /* _AMIROOS_UT_DW1000_LLD_HPP_ */
+#endif /* _AMIROOS_UT_DW1000_LLD_H_ */
diff --git a/unittests/periphery-lld/inc/ut_alld_hmc5883l.h b/unittests/periphery-lld/inc/ut_alld_hmc5883l.h
index e478c2f..9dd5356 100644
--- a/unittests/periphery-lld/inc/ut_alld_hmc5883l.h
+++ b/unittests/periphery-lld/inc/ut_alld_hmc5883l.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -16,8 +16,8 @@ You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _AMIROOS_UT_HMC5883L_LLD_HPP_
-#define _AMIROOS_UT_HMC5883L_LLD_HPP_
+#ifndef _AMIROOS_UT_HMC5883L_LLD_H_
+#define _AMIROOS_UT_HMC5883L_LLD_H_
 
 #include <aos_unittest.h>
 #include <amiro-lld.h>
@@ -62,4 +62,4 @@ extern "C" {
 #endif /* (AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_USE_HMC5883L) */
 
 
-#endif /* _AMIROOS_UT_HMC5883L_LLD_HPP_ */
+#endif /* _AMIROOS_UT_HMC5883L_LLD_H_ */
diff --git a/unittests/periphery-lld/inc/ut_alld_ina219.h b/unittests/periphery-lld/inc/ut_alld_ina219.h
index c386e5f..4a26940 100644
--- a/unittests/periphery-lld/inc/ut_alld_ina219.h
+++ b/unittests/periphery-lld/inc/ut_alld_ina219.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -16,8 +16,8 @@ You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _AMIROOS_UT_INA219_LLD_HPP_
-#define _AMIROOS_UT_INA219_LLD_HPP_
+#ifndef _AMIROOS_UT_INA219_LLD_H_
+#define _AMIROOS_UT_INA219_LLD_H_
 
 #include <aos_unittest.h>
 #include <amiro-lld.h>
@@ -61,4 +61,4 @@ extern "C" {
 
 #endif /* (AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_USE_INA219) */
 
-#endif /* _AMIROOS_UT_INA219_LLD_HPP_ */
+#endif /* _AMIROOS_UT_INA219_LLD_H_ */
diff --git a/unittests/periphery-lld/inc/ut_alld_l3g4200d.h b/unittests/periphery-lld/inc/ut_alld_l3g4200d.h
index ff55790..d65a226 100644
--- a/unittests/periphery-lld/inc/ut_alld_l3g4200d.h
+++ b/unittests/periphery-lld/inc/ut_alld_l3g4200d.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -16,8 +16,8 @@ You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _AMIROOS_UT_L3G4200D_LLD_HPP_
-#define _AMIROOS_UT_L3G4200D_LLD_HPP_
+#ifndef _AMIROOS_UT_L3G4200D_LLD_H_
+#define _AMIROOS_UT_L3G4200D_LLD_H_
 
 #include <aos_unittest.h>
 #include <amiro-lld.h>
@@ -61,5 +61,5 @@ extern "C" {
 
 #endif /* (AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_USE_L3G4200D) */
 
-#endif /* _AMIROOS_UT_L3G4200D_LLD_HPP_ */
+#endif /* _AMIROOS_UT_L3G4200D_LLD_H_ */
 
diff --git a/unittests/periphery-lld/inc/ut_alld_led.h b/unittests/periphery-lld/inc/ut_alld_led.h
index d8a3e21..ec01070 100644
--- a/unittests/periphery-lld/inc/ut_alld_led.h
+++ b/unittests/periphery-lld/inc/ut_alld_led.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/inc/ut_alld_lis331dlh.h b/unittests/periphery-lld/inc/ut_alld_lis331dlh.h
index 41152f4..ad6caf4 100644
--- a/unittests/periphery-lld/inc/ut_alld_lis331dlh.h
+++ b/unittests/periphery-lld/inc/ut_alld_lis331dlh.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -16,8 +16,8 @@ You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _AMIROOS_UT_LIS331DLH_LLD_HPP_
-#define _AMIROOS_UT_LIS331DLH_LLD_HPP_
+#ifndef _AMIROOS_UT_LIS331DLH_LLD_H_
+#define _AMIROOS_UT_LIS331DLH_LLD_H_
 
 #include <aos_unittest.h>
 #include <amiro-lld.h>
@@ -61,5 +61,5 @@ extern "C" {
 
 #endif /* (AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_USE_LIS331DLH) */
 
-#endif /* _AMIROOS_UT_LIS331DLH_LLD_HPP_ */
+#endif /* _AMIROOS_UT_LIS331DLH_LLD_H_ */
 
diff --git a/unittests/periphery-lld/inc/ut_alld_ltc4412.h b/unittests/periphery-lld/inc/ut_alld_ltc4412.h
index 9a68766..9921ed7 100644
--- a/unittests/periphery-lld/inc/ut_alld_ltc4412.h
+++ b/unittests/periphery-lld/inc/ut_alld_ltc4412.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/inc/ut_alld_mpr121.h b/unittests/periphery-lld/inc/ut_alld_mpr121.h
index 019d521..d1c9632 100644
--- a/unittests/periphery-lld/inc/ut_alld_mpr121.h
+++ b/unittests/periphery-lld/inc/ut_alld_mpr121.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/inc/ut_alld_pca9544a.h b/unittests/periphery-lld/inc/ut_alld_pca9544a.h
index 08e153c..33012f1 100644
--- a/unittests/periphery-lld/inc/ut_alld_pca9544a.h
+++ b/unittests/periphery-lld/inc/ut_alld_pca9544a.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/inc/ut_alld_pklcs1212e4001.h b/unittests/periphery-lld/inc/ut_alld_pklcs1212e4001.h
index 9fc35c9..73ffa6b 100644
--- a/unittests/periphery-lld/inc/ut_alld_pklcs1212e4001.h
+++ b/unittests/periphery-lld/inc/ut_alld_pklcs1212e4001.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/inc/ut_alld_tlc5947.h b/unittests/periphery-lld/inc/ut_alld_tlc5947.h
index 5c31bdc..e5ed617 100644
--- a/unittests/periphery-lld/inc/ut_alld_tlc5947.h
+++ b/unittests/periphery-lld/inc/ut_alld_tlc5947.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/inc/ut_alld_tps2051bdbv.h b/unittests/periphery-lld/inc/ut_alld_tps2051bdbv.h
index 10e1e38..0dc5f4d 100644
--- a/unittests/periphery-lld/inc/ut_alld_tps2051bdbv.h
+++ b/unittests/periphery-lld/inc/ut_alld_tps2051bdbv.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/inc/ut_alld_tps62113.h b/unittests/periphery-lld/inc/ut_alld_tps62113.h
index 9915ea4..a76bdbe 100644
--- a/unittests/periphery-lld/inc/ut_alld_tps62113.h
+++ b/unittests/periphery-lld/inc/ut_alld_tps62113.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/inc/ut_alld_tps62113_ina219.h b/unittests/periphery-lld/inc/ut_alld_tps62113_ina219.h
index 034fd82..7c4cf6d 100644
--- a/unittests/periphery-lld/inc/ut_alld_tps62113_ina219.h
+++ b/unittests/periphery-lld/inc/ut_alld_tps62113_ina219.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/inc/ut_alld_vcnl4020.h b/unittests/periphery-lld/inc/ut_alld_vcnl4020.h
index 4c0c37f..68c72cc 100644
--- a/unittests/periphery-lld/inc/ut_alld_vcnl4020.h
+++ b/unittests/periphery-lld/inc/ut_alld_vcnl4020.h
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -16,8 +16,8 @@ You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _AMIROOS_UT_VCNL4020_LLD_HPP_
-#define _AMIROOS_UT_VCNL4020_LLD_HPP_
+#ifndef _AMIROOS_UT_VCNL4020_LLD_H_
+#define _AMIROOS_UT_VCNL4020_LLD_H_
 
 #include <aos_unittest.h>
 #include <amiro-lld.h>
@@ -61,6 +61,6 @@ extern "C" {
 
 #endif /* (AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_USE_VCNL4020) */
 
-#endif /* _AMIROOS_UT_VCNL4020_LLD_HPP_ */
+#endif /* _AMIROOS_UT_VCNL4020_LLD_H_ */
 
 
diff --git a/unittests/periphery-lld/module.h b/unittests/periphery-lld/module.h
deleted file mode 100755
index ed68d1f..0000000
--- a/unittests/periphery-lld/module.h
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
-AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _AMIROOS_MODULE_H_
-#define _AMIROOS_MODULE_H_
-
-/*===========================================================================*/
-/**
- * @name Module specific functions
- * @{
- */
-/*===========================================================================*/
-
-static void _alld_dw1000_callback(void* args);
-
-/** @} */
-
-/*===========================================================================*/
-/**
- * @name ChibiOS/HAL configuration
- * @{
- */
-/*===========================================================================*/
-#include <hal.h>
-
-/**
- * @brief   CAN driver to use.
- */
-#define MODULE_HAL_CAN                          CAND1
-
-/**
- * @brief   Configuration for the CAN driver.
- */
-extern CANConfig moduleHalCanConfig;
-
-/**
- * @brief   I2C driver to access the EEPROM.
- */
-#define MODULE_HAL_I2C_EEPROM                   I2CD2
-
-/**
- * @brief   Configuration for the EEPROM I2C driver.
- */
-extern I2CConfig moduleHalI2cEepromConfig;
-
-/**
- * @brief   Serial driver of the programmer interface.
- */
-#define MODULE_HAL_PROGIF                       SD1
-
-/**
- * @brief   Configuration for the programmer serial interface driver.
- */
-extern SerialConfig moduleHalProgIfConfig;
-
-/**
- * @brief   SPI interface driver for the motion sensors (gyroscope and accelerometer).
- */
-#define MODULE_HAL_SPI_LIGHT                    SPID1
-
-/**
- * @brief   SPI interface driver for UWB Module.
- */
-#define MODULE_HAL_SPI_UWB                      SPID2
-
-/**
- * @brief   Configuration for the SPI interface driver to communicate with the LED driver.
- */
-extern SPIConfig moduleHalSpiLightConfig;
-
-/**
- * @brief   Configuration for the SPI interface driver to communicate with the LED driver.
- */
-extern SPIConfig moduleHalSpiUWBConfig;
-
-/**
- * @brief   Real-Time Clock driver.
- */
-#define MODULE_HAL_RTC                          RTCD1
-
-/** @} */
-
-/*===========================================================================*/
-/**
- * @name GPIO definitions
- * @{
- */
-/*===========================================================================*/
-#include <amiro-lld.h>
-
-/**
- * @brief   LIGHT_BANK output signal GPIO.
- */
-extern apalControlGpio_t moduleGpioLightBlank;
-
-/**
- * @brief   LASER_EN output signal GPIO.
- */
-extern apalControlGpio_t moduleGpioLaserEn;
-
-/**
- * @brief   LASER_OC input signal GPIO.
- */
-extern apalControlGpio_t moduleGpioLaserOc;
-
-/**
- * @brief   SYS_UART_DN bidirectional signal GPIO.
- */
-extern apalControlGpio_t moduleGpioSysUartDn;
-
-/**
- * @brief   WL_GDO2 input signal GPIO.
- */
-extern apalControlGpio_t moduleGpioWlGdo2;
-
-/**
- * @brief   WL_GDO0 input signal GPIO.
- */
-extern apalControlGpio_t moduleGpioWlGdo0;
-
-/**
- * @brief   LIGHT_XLAT output signal GPIO.
- */
-extern apalControlGpio_t moduleGpioLightXlat;
-
-/**
- * @brief   SYS_PD bidirectional signal GPIO.
- */
-extern apalControlGpio_t moduleGpioSysPd;
-
-/**
- * @brief   SYS_SYNC bidirectional signal GPIO.
- */
-extern apalControlGpio_t moduleGpioSysSync;
-
-/** @} */
-
-/*===========================================================================*/
-/**
- * @name AMiRo-OS core configurations
- * @{
- */
-/*===========================================================================*/
-
-/**
- * @brief   Event flag to be set on a LASER_OC interrupt.
- */
-#define MODULE_OS_IOEVENTFLAGS_LASEROC          ((eventflags_t)1 << GPIOB_LASER_OC_N)
-
-/**
- * @brief   Event flag to be set on a SYS_UART_DN interrupt.
- */
-#define MODULE_OS_IOEVENTFLAGS_SYSUARTDN        ((eventflags_t)1 << GPIOB_SYS_UART_DN)
-
-/**
- * @brief   Event flag to be set on a WL_GDO2 interrupt.
- */
-#define MODULE_OS_IOEVENTFLAGS_WLGDO2           ((eventflags_t)1 << GPIOB_WL_GDO2)
-
-/**
- * @brief   Event flag to be set on a WL_GDO0 interrupt.
- */
-#define MODULE_OS_IOEVENTFLAGS_WLGDO0           ((eventflags_t)1 << GPIOB_WL_GDO0)
-
-/**
- * @brief   Event flag to be set on a SYS_PD interrupt.
- */
-#define MODULE_OS_IOEVENTFLAGS_SYSPD            ((eventflags_t)1 << GPIOC_SYS_PD_N)
-
-/**
- * @brief   Event flag to be set on a SYS_SYNC interrupt.
- */
-#define MODULE_OS_IOEVENTFLAGS_SYSSYNC          ((eventflags_t)1 << GPIOD_SYS_INT_N)
-
-#if (AMIROOS_CFG_SHELL_ENABLE == true) || defined(__DOXYGEN__)
-/**
- * @brief   Shell prompt text.
- */
-extern const char* moduleShellPrompt;
-#endif
-
-
-
-
-/**
- * @brief   Interrupt initialization macro.
- * @note    SSSP related interrupt signals are already initialized in 'aos_system.c'.
- */
-#define MODULE_INIT_INTERRUPTS() {                                            \
-  /* LASER_OC */                                                              \
-  palSetPadCallback(moduleGpioLaserOc.gpio->port, moduleGpioLaserOc.gpio->pad, _intCallback, &moduleGpioLaserOc.gpio->pad); \
-  palEnablePadEvent(moduleGpioLaserOc.gpio->port, moduleGpioLaserOc.gpio->pad, APAL2CH_EDGE(moduleGpioLaserOc.meta.edge));  \
-  /* WL_GDO2 */                                                               \
-  palSetPadCallback(moduleGpioWlGdo2.gpio->port, moduleGpioWlGdo2.gpio->pad, _alld_dw1000_callback, &moduleGpioWlGdo2.gpio->pad);  \
-  palEnablePadEvent(moduleGpioWlGdo2.gpio->port, moduleGpioWlGdo2.gpio->pad, APAL2CH_EDGE(moduleGpioWlGdo2.meta.edge));   \
-  /* WL_GDO0 */                                                               \
-  palSetPadCallback(moduleGpioWlGdo0.gpio->port, moduleGpioWlGdo0.gpio->pad, _alld_dw1000_callback, &moduleGpioWlGdo0.gpio->pad);  \
-  /*palEnablePadEvent(moduleGpioWlGdo0.gpio->port, moduleGpioWlGdo0.gpio->pad, APAL2CH_EDGE(moduleGpioWlGdo0.meta.edge)); // this is broken for some reason*/   \
-}
-
-/**
- * @brief   Unit test initialization hook.
- */
-#define MODULE_INIT_TESTS() {                                                 \
-  /* add unit-test shell commands */                                          \
-  aosShellAddCommand(&aos.shell, &moduleUtAlldAt24c01bn.shellcmd);            \
-  aosShellAddCommand(&aos.shell, &moduleUtAlldTlc5947.shellcmd);              \
-  aosShellAddCommand(&aos.shell, &moduleUtAlldTps2051bdbv.shellcmd);          \
-  aosShellAddCommand(&aos.shell, &moduleUtAlldDw1000.shellcmd);                \
-}
-
-/**
- * @brief   Periphery communication interfaces initialization hook.
- */
-#define MODULE_INIT_PERIPHERY_COMM() {                                        \
-  /* serial driver */                                                         \
-  sdStart(&MODULE_HAL_PROGIF, &moduleHalProgIfConfig);                        \
-  /* I2C */                                                                   \
-  moduleHalI2cEepromConfig.clock_speed = (AT24C01BN_LLD_I2C_MAXFREQUENCY < moduleHalI2cEepromConfig.clock_speed) ? AT24C01BN_LLD_I2C_MAXFREQUENCY : moduleHalI2cEepromConfig.clock_speed; \
-  moduleHalI2cEepromConfig.duty_cycle = (moduleHalI2cEepromConfig.clock_speed <= 100000) ? STD_DUTY_CYCLE : FAST_DUTY_CYCLE_2;  \
-  i2cStart(&MODULE_HAL_I2C_EEPROM, &moduleHalI2cEepromConfig);                \
-  /* SPI */                                                                   \
-  spiStart(&MODULE_HAL_SPI_LIGHT, &moduleHalSpiLightConfig);                  \
-  spiStart(&MODULE_HAL_SPI_UWB, &moduleHalSpiUWBConfig);                      \
-}
-
-/**
- * @brief   Periphery communication interface deinitialization hook.
- */
-#define MODULE_SHUTDOWN_PERIPHERY_COMM() {                                    \
-  /* SPI */                                                                   \
-  spiStop(&MODULE_HAL_SPI_LIGHT);                                             \
-  spiStop(&MODULE_HAL_SPI_UWB);                                               \
-  /* I2C */                                                                   \
-  i2cStop(&MODULE_HAL_I2C_EEPROM);                                            \
-  /* don't stop the serial driver so messages can still be printed */         \
-}
-
-/** @} */
-
-#if (AMIROOS_CFG_SSSP_ENABLE == true)
-/*===========================================================================*/
-/**
- * @name Startup Shutdown Synchronization Protocol (SSSP)
- * @{
- */
-/*===========================================================================*/
-
-/**
- * @brief   PD signal GPIO.
- */
-#define moduleSsspGpioPd                        moduleGpioSysPd
-
-/**
- * @brief   SYNC signal GPIO.
- */
-#define moduleSsspGpioSync                      moduleGpioSysSync
-
-/**
- * @brief   DN signal GPIO.
- */
-#define moduleSsspGpioDn                        moduleGpioSysUartDn
-
-/**
- * @brief   Event flags for PD signal events.
- */
-#define MODULE_SSSP_EVENTFLAGS_PD               MODULE_OS_IOEVENTFLAGS_SYSPD
-
-/**
- * @brief   Event flags for SYNC signal events.
- */
-#define MODULE_SSSP_EVENTFLAGS_SYNC             MODULE_OS_IOEVENTFLAGS_SYSSYNC
-
-/**
- * @brief   Event flags for DN signal events.
- */
-#define MODULE_SSSP_EVENTFLAGS_DN               MODULE_OS_IOEVENTFLAGS_SYSUARTDN
-
-/** @} */
-
-#endif
-
-/*===========================================================================*/
-/**
- * @name Low-level drivers
- * @{
- */
-/*===========================================================================*/
-#include <alld_at24c01bn-sh-b.h>
-#include <alld_tlc5947.h>
-#include <alld_tps2051bdbv.h>
-#include <alld_dw1000.h>
-
-/**
- * @brief   EEPROM driver.
- */
-extern AT24C01BNDriver moduleLldEeprom;
-
-/**
- * @brief   LED PWM driver.
- */
-extern TLC5947Driver moduleLldLedPwm;
-
-/**
- * @brief   Power switch driver for the laser supply power.
- */
-extern TPS2051BDriver moduleLldPowerSwitchLaser;
-
-/**
- * @brief   DW1000 driver for UWB.
- */
-extern DW1000Driver moduleLldDW1000;
-
-
-
-
-/*! ------------------------------------------------------------------------------------------------------------------
- * Function: _alld_dw1000_callback()
- *
- * Low level abstract function to handle 'reset' adn 'irq' interrupt from DW1000
- * Expects arg to be of iopadid_t* type, used to distinguish between irq or reset signal
- */
-static void _alld_dw1000_callback(void* args) {
-
-    aosDbgCheck(true);
-
-
-    chSysLockFromISR();
-    if ((*(iopadid_t*) args) == moduleLldDW1000.gpio_reset->pad)
-    {
-        // dw1000 external indicate reset done
-    }
-    else if ((*(iopadid_t*) args) == moduleLldDW1000.gpio_exti->pad)
-    {
-        dwt_isr();
-    }
-    else
-    {
-        return;
-    }
-    chSysUnlockFromISR();
-
-}
-
-
-/** @} */
-
-/*===========================================================================*/
-/**
- * @name Unit tests (UT)
- * @{
- */
-/*===========================================================================*/
-#if (AMIROOS_CFG_TESTS_ENABLE == true) || defined(__DOXYGEN__)
-#include <ut_alld_at24c01bn-sh-b.h>
-#include <ut_alld_tlc5947.h>
-#include <ut_alld_tps2051bdbv.h>
-#include <ut_alld_dw1000.h>
-
-/**
- * @brief   EEPROM unit test object.
- */
-extern aos_unittest_t moduleUtAlldAt24c01bn;
-
-/**
- * @brief   LED PWM driver unit test object.
- */
-extern aos_unittest_t moduleUtAlldTlc5947;
-
-/**
- * @brief   Current-limited power switch (Laser output)
- */
-extern aos_unittest_t moduleUtAlldTps2051bdbv;
-
-/**
- * @brief   DW1000 unit test object.
- */
-extern aos_unittest_t moduleUtAlldDw1000;
-
-
-#endif /* AMIROOS_CFG_TESTS_ENABLE == true */
-
-/** @} */
-
-#endif /* _AMIROOS_MODULE_H_ */
diff --git a/unittests/periphery-lld/src/ut_alld_a3906.c b/unittests/periphery-lld/src/ut_alld_a3906.c
index 4e4dd29..e61f742 100644
--- a/unittests/periphery-lld/src/ut_alld_a3906.c
+++ b/unittests/periphery-lld/src/ut_alld_a3906.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_at24c01bn-sh-b.c b/unittests/periphery-lld/src/ut_alld_at24c01bn-sh-b.c
index a841ba0..d483867 100644
--- a/unittests/periphery-lld/src/ut_alld_at24c01bn-sh-b.c
+++ b/unittests/periphery-lld/src/ut_alld_at24c01bn-sh-b.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_bq24103a.c b/unittests/periphery-lld/src/ut_alld_bq24103a.c
index 42a5ba0..e5d8708 100644
--- a/unittests/periphery-lld/src/ut_alld_bq24103a.c
+++ b/unittests/periphery-lld/src/ut_alld_bq24103a.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_bq27500.c b/unittests/periphery-lld/src/ut_alld_bq27500.c
index d18282a..1d40c68 100644
--- a/unittests/periphery-lld/src/ut_alld_bq27500.c
+++ b/unittests/periphery-lld/src/ut_alld_bq27500.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_bq27500_bq24103a.c b/unittests/periphery-lld/src/ut_alld_bq27500_bq24103a.c
index f5dbfde..f304c49 100644
--- a/unittests/periphery-lld/src/ut_alld_bq27500_bq24103a.c
+++ b/unittests/periphery-lld/src/ut_alld_bq27500_bq24103a.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_dw1000.c b/unittests/periphery-lld/src/ut_alld_dw1000.c
index f17071b..a0c977b 100755
--- a/unittests/periphery-lld/src/ut_alld_dw1000.c
+++ b/unittests/periphery-lld/src/ut_alld_dw1000.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_hmc5883l.c b/unittests/periphery-lld/src/ut_alld_hmc5883l.c
index eb4b7ca..f3e1332 100644
--- a/unittests/periphery-lld/src/ut_alld_hmc5883l.c
+++ b/unittests/periphery-lld/src/ut_alld_hmc5883l.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_ina219.c b/unittests/periphery-lld/src/ut_alld_ina219.c
index 06d0470..0d12e86 100644
--- a/unittests/periphery-lld/src/ut_alld_ina219.c
+++ b/unittests/periphery-lld/src/ut_alld_ina219.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_l3g4200d.c b/unittests/periphery-lld/src/ut_alld_l3g4200d.c
index bbca210..9fcef91 100644
--- a/unittests/periphery-lld/src/ut_alld_l3g4200d.c
+++ b/unittests/periphery-lld/src/ut_alld_l3g4200d.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_led.c b/unittests/periphery-lld/src/ut_alld_led.c
index 53ac634..2b71eee 100644
--- a/unittests/periphery-lld/src/ut_alld_led.c
+++ b/unittests/periphery-lld/src/ut_alld_led.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_lis331dlh.c b/unittests/periphery-lld/src/ut_alld_lis331dlh.c
index 56378fa..9d159f7 100644
--- a/unittests/periphery-lld/src/ut_alld_lis331dlh.c
+++ b/unittests/periphery-lld/src/ut_alld_lis331dlh.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_ltc4412.c b/unittests/periphery-lld/src/ut_alld_ltc4412.c
index 40ee37f..be48f56 100644
--- a/unittests/periphery-lld/src/ut_alld_ltc4412.c
+++ b/unittests/periphery-lld/src/ut_alld_ltc4412.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_mpr121.c b/unittests/periphery-lld/src/ut_alld_mpr121.c
index 2e5e30f..895b413 100644
--- a/unittests/periphery-lld/src/ut_alld_mpr121.c
+++ b/unittests/periphery-lld/src/ut_alld_mpr121.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_pca9544a.c b/unittests/periphery-lld/src/ut_alld_pca9544a.c
index 827f557..ecadcb5 100644
--- a/unittests/periphery-lld/src/ut_alld_pca9544a.c
+++ b/unittests/periphery-lld/src/ut_alld_pca9544a.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_pklcs1212e4001.c b/unittests/periphery-lld/src/ut_alld_pklcs1212e4001.c
index 33d2a6a..09f6c0c 100644
--- a/unittests/periphery-lld/src/ut_alld_pklcs1212e4001.c
+++ b/unittests/periphery-lld/src/ut_alld_pklcs1212e4001.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_tlc5947.c b/unittests/periphery-lld/src/ut_alld_tlc5947.c
index deb93a3..7ba3104 100644
--- a/unittests/periphery-lld/src/ut_alld_tlc5947.c
+++ b/unittests/periphery-lld/src/ut_alld_tlc5947.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_tps2051bdbv.c b/unittests/periphery-lld/src/ut_alld_tps2051bdbv.c
index ca74611..b101cff 100644
--- a/unittests/periphery-lld/src/ut_alld_tps2051bdbv.c
+++ b/unittests/periphery-lld/src/ut_alld_tps2051bdbv.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_tps62113.c b/unittests/periphery-lld/src/ut_alld_tps62113.c
index 403579e..78c33f3 100644
--- a/unittests/periphery-lld/src/ut_alld_tps62113.c
+++ b/unittests/periphery-lld/src/ut_alld_tps62113.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_tps62113_ina219.c b/unittests/periphery-lld/src/ut_alld_tps62113_ina219.c
index 7ce0035..87eab35 100644
--- a/unittests/periphery-lld/src/ut_alld_tps62113_ina219.c
+++ b/unittests/periphery-lld/src/ut_alld_tps62113_ina219.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/periphery-lld/src/ut_alld_vcnl4020.c b/unittests/periphery-lld/src/ut_alld_vcnl4020.c
index fc3c674..68bba29 100644
--- a/unittests/periphery-lld/src/ut_alld_vcnl4020.c
+++ b/unittests/periphery-lld/src/ut_alld_vcnl4020.c
@@ -1,6 +1,6 @@
 /*
 AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/unittests/unittests.mk b/unittests/unittests.mk
index 332aa91..10fe749 100644
--- a/unittests/unittests.mk
+++ b/unittests/unittests.mk
@@ -1,7 +1,7 @@
 ################################################################################
 # AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
 # (AMiRo) platform.                                                            #
-# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
+# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
 #                                                                              #
 # This program is free software: you can redistribute it and/or modify         #
 # it under the terms of the GNU General Public License as published by         #
@@ -31,25 +31,6 @@ UNITTESTSINC = $(UNITTESTS_DIR)lld/inc \
                $(UNITTESTS_DIR)periphery-lld/inc
 
 # C sources
-UNITTESTSCSRC = $(UNITTESTS_DIR)lld/src/ut_lld_adc.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_a3906.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_at24c01bn-sh-b.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_bq24103a.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_bq27500.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_bq27500_bq24103a.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_hmc5883l.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_ina219.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_l3g4200d.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_led.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_lis331dlh.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_ltc4412.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_mpr121.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_pca9544a.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_pklcs1212e4001.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_tlc5947.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_tps2051bdbv.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_tps62113.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_tps62113_ina219.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_vcnl4020.c \
-                $(UNITTESTS_DIR)periphery-lld/src/ut_alld_dw1000.c
+UNITTESTSCSRC = $(wildcard $(UNITTESTS_DIR)lld/src/*.c) \
+                $(wildcard $(UNITTESTS_DIR)periphery-lld/src/*.c)
 
