commit deaaa47ee7b4833794a93ca7a1cee202a255071b
Author: Cung Sang <csang@techfak.uni-bielefeld.de>
Date:   Fri Feb 8 18:39:52 2019 +0100

    Added DW1000 demo app on top of NUCLEO_F103RB example

diff --git a/modules/NUCLEO-F103RB/alldconf.h b/modules/NUCLEO-F103RB/alldconf.h
index b510d59..32f4a89 100644
--- a/modules/NUCLEO-F103RB/alldconf.h
+++ b/modules/NUCLEO-F103RB/alldconf.h
@@ -43,6 +43,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #define AMIROLLD_CFG_TIME_SIZE          32
 
+#define AMIROLLD_CFG_DW1000              1
+
 #endif /* ALLDCONF_H */
 
 /** @} */
diff --git a/modules/NUCLEO-F103RB/aosconf.h b/modules/NUCLEO-F103RB/aosconf.h
index d4fadc9..fd4dbe8 100644
--- a/modules/NUCLEO-F103RB/aosconf.h
+++ b/modules/NUCLEO-F103RB/aosconf.h
@@ -84,7 +84,7 @@ 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    MODULE_OS_IOEVENTFLAGS_USERBUTTON
+  #define AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK    (MODULE_OS_IOEVENTFLAGS_DW1000_IRQn | MODULE_OS_IOEVENTFLAGS_USERBUTTON)
 #else
   #define AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK    OS_CFG_MAIN_LOOP_IOEVENT_MASK
 #endif
diff --git a/modules/NUCLEO-F103RB/halconf.h b/modules/NUCLEO-F103RB/halconf.h
index 9467fea..07dbcac 100644
--- a/modules/NUCLEO-F103RB/halconf.h
+++ b/modules/NUCLEO-F103RB/halconf.h
@@ -172,7 +172,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  * @brief   Enables the SPI subsystem.
  */
 #if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
-#define HAL_USE_SPI                         FALSE
+#define HAL_USE_SPI                         TRUE   
 #endif
 
 /**
diff --git a/modules/NUCLEO-F103RB/mcuconf.h b/modules/NUCLEO-F103RB/mcuconf.h
index 4656812..807a139 100644
--- a/modules/NUCLEO-F103RB/mcuconf.h
+++ b/modules/NUCLEO-F103RB/mcuconf.h
@@ -168,7 +168,7 @@
  * SPI driver system settings.
  */
 #define STM32_SPI_USE_SPI1                  FALSE
-#define STM32_SPI_USE_SPI2                  FALSE
+#define STM32_SPI_USE_SPI2                  TRUE
 #define STM32_SPI_USE_SPI3                  FALSE
 #define STM32_SPI_SPI1_DMA_PRIORITY         1
 #define STM32_SPI_SPI2_DMA_PRIORITY         1
diff --git a/modules/NUCLEO-F103RB/module.c b/modules/NUCLEO-F103RB/module.c
index 11c5683..a60099c 100644
--- a/modules/NUCLEO-F103RB/module.c
+++ b/modules/NUCLEO-F103RB/module.c
@@ -49,6 +49,29 @@ SerialConfig moduleHalProgIfConfig = {
   /* CR1      */ 0,
 };
 
+#ifdef AMIROLLD_CFG_DW1000
+
+/*! SPI (high and low speed) configuration for DW1000 */
+SPIConfig moduleHalSpiUwbHsConfig = {
+  /* circular buffer mode        */ false,
+  /* callback function pointer   */ NULL,
+  /* chip select line port       */ GPIOB,
+  /* chip select line pad number */ GPIOB_PIN12,
+  /* CR1                         */ 0,
+  /* CR2                         */ 0,
+};
+
+SPIConfig moduleHalSpiUwbLsConfig = {
+  /* circular buffer mode        */ false,
+  /* callback function pointer   */ NULL,
+  /* chip select line port       */ GPIOB,
+  /* chip select line pad number */ GPIOB_PIN12,
+  /* CR1                         */ SPI_CR1_BR_1 | SPI_CR1_BR_0,
+  /* CR2                         */ 0,
+};
+
+#endif
+
 /** @} */
 
 /*===========================================================================*/
@@ -74,6 +97,60 @@ ROMCONST apalControlGpio_t moduleGpioLed = {
   },
 };
 
+#ifdef AMIROLLD_CFG_DW1000
+
+/**
+ * @brief   DW1000 reset output signal GPIO.
+ */
+static apalGpio_t _gpioDw1000Reset = {
+  /* port */ GPIOA,
+  /* pad  */ GPIOA_ARD_A0,   // PIN0
+};
+ROMCONST apalControlGpio_t moduleGpioDw1000Reset = {
+  /* GPIO */ &_gpioDw1000Reset,
+  /* meta */ {
+    /* direction      */ APAL_GPIO_DIRECTION_BIDIRECTIONAL,
+    /* active state   */ APAL_GPIO_ACTIVE_HIGH,
+    /* interrupt edge */ APAL_GPIO_EDGE_NONE,
+  },
+};
+
+
+/**
+ * @brief   DW1000 interrrupt input signal GPIO.
+ */
+static apalGpio_t _gpioDw1000Irqn = {
+  /* port */ GPIOB,
+  /* pad  */ GPIOB_ARD_D6,  // GPIOB_PIN10
+};
+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 SPI chip select output signal GPIO.
+ */
+static apalGpio_t _gpioSpiChipSelect = {
+  /* port */ GPIOB,
+  /* pad  */ GPIOB_PIN12,  // GPIOB_PIN10
+};
+ROMCONST apalControlGpio_t moduleGpioSpiChipSelect = {
+  /* GPIO */ &_gpioSpiChipSelect,
+  /* meta */ {
+    /* direction      */ APAL_GPIO_DIRECTION_OUTPUT,
+    /* active state   */ APAL_GPIO_ACTIVE_LOW,
+    /* interrupt edge */ APAL_GPIO_EDGE_NONE,
+  },
+};
+
+#endif /* AMIROLLD_CFG_DW1000 */
+
 /**
  * @brief   User button input signal GPIO.
  */
@@ -112,6 +189,45 @@ ROMCONST char* moduleShellPrompt = "NUCLEO-F103RB";
  */
 /*===========================================================================*/
 
+
+/*===========================================================================*/
+/**
+ * @name Hardware specific wrappers Functions
+ * @{
+ */
+/*===========================================================================*/
+
+#ifdef AMIROLLD_CFG_DW1000
+
+/*! @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 TODO: Manual implementation of SPI configuration. Somehow, it is necessary in NUCLEO-F103RB  */
+void dw1000_spi_init(void){
+  palSetPadMode(GPIOB, GPIOB_PIN13, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
+  palSetPadMode(GPIOB, GPIOB_PIN14, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
+  palSetPadMode(GPIOB, GPIOB_PIN15, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
+  palSetPadMode(moduleGpioSpiChipSelect.gpio->port, moduleGpioSpiChipSelect.gpio->pad, PAL_MODE_OUTPUT_PUSHPULL);
+  apalGpioWrite(moduleGpioSpiChipSelect.gpio, APAL_GPIO_LOW);
+}
+
+#endif /* AMIROLLD_CFG_DW1000 */
 /** @} */
 
 /*===========================================================================*/
@@ -121,6 +237,15 @@ ROMCONST char* moduleShellPrompt = "NUCLEO-F103RB";
  */
 /*===========================================================================*/
 
+#ifdef AMIROLLD_CFG_DW1000
+
+DW1000Driver moduleLldDw1000 = {
+  /* SPI driver         */ &MODULE_HAL_SPI_UWB,
+  /* ext interrupt      */ &moduleGpioDw1000Irqn,
+  /* RESET DW1000       */ &moduleGpioDw1000Reset,
+};
+
+#endif /* AMIROLLD_CFG_DW1000 */
 /** @} */
 
 /*===========================================================================*/
@@ -131,6 +256,31 @@ ROMCONST char* moduleShellPrompt = "NUCLEO-F103RB";
 /*===========================================================================*/
 #if (AMIROOS_CFG_TESTS_ENABLE == true) || defined(__DOXYGEN__)
 
+#ifdef AMIROLLD_CFG_DW1000
+
+/*
+ * UwB Driver (DW1000)
+ */
+static int _utShellCmdCb_Dw1000(BaseSequentialStream* stream, int argc, char* argv[])
+{
+  (void)argc;
+  (void)argv;
+  aosUtRun(stream, &moduleUtAlldDw1000, NULL);
+  return AOS_OK;
+}
+aos_unittest_t moduleUtAlldDw1000 = {
+  /* info           */ "DW1000",
+  /* name           */ "UWB System",
+  /* test function  */ utAlldDw1000Func,
+  /* shell command  */ {
+    /* name     */ "unittest:Uwb",
+    /* callback */ _utShellCmdCb_Dw1000,
+    /* next     */ NULL,
+  },
+  /* data           */ &moduleLldDw1000,
+};
+#endif /* AMIROLLD_CFG_DW1000 */
+
 #endif /* AMIROOS_CFG_TESTS_ENABLE == true */
 
 /** @} */
diff --git a/modules/NUCLEO-F103RB/module.h b/modules/NUCLEO-F103RB/module.h
index 4a69559..cdce702 100644
--- a/modules/NUCLEO-F103RB/module.h
+++ b/modules/NUCLEO-F103RB/module.h
@@ -36,6 +36,26 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 /*===========================================================================*/
 
+#ifdef AMIROLLD_CFG_DW1000
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+apalGpioState_t port_CheckEXT_IRQ(void) ;
+
+void dw1000_spi_init(void);
+
+void process_deca_irq(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AMIROLLD_CFG_DW1000 */
+
+
 /** @} */
 
 /*===========================================================================*/
@@ -60,8 +80,30 @@ extern SerialConfig moduleHalProgIfConfig;
  */
 #define MODULE_HAL_RTC                          RTCD1
 
+
+#ifdef AMIROLLD_CFG_DW1000
+
+/**
+ * @brief   SPI interface driver for the motion sensors (gyroscope and accelerometer).
+ */
+#define MODULE_HAL_SPI_UWB                      SPID2
+
+
+/**
+ * @brief   Configuration for the SPI interface driver to communicate with the LED driver.
+ */
+extern SPIConfig moduleHalSpiUwbHsConfig;
+
+/**
+ * @brief   Configuration for the SPI interface driver to communicate with the wireless transceiver.
+ */
+extern SPIConfig moduleHalSpiUwbLsConfig;
+
+#endif /* AMIROLLD_CFG_DW1000 */
+
 /** @} */
 
+
 /*===========================================================================*/
 /**
  * @name GPIO definitions
@@ -74,6 +116,27 @@ extern SerialConfig moduleHalProgIfConfig;
  */
 extern ROMCONST apalControlGpio_t moduleGpioLed;
 
+#ifdef AMIROLLD_CFG_DW1000
+/**
+ * @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 interrupt IRQn input signal.
+ */
+extern ROMCONST apalControlGpio_t moduleGpioDw1000Irqn;
+
+/**
+ * @brief   DW1000 SPI chip select  output signal.
+ */
+extern ROMCONST apalControlGpio_t moduleGpioSpiChipSelect ;
+
+#endif /* AMIROLLD_CFG_DW1000 */
+
 /**
  * @brief   User button input signal.
  */
@@ -89,10 +152,16 @@ extern ROMCONST apalControlGpio_t moduleGpioUserButton;
 /*===========================================================================*/
 
 /**
+ * @brief   Event flag to be call dwt_isr() interrupt.
+ */
+#define MODULE_OS_IOEVENTFLAGS_DW1000_IRQn      AOS_IOEVENT_FLAG(GPIOB_ARD_D6)
+
+/**
  * @brief   Event flag to be set on a USER_BUTTON interrupt.
  */
 #define MODULE_OS_IOEVENTFLAGS_USERBUTTON       AOS_IOEVENT_FLAG(GPIOC_BUTTON)
 
+
 #if (AMIROOS_CFG_SHELL_ENABLE == true) || (AMIROOS_CFG_TESTS_ENABLE == true) || defined(__DOXYGEN__)
 /**
  * @brief   Shell prompt text.
@@ -100,6 +169,7 @@ extern ROMCONST apalControlGpio_t moduleGpioUserButton;
 extern ROMCONST char* moduleShellPrompt;
 #endif
 
+
 /**
  * @brief   Interrupt initialization macro.
  * @note    SSSP related interrupt signals are already initialized in 'aos_system.c'.
@@ -108,14 +178,35 @@ extern ROMCONST char* moduleShellPrompt;
   /* user button */                                                           \
   palSetPadCallback(moduleGpioUserButton.gpio->port, moduleGpioUserButton.gpio->pad, _intCallback, &moduleGpioUserButton.gpio->pad);  \
   palEnablePadEvent(moduleGpioUserButton.gpio->port, moduleGpioUserButton.gpio->pad, APAL2CH_EDGE(moduleGpioUserButton.meta.edge));   \
+  MODULE_INIT_INTERRUPTS_DW1000();                                            \
 }
+#ifdef AMIROLLD_CFG_DW1000
+  #define MODULE_INIT_INTERRUPTS_DW1000() {                                   \
+    palSetPadCallback(moduleGpioDw1000Irqn.gpio->port, moduleGpioDw1000Irqn.gpio->pad, _intCallback, &moduleGpioDw1000Irqn.gpio->pad);  \
+    palEnablePadEvent(moduleGpioDw1000Irqn.gpio->port, moduleGpioDw1000Irqn.gpio->pad, APAL2CH_EDGE(moduleGpioDw1000Irqn.meta.edge));   \
+  }
+#else
+  #define MODULE_INIT_INTERRUPTS_DW1000() {                                  \
+  }
+#endif /* AMIROLLD_CFG_DW1000 */
+
 
 /**
  * @brief   Unit test initialization hook.
  */
 #define MODULE_INIT_TESTS() {                                                 \
   /* add unit-test shell commands */                                          \
+  MODULE_INIT_TESTS_DW1000();                                                 \
 }
+#ifdef AMIROLLD_CFG_DW1000
+  #define MODULE_INIT_TESTS_DW1000() {                                        \
+    aosShellAddCommand(&aos.shell, &moduleUtAlldDw1000.shellcmd);             \
+  }
+#else
+  #define MODULE_INIT_TESTS_DW1000() {                                         \
+  }
+#endif /* AMIROLLD_CFG_DW1000 */
+
 
 /**
  * @brief   Periphery communication interfaces initialization hook.
@@ -123,24 +214,58 @@ extern ROMCONST char* moduleShellPrompt;
 #define MODULE_INIT_PERIPHERY_COMM() {                                        \
   /* serial driver */                                                         \
   sdStart(&MODULE_HAL_PROGIF, &moduleHalProgIfConfig);                        \
+  MODULE_INIT_PERIPHERY_COMM_DW1000();                                        \
 }
+#ifdef AMIROLLD_CFG_DW1000
+  #define MODULE_INIT_PERIPHERY_COMM_DW1000() {                               \
+    /* SPI init */                                                            \
+    dw1000_spi_init();                                                        \
+    spiStart(&MODULE_HAL_SPI_UWB, &moduleHalSpiUwbLsConfig);                  \
+  }
+#else
+  #define MODULE_INIT_PERIPHERY_COMM_DW1000() {                               \
+  }
+#endif /* AMIROLLD_CFG_DW1000 */
+
 
 /**
  * @brief   Periphery communication interface deinitialization hook.
  */
 #define MODULE_SHUTDOWN_PERIPHERY_COMM() {                                    \
+  MODULE_SHUTDOWN_PERIPHERY_COMM_DW1000();                                    \
+}
+#ifdef AMIROLLD_CFG_DW1000
+#define MODULE_SHUTDOWN_PERIPHERY_COMM_DW1000() {                             \
+  /* SPI */                                                                   \
+  spiStop(&MODULE_HAL_SPI_UWB);                                               \
 }
+#else
+  #define MODULE_SHUTDOWN_PERIPHERY_COMM_DW1000() {                           \
+  }
+#endif /* AMIROLLD_CFG_DW1000 */
 
 /**
- * @brief   HOOK to toggle the LEDs when the user button is pressed.
+ * @brief   HOOK to call process_deca_irq() func when the dw1000 interrupt pin is activated.
  */
-#define MODULE_MAIN_LOOP_IO_EVENT(eventflags) {                               \
+#define MODULE_MAIN_LOOP_IO_EVENT(eventflags) {		                          \
   if (eventflags & MODULE_OS_IOEVENTFLAGS_USERBUTTON) {                       \
     apalControlGpioState_t buttonstate;                                       \
     apalControlGpioGet(&moduleGpioUserButton, &buttonstate);                  \
     apalControlGpioSet(&moduleGpioLed, buttonstate);                          \
   }                                                                           \
+  MODULE_MAIN_LOOP_IO_EVENT_DW1000();                                         \
 }
+#ifdef AMIROLLD_CFG_DW1000
+  #define MODULE_MAIN_LOOP_IO_EVENT_DW1000() {                                \
+    if(eventflags & MODULE_OS_IOEVENTFLAGS_DW1000_IRQn) {		              \
+      /*apalGpioToggle(moduleGpioLedGreen.gpio); // just for debug  */        \
+      process_deca_irq();                                                     \
+    }	                                                                      \
+  }
+#else
+  #define MODULE_MAIN_LOOP_IO_EVENT_DW1000() {                                \
+  }
+#endif  /* AMIROLLD_CFG_DW1000 */
 
 /** @} */
 
@@ -159,6 +284,12 @@ extern ROMCONST char* moduleShellPrompt;
  * @{
  */
 /*===========================================================================*/
+#ifdef AMIROLLD_CFG_DW1000
+#include <alld_DW1000.h>
+
+extern DW1000Driver moduleLldDw1000;
+
+#endif /* AMIROLLD_CFG_DW1000 */
 
 /** @} */
 
@@ -170,6 +301,16 @@ extern ROMCONST char* moduleShellPrompt;
 /*===========================================================================*/
 #if (AMIROOS_CFG_TESTS_ENABLE == true) || defined(__DOXYGEN__)
 
+#if defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1)
+#include<ut_alld_dw1000_v1.h>
+
+/**
+ * @brief   DW1000 unit test object.
+ */
+extern aos_unittest_t moduleUtAlldDw1000;
+
+#endif /* defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1) */
+
 #endif /* AMIROOS_CFG_TESTS_ENABLE == true */
 
 /** @} */
