commit 0b989911121411d561b0127517f258468aa2e528
Author: Cung Sang <csang@techfak.uni-bielefeld.de>
Date:   Fri Aug 9 12:55:10 2019 +0200

    added DW1000 test and demo on top of Light Ring module

diff --git a/modules/LightRing_1-2/Makefile b/modules/LightRing_1-2/Makefile
index 0d50ddd..08d8b9e 100644
--- a/modules/LightRing_1-2/Makefile
+++ b/modules/LightRing_1-2/Makefile
@@ -145,14 +145,16 @@ AMIROOS_PERIPHERYLLD_INC += $(AMIROLLD)/drivers/AT24C01B/v1 \
                             $(AMIROLLD)/drivers/INA219/v1 \
                             $(AMIROLLD)/drivers/LED/v1 \
                             $(AMIROLLD)/drivers/MIC9404x/v1 \
-                            $(AMIROLLD)/drivers/TLC5947/v1
+                            $(AMIROLLD)/drivers/TLC5947/v1 \
+			    $(AMIROLLD)/drivers/DW1000/v1
 
 # Tests.
 AMIROOS_TEST_INC += $(AMIROOS_TEST_DIR)periphery-lld/AT24C01B_v1 \
                     $(AMIROOS_TEST_DIR)periphery-lld/INA219_v1 \
                     $(AMIROOS_TEST_DIR)periphery-lld/LED_v1 \
                     $(AMIROOS_TEST_DIR)periphery-lld/MIC9404x_v1 \
-                    $(AMIROOS_TEST_DIR)periphery-lld/TLC5947_v1
+                    $(AMIROOS_TEST_DIR)periphery-lld/TLC5947_v1 \
+		    $(AMIROOS_TEST_DIR)periphery-lld/DW1000_v1
 
 # Module specific inclusion directories
 MODULE_INC = $(MODULEDIR) \
diff --git a/modules/LightRing_1-2/aosconf.h b/modules/LightRing_1-2/aosconf.h
index 1ff1159..4345d33 100644
--- a/modules/LightRing_1-2/aosconf.h
+++ b/modules/LightRing_1-2/aosconf.h
@@ -84,7 +84,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  * @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
+//  #define AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK    0
+  #define AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK      MODULE_OS_IOEVENTFLAGS_DW1000
 #else /* !defined(OS_CFG_MAIN_LOOP_IOEVENT_MASK) */
   #define AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK    OS_CFG_MAIN_LOOP_IOEVENT_MASK
 #endif /* !defined(OS_CFG_MAIN_LOOP_IOEVENT_MASK) */
diff --git a/modules/LightRing_1-2/board.h b/modules/LightRing_1-2/board.h
index e9dad05..67ef256 100644
--- a/modules/LightRing_1-2/board.h
+++ b/modules/LightRing_1-2/board.h
@@ -61,6 +61,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define STM32F103xE
 
 /*
+ * Identifiers for optional peripherals.
+ */
+#define BOARD_DW1000_CONNECTED      false
+#define BOARD_MIC9404x_CONNECTED    true /* Power supply for DW1000 in Light ring */
+
+/*
  * IO pins assignments.
  */
 #define GPIOA_USART_CTS             0U
diff --git a/modules/LightRing_1-2/module.c b/modules/LightRing_1-2/module.c
index 7288abd..801e533 100644
--- a/modules/LightRing_1-2/module.c
+++ b/modules/LightRing_1-2/module.c
@@ -69,6 +69,29 @@ SPIConfig moduleHalSpiLightConfig = {
   /* CR2                         */ SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN,
 };
 
+#if (BOARD_DW1000_CONNECTED == true)
+
+/*! SPI (high speed) configuration for DW1000 */
+SPIConfig moduleHalSpiUwbHsConfig = {
+  /* circular buffer mode        */ false,
+  /* callback function pointer   */ NULL,
+  /* chip select line port       */ PAL_PORT(LINE_SPI_SS_N),
+  /* chip select line pad number */ PAL_PAD(LINE_SPI_SS_N),
+  /* CR1                         */ 0,                                  // 36/2 Mbps
+  /* CR2                         */ SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN,  // 0
+};
+/*! SPI (low speed) configuration for DW1000 */
+SPIConfig moduleHalSpiUwbLsConfig = {
+  /* circular buffer mode        */ false,
+  /* callback function pointer   */ NULL,
+  /* chip select line port       */ PAL_PORT(LINE_SPI_SS_N),
+  /* chip select line pad number */ PAL_PAD(LINE_SPI_SS_N),
+  /* CR1                         */ SPI_CR1_BR_1 | SPI_CR1_BR_0,        // 36/16 Mbps
+  /* CR2                         */ SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN,  // 0
+};
+
+#endif /* BOARD_DW1000_CONNECTED == true */
+
 
 /*===========================================================================*/
 /**
@@ -213,22 +236,68 @@ ROMCONST apalControlGpio_t moduleGpioSysUartDn = {
   },
 };
 
+#if (BOARD_DW1000_CONNECTED == true)
 /**
- * @brief   IO_7 breakout signal GPIO.
+ * @brief   DW1000 interrrupt input signal GPIO.
  */
-static apalGpio_t _gpioBreakoutIo7 = {
+static apalGpio_t _gpioDw1000Irqn = {
+  /* line */  LINE_IO_8,            // (GPIOB, GPIOB_IO_8),
+};
+ROMCONST apalControlGpio_t moduleGpioDw1000Irqn = {
+  /* GPIO */ &_gpioDw1000Irqn,
+  /* meta */ {
+    /* direction      */ APAL_GPIO_DIRECTION_INPUT,
+    /* active state   */ APAL_GPIO_ACTIVE_LOW,
+    /* interrupt edge */ APAL_GPIO_EDGE_RISING,
+  },
+};
+
+/**
+ * @brief   DW1000 reset output signal GPIO.
+ */
+static apalGpio_t _gpioDw1000Reset = {
   /* line */ LINE_IO_7,
 };
-apalControlGpio_t moduleGpioBreakoutIo7 = {
-  /* GPIO */ &_gpioBreakoutIo7,
+ROMCONST apalControlGpio_t moduleGpioDw1000Reset = {
+  /* GPIO */ &_gpioDw1000Reset,
   /* meta */ {
-    /* direction      */ APAL_GPIO_DIRECTION_UNDEFINED,
+    /* direction      */ APAL_GPIO_DIRECTION_BIDIRECTIONAL,
     /* active state   */ APAL_GPIO_ACTIVE_LOW,
     /* interrupt edge */ APAL_GPIO_EDGE_NONE,
   },
 };
 
 /**
+ * @brief   IO_2 breakout signal GPIO.
+ */
+static apalGpio_t _gpioDw1000WakeUp = {
+  /* line */ LINE_IO_2,
+};
+ROMCONST apalControlGpio_t moduleGpioDw1000WakeUp = {
+  /* GPIO */ &_gpioDw1000WakeUp,
+  /* meta */ {
+    /* direction      */ APAL_GPIO_DIRECTION_OUTPUT,
+    /* active state   */ APAL_GPIO_ACTIVE_HIGH,
+    /* interrupt edge */ APAL_GPIO_EDGE_NONE,
+  },
+};
+
+/**
+ * @brief   DW1000 SPI chip select output signal GPIO.
+ */
+static apalGpio_t _gpioSpiChipSelect = {
+  /* line */ LINE_SPI_SS_N,
+};
+ROMCONST apalControlGpio_t moduleGpioSpiChipSelect = {
+  /* GPIO */ &_gpioSpiChipSelect,
+  /* meta */ {
+    /* direction      */ APAL_GPIO_DIRECTION_OUTPUT,
+    /* active state   */ APAL_GPIO_ACTIVE_LOW,
+    /* interrupt edge */ APAL_GPIO_EDGE_NONE,
+  },
+};
+#else
+/**
  * @brief   IO_8 breakout signal GPIO.
  */
 static apalGpio_t _gpioBreakoutIo8 = {
@@ -244,6 +313,38 @@ apalControlGpio_t moduleGpioBreakoutIo8 = {
 };
 
 /**
+ * @brief   IO_7 breakout signal GPIO.
+ */
+static apalGpio_t _gpioBreakoutIo7 = {
+  /* line */ LINE_IO_7,
+};
+apalControlGpio_t moduleGpioBreakoutIo7 = {
+  /* GPIO */ &_gpioBreakoutIo7,
+  /* meta */ {
+    /* direction      */ APAL_GPIO_DIRECTION_UNDEFINED,
+    /* active state   */ APAL_GPIO_ACTIVE_LOW,
+    /* interrupt edge */ APAL_GPIO_EDGE_NONE,
+  },
+};
+
+/**
+ * @brief   IO_2 breakout signal GPIO.
+ */
+static apalGpio_t _gpioBreakoutIo2 = {
+  /* line */ LINE_IO_2,
+};
+apalControlGpio_t moduleGpioBreakoutIo2 = {
+  /* GPIO */ &_gpioBreakoutIo2,
+  /* meta */ {
+    /* direction      */ APAL_GPIO_DIRECTION_UNDEFINED,
+    /* active state   */ APAL_GPIO_ACTIVE_LOW,
+    /* interrupt edge */ APAL_GPIO_EDGE_NONE,
+  },
+};
+#endif  /* BOARD_DW1000_CONNECTED == true */
+
+
+/**
  * @brief   IO_4 breakout signal GPIO.
  */
 static apalGpio_t _gpioBreakoutIo4 = {
@@ -273,20 +374,6 @@ apalControlGpio_t moduleGpioBreakoutIo1 = {
   },
 };
 
-/**
- * @brief   IO_2 breakout signal GPIO.
- */
-static apalGpio_t _gpioBreakoutIo2 = {
-  /* line */ LINE_IO_2,
-};
-apalControlGpio_t moduleGpioBreakoutIo2 = {
-  /* GPIO */ &_gpioBreakoutIo2,
-  /* meta */ {
-    /* direction      */ APAL_GPIO_DIRECTION_UNDEFINED,
-    /* active state   */ APAL_GPIO_ACTIVE_LOW,
-    /* interrupt edge */ APAL_GPIO_EDGE_NONE,
-  },
-};
 
 /**
  * @brief   LED output signal GPIO.
@@ -419,6 +506,72 @@ ROMCONST char* moduleShellPrompt = "LightRing";
 
 /*===========================================================================*/
 /**
+ * @name Hardware specific wrappers Functions
+ * @{
+ */
+/*===========================================================================*/
+
+#if (BOARD_DW1000_CONNECTED == true)
+/*! @brief Manually reset the DW1000 module  */
+void reset_DW1000(void){
+
+  // Set the pin as output
+  palSetLineMode(moduleGpioDw1000Reset.gpio->line, APAL_GPIO_DIRECTION_OUTPUT);
+
+  //drive the RSTn pin low
+  apalGpioWrite(moduleGpioDw1000Reset.gpio, APAL_GPIO_LOW);
+
+  //put the pin back to tri-state ... as input
+//  palSetLineMode(moduleGpioDw1000Reset.gpio->line, APAL_GPIO_DIRECTION_INPUT); // TODO:
+
+  aosThdMSleep(2);
+}
+
+/*! @brief entry point to the IRQn event in DW1000 module
+ *
+ * */
+void process_deca_irq(void){
+  do{
+    dwt_isr();
+   //while IRS line active (ARM can only do edge sensitive interrupts)
+  }while(port_CheckEXT_IRQ() == 1);
+}
+
+/*! @brief Check the current value of GPIO pin and return the value */
+apalGpioState_t port_CheckEXT_IRQ(void) {
+  apalGpioState_t  val;
+  apalGpioRead(moduleGpioDw1000Irqn.gpio, &val);
+  return val;
+}
+
+/*! @brief Manually set the chip select pin of the SPI */
+void set_SPI_chip_select(void){
+  apalGpioWrite(moduleGpioSpiChipSelect.gpio, APAL_GPIO_HIGH);
+}
+
+/*! @brief Manually reset the chip select pin of the SPI */
+void clear_SPI_chip_select(void){
+  apalGpioWrite(moduleGpioSpiChipSelect.gpio, APAL_GPIO_LOW);
+}
+
+/*! @brief Change the SPI speed configuration on the fly */
+void setHighSpeed_SPI(bool speedValue, DW1000Driver* drv){
+
+  spiStop(drv->spid);
+
+  if (speedValue == FALSE){
+    spiStart(drv->spid, &moduleHalSpiUwbLsConfig);  // low speed spi configuration
+  }
+  else{
+    spiStart(drv->spid, &moduleHalSpiUwbHsConfig); // high speed spi configuration
+  }
+}
+#endif /* (BOARD_DW1000_CONNECTED == true) */
+/** @} */
+
+
+/*===========================================================================*/
+/**
  * @name Low-level drivers
  * @{
  */
@@ -469,6 +622,18 @@ TLC5947Driver moduleLldLedPwm = {
   /* XLAT signal GPIO   */ &moduleGpioLightXlat,
 };
 
+#if (BOARD_DW1000_CONNECTED == true)
+DW1000Driver moduleLldDw1000 = {
+  /* SPI driver         */ &MODULE_HAL_SPI_UWB,
+  /* ext interrupt      */ &moduleGpioDw1000Irqn,
+  /* RESET DW1000       */ &moduleGpioDw1000Reset,
+};
+
+MIC9404xDriver moduleLldPowerSwitchDw1000 = {
+  /* power enable GPIO  */ &moduleGpioSwVsysEn,
+};
+#endif /* (BOARD_DW1000_CONNECTED == true) */
+
 /** @} */
 
 /*===========================================================================*/
@@ -531,6 +696,18 @@ static int _testTlc5947ShellCmdCb(BaseSequentialStream* stream, int argc, char*
 }
 AOS_SHELL_COMMAND(moduleTestTlc5947ShellCmd, "test:Lights", _testTlc5947ShellCmdCb);
 
+#if (BOARD_DW1000_CONNECTED == true) || defined(__DOXYGEN__)
+/*
+ * UwB Driver (DW1000)
+ */
+#include <module_test_DW1000.h>
+static int _testDw1000ShellCmdCb(BaseSequentialStream* stream, int argc, char* argv[])
+{
+  return moduleTestDw1000ShellCb(stream, argc, argv, NULL);
+}
+AOS_SHELL_COMMAND(moduleTestDw1000ShellCmd, "test:DW1000", _testDw1000ShellCmdCb);
+#endif /* (BOARD_DW1000_CONNECTED == true) */
+
 /*
  * entire module
  */
diff --git a/modules/LightRing_1-2/module.h b/modules/LightRing_1-2/module.h
index ffb29a4..02431f3 100644
--- a/modules/LightRing_1-2/module.h
+++ b/modules/LightRing_1-2/module.h
@@ -36,6 +36,24 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 /*===========================================================================*/
 
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+#if (BOARD_DW1000_CONNECTED == true)
+void process_deca_irq(void);
+apalGpioState_t port_CheckEXT_IRQ(void) ;
+#endif /* (BOARD_DW1000_CONNECTED == true) */
+
+void set_SPI_chip_select(void);
+void clear_SPI_chip_select(void);
+void reset_DW1000(void);
+
+#if defined(__cplusplus)
+}
+#endif /* defined(__cplusplus) */
+
 /** @} */
 
 /*===========================================================================*/
@@ -85,11 +103,32 @@ extern SerialConfig moduleHalProgIfConfig;
  */
 extern SPIConfig moduleHalSpiLightConfig;
 
+#if (BOARD_DW1000_CONNECTED == true)
+/**
+ * @brief   SPI interface driver for UWB DW1000 module.
+ */
+#define MODULE_HAL_SPI_UWB                      SPID2
+
+/**
+ * @brief   Configuration for the high-speed SPI interface driver of DW1000 module.
+ */
+extern SPIConfig moduleHalSpiUwbHsConfig;
+
+/**
+ * @brief   Configuration for the low-speed SPI interface driver of DW1000 module.
+ */
+extern SPIConfig moduleHalSpiUwbLsConfig;
+
+#else
+
 /**
  * @brief   SPI interface driver for the breakout header.
  */
 #define MODULE_HAL_SPI_BREAKOUT                 SPID2
 
+#endif /* BOARD_DW1000_CONNECTED == true*/
+
+
 /**
  * @brief   UART interface driver for the breakout header (alternative to serial).
  */
@@ -156,16 +195,6 @@ extern apalControlGpio_t moduleGpioBreakoutIo6;
 extern ROMCONST apalControlGpio_t moduleGpioSysUartDn;
 
 /**
- * @brief   IO_7 breakout signal GPIO.
- */
-extern apalControlGpio_t moduleGpioBreakoutIo7;
-
-/**
- * @brief   IO_8 breakout signal GPIO.
- */
-extern apalControlGpio_t moduleGpioBreakoutIo8;
-
-/**
  * @brief   IO_4 breakout signal GPIO.
  */
 extern apalControlGpio_t moduleGpioBreakoutIo4;
@@ -176,11 +205,6 @@ extern apalControlGpio_t moduleGpioBreakoutIo4;
 extern apalControlGpio_t moduleGpioBreakoutIo1;
 
 /**
- * @brief   IO_2 breakout signal GPIO.
- */
-extern apalControlGpio_t moduleGpioBreakoutIo2;
-
-/**
  * @brief   LED output signal GPIO.
  */
 extern ROMCONST apalControlGpio_t moduleGpioLed;
@@ -215,6 +239,48 @@ extern ROMCONST apalControlGpio_t moduleGpioSysPd;
  */
 extern ROMCONST apalControlGpio_t moduleGpioSysSync;
 
+#if (BOARD_DW1000_CONNECTED == true)
+/**
+ * @brief   DW1000 reset output signal
+ * @note    the reset pin should be drived as low by MCU to activate.
+ *          Then, put back the reset pin as input to MCU (tri-state float on the air
+ *          is not supported in AMiRo)
+ */
+extern ROMCONST apalControlGpio_t moduleGpioDw1000Reset;
+
+/**
+ * @brief   DW1000 wakeup signal
+ */
+extern ROMCONST apalControlGpio_t moduleGpioDw1000WakeUp;
+
+/**
+ * @brief   DW1000 interrupt IRQn input signal.
+ */
+extern ROMCONST apalControlGpio_t moduleGpioDw1000Irqn;
+
+/**
+ * @brief   DW1000 SPI chip select  output signal.
+ */
+extern ROMCONST apalControlGpio_t moduleGpioSpiChipSelect ;
+
+#else
+/**
+ * @brief   IO_2 breakout signal GPIO.
+ */
+extern apalControlGpio_t moduleGpioBreakoutIo2;
+
+/**
+ * @brief   IO_7 breakout signal GPIO.
+ */
+extern apalControlGpio_t moduleGpioBreakoutIo7;
+
+/**
+ * @brief   IO_8 breakout signal GPIO.
+ */
+extern apalControlGpio_t moduleGpioBreakoutIo8;
+
+#endif /* BOARD_DW1000_CONNECTED == true */
+
 /** @} */
 
 /*===========================================================================*/
@@ -275,6 +341,11 @@ extern ROMCONST apalControlGpio_t moduleGpioSysSync;
 #define MODULE_OS_IOEVENTFLAGS_BREAKOUTIO8      AOS_IOEVENT_FLAG(PAL_PAD(LINE_IO_8))
 
 /**
+ * @brief   Event flag to be set on a DW1000 interrupt.
+ */
+#define MODULE_OS_IOEVENTFLAGS_DW1000           AOS_IOEVENT_FLAG(PAL_PAD(LINE_IO_8))
+
+/**
  * @brief   Event flag to be set on a SYS_PD interrupt.
  */
 #define MODULE_OS_IOEVENTFLAGS_SYSPD            AOS_IOEVENT_FLAG(PAL_PAD(LINE_SYS_PD_N))
@@ -292,7 +363,17 @@ extern ROMCONST char* moduleShellPrompt;
  */
 #define MODULE_INIT_INTERRUPTS() {                                            \
   /* breakout interrupts must be enabled explicitely */                       \
+  MODULE_INIT_INTERRUPTS_DW1000();                                            \
 }
+#if (BOARD_DW1000_CONNECTED == true)
+  #define MODULE_INIT_INTERRUPTS_DW1000() {                                   \
+    palSetLineCallback(moduleGpioDw1000Irqn.gpio->line, aosSysGetStdExtiCallback(), &moduleGpioDw1000Irqn.gpio->line);  \
+    palEnableLineEvent(moduleGpioDw1000Irqn.gpio->line, APAL2CH_EDGE(moduleGpioDw1000Irqn.meta.edge));                  \
+  }
+#else /* (BOARD_DW1000_CONNECTED == true) */
+  #define MODULE_INIT_INTERRUPTS_DW1000() {                                   \
+  }
+#endif /* (BOARD_DW1000_CONNECTED == true) */
 
 /**
  * @brief   Unit test initialization hook.
@@ -305,7 +386,16 @@ extern ROMCONST char* moduleShellPrompt;
   aosShellAddCommand(&aos.shell, &moduleTestMic9404xShellCmd);                \
   aosShellAddCommand(&aos.shell, &moduleTestTlc5947ShellCmd);                 \
   aosShellAddCommand(&aos.shell, &moduleTestAllShellCmd);                     \
+  MODULE_INIT_TESTS_DW1000();                                                 \
 }
+#if (BOARD_DW1000_CONNECTED == true)
+  #define MODULE_INIT_TESTS_DW1000() {                                        \
+    aosShellAddCommand(&aos.shell, &moduleTestDw1000ShellCmd);                \
+  }
+#else /* defined(AMIROLLD_CFG_DW1000) */
+  #define MODULE_INIT_TESTS_DW1000() {                                        \
+  }
+#endif /* BOARD_DW1000_CONNECTED == true */
 
 /**
  * @brief   Periphery communication interfaces initialization hook.
@@ -320,7 +410,16 @@ extern ROMCONST char* moduleShellPrompt;
   i2cStart(&MODULE_HAL_I2C_EEPROM_PWRMTR_BREAKOUT, &moduleHalI2cEepromPwrmtrBreakoutConfig);  \
   /* SPI */                                                                   \
   spiStart(&MODULE_HAL_SPI_LIGHT, &moduleHalSpiLightConfig);                  \
+  MODULE_INIT_PERIPHERY_COMM_DW1000();                                        \
 }
+#if (BOARD_DW1000_CONNECTED == true)
+  #define MODULE_INIT_PERIPHERY_COMM_DW1000() {                               \
+  spiStart(&MODULE_HAL_SPI_UWB, &moduleHalSpiUwbLsConfig);                    \
+  }
+#else /* defined(AMIROLLD_CFG_DW1000) */
+  #define MODULE_INIT_PERIPHERY_COMM_DW1000() {                               \
+  }
+#endif /* BOARD_DW1000_CONNECTED == true */
 
 /**
  * @brief   Periphery communication interface deinitialization hook.
@@ -330,8 +429,36 @@ extern ROMCONST char* moduleShellPrompt;
   spiStop(&MODULE_HAL_SPI_LIGHT);                                             \
   /* I2C */                                                                   \
   i2cStop(&MODULE_HAL_I2C_EEPROM_PWRMTR_BREAKOUT);                            \
+  MODULE_SHUTDOWN_PERIPHERY_COMM_DW1000();                                    \
   /* don't stop the serial driver so messages can still be printed */         \
 }
+#if (BOARD_DW1000_CONNECTED == true)
+#define MODULE_SHUTDOWN_PERIPHERY_COMM_DW1000() {                             \
+  /* SPI */                                                                   \
+  spiStop(&MODULE_HAL_SPI_UWB);                                               \
+}
+#else /* defined(AMIROLLD_CFG_DW1000) */
+  #define MODULE_SHUTDOWN_PERIPHERY_COMM_DW1000() {                           \
+  }
+#endif /* BOARD_DW1000_CONNECTED == true */
+
+
+/**
+ * @brief   HOOK to call process_deca_irq() func when the dw1000 interrupt pin is activated.
+ */
+#define MODULE_MAIN_LOOP_IO_EVENT(eventflags) {                               \
+  MODULE_MAIN_LOOP_IO_EVENT_DW1000();                                         \
+}
+#if (BOARD_DW1000_CONNECTED == true)
+  #define MODULE_MAIN_LOOP_IO_EVENT_DW1000() {                                \
+    if(eventflags & MODULE_OS_IOEVENTFLAGS_DW1000) {                          \
+      process_deca_irq();                                                     \
+    }                                                                         \
+  }
+#else /* defined(AMIROLLD_CFG_DW1000) */
+  #define MODULE_MAIN_LOOP_IO_EVENT_DW1000() {                                \
+  }
+#endif /* BOARD_DW1000_CONNECTED == true */
 
 /** @} */
 
@@ -396,6 +523,7 @@ extern ROMCONST char* moduleShellPrompt;
 #include <alld_MIC9404x.h>
 // TODO: add SNx5C3221E
 #include <alld_TLC5947.h>
+#include <alld_DW1000.h>
 
 /**
  * @brief   EEPROM driver.
@@ -445,6 +573,15 @@ extern MIC9404xDriver moduleLldPowerSwitchVsys;
  */
 extern TLC5947Driver moduleLldLedPwm;
 
+/**
+ * @brief   DW1000 driver.
+ */
+void setHighSpeed_SPI(bool speedValue, DW1000Driver* drv);
+#if (BOARD_DW1000_CONNECTED == true)
+extern DW1000Driver moduleLldDw1000;
+extern MIC9404xDriver moduleLldPowerSwitchDw1000;
+#endif /* (BOARD_DW1000_CONNECTED == true) */
+
 /** @} */
 
 /*===========================================================================*/
@@ -487,6 +624,14 @@ extern aos_shellcommand_t moduleTestTlc5947ShellCmd;
  */
 extern aos_shellcommand_t moduleTestAllShellCmd;
 
+
+#if (BOARD_DW1000_CONNECTED == true)
+/**
+ * @brief   DW1000 (UWB transmitter) test command.
+ */
+extern aos_shellcommand_t moduleTestDw1000ShellCmd;
+#endif /* (BOARD_DW1000_CONNECTED == true) */
+
 #endif /* (AMIROOS_CFG_TESTS_ENABLE == true) */
 
 /** @} */
diff --git a/modules/LightRing_1-2/test/DW1000/module_test_DW1000.c b/modules/LightRing_1-2/test/DW1000/module_test_DW1000.c
new file mode 100644
index 0000000..04c78aa
--- /dev/null
+++ b/modules/LightRing_1-2/test/DW1000/module_test_DW1000.c
@@ -0,0 +1,89 @@
+/*
+AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
+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
+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/>.
+*/
+
+#include <amiroos.h>
+
+#if (AMIROOS_CFG_TESTS_ENABLE == true) && (BOARD_DW1000_CONNECTED == true) || defined(__DOXYGEN__)
+
+
+#include <module_test_DW1000.h>
+#include <aos_test_DW1000.h>
+//#include <aos_test_MIC9404x.h>
+#include <module_test_MIC9404x.h>
+
+/******************************************************************************/
+/* LOCAL DEFINITIONS                                                          */
+/******************************************************************************/
+
+/******************************************************************************/
+/* EXPORTED VARIABLES                                                         */
+/******************************************************************************/
+
+/******************************************************************************/
+/* LOCAL TYPES                                                                */
+/******************************************************************************/
+
+/******************************************************************************/
+/* LOCAL VARIABLES                                                            */
+/******************************************************************************/
+
+static aos_test_dw1000data_t _data = {
+  /* UWB data     */ &moduleLldDw1000,
+  /* event source */ &aos.events.io,
+  /* event flags  */ MODULE_OS_IOEVENTFLAGS_DW1000,
+  /* Power supply */ &moduleLldPowerSwitchDw1000,
+};
+
+static AOS_TEST(_test, "DW1000", NULL, moduleTestDw1000ShellCb, aosTestDw1000Func, &_data);
+
+/******************************************************************************/
+/* LOCAL FUNCTIONS                                                            */
+/******************************************************************************/
+
+/******************************************************************************/
+/* EXPORTED FUNCTIONS                                                         */
+/******************************************************************************/
+
+int moduleTestDw1000ShellCb(BaseSequentialStream* stream, int argc, char* argv[], aos_testresult_t* result)
+{
+  (void)argc;
+  (void)argv;
+
+  /* MIC9404x (power switch) */
+  // Enable 1.8V for DW1000 module on Light Ring
+  _data.mic9404xd = &moduleLldPowerSwitchV18;
+  aosTestRun(stream, &_test, "1.8V");
+  _data.mic9404xd = NULL;
+
+  // Enable 3.3V for DW1000 module on Light Ring
+  _data.mic9404xd = &moduleLldPowerSwitchV33;
+  aosTestRun(stream, &_test, "3.3V");
+  _data.mic9404xd = NULL;
+
+
+  /* DW1000 (test) */
+  if (result != NULL) {
+    *result = aosTestRun(stream, &_test, NULL);
+
+  } else {
+    aosTestRun(stream, &_test, NULL);
+  }
+  return AOS_OK;
+}
+
+#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) */
diff --git a/modules/LightRing_1-2/test/DW1000/module_test_DW1000.h b/modules/LightRing_1-2/test/DW1000/module_test_DW1000.h
new file mode 100644
index 0000000..e95878c
--- /dev/null
+++ b/modules/LightRing_1-2/test/DW1000/module_test_DW1000.h
@@ -0,0 +1,66 @@
+/*
+AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
+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
+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 MODULE_TEST_DW1000_H
+#define MODULE_TEST_DW1000_H
+
+#include <amiroos.h>
+
+#if (AMIROOS_CFG_TESTS_ENABLE == true) && (BOARD_DW1000_CONNECTED == true) || defined(__DOXYGEN__)
+
+/******************************************************************************/
+/* CONSTANTS                                                                  */
+/******************************************************************************/
+
+/******************************************************************************/
+/* SETTINGS                                                                   */
+/******************************************************************************/
+
+/******************************************************************************/
+/* CHECKS                                                                     */
+/******************************************************************************/
+
+/******************************************************************************/
+/* DATA STRUCTURES AND TYPES                                                  */
+/******************************************************************************/
+
+/******************************************************************************/
+/* MACROS                                                                     */
+/******************************************************************************/
+
+/******************************************************************************/
+/* EXTERN DECLARATIONS                                                        */
+/******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* defined(__cplusplus) */
+  int moduleTestDw1000ShellCb(BaseSequentialStream* stream, int argc, char* argv[], aos_testresult_t* result);
+#if defined(__cplusplus)
+}
+#endif /* defined(__cplusplus) */
+
+/******************************************************************************/
+/* INLINE FUNCTIONS                                                           */
+/******************************************************************************/
+
+#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) */
+
+#endif /* MODULE_TEST_DW1000_H */
+
