bluenrg_interface

Files at this revision

API Documentation at this revision

Comitter:
Ciesarik3
Date:
Mon Nov 12 18:36:18 2018 +0000
Commit message:
crc;

Changed in this revision

bluenrg_interface.c Show annotated file Show diff for this revision Revisions of this file
cube_hal_f4.c Show annotated file Show diff for this revision Revisions of this file
cube_hal_l0.c Show annotated file Show diff for this revision Revisions of this file
cube_hal_l4.c Show annotated file Show diff for this revision Revisions of this file
main.c Show annotated file Show diff for this revision Revisions of this file
sensor_service.c Show annotated file Show diff for this revision Revisions of this file
stm32f4xx_hal_msp.c Show annotated file Show diff for this revision Revisions of this file
stm32l0xx_hal_msp.c Show annotated file Show diff for this revision Revisions of this file
stm32l4xx_hal_msp.c Show annotated file Show diff for this revision Revisions of this file
stm32xx_it.c Show annotated file Show diff for this revision Revisions of this file
system_stm32f4xx.c Show annotated file Show diff for this revision Revisions of this file
system_stm32l0xx.c Show annotated file Show diff for this revision Revisions of this file
system_stm32l4xx.c Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluenrg_interface.c	Mon Nov 12 18:36:18 2018 +0000
@@ -0,0 +1,58 @@
+/**
+  ******************************************************************************
+  * @file    bluenrg_interface.c
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    04-July-2014
+  * @brief   This file provides code for the BlueNRG Expansion Board driver
+  *          based on STM32Cube HAL for STM32 Nucleo boards.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+/* Includes ------------------------------------------------------------------*/
+#include "bluenrg_interface.h"
+
+#include "debug.h"
+#include "ble_status.h"
+#include "hci.h"
+#include "stm32_bluenrg_ble.h"
+
+extern SPI_HandleTypeDef SpiHandle;
+
+/**
+ * @brief  EXTI line detection callback.
+ * @param  Specifies the pins connected EXTI line
+ * @retval None
+ */
+void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
+{
+  HCI_Isr();
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cube_hal_f4.c	Mon Nov 12 18:36:18 2018 +0000
@@ -0,0 +1,67 @@
+/**
+  ******************************************************************************
+  * @file    cube_hal_f4.c
+  * @author  CL
+  * @version V1.0.0
+  * @date    03-November-2014
+  * @brief   
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+
+/* Includes ------------------------------------------------------------------*/
+#include "cube_hal.h"
+
+/**
+ * @brief  System Clock Configuration
+ * @param  None
+ * @retval None
+ */
+void SystemClock_Config(void)
+{
+  RCC_ClkInitTypeDef RCC_ClkInitStruct;
+  RCC_OscInitTypeDef RCC_OscInitStruct;
+
+  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
+  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
+  RCC_OscInitStruct.HSICalibrationValue = 6;
+  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
+  RCC_OscInitStruct.PLL.PLLM = 16;
+  RCC_OscInitStruct.PLL.PLLN = 256;
+  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV8;
+  RCC_OscInitStruct.PLL.PLLQ = 4;
+  HAL_RCC_OscConfig(&RCC_OscInitStruct);
+
+  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
+  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cube_hal_l0.c	Mon Nov 12 18:36:18 2018 +0000
@@ -0,0 +1,74 @@
+/**
+  ******************************************************************************
+  * @file    cube_hal_l0.c
+  * @author  CL
+  * @version V1.0.0
+  * @date    03-November-2014
+  * @brief   
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+
+/* Includes ------------------------------------------------------------------*/
+#include "cube_hal.h"
+
+/**
+ * @brief  System Clock Configuration
+ * @param  None
+ * @retval None
+ */
+  void SystemClock_Config(void)
+{
+  RCC_ClkInitTypeDef RCC_ClkInitStruct;
+  RCC_OscInitTypeDef RCC_OscInitStruct;
+
+  __PWR_CLK_ENABLE();
+
+  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
+
+  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
+  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
+  RCC_OscInitStruct.HSICalibrationValue = 0x10;
+  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
+  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4;
+  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2;
+  HAL_RCC_OscConfig(&RCC_OscInitStruct);
+
+  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
+  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
+  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
+
+  __SYSCFG_CLK_ENABLE(); 
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cube_hal_l4.c	Mon Nov 12 18:36:18 2018 +0000
@@ -0,0 +1,97 @@
+/**
+  ******************************************************************************
+  * @file    cube_hal_l4.c
+  * @author  CL
+  * @version V1.0.0
+  * @date    13-July-2015
+  * @brief   
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+
+/* Includes ------------------------------------------------------------------*/
+#include "cube_hal.h"
+
+/**
+  * @brief  System Clock Configuration
+  *         The system Clock is configured as follows :
+  *            System Clock source            = PLL (MSI)
+  *            SYSCLK(Hz)                     = 80000000
+  *            HCLK(Hz)                       = 80000000
+  *            AHB Prescaler                  = 1
+  *            APB1 Prescaler                 = 1
+  *            APB2 Prescaler                 = 1
+  *            MSI Frequency(Hz)              = 4000000
+  *            PLL_M                          = 1
+  *            PLL_N                          = 40
+  *            PLL_R                          = 2
+  *            PLL_P                          = 7
+  *            PLL_Q                          = 4
+  *            Flash Latency(WS)              = 4
+  * @param  None
+  * @retval None
+  */
+  void SystemClock_Config(void)
+{
+  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
+  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+
+  /* MSI is enabled after System reset, activate PLL with MSI as source */
+  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
+  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
+  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
+  RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
+  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
+  RCC_OscInitStruct.PLL.PLLM = 1;
+  RCC_OscInitStruct.PLL.PLLN = 40;
+  RCC_OscInitStruct.PLL.PLLR = 2;
+  RCC_OscInitStruct.PLL.PLLP = 7;
+  RCC_OscInitStruct.PLL.PLLQ = 4;
+  if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+  {
+    /* Initialization Error */
+    while(1);
+  }
+  
+  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 
+     clocks dividers */
+  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
+  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;  
+  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;  
+  if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
+  {
+    /* Initialization Error */
+    while(1);
+  } 
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.c	Mon Nov 12 18:36:18 2018 +0000
@@ -0,0 +1,354 @@
+/**
+  ******************************************************************************
+  * @file    main.c 
+  * @author  CL
+  * @version V1.0.0
+  * @date    04-July-2014
+  * @brief   This application contains an example which shows how implementing
+  *          a proprietary Bluetooth Low Energy profile: the sensor profile.
+  *          The communication is done using a Nucleo board and a Smartphone
+  *          with BTLE.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "cube_hal.h"
+
+/* USER CODE BEGIN Includes */
+#include "osal.h"
+#include "sensor_service.h"
+#include "debug.h"
+#include "stm32_bluenrg_ble.h"
+#include "bluenrg_utils.h"
+/* USER CODE END Includes */
+
+/** @addtogroup X-CUBE-BLE1_Applications
+ *  @{
+ */
+
+/** @defgroup SensorDemo
+ *  @{
+ */
+
+/** @defgroup MAIN 
+ * @{
+ */
+
+/* USER CODE BEGIN PV */
+/** @defgroup MAIN_Private_Defines 
+ * @{
+ */
+/* Private defines -----------------------------------------------------------*/
+#define BDADDR_SIZE 6
+/**
+ * @}
+ */
+ 
+/* Private macros ------------------------------------------------------------*/
+
+/** @defgroup MAIN_Private_Variables
+ * @{
+ */
+/* Private variables ---------------------------------------------------------*/
+extern volatile uint8_t set_connectable;
+extern volatile int connected;
+extern AxesRaw_t axes_data;
+uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */
+/**
+ * @}
+ */
+/* USER CODE END PV */
+
+/** @defgroup MAIN_Private_Function_Prototypes
+ * @{
+ */
+/* USER CODE BEGIN PFP */
+/* Private function prototypes -----------------------------------------------*/
+void User_Process(AxesRaw_t* p_axes);
+/* USER CODE END PFP */
+/**
+ * @}
+ */
+
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/**
+ * @brief  Main function to show how to use the BlueNRG Bluetooth Low Energy
+ *         expansion board to send data from a Nucleo board to a smartphone
+ *         with the support BLE and the "BlueNRG" app freely available on both
+ *         GooglePlay and iTunes.
+ *         The URL to the iTunes for the "BlueNRG" app is
+ *         http://itunes.apple.com/app/bluenrg/id705873549?uo=5
+ *         The URL to the GooglePlay is
+ *         https://play.google.com/store/apps/details?id=com.st.bluenrg
+ *         The source code of the "BlueNRG" app, both for iOS and Android, is
+ *         freely downloadable from the developer website at
+ *         http://software.g-maps.it/
+ *         The board will act as Server-Peripheral.
+ *
+ *         After connection has been established:
+ *          - by pressing the USER button on the board, the cube showed by
+ *            the app on the smartphone will rotate.
+ *          
+ *         The communication is done using a vendor specific profile.
+ *
+ * @param  None
+ * @retval None
+ */
+int main(void)
+{
+  /* USER CODE BEGIN 1 */
+  const char *name = "BlueNRG";
+  uint8_t SERVER_BDADDR[] = {0x12, 0x34, 0x00, 0xE1, 0x80, 0x03};
+  uint8_t bdaddr[BDADDR_SIZE];
+  uint16_t service_handle, dev_name_char_handle, appearance_char_handle;
+  
+  uint8_t  hwVersion;
+  uint16_t fwVersion;
+  
+  int ret;  
+  /* USER CODE END 1 */
+  
+  /* STM32Cube HAL library initialization:
+   *  - Configure the Flash prefetch, Flash preread and Buffer caches
+   *  - Systick timer is configured by default as source of time base, but user 
+   *    can eventually implement his proper time base source (a general purpose 
+   *    timer for example or other time source), keeping in mind that Time base 
+   *    duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and 
+   *    handled in milliseconds basis.
+   *  - Low Level Initialization
+   */
+  HAL_Init();
+  
+  /* USER CODE BEGIN Init */
+#if NEW_SERVICES
+  /* Configure LED2 */
+  BSP_LED_Init(LED2); 
+#endif
+  
+  /* Configure the User Button in GPIO Mode */
+  BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_GPIO);
+  /* USER CODE END Init */
+  
+  /* Configure the system clock */
+  SystemClock_Config();
+  
+  /* USER CODE BEGIN SysInit */
+
+  /* USER CODE END SysInit */
+
+  /* Initialize the BlueNRG SPI driver */
+  BNRG_SPI_Init();
+  
+  /* Initialize the BlueNRG HCI */
+  HCI_Init();
+
+  /* Reset BlueNRG hardware */
+  BlueNRG_RST();
+   
+  /* USER CODE BEGIN 2 */
+  /* get the BlueNRG HW and FW versions */
+  getBlueNRGVersion(&hwVersion, &fwVersion);
+
+  /* 
+   * Reset BlueNRG again otherwise we won't
+   * be able to change its MAC address.
+   * aci_hal_write_config_data() must be the first
+   * command after reset otherwise it will fail.
+   */
+  BlueNRG_RST();
+  
+  PRINTF("HWver %d, FWver %d", hwVersion, fwVersion);
+  
+  if (hwVersion > 0x30) { /* X-NUCLEO-IDB05A1 expansion board is used */
+    bnrg_expansion_board = IDB05A1; 
+    /*
+     * Change the MAC address to avoid issues with Android cache:
+     * if different boards have the same MAC address, Android
+     * applications unless you restart Bluetooth on tablet/phone
+     */
+    SERVER_BDADDR[5] = 0x02;
+  }
+
+  /* The Nucleo board must be configured as SERVER */
+  Osal_MemCpy(bdaddr, SERVER_BDADDR, sizeof(SERVER_BDADDR));
+  
+  ret = aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,
+                                  CONFIG_DATA_PUBADDR_LEN,
+                                  bdaddr);
+  if(ret){
+    PRINTF("Setting BD_ADDR failed.\n");
+  }
+  
+  ret = aci_gatt_init();    
+  if(ret){
+    PRINTF("GATT_Init failed.\n");
+  }
+
+  if (bnrg_expansion_board == IDB05A1) {
+    ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle);
+  }
+  else {
+    ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle);
+  }
+
+  if(ret != BLE_STATUS_SUCCESS){
+    PRINTF("GAP_Init failed.\n");
+  }
+
+  ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0,
+                                   strlen(name), (uint8_t *)name);
+
+  if(ret){
+    PRINTF("aci_gatt_update_char_value failed.\n");            
+    while(1);
+  }
+  
+  ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED,
+                                     OOB_AUTH_DATA_ABSENT,
+                                     NULL,
+                                     7,
+                                     16,
+                                     USE_FIXED_PIN_FOR_PAIRING,
+                                     123456,
+                                     BONDING);
+  if (ret == BLE_STATUS_SUCCESS) {
+    PRINTF("BLE Stack Initialized.\n");
+  }
+  
+  PRINTF("SERVER: BLE Stack Initialized\n");
+  
+  ret = Add_Acc_Service();
+  
+  if(ret == BLE_STATUS_SUCCESS)
+    PRINTF("Acc service added successfully.\n");
+  else
+    PRINTF("Error while adding Acc service.\n");
+  
+  ret = Add_Environmental_Sensor_Service();
+  
+  if(ret == BLE_STATUS_SUCCESS)
+    PRINTF("Environmental Sensor service added successfully.\n");
+  else
+    PRINTF("Error while adding Environmental Sensor service.\n");
+
+#if NEW_SERVICES
+  /* Instantiate Timer Service with two characteristics:
+   * - seconds characteristic (Readable only)
+   * - minutes characteristics (Readable and Notifiable )
+   */
+  ret = Add_Time_Service(); 
+  
+  if(ret == BLE_STATUS_SUCCESS)
+    PRINTF("Time service added successfully.\n");
+  else
+    PRINTF("Error while adding Time service.\n");  
+  
+  /* Instantiate LED Button Service with one characteristic:
+   * - LED characteristic (Readable and Writable)
+   */  
+  ret = Add_LED_Service();
+
+  if(ret == BLE_STATUS_SUCCESS)
+    PRINTF("LED service added successfully.\n");
+  else
+    PRINTF("Error while adding LED service.\n");  
+#endif
+
+  /* Set output power level */
+  ret = aci_hal_set_tx_power_level(1,4);
+  /* USER CODE END 2 */
+  
+  /* Infinite loop */
+  /* USER CODE BEGIN WHILE */
+  while(1)
+  {
+  /* USER CODE END WHILE */
+  /* USER CODE BEGIN 3 */
+    HCI_Process();
+    User_Process(&axes_data);
+#if NEW_SERVICES
+    Update_Time_Characteristics();
+#endif
+  }
+  /* USER CODE END 3 */
+  
+}
+
+/* USER CODE BEGIN 4 */
+/**
+ * @brief  Process user input (i.e. pressing the USER button on Nucleo board)
+ *         and send the updated acceleration data to the remote client.
+ *
+ * @param  AxesRaw_t* p_axes
+ * @retval None
+ */
+void User_Process(AxesRaw_t* p_axes)
+{
+  if(set_connectable){
+    setConnectable();
+    set_connectable = FALSE;
+  }  
+
+  /* Check if the user has pushed the button */
+  if(BSP_PB_GetState(BUTTON_KEY) == RESET)
+  {
+    while (BSP_PB_GetState(BUTTON_KEY) == RESET);
+    
+    //BSP_LED_Toggle(LED2); //used for debugging (BSP_LED_Init() above must be also enabled)
+    
+    if(connected)
+    {
+      /* Update acceleration data */
+      p_axes->AXIS_X += 100;
+      p_axes->AXIS_Y += 100;
+      p_axes->AXIS_Z += 100;
+      //PRINTF("ACC: X=%6d Y=%6d Z=%6d\r\n", p_axes->AXIS_X, p_axes->AXIS_Y, p_axes->AXIS_Z);
+      Acc_Update(p_axes);
+    }
+  }
+}
+/* USER CODE END 4 */
+
+/**
+ * @}
+ */
+ 
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensor_service.c	Mon Nov 12 18:36:18 2018 +0000
@@ -0,0 +1,793 @@
+/**
+  ******************************************************************************
+  * @file    sensor_service.c
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    04-July-2014
+  * @brief   Add a sample service using a vendor specific profile.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+#include "sensor_service.h"
+
+/** @addtogroup X-CUBE-BLE1_Applications
+ *  @{
+ */
+
+/** @addtogroup SensorDemo
+ *  @{
+ */
+ 
+/** @defgroup SENSOR_SERVICE
+ * @{
+ */
+
+/** @defgroup SENSOR_SERVICE_Private_Variables
+ * @{
+ */
+/* Private variables ---------------------------------------------------------*/
+volatile int connected = FALSE;
+volatile uint8_t set_connectable = 1;
+volatile uint16_t connection_handle = 0;
+volatile uint8_t notification_enabled = FALSE;
+volatile AxesRaw_t axes_data = {0, 0, 0};
+uint16_t sampleServHandle, TXCharHandle, RXCharHandle;
+uint16_t accServHandle, freeFallCharHandle, accCharHandle;
+uint16_t envSensServHandle, tempCharHandle, pressCharHandle, humidityCharHandle;
+
+#if NEW_SERVICES
+  uint16_t timeServHandle, secondsCharHandle, minuteCharHandle;
+  uint16_t ledServHandle, ledButtonCharHandle;
+  uint8_t ledState = 0;
+  int previousMinuteValue = -1;
+  extern uint8_t bnrg_expansion_board;
+#endif
+/**
+ * @}
+ */
+
+/** @defgroup SENSOR_SERVICE_Private_Macros
+ * @{
+ */
+/* Private macros ------------------------------------------------------------*/
+#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \
+do {\
+    uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \
+        uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \
+            uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \
+                uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \
+}while(0)
+
+#if NEW_SERVICES
+  #define COPY_ACC_SERVICE_UUID(uuid_struct)  COPY_UUID_128(uuid_struct,0x02,0x36,0x6e,0x80, 0xcf,0x3a, 0x11,0xe1, 0x9a,0xb4, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+  #define COPY_FREE_FALL_UUID(uuid_struct)    COPY_UUID_128(uuid_struct,0xe2,0x3e,0x78,0xa0, 0xcf,0x4a, 0x11,0xe1, 0x8f,0xfc, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+  #define COPY_ACC_UUID(uuid_struct)          COPY_UUID_128(uuid_struct,0x34,0x0a,0x1b,0x80, 0xcf,0x4b, 0x11,0xe1, 0xac,0x36, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+
+  #define COPY_ENV_SENS_SERVICE_UUID(uuid_struct)  COPY_UUID_128(uuid_struct,0x42,0x82,0x1a,0x40, 0xe4,0x77, 0x11,0xe2, 0x82,0xd0, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+  #define COPY_TEMP_CHAR_UUID(uuid_struct)         COPY_UUID_128(uuid_struct,0xa3,0x2e,0x55,0x20, 0xe4,0x77, 0x11,0xe2, 0xa9,0xe3, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+  #define COPY_PRESS_CHAR_UUID(uuid_struct)        COPY_UUID_128(uuid_struct,0xcd,0x20,0xc4,0x80, 0xe4,0x8b, 0x11,0xe2, 0x84,0x0b, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+  #define COPY_HUMIDITY_CHAR_UUID(uuid_struct)     COPY_UUID_128(uuid_struct,0x01,0xc5,0x0b,0x60, 0xe4,0x8c, 0x11,0xe2, 0xa0,0x73, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+              
+  // Time service: uuid = 0x08, 0x36, 0x6e, 0x80, 0xcf, 0x3a, 0x11, 0xe1, 0x9a, 0xb4, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b
+  //      straight uuid = 0x08366e80cf3a11e19ab40002a5d5c51b
+  #define COPY_TIME_SERVICE_UUID(uuid_struct)  COPY_UUID_128(uuid_struct,0x08,0x36,0x6e,0x80, 0xcf,0x3a, 0x11,0xe1, 0x9a,0xb4, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+  #define COPY_TIME_UUID(uuid_struct)          COPY_UUID_128(uuid_struct,0x09,0x36,0x6e,0x80, 0xcf,0x3a, 0x11,0xe1, 0x9a,0xb4, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+  #define COPY_MINUTE_UUID(uuid_struct)        COPY_UUID_128(uuid_struct,0x0a,0x36,0x6e,0x80, 0xcf,0x3a, 0x11,0xe1, 0x9a,0xb4, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+
+  // LED service
+  #define COPY_LED_SERVICE_UUID(uuid_struct)  COPY_UUID_128(uuid_struct,0x0b,0x36,0x6e,0x80, 0xcf,0x3a, 0x11,0xe1, 0x9a,0xb4, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+  #define COPY_LED_UUID(uuid_struct)          COPY_UUID_128(uuid_struct,0x0c,0x36,0x6e,0x80, 0xcf,0x3a, 0x11,0xe1, 0x9a,0xb4, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+#else
+  #define COPY_ACC_SERVICE_UUID(uuid_struct)  COPY_UUID_128(uuid_struct,0x02,0x36,0x6e,0x80, 0xcf,0x3a, 0x11,0xe1, 0x9a,0xb4, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+  #define COPY_FREE_FALL_UUID(uuid_struct)    COPY_UUID_128(uuid_struct,0xe2,0x3e,0x78,0xa0, 0xcf,0x4a, 0x11,0xe1, 0x8f,0xfc, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+  #define COPY_ACC_UUID(uuid_struct)          COPY_UUID_128(uuid_struct,0x34,0x0a,0x1b,0x80, 0xcf,0x4b, 0x11,0xe1, 0xac,0x36, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+
+  #define COPY_ENV_SENS_SERVICE_UUID(uuid_struct)  COPY_UUID_128(uuid_struct,0x42,0x82,0x1a,0x40, 0xe4,0x77, 0x11,0xe2, 0x82,0xd0, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+  #define COPY_TEMP_CHAR_UUID(uuid_struct)         COPY_UUID_128(uuid_struct,0xa3,0x2e,0x55,0x20, 0xe4,0x77, 0x11,0xe2, 0xa9,0xe3, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+  #define COPY_PRESS_CHAR_UUID(uuid_struct)        COPY_UUID_128(uuid_struct,0xcd,0x20,0xc4,0x80, 0xe4,0x8b, 0x11,0xe2, 0x84,0x0b, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+  #define COPY_HUMIDITY_CHAR_UUID(uuid_struct)     COPY_UUID_128(uuid_struct,0x01,0xc5,0x0b,0x60, 0xe4,0x8c, 0x11,0xe2, 0xa0,0x73, 0x00,0x02,0xa5,0xd5,0xc5,0x1b)
+#endif
+
+/* Store Value into a buffer in Little Endian Format */
+#define STORE_LE_16(buf, val)    ( ((buf)[0] =  (uint8_t) (val)    ) , \
+                                   ((buf)[1] =  (uint8_t) (val>>8) ) )
+/**
+ * @}
+ */
+
+/** @defgroup SENSOR_SERVICE_Exported_Functions 
+ * @{
+ */ 
+/**
+ * @brief  Add an accelerometer service using a vendor specific profile.
+ *
+ * @param  None
+ * @retval tBleStatus Status
+ */
+tBleStatus Add_Acc_Service(void)
+{
+  tBleStatus ret;
+
+  uint8_t uuid[16];
+  
+  COPY_ACC_SERVICE_UUID(uuid);
+  ret = aci_gatt_add_serv(UUID_TYPE_128,  uuid, PRIMARY_SERVICE, 7,
+                          &accServHandle);
+  if (ret != BLE_STATUS_SUCCESS) goto fail;    
+  
+  COPY_FREE_FALL_UUID(uuid);
+  ret =  aci_gatt_add_char(accServHandle, UUID_TYPE_128, uuid, 1,
+                           CHAR_PROP_NOTIFY, ATTR_PERMISSION_NONE, 0,
+                           16, 0, &freeFallCharHandle);
+  if (ret != BLE_STATUS_SUCCESS) goto fail;
+  
+  COPY_ACC_UUID(uuid);  
+  ret =  aci_gatt_add_char(accServHandle, UUID_TYPE_128, uuid, 6,
+                           CHAR_PROP_NOTIFY|CHAR_PROP_READ,
+                           ATTR_PERMISSION_NONE,
+                           GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP,
+                           16, 0, &accCharHandle);
+  if (ret != BLE_STATUS_SUCCESS) goto fail;
+  
+  PRINTF("Service ACC added. Handle 0x%04X, Free fall Charac handle: 0x%04X, Acc Charac handle: 0x%04X\n",accServHandle, freeFallCharHandle, accCharHandle);	
+  return BLE_STATUS_SUCCESS; 
+  
+fail:
+  PRINTF("Error while adding ACC service.\n");
+  return BLE_STATUS_ERROR ;
+    
+}
+
+/**
+ * @brief  Send a notification for a Free Fall detection.
+ *
+ * @param  None
+ * @retval tBleStatus Status
+ */
+tBleStatus Free_Fall_Notify(void)
+{  
+  uint8_t val;
+  tBleStatus ret;
+	
+  val = 0x01;	
+  ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1,
+                                   &val);
+	
+  if (ret != BLE_STATUS_SUCCESS){
+    PRINTF("Error while updating FFall characteristic.\n") ;
+    return BLE_STATUS_ERROR ;
+  }
+  return BLE_STATUS_SUCCESS;	
+}
+
+/**
+ * @brief  Update acceleration characteristic value.
+ *
+ * @param  Structure containing acceleration value in mg
+ * @retval Status
+ */
+tBleStatus Acc_Update(AxesRaw_t *data)
+{  
+  tBleStatus ret;    
+  uint8_t buff[6];
+    
+  STORE_LE_16(buff,data->AXIS_X);
+  STORE_LE_16(buff+2,data->AXIS_Y);
+  STORE_LE_16(buff+4,data->AXIS_Z);
+	
+  ret = aci_gatt_update_char_value(accServHandle, accCharHandle, 0, 6, buff);
+	
+  if (ret != BLE_STATUS_SUCCESS){
+    PRINTF("Error while updating ACC characteristic.\n") ;
+    return BLE_STATUS_ERROR ;
+  }
+  return BLE_STATUS_SUCCESS;	
+}
+
+/**
+ * @brief  Add the Environmental Sensor service.
+ *
+ * @param  None
+ * @retval Status
+ */
+tBleStatus Add_Environmental_Sensor_Service(void)
+{
+  tBleStatus ret;
+  uint8_t uuid[16];
+  uint16_t uuid16;
+  charactFormat charFormat;
+  uint16_t descHandle;
+  
+  COPY_ENV_SENS_SERVICE_UUID(uuid);
+  ret = aci_gatt_add_serv(UUID_TYPE_128,  uuid, PRIMARY_SERVICE, 10,
+                          &envSensServHandle);
+  if (ret != BLE_STATUS_SUCCESS) goto fail;
+  
+  /* Temperature Characteristic */
+  COPY_TEMP_CHAR_UUID(uuid);  
+  ret =  aci_gatt_add_char(envSensServHandle, UUID_TYPE_128, uuid, 2,
+                           CHAR_PROP_READ, ATTR_PERMISSION_NONE,
+                           GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP,
+                           16, 0, &tempCharHandle);
+  if (ret != BLE_STATUS_SUCCESS) goto fail;
+  
+  charFormat.format = FORMAT_SINT16;
+  charFormat.exp = -1;
+  charFormat.unit = UNIT_TEMP_CELSIUS;
+  charFormat.name_space = 0;
+  charFormat.desc = 0;
+  
+  uuid16 = CHAR_FORMAT_DESC_UUID;
+  
+  ret = aci_gatt_add_char_desc(envSensServHandle,
+                               tempCharHandle,
+                               UUID_TYPE_16,
+                               (uint8_t *)&uuid16, 
+                               7,
+                               7,
+                               (void *)&charFormat, 
+                               ATTR_PERMISSION_NONE,
+                               ATTR_ACCESS_READ_ONLY,
+                               0,
+                               16,
+                               FALSE,
+                               &descHandle);
+  if (ret != BLE_STATUS_SUCCESS) goto fail;
+  
+  /* Pressure Characteristic */
+  if(1){ //FIXME
+    COPY_PRESS_CHAR_UUID(uuid);  
+    ret =  aci_gatt_add_char(envSensServHandle, UUID_TYPE_128, uuid, 3,
+                             CHAR_PROP_READ, ATTR_PERMISSION_NONE,
+                             GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP,
+                             16, 0, &pressCharHandle);
+    if (ret != BLE_STATUS_SUCCESS) goto fail;
+    
+    charFormat.format = FORMAT_SINT24;
+    charFormat.exp = -5;
+    charFormat.unit = UNIT_PRESSURE_BAR;
+    charFormat.name_space = 0;
+    charFormat.desc = 0;
+    
+    uuid16 = CHAR_FORMAT_DESC_UUID;
+    
+    ret = aci_gatt_add_char_desc(envSensServHandle,
+                                 pressCharHandle,
+                                 UUID_TYPE_16,
+                                 (uint8_t *)&uuid16, 
+                                 7,
+                                 7,
+                                 (void *)&charFormat, 
+                                 ATTR_PERMISSION_NONE,
+                                 ATTR_ACCESS_READ_ONLY,
+                                 0,
+                                 16,
+                                 FALSE,
+                                 &descHandle);
+    if (ret != BLE_STATUS_SUCCESS) goto fail;
+  }    
+  /* Humidity Characteristic */
+  if(1){   //FIXME
+    COPY_HUMIDITY_CHAR_UUID(uuid);  
+    ret =  aci_gatt_add_char(envSensServHandle, UUID_TYPE_128, uuid, 2,
+                             CHAR_PROP_READ, ATTR_PERMISSION_NONE,
+                             GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP,
+                             16, 0, &humidityCharHandle);
+    if (ret != BLE_STATUS_SUCCESS) goto fail;
+    
+    charFormat.format = FORMAT_UINT16;
+    charFormat.exp = -1;
+    charFormat.unit = UNIT_UNITLESS;
+    charFormat.name_space = 0;
+    charFormat.desc = 0;
+    
+    uuid16 = CHAR_FORMAT_DESC_UUID;
+    
+    ret = aci_gatt_add_char_desc(envSensServHandle,
+                                 humidityCharHandle,
+                                 UUID_TYPE_16,
+                                 (uint8_t *)&uuid16, 
+                                 7,
+                                 7,
+                                 (void *)&charFormat, 
+                                 ATTR_PERMISSION_NONE,
+                                 ATTR_ACCESS_READ_ONLY,
+                                 0,
+                                 16,
+                                 FALSE,
+                                 &descHandle);
+    if (ret != BLE_STATUS_SUCCESS) goto fail;
+  } 
+  PRINTF("Service ENV_SENS added. Handle 0x%04X, TEMP Charac handle: 0x%04X, PRESS Charac handle: 0x%04X, HUMID Charac handle: 0x%04X\n",envSensServHandle, tempCharHandle, pressCharHandle, humidityCharHandle);	
+  return BLE_STATUS_SUCCESS; 
+  
+fail:
+  PRINTF("Error while adding ENV_SENS service.\n");
+  return BLE_STATUS_ERROR ;
+  
+}
+
+/**
+ * @brief  Update temperature characteristic value.
+ * @param  Temperature in tenths of degree 
+ * @retval Status
+ */
+tBleStatus Temp_Update(int16_t temp)
+{  
+  tBleStatus ret;
+  
+  ret = aci_gatt_update_char_value(envSensServHandle, tempCharHandle, 0, 2,
+                                   (uint8_t*)&temp);
+  
+  if (ret != BLE_STATUS_SUCCESS){
+    PRINTF("Error while updating TEMP characteristic.\n") ;
+    return BLE_STATUS_ERROR ;
+  }
+  return BLE_STATUS_SUCCESS;
+	
+}
+
+/**
+ * @brief  Update pressure characteristic value.
+ * @param  int32_t Pressure in mbar 
+ * @retval tBleStatus Status
+ */
+tBleStatus Press_Update(int32_t press)
+{  
+  tBleStatus ret;
+  
+  ret = aci_gatt_update_char_value(envSensServHandle, pressCharHandle, 0, 3,
+                                   (uint8_t*)&press);
+  
+  if (ret != BLE_STATUS_SUCCESS){
+    PRINTF("Error while updating TEMP characteristic.\n") ;
+    return BLE_STATUS_ERROR ;
+  }
+  return BLE_STATUS_SUCCESS;
+	
+}
+
+/**
+ * @brief  Update humidity characteristic value.
+ * @param  uint16_thumidity RH (Relative Humidity) in thenths of %
+ * @retval tBleStatus      Status
+ */
+tBleStatus Humidity_Update(uint16_t humidity)
+{  
+  tBleStatus ret;
+  
+  ret = aci_gatt_update_char_value(envSensServHandle, humidityCharHandle, 0, 2,
+                                   (uint8_t*)&humidity);
+  
+  if (ret != BLE_STATUS_SUCCESS){
+    PRINTF("Error while updating TEMP characteristic.\n") ;
+    return BLE_STATUS_ERROR ;
+  }
+  return BLE_STATUS_SUCCESS;
+  
+}
+
+/**
+ * @brief  Puts the device in connectable mode.
+ *         If you want to specify a UUID list in the advertising data, those data can
+ *         be specified as a parameter in aci_gap_set_discoverable().
+ *         For manufacture data, aci_gap_update_adv_data must be called.
+ * @param  None 
+ * @retval None
+ */
+/* Ex.:
+ *
+ *  tBleStatus ret;    
+ *  const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'};    
+ *  const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12};    
+ *  const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01};
+ *  
+ *  ret = aci_gap_set_discoverable(ADV_IND, 0, 0, PUBLIC_ADDR, NO_WHITE_LIST_USE,
+ *                                 8, local_name, 3, serviceUUIDList, 0, 0);    
+ *  ret = aci_gap_update_adv_data(5, manuf_data);
+ *
+ */
+void setConnectable(void)
+{  
+  tBleStatus ret;
+  
+  const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'};
+  
+  /* disable scan response */
+  hci_le_set_scan_resp_data(0,NULL);
+  PRINTF("General Discoverable Mode.\n");
+  
+  ret = aci_gap_set_discoverable(ADV_IND, 0, 0, PUBLIC_ADDR, NO_WHITE_LIST_USE,
+                                 sizeof(local_name), local_name, 0, NULL, 0, 0);
+  if (ret != BLE_STATUS_SUCCESS) {
+    PRINTF("Error while setting discoverable mode (%d)\n", ret);    
+  }  
+}
+
+/**
+ * @brief  This function is called when there is a LE Connection Complete event.
+ * @param  uint8_t Address of peer device
+ * @param  uint16_t Connection handle
+ * @retval None
+ */
+void GAP_ConnectionComplete_CB(uint8_t addr[6], uint16_t handle)
+{  
+  connected = TRUE;
+  connection_handle = handle;
+  
+  PRINTF("Connected to device:");
+  for(int i = 5; i > 0; i--){
+    PRINTF("%02X-", addr[i]);
+  }
+  PRINTF("%02X\n", addr[0]);
+}
+
+/**
+ * @brief  This function is called when the peer device gets disconnected.
+ * @param  None 
+ * @retval None
+ */
+void GAP_DisconnectionComplete_CB(void)
+{
+  connected = FALSE;
+  PRINTF("Disconnected\n");
+  /* Make the device connectable again. */
+  set_connectable = TRUE;
+  notification_enabled = FALSE;
+}
+
+/**
+ * @brief  Read request callback.
+ * @param  uint16_t Handle of the attribute
+ * @retval None
+ */
+void Read_Request_CB(uint16_t handle)
+{  
+  if(handle == accCharHandle + 1){
+    Acc_Update((AxesRaw_t*)&axes_data);
+  }  
+  else if(handle == tempCharHandle + 1){
+    int16_t data;
+    data = 270 + ((uint64_t)rand()*15)/RAND_MAX; //sensor emulation        
+    Acc_Update((AxesRaw_t*)&axes_data); //FIXME: to overcome issue on Android App
+                                        // If the user button is not pressed within
+                                        // a short time after the connection,
+                                        // a pop-up reports a "No valid characteristics found" error.
+    Temp_Update(data);
+  }
+  else if(handle == pressCharHandle + 1){
+    int32_t data;
+    struct timer t;  
+    Timer_Set(&t, CLOCK_SECOND/10);
+    data = 100000 + ((uint64_t)rand()*1000)/RAND_MAX;
+    Press_Update(data);
+  }
+  else if(handle == humidityCharHandle + 1){
+    uint16_t data;
+    
+    data = 450 + ((uint64_t)rand()*100)/RAND_MAX;
+    
+    Humidity_Update(data);
+  }  
+  
+  //EXIT:
+  if(connection_handle != 0)
+    aci_gatt_allow_read(connection_handle);
+}
+
+/**
+ * @brief  Callback processing the ACI events.
+ * @note   Inside this function each event must be identified and correctly
+ *         parsed.
+ * @param  void* Pointer to the ACI packet
+ * @retval None
+ */
+void HCI_Event_CB(void *pckt)
+{
+  hci_uart_pckt *hci_pckt = pckt;
+  /* obtain event packet */
+  hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data;
+  
+  if(hci_pckt->type != HCI_EVENT_PKT)
+    return;
+  
+  switch(event_pckt->evt){
+    
+  case EVT_DISCONN_COMPLETE:
+    {
+      GAP_DisconnectionComplete_CB();
+    }
+    break;
+    
+  case EVT_LE_META_EVENT:
+    {
+      evt_le_meta_event *evt = (void *)event_pckt->data;
+      
+      switch(evt->subevent){
+      case EVT_LE_CONN_COMPLETE:
+        {
+          evt_le_connection_complete *cc = (void *)evt->data;
+          GAP_ConnectionComplete_CB(cc->peer_bdaddr, cc->handle);
+        }
+        break;
+      }
+    }
+    break;
+    
+  case EVT_VENDOR:
+    {
+      evt_blue_aci *blue_evt = (void*)event_pckt->data;
+      switch(blue_evt->ecode){
+
+#if NEW_SERVICES
+      case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED:         
+        {
+          /* this callback is invoked when a GATT attribute is modified
+          extract callback data and pass to suitable handler function */
+          if (bnrg_expansion_board == IDB05A1) {
+            evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data;
+            Attribute_Modified_CB(evt->attr_handle, evt->data_length, evt->att_data); 
+          }
+          else {
+            evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data;
+            Attribute_Modified_CB(evt->attr_handle, evt->data_length, evt->att_data); 
+          }                       
+        }
+        break; 
+#endif
+
+      case EVT_BLUE_GATT_READ_PERMIT_REQ:
+        {
+          evt_gatt_read_permit_req *pr = (void*)blue_evt->data;                    
+          Read_Request_CB(pr->attr_handle);                    
+        }
+        break;
+      }
+    }
+    break;
+  }    
+}
+
+#if NEW_SERVICES
+/**
+ * @brief  Add a time service using a vendor specific profile
+ * @param  None
+ * @retval Status
+ */
+tBleStatus Add_Time_Service(void)
+{
+  tBleStatus ret;
+  uint8_t uuid[16];
+  
+  /* copy "Timer service UUID" defined above to 'uuid' local variable */
+  COPY_TIME_SERVICE_UUID(uuid);
+  
+  /* 
+   * now add "Time service" to GATT server, service handle is returned
+   * via 'timeServHandle' parameter of aci_gatt_add_serv() API. 
+   * Please refer to 'BlueNRG Application Command Interface.pdf' for detailed
+   * API description 
+  */
+  ret = aci_gatt_add_serv(UUID_TYPE_128,  uuid, PRIMARY_SERVICE, 7,
+                          &timeServHandle);
+  if (ret != BLE_STATUS_SUCCESS) goto fail;    
+  
+  /* 
+   * now add "Seconds characteristic" to Time service, characteristic handle 
+   * is returned via 'secondsCharHandle' parameter of aci_gatt_add_char() API.
+   * This characteristic is read only, as specified by CHAR_PROP_READ parameter.
+   * Please refer to 'BlueNRG Application Command Interface.pdf' for detailed
+   * API description 
+  */  
+  COPY_TIME_UUID(uuid);
+  ret =  aci_gatt_add_char(timeServHandle, UUID_TYPE_128, uuid, 4,
+                           CHAR_PROP_READ, ATTR_PERMISSION_NONE, 0,
+                           16, 0, &secondsCharHandle);
+  
+  if (ret != BLE_STATUS_SUCCESS) goto fail;  
+  
+  COPY_MINUTE_UUID(uuid);  
+  /* 
+   * Add "Minutes characteristic" to "Time service". 
+   * This characteristic is readable as well as notifiable only, as specified 
+   * by CHAR_PROP_NOTIFY|CHAR_PROP_READ parameter below.   
+   */
+  ret = aci_gatt_add_char(timeServHandle, UUID_TYPE_128, uuid, 4,
+                          CHAR_PROP_NOTIFY|CHAR_PROP_READ, ATTR_PERMISSION_NONE, 0,
+                          16, 1, &minuteCharHandle);
+  if (ret != BLE_STATUS_SUCCESS) goto fail;
+  
+  PRINTF("Service TIME added. Handle 0x%04X, TIME Charac handle: 0x%04X\n",timeServHandle, secondsCharHandle);	
+  return BLE_STATUS_SUCCESS; 
+  
+  /* return BLE_STATUS_ERROR if we reach this tag */
+fail:
+  PRINTF("Error while adding Time service.\n");
+  return BLE_STATUS_ERROR ;    
+}
+
+/**
+ * @brief  Update seconds characteristic value of Time service.
+ * @param  None
+ * @retval Status
+ */
+tBleStatus Seconds_Update(void)
+{  
+  uint32_t val;
+  tBleStatus ret;  
+  
+  /* Obtain system tick value in milliseconds, and convert it to seconds. */    
+  val = HAL_GetTick();
+  val = val/1000;
+  
+  /* create a time[] array to pass as last argument of aci_gatt_update_char_value() API*/
+  const uint8_t time[4] = {(val >> 24)&0xFF, (val >> 16)&0xFF, (val >> 8)&0xFF, (val)&0xFF};  
+  
+  /*
+   * Update value of "Seconds characteristic" using aci_gatt_update_char_value() API 
+   * Please refer to 'BlueNRG Application Command Interface.pdf' for detailed
+   * API description   
+   */
+  ret = aci_gatt_update_char_value(timeServHandle, secondsCharHandle, 0, 4,
+                                   time);
+	
+  if (ret != BLE_STATUS_SUCCESS){
+    PRINTF("Error while updating TIME characteristic.\n") ;
+    return BLE_STATUS_ERROR ;
+  }
+  return BLE_STATUS_SUCCESS;		
+}
+
+/**
+ * @brief  Send a notification for a minute characteristic of time service.
+ * @param  None
+ * @retval Status
+ */
+tBleStatus Minutes_Notify(void)
+{  
+  uint32_t val; 
+  uint32_t minuteValue;   
+  tBleStatus ret;
+
+  /* Obtain system tick value in milliseconds */  
+  val = HAL_GetTick();	
+  
+  /* update "Minutes characteristic" value if it has changed w.r.t. previous 
+   * "minute" value. 
+   */
+  if((minuteValue=val/(60*1000))!=previousMinuteValue) {    
+    /* memorize this "minute" value for future usage */
+    previousMinuteValue = minuteValue;    
+  
+    /* create a time[] array to pass as last argument of aci_gatt_update_char_value() API*/
+    const uint8_t time[4] = {(minuteValue >> 24)&0xFF, (minuteValue >> 16)&0xFF, (minuteValue >> 8)&0xFF, (minuteValue)&0xFF};
+   
+  /*
+   * Update value of "Minutes characteristic" using aci_gatt_update_char_value() API 
+   * Please refer to 'BlueNRG Application Command Interface.pdf' for detailed
+   * API description   
+   */    
+    ret = aci_gatt_update_char_value(timeServHandle, minuteCharHandle, 0, 4,
+                                     time);          
+    if (ret != BLE_STATUS_SUCCESS){
+      PRINTF("Error while updating TIME characteristic.\n") ;
+      return BLE_STATUS_ERROR ;
+    }
+  }
+  return BLE_STATUS_SUCCESS;	
+}
+
+/**
+ * @brief  Updates "Seconds and Minutes characteristics" values.
+ * @param  None
+ * @retval None
+ */
+void Update_Time_Characteristics(void) {
+  /* update "seconds and minutes characteristics" of time service */
+  Seconds_Update();
+  Minutes_Notify();
+}
+
+/*
+ * @brief  Add LED button service using a vendor specific profile.
+ * @param  None
+ * @retval Status
+ */
+tBleStatus Add_LED_Service(void)
+{
+  tBleStatus ret;
+  uint8_t uuid[16];
+  
+  /* copy "LED service UUID" defined above to 'uuid' local variable */
+  COPY_LED_SERVICE_UUID(uuid);
+  /* 
+   * now add "LED service" to GATT server, service handle is returned
+   * via 'ledServHandle' parameter of aci_gatt_add_serv() API. 
+   * Please refer to 'BlueNRG Application Command Interface.pdf' for detailed
+   * API description 
+  */  
+  ret = aci_gatt_add_serv(UUID_TYPE_128, uuid, PRIMARY_SERVICE, 7,
+                          &ledServHandle);
+  if (ret != BLE_STATUS_SUCCESS) goto fail;    
+  
+  /* copy "LED button characteristic UUID" defined above to 'uuid' local variable */  
+  COPY_LED_UUID(uuid);
+  /* 
+   * now add "LED button characteristic" to LED service, characteristic handle 
+   * is returned via 'ledButtonCharHandle' parameter of aci_gatt_add_char() API.
+   * This characteristic is writable, as specified by 'CHAR_PROP_WRITE' parameter.
+   * Please refer to 'BlueNRG Application Command Interface.pdf' for detailed
+   * API description 
+  */   
+  ret =  aci_gatt_add_char(ledServHandle, UUID_TYPE_128, uuid, 4,
+                           CHAR_PROP_WRITE | CHAR_PROP_WRITE_WITHOUT_RESP, ATTR_PERMISSION_NONE, GATT_NOTIFY_ATTRIBUTE_WRITE,
+                           16, 1, &ledButtonCharHandle);
+  if (ret != BLE_STATUS_SUCCESS) goto fail;  
+  
+  PRINTF("Service LED BUTTON added. Handle 0x%04X, LED button Charac handle: 0x%04X\n",ledServHandle, ledButtonCharHandle);	
+  return BLE_STATUS_SUCCESS; 
+  
+fail:
+  PRINTF("Error while adding LED service.\n");
+  return BLE_STATUS_ERROR;
+}
+
+/**
+ * @brief  This function is called attribute value corresponding to 
+ *         ledButtonCharHandle characteristic gets modified.
+ * @param  Handle of the attribute
+ * @param  Size of the modified attribute data
+ * @param  Pointer to the modified attribute data
+ * @retval None
+ */
+void Attribute_Modified_CB(uint16_t handle, uint8_t data_length, uint8_t *att_data)
+{
+  /* If GATT client has modified 'LED button characteristic' value, toggle LED2 */
+  if(handle == ledButtonCharHandle + 1){      
+      BSP_LED_Toggle(LED2);
+  }
+}
+#endif /* NEW_SERVICES */
+/**
+ * @}
+ */
+ 
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+ /**
+ * @}
+ */
+ 
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm32f4xx_hal_msp.c	Mon Nov 12 18:36:18 2018 +0000
@@ -0,0 +1,161 @@
+/**
+  ******************************************************************************
+  * @file    stm32f4xx_hal_msp.c
+  * @author  MCD Application Team
+  * @version V1.5.0
+  * @date    06-May-2016
+  * @brief   This file contains the HAL System and Peripheral (PPP) MSP initialization
+  *          and de-initialization functions.
+  *******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_nucleo_bluenrg.h"
+
+/** @addtogroup X-CUBE-BLE1_Applications
+ *  @{
+ */
+
+/** @addtogroup SensorDemo
+ *  @{
+ */
+ 
+/** @defgroup STM32F4XX_HAL_MSP
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup STM32F4XX_HAL_MSP_Private_Functions
+  * @{
+  */
+
+/**
+ * @brief  This function is used for low level initialization of the SPI 
+ *         communication with the BlueNRG Expansion Board.
+ * @param  hspi: SPI handle.
+ * @retval None
+ */
+void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
+{
+  GPIO_InitTypeDef GPIO_InitStruct;
+  if(hspi->Instance==BNRG_SPI_INSTANCE)
+  {
+    /* Enable peripherals clock */
+
+    /* Enable GPIO Ports Clock */  
+    BNRG_SPI_RESET_CLK_ENABLE();
+    BNRG_SPI_SCLK_CLK_ENABLE();
+    BNRG_SPI_MISO_CLK_ENABLE();
+    BNRG_SPI_MOSI_CLK_ENABLE();
+    BNRG_SPI_CS_CLK_ENABLE();
+    BNRG_SPI_IRQ_CLK_ENABLE();
+
+    /* Enable SPI clock */
+    BNRG_SPI_CLK_ENABLE();
+
+    /* Reset */
+    GPIO_InitStruct.Pin = BNRG_SPI_RESET_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_RESET_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_RESET_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_RESET_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_RESET_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct);	
+    HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_RESET);	/*Added to avoid spurious interrupt from the BlueNRG */
+
+    /* SCLK */
+    GPIO_InitStruct.Pin = BNRG_SPI_SCLK_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_SCLK_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_SCLK_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_SCLK_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_SCLK_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_SCLK_PORT, &GPIO_InitStruct); 
+
+    /* MISO */
+    GPIO_InitStruct.Pin = BNRG_SPI_MISO_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_MISO_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_MISO_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_MISO_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_MISO_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_MISO_PORT, &GPIO_InitStruct);
+
+    /* MOSI */
+    GPIO_InitStruct.Pin = BNRG_SPI_MOSI_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_MOSI_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_MOSI_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_MOSI_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_MOSI_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_MOSI_PORT, &GPIO_InitStruct);
+
+    /* NSS/CSN/CS */
+    GPIO_InitStruct.Pin = BNRG_SPI_CS_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_CS_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_CS_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_CS_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_CS_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_CS_PORT, &GPIO_InitStruct);
+    HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
+
+    /* IRQ -- INPUT */
+    GPIO_InitStruct.Pin = BNRG_SPI_IRQ_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_IRQ_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_IRQ_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_IRQ_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_IRQ_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_IRQ_PORT, &GPIO_InitStruct);
+
+    /* Configure the NVIC for SPI */  
+    HAL_NVIC_SetPriority(BNRG_SPI_EXTI_IRQn, 3, 0);    
+    HAL_NVIC_EnableIRQ(BNRG_SPI_EXTI_IRQn);
+  }
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm32l0xx_hal_msp.c	Mon Nov 12 18:36:18 2018 +0000
@@ -0,0 +1,160 @@
+/**
+  ******************************************************************************
+  * @file    stm32l0xx_hal_msp.c
+  * @author  MCD Application Team
+  * @version V1.5.0
+  * @date    8-January-2016
+  * @brief   HAL MSP module.
+  *******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32l0xx_nucleo_bluenrg.h"
+
+/** @addtogroup X-CUBE-BLE1_Applications
+ *  @{
+ */
+
+/** @addtogroup SensorDemo
+ *  @{
+ */
+ 
+/** @defgroup STM32L0XX_HAL_MSP
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup STM32L0XX_HAL_MSP_Private_Functions
+  * @{
+  */
+
+/**
+ * @brief  This function is used for low level initialization of the SPI 
+ *         communication with the BlueNRG Expansion Board.
+ * @param  hspi: SPI handle.
+ * @retval None
+ */
+void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
+{
+  GPIO_InitTypeDef GPIO_InitStruct;
+  if(hspi->Instance==BNRG_SPI_INSTANCE)
+  {
+    /* Enable peripherals clock */
+
+    /* Enable GPIO Ports Clock */  
+    BNRG_SPI_RESET_CLK_ENABLE();
+    BNRG_SPI_SCLK_CLK_ENABLE();
+    BNRG_SPI_MISO_CLK_ENABLE();
+    BNRG_SPI_MOSI_CLK_ENABLE();
+    BNRG_SPI_CS_CLK_ENABLE();
+    BNRG_SPI_IRQ_CLK_ENABLE();
+
+    /* Enable SPI clock */
+    BNRG_SPI_CLK_ENABLE();
+
+    /* Reset */
+    GPIO_InitStruct.Pin = BNRG_SPI_RESET_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_RESET_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_RESET_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_RESET_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_RESET_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct);	
+    HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_RESET);	/*Added to avoid spurious interrupt from the BlueNRG */
+
+    /* SCLK */
+    GPIO_InitStruct.Pin = BNRG_SPI_SCLK_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_SCLK_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_SCLK_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_SCLK_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_SCLK_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_SCLK_PORT, &GPIO_InitStruct); 
+
+    /* MISO */
+    GPIO_InitStruct.Pin = BNRG_SPI_MISO_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_MISO_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_MISO_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_MISO_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_MISO_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_MISO_PORT, &GPIO_InitStruct);
+
+    /* MOSI */
+    GPIO_InitStruct.Pin = BNRG_SPI_MOSI_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_MOSI_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_MOSI_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_MOSI_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_MOSI_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_MOSI_PORT, &GPIO_InitStruct);
+
+    /* NSS/CSN/CS */
+    GPIO_InitStruct.Pin = BNRG_SPI_CS_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_CS_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_CS_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_CS_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_CS_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_CS_PORT, &GPIO_InitStruct);
+    HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
+
+    /* IRQ -- INPUT */
+    GPIO_InitStruct.Pin = BNRG_SPI_IRQ_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_IRQ_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_IRQ_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_IRQ_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_IRQ_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_IRQ_PORT, &GPIO_InitStruct);
+
+    /* Configure the NVIC for SPI */  
+    HAL_NVIC_SetPriority(BNRG_SPI_EXTI_IRQn, 3, 0);    
+    HAL_NVIC_EnableIRQ(BNRG_SPI_EXTI_IRQn);
+  }
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm32l4xx_hal_msp.c	Mon Nov 12 18:36:18 2018 +0000
@@ -0,0 +1,160 @@
+/**
+  ******************************************************************************
+  * @file    stm32l4xx_hal_msp.c
+  * @author  MCD Application Team
+  * @version V1.3.0
+  * @date    29-January-2016
+  * @brief   HAL MSP module.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************  
+  */ 
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32l4xx_nucleo_bluenrg.h"
+
+/** @addtogroup X-CUBE-BLE1_Applications
+ *  @{
+ */
+
+/** @addtogroup SensorDemo
+ *  @{
+ */
+ 
+/** @defgroup STM32L4XX_HAL_MSP
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup STM32L4XX_HAL_MSP_Private_Functions
+  * @{
+  */
+
+/**
+ * @brief  This function is used for low level initialization of the SPI 
+ *         communication with the BlueNRG Expansion Board.
+ * @param  hspi: SPI handle.
+ * @retval None
+ */
+void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
+{
+  GPIO_InitTypeDef GPIO_InitStruct;
+  if(hspi->Instance==BNRG_SPI_INSTANCE)
+  {
+    /* Enable peripherals clock */
+
+    /* Enable GPIO Ports Clock */  
+    BNRG_SPI_RESET_CLK_ENABLE();
+    BNRG_SPI_SCLK_CLK_ENABLE();
+    BNRG_SPI_MISO_CLK_ENABLE();
+    BNRG_SPI_MOSI_CLK_ENABLE();
+    BNRG_SPI_CS_CLK_ENABLE();
+    BNRG_SPI_IRQ_CLK_ENABLE();
+
+    /* Enable SPI clock */
+    BNRG_SPI_CLK_ENABLE();
+
+    /* Reset */
+    GPIO_InitStruct.Pin = BNRG_SPI_RESET_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_RESET_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_RESET_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_RESET_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_RESET_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct);	
+    HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_RESET);	/*Added to avoid spurious interrupt from the BlueNRG */
+
+    /* SCLK */
+    GPIO_InitStruct.Pin = BNRG_SPI_SCLK_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_SCLK_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_SCLK_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_SCLK_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_SCLK_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_SCLK_PORT, &GPIO_InitStruct); 
+
+    /* MISO */
+    GPIO_InitStruct.Pin = BNRG_SPI_MISO_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_MISO_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_MISO_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_MISO_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_MISO_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_MISO_PORT, &GPIO_InitStruct);
+
+    /* MOSI */
+    GPIO_InitStruct.Pin = BNRG_SPI_MOSI_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_MOSI_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_MOSI_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_MOSI_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_MOSI_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_MOSI_PORT, &GPIO_InitStruct);
+
+    /* NSS/CSN/CS */
+    GPIO_InitStruct.Pin = BNRG_SPI_CS_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_CS_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_CS_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_CS_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_CS_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_CS_PORT, &GPIO_InitStruct);
+    HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
+
+    /* IRQ -- INPUT */
+    GPIO_InitStruct.Pin = BNRG_SPI_IRQ_PIN;
+    GPIO_InitStruct.Mode = BNRG_SPI_IRQ_MODE;
+    GPIO_InitStruct.Pull = BNRG_SPI_IRQ_PULL;
+    GPIO_InitStruct.Speed = BNRG_SPI_IRQ_SPEED;
+    GPIO_InitStruct.Alternate = BNRG_SPI_IRQ_ALTERNATE;
+    HAL_GPIO_Init(BNRG_SPI_IRQ_PORT, &GPIO_InitStruct);
+
+    /* Configure the NVIC for SPI */  
+    HAL_NVIC_SetPriority(BNRG_SPI_EXTI_IRQn, 3, 0);    
+    HAL_NVIC_EnableIRQ(BNRG_SPI_EXTI_IRQn);
+  }
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm32xx_it.c	Mon Nov 12 18:36:18 2018 +0000
@@ -0,0 +1,193 @@
+/**
+  ******************************************************************************
+  * @file    stm32xx_it.c 
+  * @author  CL
+  * @version V1.0.0
+  * @date    04-July-2014
+  * @brief   Main Interrupt Service Routines.
+  *          This file provides template for all exceptions handler and 
+  *          peripherals interrupt service routine.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32xx_it.h"
+#include "debug.h"
+
+/** @addtogroup X-CUBE-BLE1_Applications
+ *  @{
+ */
+
+/** @addtogroup SensorDemo
+ *  @{
+ */
+ 
+/** @defgroup INTERRUPT_HANDLER 
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+volatile uint32_t ms_counter = 0;
+volatile uint8_t button_event = 0;
+/* SPI handler declared in "main.c" file */
+extern SPI_HandleTypeDef SpiHandle;
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/******************************************************************************/
+/*            Cortex-M0+ Processor Exceptions Handlers                         */
+/******************************************************************************/
+
+/**
+  * @brief  NMI_Handler This function handles NMI exception.
+  * @param  None
+  * @retval None
+  */
+void NMI_Handler(void)
+{
+}
+
+/**
+  * @brief  HardFault_Handler This function handles Hard Fault exception.
+  * @param  None
+  * @retval None
+  */
+void HardFault_Handler(void)
+{
+  /* Go to infinite loop when Hard Fault exception occurs */
+  while (1)
+  {
+  }
+}
+
+/**
+  * @brief  SVC_Handler This function handles SVCall exception.
+  * @param  None
+  * @retval None
+  */
+void SVC_Handler(void)
+{
+}
+
+/**
+  * @brief  DebugMon_Handler This function handles Debug Monitor exception.
+  * @param  None
+  * @retval None
+  */
+void DebugMon_Handler(void)
+{
+}
+
+/**
+  * @brief  PendSV_Handler This function handles PendSVC exception.
+  * @param  None
+  * @retval None
+  */
+void PendSV_Handler(void)
+{
+}
+
+/**
+  * @brief  SysTick_Handler This function handles SysTick Handler.
+  * @param  None
+  * @retval None
+  */
+void SysTick_Handler(void)
+{
+  HAL_IncTick();
+  
+  ms_counter++;
+}
+
+
+/******************************************************************************/
+/*                 STM32L0xx Peripherals Interrupt Handlers                   */
+/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
+/*  available peripheral interrupt handler's name please refer to the startup */
+/*  file (startup_stm32l0xx.s).                                               */
+/******************************************************************************/
+
+/**
+  * @brief  This function handles External line interrupt request for BlueNRG.
+  * @param  None
+  * @retval None
+  */
+void BNRG_SPI_EXTI_IRQHandler(void)
+{
+  HAL_GPIO_EXTI_IRQHandler(BNRG_SPI_EXTI_PIN);
+}
+
+
+/**
+  * @brief  This function handles the Push Button interrupt request.
+  * @param  None
+  * @retval None
+  */
+void PUSH_BUTTON_EXTI_IRQHandler(void)
+{
+  HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN);
+  
+  button_event = 1;
+}
+
+/******************************************************************************/
+/*                 STM32L0xx Peripherals Interrupt Handlers                   */
+/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
+/*  available peripheral interrupt handler's name please refer to the startup */
+/*  file (startup_stm32l0xx.s).                                               */
+/******************************************************************************/
+
+/**
+  * @brief  This function handles PPP interrupt request.
+  * @param  None
+  * @retval None
+  */
+/*
+void PPP_IRQHandler(void)
+{
+}
+*/
+
+/**
+ * @}
+ */ 
+
+/**
+ * @}
+ */ 
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/system_stm32f4xx.c	Mon Nov 12 18:36:18 2018 +0000
@@ -0,0 +1,763 @@
+/**
+  ******************************************************************************
+  * @file    system_stm32f4xx.c
+  * @author  MCD Application Team
+  * @version V2.6.1
+  * @date    14-February-2017
+  * @brief   CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
+  *
+  *   This file provides two functions and one global variable to be called from 
+  *   user application:
+  *      - SystemInit(): This function is called at startup just after reset and 
+  *                      before branch to main program. This call is made inside
+  *                      the "startup_stm32f4xx.s" file.
+  *
+  *      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+  *                                  by the user application to setup the SysTick 
+  *                                  timer or configure other parameters.
+  *                                     
+  *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+  *                                 be called whenever the core clock is changed
+  *                                 during program execution.
+  *
+  *
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2017 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/** @addtogroup CMSIS
+  * @{
+  */
+
+/** @addtogroup stm32f4xx_system
+  * @{
+  */  
+  
+/** @addtogroup STM32F4xx_System_Private_Includes
+  * @{
+  */
+
+
+#include "stm32f4xx.h"
+
+#if !defined  (HSE_VALUE) 
+  #define HSE_VALUE    ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined  (HSI_VALUE)
+  #define HSI_VALUE    ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F4xx_System_Private_TypesDefinitions
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F4xx_System_Private_Defines
+  * @{
+  */
+
+/************************* Miscellaneous Configuration ************************/
+/*!< Uncomment the following line if you need to use external SRAM or SDRAM as data memory  */
+#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\
+ || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
+ || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
+/* #define DATA_IN_ExtSRAM */
+#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || STM32F469xx || STM32F479xx ||\
+          STM32F412Zx || STM32F412Vx */
+ 
+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
+ || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
+/* #define DATA_IN_ExtSDRAM */
+#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx ||\
+          STM32F479xx */
+
+/*!< Uncomment the following line if you need to relocate your vector Table in
+     Internal SRAM. */
+/* #define VECT_TAB_SRAM */
+#define VECT_TAB_OFFSET  0x00 /*!< Vector Table base offset field. 
+                                   This value must be a multiple of 0x200. */
+/******************************************************************************/
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F4xx_System_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F4xx_System_Private_Variables
+  * @{
+  */
+  /* This variable is updated in three ways:
+      1) by calling CMSIS function SystemCoreClockUpdate()
+      2) by calling HAL API function HAL_RCC_GetHCLKFreq()
+      3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency 
+         Note: If you use this function to configure the system clock; then there
+               is no need to call the 2 first functions listed above, since SystemCoreClock
+               variable is updated automatically.
+  */
+uint32_t SystemCoreClock = 16000000;
+const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+const uint8_t APBPrescTable[8]  = {0, 0, 0, 0, 1, 2, 3, 4};
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes
+  * @{
+  */
+
+#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
+  static void SystemInit_ExtMemCtl(void); 
+#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32F4xx_System_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Setup the microcontroller system
+  *         Initialize the FPU setting, vector table location and External memory 
+  *         configuration.
+  * @param  None
+  * @retval None
+  */
+void SystemInit(void)
+{
+  /* FPU settings ------------------------------------------------------------*/
+  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
+  #endif
+  /* Reset the RCC clock configuration to the default reset state ------------*/
+  /* Set HSION bit */
+  RCC->CR |= (uint32_t)0x00000001;
+
+  /* Reset CFGR register */
+  RCC->CFGR = 0x00000000;
+
+  /* Reset HSEON, CSSON and PLLON bits */
+  RCC->CR &= (uint32_t)0xFEF6FFFF;
+
+  /* Reset PLLCFGR register */
+  RCC->PLLCFGR = 0x24003010;
+
+  /* Reset HSEBYP bit */
+  RCC->CR &= (uint32_t)0xFFFBFFFF;
+
+  /* Disable all interrupts */
+  RCC->CIR = 0x00000000;
+
+#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
+  SystemInit_ExtMemCtl(); 
+#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
+
+  /* Configure the Vector Table location add offset address ------------------*/
+#ifdef VECT_TAB_SRAM
+  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
+#else
+  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
+#endif
+}
+
+/**
+   * @brief  Update SystemCoreClock variable according to Clock Register Values.
+  *         The SystemCoreClock variable contains the core clock (HCLK), it can
+  *         be used by the user application to setup the SysTick timer or configure
+  *         other parameters.
+  *           
+  * @note   Each time the core clock (HCLK) changes, this function must be called
+  *         to update SystemCoreClock variable value. Otherwise, any configuration
+  *         based on this variable will be incorrect.         
+  *     
+  * @note   - The system frequency computed by this function is not the real 
+  *           frequency in the chip. It is calculated based on the predefined 
+  *           constant and the selected clock source:
+  *             
+  *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
+  *                                              
+  *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
+  *                          
+  *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) 
+  *             or HSI_VALUE(*) multiplied/divided by the PLL factors.
+  *         
+  *         (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
+  *             16 MHz) but the real value may vary depending on the variations
+  *             in voltage and temperature.   
+  *    
+  *         (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (its value
+  *              depends on the application requirements), user has to ensure that HSE_VALUE
+  *              is same as the real frequency of the crystal used. Otherwise, this function
+  *              may have wrong result.
+  *                
+  *         - The result of this function could be not correct when using fractional
+  *           value for HSE crystal.
+  *     
+  * @param  None
+  * @retval None
+  */
+void SystemCoreClockUpdate(void)
+{
+  uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
+  
+  /* Get SYSCLK source -------------------------------------------------------*/
+  tmp = RCC->CFGR & RCC_CFGR_SWS;
+
+  switch (tmp)
+  {
+    case 0x00:  /* HSI used as system clock source */
+      SystemCoreClock = HSI_VALUE;
+      break;
+    case 0x04:  /* HSE used as system clock source */
+      SystemCoreClock = HSE_VALUE;
+      break;
+    case 0x08:  /* PLL used as system clock source */
+
+      /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
+         SYSCLK = PLL_VCO / PLL_P
+         */    
+      pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
+      pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
+      
+      if (pllsource != 0)
+      {
+        /* HSE used as PLL clock source */
+        pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
+      }
+      else
+      {
+        /* HSI used as PLL clock source */
+        pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
+      }
+
+      pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
+      SystemCoreClock = pllvco/pllp;
+      break;
+    default:
+      SystemCoreClock = HSI_VALUE;
+      break;
+  }
+  /* Compute HCLK frequency --------------------------------------------------*/
+  /* Get HCLK prescaler */
+  tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
+  /* HCLK frequency */
+  SystemCoreClock >>= tmp;
+}
+
+#if defined (DATA_IN_ExtSRAM) && defined (DATA_IN_ExtSDRAM)
+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
+ || defined(STM32F469xx) || defined(STM32F479xx)
+/**
+  * @brief  Setup the external memory controller.
+  *         Called in startup_stm32f4xx.s before jump to main.
+  *         This function configures the external memories (SRAM/SDRAM)
+  *         This SRAM/SDRAM will be used as program data memory (including heap and stack).
+  * @param  None
+  * @retval None
+  */
+void SystemInit_ExtMemCtl(void)
+{
+  __IO uint32_t tmp = 0x00;
+
+  register uint32_t tmpreg = 0, timeout = 0xFFFF;
+  register __IO uint32_t index;
+
+  /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */
+  RCC->AHB1ENR |= 0x000001F8;
+
+  /* Delay after an RCC peripheral clock enabling */
+  tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
+  
+  /* Connect PDx pins to FMC Alternate function */
+  GPIOD->AFR[0]  = 0x00CCC0CC;
+  GPIOD->AFR[1]  = 0xCCCCCCCC;
+  /* Configure PDx pins in Alternate function mode */  
+  GPIOD->MODER   = 0xAAAA0A8A;
+  /* Configure PDx pins speed to 100 MHz */  
+  GPIOD->OSPEEDR = 0xFFFF0FCF;
+  /* Configure PDx pins Output type to push-pull */  
+  GPIOD->OTYPER  = 0x00000000;
+  /* No pull-up, pull-down for PDx pins */ 
+  GPIOD->PUPDR   = 0x00000000;
+
+  /* Connect PEx pins to FMC Alternate function */
+  GPIOE->AFR[0]  = 0xC00CC0CC;
+  GPIOE->AFR[1]  = 0xCCCCCCCC;
+  /* Configure PEx pins in Alternate function mode */ 
+  GPIOE->MODER   = 0xAAAA828A;
+  /* Configure PEx pins speed to 100 MHz */ 
+  GPIOE->OSPEEDR = 0xFFFFC3CF;
+  /* Configure PEx pins Output type to push-pull */  
+  GPIOE->OTYPER  = 0x00000000;
+  /* No pull-up, pull-down for PEx pins */ 
+  GPIOE->PUPDR   = 0x00000000;
+  
+  /* Connect PFx pins to FMC Alternate function */
+  GPIOF->AFR[0]  = 0xCCCCCCCC;
+  GPIOF->AFR[1]  = 0xCCCCCCCC;
+  /* Configure PFx pins in Alternate function mode */   
+  GPIOF->MODER   = 0xAA800AAA;
+  /* Configure PFx pins speed to 50 MHz */ 
+  GPIOF->OSPEEDR = 0xAA800AAA;
+  /* Configure PFx pins Output type to push-pull */  
+  GPIOF->OTYPER  = 0x00000000;
+  /* No pull-up, pull-down for PFx pins */ 
+  GPIOF->PUPDR   = 0x00000000;
+
+  /* Connect PGx pins to FMC Alternate function */
+  GPIOG->AFR[0]  = 0xCCCCCCCC;
+  GPIOG->AFR[1]  = 0xCCCCCCCC;
+  /* Configure PGx pins in Alternate function mode */ 
+  GPIOG->MODER   = 0xAAAAAAAA;
+  /* Configure PGx pins speed to 50 MHz */ 
+  GPIOG->OSPEEDR = 0xAAAAAAAA;
+  /* Configure PGx pins Output type to push-pull */  
+  GPIOG->OTYPER  = 0x00000000;
+  /* No pull-up, pull-down for PGx pins */ 
+  GPIOG->PUPDR   = 0x00000000;
+  
+  /* Connect PHx pins to FMC Alternate function */
+  GPIOH->AFR[0]  = 0x00C0CC00;
+  GPIOH->AFR[1]  = 0xCCCCCCCC;
+  /* Configure PHx pins in Alternate function mode */ 
+  GPIOH->MODER   = 0xAAAA08A0;
+  /* Configure PHx pins speed to 50 MHz */ 
+  GPIOH->OSPEEDR = 0xAAAA08A0;
+  /* Configure PHx pins Output type to push-pull */  
+  GPIOH->OTYPER  = 0x00000000;
+  /* No pull-up, pull-down for PHx pins */ 
+  GPIOH->PUPDR   = 0x00000000;
+  
+  /* Connect PIx pins to FMC Alternate function */
+  GPIOI->AFR[0]  = 0xCCCCCCCC;
+  GPIOI->AFR[1]  = 0x00000CC0;
+  /* Configure PIx pins in Alternate function mode */ 
+  GPIOI->MODER   = 0x0028AAAA;
+  /* Configure PIx pins speed to 50 MHz */ 
+  GPIOI->OSPEEDR = 0x0028AAAA;
+  /* Configure PIx pins Output type to push-pull */  
+  GPIOI->OTYPER  = 0x00000000;
+  /* No pull-up, pull-down for PIx pins */ 
+  GPIOI->PUPDR   = 0x00000000;
+  
+/*-- FMC Configuration -------------------------------------------------------*/
+  /* Enable the FMC interface clock */
+  RCC->AHB3ENR |= 0x00000001;
+  /* Delay after an RCC peripheral clock enabling */
+  tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
+
+  FMC_Bank5_6->SDCR[0] = 0x000019E4;
+  FMC_Bank5_6->SDTR[0] = 0x01115351;      
+  
+  /* SDRAM initialization sequence */
+  /* Clock enable command */
+  FMC_Bank5_6->SDCMR = 0x00000011; 
+  tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
+  while((tmpreg != 0) && (timeout-- > 0))
+  {
+    tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
+  }
+
+  /* Delay */
+  for (index = 0; index<1000; index++);
+  
+  /* PALL command */
+  FMC_Bank5_6->SDCMR = 0x00000012;           
+  timeout = 0xFFFF;
+  while((tmpreg != 0) && (timeout-- > 0))
+  {
+    tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
+  }
+  
+  /* Auto refresh command */
+  FMC_Bank5_6->SDCMR = 0x00000073;
+  timeout = 0xFFFF;
+  while((tmpreg != 0) && (timeout-- > 0))
+  {
+    tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
+  }
+ 
+  /* MRD register program */
+  FMC_Bank5_6->SDCMR = 0x00046014;
+  timeout = 0xFFFF;
+  while((tmpreg != 0) && (timeout-- > 0))
+  {
+    tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
+  } 
+  
+  /* Set refresh count */
+  tmpreg = FMC_Bank5_6->SDRTR;
+  FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
+  
+  /* Disable write protection */
+  tmpreg = FMC_Bank5_6->SDCR[0]; 
+  FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
+
+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
+  /* Configure and enable Bank1_SRAM2 */
+  FMC_Bank1->BTCR[2]  = 0x00001011;
+  FMC_Bank1->BTCR[3]  = 0x00000201;
+  FMC_Bank1E->BWTR[2] = 0x0fffffff;
+#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ 
+#if defined(STM32F469xx) || defined(STM32F479xx)
+  /* Configure and enable Bank1_SRAM2 */
+  FMC_Bank1->BTCR[2]  = 0x00001091;
+  FMC_Bank1->BTCR[3]  = 0x00110212;
+  FMC_Bank1E->BWTR[2] = 0x0fffffff;
+#endif /* STM32F469xx || STM32F479xx */
+
+  (void)(tmp); 
+}
+#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
+#elif defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
+/**
+  * @brief  Setup the external memory controller.
+  *         Called in startup_stm32f4xx.s before jump to main.
+  *         This function configures the external memories (SRAM/SDRAM)
+  *         This SRAM/SDRAM will be used as program data memory (including heap and stack).
+  * @param  None
+  * @retval None
+  */
+void SystemInit_ExtMemCtl(void)
+{
+  __IO uint32_t tmp = 0x00;
+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
+ || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
+#if defined (DATA_IN_ExtSDRAM)
+  register uint32_t tmpreg = 0, timeout = 0xFFFF;
+  register __IO uint32_t index;
+
+#if defined(STM32F446xx)
+  /* Enable GPIOA, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG interface
+      clock */
+  RCC->AHB1ENR |= 0x0000007D;
+#else
+  /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface 
+      clock */
+  RCC->AHB1ENR |= 0x000001F8;
+#endif /* STM32F446xx */  
+  /* Delay after an RCC peripheral clock enabling */
+  tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
+  
+#if defined(STM32F446xx)
+  /* Connect PAx pins to FMC Alternate function */
+  GPIOA->AFR[0]  |= 0xC0000000;
+  GPIOA->AFR[1]  |= 0x00000000;
+  /* Configure PDx pins in Alternate function mode */
+  GPIOA->MODER   |= 0x00008000;
+  /* Configure PDx pins speed to 50 MHz */
+  GPIOA->OSPEEDR |= 0x00008000;
+  /* Configure PDx pins Output type to push-pull */
+  GPIOA->OTYPER  |= 0x00000000;
+  /* No pull-up, pull-down for PDx pins */
+  GPIOA->PUPDR   |= 0x00000000;
+
+  /* Connect PCx pins to FMC Alternate function */
+  GPIOC->AFR[0]  |= 0x00CC0000;
+  GPIOC->AFR[1]  |= 0x00000000;
+  /* Configure PDx pins in Alternate function mode */
+  GPIOC->MODER   |= 0x00000A00;
+  /* Configure PDx pins speed to 50 MHz */
+  GPIOC->OSPEEDR |= 0x00000A00;
+  /* Configure PDx pins Output type to push-pull */
+  GPIOC->OTYPER  |= 0x00000000;
+  /* No pull-up, pull-down for PDx pins */
+  GPIOC->PUPDR   |= 0x00000000;
+#endif /* STM32F446xx */
+
+  /* Connect PDx pins to FMC Alternate function */
+  GPIOD->AFR[0]  = 0x000000CC;
+  GPIOD->AFR[1]  = 0xCC000CCC;
+  /* Configure PDx pins in Alternate function mode */  
+  GPIOD->MODER   = 0xA02A000A;
+  /* Configure PDx pins speed to 50 MHz */  
+  GPIOD->OSPEEDR = 0xA02A000A;
+  /* Configure PDx pins Output type to push-pull */  
+  GPIOD->OTYPER  = 0x00000000;
+  /* No pull-up, pull-down for PDx pins */ 
+  GPIOD->PUPDR   = 0x00000000;
+
+  /* Connect PEx pins to FMC Alternate function */
+  GPIOE->AFR[0]  = 0xC00000CC;
+  GPIOE->AFR[1]  = 0xCCCCCCCC;
+  /* Configure PEx pins in Alternate function mode */ 
+  GPIOE->MODER   = 0xAAAA800A;
+  /* Configure PEx pins speed to 50 MHz */ 
+  GPIOE->OSPEEDR = 0xAAAA800A;
+  /* Configure PEx pins Output type to push-pull */  
+  GPIOE->OTYPER  = 0x00000000;
+  /* No pull-up, pull-down for PEx pins */ 
+  GPIOE->PUPDR   = 0x00000000;
+
+  /* Connect PFx pins to FMC Alternate function */
+  GPIOF->AFR[0]  = 0xCCCCCCCC;
+  GPIOF->AFR[1]  = 0xCCCCCCCC;
+  /* Configure PFx pins in Alternate function mode */   
+  GPIOF->MODER   = 0xAA800AAA;
+  /* Configure PFx pins speed to 50 MHz */ 
+  GPIOF->OSPEEDR = 0xAA800AAA;
+  /* Configure PFx pins Output type to push-pull */  
+  GPIOF->OTYPER  = 0x00000000;
+  /* No pull-up, pull-down for PFx pins */ 
+  GPIOF->PUPDR   = 0x00000000;
+
+  /* Connect PGx pins to FMC Alternate function */
+  GPIOG->AFR[0]  = 0xCCCCCCCC;
+  GPIOG->AFR[1]  = 0xCCCCCCCC;
+  /* Configure PGx pins in Alternate function mode */ 
+  GPIOG->MODER   = 0xAAAAAAAA;
+  /* Configure PGx pins speed to 50 MHz */ 
+  GPIOG->OSPEEDR = 0xAAAAAAAA;
+  /* Configure PGx pins Output type to push-pull */  
+  GPIOG->OTYPER  = 0x00000000;
+  /* No pull-up, pull-down for PGx pins */ 
+  GPIOG->PUPDR   = 0x00000000;
+
+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
+ || defined(STM32F469xx) || defined(STM32F479xx)  
+  /* Connect PHx pins to FMC Alternate function */
+  GPIOH->AFR[0]  = 0x00C0CC00;
+  GPIOH->AFR[1]  = 0xCCCCCCCC;
+  /* Configure PHx pins in Alternate function mode */ 
+  GPIOH->MODER   = 0xAAAA08A0;
+  /* Configure PHx pins speed to 50 MHz */ 
+  GPIOH->OSPEEDR = 0xAAAA08A0;
+  /* Configure PHx pins Output type to push-pull */  
+  GPIOH->OTYPER  = 0x00000000;
+  /* No pull-up, pull-down for PHx pins */ 
+  GPIOH->PUPDR   = 0x00000000;
+  
+  /* Connect PIx pins to FMC Alternate function */
+  GPIOI->AFR[0]  = 0xCCCCCCCC;
+  GPIOI->AFR[1]  = 0x00000CC0;
+  /* Configure PIx pins in Alternate function mode */ 
+  GPIOI->MODER   = 0x0028AAAA;
+  /* Configure PIx pins speed to 50 MHz */ 
+  GPIOI->OSPEEDR = 0x0028AAAA;
+  /* Configure PIx pins Output type to push-pull */  
+  GPIOI->OTYPER  = 0x00000000;
+  /* No pull-up, pull-down for PIx pins */ 
+  GPIOI->PUPDR   = 0x00000000;
+#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
+  
+/*-- FMC Configuration -------------------------------------------------------*/
+  /* Enable the FMC interface clock */
+  RCC->AHB3ENR |= 0x00000001;
+  /* Delay after an RCC peripheral clock enabling */
+  tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
+
+  /* Configure and enable SDRAM bank1 */
+#if defined(STM32F446xx)
+  FMC_Bank5_6->SDCR[0] = 0x00001954;
+#else  
+  FMC_Bank5_6->SDCR[0] = 0x000019E4;
+#endif /* STM32F446xx */
+  FMC_Bank5_6->SDTR[0] = 0x01115351;      
+  
+  /* SDRAM initialization sequence */
+  /* Clock enable command */
+  FMC_Bank5_6->SDCMR = 0x00000011; 
+  tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
+  while((tmpreg != 0) && (timeout-- > 0))
+  {
+    tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
+  }
+
+  /* Delay */
+  for (index = 0; index<1000; index++);
+  
+  /* PALL command */
+  FMC_Bank5_6->SDCMR = 0x00000012;           
+  timeout = 0xFFFF;
+  while((tmpreg != 0) && (timeout-- > 0))
+  {
+    tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
+  }
+  
+  /* Auto refresh command */
+#if defined(STM32F446xx)
+  FMC_Bank5_6->SDCMR = 0x000000F3;
+#else  
+  FMC_Bank5_6->SDCMR = 0x00000073;
+#endif /* STM32F446xx */
+  timeout = 0xFFFF;
+  while((tmpreg != 0) && (timeout-- > 0))
+  {
+    tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
+  }
+ 
+  /* MRD register program */
+#if defined(STM32F446xx)
+  FMC_Bank5_6->SDCMR = 0x00044014;
+#else  
+  FMC_Bank5_6->SDCMR = 0x00046014;
+#endif /* STM32F446xx */
+  timeout = 0xFFFF;
+  while((tmpreg != 0) && (timeout-- > 0))
+  {
+    tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
+  } 
+  
+  /* Set refresh count */
+  tmpreg = FMC_Bank5_6->SDRTR;
+#if defined(STM32F446xx)
+  FMC_Bank5_6->SDRTR = (tmpreg | (0x0000050C<<1));
+#else    
+  FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
+#endif /* STM32F446xx */
+  
+  /* Disable write protection */
+  tmpreg = FMC_Bank5_6->SDCR[0]; 
+  FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
+#endif /* DATA_IN_ExtSDRAM */
+#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */
+
+#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\
+ || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
+ || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
+
+#if defined(DATA_IN_ExtSRAM)
+/*-- GPIOs Configuration -----------------------------------------------------*/
+   /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
+  RCC->AHB1ENR   |= 0x00000078;
+  /* Delay after an RCC peripheral clock enabling */
+  tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);
+  
+  /* Connect PDx pins to FMC Alternate function */
+  GPIOD->AFR[0]  = 0x00CCC0CC;
+  GPIOD->AFR[1]  = 0xCCCCCCCC;
+  /* Configure PDx pins in Alternate function mode */  
+  GPIOD->MODER   = 0xAAAA0A8A;
+  /* Configure PDx pins speed to 100 MHz */  
+  GPIOD->OSPEEDR = 0xFFFF0FCF;
+  /* Configure PDx pins Output type to push-pull */  
+  GPIOD->OTYPER  = 0x00000000;
+  /* No pull-up, pull-down for PDx pins */ 
+  GPIOD->PUPDR   = 0x00000000;
+
+  /* Connect PEx pins to FMC Alternate function */
+  GPIOE->AFR[0]  = 0xC00CC0CC;
+  GPIOE->AFR[1]  = 0xCCCCCCCC;
+  /* Configure PEx pins in Alternate function mode */ 
+  GPIOE->MODER   = 0xAAAA828A;
+  /* Configure PEx pins speed to 100 MHz */ 
+  GPIOE->OSPEEDR = 0xFFFFC3CF;
+  /* Configure PEx pins Output type to push-pull */  
+  GPIOE->OTYPER  = 0x00000000;
+  /* No pull-up, pull-down for PEx pins */ 
+  GPIOE->PUPDR   = 0x00000000;
+
+  /* Connect PFx pins to FMC Alternate function */
+  GPIOF->AFR[0]  = 0x00CCCCCC;
+  GPIOF->AFR[1]  = 0xCCCC0000;
+  /* Configure PFx pins in Alternate function mode */   
+  GPIOF->MODER   = 0xAA000AAA;
+  /* Configure PFx pins speed to 100 MHz */ 
+  GPIOF->OSPEEDR = 0xFF000FFF;
+  /* Configure PFx pins Output type to push-pull */  
+  GPIOF->OTYPER  = 0x00000000;
+  /* No pull-up, pull-down for PFx pins */ 
+  GPIOF->PUPDR   = 0x00000000;
+
+  /* Connect PGx pins to FMC Alternate function */
+  GPIOG->AFR[0]  = 0x00CCCCCC;
+  GPIOG->AFR[1]  = 0x000000C0;
+  /* Configure PGx pins in Alternate function mode */ 
+  GPIOG->MODER   = 0x00085AAA;
+  /* Configure PGx pins speed to 100 MHz */ 
+  GPIOG->OSPEEDR = 0x000CAFFF;
+  /* Configure PGx pins Output type to push-pull */  
+  GPIOG->OTYPER  = 0x00000000;
+  /* No pull-up, pull-down for PGx pins */ 
+  GPIOG->PUPDR   = 0x00000000;
+  
+/*-- FMC/FSMC Configuration --------------------------------------------------*/
+  /* Enable the FMC/FSMC interface clock */
+  RCC->AHB3ENR         |= 0x00000001;
+
+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
+  /* Delay after an RCC peripheral clock enabling */
+  tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
+  /* Configure and enable Bank1_SRAM2 */
+  FMC_Bank1->BTCR[2]  = 0x00001011;
+  FMC_Bank1->BTCR[3]  = 0x00000201;
+  FMC_Bank1E->BWTR[2] = 0x0fffffff;
+#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ 
+#if defined(STM32F469xx) || defined(STM32F479xx)
+  /* Delay after an RCC peripheral clock enabling */
+  tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
+  /* Configure and enable Bank1_SRAM2 */
+  FMC_Bank1->BTCR[2]  = 0x00001091;
+  FMC_Bank1->BTCR[3]  = 0x00110212;
+  FMC_Bank1E->BWTR[2] = 0x0fffffff;
+#endif /* STM32F469xx || STM32F479xx */
+#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx)\
+   || defined(STM32F412Zx) || defined(STM32F412Vx)
+  /* Delay after an RCC peripheral clock enabling */
+  tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN);
+  /* Configure and enable Bank1_SRAM2 */
+  FSMC_Bank1->BTCR[2]  = 0x00001011;
+  FSMC_Bank1->BTCR[3]  = 0x00000201;
+  FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF;
+#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F412Zx || STM32F412Vx */
+
+#endif /* DATA_IN_ExtSRAM */
+#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\
+          STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx  */ 
+  (void)(tmp); 
+}
+#endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/system_stm32l0xx.c	Mon Nov 12 18:36:18 2018 +0000
@@ -0,0 +1,285 @@
+/**
+  ******************************************************************************
+  * @file    system_stm32l0xx.c
+  * @author  MCD Application Team
+  * @brief   CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File.
+  *
+  *   This file provides two functions and one global variable to be called from 
+  *   user application:
+  *      - SystemInit(): This function is called at startup just after reset and 
+  *                      before branch to main program. This call is made inside
+  *                      the "startup_stm32l0xx.s" file.
+  *
+  *      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+  *                                  by the user application to setup the SysTick 
+  *                                  timer or configure other parameters.
+  *                                     
+  *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+  *                                 be called whenever the core clock is changed
+  *                                 during program execution.
+  *
+  *
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/** @addtogroup CMSIS
+  * @{
+  */
+
+/** @addtogroup stm32l0xx_system
+  * @{
+  */  
+  
+/** @addtogroup STM32L0xx_System_Private_Includes
+  * @{
+  */
+
+#include "stm32l0xx.h"
+
+#if !defined  (HSE_VALUE) 
+  #define HSE_VALUE    ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined  (MSI_VALUE)
+  #define MSI_VALUE    ((uint32_t)2000000U) /*!< Value of the Internal oscillator in Hz*/
+#endif /* MSI_VALUE */
+   
+#if !defined  (HSI_VALUE)
+  #define HSI_VALUE    ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L0xx_System_Private_TypesDefinitions
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L0xx_System_Private_Defines
+  * @{
+  */
+/************************* Miscellaneous Configuration ************************/
+
+/*!< Uncomment the following line if you need to relocate your vector Table in
+     Internal SRAM. */
+/* #define VECT_TAB_SRAM */
+#define VECT_TAB_OFFSET  0x00U /*!< Vector Table base offset field. 
+                                   This value must be a multiple of 0x200. */
+/******************************************************************************/
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L0xx_System_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L0xx_System_Private_Variables
+  * @{
+  */
+  /* This variable is updated in three ways:
+      1) by calling CMSIS function SystemCoreClockUpdate()
+      2) by calling HAL API function HAL_RCC_GetHCLKFreq()
+      3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency 
+         Note: If you use this function to configure the system clock; then there
+               is no need to call the 2 first functions listed above, since SystemCoreClock
+               variable is updated automatically.
+  */
+  uint32_t SystemCoreClock = 2000000U;
+  const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
+  const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
+  const uint8_t PLLMulTable[9] = {3U, 4U, 6U, 8U, 12U, 16U, 24U, 32U, 48U};
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L0xx_System_Private_FunctionPrototypes
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L0xx_System_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Setup the microcontroller system.
+  * @param  None
+  * @retval None
+  */
+void SystemInit (void)
+{    
+/*!< Set MSION bit */
+  RCC->CR |= (uint32_t)0x00000100U;
+
+  /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */
+  RCC->CFGR &= (uint32_t) 0x88FF400CU;
+ 
+  /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */
+  RCC->CR &= (uint32_t)0xFEF6FFF6U;
+  
+  /*!< Reset HSI48ON  bit */
+  RCC->CRRCR &= (uint32_t)0xFFFFFFFEU;
+  
+  /*!< Reset HSEBYP bit */
+  RCC->CR &= (uint32_t)0xFFFBFFFFU;
+
+  /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */
+  RCC->CFGR &= (uint32_t)0xFF02FFFFU;
+
+  /*!< Disable all interrupts */
+  RCC->CIER = 0x00000000U;
+  
+  /* Configure the Vector Table location add offset address ------------------*/
+#ifdef VECT_TAB_SRAM
+  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
+#else
+  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
+#endif
+}
+
+/**
+  * @brief  Update SystemCoreClock according to Clock Register Values
+  *         The SystemCoreClock variable contains the core clock (HCLK), it can
+  *         be used by the user application to setup the SysTick timer or configure
+  *         other parameters.
+  *           
+  * @note   Each time the core clock (HCLK) changes, this function must be called
+  *         to update SystemCoreClock variable value. Otherwise, any configuration
+  *         based on this variable will be incorrect.         
+  *     
+  * @note   - The system frequency computed by this function is not the real 
+  *           frequency in the chip. It is calculated based on the predefined 
+  *           constant and the selected clock source:
+  *             
+  *           - If SYSCLK source is MSI, SystemCoreClock will contain the MSI 
+  *             value as defined by the MSI range.
+  *                                   
+  *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
+  *                                              
+  *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
+  *                          
+  *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
+  *             or HSI_VALUE(*) multiplied/divided by the PLL factors.
+  *         
+  *         (*) HSI_VALUE is a constant defined in stm32l0xx_hal.h file (default value
+  *             16 MHz) but the real value may vary depending on the variations
+  *             in voltage and temperature.   
+  *    
+  *         (**) HSE_VALUE is a constant defined in stm32l0xx_hal.h file (default value
+  *              8 MHz), user has to ensure that HSE_VALUE is same as the real
+  *              frequency of the crystal used. Otherwise, this function may
+  *              have wrong result.
+  *                
+  *         - The result of this function could be not correct when using fractional
+  *           value for HSE crystal.
+  * @param  None
+  * @retval None
+  */
+void SystemCoreClockUpdate (void)
+{
+  uint32_t tmp = 0U, pllmul = 0U, plldiv = 0U, pllsource = 0U, msirange = 0U;
+
+  /* Get SYSCLK source -------------------------------------------------------*/
+  tmp = RCC->CFGR & RCC_CFGR_SWS;
+  
+  switch (tmp)
+  {
+    case 0x00U:  /* MSI used as system clock */
+      msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13U;
+      SystemCoreClock = (32768U * (1U << (msirange + 1U)));
+      break;
+    case 0x04U:  /* HSI used as system clock */
+      SystemCoreClock = HSI_VALUE;
+      break;
+    case 0x08U:  /* HSE used as system clock */
+      SystemCoreClock = HSE_VALUE;
+      break;
+    case 0x0CU:  /* PLL used as system clock */
+      /* Get PLL clock source and multiplication factor ----------------------*/
+      pllmul = RCC->CFGR & RCC_CFGR_PLLMUL;
+      plldiv = RCC->CFGR & RCC_CFGR_PLLDIV;
+      pllmul = PLLMulTable[(pllmul >> 18U)];
+      plldiv = (plldiv >> 22U) + 1U;
+      
+      pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
+
+      if (pllsource == 0x00U)
+      {
+        /* HSI oscillator clock selected as PLL clock entry */
+        SystemCoreClock = (((HSI_VALUE) * pllmul) / plldiv);
+      }
+      else
+      {
+        /* HSE selected as PLL clock entry */
+        SystemCoreClock = (((HSE_VALUE) * pllmul) / plldiv);
+      }
+      break;
+    default: /* MSI used as system clock */
+      msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13U;
+      SystemCoreClock = (32768U * (1U << (msirange + 1U)));
+      break;
+  }
+  /* Compute HCLK clock frequency --------------------------------------------*/
+  /* Get HCLK prescaler */
+  tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
+  /* HCLK clock frequency */
+  SystemCoreClock >>= tmp;
+}
+
+
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/system_stm32l4xx.c	Mon Nov 12 18:36:18 2018 +0000
@@ -0,0 +1,353 @@
+/**
+  ******************************************************************************
+  * @file    system_stm32l4xx.c
+  * @author  MCD Application Team
+  * @brief   CMSIS Cortex-M4 Device Peripheral Access Layer System Source File
+  *
+  *   This file provides two functions and one global variable to be called from
+  *   user application:
+  *      - SystemInit(): This function is called at startup just after reset and
+  *                      before branch to main program. This call is made inside
+  *                      the "startup_stm32l4xx.s" file.
+  *
+  *      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+  *                                  by the user application to setup the SysTick
+  *                                  timer or configure other parameters.
+  *
+  *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+  *                                 be called whenever the core clock is changed
+  *                                 during program execution.
+  *
+  *   After each device reset the MSI (4 MHz) is used as system clock source.
+  *   Then SystemInit() function is called, in "startup_stm32l4xx.s" file, to
+  *   configure the system clock before to branch to main program.
+  *
+  *   This file configures the system clock as follows:
+  *=============================================================================
+  *-----------------------------------------------------------------------------
+  *        System Clock source                    | MSI
+  *-----------------------------------------------------------------------------
+  *        SYSCLK(Hz)                             | 4000000
+  *-----------------------------------------------------------------------------
+  *        HCLK(Hz)                               | 4000000
+  *-----------------------------------------------------------------------------
+  *        AHB Prescaler                          | 1
+  *-----------------------------------------------------------------------------
+  *        APB1 Prescaler                         | 1
+  *-----------------------------------------------------------------------------
+  *        APB2 Prescaler                         | 1
+  *-----------------------------------------------------------------------------
+  *        PLL_M                                  | 1
+  *-----------------------------------------------------------------------------
+  *        PLL_N                                  | 8
+  *-----------------------------------------------------------------------------
+  *        PLL_P                                  | 7
+  *-----------------------------------------------------------------------------
+  *        PLL_Q                                  | 2
+  *-----------------------------------------------------------------------------
+  *        PLL_R                                  | 2
+  *-----------------------------------------------------------------------------
+  *        PLLSAI1_P                              | NA
+  *-----------------------------------------------------------------------------
+  *        PLLSAI1_Q                              | NA
+  *-----------------------------------------------------------------------------
+  *        PLLSAI1_R                              | NA
+  *-----------------------------------------------------------------------------
+  *        PLLSAI2_P                              | NA
+  *-----------------------------------------------------------------------------
+  *        PLLSAI2_Q                              | NA
+  *-----------------------------------------------------------------------------
+  *        PLLSAI2_R                              | NA
+  *-----------------------------------------------------------------------------
+  *        Require 48MHz for USB OTG FS,          | Disabled
+  *        SDIO and RNG clock                     |
+  *-----------------------------------------------------------------------------
+  *=============================================================================
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/** @addtogroup CMSIS
+  * @{
+  */
+
+/** @addtogroup stm32l4xx_system
+  * @{
+  */
+
+/** @addtogroup STM32L4xx_System_Private_Includes
+  * @{
+  */
+
+#include "stm32l4xx.h"
+
+#if !defined  (HSE_VALUE)
+  #define HSE_VALUE    8000000U  /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined  (MSI_VALUE)
+  #define MSI_VALUE    4000000U  /*!< Value of the Internal oscillator in Hz*/
+#endif /* MSI_VALUE */
+
+#if !defined  (HSI_VALUE)
+  #define HSI_VALUE    16000000U /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L4xx_System_Private_TypesDefinitions
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L4xx_System_Private_Defines
+  * @{
+  */
+
+/************************* Miscellaneous Configuration ************************/
+/*!< Uncomment the following line if you need to relocate your vector Table in
+     Internal SRAM. */
+/* #define VECT_TAB_SRAM */
+#define VECT_TAB_OFFSET  0x00 /*!< Vector Table base offset field.
+                                   This value must be a multiple of 0x200. */
+/******************************************************************************/
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L4xx_System_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L4xx_System_Private_Variables
+  * @{
+  */
+  /* The SystemCoreClock variable is updated in three ways:
+      1) by calling CMSIS function SystemCoreClockUpdate()
+      2) by calling HAL API function HAL_RCC_GetHCLKFreq()
+      3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
+         Note: If you use this function to configure the system clock; then there
+               is no need to call the 2 first functions listed above, since SystemCoreClock
+               variable is updated automatically.
+  */
+  uint32_t SystemCoreClock = 4000000U;
+
+  const uint8_t  AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
+  const uint8_t  APBPrescTable[8] =  {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
+  const uint32_t MSIRangeTable[12] = {100000U,   200000U,   400000U,   800000U,  1000000U,  2000000U, \
+                                      4000000U, 8000000U, 16000000U, 24000000U, 32000000U, 48000000U};
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L4xx_System_Private_FunctionPrototypes
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L4xx_System_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Setup the microcontroller system.
+  * @param  None
+  * @retval None
+  */
+
+void SystemInit(void)
+{
+  /* FPU settings ------------------------------------------------------------*/
+  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
+  #endif
+
+  /* Reset the RCC clock configuration to the default reset state ------------*/
+  /* Set MSION bit */
+  RCC->CR |= RCC_CR_MSION;
+
+  /* Reset CFGR register */
+  RCC->CFGR = 0x00000000U;
+
+  /* Reset HSEON, CSSON , HSION, and PLLON bits */
+  RCC->CR &= 0xEAF6FFFFU;
+
+  /* Reset PLLCFGR register */
+  RCC->PLLCFGR = 0x00001000U;
+
+  /* Reset HSEBYP bit */
+  RCC->CR &= 0xFFFBFFFFU;
+
+  /* Disable all interrupts */
+  RCC->CIER = 0x00000000U;
+
+  /* Configure the Vector Table location add offset address ------------------*/
+#ifdef VECT_TAB_SRAM
+  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
+#else
+  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
+#endif
+}
+
+/**
+  * @brief  Update SystemCoreClock variable according to Clock Register Values.
+  *         The SystemCoreClock variable contains the core clock (HCLK), it can
+  *         be used by the user application to setup the SysTick timer or configure
+  *         other parameters.
+  *
+  * @note   Each time the core clock (HCLK) changes, this function must be called
+  *         to update SystemCoreClock variable value. Otherwise, any configuration
+  *         based on this variable will be incorrect.
+  *
+  * @note   - The system frequency computed by this function is not the real
+  *           frequency in the chip. It is calculated based on the predefined
+  *           constant and the selected clock source:
+  *
+  *           - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*)
+  *
+  *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
+  *
+  *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
+  *
+  *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
+  *             or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors.
+  *
+  *         (*) MSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value
+  *             4 MHz) but the real value may vary depending on the variations
+  *             in voltage and temperature.
+  *
+  *         (**) HSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value
+  *              16 MHz) but the real value may vary depending on the variations
+  *              in voltage and temperature.
+  *
+  *         (***) HSE_VALUE is a constant defined in stm32l4xx_hal.h file (default value
+  *              8 MHz), user has to ensure that HSE_VALUE is same as the real
+  *              frequency of the crystal used. Otherwise, this function may
+  *              have wrong result.
+  *
+  *         - The result of this function could be not correct when using fractional
+  *           value for HSE crystal.
+  *
+  * @param  None
+  * @retval None
+  */
+void SystemCoreClockUpdate(void)
+{
+  uint32_t tmp = 0U, msirange = 0U, pllvco = 0U, pllr = 2U, pllsource = 0U, pllm = 2U;
+
+  /* Get MSI Range frequency--------------------------------------------------*/
+  if((RCC->CR & RCC_CR_MSIRGSEL) == RESET)
+  { /* MSISRANGE from RCC_CSR applies */
+    msirange = (RCC->CSR & RCC_CSR_MSISRANGE) >> 8U;
+  }
+  else
+  { /* MSIRANGE from RCC_CR applies */
+    msirange = (RCC->CR & RCC_CR_MSIRANGE) >> 4U;
+  }
+  /*MSI frequency range in HZ*/
+  msirange = MSIRangeTable[msirange];
+
+  /* Get SYSCLK source -------------------------------------------------------*/
+  switch (RCC->CFGR & RCC_CFGR_SWS)
+  {
+    case 0x00:  /* MSI used as system clock source */
+      SystemCoreClock = msirange;
+      break;
+
+    case 0x04:  /* HSI used as system clock source */
+      SystemCoreClock = HSI_VALUE;
+      break;
+
+    case 0x08:  /* HSE used as system clock source */
+      SystemCoreClock = HSE_VALUE;
+      break;
+
+    case 0x0C:  /* PLL used as system clock  source */
+      /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
+         SYSCLK = PLL_VCO / PLLR
+         */
+      pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
+      pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> 4U) + 1U ;
+
+      switch (pllsource)
+      {
+        case 0x02:  /* HSI used as PLL clock source */
+          pllvco = (HSI_VALUE / pllm);
+          break;
+
+        case 0x03:  /* HSE used as PLL clock source */
+          pllvco = (HSE_VALUE / pllm);
+          break;
+
+        default:    /* MSI used as PLL clock source */
+          pllvco = (msirange / pllm);
+          break;
+      }
+      pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8U);
+      pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25U) + 1U) * 2U;
+      SystemCoreClock = pllvco/pllr;
+      break;
+
+    default:
+      SystemCoreClock = msirange;
+      break;
+  }
+  /* Compute HCLK clock frequency --------------------------------------------*/
+  /* Get HCLK prescaler */
+  tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
+  /* HCLK clock frequency */
+  SystemCoreClock >>= tmp;
+}
+
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/