AudioRecord and FFT/MSE comparison. Call AudioRecord_demo for control record and AudioSample for subsequent recordings.

Dependencies:   CMSIS_DSP_401 STM32L4xx_HAL_Driver

Fork of OneHopeOnePrayer by Senior Design: Sound Monitor

Files at this revision

API Documentation at this revision

Comitter:
EricLew
Date:
Sat Dec 05 16:17:25 2015 +0000
Parent:
4:652cb54276d0
Commit message:
Ported to Nucleo

Changed in this revision

Main.c Show annotated file Show diff for this revision Revisions of this file
audio_record.c Show annotated file Show diff for this revision Revisions of this file
main.h Show annotated file Show diff for this revision Revisions of this file
stm32l476g_discovery.c Show diff for this revision Revisions of this file
stm32l476g_discovery.h Show diff for this revision Revisions of this file
stm32l476g_discovery_audio.c Show diff for this revision Revisions of this file
stm32l476g_discovery_audio.h Show diff for this revision Revisions of this file
stm32l476g_discovery_glass_lcd.c Show diff for this revision Revisions of this file
stm32l476g_discovery_glass_lcd.h Show diff for this revision Revisions of this file
stm32l476g_discovery_qspi.h Show diff for this revision Revisions of this file
stm32l4xx_nucleo.c Show annotated file Show diff for this revision Revisions of this file
stm32l4xx_nucleo.h Show annotated file Show diff for this revision Revisions of this file
stm32l4xx_nucleo_audio.c Show annotated file Show diff for this revision Revisions of this file
stm32l4xx_nucleo_audio.h Show annotated file Show diff for this revision Revisions of this file
--- a/Main.c	Thu Dec 03 22:16:32 2015 +0000
+++ b/Main.c	Sat Dec 05 16:17:25 2015 +0000
@@ -2,7 +2,7 @@
 
 uint32_t fftSize = 2048;
 uint32_t ifftFlag = 0;
-uint32_t doBitReverse = 1;
+uint32_t doBitReverse = 0;
 
 extern float32_t PWRCONTROLMSE; //CONTROL POWER MSE
 extern float32_t PHSCONTROLMSE; //CONTROL PHASE MSE 
--- a/audio_record.c	Thu Dec 03 22:16:32 2015 +0000
+++ b/audio_record.c	Sat Dec 05 16:17:25 2015 +0000
@@ -116,9 +116,9 @@
 
     //PERFORMS THE FFT
         //RECORDING 0
-            arm_cfft_f32(S, FloatBuffout0, 0,1); //Output of FFT is half the record buffer size
+            arm_cfft_f32(S, FloatBuffout0, 0,0); //Output of FFT is half the record buffer size
         //RECORDING 1
-            arm_cfft_f32(S, FloatBuffout1, 0,1);
+            arm_cfft_f32(S, FloatBuffout1, 0,0);
     
             //FloatBuffout0[0]=0;
             //FloatBuffout1[0]=0;
@@ -196,7 +196,7 @@
   while (EXIT != SET)
   {
         
-        if (counter==15000000) //Approximately 3 seconds of record time
+        if (counter==10000000) //Approximately 3 seconds of record time
         {
             EXIT=1;   //FLAG IS REGISTER R5
         }
@@ -224,7 +224,7 @@
              FloatBuffSAMPLEout[(n*2)+1] = 0.0;}
         
     //PERFORMS THE 
-        arm_cfft_f32(S, FloatBuffSAMPLEout, 0,1); //Output of FFT is half the record buffer size
+        arm_cfft_f32(S, FloatBuffSAMPLEout, 0,0); //Output of FFT is half the record buffer size
         //FloatBuffSAMPLEout[0]=0;
     //MSE FUNCTION
     //SEPARATES REAL AND IMAGINARY PARTS
@@ -268,24 +268,30 @@
             {SAMPLEPHASEMSE=SAMPLEPHASEMSE+compare[n];} //Takes the mean of the error, stores MSE in CONTROLMSE
             SAMPLEPHASEMSE=SAMPLEPHASEMSE/1024.0f;  
     
-    float32_t TEST[6];
+                float32_t TEST[6];
             TEST[0]=PWRCONTROLMSE;
             TEST[1]=PHSCONTROLMSE;
             TEST[2]=SAMPLEPHASEMSE;
             TEST[3]=SAMPLEPWRMSE;
             TEST[4]=(SAMPLEPWRMSE/PWRCONTROLMSE); //The ratio of sample MSE and control MSE
             TEST[5]=(SAMPLEPHASEMSE/PHSCONTROLMSE);
-            
-    //COMPARISON
-        //if(SAMPLEPHASEMSE>(10*PHSCONTROLMSE))////IMPLEMENT ABSOLUTE VALUE FUNCTION FOR DIFFERENCE!!!!!
-            //{
-                //SEND ERROR MESSAGE
-                //CREATE EVENT
-            //}
-        if(20 < TEST[4] && TEST[4] < .01)//MODEM FUNCTIONS
-            {
-                //SEND ERROR MESSAGE
-                //CREATE EVENT
-            }
-        
+                        float32_t low=.001; //LOW END OF ACCEPTED TOLERANCE RANGE
+                        float32_t high=20;  //HIGH END OF ACCEPTED TOLERANCE RANGE
+                        
+                //COMPARISON
+                    //if(SAMPLEPHASEMSE>(10*PHSCONTROLMSE))
+                        //{
+                            //SEND ERROR MESSAGE
+                            //CREATE EVENT
+                        //}
+                    if(TEST[4]>high)//MODEM FUNCTIONS
+                        {
+                            //SEND ERROR MESSAGE
+                            //CREATE EVENT
+                        }
+                    if(TEST[4] < low)
+                        {   
+                            //SEND ERROR MESSAGE
+                            //CREATE EVENT
+                        }
 }
--- a/main.h	Thu Dec 03 22:16:32 2015 +0000
+++ b/main.h	Sat Dec 05 16:17:25 2015 +0000
@@ -43,7 +43,7 @@
 #include "stdio.h"
 #include "string.h"
 #include "stm32l4xx_hal.h"
-#include "stm32l476g_discovery.h"
+#include "stm32l4xx_nucleo.h"
 
 #include "arm_math.h"
 #include "arm_const_structs.h"
@@ -54,9 +54,7 @@
 #include "core_cmInstr.h"
 #include "stdint.h"
 
-#include "stm32l476g_discovery_glass_lcd.h"
-#include "stm32l476g_discovery_audio.h"
-#include "stm32l476g_discovery_qspi.h"
+#include "stm32l4xx_nucleo_audio.h"
 
 /* Exported constants --------------------------------------------------------*/
 #define DEMO_NAME_CHAR_NB         20
--- a/stm32l476g_discovery.c	Thu Dec 03 22:16:32 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1771 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32l476g_discovery.c
-  * @author  MCD Application Team
-  * @version V1.0.1
-  * @date    16-September-2015
-  * @brief   This file provides a set of firmware functions to manage Leds, 
-  *          push-button and joystick of STM32L476G-Discovery board (MB1184)
-  ******************************************************************************
-  * @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 "stm32l476g_discovery.h"
-
-/** @addtogroup BSP
-  * @{
-  */
-
-/** @defgroup STM32L476G_DISCOVERY STM32L476G-DISCOVERY
-  * @{
-  */
-
-/** @defgroup STM32L476G_DISCOVERY_Common STM32L476G-DISCOVERY Common
-  * @{
-  */
-
-/** @defgroup STM32L476G_DISCOVERY_Private_TypesDefinitions Private Types Definitions
-  * @brief This file provides firmware functions to manage Leds, push-buttons, 
-  *        COM ports, SD card on SPI and temperature sensor (TS751) available on 
-  *        STM32L476G-DISCOVERY discoveryuation board from STMicroelectronics.
-  * @{
-  */
-
-/**
-  * @}
-  */
-
-/** @defgroup STM32L476G_DISCOVERY_Private_Defines Private Defines
-  * @{
-  */
-
-/**
- * @brief STM32L476G DISCOVERY BSP Driver version number V1.0.1
-   */
-#define __STM32L476G_DISCOVERY_BSP_VERSION_MAIN       (0x01) /*!< [31:24] main version */
-#define __STM32L476G_DISCOVERY_BSP_VERSION_SUB1       (0x00) /*!< [23:16] sub1 version */
-#define __STM32L476G_DISCOVERY_BSP_VERSION_SUB2       (0x01) /*!< [15:8]  sub2 version */
-#define __STM32L476G_DISCOVERY_BSP_VERSION_RC         (0x00) /*!< [7:0]  release candidate */
-#define __STM32L476G_DISCOVERY_BSP_VERSION            ((__STM32L476G_DISCOVERY_BSP_VERSION_MAIN << 24)\
-                                                      |(__STM32L476G_DISCOVERY_BSP_VERSION_SUB1 << 16)\
-                                                      |(__STM32L476G_DISCOVERY_BSP_VERSION_SUB2 << 8 )\
-                                                      |(__STM32L476G_DISCOVERY_BSP_VERSION_RC))
-/**
-  * @}
-  */
-
-
-/** @defgroup STM32L476G_DISCOVERY_Private_Macros Private Macros
-  * @{
-  */
-
-/**
-  * @}
-  */
-
-
-/** @defgroup STM32L476G_DISCOVERY_Exported_Variables Exported Variables
-  * @{
-  */
-
-/**
- * @brief LED variables
- */
-#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB)
-GPIO_TypeDef*   LED_PORT[LEDn] =  {LED4_GPIO_PORT,
-                                  LED5_GPIO_PORT};
-
-const uint16_t  LED_PIN[LEDn] =   {LED4_PIN,
-                                  LED5_PIN};
-#elif defined (USE_STM32L476G_DISCO_REVA)
-GPIO_TypeDef*   LED_PORT[LEDn] =  {LED3_GPIO_PORT,
-                                  LED4_GPIO_PORT};
-
-const uint16_t  LED_PIN[LEDn] =   {LED3_PIN,
-                                  LED4_PIN};
-#endif
-
-
-/**
- * @brief JOYSTICK variables
- */
- GPIO_TypeDef* JOY_PORT[JOYn] =  {SEL_JOY_GPIO_PORT,
-                                  DOWN_JOY_GPIO_PORT,
-                                  LEFT_JOY_GPIO_PORT,
-                                  RIGHT_JOY_GPIO_PORT,
-                                  UP_JOY_GPIO_PORT};
-
-const uint16_t JOY_PIN[JOYn] =   {SEL_JOY_PIN,
-                                  LEFT_JOY_PIN,
-                                  RIGHT_JOY_PIN,
-                                  DOWN_JOY_PIN,
-                                  UP_JOY_PIN};
-
-const uint8_t JOY_IRQn[JOYn] =   {SEL_JOY_EXTI_IRQn,
-                                  LEFT_JOY_EXTI_IRQn,
-                                  RIGHT_JOY_EXTI_IRQn,
-                                  DOWN_JOY_EXTI_IRQn,
-                                  UP_JOY_EXTI_IRQn};
-
-/**
- * @brief BUS variables
- */
-#if defined(HAL_I2C_MODULE_ENABLED)
-uint32_t I2c1Timeout = DISCOVERY_I2C2_TIMEOUT_MAX;  /*<! Value of Timeout when I2C1 communication fails */
-uint32_t I2c2Timeout = DISCOVERY_I2C2_TIMEOUT_MAX;  /*<! Value of Timeout when I2C2 communication fails */
-static I2C_HandleTypeDef I2c1Handle;
-static I2C_HandleTypeDef I2c2Handle;
-#endif /* HAL_I2C_MODULE_ENABLED */
-
-#if defined(HAL_SPI_MODULE_ENABLED)
-
-/* LL definition */
-#define __SPI_DIRECTION_2LINES(__HANDLE__)   do{\
-                                             CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_RXONLY | SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE);\
-                                             }while(0);
-
-#define __SPI_DIRECTION_2LINES_RXONLY(__HANDLE__)   do{\
-                                                   CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_RXONLY | SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE);\
-                                                   SET_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_RXONLY);\
-                                                   }while(0);
-
-#define __SPI_DIRECTION_1LINE_TX(__HANDLE__) do{\
-                                             CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_RXONLY | SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE);\
-                                             SET_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE);\
-                                             }while(0);
-
-#define __SPI_DIRECTION_1LINE_RX(__HANDLE__) do {\
-                                             CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_RXONLY | SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE);\
-                                             SET_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_BIDIMODE);\
-                                             } while(0);
-
-
-uint32_t SpixTimeout = SPIx_TIMEOUT_MAX;            /*<! Value of Timeout when SPI communication fails */
-static SPI_HandleTypeDef SpiHandle;
-#endif /* HAL_SPI_MODULE_ENABLED */
-
-/**
-  * @}
-  */
-
-/** @defgroup STM32L476G_DISCOVERY_Private_FunctionPrototypes Private Functions
-  * @{
-  */
-/**************************** Bus functions ************************************/
-/* I2C2 bus function */
-#if defined(HAL_I2C_MODULE_ENABLED)
-static void               I2C2_Init(void);
-static void               I2C2_MspInit(I2C_HandleTypeDef *hi2c);
-static void               I2C2_DeInit(void);
-static void               I2C2_MspDeInit(I2C_HandleTypeDef *hi2c);
-static void               I2C2_WriteData(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t Value);
-static HAL_StatusTypeDef  I2C2_WriteBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length);
-static uint8_t            I2C2_ReadData(uint16_t Addr, uint16_t Reg, uint16_t RegSize);
-static HAL_StatusTypeDef  I2C2_ReadBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length);
-static void               I2C2_Error (void);
-
-static void               I2C1_Init(void);
-static void               I2C1_MspInit(I2C_HandleTypeDef *hi2c);
-static void               I2C1_DeInit(void);
-static void               I2C1_MspDeInit(I2C_HandleTypeDef *hi2c);
-static HAL_StatusTypeDef  I2C1_WriteBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length);
-static HAL_StatusTypeDef  I2C1_ReadBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length);
-static void               I2C1_Error (void);
-#endif/* HAL_I2C_MODULE_ENABLED */
-
-/* SPIx bus function */
-#if defined(HAL_SPI_MODULE_ENABLED)
-static void               SPIx_Init(void);
-static void               SPIx_MspInit(SPI_HandleTypeDef *hspi);
-static void               SPIx_DeInit(void);
-static void               SPIx_MspDeInit(void);
-static uint8_t            SPIx_WriteRead(uint8_t Byte);
-static void               SPIx_Write(uint8_t byte);
-static uint8_t            SPIx_Read(void);
-#endif
-
-/**************************** Link functions ***********************************/
-#if defined(HAL_I2C_MODULE_ENABLED)
-/* Link functions for EEPROM peripheral over I2C */
-void                      EEPROM_I2C_IO_Init(void);
-HAL_StatusTypeDef         EEPROM_I2C_IO_WriteData(uint16_t DevAddress, uint16_t MemAddress, uint8_t* pBuffer, uint32_t BufferSize);
-HAL_StatusTypeDef         EEPROM_I2C_IO_ReadData(uint16_t DevAddress, uint16_t MemAddress, uint8_t* pBuffer, uint32_t BufferSize);
-HAL_StatusTypeDef         EEPROM_I2C_IO_IsDeviceReady(uint16_t DevAddress, uint32_t Trials);
-
-/* Link functions for Audio Codec peripheral */
-void                      AUDIO_IO_Init(void);
-void                      AUDIO_IO_DeInit(void);
-void                      AUDIO_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value);
-uint8_t                   AUDIO_IO_Read(uint8_t Addr, uint8_t Reg);
-void                      AUDIO_IO_Delay(uint32_t delay);
-#endif/* HAL_I2C_MODULE_ENABLED */
-
-#if defined(HAL_SPI_MODULE_ENABLED)
-/* Link function for COMPASS / ACCELERO peripheral */
-void                      ACCELERO_IO_Init(void);
-void                      ACCELERO_IO_DeInit(void);
-void                      ACCELERO_IO_ITConfig(void);
-void                      ACCELERO_IO_Write(uint8_t RegisterAddr, uint8_t Value);
-uint8_t                   ACCELERO_IO_Read(uint8_t RegisterAddr);
-
-void                      MAGNETO_IO_Init(void);
-void                      MAGNETO_IO_DeInit(void);
-void                      MAGNETO_IO_ITConfig(void);
-void                      MAGNETO_IO_Write(uint8_t RegisterAddr, uint8_t Value);
-uint8_t                   MAGNETO_IO_Read(uint8_t RegisterAddr);
-
-
-/* Link functions for GYRO peripheral */
-void                      GYRO_IO_Init(void);
-void                      GYRO_IO_DeInit(void);
-void                      GYRO_IO_Write(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);
-void                      GYRO_IO_Read(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead);
-
-#endif
-
-#if defined(HAL_I2C_MODULE_ENABLED)
-/*  Link functions IOExpander */
-void                      IOE_Init(void);
-void                      IOE_ITConfig(void);
-void                      IOE_Delay(uint32_t Delay);
-void                      IOE_Write(uint8_t Addr, uint8_t Reg, uint8_t Value);
-uint8_t                   IOE_Read(uint8_t Addr, uint8_t Reg);
-uint16_t                  IOE_ReadMultiple(uint8_t Addr, uint8_t Reg, uint8_t *Buffer, uint16_t Length);
-
-/* Link functions for IDD measurment */
-void                      MFX_IO_Init(void);
-void                      MFX_IO_DeInit(void);
-void                      MFX_IO_ITConfig (void);
-void                      MFX_IO_EnableWakeupPin(void);
-void                      MFX_IO_Wakeup(void);
-void                      MFX_IO_Delay(uint32_t delay);
-void                      MFX_IO_Write(uint16_t addr, uint8_t reg, uint8_t value);
-uint8_t                   MFX_IO_Read(uint16_t addr, uint8_t reg);
-void                      MFX_IO_WriteMultiple(uint16_t Addr, uint8_t Reg, uint8_t *Buffer, uint16_t Length);
-uint16_t                  MFX_IO_ReadMultiple(uint16_t addr, uint8_t reg, uint8_t *buffer, uint16_t length);
-#endif/* HAL_I2C_MODULE_ENABLED */
-/**
-  * @}
-  */
-
-/** @defgroup STM32L476G_DISCOVERY_Exported_Functions Exported Functions
-  * @{
-  */
-
-/**
-  * @brief  This method returns the STM32L476 DISCOVERY BSP Driver revision
-  * @retval version : 0xXYZR (8bits for each decimal, R for RC)
-  */
-uint32_t BSP_GetVersion(void)
-{
-  return __STM32L476G_DISCOVERY_BSP_VERSION;
-}
-
-/**
-  * @brief  This method returns the STM32L476 DISCOVERY supply mode
-  * @retval Code of current supply mode
-  *          This code can be one of following:
-  *     @arg SUPPLY_MODE_EXTERNAL
-  *     @arg SUPPLY_MODE_BATTERY
-  */
-SupplyMode_TypeDef BSP_SupplyModeDetection(void)
-{
-  SupplyMode_TypeDef supplymode = SUPPLY_MODE_ERROR;
-  GPIO_InitTypeDef GPIO_InitStruct;
-
-  BATTERY_DETECTION_GPIO_CLK_ENABLE();
-
-  /* COMP GPIO pin configuration */
-  GPIO_InitStruct.Pin = BATTERY_DETECTION_PIN;
-  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
-  HAL_GPIO_Init(BATTERY_DETECTION_GPIO_PORT, &GPIO_InitStruct);
-
-  HAL_Delay(400);
-  if(HAL_GPIO_ReadPin(BATTERY_DETECTION_GPIO_PORT, GPIO_InitStruct.Pin) != GPIO_PIN_RESET)
-  {
-    supplymode = SUPPLY_MODE_EXTERNAL;
-  }
-  else
-  {
-    supplymode = SUPPLY_MODE_BATTERY;
-  }
-  
-  HAL_GPIO_DeInit(BATTERY_DETECTION_GPIO_PORT, GPIO_InitStruct.Pin);
-  
-  return supplymode;
-}
-
-#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB)
-/**
-  * @brief  Configures LED GPIOs.
-  * @param  Led: Specifies the Led to be configured. 
-  *   This parameter can be one of following parameters:  
-  *     @arg LED4
-  *     @arg LED5
-  * @retval None
-  */
-#elif defined (USE_STM32L476G_DISCO_REVA)
-/**
-  * @brief  Configures LED GPIOs.
-  * @param  Led: Specifies the Led to be configured. 
-  *   This parameter can be one of following parameters:  
-  *     @arg LED3
-  *     @arg LED4
-  * @retval None
-  */
-#endif
-void BSP_LED_Init(Led_TypeDef Led)
-{
-  GPIO_InitTypeDef  GPIO_InitStructure;
-
-  /* Enable the GPIO_LED clock */
-  LEDx_GPIO_CLK_ENABLE(Led);
-
-  /* Configure the GPIO_LED pin */
-  GPIO_InitStructure.Pin = LED_PIN[Led];
-  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStructure.Pull = GPIO_NOPULL;
-  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
-
-  HAL_GPIO_Init(LED_PORT[Led], &GPIO_InitStructure);
-
-  HAL_GPIO_WritePin(LED_PORT[Led], GPIO_InitStructure.Pin, GPIO_PIN_RESET);
-}
-
-#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB)
-/**
-  * @brief  Unconfigures LED GPIOs.
-  * @param  Led: Specifies the Led to be unconfigured. 
-  *   This parameter can be one of following parameters:
-  *     @arg LED4
-  *     @arg LED5
-  * @retval None
-  */
-#elif defined (USE_STM32L476G_DISCO_REVA)
-/**
-  * @brief  Unconfigures LED GPIOs.
-  * @param  Led: Specifies the Led to be unconfigured. 
-  *   This parameter can be one of following parameters:
-  *     @arg LED3
-  *     @arg LED4
-  * @retval None
-  */
-#endif
-void BSP_LED_DeInit(Led_TypeDef Led)
-{
-  /* Enable the GPIO_LED clock */
-  LEDx_GPIO_CLK_ENABLE(Led);
-
-  HAL_GPIO_DeInit(LED_PORT[Led], LED_PIN[Led]);
-}
-
-#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB)
-/**
-  * @brief  Turns selected LED On.
-  * @param  Led: Specifies the Led to be set on. 
-  *   This parameter can be one of following parameters:
-  *     @arg LED4
-  *     @arg LED5
-  * @retval None
-  */
-#elif defined (USE_STM32L476G_DISCO_REVA)
-/**
-  * @brief  Turns selected LED On.
-  * @param  Led: Specifies the Led to be set on. 
-  *   This parameter can be one of following parameters:
-  *     @arg LED3
-  *     @arg LED4
-  * @retval None
-  */
-#endif
-void BSP_LED_On(Led_TypeDef Led)
-{
-  HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET);
-}
-
-#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB)
-/**
-  * @brief  Turns selected LED Off.
-  * @param  Led: Specifies the Led to be set off. 
-  *   This parameter can be one of following parameters:
-  *     @arg LED4
-  *     @arg LED5
-  * @retval None
-  */
-#elif defined (USE_STM32L476G_DISCO_REVA)
-/**
-  * @brief  Turns selected LED Off.
-  * @param  Led: Specifies the Led to be set off. 
-  *   This parameter can be one of following parameters:
-  *     @arg LED3
-  *     @arg LED4
-  * @retval None
-  */
-#endif
-void BSP_LED_Off(Led_TypeDef Led)
-{
-  HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
-}
-
-#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB)
-/**
-  * @brief  Toggles the selected LED.
-  * @param  Led: Specifies the Led to be toggled. 
-  *   This parameter can be one of following parameters:
-  *     @arg LED4
-  *     @arg LED5
-  * @retval None
-  */
-#elif defined (USE_STM32L476G_DISCO_REVA)
-/**
-  * @brief  Toggles the selected LED.
-  * @param  Led: Specifies the Led to be toggled. 
-  *   This parameter can be one of following parameters:
-  *     @arg LED3
-  *     @arg LED4
-  * @retval None
-  */
-#endif
-void BSP_LED_Toggle(Led_TypeDef Led)
-{
-  HAL_GPIO_TogglePin(LED_PORT[Led], LED_PIN[Led]);
-}
-
-/**
-  * @brief  Configures all buttons of the joystick in GPIO or EXTI modes.
-  * @param  Joy_Mode: Joystick mode.
-  *    This parameter can be one of the following values:
-  *     @arg  JOY_MODE_GPIO: Joystick pins will be used as simple IOs
-  *     @arg  JOY_MODE_EXTI: Joystick pins will be connected to EXTI line 
-  *                                 with interrupt generation capability  
-  * @retval HAL_OK: if all initializations are OK. Other value if error.
-  */
-uint8_t BSP_JOY_Init(JOYMode_TypeDef Joy_Mode)
-{
-  JOYState_TypeDef joykey;
-  GPIO_InitTypeDef GPIO_InitStruct;
-  
-  /* Initialized the Joystick. */
-  for(joykey = JOY_SEL; joykey < (JOY_SEL + JOYn) ; joykey++)
-  {
-    /* Enable the JOY clock */
-    JOYx_GPIO_CLK_ENABLE(joykey);
-    
-    GPIO_InitStruct.Pin = JOY_PIN[joykey];
-    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
-    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
-    
-    if (Joy_Mode == JOY_MODE_GPIO)
-    {
-      /* Configure Joy pin as input */
-      GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
-      HAL_GPIO_Init(JOY_PORT[joykey], &GPIO_InitStruct);
-    }
-    else if (Joy_Mode == JOY_MODE_EXTI)
-    {
-      /* Configure Joy pin as input with External interrupt */
-      GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
-      HAL_GPIO_Init(JOY_PORT[joykey], &GPIO_InitStruct);
-      
-      /* Enable and set Joy EXTI Interrupt to the lowest priority */
-      HAL_NVIC_SetPriority((IRQn_Type)(JOY_IRQn[joykey]), 0x0F, 0x00);
-      HAL_NVIC_EnableIRQ((IRQn_Type)(JOY_IRQn[joykey]));
-    }
-  }
-  
-  return HAL_OK;
-}
-
-/**
-  * @brief  Unonfigures all GPIOs used as buttons of the joystick.
-  * @retval None.
-  */
-void BSP_JOY_DeInit(void)
-{
-  JOYState_TypeDef joykey;
-  
-  /* Initialized the Joystick. */
-  for(joykey = JOY_SEL; joykey < (JOY_SEL + JOYn) ; joykey++)
-  {
-    /* Enable the JOY clock */
-    JOYx_GPIO_CLK_ENABLE(joykey);
-    
-    HAL_GPIO_DeInit(JOY_PORT[joykey], JOY_PIN[joykey]);
-  }
-}
-
-/**
-* @brief  Returns the current joystick status.
-* @retval Code of the joystick key pressed
-*          This code can be one of the following values:
-*            @arg  JOY_NONE
-*            @arg  JOY_SEL
-*            @arg  JOY_DOWN
-*            @arg  JOY_LEFT
-*            @arg  JOY_RIGHT
-*            @arg  JOY_UP
-*/
-JOYState_TypeDef BSP_JOY_GetState(void)
-{
-  JOYState_TypeDef joykey;
-  
-  for (joykey = JOY_SEL; joykey < (JOY_SEL + JOYn) ; joykey++)
-  {
-    if (HAL_GPIO_ReadPin(JOY_PORT[joykey], JOY_PIN[joykey]) == GPIO_PIN_SET)
-    {
-      /* Return Code Joystick key pressed */
-      return joykey;
-    }
-  }
-  
-  /* No Joystick key pressed */
-  return JOY_NONE;
-}
-
-/**
-  * @}
-  */ 
-
-/** @defgroup STM32L476G_DISCOVERY_BusOperations_Functions Bus Operations Functions
-  * @{
-  */ 
-
-/*******************************************************************************
-                            BUS OPERATIONS
-*******************************************************************************/
-#if defined(HAL_SPI_MODULE_ENABLED)
-/******************************* SPI Routines**********************************/
-/**
-  * @brief SPIx Bus initialization
-  * @retval None
-  */
-static void SPIx_Init(void)
-{
-  if(HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_RESET) 
-  {
-    /* SPI Config */
-    SpiHandle.Instance = DISCOVERY_SPIx;
-    /* SPI baudrate is set to 10 MHz (PCLK1/SPI_BaudRatePrescaler = 80/8 = 10 MHz) 
-      to verify these constraints:
-      lsm303c SPI interface max baudrate is 10MHz for write/read
-      PCLK1 max frequency is set to 80 MHz 
-      */
-    SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
-    SpiHandle.Init.Direction = SPI_DIRECTION_2LINES;
-    SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE;
-    SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
-    SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
-    SpiHandle.Init.CRCPolynomial = 7;
-    SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT;
-    SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
-    SpiHandle.Init.NSS = SPI_NSS_SOFT;
-    SpiHandle.Init.TIMode = SPI_TIMODE_DISABLE;
-    SpiHandle.Init.Mode = SPI_MODE_MASTER;
-
-    SPIx_MspInit(&SpiHandle);
-    HAL_SPI_Init(&SpiHandle);
-  }
-}
-
-/**
-  * @brief SPI MSP Init
-  * @param hspi: SPI handle
-  * @retval None
-  */
-static void SPIx_MspInit(SPI_HandleTypeDef *hspi)
-{
-  GPIO_InitTypeDef   GPIO_InitStructure;
-
-  /* Enable SPIx clock  */
-  DISCOVERY_SPIx_CLOCK_ENABLE();
-
-  /* enable SPIx gpio clock */
-  DISCOVERY_SPIx_GPIO_CLK_ENABLE();
-  
-  /* configure SPIx SCK, MOSI and MISO */
-  GPIO_InitStructure.Pin = (DISCOVERY_SPIx_SCK_PIN | DISCOVERY_SPIx_MOSI_PIN | DISCOVERY_SPIx_MISO_PIN);
-  GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
-  GPIO_InitStructure.Pull  = GPIO_NOPULL; // GPIO_PULLDOWN;
-  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
-  GPIO_InitStructure.Alternate = DISCOVERY_SPIx_AF;
-  HAL_GPIO_Init(DISCOVERY_SPIx_GPIO_PORT, &GPIO_InitStructure);
-}
-
-/**
-  * @brief SPIx Bus Deinitialization
-  * @retval None
-  */
-void SPIx_DeInit(void)
-{
-  if(HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_RESET) 
-  {
-    /* SPI Deinit */
-    HAL_SPI_DeInit(&SpiHandle);
-    SPIx_MspDeInit();
-  }
-}
-
-/**
-  * @brief SPI MSP DeInit
-  * @retval None
-  */
-static void SPIx_MspDeInit(void)
-{  
-  /* enable SPIx gpio clock */
-  DISCOVERY_SPIx_GPIO_CLK_ENABLE();
-
-  /* Unconfigure SPIx SCK, MOSI and MISO */
-  HAL_GPIO_DeInit(DISCOVERY_SPIx_GPIO_PORT, (DISCOVERY_SPIx_SCK_PIN | DISCOVERY_SPIx_MOSI_PIN | DISCOVERY_SPIx_MISO_PIN));
-
-  DISCOVERY_SPIx_GPIO_FORCE_RESET();
-  DISCOVERY_SPIx_GPIO_RELEASE_RESET();
-
-  /* Disable SPIx clock  */
-  DISCOVERY_SPIx_CLOCK_DISABLE();
-}
-
-/**
-  * @brief  Sends a Byte through the SPI interface and return the Byte received 
-  *         from the SPI bus.
-  * @param  Byte : Byte send.
-  * @retval none.
-  */
-static uint8_t SPIx_WriteRead(uint8_t Byte)
-{
-  uint8_t receivedbyte;
-
-  /* Enable the SPI */
-  __HAL_SPI_ENABLE(&SpiHandle);
-  /* check TXE flag */
-  while((SpiHandle.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE);
-  
-  /* Write the data */
-  *((__IO uint8_t*)&SpiHandle.Instance->DR) = Byte;
-  
-  while((SpiHandle.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE);
-  receivedbyte = *((__IO uint8_t*)&SpiHandle.Instance->DR);
-
-  /* Wait BSY flag */
-  while((SpiHandle.Instance->SR & SPI_FLAG_FTLVL) != SPI_FTLVL_EMPTY);
-  while((SpiHandle.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY);
-  
-  /* disable the SPI */
-  __HAL_SPI_DISABLE(&SpiHandle);
-
-  return receivedbyte;
-}
-
-/**
-  * @brief  Sends a Byte through the SPI interface.
-  * @param  Byte : Byte to send.
-  * @retval none.
-  */
-static void SPIx_Write(uint8_t Byte)
-{
-  /* Enable the SPI */
-  __HAL_SPI_ENABLE(&SpiHandle);
-  /* check TXE flag */
-  while((SpiHandle.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE);
-  
-  /* Write the data */
-  *((__IO uint8_t*)&SpiHandle.Instance->DR) = Byte;
-  
-  /* Wait BSY flag */
-  while((SpiHandle.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY);
-  
-  /* disable the SPI */
-  __HAL_SPI_DISABLE(&SpiHandle);
-}
-
-#if defined(__ICCARM__)
-#pragma optimize=none
-#endif
-/**
-  * @brief  Receives a Byte from the SPI bus.
-  * @retval The received byte value
-  */
-static uint8_t SPIx_Read(void)
-{
-  uint8_t receivedbyte;
-
-    __HAL_SPI_ENABLE(&SpiHandle);
-    __DSB();
-    __DSB();
-    __DSB();
-    __DSB();
-    __DSB();
-    __DSB();
-    __DSB();
-    __DSB();
-     __HAL_SPI_DISABLE(&SpiHandle);
-
-  while((SpiHandle.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE);
-  /* read the received data */
-  receivedbyte = *(__IO uint8_t *)&SpiHandle.Instance->DR;
-  
-  /* Wait for the BSY flag reset */
-  while((SpiHandle.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY); 
-
-  
-  return receivedbyte;
-}
-#endif /* HAL_SPI_MODULE_ENABLED */
-
-
-#if defined(HAL_I2C_MODULE_ENABLED)
-/******************************* I2C Routines**********************************/
-/**
-  * @brief Discovery I2C1 Bus initialization
-  * @retval None
-  */
-static void I2C1_Init(void)
-{
-  if(HAL_I2C_GetState(&I2c1Handle) == HAL_I2C_STATE_RESET)
-  {
-    I2c1Handle.Instance              = DISCOVERY_I2C1;
-    I2c1Handle.Init.Timing           = DISCOVERY_I2C1_TIMING;
-    I2c1Handle.Init.OwnAddress1      = 0;
-    I2c1Handle.Init.AddressingMode   = I2C_ADDRESSINGMODE_7BIT;
-    I2c1Handle.Init.DualAddressMode  = I2C_DUALADDRESS_DISABLE;
-    I2c1Handle.Init.OwnAddress2      = 0;
-    I2c1Handle.Init.GeneralCallMode  = I2C_GENERALCALL_DISABLE;
-    I2c1Handle.Init.NoStretchMode    = I2C_NOSTRETCH_DISABLE;  
-
-    /* Init the I2C */
-    I2C1_MspInit(&I2c1Handle);
-    HAL_I2C_Init(&I2c1Handle);
-  }
-}
-
-/**
-  * @brief Discovery I2C1 MSP Initialization
-  * @param hi2c: I2C handle
-  * @retval None
-  */
-static void I2C1_MspInit(I2C_HandleTypeDef *hi2c)
-{
-  GPIO_InitTypeDef  GPIO_InitStructure;  
-  RCC_PeriphCLKInitTypeDef  RCC_PeriphCLKInitStruct;
-
-  /* IOSV bit MUST be set to access GPIO port G[2:15] */
-  __HAL_RCC_PWR_CLK_ENABLE();
-  HAL_PWREx_EnableVddIO2();
-  
-  if (hi2c->Instance == DISCOVERY_I2C1)
-  {
-    /*##-1- Configure the Discovery I2C clock source. The clock is derived from the SYSCLK #*/
-    RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C1;
-    RCC_PeriphCLKInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_SYSCLK;
-    HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);
-
-    /*##-2- Configure the GPIOs ################################################*/  
-    /* Enable GPIO clock */
-    DISCOVERY_I2C1_SDA_GPIO_CLK_ENABLE();
-    DISCOVERY_I2C1_SCL_GPIO_CLK_ENABLE();
-      
-    /* Configure I2C Rx/Tx as alternate function  */
-    GPIO_InitStructure.Pin       = DISCOVERY_I2C1_SCL_PIN | DISCOVERY_I2C1_SDA_PIN;
-    GPIO_InitStructure.Mode      = GPIO_MODE_AF_OD;
-    GPIO_InitStructure.Pull      = GPIO_PULLUP;
-    GPIO_InitStructure.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
-    GPIO_InitStructure.Alternate = DISCOVERY_I2C1_SCL_SDA_AF;
-    HAL_GPIO_Init(DISCOVERY_I2C1_SCL_GPIO_PORT, &GPIO_InitStructure);
-      
-    /*##-3- Configure the Discovery I2C1 peripheral #######################################*/ 
-    /* Enable Discovery I2C1 clock */
-    DISCOVERY_I2C1_CLK_ENABLE();
-    
-    /* Force and release the I2C Peripheral Clock Reset */
-    DISCOVERY_I2C1_FORCE_RESET();
-    DISCOVERY_I2C1_RELEASE_RESET();
-    
-    /* Enable and set Discovery I2C1 Interrupt to the highest priority */
-    HAL_NVIC_SetPriority(DISCOVERY_I2C1_EV_IRQn, 0x00, 0);
-    HAL_NVIC_EnableIRQ(DISCOVERY_I2C1_EV_IRQn);
-    
-    /* Enable and set Discovery I2C1 Interrupt to the highest priority */
-    HAL_NVIC_SetPriority(DISCOVERY_I2C1_ER_IRQn, 0x00, 0);
-    HAL_NVIC_EnableIRQ(DISCOVERY_I2C1_ER_IRQn); 
-  }
-}
-
-/**
-  * @brief Discovery I2C1 Bus Deitialization
-  * @retval None
-  */
-static void I2C1_DeInit(void)
-{
-  if(HAL_I2C_GetState(&I2c1Handle) != HAL_I2C_STATE_RESET)
-  {
-    /* Deinit the I2C */
-    HAL_I2C_DeInit(&I2c1Handle);
-    I2C1_MspDeInit(&I2c1Handle);
-  }
-}
-
-/**
-  * @brief Discovery I2C1 MSP Deinitialization
-  * @param hi2c: I2C handle
-  * @retval None
-  */
-static void I2C1_MspDeInit(I2C_HandleTypeDef *hi2c)
-{
-  if(hi2c->Instance == DISCOVERY_I2C1)
-  {
-    /*##-1- Unconfigure the GPIOs ################################################*/
-    /* Enable GPIO clock */
-    DISCOVERY_I2C1_SDA_GPIO_CLK_ENABLE();
-    DISCOVERY_I2C1_SCL_GPIO_CLK_ENABLE();
-
-    /* Deinit Rx/Tx pins */
-    HAL_GPIO_DeInit(DISCOVERY_I2C1_SCL_GPIO_PORT, (DISCOVERY_I2C1_SCL_PIN | DISCOVERY_I2C1_SDA_PIN));
-
-    /*##-2- Unconfigure the Discovery I2C1 peripheral ############################*/
-    /* Force & Release the I2C Peripheral Clock Reset */  
-    DISCOVERY_I2C1_FORCE_RESET();
-    DISCOVERY_I2C1_RELEASE_RESET();
-
-    /* Disable Discovery I2C1 clock */
-    DISCOVERY_I2C1_CLK_DISABLE();
-
-    /* Disable Discovery I2C1 interrupts */
-    HAL_NVIC_DisableIRQ(DISCOVERY_I2C1_EV_IRQn);
-    HAL_NVIC_DisableIRQ(DISCOVERY_I2C1_ER_IRQn);
-    
-    __HAL_RCC_PWR_CLK_ENABLE();
-    HAL_PWREx_DisableVddIO2();
-  }
-}
-
-/**
-  * @brief  Write a value in a register of the device through BUS.
-  * @param  Addr: Device address on BUS Bus.  
-  * @param  Reg: The target register address to write
-  * @param  RegSize: The target register size (can be 8BIT or 16BIT)
-  * @param  pBuffer: The target register value to be written 
-  * @param  Length: buffer size to be written
-  * @retval None
-  */
-static HAL_StatusTypeDef I2C1_WriteBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  
-  status = HAL_I2C_Mem_Write(&I2c1Handle, Addr, (uint16_t)Reg, RegSize, pBuffer, Length, I2c1Timeout); 
-
-/* Check the communication status */
-  if(status != HAL_OK)
-  {
-    /* Re-Initiaize the BUS */
-    I2C1_Error();
-  }        
-  return status;
-}
-
-/**
-  * @brief  Reads multiple data on the BUS.
-  * @param  Addr: I2C Address
-  * @param  Reg: Reg Address 
-  * @param  RegSize : The target register size (can be 8BIT or 16BIT)
-  * @param  pBuffer: pointer to read data buffer
-  * @param  Length: length of the data
-  * @retval 0 if no problems to read multiple data
-  */
-static HAL_StatusTypeDef I2C1_ReadBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  status = HAL_I2C_Mem_Read(&I2c1Handle, Addr, (uint16_t)Reg, RegSize, pBuffer, Length, I2c1Timeout);
-  
-/* Check the communication status */
-  if(status != HAL_OK)
-  {
-    /* Re-Initiaize the BUS */
-    I2C1_Error();
-  }        
-  return status;
-}
-
-/**
-  * @brief Discovery I2C1 error treatment function
-  * @retval None
-  */
-static void I2C1_Error (void)
-{
-  /* De-initialize the I2C communication BUS */
-  HAL_I2C_DeInit(&I2c1Handle);
-  
-  /* Re- Initiaize the I2C communication BUS */
-  I2C1_Init();
-}
-
-/**
-  * @brief Discovery I2C2 Bus initialization
-  * @retval None
-  */
-static void I2C2_Init(void)
-{
-  if(HAL_I2C_GetState(&I2c2Handle) == HAL_I2C_STATE_RESET)
-  {
-    I2c2Handle.Instance              = DISCOVERY_I2C2;
-    I2c2Handle.Init.Timing           = DISCOVERY_I2C2_TIMING;
-    I2c2Handle.Init.OwnAddress1      = 0;
-    I2c2Handle.Init.AddressingMode   = I2C_ADDRESSINGMODE_7BIT;
-    I2c2Handle.Init.DualAddressMode  = I2C_DUALADDRESS_DISABLE;
-    I2c2Handle.Init.OwnAddress2      = 0;
-    I2c2Handle.Init.GeneralCallMode  = I2C_GENERALCALL_DISABLE;
-    I2c2Handle.Init.NoStretchMode    = I2C_NOSTRETCH_DISABLE;
-
-    /* Init the I2C */
-    I2C2_MspInit(&I2c2Handle);
-    HAL_I2C_Init(&I2c2Handle);
-  }
-}
-
-/**
-  * @brief Discovery I2C2 MSP Initialization
-  * @param hi2c: I2C2 handle
-  * @retval None
-  */
-static void I2C2_MspInit(I2C_HandleTypeDef *hi2c)
-{
-  GPIO_InitTypeDef  GPIO_InitStructure;
-  RCC_PeriphCLKInitTypeDef  RCC_PeriphCLKInitStruct;
-
-  if (hi2c->Instance == DISCOVERY_I2C2)
-  {
-    /*##-1- Configure the Discovery I2C2 clock source. The clock is derived from the SYSCLK #*/
-    RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C2;
-    RCC_PeriphCLKInitStruct.I2c2ClockSelection = RCC_I2C2CLKSOURCE_SYSCLK;
-    HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);
-
-    /*##-2- Configure the GPIOs ################################################*/
-    /* Enable GPIO clock */
-    DISCOVERY_I2C2_SDA_GPIO_CLK_ENABLE();
-    DISCOVERY_I2C2_SCL_GPIO_CLK_ENABLE();
-
-    /* Configure I2C Rx/Tx as alternate function  */
-    GPIO_InitStructure.Pin       = DISCOVERY_I2C2_SCL_PIN | DISCOVERY_I2C2_SDA_PIN;
-    GPIO_InitStructure.Mode      = GPIO_MODE_AF_OD;
-    GPIO_InitStructure.Pull      = GPIO_PULLUP;
-    GPIO_InitStructure.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
-    GPIO_InitStructure.Alternate = DISCOVERY_I2C2_SCL_SDA_AF;
-    HAL_GPIO_Init(DISCOVERY_I2C2_SCL_GPIO_PORT, &GPIO_InitStructure);
-
-    /*##-3- Configure the Discovery I2C2 peripheral #############################*/
-    /* Enable Discovery_I2C2 clock */
-    DISCOVERY_I2C2_CLK_ENABLE();
-
-    /* Force and release the I2C Peripheral Clock Reset */  
-    DISCOVERY_I2C2_FORCE_RESET();
-    DISCOVERY_I2C2_RELEASE_RESET(); 
-
-    /* Enable and set Discovery I2C2 Interrupt to the highest priority */
-    HAL_NVIC_SetPriority(DISCOVERY_I2C2_EV_IRQn, 0x00, 0);
-    HAL_NVIC_EnableIRQ(DISCOVERY_I2C2_EV_IRQn);
-
-    /* Enable and set Discovery I2C2 Interrupt to the highest priority */
-    HAL_NVIC_SetPriority(DISCOVERY_I2C2_ER_IRQn, 0x00, 0);
-    HAL_NVIC_EnableIRQ(DISCOVERY_I2C2_ER_IRQn); 
-  }
-}
-
-/**
-  * @brief Discovery I2C2 Bus Deinitialization
-  * @retval None
-  */
-static void I2C2_DeInit(void)
-{
-  if(HAL_I2C_GetState(&I2c2Handle) != HAL_I2C_STATE_RESET)
-  {
-    /* DeInit the I2C */
-    HAL_I2C_DeInit(&I2c2Handle);
-    I2C2_MspDeInit(&I2c2Handle);
-  }
-}
-
-/**
-  * @brief Discovery I2C2 MSP DeInitialization
-  * @param hi2c: I2C2 handle
-  * @retval None
-  */
-static void I2C2_MspDeInit(I2C_HandleTypeDef *hi2c)
-{
-  if (hi2c->Instance == DISCOVERY_I2C2)
-  {
-    /*##-1- Unconfigure the GPIOs ################################################*/
-    /* Enable GPIO clock */
-    DISCOVERY_I2C2_SDA_GPIO_CLK_ENABLE();
-    DISCOVERY_I2C2_SCL_GPIO_CLK_ENABLE();
-      
-    /* Configure I2C Rx/Tx as alternate function  */
-    HAL_GPIO_DeInit(DISCOVERY_I2C2_SCL_GPIO_PORT, (DISCOVERY_I2C2_SCL_PIN | DISCOVERY_I2C2_SDA_PIN));
-      
-    /*##-2- Unconfigure the Discovery I2C2 peripheral ############################*/
-    /* Force and release I2C Peripheral */
-    DISCOVERY_I2C2_FORCE_RESET();
-    DISCOVERY_I2C2_RELEASE_RESET();
-
-    /* Disable Discovery I2C2 clock */
-    DISCOVERY_I2C2_CLK_DISABLE();
-
-    /* Disable Discovery I2C2 interrupts */
-    HAL_NVIC_DisableIRQ(DISCOVERY_I2C2_EV_IRQn);
-    HAL_NVIC_DisableIRQ(DISCOVERY_I2C2_ER_IRQn);
-  }
-}
-
-/**
-  * @brief  Write a value in a register of the device through BUS.
-  * @param  Addr: Device address on BUS Bus.  
-  * @param  Reg: The target register address to write
-  * @param  RegSize: The target register size (can be 8BIT or 16BIT)
-  * @param  Value: The target register value to be written 
-  * @retval None 
-  */
-static void I2C2_WriteData(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t Value)
-  {
-  HAL_StatusTypeDef status = HAL_OK;
-  
-  status = HAL_I2C_Mem_Write(&I2c2Handle, Addr, (uint16_t)Reg, RegSize, &Value, 1, I2c2Timeout); 
-  
-  /* Check the communication status */
-  if(status != HAL_OK)
-  {
-    /* Re-Initiaize the BUS */
-    I2C2_Error();
-  }
-}
-
-/**
-  * @brief  Write a value in a register of the device through BUS.
-  * @param  Addr: Device address on BUS Bus.  
-  * @param  Reg: The target register address to write
-  * @param  RegSize: The target register size (can be 8BIT or 16BIT)
-  * @param  pBuffer: The target register value to be written 
-  * @param  Length: buffer size to be written
-  * @retval None
-  */
-static HAL_StatusTypeDef I2C2_WriteBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  
-  status = HAL_I2C_Mem_Write(&I2c2Handle, Addr, (uint16_t)Reg, RegSize, pBuffer, Length, I2c2Timeout); 
-
-  /* Check the communication status */
-  if(status != HAL_OK)
-  {
-    /* Re-Initiaize the BUS */
-    I2C2_Error();
-  }
-  
-  return status;
-}
-
-/**
-  * @brief  Read a register of the device through BUS
-  * @param  Addr: Device address on BUS
-  * @param  Reg: The target register address to read
-  * @param  RegSize: The target register size (can be 8BIT or 16BIT)
-  * @retval read register value
-  */
-static uint8_t I2C2_ReadData(uint16_t Addr, uint16_t Reg, uint16_t RegSize)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint8_t value = 0x0;
-  
-  status = HAL_I2C_Mem_Read(&I2c2Handle, Addr, Reg, RegSize, &value, 1, I2c2Timeout);
-    
-  /* Check the communication status */
-  if(status != HAL_OK)
-  {
-    /* Re-Initiaize the BUS */
-    I2C2_Error();
-  }
-  
-  return value;
-}
-
-/**
-  * @brief  Reads multiple data on the BUS.
-  * @param  Addr: I2C Address
-  * @param  Reg: Reg Address 
-  * @param  RegSize : The target register size (can be 8BIT or 16BIT)
-  * @param  pBuffer: pointer to read data buffer
-  * @param  Length: length of the data
-  * @retval 0 if no problems to read multiple data
-  */
-static HAL_StatusTypeDef I2C2_ReadBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  status = HAL_I2C_Mem_Read(&I2c2Handle, Addr, (uint16_t)Reg, RegSize, pBuffer, Length, I2c2Timeout);
-  
-  /* Check the communication status */
-  if(status != HAL_OK)
-  {
-    /* Re-Initiaize the BUS */
-    I2C2_Error();
-  }
-  
-  return status;
-}
-
-/**
-  * @brief Discovery I2C2 error treatment function
-  * @retval None
-  */
-static void I2C2_Error (void)
-{
-  /* De-initialize the I2C communication BUS */
-  HAL_I2C_DeInit(&I2c2Handle);
-  
-  /* Re- Initiaize the I2C communication BUS */
-  I2C2_Init();
-}
-#endif /*HAL_I2C_MODULE_ENABLED*/
-
-
-/*******************************************************************************
-                            LINK OPERATIONS
-*******************************************************************************/
-#if defined(HAL_SPI_MODULE_ENABLED)
-/*********************** LINK ACCELEROMETER ***********************************/
-/**
-  * @brief  Configures COMPASS/ACCELEROMETER io interface.
-  * @retval None
-  */
-void ACCELERO_IO_Init(void)
-{
-  GPIO_InitTypeDef GPIO_InitStructure;
-     
-  /* Enable CS GPIO clock and  Configure GPIO PIN for Gyroscope Chip select */
-  ACCELERO_CS_GPIO_CLK_ENABLE();
-  GPIO_InitStructure.Pin = ACCELERO_CS_PIN;
-  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStructure.Pull  = GPIO_NOPULL;
-  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
-  HAL_GPIO_Init(ACCELERO_CS_GPIO_PORT, &GPIO_InitStructure);
-
-  /* Deselect : Chip Select high */
-  ACCELERO_CS_HIGH();
-  
-  SPIx_Init();
-}
-
-/**
-  * @brief  De-Configures COMPASS/ACCELEROMETER io interface.
-  * @retval None
-  */
-void ACCELERO_IO_DeInit(void)
-{
-  GPIO_InitTypeDef GPIO_InitStructure;
-     
-  /* Enable CS GPIO clock and  Configure GPIO PIN for Gyroscope Chip select */
-  ACCELERO_CS_GPIO_CLK_ENABLE();
-  GPIO_InitStructure.Pin = ACCELERO_CS_PIN;
-  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStructure.Pull  = GPIO_NOPULL;
-  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
-  HAL_GPIO_Init(ACCELERO_CS_GPIO_PORT, &GPIO_InitStructure);
-
-  /* Deselect : Chip Select high */
-  ACCELERO_CS_HIGH();
-
-  /* Uninitialize SPI bus */
-  SPIx_DeInit();
-}
-
-/**
-  * @brief  Configures COMPASS / ACCELERO click IT
-  * @retval None
-  */
-void ACCELERO_IO_ITConfig(void)
-{
-}
-
-/**
-  * @brief  Writes one byte to the COMPASS / ACCELEROMETER.
-  * @param  RegisterAddr specifies the COMPASS / ACCELEROMETER register to be written.
-  * @param  Value : Data to be written
-  * @retval   None
- */
-void ACCELERO_IO_Write(uint8_t RegisterAddr, uint8_t Value)
-{
-  ACCELERO_CS_LOW();
-  __SPI_DIRECTION_1LINE_TX(&SpiHandle);
-  /* call SPI Read data bus function */
-  SPIx_Write(RegisterAddr);
-  SPIx_Write(Value);
-  ACCELERO_CS_HIGH();
-}
-
-/**
-  * @brief  Reads a block of data from the COMPASS / ACCELEROMETER.
-  * @param  RegisterAddr : specifies the COMPASS / ACCELEROMETER internal address register to read from
-  * @retval ACCELEROMETER register value
-  */ 
-uint8_t ACCELERO_IO_Read(uint8_t RegisterAddr)
-{
-  RegisterAddr = RegisterAddr | ((uint8_t)0x80);
-  ACCELERO_CS_LOW();
-  __SPI_DIRECTION_1LINE_TX(&SpiHandle);
-  SPIx_Write(RegisterAddr);
-  __SPI_DIRECTION_1LINE_RX(&SpiHandle);
-  uint8_t val = SPIx_Read();
-  ACCELERO_CS_HIGH();
-  return val;
-}
-
-/********************************* LINK MAGNETO *******************************/
-/**
-  * @brief  Configures COMPASS/MAGNETO SPI interface.
-  * @retval None
-  */
-void MAGNETO_IO_Init(void)
-{
-  GPIO_InitTypeDef GPIO_InitStructure;
-  
-  /* Enable CS GPIO clock and  Configure GPIO PIN for Gyroscope Chip select */  
-  MAGNETO_CS_GPIO_CLK_ENABLE();  
-  GPIO_InitStructure.Pin = MAGNETO_CS_PIN;
-  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStructure.Pull  = GPIO_NOPULL;
-  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
-  HAL_GPIO_Init(MAGNETO_CS_GPIO_PORT, &GPIO_InitStructure);
-
-  /* Deselect : Chip Select high */
-  MAGNETO_CS_HIGH();
-  
-  SPIx_Init();
-}
-
-/**
-  * @brief  de-Configures COMPASS/MAGNETO SPI interface.
-  * @retval None
-  */
-void MAGNETO_IO_DeInit(void)
-{
-  GPIO_InitTypeDef GPIO_InitStructure;
-  
-  /* Enable CS GPIO clock and  Configure GPIO PIN for Gyroscope Chip select */  
-  MAGNETO_CS_GPIO_CLK_ENABLE();  
-  GPIO_InitStructure.Pin = MAGNETO_CS_PIN;
-  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStructure.Pull  = GPIO_NOPULL;
-  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
-  HAL_GPIO_Init(MAGNETO_CS_GPIO_PORT, &GPIO_InitStructure);
-
-  /* Deselect : Chip Select high */
-  MAGNETO_CS_HIGH();
-  
-   HAL_GPIO_DeInit(MAGNETO_CS_GPIO_PORT, MAGNETO_INT1_PIN|MAGNETO_DRDY_PIN);
-
-
-  /* Uninitialize SPI bus */
-  SPIx_DeInit();
-}
-
-/**
-  * @brief  Writes one byte to the COMPASS/MAGNETO.
-  * @param  RegisterAddr specifies the COMPASS/MAGNETO register to be written.
-  * @param  Value : Data to be written
-  * @retval   None
- */
-void MAGNETO_IO_Write(uint8_t RegisterAddr, uint8_t Value)
-{
-  MAGNETO_CS_LOW();
-  __SPI_DIRECTION_1LINE_TX(&SpiHandle);
-  /* call SPI Read data bus function */
-  SPIx_Write(RegisterAddr);
-  SPIx_Write(Value);
-  MAGNETO_CS_HIGH();
-}
-
-/**
-  * @brief  Reads a block of data from the COMPASS/MAGNETO.
-  * @param  RegisterAddr : specifies the COMPASS/MAGNETO internal address register to read from
-  * @retval ACCELEROMETER register value
-  */ 
-uint8_t MAGNETO_IO_Read(uint8_t RegisterAddr)
-{
-  MAGNETO_CS_LOW();
-  __SPI_DIRECTION_1LINE_TX(&SpiHandle);
-  SPIx_Write(RegisterAddr | 0x80);
-  __SPI_DIRECTION_1LINE_RX(&SpiHandle);
-  uint8_t val = SPIx_Read();
-  MAGNETO_CS_HIGH();
-  return val;
-}
-
-/********************************* LINK GYRO *****************************/
-/**
-  * @brief  Configures the GYRO SPI interface.
-  * @retval None
-  */
-void GYRO_IO_Init(void)
-{
-  GPIO_InitTypeDef GPIO_InitStructure;
-  
-    
-  /* Case GYRO not used in the demonstration software except being set in
-     low power mode.
-     To avoid access conflicts with accelerometer and magnetometer, 
-     initialize  XL_CS and MAG_CS pins then deselect these I/O */
-  ACCELERO_CS_GPIO_CLK_ENABLE();
-  GPIO_InitStructure.Pin = ACCELERO_CS_PIN;
-  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStructure.Pull  = GPIO_NOPULL;
-  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
-  HAL_GPIO_Init(ACCELERO_CS_GPIO_PORT, &GPIO_InitStructure);
-
-  /* Deselect : Chip Select high */
-  ACCELERO_CS_HIGH();    
-  
-   /* Enable CS GPIO clock and  Configure GPIO PIN for Gyroscope Chip select */  
-  MAGNETO_CS_GPIO_CLK_ENABLE();  
-  GPIO_InitStructure.Pin = MAGNETO_CS_PIN;
-  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStructure.Pull  = GPIO_NOPULL;
-  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
-  HAL_GPIO_Init(MAGNETO_CS_GPIO_PORT, &GPIO_InitStructure);
-
-  /* Deselect : Chip Select high */
-  MAGNETO_CS_HIGH();
-    
-  
-  /* Configure the Gyroscope Control pins ---------------------------------*/
-  /* Enable CS GPIO clock and  Configure GPIO PIN for Gyroscope Chip select */  
-  GYRO_CS_GPIO_CLK_ENABLE();  
-  GPIO_InitStructure.Pin = GYRO_CS_PIN;
-  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStructure.Pull  = GPIO_NOPULL;
-  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
-  HAL_GPIO_Init(GYRO_CS_GPIO_PORT, &GPIO_InitStructure);
-
-  /* Deselect : Chip Select high */
-  GYRO_CS_HIGH();
-
-  /* Enable INT1, INT2 GPIO clock and Configure GPIO PINs to detect Interrupts */
-  GYRO_INT1_GPIO_CLK_ENABLE();
-  GPIO_InitStructure.Pin = GYRO_INT1_PIN;
-  GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
-  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
-  GPIO_InitStructure.Pull= GPIO_NOPULL;
-  HAL_GPIO_Init(GYRO_INT1_GPIO_PORT, &GPIO_InitStructure);
-  
-  GYRO_INT2_GPIO_CLK_ENABLE();
-  GPIO_InitStructure.Pin = GYRO_INT2_PIN;
-  HAL_GPIO_Init(GYRO_INT2_GPIO_PORT, &GPIO_InitStructure);
-  
-  SPIx_Init();
-  
-}
-
-
-/**
-  * @brief  de-Configures GYRO SPI interface.
-  * @retval None
-  */
-void GYRO_IO_DeInit(void)
-{
- GPIO_InitTypeDef GPIO_InitStructure;
-  /* Enable CS GPIO clock */
-  GYRO_CS_GPIO_CLK_ENABLE();
-   
-  GPIO_InitStructure.Pin = GYRO_CS_PIN;
-  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStructure.Pull  = GPIO_NOPULL;
-  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
-  HAL_GPIO_Init(GYRO_CS_GPIO_PORT, &GPIO_InitStructure);
-
-  /* Deselect : Chip Select high */
-  GYRO_CS_HIGH();
-  
-  GYRO_INT1_GPIO_CLK_ENABLE();
-  GYRO_INT2_GPIO_CLK_ENABLE();
-
-  /* Uninitialize the INT1/INT2 Pins */
-  HAL_GPIO_DeInit(GYRO_INT1_GPIO_PORT, GYRO_INT1_PIN);
-  HAL_GPIO_DeInit(GYRO_INT2_GPIO_PORT, GYRO_INT2_PIN);
-
-  /* Uninitialize SPI bus */
-  SPIx_DeInit();
-}
-
-/**
-  * @brief  Writes one byte to the GYRO.
-  * @param  pBuffer : pointer to the buffer  containing the data to be written to the GYRO.
-  * @param  WriteAddr : GYRO's internal address to write to.
-  * @param  NumByteToWrite: Number of bytes to write.
-  * @retval None
-  */
-void GYRO_IO_Write(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite)
-{
-  /* Configure the MS bit: 
-       - When 0, the address will remain unchanged in multiple read/write commands.
-       - When 1, the address will be auto incremented in multiple read/write commands.
-  */
-  if(NumByteToWrite > 0x01)
-  {
-    WriteAddr |= (uint8_t)MULTIPLEBYTE_CMD;
-  }
-  /* Set chip select Low at the start of the transmission */
-  GYRO_CS_LOW();
-  __SPI_DIRECTION_2LINES(&SpiHandle);
-  
-  /* Send the Address of the indexed register */
-  SPIx_WriteRead(WriteAddr);
-  
-  /* Send the data that will be written into the device (MSB First) */
-  while(NumByteToWrite >= 0x01)
-  {
-    SPIx_WriteRead(*pBuffer);
-    NumByteToWrite--;
-    pBuffer++;
-  }
-  
-  /* Set chip select High at the end of the transmission */ 
-  GYRO_CS_HIGH();
-}
-
-/**
-  * @brief  Reads a block of data from the GYROSCOPE.
-  * @param  pBuffer : pointer to the buffer that receives the data read from the GYROSCOPE.
-  * @param  ReadAddr : GYROSCOPE's internal address to read from.
-  * @param  NumByteToRead : number of bytes to read from the GYROSCOPE.
-  * @retval None
-  */
-void GYRO_IO_Read(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead)
-{  
-  if(NumByteToRead > 0x01)
-  {
-    ReadAddr |= (uint8_t)(READWRITE_CMD | MULTIPLEBYTE_CMD);
-  }
-  else
-  {
-    ReadAddr |= (uint8_t)READWRITE_CMD;
-  }
-  /* Set chip select Low at the start of the transmission */
-  GYRO_CS_LOW();
-  __SPI_DIRECTION_2LINES(&SpiHandle);
-  /* Send the Address of the indexed register */
-  SPIx_WriteRead(ReadAddr);
-  
-  /* Receive the data that will be read from the device (MSB First) */
-  while(NumByteToRead > 0x00)
-  {
-    /* Send dummy byte (0x00) to generate the SPI clock to GYROSCOPE (Slave device) */
-    *pBuffer = SPIx_WriteRead(0x00);
-    NumByteToRead--;
-    pBuffer++;
-  }
-  
-  /* Set chip select High at the end of the transmission */ 
-  GYRO_CS_HIGH();
-}
-#endif /* HAL_SPI_MODULE_ENABLED */
-
-#if defined(HAL_I2C_MODULE_ENABLED)
-/********************************* LINK MFX ***********************************/
-/**
-  * @brief  Initializes MFX low level.
-  * @retval None
-  */
-void MFX_IO_Init(void)
-{
-  /* I2C2 init */
-  I2C2_Init();
-}
-/**
-  * @brief  Deinitializes MFX low level.
-  * @retval None
-  */
-void MFX_IO_DeInit(void)
-{
-  GPIO_InitTypeDef  GPIO_InitStruct;
-
-  /* Enable wakeup gpio clock */
-  IDD_WAKEUP_GPIO_CLK_ENABLE();
-  
-  /* MFX wakeup pin configuration */
-  GPIO_InitStruct.Pin   = IDD_WAKEUP_PIN;
-  GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
-  GPIO_InitStruct.Pull  = GPIO_PULLDOWN;
-  HAL_GPIO_Init(IDD_WAKEUP_GPIO_PORT, &GPIO_InitStruct);
-
-  /* DeInit interrupt pin : disable IRQ before to avoid spurious interrupt */
-  HAL_NVIC_DisableIRQ((IRQn_Type)(IDD_INT_EXTI_IRQn));
-  IDD_INT_GPIO_CLK_ENABLE();
-  HAL_GPIO_DeInit(IDD_INT_GPIO_PORT, IDD_INT_PIN);
-
-  /* I2C2 Deinit */
-  I2C2_DeInit();
-}
-
-/**
-  * @brief  Configures MFX low level interrupt.
-  * @retval None
-  */
-void MFX_IO_ITConfig(void)
-{
-  GPIO_InitTypeDef  GPIO_InitStruct;
-
-  /* Enable the GPIO clock */
-  IDD_INT_GPIO_CLK_ENABLE();
-
-  /* MFX_OUT_IRQ (normally used for EXTI_WKUP) */
-  GPIO_InitStruct.Pin   = IDD_INT_PIN;
-  GPIO_InitStruct.Pull  = GPIO_PULLDOWN;
-  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
-  GPIO_InitStruct.Mode  = GPIO_MODE_IT_RISING;
-  HAL_GPIO_Init(IDD_INT_GPIO_PORT, &GPIO_InitStruct);
-  
-  /* Enable and set GPIO EXTI Interrupt to the lowest priority */
-  HAL_NVIC_SetPriority((IRQn_Type)(IDD_INT_EXTI_IRQn), 0x0F, 0x0F);
-  HAL_NVIC_EnableIRQ((IRQn_Type)(IDD_INT_EXTI_IRQn));
-}
-
-/**
-  * @brief  Configures MFX wke up  pin.
-  * @retval None
-  */
-void MFX_IO_EnableWakeupPin(void)
-{
-  GPIO_InitTypeDef  GPIO_InitStruct;
-  
-  /* Enable wakeup gpio clock */
-  IDD_WAKEUP_GPIO_CLK_ENABLE();
-  
-  /* MFX wakeup pin configuration */
-  GPIO_InitStruct.Pin   = IDD_WAKEUP_PIN;
-  GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
-  GPIO_InitStruct.Pull  = GPIO_NOPULL;
-  HAL_GPIO_Init(IDD_WAKEUP_GPIO_PORT, &GPIO_InitStruct);
-}
-
-/**
-  * @brief  Wakeup MFX.
-  * @retval None
-  */
-void MFX_IO_Wakeup(void)
-{
-  /* Set Wakeup pin to high to wakeup Idd measurement component from standby mode */
-  HAL_GPIO_WritePin(IDD_WAKEUP_GPIO_PORT, IDD_WAKEUP_PIN, GPIO_PIN_SET);
-
-  /* Wait */
-  HAL_Delay(1);
-
-  /* Set gpio pin basck to low */
-  HAL_GPIO_WritePin(IDD_WAKEUP_GPIO_PORT, IDD_WAKEUP_PIN, GPIO_PIN_RESET);
-}
-
-/**
-  * @brief  MFX writes single data.
-  * @param  Addr: I2C address
-  * @param  Reg: Register address 
-  * @param  Value: Data to be written
-  * @retval None
-  */
-void MFX_IO_Write(uint16_t Addr, uint8_t Reg, uint8_t Value)
-{
-  I2C2_WriteData(Addr, Reg, I2C_MEMADD_SIZE_8BIT, Value);
-}
-
-/**
-  * @brief  MFX reads single data.
-  * @param  Addr: I2C address
-  * @param  Reg: Register address 
-  * @retval Read data
-  */
-uint8_t MFX_IO_Read(uint16_t Addr, uint8_t Reg)
-{
-  return I2C2_ReadData(Addr, Reg, I2C_MEMADD_SIZE_8BIT);
-}
-
-/**
-  * @brief  MFX reads multiple data.
-  * @param  Addr: I2C address
-  * @param  Reg: Register address 
-  * @param  Buffer: Pointer to data buffer
-  * @param  Length: Length of the data
-  * @retval Number of read data
-  */
-uint16_t MFX_IO_ReadMultiple(uint16_t Addr, uint8_t Reg, uint8_t *Buffer, uint16_t Length)
-{
- return I2C2_ReadBuffer(Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, Buffer, Length);
-}
-
-/**
-  * @brief  MFX writes multiple data.
-  * @param  Addr: I2C address
-  * @param  Reg: Register address 
-  * @param  Buffer: Pointer to data buffer
-  * @param  Length: Length of the data
-  * @retval None
-  */
-void MFX_IO_WriteMultiple(uint16_t Addr, uint8_t Reg, uint8_t *Buffer, uint16_t Length)
-{
-  I2C2_WriteBuffer(Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, Buffer, Length);
-}
-
-/**
-  * @brief  MFX delay 
-  * @param  Delay: Delay in ms
-  * @retval None
-  */
-void MFX_IO_Delay(uint32_t Delay)
-{
-  HAL_Delay(Delay);
-}
-
-
-/********************************* LINK AUDIO *********************************/
-/**
-  * @brief  Initializes Audio low level.
-  * @retval None
-  */
-void AUDIO_IO_Init(void) 
-{
-  GPIO_InitTypeDef  GPIO_InitStruct;
-  
-  /* Enable Reset GPIO Clock */
-  AUDIO_RESET_GPIO_CLK_ENABLE();
-  
-  /* Audio reset pin configuration */
-  GPIO_InitStruct.Pin = AUDIO_RESET_PIN; 
-  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
-  GPIO_InitStruct.Pull  = GPIO_NOPULL;
-  HAL_GPIO_Init(AUDIO_RESET_GPIO, &GPIO_InitStruct);
-
-  /* I2C bus init */
-  I2C1_Init();
-
-  /* Power Down the codec */
-  CODEC_AUDIO_POWER_OFF();
-
-  /* wait for a delay to insure registers erasing */
-  HAL_Delay(5); 
-
-  /* Power on the codec */
-  CODEC_AUDIO_POWER_ON();
-   
-  /* wait for a delay to insure registers erasing */
-  HAL_Delay(5); 
-}
-
-/**
-  * @brief  Deinitializes Audio low level.
-  * @retval None
-  */
-void AUDIO_IO_DeInit(void)                       /* TO DO */
-{
-  GPIO_InitTypeDef  GPIO_InitStruct;
-  
-  /***********************************************************************/
-  /* In case of battery-supplied powered, there is no audio codec-based 
-     features available. Set audio codec I/O default setting */
-  /***********************************************************************/ 
-  __HAL_RCC_GPIOE_CLK_ENABLE();  
-  GPIO_InitStruct.Mode      = GPIO_MODE_OUTPUT_PP  ;
-  GPIO_InitStruct.Pin       = (GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6);
-  GPIO_InitStruct.Pull      = GPIO_PULLDOWN;
-  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH; 
-  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
-  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET);
-  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);
-  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_4, GPIO_PIN_RESET);
-  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_RESET);
-  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_6, GPIO_PIN_RESET);
-
-  /* I2C bus Deinit */
-  I2C1_DeInit();
-}
-
-/**
-  * @brief  Writes a single data.
-  * @param  Addr: I2C address
-  * @param  Reg: Reg address 
-  * @param  Value: Data to be written
-  * @retval None
-  */
-void AUDIO_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value)
-{
-  I2C1_WriteBuffer(Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, &Value, 1);
-}
-
-/**
-  * @brief  Reads a single data.
-  * @param  Addr: I2C address
-  * @param  Reg: Reg address 
-  * @retval Data to be read
-  */
-uint8_t AUDIO_IO_Read(uint8_t Addr, uint8_t Reg)
-{
-  uint8_t Read_Value = 0;
-  
-  I2C1_ReadBuffer((uint16_t) Addr, (uint16_t) Reg, I2C_MEMADD_SIZE_8BIT, &Read_Value, 1); 
-  
-  return Read_Value;
-}
-
-/**
-  * @brief  AUDIO Codec delay 
-  * @param  Delay: Delay in ms
-  * @retval None
-  */
-void AUDIO_IO_Delay(uint32_t Delay)
-{
-  HAL_Delay(Delay);
-}
-#endif /* HAL_I2C_MODULE_ENABLED */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-  
-/**
-  * @}
-  */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
--- a/stm32l476g_discovery.h	Thu Dec 03 22:16:32 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,566 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32l476g_discovery.h
-  * @author  MCD Application Team
-  * @version V1.0.1
-  * @date    16-September-2015
-  * @brief   This file contains definitions for STM32L476G_DISCOVERY's LEDs, 
-  *          push-buttons hardware resources (MB1184).
-  ******************************************************************************
-  * @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.
-  *
-  ******************************************************************************
-  */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32L476G_DISCOVERY_H
-#define __STM32L476G_DISCOVERY_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/** 
-  * @brief  Define for STM32L476G_DISCOVERY board
-  */
-#if !defined (USE_STM32L476G_DISCO_REVC) && !defined (USE_STM32L476G_DISCO_REVB) && !defined (USE_STM32L476G_DISCO_REVA)
-#define USE_STM32L476G_DISCO_REVC
-#endif
-
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32l4xx_hal.h"
-
-/** @addtogroup BSP
-  * @{
-  */
-
-/** @addtogroup STM32L476G_DISCOVERY
-  * @{
-  */
-
-/** @addtogroup STM32L476G_DISCOVERY_Common
-  * @{
-  */
-
-/** @defgroup STM32L476G_DISCOVERY_Exported_Types Exported Types
-  * @{
-  */
-
-/**
- * @brief LED Types Definition
- */
-#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB)
-typedef enum
-{
-  LED4 = 0,
-  LED5 = 1,
-  LED_RED    = LED4,
-  LED_GREEN  = LED5
-}Led_TypeDef;
-#elif defined (USE_STM32L476G_DISCO_REVA)
-typedef enum
-{
-  LED3 = 0,
-  LED4 = 1,
-  LED_RED    = LED3,
-  LED_GREEN  = LED4
-}Led_TypeDef;
-#endif
-
-/**
- * @brief JOYSTICK Types Definition
- */
-typedef enum 
-{ 
-  JOY_SEL   = 0,
-  JOY_LEFT  = 1,
-  JOY_RIGHT = 2,
-  JOY_DOWN  = 3,
-  JOY_UP    = 4,
-  JOY_NONE  = 5
-}JOYState_TypeDef;
-
-typedef enum 
-{  
-  JOY_MODE_GPIO = 0,
-  JOY_MODE_EXTI = 1
-}JOYMode_TypeDef;
-
-typedef enum 
-{  
-  SUPPLY_MODE_ERROR = 0,
-  SUPPLY_MODE_EXTERNAL = 1,
-  SUPPLY_MODE_BATTERY = 2
-}SupplyMode_TypeDef;
-
-/**
-  * @}
-  */
-
-/** @defgroup STM32L476G_DISCOVERY_Exported_Constants Exported Constants
-  * @{
-  */
-
-/** @defgroup STM32L476G_DISCOVERY_BATTERY BATTERY Detection Constants
-  * @{
-  */
-#define BATTERY_DETECTION_PIN                 GPIO_PIN_3
-#define BATTERY_DETECTION_GPIO_PORT           GPIOB
-#define BATTERY_DETECTION_GPIO_CLK_ENABLE()   __HAL_RCC_GPIOB_CLK_ENABLE()
-#define BATTERY_DETECTION_GPIO_CLK_DISABLE()  __HAL_RCC_GPIOB_CLK_DISABLE()
-/**
-  * @}
-  */ 
-
-/** @defgroup STM32L476G_DISCOVERY_LED LED Constants
-  * @{
-  */
-#define LEDn                              2
-
-#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB)
-#define LED4_PIN                          GPIO_PIN_2
-#define LED4_GPIO_PORT                    GPIOB
-#define LED4_GPIO_CLK_ENABLE()            __HAL_RCC_GPIOB_CLK_ENABLE()
-#define LED4_GPIO_CLK_DISABLE()           __HAL_RCC_GPIOB_CLK_DISABLE()
-
-#define LED5_PIN                          GPIO_PIN_8
-#define LED5_GPIO_PORT                    GPIOE
-#define LED5_GPIO_CLK_ENABLE()            __HAL_RCC_GPIOE_CLK_ENABLE()
-#define LED5_GPIO_CLK_DISABLE()           __HAL_RCC_GPIOE_CLK_DISABLE()
-
-#define LEDx_GPIO_CLK_ENABLE(__LED__)     do { if((__LED__) == LED4) { LED4_GPIO_CLK_ENABLE(); } else \
-                                               if((__LED__) == LED5) { LED5_GPIO_CLK_ENABLE(); } } while(0)
-
-#define LEDx_GPIO_CLK_DISABLE(__LED__)    do { if((__LED__) == LED4) { LED4_GPIO_CLK_DISABLE(); } else \
-                                               if((__LED__) == LED5) { LED5_GPIO_CLK_DISABLE(); } } while(0)
-
-#elif defined (USE_STM32L476G_DISCO_REVA)
-#define LED3_PIN                          GPIO_PIN_2
-#define LED3_GPIO_PORT                    GPIOB
-#define LED3_GPIO_CLK_ENABLE()            __HAL_RCC_GPIOB_CLK_ENABLE()
-#define LED3_GPIO_CLK_DISABLE()           __HAL_RCC_GPIOB_CLK_DISABLE()
-
-#define LED4_PIN                          GPIO_PIN_8
-#define LED4_GPIO_PORT                    GPIOE
-#define LED4_GPIO_CLK_ENABLE()            __HAL_RCC_GPIOE_CLK_ENABLE()
-#define LED4_GPIO_CLK_DISABLE()           __HAL_RCC_GPIOE_CLK_DISABLE()
-
-#define LEDx_GPIO_CLK_ENABLE(__LED__)     do { if((__LED__) == LED3) { LED3_GPIO_CLK_ENABLE(); } else \
-                                               if((__LED__) == LED4) { LED4_GPIO_CLK_ENABLE(); } } while(0)
-
-#define LEDx_GPIO_CLK_DISABLE(__LED__)    do { if((__LED__) == LED3) { LED3_GPIO_CLK_DISABLE(); } else \
-                                               if((__LED__) == LED4) { LED4_GPIO_CLK_DISABLE(); } } while(0)
-
-#endif
-/**
-  * @}
-  */
-
-/** @defgroup STM32L476G_DISCOVERY_BUTTON  BUTTON Constants
-  * @{
-  */
-#define JOYn                              5
-
-/**
-* @brief Joystick Right push-button
-*/
-#define RIGHT_JOY_PIN                     GPIO_PIN_2  /* PA.02 */
-#define RIGHT_JOY_GPIO_PORT               GPIOA
-#define RIGHT_JOY_GPIO_CLK_ENABLE()       __HAL_RCC_GPIOA_CLK_ENABLE()
-#define RIGHT_JOY_GPIO_CLK_DISABLE()      __HAL_RCC_GPIOA_CLK_DISABLE()
-#define RIGHT_JOY_EXTI_IRQn               EXTI2_IRQn
-
-/**
-* @brief Joystick Left push-button
-*/
-#define LEFT_JOY_PIN                      GPIO_PIN_1  /* PA.01 */
-#define LEFT_JOY_GPIO_PORT                GPIOA
-#define LEFT_JOY_GPIO_CLK_ENABLE()        __HAL_RCC_GPIOA_CLK_ENABLE()
-#define LEFT_JOY_GPIO_CLK_DISABLE()       __HAL_RCC_GPIOA_CLK_DISABLE()
-#define LEFT_JOY_EXTI_IRQn                EXTI1_IRQn  
-
-/**
-* @brief Joystick Up push-button
-*/
-#define UP_JOY_PIN                        GPIO_PIN_3  /* PA.03 */
-#define UP_JOY_GPIO_PORT                  GPIOA
-#define UP_JOY_GPIO_CLK_ENABLE()          __HAL_RCC_GPIOA_CLK_ENABLE()
-#define UP_JOY_GPIO_CLK_DISABLE()         __HAL_RCC_GPIOA_CLK_DISABLE()
-#define UP_JOY_EXTI_IRQn                  EXTI3_IRQn
-
-/**
- * @brief Joystick Down push-button
- */  
-#define DOWN_JOY_PIN                      GPIO_PIN_5   /* PA.05 */
-#define DOWN_JOY_GPIO_PORT                GPIOA
-#define DOWN_JOY_GPIO_CLK_ENABLE()        __HAL_RCC_GPIOA_CLK_ENABLE()
-#define DOWN_JOY_GPIO_CLK_DISABLE()       __HAL_RCC_GPIOA_CLK_DISABLE()
-#define DOWN_JOY_EXTI_IRQn                EXTI9_5_IRQn
-
-/**
- * @brief Joystick Sel push-button
- */
-#define SEL_JOY_PIN                       GPIO_PIN_0   /* PA.00 */
-#define SEL_JOY_GPIO_PORT                 GPIOA
-#define SEL_JOY_GPIO_CLK_ENABLE()         __HAL_RCC_GPIOA_CLK_ENABLE()
-#define SEL_JOY_GPIO_CLK_DISABLE()        __HAL_RCC_GPIOA_CLK_DISABLE()
-#define SEL_JOY_EXTI_IRQn                 EXTI0_IRQn 
-
-#define JOYx_GPIO_CLK_ENABLE(__JOY__)     do { if((__JOY__) == JOY_SEL)   { SEL_JOY_GPIO_CLK_ENABLE();   } else \
-                                               if((__JOY__) == JOY_DOWN)  { DOWN_JOY_GPIO_CLK_ENABLE();  } else \
-                                               if((__JOY__) == JOY_LEFT)  { LEFT_JOY_GPIO_CLK_ENABLE();  } else \
-                                               if((__JOY__) == JOY_RIGHT) { RIGHT_JOY_GPIO_CLK_ENABLE(); } else \
-                                               if((__JOY__) == JOY_UP)    { UP_JOY_GPIO_CLK_ENABLE(); }  } while(0)
-
-#define JOYx_GPIO_CLK_DISABLE(__JOY__)    do { if((__JOY__) == JOY_SEL)   { SEL_JOY_GPIO_CLK_DISABLE();   } else \
-                                               if((__JOY__) == JOY_DOWN)  { DOWN_JOY_GPIO_CLK_DISABLE();  } else \
-                                               if((__JOY__) == JOY_LEFT)  { LEFT_JOY_GPIO_CLK_DISABLE();  } else \
-                                               if((__JOY__) == JOY_RIGHT) { RIGHT_JOY_GPIO_CLK_DISABLE(); } else \
-                                               if((__JOY__) == JOY_UP)    { UP_JOY_GPIO_CLK_DISABLE(); }  } while(0)
-
-#define JOY_ALL_PINS                      (RIGHT_JOY_PIN | LEFT_JOY_PIN | UP_JOY_PIN | DOWN_JOY_PIN | SEL_JOY_PIN)
-
-/**
-  * @}
-  */
-
-/** @defgroup STM32L476G_DISCOVERY_BUS  BUS Constants
-  * @{
-  */
-#if defined(HAL_SPI_MODULE_ENABLED)
-/*##################### SPI2 ###################################*/
-#define DISCOVERY_SPIx                          SPI2
-#define DISCOVERY_SPIx_CLOCK_ENABLE()           __HAL_RCC_SPI2_CLK_ENABLE()
-#define DISCOVERY_SPIx_CLOCK_DISABLE()          __HAL_RCC_SPI2_CLK_DISABLE()
-#define DISCOVERY_SPIx_GPIO_PORT                GPIOD                      /* GPIOD */
-#define DISCOVERY_SPIx_AF                       GPIO_AF5_SPI2
-#define DISCOVERY_SPIx_GPIO_CLK_ENABLE()        __HAL_RCC_GPIOD_CLK_ENABLE()
-#define DISCOVERY_SPIx_GPIO_CLK_DISABLE()       __HAL_RCC_GPIOD_CLK_DISABLE()
-#define DISCOVERY_SPIx_GPIO_FORCE_RESET()       __HAL_RCC_SPI2_FORCE_RESET()
-#define DISCOVERY_SPIx_GPIO_RELEASE_RESET()     __HAL_RCC_SPI2_RELEASE_RESET()
-#define DISCOVERY_SPIx_SCK_PIN                  GPIO_PIN_1                 /* PD.01*/
-#define DISCOVERY_SPIx_MISO_PIN                 GPIO_PIN_3                 /* PD.03 */
-#define DISCOVERY_SPIx_MOSI_PIN                 GPIO_PIN_4                 /* PD.04 */
-
-/* Maximum Timeout values for flags waiting loops. These timeouts are not based
-   on accurate values, they just guarantee that the application will not remain
-   stuck if the SPI communication is corrupted.
-   You may modify these timeout values depending on CPU frequency and application
-   conditions (interrupts routines ...). */
-#define SPIx_TIMEOUT_MAX                        ((uint32_t)0x1000)
-/* Read/Write command */
-#define READWRITE_CMD                           ((uint8_t)0x80) 
-/* Multiple byte read/write command */ 
-#define MULTIPLEBYTE_CMD                        ((uint8_t)0x40)
-/* Dummy Byte Send by the SPI Master device in order to generate the Clock to the Slave device */
-#define DUMMY_BYTE                              ((uint8_t)0x00)
-
-#endif /* HAL_SPI_MODULE_ENABLED */
-
-#if defined(HAL_I2C_MODULE_ENABLED)
-/*##################### I2C1 ###################################*/
-/* User can use this section to tailor I2C1 instance used and associated 
-   resources */
-/* Definition for I2C1 Pins */
-#define DISCOVERY_I2C1_SCL_GPIO_PORT            GPIOB
-#define DISCOVERY_I2C1_SDA_GPIO_PORT            GPIOB
-#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB)
-#define DISCOVERY_I2C1_SCL_PIN                  GPIO_PIN_6
-#define DISCOVERY_I2C1_SDA_PIN                  GPIO_PIN_7
-#elif defined (USE_STM32L476G_DISCO_REVA)
-#define DISCOVERY_I2C1_SCL_PIN                  GPIO_PIN_8
-#define DISCOVERY_I2C1_SDA_PIN                  GPIO_PIN_9
-#endif
-#define DISCOVERY_I2C1_SCL_SDA_AF               GPIO_AF4_I2C1
-
-/* Definition for I2C1 clock resources */
-#define DISCOVERY_I2C1                          I2C1
-#define DISCOVERY_I2C1_CLK_ENABLE()             __HAL_RCC_I2C1_CLK_ENABLE()
-#define DISCOVERY_I2C1_CLK_DISABLE()            __HAL_RCC_I2C1_CLK_DISABLE()
-#define DISCOVERY_I2C1_SDA_GPIO_CLK_ENABLE()    __HAL_RCC_GPIOB_CLK_ENABLE()
-#define DISCOVERY_I2C1_SCL_GPIO_CLK_ENABLE()    __HAL_RCC_GPIOB_CLK_ENABLE()
-#define DISCOVERY_I2C1_SDA_GPIO_CLK_DISABLE()   __HAL_RCC_GPIOB_CLK_DISABLE()
-#define DISCOVERY_I2C1_SCL_GPIO_CLK_DISABLE()   __HAL_RCC_GPIOB_CLK_DISABLE()
-#define DISCOVERY_I2C1_FORCE_RESET()            __HAL_RCC_I2C1_FORCE_RESET()
-#define DISCOVERY_I2C1_RELEASE_RESET()          __HAL_RCC_I2C1_RELEASE_RESET()
-    
-/* Definition for I2C1's NVIC */
-#define DISCOVERY_I2C1_EV_IRQn                  I2C1_EV_IRQn
-#define DISCOVERY_I2C1_EV_IRQHandler            I2C1_EV_IRQHandler
-#define DISCOVERY_I2C1_ER_IRQn                  I2C1_ER_IRQn
-#define DISCOVERY_I2C1_ER_IRQHandler            I2C1_ER_IRQHandler
-
-/* I2C TIMING Register define when I2C clock source is SYSCLK */
-/* I2C TIMING is calculated in case of the I2C Clock source is the SYSCLK = 80 MHz */
-/* Set 0x90112626 value to reach 100 KHz speed (Rise time = 640ns, Fall time = 20ns) */
-#ifndef DISCOVERY_I2C1_TIMING
- #define DISCOVERY_I2C1_TIMING                  0x90112626
-#endif /* DISCOVERY_I2C1_TIMING */
-
-/* I2C clock speed configuration (in Hz) 
-   WARNING: 
-   Make sure that this define is not already declared in other files (ie. 
-   stm324xg_discovery.h file). It can be used in parallel by other modules. */
-#ifndef BSP_I2C_SPEED
- #define BSP_I2C_SPEED                              100000
-#endif /* BSP_I2C_SPEED */
-
-
-/* Audio codec I2C address */
-#define AUDIO_I2C_ADDRESS                       ((uint16_t) 0x94)
-
-/* Maximum Timeout values for flags waiting loops. These timeouts are not based
-   on accurate values, they just guarantee that the application will not remain
-   stuck if the I2C communication is corrupted.
-   You may modify these timeout values depending on CPU frequency and application
-   conditions (interrupts routines ...). */   
-#define DISCOVERY_I2C1_TIMEOUT_MAX              3000
-
-
-/*##################### I2C2 ###################################*/
-/* User can use this section to tailor I2C2 instance used and associated 
-   resources */
-/* Definition for I2C2 Pins */
-#define DISCOVERY_I2C2_SCL_PIN                  GPIO_PIN_10
-#define DISCOVERY_I2C2_SCL_GPIO_PORT            GPIOB
-#define DISCOVERY_I2C2_SDA_PIN                  GPIO_PIN_11
-#define DISCOVERY_I2C2_SDA_GPIO_PORT            GPIOB
-#define DISCOVERY_I2C2_SCL_SDA_AF               GPIO_AF4_I2C2
-/* Definition for I2C2 clock resources */
-#define DISCOVERY_I2C2                          I2C2
-#define DISCOVERY_I2C2_CLK_ENABLE()             __HAL_RCC_I2C2_CLK_ENABLE()
-#define DISCOVERY_I2C2_CLK_DISABLE()            __HAL_RCC_I2C2_CLK_DISABLE()
-#define DISCOVERY_I2C2_SDA_GPIO_CLK_ENABLE()    __HAL_RCC_GPIOB_CLK_ENABLE()
-#define DISCOVERY_I2C2_SCL_GPIO_CLK_ENABLE()    __HAL_RCC_GPIOB_CLK_ENABLE()
-#define DISCOVERY_I2C2_SDA_GPIO_CLK_DISABLE()   __HAL_RCC_GPIOB_CLK_DISABLE()
-#define DISCOVERY_I2C2_SCL_GPIO_CLK_DISABLE()   __HAL_RCC_GPIOB_CLK_DISABLE()
-#define DISCOVERY_I2C2_FORCE_RESET()            __HAL_RCC_I2C2_FORCE_RESET()
-#define DISCOVERY_I2C2_RELEASE_RESET()          __HAL_RCC_I2C2_RELEASE_RESET()
-    
-/* Definition for I2C2's NVIC */
-#define DISCOVERY_I2C2_EV_IRQn                  I2C2_EV_IRQn
-#define DISCOVERY_I2C2_ER_IRQn                  I2C2_ER_IRQn
-
-/* I2C TIMING Register define when I2C clock source is SYSCLK */
-/* I2C TIMING is calculated in case of the I2C Clock source is the SYSCLK = 80 MHz */
-/* Set 0x90112626 value to reach 100 KHz speed (Rise time = 640ns, Fall time = 20ns) */
-#ifndef DISCOVERY_I2C2_TIMING
- #define DISCOVERY_I2C2_TIMING                  0x90112626
-#endif /* DISCOVERY_I2C2_TIMING */
-
-/* I2C clock speed configuration (in Hz) 
-   WARNING: 
-   Make sure that this define is not already declared in other files (ie. 
-   stm324xg_discovery.h file). It can be used in parallel by other modules. */
-#ifndef BSP_I2C_SPEED
- #define BSP_I2C_SPEED                              100000
-#endif /* BSP_I2C_SPEED */
-
-#define IDD_I2C_ADDRESS                         ((uint16_t) 0x84)
-
-/* Maximum Timeout values for flags waiting loops. These timeouts are not based
-   on accurate values, they just guarantee that the application will not remain
-   stuck if the I2C communication is corrupted.
-   You may modify these timeout values depending on CPU frequency and application
-   conditions (interrupts routines ...). */   
-#define DISCOVERY_I2C2_TIMEOUT_MAX              3000
-#endif /* HAL_I2C_MODULE_ENABLED */
-
-/*##################### Accelerometer ##########################*/
-/**
-  * @brief  Accelerometer Chip Select macro definition
-  */
-#define ACCELERO_CS_LOW()                       HAL_GPIO_WritePin(ACCELERO_CS_GPIO_PORT, ACCELERO_CS_PIN, GPIO_PIN_RESET)
-#define ACCELERO_CS_HIGH()                      HAL_GPIO_WritePin(ACCELERO_CS_GPIO_PORT, ACCELERO_CS_PIN, GPIO_PIN_SET)
-
-/**
-  * @brief  Accelerometer SPI Interface pins
-  */
-#define ACCELERO_CS_GPIO_PORT                   GPIOE                       /* GPIOE */
-#define ACCELERO_CS_GPIO_CLK_ENABLE()           __HAL_RCC_GPIOE_CLK_ENABLE()
-#define ACCELERO_CS_GPIO_CLK_DISABLE()          __HAL_RCC_GPIOE_CLK_DISABLE()
-#define ACCELERO_CS_PIN                         GPIO_PIN_0                  /* PE.00 */
-
-/**
-  * @brief  Accelerometer Interrupt pins
-  */
-#define ACCELERO_XLINT_GPIO_PORT                  GPIOE                       /* GPIOE */
-#define ACCELERO_XLINT_GPIO_CLK_ENABLE()         __HAL_RCC_GPIOE_CLK_ENABLE()
-#define ACCELERO_XLINT_GPIO_CLK_DISABLE()        __HAL_RCC_GPIOE_CLK_DISABLE()
-#define ACCELERO_XLINT_PIN                       GPIO_PIN_1                  /* PE.01 */
-#define ACCELERO_XLINT_EXTI_IRQn                 EXTI1_IRQn
-
-/*##################### Magnetometer ##########################*/
-/**
-  * @brief  Magnetometer Chip Select macro definition
-  */
-#define MAGNETO_CS_LOW()                        HAL_GPIO_WritePin(MAGNETO_CS_GPIO_PORT, MAGNETO_CS_PIN, GPIO_PIN_RESET)
-#define MAGNETO_CS_HIGH()                       HAL_GPIO_WritePin(MAGNETO_CS_GPIO_PORT, MAGNETO_CS_PIN, GPIO_PIN_SET)
-
-/**
-  * @brief  Magnetometer SPI Interface pins
-  */
-#define MAGNETO_CS_GPIO_PORT                    GPIOC                       /* GPIOC */
-#define MAGNETO_CS_GPIO_CLK_ENABLE()            __HAL_RCC_GPIOC_CLK_ENABLE()
-#define MAGNETO_CS_GPIO_CLK_DISABLE()           __HAL_RCC_GPIOC_CLK_DISABLE()
-#define MAGNETO_CS_PIN                          GPIO_PIN_0                  /* PC.00 */
-
-
-/**
-  * @brief  Magnetometer Interrupt pins
-  */
-#define MAGNETO_INT_GPIO_PORT                   GPIOC                       /* GPIOC */
-#define MAGNETO_INT_GPIO_CLK_ENABLE()           __HAL_RCC_GPIOC_CLK_ENABLE()
-#define MAGNETO_INT_GPIO_CLK_DISABLE()          __HAL_RCC_GPIOC_CLK_DISABLE()
-#define MAGNETO_INT1_PIN                        GPIO_PIN_1                  /* PC.01 */
-#define MAGNETO_INT1_EXTI_IRQn                  EXTI1_IRQn
-
-#define MAGNETO_DRDY_GPIO_PORT                   GPIOC                       /* GPIOC */
-#define MAGNETO_DRDY_GPIO_CLK_ENABLE()           __HAL_RCC_GPIOC_CLK_ENABLE()
-#define MAGNETO_DRDY_GPIO_CLK_DISABLE()          __HAL_RCC_GPIOC_CLK_DISABLE()
-#define MAGNETO_DRDY_PIN                        GPIO_PIN_2                  /* PC.01 */
-
-
-/*##################### Audio Codec ##########################*/
-/**
-  * @brief  Audio codec chip reset definition
-  */
-/* Audio codec power on/off macro definition */
-#define CODEC_AUDIO_POWER_OFF()      HAL_GPIO_WritePin(AUDIO_RESET_GPIO, AUDIO_RESET_PIN, GPIO_PIN_RESET)
-#define CODEC_AUDIO_POWER_ON()       HAL_GPIO_WritePin(AUDIO_RESET_GPIO, AUDIO_RESET_PIN, GPIO_PIN_SET)
-
-/* Audio Reset Pin definition */
-#define AUDIO_RESET_GPIO_CLK_ENABLE()           __HAL_RCC_GPIOE_CLK_ENABLE()
-#define AUDIO_RESET_GPIO_CLK_DISABLE()          __HAL_RCC_GPIOE_CLK_DISABLE()
-#define AUDIO_RESET_PIN                         GPIO_PIN_3
-#define AUDIO_RESET_GPIO                        GPIOE
-
-/*##################### Gyroscope ##########################*/
-/**
-  * @brief  Gyroscope Chip Select macro definition
-  */
-#define GYRO_CS_LOW()                           HAL_GPIO_WritePin(GYRO_CS_GPIO_PORT, GYRO_CS_PIN, GPIO_PIN_RESET)
-#define GYRO_CS_HIGH()                          HAL_GPIO_WritePin(GYRO_CS_GPIO_PORT, GYRO_CS_PIN, GPIO_PIN_SET)
-  
-/**
-  * @brief  Gyroscope SPI Interface pins
-  */
-#define GYRO_CS_GPIO_PORT                       GPIOD                       /* GPIOD */
-#define GYRO_CS_GPIO_CLK_ENABLE()               __HAL_RCC_GPIOD_CLK_ENABLE()
-#define GYRO_CS_GPIO_CLK_DISABLE()              __HAL_RCC_GPIOD_CLK_DISABLE()
-#define GYRO_CS_PIN                             GPIO_PIN_7                  /* PD.07 */
-
-/**
-  * @brief  Gyroscope Interrupt pins
-  */
-#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB)
-#define GYRO_INT1_GPIO_PORT                     GPIOD                       /* GPIOD */
-#define GYRO_INT1_GPIO_CLK_ENABLE()             __HAL_RCC_GPIOD_CLK_ENABLE()
-#define GYRO_INT1_GPIO_CLK_DISABLE()            __HAL_RCC_GPIOD_CLK_DISABLE()
-#define GYRO_INT1_PIN                           GPIO_PIN_2                  /* PD.02 */
-#define GYRO_INT1_EXTI_IRQn                     EXTI2_IRQn
-#define GYRO_INT2_GPIO_PORT                     GPIOB                       /* GPIOB */
-#define GYRO_INT2_GPIO_CLK_ENABLE()             __HAL_RCC_GPIOB_CLK_ENABLE()
-#define GYRO_INT2_GPIO_CLK_DISABLE()            __HAL_RCC_GPIOB_CLK_DISABLE()
-#define GYRO_INT2_PIN                           GPIO_PIN_8                  /* PB.08 */
-#define GYRO_INT2_EXTI_IRQn                     EXTI9_5_IRQn
-#elif defined (USE_STM32L476G_DISCO_REVA)
-#define GYRO_INT1_GPIO_PORT                     GPIOB                       /* GPIOB */
-#define GYRO_INT1_GPIO_CLK_ENABLE()             __HAL_RCC_GPIOB_CLK_ENABLE()
-#define GYRO_INT1_GPIO_CLK_DISABLE()            __HAL_RCC_GPIOB_CLK_DISABLE()
-#define GYRO_INT1_PIN                           GPIO_PIN_6                  /* PB.06 */
-#define GYRO_INT1_EXTI_IRQn                     EXTI9_5_IRQn
-#define GYRO_INT2_GPIO_PORT                     GPIOB                       /* GPIOB */
-#define GYRO_INT2_GPIO_CLK_ENABLE()             __HAL_RCC_GPIOB_CLK_ENABLE()
-#define GYRO_INT2_GPIO_CLK_DISABLE()            __HAL_RCC_GPIOB_CLK_DISABLE()
-#define GYRO_INT2_PIN                           GPIO_PIN_7                  /* PB.07 */
-#define GYRO_INT2_EXTI_IRQn                     EXTI9_5_IRQn
-#endif
-
-/*##################### Idd ##########################*/
-/**
-  * @brief  Idd current measurement interface pins
-  */
-#define IDD_INT_GPIO_PORT                       GPIOC                       /* GPIOC */
-#define IDD_INT_GPIO_CLK_ENABLE()               __HAL_RCC_GPIOC_CLK_ENABLE()
-#define IDD_INT_GPIO_CLK_DISABLE()              __HAL_RCC_GPIOC_CLK_DISABLE()
-#define IDD_INT_PIN                             GPIO_PIN_13                  /* PC.13 */
-#define IDD_INT_EXTI_IRQn                       EXTI15_10_IRQn
-
-#define IDD_WAKEUP_GPIO_PORT                    GPIOA                       /* GPIOA */
-#define IDD_WAKEUP_GPIO_CLK_ENABLE()            __HAL_RCC_GPIOA_CLK_ENABLE()
-#define IDD_WAKEUP_GPIO_CLK_DISABLE()           __HAL_RCC_GPIOA_CLK_DISABLE()
-#define IDD_WAKEUP_PIN                          GPIO_PIN_4                  /* PA.04 */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-
-/** @defgroup STM32L476G_DISCOVERY_Exported_Functions Exported Functions
-  * @{
-  */
-uint32_t                BSP_GetVersion(void);
-SupplyMode_TypeDef      BSP_SupplyModeDetection(void);
-void                    BSP_LED_Init(Led_TypeDef Led);
-void                    BSP_LED_DeInit(Led_TypeDef Led);
-void                    BSP_LED_On(Led_TypeDef Led);
-void                    BSP_LED_Off(Led_TypeDef Led);
-void                    BSP_LED_Toggle(Led_TypeDef Led);
-uint8_t                 BSP_JOY_Init(JOYMode_TypeDef Joy_Mode);
-void                    BSP_JOY_DeInit(void);
-JOYState_TypeDef        BSP_JOY_GetState(void);
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32L476G_DISCOVERY_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
--- a/stm32l476g_discovery_audio.c	Thu Dec 03 22:16:32 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1070 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32l476g_discovery_audio.c
-  * @author  MCD Application Team
-  * @version V1.0.1
-  * @date    16-September-2015
-  * @brief   This file provides a set of functions needed to manage the 
-  *          Audio driver for the STM32L476G-Discovery board.
-  ******************************************************************************
-  * @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.
-  *
-  ******************************************************************************
-  */
-
-/*==============================================================================
-                                 User NOTES
-                                 
-1. How To use this driver:
---------------------------
-   + This driver supports STM32L4xx devices on STM32L476G-Discovery (MB1184) Discovery boards.
-        a) to play an audio file (all functions names start by BSP_AUDIO_OUT_xxx)
-        b) to record an audio file through MP34DT01TR, ST MEMS (all functions names start by BSP_AUDIO_IN_xxx)
-
-a) PLAY A FILE:
-==============
-   + Call the function BSP_AUDIO_OUT_Init(
-                                    OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER, 
-                                                  OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
-                                    Volume      : Initial volume to be set (0 is min (mute), 100 is max (100%)
-                                    AudioFreq   : Audio frequency in Hz (8000, 16000, 22500, 32000...)
-                                                  this parameter is relative to the audio file/stream type.
-                                   )
-      This function configures all the hardware required for the audio application (codec, I2C, SAI, 
-      GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
-      If the returned value is different from AUDIO_OK or the function is stuck then the communication with
-      the audio codec has failed.
-      - OUTPUT_DEVICE_SPEAKER  : only speaker will be set as output for the audio stream.
-      - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
-      - OUTPUT_DEVICE_BOTH     : both Speaker and Headphone are used as outputs for the audio stream
-                                 at the same time.
-
-   + Call the function BSP_AUDIO_OUT_RegisterCallbacks to register user callbacks
-     required to manage audio data streaming towards the audio codec (ErrorCallback(),
-     HalfTransfer_CallBack() and TransferComplete_CallBack()).
-
-   + Call the function BSP_AUDIO_OUT_Play() to start audio playback (for the first time).
-   + Call the function BSP_AUDIO_OUT_Pause() to pause audio playabck   
-   + Call the function BSP_AUDIO_OUT_Resume() to resume audio playback.
-       Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
-          for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
-       Note. This function should be called only when the audio file is played or paused (not stopped).
-   + Call the function BSP_AUDIO_OUT_Stop() to stop audio playback.
-   + To modify the volume level, the sampling frequency, the device output mode, 
-      the mute status or the audio configuration or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(), 
-      AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetOutputMode(), BSP_AUDIO_OUT_SetMute()and 
-      BSP_AUDIO_OUT_ChangeAudioConfig().
- 
-Driver architecture:
---------------------
-   + This driver provides the audio layer high level API: it consists in functions
-     exported in the stm32l476g_discovery_audio.h file (e.g. BSP_AUDIO_OUT_Init(),
-     BSP_AUDIO_OUT_Play(), ...).
-   + This driver also includes the Media Access Layer (MAL): it consists in 
-     functions allowing to access setup the audio devices. These functions 
-     are  included as local functions into the stm32l476g_discovery_audio.c file
-     (e.g. AUDIO_SAIx_Init()).
-
-Known Limitations:
-------------------
-   1- Communication with the audio codec (through I2C) may be corrupted if it is interrupted by some
-      user interrupt routines (in this case, interrupts could be disabled just before the start of 
-      communication then re-enabled when it is over). Note that this communication is only done at
-      the configuration phase (BSP_AUDIO_OUT_Init() or BSP_AUDIO_OUT_Stop()) and when Volume control modification is 
-      performed (BSP_AUDIO_OUT_SetVolume() or BSP_AUDIO_OUT_SetMute()or BSP_AUDIO_OUT_SetOutputMode()). 
-      When the audio data is played, no communication is required with the audio codec.
-   2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size, 
-      File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
-   3- Supports only 16-bits audio data size.
-
-b) RECORD A FILE:
-================
-   + Call the function BSP_AUDIO_IN_Init(
-                                    AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000 ...)
-                                    )
-      This function configures all the hardware required for the audio application (DFSDM, 
-      GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if the 
-      configuration completes successfully.
-
-   + Call the function BSP_AUDIO_IN_RegisterCallbacks to register user callbacks
-     used to stream audio data toward the record buffer (ErrorCallback(),
-     HalfTransfer_CallBack() and TransferComplete_CallBack()).
-
-   + Call the function BSP_AUDIO_IN_Record(
-                            pbuf Main buffer pointer for the recorded data storing  
-                            size Current size of the recorded buffer
-                            )
-      to start recording from the microphone.
-
-   + Call the function AUDIO_IN_STOP() to stop recording 
-==============================================================================*/
-
-/* Includes ------------------------------------------------------------------*/
-#include <string.h>
-#include "stm32l476g_discovery_audio.h"
-
-/** @addtogroup BSP
-  * @{
-  */
-
-/** @addtogroup STM32L476G_DISCOVERY
-  * @{
-  */
-
-/** @defgroup STM32L476G_DISCOVERY_AUDIO STM32L476G-DISCOVERY AUDIO
-  * @brief This file includes the low layer driver for cs43l22 Audio Codec
-  *        available on STM32L476G-Discovery board(MB1184).
-  * @{
-  */ 
-
-/* Private typedef -----------------------------------------------------------*/
-/** @defgroup STM32L476G_DISCOVERY_AUDIO_Private_Types Private Types
-  * @{
-  */
-typedef struct
-{
-  
-  Audio_CallbackTypeDef CbError;            /* pointer to the callback function invoked when ... */
-  Audio_CallbackTypeDef CbHalfTransfer;     /* pointer to the callback function invoked when ... */
-  Audio_CallbackTypeDef CbTransferComplete; /* pointer to the callback function invoked when ... */
-} AUDIO_OUT_TypeDef;
-
-typedef struct
-{
-  DFSDM_Channel_HandleTypeDef hDfsdmLeftChannel;  /* DFSDM channel handle used for left channel */
-  DMA_HandleTypeDef           hDmaDfsdmLeft;      /* DMA handle used for DFSDM regular conversions on left channel */
-  int32_t *                   LeftRecBuff;        /* Buffers for left samples */
-  uint32_t                Frequency;        /* Record Frequency */
-  uint32_t                BitResolution;    /* Record bit resolution */
-  uint32_t                ChannelNbr;       /* Record Channel Number */
-  uint16_t *              pRecBuf;          /* Pointer to record user buffer */
-  uint32_t                RecSize;          /* Size to record in mono, double size to record in stereo */
-  Audio_CallbackTypeDef       CbError;            /* pointer to the callback function invoked when a DMA transfer fails */
-  Audio_CallbackTypeDef       CbHalfTransfer;     /* pointer to the callback function invoked when half of the DMA transfer is completed */
-  Audio_CallbackTypeDef       CbTransferComplete; /* pointer to the callback function invoked when the DMA transfer is completed */
-} AUDIO_IN_TypeDef;
-
-/**
-  * @}
-  */
-
-/* Private defines ------------------------------------------------------------*/
-/** @defgroup STM32L476G_DISCOVERY_AUDIO_Private_Constants Private Constants
-  * @{
-  */
-/**
-  * @}
-  */
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup STM32L476G_DISCOVERY_AUDIO_Private_Macros Private Macros
-  * @{
-  */
-/*### PLAY ###*/
-/* SCK(kHz) = SAI_CK_x/(SAIClockDivider*2*256) */
-#define SAIClockDivider(__FREQUENCY__) \
-        (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 12 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 2 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 6 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 1 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 3 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 0 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 2 : 1  \
-
-/*### RECORD ###*/
-#define DFSDMOverSampling(__FREQUENCY__) \
-        (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 256 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 256 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 128 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 128 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 64 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 64  \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 32 : 16  \
-
-#define DFSDMClockDivider(__FREQUENCY__) \
-        (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 24 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 4 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 24 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 4 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 24 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 4  \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 32 : 32  \
-
-#define DFSDMFilterOrder(__FREQUENCY__) \
-        (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? DFSDM_FILTER_SINC3_ORDER \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? DFSDM_FILTER_SINC3_ORDER \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? DFSDM_FILTER_SINC3_ORDER \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? DFSDM_FILTER_SINC3_ORDER \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? DFSDM_FILTER_SINC4_ORDER \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? DFSDM_FILTER_SINC4_ORDER  \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? DFSDM_FILTER_SINC4_ORDER : DFSDM_FILTER_SINC5_ORDER  \
-
-#define DFSDMRightBitShift(__FREQUENCY__) \
-        (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 2 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 3 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 3 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 0 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 3 \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 3  \
-      : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 7 : 0  \
-
-/* Saturate the record PCM sample */
-#define SaturaLH(N, L, H) (((N)<(L))?(L):(((N)>(H))?(H):(N)))
-
-/**
-  * @}
-  */ 
-  
-/* Private variables ---------------------------------------------------------*/
-/** @defgroup STM32L476G_DISCOVERY_AUDIO_Private_Variables Private Variables
-  * @{
-  */
-/* Audio output context information */
-static AUDIO_OUT_TypeDef hAudioOut;
-
-/* Audio input context information */
-static AUDIO_IN_TypeDef hAudioIn;
-
-/* SAI DMA handle */
-static DMA_HandleTypeDef hDmaSai;
-/**
-  * @}
-  */
-
-/* Exported variables ---------------------------------------------------------*/
-/** @defgroup STM32L476G_DISCOVERY_AUDIO_Exported_Variables Exported Variables
-  * @{
-  */
-/* SAIx handle */
-SAI_HandleTypeDef               BSP_AUDIO_hSai;
-    
-/* DFSDM filter handle */
-DFSDM_Filter_HandleTypeDef      BSP_AUDIO_hDfsdmLeftFilter;
-/**
-  * @}
-  */
-
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup STM32L476G_DISCOVERY_AUDIO_Private_Functions Private Functions
-  * @{
-  */
-static void    AUDIO_CODEC_Reset(void);
-static uint8_t AUDIO_SAIx_Init(uint32_t AudioFreq);
-static uint8_t AUDIO_SAIx_DeInit(void);
-static uint8_t AUDIO_DFSDMx_Init(uint32_t AudioFreq);
-static uint8_t AUDIO_DFSDMx_DeInit(void);
-static uint8_t AUDIO_SAIPLLConfig(uint32_t AudioFreq);
-/**
-  * @}
-  */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup STM32L476G_DISCOVERY_AUDIO_Exported_Functions
-  * @{
-  */ 
-
-/**
-  * @brief  Configures the audio codec related peripherals.
-  * @param  OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
-  *                       or OUTPUT_DEVICE_BOTH.
-  * @param  Volume: Initial volume level (from 0 (Mute) to 100 (Max))
-  * @param  AudioFreq: Audio frequency used to play the audio stream.ion.  
-  * @retval BSP AUDIO status
-  * @note   The SAI PLL input clock must be configure in the user application.
-  *         The SAI PLL configuration done within this function assumes that
-  *         the SAI PLL input clock runs at 8 MHz.
-  */
-
-/**
-  * @brief  Tx Transfer completed callbacks.
-  * @param  hsai: SAI handle
-  * @retval None
-  */
-void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
-{
-  /* Invoke the registered 'TransferComplete' function (if any) */
-  if (hAudioOut.CbTransferComplete != (Audio_CallbackTypeDef)NULL)
-  {
-    hAudioOut.CbTransferComplete();
-  }
-}
-
-/**
-  * @brief  Tx Half Transfer completed callbacks.
-  * @param  hsai: SAI handle
-  * @retval None
-  */
-void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
-{
-  /* Invoke the registered 'HalfTransfer' callback function (if any) */
-  if (hAudioOut.CbHalfTransfer != (Audio_CallbackTypeDef)NULL)
-  {
-    hAudioOut.CbHalfTransfer();
-  }
-}
-
-/**
-  * @brief  SAI error callbacks.
-  * @param  hsai: SAI handle
-  * @retval None
-  */
-void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
-{
-  /* Invoke the registered 'ErrorCallback' callback function (if any) */
-  if (hAudioOut.CbError != (Audio_CallbackTypeDef)NULL)
-  {
-    hAudioOut.CbError();
-  }
-}
-
-/**
-  * @}
-  */
-
-/** @addtogroup STM32L476G_EVAL_AUDIO_Exported_Functions
-  * @{
-  */
-  
-/**
-  * @brief  Initializes micropone related peripherals.
-  * @note   This function assumes that the SAI input clock (through PLL_M)
-  *         is already configured and ready to be used.  
-  * @param  AudioFreq: Audio frequency to be configured for the SAI peripheral. 
-  * @param  BitRes: Audio frequency to be configured for the SAI peripheral.
-  * @param  ChnlNbr: Audio frequency to be configured for the SAI peripheral.
-  * @retval BSP AUDIO status
-  */
-uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
-{
-  /* Update the audio input context */
-  hAudioIn.Frequency          = AudioFreq;
-  hAudioIn.BitResolution      = BitRes;
-  hAudioIn.ChannelNbr         = ChnlNbr;
-  hAudioIn.CbError            = (Audio_CallbackTypeDef)NULL; 
-  hAudioIn.CbHalfTransfer     = (Audio_CallbackTypeDef)NULL; 
-  hAudioIn.CbTransferComplete = (Audio_CallbackTypeDef)NULL;
-
-  /* Configure the SAI PLL according to the requested audio frequency */
-  if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
-  {
-    return AUDIO_ERROR;
-  }
- 
-  /* Initializes the Digital Filter for Sigma-Delta Modulators interface */
-  if(AUDIO_DFSDMx_Init(AudioFreq) != AUDIO_OK)
-  {
-    return AUDIO_ERROR;
-  }
-  
-  return AUDIO_OK;
-  }
-
-/**
-  * @brief  De-Initializes microphone related peripherals.
-  * @retval BSP AUDIO status
-
-  */
-uint8_t BSP_AUDIO_IN_DeInit(void)
-{
-  /* De-initializes the Digital Filter for Sigma-Delta Modulators interface */
-  if (AUDIO_DFSDMx_DeInit() != AUDIO_OK)
-  {
-    return AUDIO_ERROR;
-  }
-  
-  /* Reset the audio input context */
-  memset(&hAudioIn, 0, sizeof(hAudioIn));
-
-  return AUDIO_OK;
-}
-
-/**
-  * @brief  Starts audio recording.
-  * @param  pbuf: Main buffer pointer for the recorded data storing  
-  * @param  size: Current size of the recorded buffer
-  * @note   The Right channel is start at first with synchro on start of Left channel
-  * @retval BSP AUDIO status
-  */
-uint8_t BSP_AUDIO_IN_Record(uint16_t* pbuf, uint32_t size)
-{
-  hAudioIn.pRecBuf = pbuf;
-  hAudioIn.RecSize = size;
-
-  /* Allocate hAudioIn.LeftRecBuff buffer */
-#if defined(BSP_AUDIO_USE_RTOS)
-  hAudioIn.LeftRecBuff  = (int32_t *)k_malloc(size * sizeof(int32_t));
-#else
-  hAudioIn.LeftRecBuff  = (int32_t *)malloc(size * sizeof(int32_t));
-#endif
-  if(hAudioIn.LeftRecBuff == NULL)
-  {
-    return AUDIO_ERROR;
-  }
-
-  /* Call the Media layer start function for left channel */
-  if(HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmLeftFilter, 
-                                      (int32_t*)hAudioIn.LeftRecBuff, 
-                                      (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR)) != HAL_OK)
-  {
-    return AUDIO_ERROR;
-  }
-
-  return AUDIO_OK;
-}
-
-/**
-  * @brief  Updates the audio frequency.
-  * @param  AudioFreq: Audio frequency used to record the audio stream.
-  * @note   This API should be called after the BSP_AUDIO_IN_Init() to adjust the
-  *         audio frequency.
-  * @retval BSP AUDIO status
-  */
-uint8_t BSP_AUDIO_IN_SetFrequency(uint32_t AudioFreq)
-{ 
-  /* Configure the SAI PLL according to the requested audio frequency */
-  if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
-  {
-    return AUDIO_ERROR;
-  }
-
-  /* De-initializes the Digital Filter for Sigma-Delta Modulators interface */
-  if(AUDIO_DFSDMx_DeInit() != AUDIO_OK)
-  {
-    return AUDIO_ERROR;
-  }
-  
-  /* Initializes the Digital Filter for Sigma-Delta Modulators interface */
-  if(AUDIO_DFSDMx_Init(AudioFreq) != AUDIO_OK)
-  {
-    return AUDIO_ERROR;
-  }
-  
-  return AUDIO_OK;
-}
-
-/**
-  * @brief  Regular conversion complete callback. 
-  * @note   In interrupt mode, user has to read conversion value in this function
-            using HAL_DFSDM_FilterGetRegularValue.
-  * @param  hdfsdm_filter : DFSDM filter handle.
-  * @retval None
-  */
-void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
-{
-  uint32_t index;
-  uint32_t recbufsize = (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR);
-  
-  for(index = (recbufsize/2); index < recbufsize; index++)
-  {
-    hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32760, 32760));
-  }
-  
-  /* Invoke the registered 'TransferComplete' function (if any) */
-  if (hAudioIn.CbTransferComplete != (Audio_CallbackTypeDef)NULL)
-  {
-    hAudioIn.CbTransferComplete();
-  }
-}
-
-/**
-  * @brief  Half regular conversion complete callback. 
-  * @param  hdfsdm_filter : DFSDM filter handle.
-  * @retval None
-  */
-void HAL_DFSDM_FilterRegConvHalfCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
-{
-  uint32_t index;
-  uint32_t recbufsize = (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR);
-  
-  
-  for(index = 0; index < (recbufsize/2); index++)
-  {
-    hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32760, 32760));
-  }
-  
-  /* Invoke the registered 'HalfTransfer' callback function (if any) */
-  if (hAudioIn.CbHalfTransfer != (Audio_CallbackTypeDef)NULL)
-  {
-    hAudioIn.CbHalfTransfer();
-  }
-}
-
-/**
-  * @brief  Error callback. 
-  * @param  hdfsdm_filter : DFSDM filter handle.
-  * @retval None
-  */
-void HAL_DFSDM_FilterErrorCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
-{
-  /* Invoke the registered 'ErrorCallback' callback function (if any) */
-  if (hAudioIn.CbError != (Audio_CallbackTypeDef)NULL)
-  {
-    hAudioIn.CbError();
-  }
-}
-
-/**
-  * @brief  Stops audio recording.
-  * @retval BSP AUDIO status
-  */
-uint8_t BSP_AUDIO_IN_Stop(void)
-{
-  /* Call the Media layer stop function for left channel */
-  if(HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK )
-  {
-    return AUDIO_ERROR;
-  }
-
-  /* Free hAudioIn.LeftRecBuff buffer */
-#if defined(BSP_AUDIO_USE_RTOS)
-  k_free((void *)hAudioIn.LeftRecBuff);
-#else
-  free((void *)hAudioIn.LeftRecBuff);
-#endif
-  
-  return AUDIO_OK;
-}
-
-/**
-  * @brief  Pauses the audio file stream.
-  * @retval BSP AUDIO status
-  */
-uint8_t BSP_AUDIO_IN_Pause(void)
-{    
-  /* Call the Media layer stop function */
-  if(HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
-  {
-    return AUDIO_ERROR;
-  }
-  
-  return AUDIO_OK;
-}
-
-/**
-  * @brief  Resumes the audio file stream.
-  * @retval BSP AUDIO status
-  */
-uint8_t BSP_AUDIO_IN_Resume(void)
-{    
-  /* Call the Media layer start function for left channel */
-  if(HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmLeftFilter,
-                                      (int32_t*)hAudioIn.LeftRecBuff,
-                                      (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR)) != HAL_OK)
-  {
-    return AUDIO_ERROR;
-  }
-  
-  return AUDIO_OK;
-}
-
-/**
-  * @brief  register user callback functions 
-  * @param  ErrorCallback: pointer to the error callback function
-  * @param  HalfTransferCallback: pointer to the half transfer callback function
-  * @param  TransferCompleteCallback: pointer to the transfer complete callback function
-  * @retval None
-  */
-void BSP_AUDIO_IN_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback,
-                                    Audio_CallbackTypeDef HalfTransferCallback, 
-                                    Audio_CallbackTypeDef TransferCompleteCallback)
-{
-  hAudioIn.CbError            = ErrorCallback; 
-  hAudioIn.CbHalfTransfer     = HalfTransferCallback; 
-  hAudioIn.CbTransferComplete = TransferCompleteCallback;
-}
-/**
-  * @}
-  */
-
-/* private functions --------------------------------------------------------*/
-/** @addtogroup STM32L476G_DISCOVERY_AUDIO_Private_Functions
-  * @{
-  */
-/**
-  * @brief  Initializes the Audio Codec audio interface (SAI).
-  * @param  AudioFreq: Audio frequency to be configured for the SAI peripheral.
-  * @note   The default SlotActive configuration is set to CODEC_AUDIOFRAME_SLOT_0123 
-  *         and user can update this configuration using 
-  * @retval BSP AUDIO status
-  */
-static uint8_t AUDIO_SAIx_Init(uint32_t AudioFreq)
-{
-  /* Disable SAI peripheral to allow access to SAI internal registers */
-  __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
-  
-  /* Initialize the BSP_AUDIO_hSai Instance parameter */
-  BSP_AUDIO_hSai.Instance = AUDIO_SAIx;
-  
-  /* Configure SAI_Block_x 
-  LSBFirst: Disabled 
-  DataSize: 16 */
-  BSP_AUDIO_hSai.Init.AudioMode      = SAI_MODEMASTER_TX;
-  BSP_AUDIO_hSai.Init.Synchro        = SAI_ASYNCHRONOUS;
-  BSP_AUDIO_hSai.Init.SynchroExt     = SAI_SYNCEXT_DISABLE;
-  BSP_AUDIO_hSai.Init.OutputDrive    = SAI_OUTPUTDRIVE_ENABLE;
-  BSP_AUDIO_hSai.Init.NoDivider      = SAI_MASTERDIVIDER_ENABLE;
-  BSP_AUDIO_hSai.Init.FIFOThreshold  = SAI_FIFOTHRESHOLD_1QF;
-  BSP_AUDIO_hSai.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_MCKDIV;
-  BSP_AUDIO_hSai.Init.Mckdiv         = SAIClockDivider(AudioFreq);
-  BSP_AUDIO_hSai.Init.MonoStereoMode = SAI_STEREOMODE;
-  BSP_AUDIO_hSai.Init.CompandingMode = SAI_NOCOMPANDING;
-  BSP_AUDIO_hSai.Init.TriState       = SAI_OUTPUT_NOTRELEASED;
-  BSP_AUDIO_hSai.Init.Protocol       = SAI_FREE_PROTOCOL;
-  BSP_AUDIO_hSai.Init.DataSize       = SAI_DATASIZE_16;
-  BSP_AUDIO_hSai.Init.FirstBit       = SAI_FIRSTBIT_MSB;
-  BSP_AUDIO_hSai.Init.ClockStrobing  = SAI_CLOCKSTROBING_RISINGEDGE;
-  
-  /* Configure SAI_Block_x Frame 
-  Frame Length: 32
-  Frame active Length: 16
-  FS Definition: Start frame + Channel Side identification
-  FS Polarity: FS active Low
-  FS Offset: FS asserted one bit before the first bit of slot 0 */ 
-  BSP_AUDIO_hSai.FrameInit.FrameLength = 32;
-  BSP_AUDIO_hSai.FrameInit.ActiveFrameLength = 16;
-  BSP_AUDIO_hSai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
-  BSP_AUDIO_hSai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
-  BSP_AUDIO_hSai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
-  
-  /* Configure SAI Block_x Slot 
-  Slot First Bit Offset: 0
-  Slot Size  : 16
-  Slot Number: 2
-  Slot Active: Slots 0 and 1 actives */
-  BSP_AUDIO_hSai.SlotInit.FirstBitOffset = 0;
-  BSP_AUDIO_hSai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
-  BSP_AUDIO_hSai.SlotInit.SlotNumber = 2; 
-  BSP_AUDIO_hSai.SlotInit.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1;
-
-  /* Initializes the SAI peripheral*/
-  if (HAL_SAI_Init(&BSP_AUDIO_hSai) != HAL_OK)
-  {
-    return AUDIO_ERROR;
-  }
-  
-  /* Enable SAI peripheral to generate MCLK */
-  __HAL_SAI_ENABLE(&BSP_AUDIO_hSai);
-  
-  return AUDIO_OK;
-  
-}
-
-/**
-  * @brief  De-initializes the Audio Codec audio interface (SAI).
-  * @retval BSP AUDIO status
-  */
-static uint8_t AUDIO_SAIx_DeInit(void)
-{
-  /* Disable the SAI audio block */
-  __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
-
-  /* De-initializes the SAI peripheral */
-  if (HAL_SAI_DeInit(&BSP_AUDIO_hSai) != HAL_OK)
-  {
-    return AUDIO_ERROR;
-  }
-  
-  /* Disable SAIx PLL */
-  if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK)
-  {
-    return AUDIO_ERROR;
-  }  
-  
-  return AUDIO_OK;
-}
-
-/**
-  * @brief  SAI MSP Init
-  * @param  hsai : pointer to a SAI_HandleTypeDef structure
-  * @retval None
-  */
-void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai)
-{ 
-  GPIO_InitTypeDef  GPIO_InitStruct;  
-
-  /* Enable SAI clock */
-  AUDIO_SAIx_CLK_ENABLE();
-  
-  /* Enable GPIO clock */
-  AUDIO_SAIx_MCK_SCK_SD_FS_ENABLE();
-  
-  /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
-  GPIO_InitStruct.Pin = AUDIO_SAIx_FS_PIN | AUDIO_SAIx_SCK_PIN | AUDIO_SAIx_SD_PIN | AUDIO_SAIx_MCK_PIN;
-  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
-  GPIO_InitStruct.Alternate = AUDIO_SAIx_MCK_SCK_SD_FS_AF;
-  HAL_GPIO_Init(AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT, &GPIO_InitStruct);
-
-  /* Enable the DMA clock */
-  AUDIO_SAIx_DMAx_CLK_ENABLE();
-    
-  if(hsai->Instance == AUDIO_SAIx)
-  {
-    /* Configure the hDmaSai handle parameters */   
-    hDmaSai.Init.Request             = DMA_REQUEST_1;
-    hDmaSai.Init.Direction           = DMA_MEMORY_TO_PERIPH;
-    hDmaSai.Init.PeriphInc           = DMA_PINC_DISABLE;
-    hDmaSai.Init.MemInc              = DMA_MINC_ENABLE;
-    hDmaSai.Init.PeriphDataAlignment = AUDIO_SAIx_DMAx_PERIPH_DATA_SIZE;
-    hDmaSai.Init.MemDataAlignment    = AUDIO_SAIx_DMAx_MEM_DATA_SIZE;
-    hDmaSai.Init.Mode                = DMA_NORMAL;
-    hDmaSai.Init.Priority            = DMA_PRIORITY_HIGH;
-    
-    hDmaSai.Instance = AUDIO_SAIx_DMAx_CHANNEL;
-    
-    /* Associate the DMA handle */
-    __HAL_LINKDMA(hsai, hdmatx, hDmaSai);
-    
-    /* Deinitialize the Stream for new transfer */
-    HAL_DMA_DeInit(&hDmaSai);
-    
-    /* Configure the DMA Stream */
-    HAL_DMA_Init(&hDmaSai);      
-  }
-  
-  /* SAI DMA IRQ Channel configuration */
-  HAL_NVIC_SetPriority(AUDIO_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
-  HAL_NVIC_EnableIRQ(AUDIO_SAIx_DMAx_IRQ); 
-}
-
-/**
-  * @brief  SAI MSP De-init
-  * @param  hsai : pointer to a SAI_HandleTypeDef structure
-  * @retval None
-  */
-void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai)
-{
-  /* Disable SAI DMA Channel IRQ  */
-  HAL_NVIC_DisableIRQ(AUDIO_SAIx_DMAx_IRQ); 
-
-  /* Reset the DMA Stream configuration*/
-  HAL_DMA_DeInit(&hDmaSai);
-  
-  /* Disable the DMA clock */
-  AUDIO_SAIx_DMAx_CLK_DISABLE();
-    
-  /* De-initialize FS, SCK, MCK and SD pins*/
-  HAL_GPIO_DeInit(AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT, 
-                  AUDIO_SAIx_FS_PIN | AUDIO_SAIx_SCK_PIN | AUDIO_SAIx_SD_PIN | AUDIO_SAIx_MCK_PIN);
-  
-  /* Disable GPIO clock */
-  AUDIO_SAIx_MCK_SCK_SD_FS_DISABLE();
-  
-  /* Disable SAI clock */
-  AUDIO_SAIx_CLK_DISABLE();
-}
-
-/**
-  * @brief  Resets the audio codec. It restores the default configuration of the 
-  *         codec (this function shall be called before initializing the codec).
-  * @retval None
-  */
-
-
-/**
-  * @}
-  */
-
-/** @addtogroup STM32L476G_DISCOVERY_AUDIO_Private_Functions
-  * @{
-  */ 
-
-/**
-  * @brief  Initializes the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
-  * @param  AudioFreq: Audio frequency to be used to set correctly the DFSDM peripheral.
-  * @retval BSP AUDIO status
-  */
-static uint8_t AUDIO_DFSDMx_Init(uint32_t AudioFreq)
-{
-  /*####CHANNEL 2####*/
-  hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Activation   = ENABLE;
-  hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Selection    = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
-  /* Set the DFSDM clock OUT audio frequency configuration */
-  hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Divider      = DFSDMClockDivider(AudioFreq);
-  hAudioIn.hDfsdmLeftChannel.Init.Input.Multiplexer        = DFSDM_CHANNEL_EXTERNAL_INPUTS;
-  hAudioIn.hDfsdmLeftChannel.Init.Input.DataPacking        = DFSDM_CHANNEL_STANDARD_MODE;
-  hAudioIn.hDfsdmLeftChannel.Init.Input.Pins               = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
-  /* Request to sample stable data for LEFT micro on Rising edge */
-  hAudioIn.hDfsdmLeftChannel.Init.SerialInterface.Type     = DFSDM_CHANNEL_SPI_RISING;
-  hAudioIn.hDfsdmLeftChannel.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
-  hAudioIn.hDfsdmLeftChannel.Init.Awd.FilterOrder          = DFSDM_CHANNEL_SINC1_ORDER;
-  hAudioIn.hDfsdmLeftChannel.Init.Awd.Oversampling         = 10;
-  hAudioIn.hDfsdmLeftChannel.Init.Offset                   = 0;
-  hAudioIn.hDfsdmLeftChannel.Init.RightBitShift            = DFSDMRightBitShift(AudioFreq);
-
-  hAudioIn.hDfsdmLeftChannel.Instance                      = DFSDM_Channel2;
-
-    /* Init the DFSDM Channel */
-  if (HAL_DFSDM_ChannelInit(&hAudioIn.hDfsdmLeftChannel) != HAL_OK)
-  {
-    return AUDIO_ERROR;
-  }
-
-  /*####FILTER 0####*/
-  BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.Trigger         = DFSDM_FILTER_SW_TRIGGER;
-  BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.FastMode        = ENABLE;
-  BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.DmaMode         = ENABLE;
-  BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.Trigger        = DFSDM_FILTER_SW_TRIGGER;
-  BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ScanMode       = DISABLE;
-  BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.DmaMode        = DISABLE;
-  BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ExtTrigger     = DFSDM_FILTER_EXT_TRIG_TIM8_TRGO;
-  BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ExtTriggerEdge = DFSDM_FILTER_EXT_TRIG_BOTH_EDGES;
-  BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.SincOrder        = DFSDMFilterOrder(AudioFreq);
-  /* Set the DFSDM Filters Oversampling to have correct sample rate */
-  BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.Oversampling     = DFSDMOverSampling(AudioFreq);
-  BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.IntOversampling  = 1;
-  
-  BSP_AUDIO_hDfsdmLeftFilter.Instance                          = AUDIO_DFSDMx_LEFT_FILTER;
-
-    /* Init the DFSDM Filter */
-  if (HAL_DFSDM_FilterInit(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
-  {
-    return AUDIO_ERROR;
-  }
-  
-  /* Configure regular channel */
-  if (HAL_DFSDM_FilterConfigRegChannel(&BSP_AUDIO_hDfsdmLeftFilter, 
-                                      DFSDM_CHANNEL_2, 
-                                      DFSDM_CONTINUOUS_CONV_ON) != HAL_OK)
-  {
-    return AUDIO_ERROR;
-  }
-
-  return AUDIO_OK;
-}
-
-/**
-  * @brief  De-initializes the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
-  * @retval BSP AUDIO status
-  */
-static uint8_t AUDIO_DFSDMx_DeInit(void)
-{
-  /* De-initializes the DFSDM filters to allow access to DFSDM internal registers */
-  if (HAL_DFSDM_FilterDeInit(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
-  {
-    return AUDIO_ERROR;
-  }
-
-  /* De-initializes the DFSDM channels to allow access to DFSDM internal registers */
-  if (HAL_DFSDM_ChannelDeInit(&hAudioIn.hDfsdmLeftChannel) != HAL_OK)
-  {
-    return AUDIO_ERROR;
-  }
-
-  /* Disable DFSDM clock */
-  AUDIO_DFSDMx_CLK_DISABLE();
-
-  /* Disable SAIx PLL */
-  if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK)
-  {
-    return AUDIO_ERROR;
-  }  
-
-  /* DFSDM reset */
-  __HAL_RCC_DFSDM_FORCE_RESET();
-  __HAL_RCC_DFSDM_RELEASE_RESET();
-
-  return AUDIO_OK;
-}
-
-/**
-  * @brief  Initializes the DFSDM channel MSP.
-  * @param  hdfsdm_channel : DFSDM channel handle.
-  * @retval None
-  */
-void HAL_DFSDM_ChannelMspInit(DFSDM_Channel_HandleTypeDef *hdfsdm_channel)
-{
-  GPIO_InitTypeDef  GPIO_InitStruct;  
-
-  /* Enable DFSDM clock */
-  AUDIO_DFSDMx_CLK_ENABLE();
-  
-  /* Enable GPIO clock */
-  AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE();
-  
-  /* DFSDM pins configuration: DFSDM_CKOUT, DMIC_DATIN pins ------------------*/
-  GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN | AUDIO_DFSDMx_DMIC_DATIN_PIN;
-  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
-  GPIO_InitStruct.Alternate = AUDIO_DFSDMx_CKOUT_DMIC_DATIN_AF;
-  HAL_GPIO_Init(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct);
-}
-
-/**
-  * @brief  De-initializes the DFSDM channel MSP.
-  * @param  hdfsdm_channel : DFSDM channel handle.
-  * @retval None
-  */
-void HAL_DFSDM_ChannelMspDeInit(DFSDM_Channel_HandleTypeDef *hdfsdm_channel)
-{
-  GPIO_InitTypeDef  GPIO_InitStruct;
-  
-  /* Enable GPIO clock */
-  AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE();
-  
-  /* DFSDM pins configuration: DFSDM_CKOUT */
-  GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN;
-  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
-  HAL_GPIO_Init(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct);
-  HAL_GPIO_WritePin(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, AUDIO_DFSDMx_CKOUT_PIN, GPIO_PIN_RESET);
-
-
-  /* De-initialize DMIC_DATIN pin */
-  HAL_GPIO_DeInit(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, AUDIO_DFSDMx_DMIC_DATIN_PIN);
-}
-
-/**
-  * @brief  Initializes the DFSDM filter MSP.
-  * @param  hdfsdm_filter : DFSDM filter handle.
-  * @retval None
-  */
-void HAL_DFSDM_FilterMspInit(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
-{
-  /* Enable DFSDM clock */
-  AUDIO_DFSDMx_CLK_ENABLE();
-  
-  /* Enable the DMA clock */
-  AUDIO_DFSDMx_DMAx_CLK_ENABLE();
-    
-  /* Configure the hAudioIn.hDmaDfsdmLeft handle parameters */   
-  hAudioIn.hDmaDfsdmLeft.Init.Request             = DMA_REQUEST_0;
-  hAudioIn.hDmaDfsdmLeft.Init.Direction           = DMA_PERIPH_TO_MEMORY;
-  hAudioIn.hDmaDfsdmLeft.Init.PeriphInc           = DMA_PINC_DISABLE;
-  hAudioIn.hDmaDfsdmLeft.Init.MemInc              = DMA_MINC_ENABLE;
-  hAudioIn.hDmaDfsdmLeft.Init.PeriphDataAlignment = AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE;
-  hAudioIn.hDmaDfsdmLeft.Init.MemDataAlignment    = AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE;
-  hAudioIn.hDmaDfsdmLeft.Init.Mode                = DMA_CIRCULAR;
-  hAudioIn.hDmaDfsdmLeft.Init.Priority            = DMA_PRIORITY_HIGH;
-
-  hAudioIn.hDmaDfsdmLeft.Instance               = AUDIO_DFSDMx_DMAx_LEFT_CHANNEL;
-  
-  /* Associate the DMA handle */
-  __HAL_LINKDMA(hdfsdm_filter, hdmaReg, hAudioIn.hDmaDfsdmLeft);
-  
-  /* Reset DMA handle state */
-  __HAL_DMA_RESET_HANDLE_STATE(&hAudioIn.hDmaDfsdmLeft);
-
-  /* Configure the DMA Channel */
-  HAL_DMA_Init(&hAudioIn.hDmaDfsdmLeft);      
-
-  /* DMA IRQ Channel configuration */
-    HAL_NVIC_SetPriority(AUDIO_DFSDMx_DMAx_LEFT_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
-    HAL_NVIC_EnableIRQ(AUDIO_DFSDMx_DMAx_LEFT_IRQ);
-  }
-
- /**
-  * @brief  De-initializes the DFSDM filter MSP.
-  * @param  hdfsdm_filter : DFSDM filter handle.
-  * @retval None
-  */
-void HAL_DFSDM_FilterMspDeInit(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
-{
-  /* Disable DMA  Channel IRQ */
-  HAL_NVIC_DisableIRQ(AUDIO_DFSDMx_DMAx_LEFT_IRQ);
-
-  /* De-initialize the DMA Channel */
-  HAL_DMA_DeInit(&hAudioIn.hDmaDfsdmLeft);      
-
-  /* Disable the DMA clock */
-  AUDIO_DFSDMx_DMAx_CLK_DISABLE();
-}
-
-/**
-  * @brief  Configures the SAI PLL clock according to the required audio frequency.
-  * @param  Frequency: Audio frequency.  
-  * @retval BSP AUDIO status
-  * @note   The SAI PLL input clock must be configured in the user application.
-  *         The SAI PLL configuration done within this function assumes that
-  *         the SAI PLL input clock runs at 8 MHz.
-  */
-static uint8_t AUDIO_SAIPLLConfig(uint32_t Frequency)
-{
-  RCC_PeriphCLKInitTypeDef RCC_ExCLKInitStruct;
-
-  /* Retreive actual RCC configuration */
-  HAL_RCCEx_GetPeriphCLKConfig(&RCC_ExCLKInitStruct);
-  
-    if (   (Frequency == AUDIO_FREQUENCY_11K) 
-        || (Frequency == AUDIO_FREQUENCY_22K)
-        || (Frequency == AUDIO_FREQUENCY_44K) )
-  {
-    /* Configure PLLSAI prescalers */
-    /* SAI clock config 
-    PLLSAI1_VCO= 8 Mhz * PLLSAI1N = 8 * 24 = VCO_192M 
-    SAI_CK_x = PLLSAI1_VCO/PLLSAI1P = 192/17 = 11.294 Mhz */  
-    RCC_ExCLKInitStruct.PeriphClockSelection    = RCC_PERIPHCLK_SAI1;
-    RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N        = 24; 
-    RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P        = 17; 
-    RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK;
-    RCC_ExCLKInitStruct.Sai1ClockSelection      = RCC_SAI1CLKSOURCE_PLLSAI1;
-  }
-  else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */
-  {
-    /* SAI clock config 
-    PLLSAI1_VCO= 8 Mhz * PLLSAI1N = 8 * 43 = VCO_344M 
-    SAI_CK_x = PLLSAI1_VCO/PLLSAI1P = 344/7 = 49.142 Mhz */  
-    RCC_ExCLKInitStruct.PeriphClockSelection    = RCC_PERIPHCLK_SAI1;
-    RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N        = 43;
-    RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P        = 7;
-    RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK;
-    RCC_ExCLKInitStruct.Sai1ClockSelection      = RCC_SAI1CLKSOURCE_PLLSAI1;
-  }
-  
-  if (HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct) != HAL_OK)
-  {
-    return AUDIO_ERROR;
-  }    
-
-  return AUDIO_OK;
-}
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
--- a/stm32l476g_discovery_audio.h	Thu Dec 03 22:16:32 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,280 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32l476g_discovery_audio.h
-  * @author  MCD Application Team
-  * @version V1.0.1
-  * @date    16-September-2015
-  * @brief   This file contains the common defines and functions prototypes for
-  *          the stm32l476g_discovery_audio.c driver.
-  ******************************************************************************
-  * @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.
-  *
-  ******************************************************************************
-  */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32L476G_DISCOVERY_AUDIO_H
-#define __STM32L476G_DISCOVERY_AUDIO_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#if defined(BSP_AUDIO_USE_RTOS)
-#include "k_mem.h"
-#else
-#include <stdlib.h>
-#endif
-/* Include audio component Driver */
-
-#include "stm32l476g_discovery.h"
-
-/** @addtogroup BSP
-  * @{
-  */ 
-
-/** @addtogroup STM32L476G_DISCOVERY
-  * @{
-  */
-
-/** @addtogroup STM32L476G_DISCOVERY_AUDIO
-  * @{
-  */
-
-/** @defgroup STM32L476G_DISCOVERY_AUDIO_Exported_Types Exported Types
-  * @{
-  */
-typedef void (*Audio_CallbackTypeDef)(void);
-
-/**
-  * @}
-  */
-
-/** @defgroup STM32L476G_DISCOVERY_AUDIO_Exported_Constants Exported Constants
-  * @{
-  */
-/** @defgroup BSP_Audio_Out_Option BSP Audio Out Option
-  * @{
-  */
-#define BSP_AUDIO_OUT_CIRCULARMODE      ((uint32_t)0x00000001) /* BUFFER CIRCULAR MODE */
-#define BSP_AUDIO_OUT_NORMALMODE        ((uint32_t)0x00000002) /* BUFFER NORMAL MODE   */
-#define BSP_AUDIO_OUT_STEREOMODE        ((uint32_t)0x00000004) /* STEREO MODE          */
-#define BSP_AUDIO_OUT_MONOMODE          ((uint32_t)0x00000008) /* MONO MODE            */
-/**
-  * @}
-  */
- 
-/** @defgroup BSP_Audio_Sample_Rate BSP Audio Sample Rate
-  * @{
-  */
-#define BSP_AUDIO_FREQUENCY_96K         SAI_AUDIO_FREQUENCY_96K
-#define BSP_AUDIO_FREQUENCY_48K         SAI_AUDIO_FREQUENCY_48K
-#define BSP_AUDIO_FREQUENCY_44K         SAI_AUDIO_FREQUENCY_44K
-#define BSP_AUDIO_FREQUENCY_32K         SAI_AUDIO_FREQUENCY_32K
-#define BSP_AUDIO_FREQUENCY_22K         SAI_AUDIO_FREQUENCY_22K
-#define BSP_AUDIO_FREQUENCY_16K         SAI_AUDIO_FREQUENCY_16K
-#define BSP_AUDIO_FREQUENCY_11K         SAI_AUDIO_FREQUENCY_11K
-#define BSP_AUDIO_FREQUENCY_8K          SAI_AUDIO_FREQUENCY_8K
-/**
-  * @}
-  */
-  
-/* AUDIO FREQUENCY */
-#define AUDIO_FREQUENCY_192K          ((uint32_t)192000)
-#define AUDIO_FREQUENCY_96K           ((uint32_t)96000)
-#define AUDIO_FREQUENCY_48K           ((uint32_t)48000)
-#define AUDIO_FREQUENCY_44K           ((uint32_t)44100)
-#define AUDIO_FREQUENCY_32K           ((uint32_t)32000)
-#define AUDIO_FREQUENCY_22K           ((uint32_t)22050)
-#define AUDIO_FREQUENCY_16K           ((uint32_t)16000)
-#define AUDIO_FREQUENCY_11K           ((uint32_t)11025)
-#define AUDIO_FREQUENCY_8K            ((uint32_t)8000)  
-  
-/*------------------------------------------------------------------------------
-                          USER SAI defines parameters
- -----------------------------------------------------------------------------*/
-/* SAI peripheral configuration defines */
-#define AUDIO_SAIx                             SAI1_Block_A
-#define AUDIO_SAIx_CLK_ENABLE()                __HAL_RCC_SAI1_CLK_ENABLE()
-#define AUDIO_SAIx_CLK_DISABLE()               __HAL_RCC_SAI1_CLK_DISABLE()
-#define AUDIO_SAIx_MCK_SCK_SD_FS_AF            GPIO_AF13_SAI1
-
-#define AUDIO_SAIx_MCK_SCK_SD_FS_ENABLE()      __HAL_RCC_GPIOE_CLK_ENABLE()
-#define AUDIO_SAIx_MCK_SCK_SD_FS_DISABLE()     __HAL_RCC_GPIOE_CLK_DISABLE()
-#define AUDIO_SAIx_FS_PIN                      GPIO_PIN_4
-#define AUDIO_SAIx_SCK_PIN                     GPIO_PIN_5
-#define AUDIO_SAIx_SD_PIN                      GPIO_PIN_6
-#define AUDIO_SAIx_MCK_PIN                     GPIO_PIN_2
-#define AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT     GPIOE
-
-/* SAI DMA Channel definitions */
-#define AUDIO_SAIx_DMAx_CLK_ENABLE()         __HAL_RCC_DMA2_CLK_ENABLE()
-#define AUDIO_SAIx_DMAx_CLK_DISABLE()        __HAL_RCC_DMA2_CLK_DISABLE()
-#define AUDIO_SAIx_DMAx_CHANNEL              DMA2_Channel1
-#define AUDIO_SAIx_DMAx_IRQ                  DMA2_Channel1_IRQn
-#define AUDIO_SAIx_DMAx_PERIPH_DATA_SIZE     DMA_PDATAALIGN_HALFWORD
-#define AUDIO_SAIx_DMAx_MEM_DATA_SIZE        DMA_MDATAALIGN_HALFWORD
-#define DMA_MAX_SZE                          (uint32_t)0xFFFF
-   
-#define AUDIO_SAIx_DMAx_IRQHandler           DMA2_Channel1_IRQHandler
-
-/* Select the interrupt preemption priority for the DMA interrupt */
-#define AUDIO_OUT_IRQ_PREPRIO           5   /* Select the preemption priority level(0 is the highest) */   
-
-/* Disable SAIx PLL */
-#define AUDIO_SAIx_PLL_DISABLE()             HAL_RCCEx_DisablePLLSAI1()
-
-/*------------------------------------------------------------------------------
-                        AUDIO IN CONFIGURATION
-------------------------------------------------------------------------------*/
-/* DFSDM Configuration defines */
-#define AUDIO_DFSDMx_LEFT_CHANNEL                       DFSDM_Channel2
-#define AUDIO_DFSDMx_LEFT_FILTER                        DFSDM_Filter0
-#define AUDIO_DFSDMx_CLK_ENABLE()                       __HAL_RCC_DFSDM_CLK_ENABLE()
-#define AUDIO_DFSDMx_CLK_DISABLE()                       __HAL_RCC_DFSDM_CLK_DISABLE()
-#define AUDIO_DFSDMx_CKOUT_PIN                          GPIO_PIN_9
-#define AUDIO_DFSDMx_DMIC_DATIN_PIN                     GPIO_PIN_7
-#define AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT         GPIOE
-#define AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
-#define AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_DISABLE() __HAL_RCC_GPIOE_CLK_DISABLE()
-#define AUDIO_DFSDMx_CKOUT_DMIC_DATIN_AF                GPIO_AF6_DFSDM
-
-/* DFSDM DMA Right and Left channels definitions */
-#define AUDIO_DFSDMx_DMAx_CLK_ENABLE()                  __HAL_RCC_DMA1_CLK_ENABLE()
-#define AUDIO_DFSDMx_DMAx_CLK_DISABLE()                 __HAL_RCC_DMA1_CLK_DISABLE()
-#define AUDIO_DFSDMx_DMAx_LEFT_CHANNEL                  DMA1_Channel4
-#define AUDIO_DFSDMx_DMAx_LEFT_IRQ                      DMA1_Channel4_IRQn
-#define AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE              DMA_PDATAALIGN_WORD
-#define AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE                 DMA_MDATAALIGN_WORD
-   
-#define AUDIO_DFSDM_DMAx_LEFT_IRQHandler                DMA1_Channel4_IRQHandler
-  
-/* Select the interrupt preemption priority and subpriority for the IT/DMA interrupt */
-#define AUDIO_IN_IRQ_PREPRIO                6   /* Select the preemption priority level(0 is the highest) */
-
-/*------------------------------------------------------------------------------
-             CONFIGURATION: Audio Driver Configuration parameters
-------------------------------------------------------------------------------*/
-
-#define AUDIODATA_SIZE                      2   /* 16-bits audio data size */
-
-/* Audio status definition */     
-#define AUDIO_OK                            0
-#define AUDIO_ERROR                         1
-#define AUDIO_TIMEOUT                       2
-
-/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */
-#define DEFAULT_AUDIO_IN_FREQ               BSP_AUDIO_FREQUENCY_16K
-#define DEFAULT_AUDIO_IN_BIT_RESOLUTION     16
-#define DEFAULT_AUDIO_IN_CHANNEL_NBR        1 /* Mono = 1, Stereo = 2 */
-#define DEFAULT_AUDIO_IN_VOLUME             64
-
-/*------------------------------------------------------------------------------
-                    OPTIONAL Configuration defines parameters
-------------------------------------------------------------------------------*/
-
-/* Delay for the Codec to be correctly reset */
-#define CODEC_RESET_DELAY           5
-
-/**
-  * @}
-  */
- 
-/** @defgroup STM32L476G_DISCOVERY_AUDIO_Exported_Variables Exported Variables
-  * @{
-  */
-extern SAI_HandleTypeDef          BSP_AUDIO_hSai;
-extern DFSDM_Filter_HandleTypeDef BSP_AUDIO_hDfsdmLeftFilter;
-
- /**
-  * @}
-  */
-   
-/** @defgroup STM32L476G_DISCOVERY_AUDIO_Exported_Macros Exported Macros
-  * @{
-  */
-#define DMA_MAX(_X_)                (((_X_) <= DMA_MAX_SZE)? (_X_):DMA_MAX_SZE)
-
-/**
-  * @}
-  */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup STM32L476G_DISCOVERY_AUDIO_Exported_Functions Exported Functions
-  * @{
-  */
-uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq);
-uint8_t BSP_AUDIO_OUT_DeInit(void);
-uint8_t BSP_AUDIO_OUT_Play(uint16_t* pData, uint32_t Size);
-uint8_t BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size);
-uint8_t BSP_AUDIO_OUT_Pause(void);
-uint8_t BSP_AUDIO_OUT_Resume(void);
-uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option);
-uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume);
-uint8_t BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq);
-void    BSP_AUDIO_OUT_ChangeAudioConfig(uint32_t AudioOutOption);
-uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd);
-uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output);
-void    BSP_AUDIO_OUT_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback, 
-                                        Audio_CallbackTypeDef HalfTransferCallback, 
-                                        Audio_CallbackTypeDef TransferCompleteCallback);
-
-uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
-uint8_t BSP_AUDIO_IN_DeInit(void);
-uint8_t BSP_AUDIO_IN_Record(uint16_t *pData, uint32_t Size);
-uint8_t BSP_AUDIO_IN_SetFrequency(uint32_t AudioFreq);
-uint8_t BSP_AUDIO_IN_Stop(void);
-uint8_t BSP_AUDIO_IN_Pause(void);
-uint8_t BSP_AUDIO_IN_Resume(void);
-void    BSP_AUDIO_IN_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback, 
-                                       Audio_CallbackTypeDef HalfTransferCallback, 
-                                       Audio_CallbackTypeDef TransferCompleteCallback);
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32L476G_DISCOVERY_AUDIO_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
--- a/stm32l476g_discovery_glass_lcd.c	Thu Dec 03 22:16:32 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,988 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32l476g_discovery_glass_lcd.c
-  * @author  MCD Application Team
-  * @version V1.0.1
-  * @date    16-September-2015
-  * @brief   This file provides a set of functions needed to manage the 
-  *          LCD Glass driver for the STM32L476G-Discovery board.
-  ******************************************************************************
-  * @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 "stm32l476g_discovery_glass_lcd.h"
-
-/** @addtogroup BSP
-  * @{
-  */
-
-/** @addtogroup STM32L476G_DISCOVERY
-  * @{
-  */
-
-/** @defgroup STM32L476G_DISCOVERY_GLASS_LCD STM32L476G-DISCOVERY GLASS LCD
-  * @brief This file includes the LCD Glass driver for LCD Module of 
-  *        STM32L476G-DISCOVERY board.
-  * @{
-  */
-
-/* Private constants ---------------------------------------------------------*/
-
-/** @defgroup STM32L476G_DISCOVERY_GLASS_LCD_Private_Constants Private Constants
-  * @{
-  */
-#define ASCII_CHAR_0                  0x30  /* 0 */
-#define ASCII_CHAR_AT_SYMBOL          0x40  /* @ */
-#define ASCII_CHAR_LEFT_OPEN_BRACKET  0x5B  /* [ */
-#define ASCII_CHAR_APOSTROPHE         0x60  /* ` */
-#define ASCII_CHAR_LEFT_OPEN_BRACE    0x7B  /* ( */
-/**
-  * @}
-  */
-
-/* Private variables ---------------------------------------------------------*/
-
-/** @defgroup STM32L476G_DISCOVERY_GLASS_LCD_Private_Variables Private Variables
-  * @{
-  */
-
-/* this variable can be used for accelerate the scrolling exit when push user button */
-__IO uint8_t bLCDGlass_KeyPressed = 0; 
-
-/**
-  @verbatim
-================================================================================
-                              GLASS LCD MAPPING
-================================================================================
-LCD allows to display informations on six 14-segment digits and 4 bars:
-
-  1       2       3       4       5       6
------   -----   -----   -----   -----   -----   
-|\|/| o |\|/| o |\|/| o |\|/| o |\|/|   |\|/|   BAR3
--- --   -- --   -- --   -- --   -- --   -- --   BAR2
-|/|\| o |/|\| o |/|\| o |/|\| o |/|\|   |/|\|   BAR1
------ * ----- * ----- * ----- * -----   -----   BAR0
-
-LCD segment mapping:
---------------------
-  -----A-----        _ 
-  |\   |   /|   COL |_|
-  F H  J  K B          
-  |  \ | /  |        _ 
-  --G-- --M--   COL |_|
-  |  / | \  |          
-  E Q  P  N C          
-  |/   |   \|        _ 
-  -----D-----   DP  |_|
-
- An LCD character coding is based on the following matrix:
-COM           0   1   2     3
-SEG(n)      { E , D , P ,   N   }
-SEG(n+1)    { M , C , COL , DP  }
-SEG(23-n-1) { B , A , K ,   J   }
-SEG(23-n)   { G , F , Q ,   H   }
-with n positive odd number.
-
- The character 'A' for example is:
-  -------------------------------
-LSB   { 1 , 0 , 0 , 0   }
-      { 1 , 1 , 0 , 0   }
-      { 1 , 1 , 0 , 0   }
-MSB   { 1 , 1 , 0 , 0   }
-      -------------------
-  'A' =  F    E   0   0 hexa
-
-  @endverbatim
-*/
-
-LCD_HandleTypeDef LCDHandle;
-
-/* Constant table for cap characters 'A' --> 'Z' */
-const uint16_t CapLetterMap[26]=
-    {
-        /* A      B      C      D      E      F      G      H      I  */
-        0xFE00, 0x6714, 0x1D00, 0x4714, 0x9D00, 0x9C00, 0x3F00, 0xFA00, 0x0014,
-        /* J      K      L      M      N      O      P      Q      R  */
-        0x5300, 0x9841, 0x1900, 0x5A48, 0x5A09, 0x5F00, 0xFC00, 0x5F01, 0xFC01,
-        /* S      T      U      V      W      X      Y      Z  */
-        0xAF00, 0x0414, 0x5b00, 0x18C0, 0x5A81, 0x00C9, 0x0058, 0x05C0
-    };
-
-/* Constant table for number '0' --> '9' */
-const uint16_t NumberMap[10]=
-    {
-        /* 0      1      2      3      4      5      6      7      8      9  */
-        0x5F00,0x4200,0xF500,0x6700,0xEa00,0xAF00,0xBF00,0x04600,0xFF00,0xEF00
-    };
-
-uint32_t Digit[4];     /* Digit frame buffer */
-
-/* LCD BAR status: To save the bar setting after writing in LCD RAM memory */
-uint8_t LCDBar = BATTERYLEVEL_FULL;
-
-/**
-  * @}
-  */
-
-/** @defgroup STM32L476G_DISCOVERY_LCD_Private_Functions Private Functions
-  * @{
-  */
-static void Convert(uint8_t* Char, Point_Typedef Point, DoublePoint_Typedef Colon);
-static void WriteChar(uint8_t* ch, Point_Typedef Point, DoublePoint_Typedef Colon, DigitPosition_Typedef Position);
-static void LCD_MspInit(LCD_HandleTypeDef *hlcd);
-static void LCD_MspDeInit(LCD_HandleTypeDef *hlcd);
-
-/**
-  * @}
-  */
-
-/** @addtogroup STM32L476G_DISCOVERY_LCD_Exported_Functions
-  * @{
-  */
-
-/**
-  * @brief  Initialize the LCD GLASS relative GPIO port IOs and LCD peripheral.
-  * @retval None
-  */
-void BSP_LCD_GLASS_Init(void)
-{
-  LCDHandle.Instance              = LCD;
-  LCDHandle.Init.Prescaler        = LCD_PRESCALER_1;
-  LCDHandle.Init.Divider          = LCD_DIVIDER_31;
-#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB)
-  LCDHandle.Init.Duty             = LCD_DUTY_1_4;
-#elif defined (USE_STM32L476G_DISCO_REVA)
-  LCDHandle.Init.Duty             = LCD_DUTY_1_8;
-#endif
-  LCDHandle.Init.Bias             = LCD_BIAS_1_3;
-  LCDHandle.Init.VoltageSource    = LCD_VOLTAGESOURCE_INTERNAL;
-  LCDHandle.Init.Contrast         = LCD_CONTRASTLEVEL_5;
-  LCDHandle.Init.DeadTime         = LCD_DEADTIME_0;
-  LCDHandle.Init.PulseOnDuration  = LCD_PULSEONDURATION_4;
-  LCDHandle.Init.HighDrive        = LCD_HIGHDRIVE_DISABLE;
-  LCDHandle.Init.BlinkMode        = LCD_BLINKMODE_OFF;
-  LCDHandle.Init.BlinkFrequency   = LCD_BLINKFREQUENCY_DIV32;
-  LCDHandle.Init.MuxSegment       = LCD_MUXSEGMENT_DISABLE;
-  
-  /* Initialize the LCD */
-  LCD_MspInit(&LCDHandle);
-  HAL_LCD_Init(&LCDHandle);
-
-  BSP_LCD_GLASS_Clear();
-}
-
-/**
-  * @brief  DeInitialize the LCD GLASS relative GPIO port IOs and LCD peripheral.
-  * @retval None
-  */
-void BSP_LCD_GLASS_DeInit(void)
-{
-  /* De-Initialize the LCD */
-  LCD_MspDeInit(&LCDHandle);
-  HAL_LCD_DeInit(&LCDHandle);
-}
-
-
-/**
-  * @brief  Configure the LCD Blink mode and Blink frequency.
-  * @param  BlinkMode: specifies the LCD blink mode.
-  *   This parameter can be one of the following values:
-  *     @arg LCD_BLINKMODE_OFF:           Blink disabled
-  *     @arg LCD_BLINKMODE_SEG0_COM0:     Blink enabled on SEG[0], COM[0] (1 pixel)
-  *     @arg LCD_BLINKMODE_SEG0_ALLCOM:   Blink enabled on SEG[0], all COM (up to 8 
-  *                                       pixels according to the programmed duty)
-  *     @arg LCD_BLINKMODE_ALLSEG_ALLCOM: Blink enabled on all SEG and all COM 
-  *                                       (all pixels)
-  * @param  BlinkFrequency: specifies the LCD blink frequency.
-  *     @arg LCD_BLINKFREQUENCY_DIV8:    The Blink frequency = fLcd/8
-  *     @arg LCD_BLINKFREQUENCY_DIV16:   The Blink frequency = fLcd/16
-  *     @arg LCD_BLINKFREQUENCY_DIV32:   The Blink frequency = fLcd/32
-  *     @arg LCD_BLINKFREQUENCY_DIV64:   The Blink frequency = fLcd/64 
-  *     @arg LCD_BLINKFREQUENCY_DIV128:  The Blink frequency = fLcd/128
-  *     @arg LCD_BLINKFREQUENCY_DIV256:  The Blink frequency = fLcd/256
-  *     @arg LCD_BLINKFREQUENCY_DIV512:  The Blink frequency = fLcd/512
-  *     @arg LCD_BLINKFREQUENCY_DIV1024: The Blink frequency = fLcd/1024
-  * @retval None
-  */
-void BSP_LCD_GLASS_BlinkConfig(uint32_t BlinkMode, uint32_t BlinkFrequency)
-{
-  __HAL_LCD_BLINK_CONFIG(&LCDHandle, BlinkMode, BlinkFrequency);
-}
-
-/**
-  * @brief  Configure the LCD contrast.
-  * @param  Contrast: specifies the LCD contrast value.
-  *   This parameter can be one of the following values:
-  *     @arg LCD_CONTRASTLEVEL_0: Maximum Voltage = 2.60V
-  *     @arg LCD_CONTRASTLEVEL_1: Maximum Voltage = 2.73V
-  *     @arg LCD_CONTRASTLEVEL_2: Maximum Voltage = 2.86V
-  *     @arg LCD_CONTRASTLEVEL_3: Maximum Voltage = 2.99V
-  *     @arg LCD_CONTRASTLEVEL_4: Maximum Voltage = 3.12V
-  *     @arg LCD_CONTRASTLEVEL_5: Maximum Voltage = 3.25V
-  *     @arg LCD_CONTRASTLEVEL_6: Maximum Voltage = 3.38V
-  *     @arg LCD_CONTRASTLEVEL_7: Maximum Voltage = 3.51V
-  * @retval None
-  */
-void BSP_LCD_GLASS_Contrast(uint32_t Contrast)
-{
-  __HAL_LCD_CONTRAST_CONFIG(&LCDHandle, Contrast);
-}
-
-/**
-  * @brief Display one or several bar in LCD frame buffer.
-  * @param BarId: specifies the LCD GLASS Bar to display
-  *     This parameter can be one of the following values:
-  *     @arg BAR0: LCD GLASS Bar 0
-  *     @arg BAR0: LCD GLASS Bar 1
-  *     @arg BAR0: LCD GLASS Bar 2
-  *     @arg BAR0: LCD GLASS Bar 3
-  * @retval None
-  */
-void BSP_LCD_GLASS_DisplayBar(uint32_t BarId)
-{
-  uint32_t position = 0;
-
-  /* Check which bar is selected */
-  while ((BarId) >> position)
-  {
-    /* Check if current bar is selected */
-    switch(BarId & (1 << position))
-    {
-      /* Bar 0 */
-      case LCD_BAR_0:
-        /* Set BAR0 */
-        HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG), LCD_BAR0_SEG);
-        break;
-        
-      /* Bar 1 */
-      case LCD_BAR_1:
-        /* Set BAR1 */
-        HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG), LCD_BAR1_SEG);
-        break;
-        
-      /* Bar 2 */
-      case LCD_BAR_2:
-        /* Set BAR2 */
-        HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR2_SEG), LCD_BAR2_SEG);
-        break;
-        
-      /* Bar 3 */
-      case LCD_BAR_3:
-        /* Set BAR3 */
-        HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR3_SEG), LCD_BAR3_SEG);
-        break;
-        
-      default:
-        break;
-    }
-    position++;
-  }
-  
-  /* Update the LCD display */
-  HAL_LCD_UpdateDisplayRequest(&LCDHandle);
-}
-
-/**
-  * @brief Clear one or several bar in LCD frame buffer. 
-  * @param BarId: specifies the LCD GLASS Bar to display
-  *     This parameter can be combination of one of the following values:
-  *     @arg LCD_BAR_0: LCD GLASS Bar 0
-  *     @arg LCD_BAR_1: LCD GLASS Bar 1
-  *     @arg LCD_BAR_2: LCD GLASS Bar 2
-  *     @arg LCD_BAR_3: LCD GLASS Bar 3
-  * @retval None
-  */
-void BSP_LCD_GLASS_ClearBar(uint32_t BarId)
-{
-  uint32_t position = 0;
-
-  /* Check which bar is selected */
-  while ((BarId) >> position)
-  {
-    /* Check if current bar is selected */
-    switch(BarId & (1 << position))
-    {
-      /* Bar 0 */
-      case LCD_BAR_0:
-        /* Set BAR0 */
-        HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG) , 0);
-        break;
-        
-      /* Bar 1 */
-      case LCD_BAR_1:
-        /* Set BAR1 */
-        HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG), 0);
-        break;
-        
-      /* Bar 2 */
-      case LCD_BAR_2:
-        /* Set BAR2 */
-        HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR2_SEG), 0);
-        break;
-        
-      /* Bar 3 */
-      case LCD_BAR_3:
-        /* Set BAR3 */
-        HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR3_SEG), 0);
-        break;
-        
-      default:
-        break;
-    }
-    position++;
-  }
-  
-  /* Update the LCD display */
-  HAL_LCD_UpdateDisplayRequest(&LCDHandle);
-}
-
-/**
-  * @brief Configure the bar level on LCD by writing bar value in LCD frame buffer.
-  * @param BarLevel: specifies the LCD GLASS Battery Level.
-  *     This parameter can be one of the following values:
-  *     @arg BATTERYLEVEL_OFF: LCD GLASS Battery Empty
-  *     @arg BATTERYLEVEL_1_4: LCD GLASS Battery 1/4 Full
-  *     @arg BATTERYLEVEL_1_2: LCD GLASS Battery 1/2 Full
-  *     @arg BATTERYLEVEL_3_4: LCD GLASS Battery 3/4 Full
-  *     @arg BATTERYLEVEL_FULL: LCD GLASS Battery Full
-  * @retval None
-  */
-void BSP_LCD_GLASS_BarLevelConfig(uint8_t BarLevel)
-{
-  switch (BarLevel)
-  {
-  /* BATTERYLEVEL_OFF */
-  case BATTERYLEVEL_OFF:
-    /* Set BAR0 & BAR2 off */
-    HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG | LCD_BAR2_SEG), 0);
-    /* Set BAR1 & BAR3 off */
-    HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG | LCD_BAR3_SEG), 0);
-    LCDBar = BATTERYLEVEL_OFF;
-    break;
-    
-  /* BARLEVEL 1/4 */
-  case BATTERYLEVEL_1_4:
-    /* Set BAR0 on & BAR2 off */
-    HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG | LCD_BAR2_SEG), LCD_BAR0_SEG);
-    /* Set BAR1 & BAR3 off */
-    HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG | LCD_BAR3_SEG), 0);
-    LCDBar = BATTERYLEVEL_1_4;
-    break;
-    
-  /* BARLEVEL 1/2 */
-  case BATTERYLEVEL_1_2:
-    /* Set BAR0 on & BAR2 off */
-    HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG | LCD_BAR2_SEG), LCD_BAR0_SEG);
-    /* Set BAR1 on & BAR3 off */
-    HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG | LCD_BAR3_SEG), LCD_BAR1_SEG);
-    LCDBar = BATTERYLEVEL_1_2;
-    break;
-    
-  /* Battery Level 3/4 */
-  case BATTERYLEVEL_3_4:
-    /* Set BAR0 & BAR2 on */
-    HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG | LCD_BAR2_SEG), (LCD_BAR0_SEG | LCD_BAR2_SEG));
-    /* Set BAR1 on & BAR3 off */
-    HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG | LCD_BAR3_SEG), LCD_BAR1_SEG);
-    LCDBar = BATTERYLEVEL_3_4;
-    break;
-    
-  /* BATTERYLEVEL_FULL */
-  case BATTERYLEVEL_FULL:
-    /* Set BAR0 & BAR2 on */
-    HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG | LCD_BAR2_SEG), (LCD_BAR0_SEG | LCD_BAR2_SEG));
-    /* Set BAR1 on & BAR3 on */
-    HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG | LCD_BAR3_SEG), (LCD_BAR1_SEG | LCD_BAR3_SEG));
-    LCDBar = BATTERYLEVEL_FULL;
-    break;
-    
-  default:
-    break;
-  }
-  
-  /* Update the LCD display */
-  HAL_LCD_UpdateDisplayRequest(&LCDHandle);
-}
-
-/**
-  * @brief  Write a character in the LCD RAM buffer.
-  * @param  ch: The character to display.
-  * @param  Point: A point to add in front of char.
-  *          This parameter can be one of the following values:  
-  *              @arg POINT_OFF: No point to add in front of char.
-  *              @arg POINT_ON: Add a point in front of char.
-  * @param  Colon: Flag indicating if a colon character has to be added in front 
-  *                     of displayed character.
-  *          This parameter can be one of the following values:
-  *              @arg DOUBLEPOINT_OFF: No colon to add in back of char.
-  *              @arg DOUBLEPOINT_ON: Add an colon in back of char.
-  * @param  Position: Position in the LCD of the character to write.
-  *                   This parameter can be any value in range [1:6].
-  * @retval None
-  * @note   Required preconditions: The LCD should be cleared before to start the
-  *         write operation.
-  */
-void BSP_LCD_GLASS_DisplayChar(uint8_t* ch, Point_Typedef Point, DoublePoint_Typedef Colon, DigitPosition_Typedef Position)
-{
-  WriteChar(ch, Point, Colon, Position);
-  
-  /* Update the LCD display */
-  HAL_LCD_UpdateDisplayRequest(&LCDHandle);
-}
-
-/**
-  * @brief  Write a character string in the LCD RAM buffer.
-  * @param  ptr: Pointer to string to display on the LCD Glass.
-  * @retval None
-  */
-void BSP_LCD_GLASS_DisplayString(uint8_t* ptr)
-{
-  DigitPosition_Typedef position = LCD_DIGIT_POSITION_1;
-
-  /* Send the string character by character on lCD */
-  while ((*ptr != 0) & (position <= LCD_DIGIT_POSITION_6))
-  {
-    /* Write one character on LCD */
-    WriteChar(ptr, POINT_OFF, DOUBLEPOINT_OFF, position);
-
-    /* Point on the next character */
-    ptr++;
-
-    /* Increment the character counter */
-    position++;
-  }
-  /* Update the LCD display */
-  HAL_LCD_UpdateDisplayRequest(&LCDHandle);
-}
-
-/**
-  * @brief  Write a character string with decimal point in the LCD RAM buffer.
-  * @param  ptr: Pointer to string to display on the LCD Glass.
-  * @retval None
-  * @note Required preconditions: Char is ASCCI value "ORed" with decimal point or Colon flag
-  */
-void BSP_LCD_GLASS_DisplayStrDeci(uint16_t* ptr)
-{
-  DigitPosition_Typedef index = LCD_DIGIT_POSITION_1;
-  uint8_t tmpchar = 0;
-  
-  /* Send the string character by character on lCD */
-  while((*ptr != 0) & (index <= LCD_DIGIT_POSITION_6))
-  {      
-    tmpchar = (*ptr) & 0x00FF;
-    
-    switch((*ptr) & 0xF000)
-    {
-    case DOT:
-      /* Write one character on LCD with decimal point */
-      WriteChar(&tmpchar, POINT_ON, DOUBLEPOINT_OFF, index);
-      break;
-    case DOUBLE_DOT:
-      /* Write one character on LCD with decimal point */
-      WriteChar(&tmpchar, POINT_OFF, DOUBLEPOINT_ON, index);
-      break;
-    default:
-      WriteChar(&tmpchar, POINT_OFF, DOUBLEPOINT_OFF, index);    
-      break;
-    }/* Point on the next character */
-    ptr++;
-    
-    /* Increment the character counter */
-    index++;
-  }
-  /* Update the LCD display */
-  HAL_LCD_UpdateDisplayRequest(&LCDHandle);
-}
-
-/**
-  * @brief  Clear the whole LCD RAM buffer.
-  * @retval None
-  */
-void BSP_LCD_GLASS_Clear(void)
-{
-  HAL_LCD_Clear(&LCDHandle); 
-}
-
-/**
-  * @brief  Display a string in scrolling mode
-  * @param  ptr: Pointer to string to display on the LCD Glass.
-  * @param  nScroll: Specifies how many time the message will be scrolled
-  * @param  ScrollSpeed : Specifies the speed of the scroll, low value gives
-  *         higher speed 
-  * @retval None
-  * @note   Required preconditions: The LCD should be cleared before to start the
-  *         write operation.
-  */
-void BSP_LCD_GLASS_ScrollSentence(uint8_t* ptr, uint16_t nScroll, uint16_t ScrollSpeed)
-{
-  uint8_t repetition = 0, nbrchar = 0, sizestr = 0;
-  uint8_t* ptr1;
-  uint8_t str[6] = "";
-
-  /* Reset interrupt variable in case key was press before entering function */
-  bLCDGlass_KeyPressed = 0;
-  
-  if(ptr == 0)
-  {
-    return;
-  }
-  
-  /* To calculate end of string */
-  for(ptr1 = ptr, sizestr = 0; *ptr1 != 0; sizestr++, ptr1++);
-  
-  ptr1 = ptr;
-  
-  BSP_LCD_GLASS_DisplayString(str);
-  HAL_Delay(ScrollSpeed);
-  
-  /* To shift the string for scrolling display*/
-  for (repetition = 0; repetition < nScroll; repetition++)
-  {
-    for(nbrchar = 0; nbrchar < sizestr; nbrchar++)
-    {
-      *(str) =* (ptr1+((nbrchar+1)%sizestr));
-      *(str+1) =* (ptr1+((nbrchar+2)%sizestr));
-      *(str+2) =* (ptr1+((nbrchar+3)%sizestr));
-      *(str+3) =* (ptr1+((nbrchar+4)%sizestr));
-      *(str+4) =* (ptr1+((nbrchar+5)%sizestr));
-      *(str+5) =* (ptr1+((nbrchar+6)%sizestr));
-      BSP_LCD_GLASS_Clear();
-      BSP_LCD_GLASS_DisplayString(str);
-      
-      /* user button pressed stop the scrolling sentence */
-      if(bLCDGlass_KeyPressed)
-      {
-        bLCDGlass_KeyPressed = 0;
-        return;
-      }
-       HAL_Delay(ScrollSpeed);
-    }  
-  }
-}
-
-/**
-  * @}
-  */
-
-/** @addtogroup STM32L476G_DISCOVERY_LCD_Private_Functions
-  * @{
-  */
-
-/**
-  * @brief  Initialize the LCD MSP.
-  * @param  hlcd: LCD handle
-  * @retval None
-  */
-static void LCD_MspInit(LCD_HandleTypeDef *hlcd)
-{
-  GPIO_InitTypeDef  gpioinitstruct = {0};
-  RCC_OscInitTypeDef oscinitstruct = {0};
-  RCC_PeriphCLKInitTypeDef periphclkstruct = {0};
-  
-  /*##-1- Enable PWR  peripheral Clock #######################################*/
-  __HAL_RCC_PWR_CLK_ENABLE();
-  
-  /*##-2- Configure LSE as RTC clock soucre ###################################*/ 
-  oscinitstruct.OscillatorType  = RCC_OSCILLATORTYPE_LSE;
-  oscinitstruct.PLL.PLLState    = RCC_PLL_NONE;
-  oscinitstruct.LSEState        = RCC_LSE_ON;
-  if(HAL_RCC_OscConfig(&oscinitstruct) != HAL_OK)
-  { 
-    while(1);
-  }
-  
-  /*##-3- Select LSE as RTC clock source.##########################*/
-  /* Backup domain management is done in RCC function */
-  periphclkstruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
-  periphclkstruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
-  HAL_RCCEx_PeriphCLKConfig(&periphclkstruct);
-
-  /*##-4- Enable LCD GPIO Clocks #############################################*/
-  __HAL_RCC_GPIOA_CLK_ENABLE();
-  __HAL_RCC_GPIOB_CLK_ENABLE();
-  __HAL_RCC_GPIOC_CLK_ENABLE();
-  __HAL_RCC_GPIOD_CLK_ENABLE();
-
-  
-  /*##-5- Configure peripheral GPIO ##########################################*/
-  /* Configure Output for LCD */
-  /* Port A */
-  gpioinitstruct.Pin        = LCD_GPIO_BANKA_PINS;
-  gpioinitstruct.Mode       = GPIO_MODE_AF_PP;
-  gpioinitstruct.Pull       = GPIO_NOPULL;
-  gpioinitstruct.Speed      = GPIO_SPEED_FREQ_VERY_HIGH;
-  gpioinitstruct.Alternate  = GPIO_AF11_LCD;
-  HAL_GPIO_Init(GPIOA, &gpioinitstruct);
-
-  /* Port B */
-  gpioinitstruct.Pin        = LCD_GPIO_BANKB_PINS;
-  HAL_GPIO_Init(GPIOB, &gpioinitstruct);
-  
-  /* Port C*/
-  gpioinitstruct.Pin        = LCD_GPIO_BANKC_PINS;
-  HAL_GPIO_Init(GPIOC, &gpioinitstruct);
-
-  /* Port D */
-  gpioinitstruct.Pin        = LCD_GPIO_BANKD_PINS;
-  HAL_GPIO_Init(GPIOD, &gpioinitstruct);
-
-  /* Wait for the external capacitor Cext which is connected to the VLCD pin is charged
-  (approximately 2ms for Cext=1uF) */
-  HAL_Delay(2);
-
-  /*##-6- Enable LCD peripheral Clock ########################################*/
-  __HAL_RCC_LCD_CLK_ENABLE();
-}
-
-/**
-  * @brief  DeInitialize the LCD MSP.
-  * @param  hlcd: LCD handle
-  * @retval None
-  */
-static void LCD_MspDeInit(LCD_HandleTypeDef *hlcd)
-{
-  uint32_t gpiopin = 0;
-  
-  /*##-1- Enable LCD GPIO Clocks #############################################*/
-  __HAL_RCC_GPIOA_CLK_ENABLE();
-  __HAL_RCC_GPIOB_CLK_ENABLE();
-  __HAL_RCC_GPIOC_CLK_ENABLE();
-  __HAL_RCC_GPIOD_CLK_ENABLE();
-
-  /*##-1- Configure peripheral GPIO ##########################################*/
-  /* Configure Output for LCD */
-  /* Port A */
-  gpiopin = LCD_GPIO_BANKA_PINS;
-  HAL_GPIO_DeInit(GPIOA, gpiopin);
-
-  /* Port B */
-  gpiopin = LCD_GPIO_BANKB_PINS;
-  HAL_GPIO_DeInit(GPIOB, gpiopin);
-
-  /* Port C*/
-  gpiopin = LCD_GPIO_BANKC_PINS;
-  HAL_GPIO_DeInit(GPIOC, gpiopin);
-
-  /* Port D */
-  gpiopin = LCD_GPIO_BANKD_PINS;
-  HAL_GPIO_DeInit(GPIOD, gpiopin);
-
-  /*##-5- Enable LCD peripheral Clock ########################################*/
-  __HAL_RCC_LCD_CLK_DISABLE();
-}
-
-/**
-  * @brief  Convert an ascii char to the a LCD digit.
-  * @param  Char: a char to display.
-  * @param  Point: a point to add in front of char
-  *         This parameter can be: POINT_OFF or POINT_ON
-  * @param  Colon : flag indicating if a colon character has to be added in front
-  *         of displayed character.
-  *         This parameter can be: DOUBLEPOINT_OFF or DOUBLEPOINT_ON.
-  * @retval None
-  */
-static void Convert(uint8_t* Char, Point_Typedef Point, DoublePoint_Typedef Colon)
-{
-  uint16_t ch = 0 ;
-  uint8_t loop = 0, index = 0;
-  
-  switch (*Char)
-    {
-    case ' ' :
-      ch = 0x00;
-      break;
-
-    case '*':
-      ch = C_STAR;
-      break;
-
-    case '(' :
-      ch = C_OPENPARMAP;
-      break;
-
-    case ')' :
-      ch = C_CLOSEPARMAP;
-      break;
-      
-    case 'd' :
-      ch = C_DMAP;
-      break;
-    
-    case 'm' :
-      ch = C_MMAP;
-      break;
-    
-    case 'n' :
-      ch = C_NMAP;
-      break;
-
-    case 'u' :
-      ch = C_UMAP;
-      break;
-
-    case '-' :
-      ch = C_MINUS;
-      break;
-
-    case '+' :
-      ch = C_PLUS;
-      break;
-
-    case '/' :
-      ch = C_SLATCH;
-      break;  
-      
-    case '�' :
-      ch = C_PERCENT_1;
-      break;  
-    case '%' :
-      ch = C_PERCENT_2; 
-      break;
-    case 255 :
-      ch = C_FULL;
-      break ;
-    
-    case '0':
-    case '1':
-    case '2':
-    case '3':
-    case '4':
-    case '5':
-    case '6':
-    case '7':
-    case '8':
-    case '9':      
-      ch = NumberMap[*Char - ASCII_CHAR_0];    
-      break;
-          
-    default:
-      /* The character Char is one letter in upper case*/
-      if ( (*Char < ASCII_CHAR_LEFT_OPEN_BRACKET) && (*Char > ASCII_CHAR_AT_SYMBOL) )
-      {
-        ch = CapLetterMap[*Char - 'A'];
-      }
-      /* The character Char is one letter in lower case*/
-      if ( (*Char < ASCII_CHAR_LEFT_OPEN_BRACE) && ( *Char > ASCII_CHAR_APOSTROPHE) )
-      {
-        ch = CapLetterMap[*Char - 'a'];
-      }
-      break;
-  }
-       
-  /* Set the digital point can be displayed if the point is on */
-  if (Point == POINT_ON)
-  {
-    ch |= 0x0002;
-  }
-
-  /* Set the "COL" segment in the character that can be displayed if the colon is on */
-  if (Colon == DOUBLEPOINT_ON)
-  {
-    ch |= 0x0020;
-  }    
-
-  for (loop = 12,index=0 ;index < 4; loop -= 4,index++)
-  {
-    Digit[index] = (ch >> loop) & 0x0f; /*To isolate the less significant digit */
-  }
-}
-
-/**
-  * @brief  Write a character in the LCD frame buffer.
-  * @param  ch: the character to display.
-  * @param  Point: a point to add in front of char
-  *         This parameter can be: POINT_OFF or POINT_ON
-  * @param  Colon: flag indicating if a colon character has to be added in front
-  *         of displayed character.
-  *         This parameter can be: DOUBLEPOINT_OFF or DOUBLEPOINT_ON.           
-  * @param  Position: position in the LCD of the character to write [1:6]
-  * @retval None
-  */
-static void WriteChar(uint8_t* ch, Point_Typedef Point, DoublePoint_Typedef Colon, DigitPosition_Typedef Position)
-{
-  uint32_t data =0x00;
-  /* To convert displayed character in segment in array digit */
-  Convert(ch, (Point_Typedef)Point, (DoublePoint_Typedef)Colon);
-
-  switch (Position)
-  {
-    /* Position 1 on LCD (Digit1)*/
-    case LCD_DIGIT_POSITION_1:
-      data = ((Digit[0] & 0x1) << LCD_SEG0_SHIFT) | (((Digit[0] & 0x2) >> 1) << LCD_SEG1_SHIFT)
-          | (((Digit[0] & 0x4) >> 2) << LCD_SEG22_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG23_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT1_COM0, LCD_DIGIT1_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */
-      
-      data = ((Digit[1] & 0x1) << LCD_SEG0_SHIFT) | (((Digit[1] & 0x2) >> 1) << LCD_SEG1_SHIFT)
-          | (((Digit[1] & 0x4) >> 2) << LCD_SEG22_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG23_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT1_COM1, LCD_DIGIT1_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D  */
-      
-      data = ((Digit[2] & 0x1) << LCD_SEG0_SHIFT) | (((Digit[2] & 0x2) >> 1) << LCD_SEG1_SHIFT)
-          | (((Digit[2] & 0x4) >> 2) << LCD_SEG22_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG23_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT1_COM2, LCD_DIGIT1_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P  */
-      
-      data = ((Digit[3] & 0x1) << LCD_SEG0_SHIFT) | (((Digit[3] & 0x2) >> 1) << LCD_SEG1_SHIFT)
-          | (((Digit[3] & 0x4) >> 2) << LCD_SEG22_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG23_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT1_COM3, LCD_DIGIT1_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N  */
-      break;
-
-    /* Position 2 on LCD (Digit2)*/
-    case LCD_DIGIT_POSITION_2:
-      data = ((Digit[0] & 0x1) << LCD_SEG2_SHIFT) | (((Digit[0] & 0x2) >> 1) << LCD_SEG3_SHIFT)
-          | (((Digit[0] & 0x4) >> 2) << LCD_SEG20_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG21_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT2_COM0, LCD_DIGIT2_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */
-      
-      data = ((Digit[1] & 0x1) << LCD_SEG2_SHIFT) | (((Digit[1] & 0x2) >> 1) << LCD_SEG3_SHIFT)
-          | (((Digit[1] & 0x4) >> 2) << LCD_SEG20_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG21_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT2_COM1, LCD_DIGIT2_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D  */
-      
-      data = ((Digit[2] & 0x1) << LCD_SEG2_SHIFT) | (((Digit[2] & 0x2) >> 1) << LCD_SEG3_SHIFT)
-          | (((Digit[2] & 0x4) >> 2) << LCD_SEG20_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG21_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT2_COM2, LCD_DIGIT2_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P  */
-      
-      data = ((Digit[3] & 0x1) << LCD_SEG2_SHIFT) | (((Digit[3] & 0x2) >> 1) << LCD_SEG3_SHIFT)
-          | (((Digit[3] & 0x4) >> 2) << LCD_SEG20_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG21_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT2_COM3, LCD_DIGIT2_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N  */
-      break;
-    
-    /* Position 3 on LCD (Digit3)*/
-    case LCD_DIGIT_POSITION_3:
-      data = ((Digit[0] & 0x1) << LCD_SEG4_SHIFT) | (((Digit[0] & 0x2) >> 1) << LCD_SEG5_SHIFT)
-          | (((Digit[0] & 0x4) >> 2) << LCD_SEG18_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG19_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT3_COM0, LCD_DIGIT3_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */
-      
-      data = ((Digit[1] & 0x1) << LCD_SEG4_SHIFT) | (((Digit[1] & 0x2) >> 1) << LCD_SEG5_SHIFT)
-          | (((Digit[1] & 0x4) >> 2) << LCD_SEG18_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG19_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT3_COM1, LCD_DIGIT3_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D  */
-      
-      data = ((Digit[2] & 0x1) << LCD_SEG4_SHIFT) | (((Digit[2] & 0x2) >> 1) << LCD_SEG5_SHIFT)
-          | (((Digit[2] & 0x4) >> 2) << LCD_SEG18_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG19_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT3_COM2, LCD_DIGIT3_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P  */
-      
-      data = ((Digit[3] & 0x1) << LCD_SEG4_SHIFT) | (((Digit[3] & 0x2) >> 1) << LCD_SEG5_SHIFT)
-          | (((Digit[3] & 0x4) >> 2) << LCD_SEG18_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG19_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT3_COM3, LCD_DIGIT3_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N  */
-      break;
-    
-    /* Position 4 on LCD (Digit4)*/
-    case LCD_DIGIT_POSITION_4:
-      data = ((Digit[0] & 0x1) << LCD_SEG6_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG17_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM0, LCD_DIGIT4_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */
-      
-      data = (((Digit[0] & 0x2) >> 1) << LCD_SEG7_SHIFT) | (((Digit[0] & 0x4) >> 2) << LCD_SEG16_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM0_1, LCD_DIGIT4_COM0_1_SEG_MASK, data); /* 1G 1B 1M 1E */
-      
-      data = ((Digit[1] & 0x1) << LCD_SEG6_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG17_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM1, LCD_DIGIT4_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D  */
-      
-      data = (((Digit[1] & 0x2) >> 1) << LCD_SEG7_SHIFT) | (((Digit[1] & 0x4) >> 2) << LCD_SEG16_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM1_1, LCD_DIGIT4_COM1_1_SEG_MASK, data) ; /* 1F 1A 1C 1D  */
-      
-      data = ((Digit[2] & 0x1) << LCD_SEG6_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG17_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM2, LCD_DIGIT4_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P  */
-      
-      data = (((Digit[2] & 0x2) >> 1) << LCD_SEG7_SHIFT) | (((Digit[2] & 0x4) >> 2) << LCD_SEG16_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM2_1, LCD_DIGIT4_COM2_1_SEG_MASK, data) ; /* 1Q 1K 1Col 1P  */
-      
-      data = ((Digit[3] & 0x1) << LCD_SEG6_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG17_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM3, LCD_DIGIT4_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N  */
-      
-      data = (((Digit[3] & 0x2) >> 1) << LCD_SEG7_SHIFT) | (((Digit[3] & 0x4) >> 2) << LCD_SEG16_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM3_1, LCD_DIGIT4_COM3_1_SEG_MASK, data) ; /* 1H 1J 1DP 1N  */
-      break;
-    
-    /* Position 5 on LCD (Digit5)*/
-    case LCD_DIGIT_POSITION_5:
-       data = (((Digit[0] & 0x2) >> 1) << LCD_SEG9_SHIFT) | (((Digit[0] & 0x4) >> 2) << LCD_SEG14_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM0, LCD_DIGIT5_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */
-      
-      data = ((Digit[0] & 0x1) << LCD_SEG8_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG15_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM0_1, LCD_DIGIT5_COM0_1_SEG_MASK, data); /* 1G 1B 1M 1E */
-      
-      data = (((Digit[1] & 0x2) >> 1) << LCD_SEG9_SHIFT) | (((Digit[1] & 0x4) >> 2) << LCD_SEG14_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM1, LCD_DIGIT5_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D  */
-      
-       data = ((Digit[1] & 0x1) << LCD_SEG8_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG15_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM1_1, LCD_DIGIT5_COM1_1_SEG_MASK, data) ; /* 1F 1A 1C 1D  */
-      
-      data = (((Digit[2] & 0x2) >> 1) << LCD_SEG9_SHIFT) | (((Digit[2] & 0x4) >> 2) << LCD_SEG14_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM2, LCD_DIGIT5_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P  */
-      
-      data = ((Digit[2] & 0x1) << LCD_SEG8_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG15_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM2_1, LCD_DIGIT5_COM2_1_SEG_MASK, data) ; /* 1Q 1K 1Col 1P  */
-      
-      data = (((Digit[3] & 0x2) >> 1) << LCD_SEG9_SHIFT) | (((Digit[3] & 0x4) >> 2) << LCD_SEG14_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM3, LCD_DIGIT5_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N  */
-      
-      data = ((Digit[3] & 0x1) << LCD_SEG8_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG15_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM3_1, LCD_DIGIT5_COM3_1_SEG_MASK, data) ; /* 1H 1J 1DP 1N  */
-      break;
-    
-    /* Position 6 on LCD (Digit6)*/
-    case LCD_DIGIT_POSITION_6:
-      data = ((Digit[0] & 0x1) << LCD_SEG10_SHIFT) | (((Digit[0] & 0x2) >> 1) << LCD_SEG11_SHIFT)
-          | (((Digit[0] & 0x4) >> 2) << LCD_SEG12_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG13_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT6_COM0, LCD_DIGIT6_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */
-      
-      data = ((Digit[1] & 0x1) << LCD_SEG10_SHIFT) | (((Digit[1] & 0x2) >> 1) << LCD_SEG11_SHIFT)
-          | (((Digit[1] & 0x4) >> 2) << LCD_SEG12_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG13_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT6_COM1, LCD_DIGIT6_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D  */
-      
-      data = ((Digit[2] & 0x1) << LCD_SEG10_SHIFT) | (((Digit[2] & 0x2) >> 1) << LCD_SEG11_SHIFT)
-          | (((Digit[2] & 0x4) >> 2) << LCD_SEG12_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG13_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT6_COM2, LCD_DIGIT6_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P  */
-      
-      data = ((Digit[3] & 0x1) << LCD_SEG10_SHIFT) | (((Digit[3] & 0x2) >> 1) << LCD_SEG11_SHIFT)
-          | (((Digit[3] & 0x4) >> 2) << LCD_SEG12_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG13_SHIFT);
-      HAL_LCD_Write(&LCDHandle, LCD_DIGIT6_COM3, LCD_DIGIT6_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N  */
-      break;
-    
-     default:
-      break;
-  }
-}
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
--- a/stm32l476g_discovery_glass_lcd.h	Thu Dec 03 22:16:32 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,547 +0,0 @@
- /**
-  ******************************************************************************
-  * @file    stm32l476g_discovery_glass_lcd.h
-  * @author  MCD Application Team
-  * @version V1.0.1
-  * @date    16-September-2015
-  * @brief   Header file for stm32l476g_discovery_glass_lcd.c module.
-  ******************************************************************************
-  * @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.
-  *
-  ******************************************************************************
-  */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32L476G_DISCOVERY_GLASS_LCD_H
-#define __STM32L476G_DISCOVERY_GLASS_LCD_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32l476g_discovery.h"
-
-/** @addtogroup BSP
-  * @{
-  */
-
-/** @addtogroup STM32L476G_DISCOVERY
-  * @{
-  */
-
-/** @addtogroup STM32L476G_DISCOVERY_GLASS_LCD
-  * @{
-  */
-
-/* Exported types ------------------------------------------------------------*/
-
-/** @defgroup STM32L476G_DISCOVERY_GLASS_LCD_Exported_Types Exported Types
-  * @{
-  */
-/**
-  * @brief LCD Glass digit position
-  */
-typedef enum
-{
-  LCD_DIGIT_POSITION_1 = 0,
-  LCD_DIGIT_POSITION_2 = 1,
-  LCD_DIGIT_POSITION_3 = 2,
-  LCD_DIGIT_POSITION_4 = 3,
-  LCD_DIGIT_POSITION_5 = 4,
-  LCD_DIGIT_POSITION_6 = 5,
-  LCD_DIGIT_MAX_NUMBER = 6,
-}DigitPosition_Typedef;
-/**
-  * @brief LCD Glass point
-  * Warning: element values correspond to LCD Glass point.
-  */
-
-typedef enum
-{
-  POINT_OFF = 0,
-  POINT_ON = 1
-}Point_Typedef;
-
-/**
-  * @brief LCD Glass Double point
-  * Warning: element values correspond to LCD Glass Double point.
-  */
-typedef enum
-{
-  DOUBLEPOINT_OFF = 0,
-  DOUBLEPOINT_ON = 1
-}DoublePoint_Typedef;
-
-/**
-  * @brief LCD Glass Battery Level
-  * element values correspond to different LCD Glass battery levels
-  */
-typedef enum
-{
-  BATTERYLEVEL_OFF = 0,
-  BATTERYLEVEL_1_4 = 1,
-  BATTERYLEVEL_1_2 = 2,
-  BATTERYLEVEL_3_4 = 3,
-  BATTERYLEVEL_FULL = 4
-}BatteryLevel_Typedef;
-
-/**
-  * @brief LCD Glass Bar Id
-  */
-typedef enum
-{
-  LCD_BAR_NONE  = 0,
-  LCD_BAR_0     = (1 << 0),
-  LCD_BAR_1     = (1 << 1),
-  LCD_BAR_2     = (1 << 2),
-  LCD_BAR_3     = (1 << 3)
-}BarId_Typedef;
-/**
-  * @}
-  */
-
-/** @defgroup STM32L476G_DISCOVERY_GLASS_LCD_Exported_Constants Exported Constants
-  * @{
-*/
-/**
-  * @brief LCD digit defintion 
-  */
-#define COM_PER_DIGIT_NB          4/*!< Specifies number of COM to address a digit */
-#define SEG_PER_DIGIT_NB          4/*!< Specifies number of SEG to address a digit */
-
-#define LCD_MAP_CHAR_COM0_SEG_1ST_POS   (1 << LCD_MAP_CHAR_COM0_SEG_1ST_SHIFT)
-#define LCD_MAP_CHAR_COM0_SEG_2ND_POS   (1 << LCD_MAP_CHAR_COM0_SEG_2ND_SHIFT)
-#define LCD_MAP_CHAR_COM0_SEG_3RD_POS   (1 << LCD_MAP_CHAR_COM0_SEG_3RD_SHIFT)
-#define LCD_MAP_CHAR_COM0_SEG_4TH_POS   (1 << LCD_MAP_CHAR_COM0_SEG_4TH_SHIFT)
-#define LCD_MAP_CHAR_COM1_SEG_1ST_POS   (1 << LCD_MAP_CHAR_COM1_SEG_1ST_SHIFT)
-#define LCD_MAP_CHAR_COM1_SEG_2ND_POS   (1 << LCD_MAP_CHAR_COM1_SEG_2ND_SHIFT)
-#define LCD_MAP_CHAR_COM1_SEG_3RD_POS   (1 << LCD_MAP_CHAR_COM1_SEG_3RD_SHIFT)
-#define LCD_MAP_CHAR_COM1_SEG_4TH_POS   (1 << LCD_MAP_CHAR_COM1_SEG_4TH_SHIFT)
-#define LCD_MAP_CHAR_COM2_SEG_1ST_POS   (1 << LCD_MAP_CHAR_COM2_SEG_1ST_SHIFT)
-#define LCD_MAP_CHAR_COM2_SEG_2ND_POS   (1 << LCD_MAP_CHAR_COM2_SEG_2ND_SHIFT)
-#define LCD_MAP_CHAR_COM2_SEG_3RD_POS   (1 << LCD_MAP_CHAR_COM2_SEG_3RD_SHIFT)
-#define LCD_MAP_CHAR_COM2_SEG_4TH_POS   (1 << LCD_MAP_CHAR_COM2_SEG_4TH_SHIFT)
-#define LCD_MAP_CHAR_COM3_SEG_1ST_POS   (1 << LCD_MAP_CHAR_COM3_SEG_1ST_SHIFT)
-#define LCD_MAP_CHAR_COM3_SEG_2ND_POS   (1 << LCD_MAP_CHAR_COM3_SEG_2ND_SHIFT)
-#define LCD_MAP_CHAR_COM3_SEG_3RD_POS   (1 << LCD_MAP_CHAR_COM3_SEG_3RD_SHIFT)
-#define LCD_MAP_CHAR_COM3_SEG_4TH_POS   (1 << LCD_MAP_CHAR_COM3_SEG_4TH_SHIFT)
-#define LCD_MAP_CHAR_COM0_SEG_1ST_SHIFT 0x00000000
-#define LCD_MAP_CHAR_COM0_SEG_2ND_SHIFT 0x00000001
-#define LCD_MAP_CHAR_COM0_SEG_3RD_SHIFT 0x00000002
-#define LCD_MAP_CHAR_COM0_SEG_4TH_SHIFT 0x00000003
-#define LCD_MAP_CHAR_COM1_SEG_1ST_SHIFT 0x00000004
-#define LCD_MAP_CHAR_COM1_SEG_2ND_SHIFT 0x00000005
-#define LCD_MAP_CHAR_COM1_SEG_3RD_SHIFT 0x00000006
-#define LCD_MAP_CHAR_COM1_SEG_4TH_SHIFT 0x00000007
-#define LCD_MAP_CHAR_COM2_SEG_1ST_SHIFT 0x00000008
-#define LCD_MAP_CHAR_COM2_SEG_2ND_SHIFT 0x00000009
-#define LCD_MAP_CHAR_COM2_SEG_3RD_SHIFT 0x00000010
-#define LCD_MAP_CHAR_COM2_SEG_4TH_SHIFT 0x00000011
-#define LCD_MAP_CHAR_COM3_SEG_1ST_SHIFT 0x00000012
-#define LCD_MAP_CHAR_COM3_SEG_2ND_SHIFT 0x00000013
-#define LCD_MAP_CHAR_COM3_SEG_3RD_SHIFT 0x00000014
-#define LCD_MAP_CHAR_COM3_SEG_4TH_SHIFT 0x00000015
-
-/**
-  * @brief LCD Digit defines
-  */
-#define LCD_DIGIT1_COM0               LCD_COM0
-#define LCD_DIGIT1_COM0_SEG_MASK      ~(LCD_SEG0 | LCD_SEG1 | LCD_SEG22 | LCD_SEG23)
-#define LCD_DIGIT1_COM1               LCD_COM1
-#define LCD_DIGIT1_COM1_SEG_MASK      ~(LCD_SEG0 | LCD_SEG1 | LCD_SEG22 | LCD_SEG23)
-#define LCD_DIGIT1_COM2               LCD_COM2
-#define LCD_DIGIT1_COM2_SEG_MASK      ~(LCD_SEG0 | LCD_SEG1 | LCD_SEG22 | LCD_SEG23)
-#define LCD_DIGIT1_COM3               LCD_COM3
-#define LCD_DIGIT1_COM3_SEG_MASK      ~(LCD_SEG0 | LCD_SEG1 | LCD_SEG22 | LCD_SEG23)
-
-#define LCD_DIGIT2_COM0               LCD_COM0
-#define LCD_DIGIT2_COM0_SEG_MASK      ~(LCD_SEG2 | LCD_SEG3 | LCD_SEG20 | LCD_SEG21)
-#define LCD_DIGIT2_COM1               LCD_COM1
-#define LCD_DIGIT2_COM1_SEG_MASK      ~(LCD_SEG2 | LCD_SEG3 | LCD_SEG20 | LCD_SEG21)
-#define LCD_DIGIT2_COM2               LCD_COM2
-#define LCD_DIGIT2_COM2_SEG_MASK      ~(LCD_SEG2 | LCD_SEG3 | LCD_SEG20 | LCD_SEG21)
-#define LCD_DIGIT2_COM3               LCD_COM3
-#define LCD_DIGIT2_COM3_SEG_MASK      ~(LCD_SEG2 | LCD_SEG3 | LCD_SEG20 | LCD_SEG21)
-
-#define LCD_DIGIT3_COM0               LCD_COM0
-#define LCD_DIGIT3_COM0_SEG_MASK      ~(LCD_SEG4 | LCD_SEG5 | LCD_SEG18 | LCD_SEG19)
-#define LCD_DIGIT3_COM1               LCD_COM1
-#define LCD_DIGIT3_COM1_SEG_MASK      ~(LCD_SEG4 | LCD_SEG5 | LCD_SEG18 | LCD_SEG19)
-#define LCD_DIGIT3_COM2               LCD_COM2
-#define LCD_DIGIT3_COM2_SEG_MASK      ~(LCD_SEG4 | LCD_SEG5 | LCD_SEG18 | LCD_SEG19)
-#define LCD_DIGIT3_COM3               LCD_COM3
-#define LCD_DIGIT3_COM3_SEG_MASK      ~(LCD_SEG4 | LCD_SEG5 | LCD_SEG18 | LCD_SEG19)
-
-#define LCD_DIGIT4_COM0               LCD_COM0
-#define LCD_DIGIT4_COM0_SEG_MASK      ~(LCD_SEG6 | LCD_SEG17)
-#define LCD_DIGIT4_COM0_1             LCD_COM0_1
-#define LCD_DIGIT4_COM0_1_SEG_MASK    ~(LCD_SEG7 | LCD_SEG16)
-#define LCD_DIGIT4_COM1               LCD_COM1
-#define LCD_DIGIT4_COM1_SEG_MASK      ~(LCD_SEG6 |  LCD_SEG17)
-#define LCD_DIGIT4_COM1_1             LCD_COM1_1
-#define LCD_DIGIT4_COM1_1_SEG_MASK    ~(LCD_SEG7 | LCD_SEG16)
-#define LCD_DIGIT4_COM2               LCD_COM2
-#define LCD_DIGIT4_COM2_SEG_MASK      ~(LCD_SEG6 | LCD_SEG17)
-#define LCD_DIGIT4_COM2_1             LCD_COM2_1
-#define LCD_DIGIT4_COM2_1_SEG_MASK    ~(LCD_SEG7 | LCD_SEG16)
-#define LCD_DIGIT4_COM3               LCD_COM3
-#define LCD_DIGIT4_COM3_SEG_MASK      ~(LCD_SEG6 | LCD_SEG17)
-#define LCD_DIGIT4_COM3_1             LCD_COM3_1
-#define LCD_DIGIT4_COM3_1_SEG_MASK    ~(LCD_SEG7 | LCD_SEG16)
-
-#define LCD_DIGIT5_COM0               LCD_COM0
-#define LCD_DIGIT5_COM0_SEG_MASK      ~(LCD_SEG9 | LCD_SEG14)
-#define LCD_DIGIT5_COM0_1             LCD_COM0_1
-#define LCD_DIGIT5_COM0_1_SEG_MASK    ~(LCD_SEG8 | LCD_SEG15)
-#define LCD_DIGIT5_COM1               LCD_COM1
-#define LCD_DIGIT5_COM1_SEG_MASK      ~(LCD_SEG9 | LCD_SEG14)
-#define LCD_DIGIT5_COM1_1             LCD_COM1_1
-#define LCD_DIGIT5_COM1_1_SEG_MASK    ~(LCD_SEG8 | LCD_SEG15)
-#define LCD_DIGIT5_COM2               LCD_COM2
-#define LCD_DIGIT5_COM2_SEG_MASK      ~(LCD_SEG9 | LCD_SEG14)
-#define LCD_DIGIT5_COM2_1             LCD_COM2_1
-#define LCD_DIGIT5_COM2_1_SEG_MASK    ~(LCD_SEG8 | LCD_SEG15)
-#define LCD_DIGIT5_COM3               LCD_COM3
-#define LCD_DIGIT5_COM3_SEG_MASK      ~(LCD_SEG9 | LCD_SEG14)
-#define LCD_DIGIT5_COM3_1             LCD_COM3_1
-#define LCD_DIGIT5_COM3_1_SEG_MASK    ~(LCD_SEG8 | LCD_SEG15)
-
-#define LCD_DIGIT6_COM0               LCD_COM0
-#define LCD_DIGIT6_COM0_SEG_MASK      ~(LCD_SEG10 | LCD_SEG11 | LCD_SEG12 | LCD_SEG13)
-#define LCD_DIGIT6_COM1               LCD_COM1
-#define LCD_DIGIT6_COM1_SEG_MASK      ~(LCD_SEG10 | LCD_SEG11 | LCD_SEG12 | LCD_SEG13)
-#define LCD_DIGIT6_COM2               LCD_COM2
-#define LCD_DIGIT6_COM2_SEG_MASK      ~(LCD_SEG10 | LCD_SEG11 | LCD_SEG12 | LCD_SEG13)
-#define LCD_DIGIT6_COM3               LCD_COM3
-#define LCD_DIGIT6_COM3_SEG_MASK      ~(LCD_SEG10 | LCD_SEG11 | LCD_SEG12 | LCD_SEG13)
-
-/**
-  * @brief LCD Bar location
-  */
-#define LCD_BAR0_2_COM            LCD_COM3
-#define LCD_BAR1_3_COM            LCD_COM2
-#define LCD_BAR0_SEG              LCD_SEG11
-#define LCD_BAR1_SEG              LCD_SEG11
-#define LCD_BAR2_SEG              LCD_SEG9
-#define LCD_BAR3_SEG              LCD_SEG9
-#define LCD_BAR0_2_SEG_MASK       ~(LCD_BAR0_SEG | LCD_BAR2_SEG)
-#define LCD_BAR1_3_SEG_MASK       ~(LCD_BAR1_SEG | LCD_BAR3_SEG)
-
-/**
-  * @brief LCD segments & coms redefinition.
-  * LCD component segments & coms are not necessarily link to MCU segmnents & coms output.
-  */
-#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB)
-#define LCD_COM0          MCU_LCD_COM0
-#define LCD_COM0_1        MCU_LCD_COM0_1
-#define LCD_COM1          MCU_LCD_COM1
-#define LCD_COM1_1        MCU_LCD_COM1_1
-#define LCD_COM2          MCU_LCD_COM2
-#define LCD_COM2_1        MCU_LCD_COM2_1
-#define LCD_COM3          MCU_LCD_COM3
-#define LCD_COM3_1        MCU_LCD_COM3_1
-#elif defined (USE_STM32L476G_DISCO_REVA)
-#define LCD_COM0          MCU_LCD_COM5
-#define LCD_COM0_1        MCU_LCD_COM5_1
-#define LCD_COM1          MCU_LCD_COM7
-#define LCD_COM1_1        MCU_LCD_COM7_1
-#define LCD_COM2          MCU_LCD_COM6
-#define LCD_COM2_1        MCU_LCD_COM6_1
-#define LCD_COM3          MCU_LCD_COM4
-#define LCD_COM3_1        MCU_LCD_COM4_1
-#endif
-#define LCD_SEG0          MCU_LCD_SEG4
-#define LCD_SEG1          MCU_LCD_SEG23
-#define LCD_SEG2          MCU_LCD_SEG6
-#define LCD_SEG3          MCU_LCD_SEG13
-#define LCD_SEG4          MCU_LCD_SEG15
-#define LCD_SEG5          MCU_LCD_SEG29
-#define LCD_SEG6          MCU_LCD_SEG31
-#define LCD_SEG7          MCU_LCD_SEG33
-#define LCD_SEG8          MCU_LCD_SEG35
-#define LCD_SEG9          MCU_LCD_SEG25
-#define LCD_SEG10         MCU_LCD_SEG17
-#define LCD_SEG11         MCU_LCD_SEG8
-#define LCD_SEG12         MCU_LCD_SEG9
-#define LCD_SEG13         MCU_LCD_SEG26
-#define LCD_SEG14         MCU_LCD_SEG24
-#define LCD_SEG15         MCU_LCD_SEG34
-#define LCD_SEG16         MCU_LCD_SEG32
-#define LCD_SEG17         MCU_LCD_SEG30
-#define LCD_SEG18         MCU_LCD_SEG28
-#define LCD_SEG19         MCU_LCD_SEG14
-#define LCD_SEG20         MCU_LCD_SEG12
-#define LCD_SEG21         MCU_LCD_SEG5
-#define LCD_SEG22         MCU_LCD_SEG22
-#define LCD_SEG23         MCU_LCD_SEG3
-#define LCD_SEG0_SHIFT          MCU_LCD_SEG4_SHIFT
-#define LCD_SEG1_SHIFT          MCU_LCD_SEG23_SHIFT
-#define LCD_SEG2_SHIFT          MCU_LCD_SEG6_SHIFT
-#define LCD_SEG3_SHIFT          MCU_LCD_SEG13_SHIFT
-#define LCD_SEG4_SHIFT          MCU_LCD_SEG15_SHIFT
-#define LCD_SEG5_SHIFT          MCU_LCD_SEG29_SHIFT
-#define LCD_SEG6_SHIFT          MCU_LCD_SEG31_SHIFT
-#define LCD_SEG7_SHIFT          MCU_LCD_SEG33_SHIFT
-#define LCD_SEG8_SHIFT          MCU_LCD_SEG35_SHIFT
-#define LCD_SEG9_SHIFT          MCU_LCD_SEG25_SHIFT
-#define LCD_SEG10_SHIFT         MCU_LCD_SEG17_SHIFT
-#define LCD_SEG11_SHIFT         MCU_LCD_SEG8_SHIFT
-#define LCD_SEG12_SHIFT         MCU_LCD_SEG9_SHIFT
-#define LCD_SEG13_SHIFT         MCU_LCD_SEG26_SHIFT
-#define LCD_SEG14_SHIFT         MCU_LCD_SEG24_SHIFT
-#define LCD_SEG15_SHIFT         MCU_LCD_SEG34_SHIFT
-#define LCD_SEG16_SHIFT         MCU_LCD_SEG32_SHIFT
-#define LCD_SEG17_SHIFT         MCU_LCD_SEG30_SHIFT
-#define LCD_SEG18_SHIFT         MCU_LCD_SEG28_SHIFT
-#define LCD_SEG19_SHIFT         MCU_LCD_SEG14_SHIFT
-#define LCD_SEG20_SHIFT         MCU_LCD_SEG12_SHIFT
-#define LCD_SEG21_SHIFT         MCU_LCD_SEG5_SHIFT
-#define LCD_SEG22_SHIFT         MCU_LCD_SEG22_SHIFT
-#define LCD_SEG23_SHIFT         MCU_LCD_SEG3_SHIFT
-
-/**
-  * @brief STM32 LCD segments & coms definitions.
-  */
-#define MCU_LCD_COM0          LCD_RAM_REGISTER0
-#define MCU_LCD_COM0_1        LCD_RAM_REGISTER1
-#define MCU_LCD_COM1          LCD_RAM_REGISTER2
-#define MCU_LCD_COM1_1        LCD_RAM_REGISTER3
-#define MCU_LCD_COM2          LCD_RAM_REGISTER4
-#define MCU_LCD_COM2_1        LCD_RAM_REGISTER5
-#define MCU_LCD_COM3          LCD_RAM_REGISTER6
-#define MCU_LCD_COM3_1        LCD_RAM_REGISTER7
-#define MCU_LCD_COM4          LCD_RAM_REGISTER8
-#define MCU_LCD_COM4_1        LCD_RAM_REGISTER9
-#define MCU_LCD_COM5          LCD_RAM_REGISTER10
-#define MCU_LCD_COM5_1        LCD_RAM_REGISTER11
-#define MCU_LCD_COM6          LCD_RAM_REGISTER12
-#define MCU_LCD_COM6_1        LCD_RAM_REGISTER13
-#define MCU_LCD_COM7          LCD_RAM_REGISTER14
-#define MCU_LCD_COM7_1        LCD_RAM_REGISTER15
-#define MCU_LCD_SEG0          (1U << MCU_LCD_SEG0_SHIFT)
-#define MCU_LCD_SEG1          (1U << MCU_LCD_SEG1_SHIFT)
-#define MCU_LCD_SEG2          (1U << MCU_LCD_SEG2_SHIFT)
-#define MCU_LCD_SEG3          (1U << MCU_LCD_SEG3_SHIFT)
-#define MCU_LCD_SEG4          (1U << MCU_LCD_SEG4_SHIFT)
-#define MCU_LCD_SEG5          (1U << MCU_LCD_SEG5_SHIFT)
-#define MCU_LCD_SEG6          (1U << MCU_LCD_SEG6_SHIFT)
-#define MCU_LCD_SEG7          (1U << MCU_LCD_SEG7_SHIFT)
-#define MCU_LCD_SEG8          (1U << MCU_LCD_SEG8_SHIFT)
-#define MCU_LCD_SEG9          (1U << MCU_LCD_SEG9_SHIFT)
-#define MCU_LCD_SEG10         (1U << MCU_LCD_SEG10_SHIFT)
-#define MCU_LCD_SEG11         (1U << MCU_LCD_SEG11_SHIFT)
-#define MCU_LCD_SEG12         (1U << MCU_LCD_SEG12_SHIFT)
-#define MCU_LCD_SEG13         (1U << MCU_LCD_SEG13_SHIFT)
-#define MCU_LCD_SEG14         (1U << MCU_LCD_SEG14_SHIFT)
-#define MCU_LCD_SEG15         (1U << MCU_LCD_SEG15_SHIFT)
-#define MCU_LCD_SEG16         (1U << MCU_LCD_SEG16_SHIFT)
-#define MCU_LCD_SEG17         (1U << MCU_LCD_SEG17_SHIFT)
-#define MCU_LCD_SEG18         (1U << MCU_LCD_SEG18_SHIFT)
-#define MCU_LCD_SEG19         (1U << MCU_LCD_SEG19_SHIFT)
-#define MCU_LCD_SEG20         (1U << MCU_LCD_SEG20_SHIFT)
-#define MCU_LCD_SEG21         (1U << MCU_LCD_SEG21_SHIFT)
-#define MCU_LCD_SEG22         (1U << MCU_LCD_SEG22_SHIFT)
-#define MCU_LCD_SEG23         (1U << MCU_LCD_SEG23_SHIFT)
-#define MCU_LCD_SEG24         (1U << MCU_LCD_SEG24_SHIFT)
-#define MCU_LCD_SEG25         (1U << MCU_LCD_SEG25_SHIFT)
-#define MCU_LCD_SEG26         (1U << MCU_LCD_SEG26_SHIFT)
-#define MCU_LCD_SEG27         (1U << MCU_LCD_SEG27_SHIFT)
-#define MCU_LCD_SEG28         (1U << MCU_LCD_SEG28_SHIFT)
-#define MCU_LCD_SEG29         (1U << MCU_LCD_SEG29_SHIFT)
-#define MCU_LCD_SEG30         (1U << MCU_LCD_SEG30_SHIFT)
-#define MCU_LCD_SEG31         (1U << MCU_LCD_SEG31_SHIFT)
-#define MCU_LCD_SEG32         (1U << MCU_LCD_SEG32_SHIFT)
-#define MCU_LCD_SEG33         (1U << MCU_LCD_SEG33_SHIFT)
-#define MCU_LCD_SEG34         (1U << MCU_LCD_SEG34_SHIFT)
-#define MCU_LCD_SEG35         (1U << MCU_LCD_SEG35_SHIFT)
-#define MCU_LCD_SEG36         (1U << MCU_LCD_SEG36_SHIFT)
-#define MCU_LCD_SEG37         (1U << MCU_LCD_SEG37_SHIFT)
-#define MCU_LCD_SEG38         (1U << MCU_LCD_SEG38_SHIFT)
-#define MCU_LCD_SEG0_SHIFT    0
-#define MCU_LCD_SEG1_SHIFT    1
-#define MCU_LCD_SEG2_SHIFT    2
-#define MCU_LCD_SEG3_SHIFT    3
-#define MCU_LCD_SEG4_SHIFT    4
-#define MCU_LCD_SEG5_SHIFT    5
-#define MCU_LCD_SEG6_SHIFT    6
-#define MCU_LCD_SEG7_SHIFT    7
-#define MCU_LCD_SEG8_SHIFT    8
-#define MCU_LCD_SEG9_SHIFT    9
-#define MCU_LCD_SEG10_SHIFT   10
-#define MCU_LCD_SEG11_SHIFT   11
-#define MCU_LCD_SEG12_SHIFT   12
-#define MCU_LCD_SEG13_SHIFT   13
-#define MCU_LCD_SEG14_SHIFT   14
-#define MCU_LCD_SEG15_SHIFT   15
-#define MCU_LCD_SEG16_SHIFT   16
-#define MCU_LCD_SEG17_SHIFT   17
-#define MCU_LCD_SEG18_SHIFT   18
-#define MCU_LCD_SEG19_SHIFT   19
-#define MCU_LCD_SEG20_SHIFT   20
-#define MCU_LCD_SEG21_SHIFT   21
-#define MCU_LCD_SEG22_SHIFT   22
-#define MCU_LCD_SEG23_SHIFT   23
-#define MCU_LCD_SEG24_SHIFT   24
-#define MCU_LCD_SEG25_SHIFT   25
-#define MCU_LCD_SEG26_SHIFT   26
-#define MCU_LCD_SEG27_SHIFT   27
-#define MCU_LCD_SEG28_SHIFT   28
-#define MCU_LCD_SEG29_SHIFT   29
-#define MCU_LCD_SEG30_SHIFT   30
-#define MCU_LCD_SEG31_SHIFT   31
-#define MCU_LCD_SEG32_SHIFT   0
-#define MCU_LCD_SEG33_SHIFT   1
-#define MCU_LCD_SEG34_SHIFT   2
-#define MCU_LCD_SEG35_SHIFT   3
-#define MCU_LCD_SEG36_SHIFT   4
-#define MCU_LCD_SEG37_SHIFT   5
-#define MCU_LCD_SEG38_SHIFT   6
-#define MCU_LCD_SEG39_SHIFT   7
-#define MCU_LCD_SEG40_SHIFT   8
-#define MCU_LCD_SEG41_SHIFT   9
-#define MCU_LCD_SEG42_SHIFT   10
-#define MCU_LCD_SEG43_SHIFT   11
-
-/**
-  * @brief LCD Pins definition.
-  */
-#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB)
-#define LCD_GPIO_BANKA_PINS  (GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 |    \
-                              GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_15)
-#define LCD_GPIO_BANKB_PINS  (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 |    \
-                              GPIO_PIN_5 | GPIO_PIN_9 | GPIO_PIN_12 |   \
-                              GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15)
-#define LCD_GPIO_BANKC_PINS  (GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 |    \
-                              GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8)
-#define LCD_GPIO_BANKD_PINS  (GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 |   \
-                              GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | \
-                              GPIO_PIN_14 | GPIO_PIN_15)
-#elif defined (USE_STM32L476G_DISCO_REVA)
-#define LCD_GPIO_BANKA_PINS  (GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_15)
-#define LCD_GPIO_BANKB_PINS  (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 |    \
-                              GPIO_PIN_5 | GPIO_PIN_12 | GPIO_PIN_13 |  \
-                              GPIO_PIN_14 | GPIO_PIN_15)
-#define LCD_GPIO_BANKC_PINS  (GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 |    \
-                              GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 |    \
-                              GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12)
-#define LCD_GPIO_BANKD_PINS  (GPIO_PIN_2 | GPIO_PIN_8 | GPIO_PIN_9 |    \
-                              GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | \
-                              GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15)
-#endif
-
-/* Define for scrolling sentences*/
-#define SCROLL_SPEED_HIGH     150
-#define SCROLL_SPEED_MEDIUM   300
-#define SCROLL_SPEED_LOW      450
-
-#define DOT                   ((uint16_t) 0x8000 ) /* for add decimal point in string */
-#define DOUBLE_DOT            ((uint16_t) 0x4000) /* for add decimal point in string */
-
-/* code for '(' character */
-#define C_OPENPARMAP          ((uint16_t) 0x0028)
-
-/* code for ')' character */
-#define C_CLOSEPARMAP         ((uint16_t) 0x0011)
-
-/* code for 'd' character */
-#define C_DMAP                ((uint16_t) 0xf300)
-
-/* code for 'm' character */
-#define C_MMAP                ((uint16_t) 0xb210)
-
-/* code for 'n' character */
-#define C_NMAP                ((uint16_t) 0x2210)
-
-/* code for 'µ' character */
-#define C_UMAP                ((uint16_t) 0x6084)
-
-/* constant code for '*' character */
-#define C_STAR                ((uint16_t) 0xA0DD)
-
-/* constant code for '-' character */
-#define C_MINUS               ((uint16_t) 0xA000)
-
-/* constant code for '+' character */
-#define C_PLUS                ((uint16_t) 0xA014)
-
-/* constant code for '/' */
-#define C_SLATCH              ((uint16_t) 0x00c0)
-
-/* constant code for ° */
-#define C_PERCENT_1           ((uint16_t) 0xec00)
-
-/* constant code for small o */
-#define C_PERCENT_2           ((uint16_t) 0xb300)
-
-#define C_FULL                ((uint16_t) 0xffdd)
-
-/**
-  * @}
-  */
-
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup STM32L476G_DISCOVERY_LCD_Exported_Functions Exported Functions
-  * @{
-  */
-void BSP_LCD_GLASS_Init(void);
-void BSP_LCD_GLASS_DeInit(void);
-void BSP_LCD_GLASS_BlinkConfig(uint32_t BlinkMode, uint32_t BlinkFrequency);
-void BSP_LCD_GLASS_Contrast(uint32_t Contrast);
-void BSP_LCD_GLASS_DisplayChar(uint8_t* ch, Point_Typedef Point, DoublePoint_Typedef Column, DigitPosition_Typedef Position);
-void BSP_LCD_GLASS_DisplayString(uint8_t* ptr);
-void BSP_LCD_GLASS_DisplayStrDeci(uint16_t* ptr);
-void BSP_LCD_GLASS_ScrollSentence(uint8_t* ptr, uint16_t nScroll, uint16_t ScrollSpeed);
-void BSP_LCD_GLASS_DisplayBar(uint32_t BarId);
-void BSP_LCD_GLASS_ClearBar(uint32_t BarId);
-void BSP_LCD_GLASS_BarLevelConfig(uint8_t BarLevel);
-void BSP_LCD_GLASS_Clear(void);
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32L476G_DISCOVERY_GLASS_LCD_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
--- a/stm32l476g_discovery_qspi.h	Thu Dec 03 22:16:32 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32l476g_discovery_qspi.h
-  * @author  MCD Application Team
-  * @version V1.0.1
-  * @date    16-September-2015
-  * @brief   This file contains the common defines and functions prototypes for
-  *          the stm32l476g_discovery_qspi.c driver.
-  ******************************************************************************
-  * @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.
-  *
-  ******************************************************************************
-  */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32L476G_DISCOVERY_QSPI_H
-#define __STM32L476G_DISCOVERY_QSPI_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif 
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32l4xx_hal.h"
-#include "n25q128a.h"
-
-/** @addtogroup BSP
-  * @{
-  */
-
-/** @addtogroup STM32L476G_DISCOVERY
-  * @{
-  */
-
-/** @addtogroup STM32L476G_DISCOVERY_QSPI
-  * @{
-  */
-
-/* Exported constants --------------------------------------------------------*/ 
-/** @defgroup STM32L476G_DISCOVERY_QSPI_Exported_Constants Exported Constants
-  * @{
-  */
-/* QSPI Error codes */
-#define QSPI_OK            ((uint8_t)0x00)
-#define QSPI_ERROR         ((uint8_t)0x01)
-#define QSPI_BUSY          ((uint8_t)0x02)
-#define QSPI_NOT_SUPPORTED ((uint8_t)0x04)
-#define QSPI_SUSPENDED     ((uint8_t)0x08)
-
-/**
-  * @}
-  */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup STM32L476G_DISCOVERY_QSPI_Exported_Types Exported Types
-  * @{
-  */
-/* QSPI Info */
-typedef struct {
-  uint32_t FlashSize;          /*!< Size of the flash */
-  uint32_t EraseSectorSize;    /*!< Size of sectors for the erase operation */
-  uint32_t EraseSectorsNumber; /*!< Number of sectors for the erase operation */
-  uint32_t ProgPageSize;       /*!< Size of pages for the program operation */
-  uint32_t ProgPagesNumber;    /*!< Number of pages for the program operation */
-} QSPI_Info;
-
-/**
-  * @}
-  */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup STM32L476G_DISCOVERY_QSPI_Exported_Functions Exported Functions
-  * @{
-  */
-uint8_t BSP_QSPI_Init        (void);
-uint8_t BSP_QSPI_DeInit      (void);
-uint8_t BSP_QSPI_Read        (uint8_t* pData, uint32_t ReadAddr, uint32_t Size);
-uint8_t BSP_QSPI_Write       (uint8_t* pData, uint32_t WriteAddr, uint32_t Size);
-uint8_t BSP_QSPI_Erase_Block (uint32_t BlockAddress);
-uint8_t BSP_QSPI_Erase_Sector(uint32_t Sector);
-uint8_t BSP_QSPI_Erase_Chip  (void);
-uint8_t BSP_QSPI_GetStatus   (void);
-uint8_t BSP_QSPI_GetInfo     (QSPI_Info* pInfo);
-uint8_t BSP_QSPI_EnableMemoryMappedMode(void);
-uint8_t BSP_QSPI_SuspendErase(void);
-uint8_t BSP_QSPI_ResumeErase (void);
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32L476G_DISCOVERY_QSPI_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm32l4xx_nucleo.c	Sat Dec 05 16:17:25 2015 +0000
@@ -0,0 +1,782 @@
+/**
+  ******************************************************************************
+  * @file    stm32l4xx_nucleo.c
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    16-September-2015
+  * @brief   This file provides set of firmware functions to manage:
+  *          - LEDs and push-button available on STM32L4XX-Nucleo Kit
+  *            from STMicroelectronics
+  *          - LCD, joystick and microSD available on Adafruit 1.8" TFT LCD
+  *            shield (reference ID 802)
+  ******************************************************************************
+  * @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 "stm32l4xx_nucleo.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @defgroup STM32L4XX_NUCLEO STM32L476RG-Nucleo
+  * @brief This file provides set of firmware functions to manage Leds and push-button
+  *        available on STM32L4XX-Nucleo Kit from STMicroelectronics.
+  *        It provides also LCD, joystick and uSD functions to communicate with
+  *        Adafruit 1.8" TFT LCD shield (reference ID 802)
+  * @{
+  */
+
+
+/** @defgroup STM32L4XX_NUCLEO_Private_Defines Private Defines
+  * @{
+  */
+
+/**
+  * @brief STM32L476RG NUCLEO BSP Driver version V2.0.0
+  */
+#define __STM32L4XX_NUCLEO_BSP_VERSION_MAIN   (0x02) /*!< [31:24] main version */
+#define __STM32L4XX_NUCLEO_BSP_VERSION_SUB1   (0x00) /*!< [23:16] sub1 version */
+#define __STM32L4XX_NUCLEO_BSP_VERSION_SUB2   (0x00) /*!< [15:8]  sub2 version */
+#define __STM32L4XX_NUCLEO_BSP_VERSION_RC     (0x00) /*!< [7:0]  release candidate */
+#define __STM32L4XX_NUCLEO_BSP_VERSION       ((__STM32L4XX_NUCLEO_BSP_VERSION_MAIN << 24)\
+                                             |(__STM32L4XX_NUCLEO_BSP_VERSION_SUB1 << 16)\
+                                             |(__STM32L4XX_NUCLEO_BSP_VERSION_SUB2 << 8 )\
+                                             |(__STM32L4XX_NUCLEO_BSP_VERSION_RC))
+
+/**
+  * @brief LINK SD Card
+  */
+#define SD_DUMMY_BYTE            0xFF
+#define SD_NO_RESPONSE_EXPECTED  0x80
+
+/**
+  * @}
+  */
+
+
+/** @defgroup STM32L4XX_NUCLEO_Private_Variables Exported Variables
+  * @{
+  */
+GPIO_TypeDef* GPIO_PORT[LEDn] = {LED2_GPIO_PORT};
+
+const uint16_t GPIO_PIN[LEDn] = {LED2_PIN};
+
+GPIO_TypeDef*  BUTTON_PORT[BUTTONn] = {USER_BUTTON_GPIO_PORT};
+const uint16_t BUTTON_PIN[BUTTONn] = {USER_BUTTON_PIN};
+const uint16_t BUTTON_IRQn[BUTTONn] = {USER_BUTTON_EXTI_IRQn};
+
+/**
+ * @brief BUS variables
+ */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+uint32_t hnucleo_SpixTimeout = NUCLEO_SPIx_TIMEOUT_MAX;        /*<! Value of Timeout when SPI communication fails */
+static SPI_HandleTypeDef hnucleo_Spi;
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+static ADC_HandleTypeDef hnucleo_Adc;
+/* ADC channel configuration structure declaration */
+static ADC_ChannelConfTypeDef hnucleo_AdcChannelConfig;
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+/**
+  * @}
+  */
+
+/** @defgroup STM32L4XX_NUCLEO_Private_Functions Private Functions
+  * @{
+  */
+#ifdef HAL_SPI_MODULE_ENABLED
+static void               SPIx_Init(void);
+static void               SPIx_Write(uint8_t Value);
+static void               SPIx_Error (void);
+static void               SPIx_MspInit(void);
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+static HAL_StatusTypeDef  ADCx_Init(void);
+static void               ADCx_MspInit(ADC_HandleTypeDef *hadc);
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+/* SD IO functions */
+void                      SD_IO_Init(void);
+void                      SD_IO_CSState(uint8_t state);
+void                      SD_IO_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLength);
+uint8_t                   SD_IO_WriteByte(uint8_t Data);
+
+/* LCD IO functions */
+void                      LCD_IO_Init(void);
+void                      LCD_IO_WriteMultipleData(uint8_t *pData, uint32_t Size);
+void                      LCD_IO_WriteReg(uint8_t LCDReg);
+void                      LCD_Delay(uint32_t delay);
+#endif /* HAL_SPI_MODULE_ENABLED */
+/**
+  * @}
+  */
+
+/** @defgroup STM32L4XX_NUCLEO_Exported_Functions Exported Functions
+  * @{
+  */
+
+/**
+  * @brief  This method returns the STM32L4XX NUCLEO BSP Driver revision
+  * @retval version : 0xXYZR (8bits for each decimal, R for RC)
+  */
+uint32_t BSP_GetVersion(void)
+{
+    return __STM32L4XX_NUCLEO_BSP_VERSION;
+}
+
+/** @defgroup STM32L4XX_NUCLEO_LED_Functions LED Functions
+  * @{
+  */
+
+/**
+  * @brief  Configures LED GPIO.
+  * @param  Led: LED to be configured.
+  *          This parameter can be one of the following values:
+  *            @arg  LED2
+  * @retval None
+  */
+void BSP_LED_Init(Led_TypeDef Led)
+{
+    GPIO_InitTypeDef  gpioinitstruct = {0};
+
+    /* Enable the GPIO_LED Clock */
+    LEDx_GPIO_CLK_ENABLE(Led);
+
+    /* Configure the GPIO_LED pin */
+    gpioinitstruct.Pin   = GPIO_PIN[Led];
+    gpioinitstruct.Mode  = GPIO_MODE_OUTPUT_PP;
+    gpioinitstruct.Pull  = GPIO_NOPULL;
+    gpioinitstruct.Speed = GPIO_SPEED_FREQ_HIGH;
+    HAL_GPIO_Init(GPIO_PORT[Led], &gpioinitstruct);
+}
+
+/**
+  * @brief  Turns selected LED On.
+  * @param  Led: Specifies the Led to be set on.
+  *   This parameter can be one of following parameters:
+  *            @arg  LED2
+  * @retval None
+  */
+void BSP_LED_On(Led_TypeDef Led)
+{
+    HAL_GPIO_WritePin(GPIO_PORT[Led], GPIO_PIN[Led], GPIO_PIN_SET);
+}
+
+/**
+  * @brief  Turns selected LED Off.
+  * @param  Led: Specifies the Led to be set off.
+  *   This parameter can be one of following parameters:
+  *            @arg  LED2
+  * @retval None
+  */
+void BSP_LED_Off(Led_TypeDef Led)
+{
+    HAL_GPIO_WritePin(GPIO_PORT[Led], GPIO_PIN[Led], GPIO_PIN_RESET);
+}
+
+/**
+  * @brief  Toggles the selected LED.
+  * @param  Led: Specifies the Led to be toggled.
+  *   This parameter can be one of following parameters:
+  *            @arg  LED2
+  * @retval None
+  */
+void BSP_LED_Toggle(Led_TypeDef Led)
+{
+    HAL_GPIO_TogglePin(GPIO_PORT[Led], GPIO_PIN[Led]);
+}
+
+/**
+  * @}
+  */
+
+/** @defgroup STM32L4XX_NUCLEO_BUTTON_Functions BUTTON Functions
+  * @{
+  */
+
+/**
+  * @brief  Configures Button GPIO and EXTI Line.
+  * @param  Button: Specifies the Button to be configured.
+  *   This parameter should be: BUTTON_USER
+  * @param  ButtonMode: Specifies Button mode.
+  *   This parameter can be one of following parameters:
+  *     @arg BUTTON_MODE_GPIO: Button will be used as simple IO
+  *     @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line with interrupt
+  *                            generation capability
+  * @retval None
+  */
+void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
+{
+    GPIO_InitTypeDef gpioinitstruct = {0};
+
+    /* Enable the BUTTON Clock */
+    BUTTONx_GPIO_CLK_ENABLE(Button);
+
+    if (ButtonMode == BUTTON_MODE_GPIO) {
+        /* Configure Button pin as input */
+        gpioinitstruct.Pin    = BUTTON_PIN[Button];
+        gpioinitstruct.Mode   = GPIO_MODE_INPUT;
+        gpioinitstruct.Pull   = GPIO_NOPULL;
+        gpioinitstruct.Speed  = GPIO_SPEED_FREQ_HIGH;
+
+        HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
+    } else if(ButtonMode == BUTTON_MODE_EXTI) {
+        /* Configure Button pin as input with External interrupt */
+        gpioinitstruct.Pin    = BUTTON_PIN[Button];
+        gpioinitstruct.Mode   = GPIO_MODE_IT_FALLING;
+        gpioinitstruct.Pull   = GPIO_NOPULL;
+        gpioinitstruct.Speed  = GPIO_SPEED_FREQ_HIGH;
+        HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
+
+        /* Enable and set Button EXTI Interrupt to the lowest priority */
+        HAL_NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F, 0);
+        HAL_NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
+    }
+}
+
+/**
+  * @brief  Returns the selected Button state.
+  * @param  Button: Specifies the Button to be checked.
+  *   This parameter should be: BUTTON_USER
+  * @retval Button state.
+  */
+uint32_t BSP_PB_GetState(Button_TypeDef Button)
+{
+    return HAL_GPIO_ReadPin(BUTTON_PORT[Button], BUTTON_PIN[Button]);
+}
+
+#ifdef HAL_ADC_MODULE_ENABLED
+/**
+  * @brief  Configures joystick available on adafruit 1.8" TFT shield
+  *         managed through ADC to detect motion.
+  * @retval Joystickstatus (0=> success, 1=> fail)
+  */
+uint8_t BSP_JOY_Init(void)
+{
+    if (ADCx_Init() != HAL_OK) {
+        return (uint8_t) HAL_ERROR;
+    }
+
+    /* Select Channel 15 to be converted */
+    hnucleo_AdcChannelConfig.Channel       = ADC_CHANNEL_15;
+    hnucleo_AdcChannelConfig.SamplingTime  = ADC_SAMPLETIME_24CYCLES_5;
+    hnucleo_AdcChannelConfig.Rank          = 1;
+    hnucleo_AdcChannelConfig.SingleDiff    = ADC_SINGLE_ENDED;
+    hnucleo_AdcChannelConfig.OffsetNumber  = ADC_OFFSET_NONE;
+
+    /* Return Joystick initialization status */
+    return (uint8_t) HAL_ADC_ConfigChannel(&hnucleo_Adc, &hnucleo_AdcChannelConfig);
+}
+
+/**
+  * @brief  Returns the Joystick key pressed.
+  * @note   To know which Joystick key is pressed we need to detect the voltage
+  *         level on each key output
+  *           - None  : 3.3 V / 4095
+  *           - SEL   : 1.055 V / 1308
+  *           - DOWN  : 0.71 V / 88
+  *           - LEFT  : 3.0 V / 3720
+  *           - RIGHT : 0.595 V / 737
+  *           - UP    : 1.65 V / 2046
+  * @retval JOYState_TypeDef: Code of the Joystick key pressed.
+  */
+JOYState_TypeDef BSP_JOY_GetState(void)
+{
+    JOYState_TypeDef state = JOY_NONE;
+    uint16_t  keyconvertedvalue = 0;
+
+    /* Start the conversion process */
+    HAL_ADC_Start(&hnucleo_Adc);
+
+    /* Wait for the end of conversion */
+    HAL_ADC_PollForConversion(&hnucleo_Adc, 10);
+
+    /* Check if the continous conversion of regular channel is finished */
+    if(HAL_ADC_GetState(&hnucleo_Adc) & HAL_ADC_STATE_REG_EOC) {
+        /* Get the converted value of regular channel */
+        keyconvertedvalue = HAL_ADC_GetValue(&hnucleo_Adc);
+    }
+
+    if((keyconvertedvalue > 1980) && (keyconvertedvalue < 2120)) {
+        state = JOY_UP;
+    } else if((keyconvertedvalue > 630) && (keyconvertedvalue < 830)) {
+        state = JOY_RIGHT;
+    } else if((keyconvertedvalue > 1210) && (keyconvertedvalue < 1410)) {
+        state = JOY_SEL;
+    } else if((keyconvertedvalue > 20) && (keyconvertedvalue < 160)) {
+        state = JOY_DOWN;
+    } else if((keyconvertedvalue > 3620) && (keyconvertedvalue < 3820)) {
+        state = JOY_LEFT;
+    } else {
+        state = JOY_NONE;
+    }
+
+    /* Return the code of the Joystick key pressed*/
+    return state;
+}
+
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L4XX_NUCLEO_Private_Functions
+  * @{
+  */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+/******************************************************************************
+                            BUS OPERATIONS
+*******************************************************************************/
+/**
+  * @brief  Initialize SPI MSP.
+  * @retval None
+  */
+static void SPIx_MspInit(void)
+{
+    GPIO_InitTypeDef  gpioinitstruct = {0};
+
+    /*** Configure the GPIOs ***/
+    /* Enable GPIO clock */
+    NUCLEO_SPIx_SCK_GPIO_CLK_ENABLE();
+    NUCLEO_SPIx_MISO_MOSI_GPIO_CLK_ENABLE();
+
+    /* Configure SPI SCK */
+    gpioinitstruct.Pin        = NUCLEO_SPIx_SCK_PIN;
+    gpioinitstruct.Mode       = GPIO_MODE_AF_PP;
+    gpioinitstruct.Pull       = GPIO_PULLUP;
+    gpioinitstruct.Speed      = GPIO_SPEED_FREQ_VERY_HIGH;
+    gpioinitstruct.Alternate  = NUCLEO_SPIx_SCK_AF;
+    HAL_GPIO_Init(NUCLEO_SPIx_SCK_GPIO_PORT, &gpioinitstruct);
+
+    /* Configure SPI MISO and MOSI */
+    gpioinitstruct.Pin        = NUCLEO_SPIx_MOSI_PIN;
+    gpioinitstruct.Alternate  = NUCLEO_SPIx_MISO_MOSI_AF;
+    gpioinitstruct.Pull       = GPIO_PULLDOWN;
+    HAL_GPIO_Init(NUCLEO_SPIx_MISO_MOSI_GPIO_PORT, &gpioinitstruct);
+
+    gpioinitstruct.Pin        = NUCLEO_SPIx_MISO_PIN;
+    HAL_GPIO_Init(NUCLEO_SPIx_MISO_MOSI_GPIO_PORT, &gpioinitstruct);
+
+    /*** Configure the SPI peripheral ***/
+    /* Enable SPI clock */
+    NUCLEO_SPIx_CLK_ENABLE();
+}
+
+/**
+  * @brief  Initialize SPI HAL.
+  * @retval None
+  */
+static void SPIx_Init(void)
+{
+    if(HAL_SPI_GetState(&hnucleo_Spi) == HAL_SPI_STATE_RESET) {
+        /* SPI Config */
+        hnucleo_Spi.Instance = NUCLEO_SPIx;
+        /* SPI baudrate is set to 8 MHz maximum (PCLK2/SPI_BaudRatePrescaler = 32/4 = 8 MHz)
+         to verify these constraints:
+            - ST7735 LCD SPI interface max baudrate is 15MHz for write and 6.66MHz for read
+              Since the provided driver doesn't use read capability from LCD, only constraint
+              on write baudrate is considered.
+            - SD card SPI interface max baudrate is 25MHz for write/read
+            - PCLK2 max frequency is 32 MHz
+         */
+        hnucleo_Spi.Init.BaudRatePrescaler  = SPI_BAUDRATEPRESCALER_4;
+        hnucleo_Spi.Init.Direction          = SPI_DIRECTION_2LINES;
+        hnucleo_Spi.Init.CLKPhase           = SPI_PHASE_2EDGE;
+        hnucleo_Spi.Init.CLKPolarity        = SPI_POLARITY_HIGH;
+        hnucleo_Spi.Init.CRCCalculation     = SPI_CRCCALCULATION_DISABLE;
+        hnucleo_Spi.Init.CRCPolynomial      = 7;
+        hnucleo_Spi.Init.CRCLength          = SPI_CRC_LENGTH_DATASIZE;
+        hnucleo_Spi.Init.DataSize           = SPI_DATASIZE_8BIT;
+        hnucleo_Spi.Init.FirstBit           = SPI_FIRSTBIT_MSB;
+        hnucleo_Spi.Init.NSS                = SPI_NSS_SOFT;
+        hnucleo_Spi.Init.NSSPMode           = SPI_NSS_PULSE_DISABLE;
+        hnucleo_Spi.Init.TIMode             = SPI_TIMODE_DISABLE;
+        hnucleo_Spi.Init.Mode               = SPI_MODE_MASTER;
+
+        SPIx_MspInit();
+        HAL_SPI_Init(&hnucleo_Spi);
+    }
+}
+
+/**
+  * @brief  SPI Write byte(s) to device
+  * @param  DataIn: Pointer to data buffer to write
+  * @param  DataOut: Pointer to data buffer for read data
+  * @param  DataLength: number of bytes to write
+  * @retval None
+  */
+static void SPIx_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLength)
+{
+    HAL_StatusTypeDef status = HAL_OK;
+    status = HAL_SPI_TransmitReceive(&hnucleo_Spi, (uint8_t*) DataIn, DataOut, DataLength, hnucleo_SpixTimeout);
+
+    /* Check the communication status */
+    if(status != HAL_OK) {
+        /* Execute user timeout callback */
+        SPIx_Error();
+    }
+}
+
+/**
+  * @brief  SPI Write a byte to device
+  * @param  Value: value to be written
+  * @retval None
+  */
+static void SPIx_Write(uint8_t Value)
+{
+    HAL_StatusTypeDef status = HAL_OK;
+    uint8_t data;
+
+    status = HAL_SPI_TransmitReceive(&hnucleo_Spi, (uint8_t*) &Value, &data, 1, hnucleo_SpixTimeout);
+
+    /* Check the communication status */
+    if(status != HAL_OK) {
+        /* Execute user timeout callback */
+        SPIx_Error();
+    }
+}
+
+/**
+  * @brief  SPI error treatment function
+  * @retval None
+  */
+static void SPIx_Error (void)
+{
+    /* De-initialize the SPI communication BUS */
+    HAL_SPI_DeInit(&hnucleo_Spi);
+
+    /* Re-Initiaize the SPI communication BUS */
+    SPIx_Init();
+}
+
+/******************************************************************************
+                            LINK OPERATIONS
+*******************************************************************************/
+
+/********************************* LINK SD ************************************/
+/**
+  * @brief  Initialize the SD Card and put it into StandBy State (Ready for
+  *         data transfer).
+  * @retval None
+  */
+void SD_IO_Init(void)
+{
+    GPIO_InitTypeDef  gpioinitstruct = {0};
+    uint8_t counter = 0;
+
+    /* SD_CS_GPIO Periph clock enable */
+    SD_CS_GPIO_CLK_ENABLE();
+
+    /* Configure SD_CS_PIN pin: SD Card CS pin */
+    gpioinitstruct.Pin    = SD_CS_PIN;
+    gpioinitstruct.Mode   = GPIO_MODE_OUTPUT_PP;
+    gpioinitstruct.Pull   = GPIO_PULLUP;
+    gpioinitstruct.Speed  = GPIO_SPEED_FREQ_VERY_HIGH;
+    HAL_GPIO_Init(SD_CS_GPIO_PORT, &gpioinitstruct);
+
+    /* Configure LCD_CS_PIN pin: LCD Card CS pin */
+    gpioinitstruct.Pin   = LCD_CS_PIN;
+    gpioinitstruct.Mode  = GPIO_MODE_OUTPUT_PP;
+    gpioinitstruct.Pull  = GPIO_NOPULL;
+    gpioinitstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+    HAL_GPIO_Init(SD_CS_GPIO_PORT, &gpioinitstruct);
+    LCD_CS_HIGH();
+
+    /*------------Put SD in SPI mode--------------*/
+    /* SD SPI Config */
+    SPIx_Init();
+
+    /* SD chip select high */
+    SD_CS_HIGH();
+
+    /* Send dummy byte 0xFF, 10 times with CS high */
+    /* Rise CS and MOSI for 80 clocks cycles */
+    for (counter = 0; counter <= 9; counter++) {
+        /* Send dummy byte 0xFF */
+        SD_IO_WriteByte(SD_DUMMY_BYTE);
+    }
+}
+
+/**
+  * @brief  Set SD interface Chip Select state
+  * @param  val: 0 (low) or 1 (high) state
+  * @retval None
+  */
+void SD_IO_CSState(uint8_t val)
+{
+    if(val == 1) {
+        SD_CS_HIGH();
+    } else {
+        SD_CS_LOW();
+    }
+}
+
+/**
+  * @brief  Write byte(s) on the SD
+  * @param  DataIn: Pointer to data buffer to write
+  * @param  DataOut: Pointer to data buffer for read data
+  * @param  DataLength: number of bytes to write
+  * @retval None
+  */
+void SD_IO_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLength)
+{
+    /* Send the byte */
+    SPIx_WriteReadData(DataIn, DataOut, DataLength);
+}
+
+/**
+  * @brief  Write a byte on the SD.
+  * @param  Data: byte to send.
+  * @retval Data written
+  */
+uint8_t SD_IO_WriteByte(uint8_t Data)
+{
+    uint8_t tmp;
+
+    /* Send the byte */
+    SPIx_WriteReadData(&Data,&tmp,1);
+    return tmp;
+}
+
+/********************************* LINK LCD ***********************************/
+/**
+  * @brief  Initialize the LCD
+  * @retval None
+  */
+void LCD_IO_Init(void)
+{
+    GPIO_InitTypeDef  gpioinitstruct = {0};
+
+    /* LCD_CS_GPIO and LCD_DC_GPIO Periph clock enable */
+    LCD_CS_GPIO_CLK_ENABLE();
+    LCD_DC_GPIO_CLK_ENABLE();
+
+    /* Configure LCD_CS_PIN pin: LCD Card CS pin */
+    gpioinitstruct.Pin    = LCD_CS_PIN;
+    gpioinitstruct.Mode   = GPIO_MODE_OUTPUT_PP;
+    gpioinitstruct.Pull   = GPIO_NOPULL;
+    gpioinitstruct.Speed  = GPIO_SPEED_FREQ_VERY_HIGH;
+    HAL_GPIO_Init(SD_CS_GPIO_PORT, &gpioinitstruct);
+
+    /* Configure LCD_DC_PIN pin: LCD Card DC pin */
+    gpioinitstruct.Pin    = LCD_DC_PIN;
+    HAL_GPIO_Init(LCD_DC_GPIO_PORT, &gpioinitstruct);
+
+    /* LCD chip select high */
+    LCD_CS_HIGH();
+
+    /* LCD SPI Config */
+    SPIx_Init();
+}
+
+/**
+  * @brief  Write command to select the LCD register.
+  * @param  LCDReg: Address of the selected register.
+  * @retval None
+  */
+void LCD_IO_WriteReg(uint8_t LCDReg)
+{
+    /* Reset LCD control line CS */
+    LCD_CS_LOW();
+
+    /* Set LCD data/command line DC to Low */
+    LCD_DC_LOW();
+
+    /* Send Command */
+    SPIx_Write(LCDReg);
+
+    /* Deselect : Chip Select high */
+    LCD_CS_HIGH();
+}
+
+/**
+* @brief  Write register value.
+* @param  pData Pointer on the register value
+* @param  Size Size of byte to transmit to the register
+* @retval None
+*/
+void LCD_IO_WriteMultipleData(uint8_t *pData, uint32_t Size)
+{
+    uint32_t counter = 0;
+    __IO uint32_t data = 0;
+
+    /* Reset LCD control line CS */
+    LCD_CS_LOW();
+
+    /* Set LCD data/command line DC to High */
+    LCD_DC_HIGH();
+
+    if (Size == 1) {
+        /* Only 1 byte to be sent to LCD - general interface can be used */
+        /* Send Data */
+        SPIx_Write(*pData);
+    } else {
+        /* Several data should be sent in a raw */
+        /* Direct SPI accesses for optimization */
+        for (counter = Size; counter != 0; counter--) {
+            while(((hnucleo_Spi.Instance->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE) {
+            }
+            /* Need to invert bytes for LCD*/
+            *((__IO uint8_t*)&hnucleo_Spi.Instance->DR) = *(pData+1);
+
+            while(((hnucleo_Spi.Instance->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE) {
+            }
+            *((__IO uint8_t*)&hnucleo_Spi.Instance->DR) = *pData;
+            counter--;
+            pData += 2;
+        }
+
+        /* Wait until the bus is ready before releasing Chip select */
+        while(((hnucleo_Spi.Instance->SR) & SPI_FLAG_BSY) != RESET) {
+        }
+    }
+
+    /* Empty the Rx fifo */
+    data = *(&hnucleo_Spi.Instance->DR);
+    UNUSED(data);  /* Remove GNU warning */
+
+    /* Deselect : Chip Select high */
+    LCD_CS_HIGH();
+}
+
+/**
+  * @brief  Wait for loop in ms.
+  * @param  Delay in ms.
+  * @retval None
+  */
+void LCD_Delay(uint32_t Delay)
+{
+    HAL_Delay(Delay);
+}
+
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+/******************************* LINK JOYSTICK ********************************/
+/**
+  * @brief  Initialize ADC MSP.
+  * @retval None
+  */
+static void ADCx_MspInit(ADC_HandleTypeDef *hadc)
+{
+    GPIO_InitTypeDef  gpioinitstruct = {0};
+    RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct;
+
+    /*** Configure the GPIOs ***/
+    /* Enable GPIO clock */
+    NUCLEO_ADCx_GPIO_CLK_ENABLE();
+
+    /* Configure ADC1 Channel8 as analog input */
+    gpioinitstruct.Pin    = NUCLEO_ADCx_GPIO_PIN ;
+    gpioinitstruct.Mode   = GPIO_MODE_ANALOG_ADC_CONTROL;
+    gpioinitstruct.Pull   = GPIO_NOPULL;
+    gpioinitstruct.Speed  = GPIO_SPEED_FREQ_HIGH;
+    HAL_GPIO_Init(NUCLEO_ADCx_GPIO_PORT, &gpioinitstruct);
+
+    /*** Configure the ADC peripheral ***/
+    /* Enable ADC clock */
+    NUCLEO_ADCx_CLK_ENABLE();
+
+    /* Configure SYSCLK as source clock for ADC */
+    RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
+    RCC_PeriphCLKInitStruct.AdcClockSelection    = RCC_ADCCLKSOURCE_SYSCLK;
+    HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);
+}
+
+/**
+  * @brief  Initializes ADC HAL.
+  * @retval None
+  */
+static HAL_StatusTypeDef ADCx_Init(void)
+{
+    if(HAL_ADC_GetState(&hnucleo_Adc) == HAL_ADC_STATE_RESET) {
+        /* ADC Config */
+        hnucleo_Adc.Instance                    = NUCLEO_ADCx;
+        hnucleo_Adc.Init.ClockPrescaler         = ADC_CLOCK_ASYNC_DIV8; /* (must not exceed 16MHz) */
+        hnucleo_Adc.Init.Resolution             = ADC_RESOLUTION_12B;
+        hnucleo_Adc.Init.DataAlign              = ADC_DATAALIGN_RIGHT;
+        hnucleo_Adc.Init.ScanConvMode           = DISABLE;
+        hnucleo_Adc.Init.EOCSelection           = ADC_EOC_SINGLE_CONV;
+        hnucleo_Adc.Init.LowPowerAutoWait       = ENABLE;
+        hnucleo_Adc.Init.ContinuousConvMode     = DISABLE;
+        hnucleo_Adc.Init.NbrOfConversion        = 1;
+        hnucleo_Adc.Init.DiscontinuousConvMode  = DISABLE;
+        hnucleo_Adc.Init.NbrOfDiscConversion    = 1;
+        hnucleo_Adc.Init.ExternalTrigConv       = ADC_SOFTWARE_START;
+        hnucleo_Adc.Init.ExternalTrigConvEdge   = ADC_EXTERNALTRIGCONVEDGE_NONE;
+        hnucleo_Adc.Init.DMAContinuousRequests  = DISABLE;
+        hnucleo_Adc.Init.Overrun                = ADC_OVR_DATA_PRESERVED;
+        hnucleo_Adc.Init.OversamplingMode       = DISABLE;
+
+        ADCx_MspInit(&hnucleo_Adc);
+        if (HAL_ADC_Init(&hnucleo_Adc) != HAL_OK) {
+            return HAL_ERROR;
+        }
+
+        if (HAL_ADCEx_Calibration_Start(&hnucleo_Adc,ADC_SINGLE_ENDED) != HAL_OK) {
+            return HAL_ERROR;
+        }
+    }
+
+    return HAL_OK;
+}
+
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm32l4xx_nucleo.h	Sat Dec 05 16:17:25 2015 +0000
@@ -0,0 +1,295 @@
+/**
+  ******************************************************************************
+  * @file    stm32l4xx_nucleo.h
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    16-September-2015
+  * @brief   This file contains definitions for:
+  *          - LEDs and push-button available on STM32L4XX-Nucleo Kit 
+  *            from STMicroelectronics
+  *          - LCD, joystick and microSD available on Adafruit 1.8" TFT LCD 
+  *            shield (reference ID 802)
+  ******************************************************************************
+  * @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.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32L4XX_NUCLEO_H
+#define __STM32L4XX_NUCLEO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup STM32L4XX_NUCLEO
+  * @{
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32l4xx_hal.h"
+   
+   
+/** @defgroup STM32L4XX_NUCLEO_Exported_Types Exported Types
+  * @{
+  */
+typedef enum 
+{
+  LED2 = 0,
+  LED4 = 1,				// disco
+  LED_GREEN = LED2
+} Led_TypeDef;
+
+typedef enum 
+{  
+  BUTTON_USER = 0,
+  /* Alias */
+  BUTTON_KEY  = BUTTON_USER
+} Button_TypeDef;
+
+typedef enum 
+{  
+  BUTTON_MODE_GPIO = 0,
+  BUTTON_MODE_EXTI = 1
+} ButtonMode_TypeDef; 
+
+typedef enum 
+{ 
+  JOY_NONE  = 0,
+  JOY_SEL   = 1,
+  JOY_DOWN  = 2,
+  JOY_LEFT  = 3,
+  JOY_RIGHT = 4,
+  JOY_UP    = 5
+} JOYState_TypeDef;
+
+/**
+  * @}
+  */ 
+
+/** @defgroup STM32L4XX_NUCLEO_Exported_Constants Exported Constants
+  * @{
+  */ 
+
+/** 
+* @brief	Define for STM32L4XX_NUCLEO board  
+  */ 
+#if !defined (USE_STM32L4XX_NUCLEO)
+ #define USE_STM32L4XX_NUCLEO
+#endif
+
+/** @defgroup STM32L4XX_NUCLEO_LED LED Constants
+  * @{
+  */
+#define LEDn                               1
+
+#define LED2_PIN                           GPIO_PIN_5
+#define LED2_GPIO_PORT                     GPIOA
+#define LED2_GPIO_CLK_ENABLE()             __HAL_RCC_GPIOA_CLK_ENABLE()  
+#define LED2_GPIO_CLK_DISABLE()            __HAL_RCC_GPIOA_CLK_DISABLE()
+  
+#define LEDx_GPIO_CLK_ENABLE(__LED__)      do { if((__LED__) == LED2) { LED2_GPIO_CLK_ENABLE(); } } while(0)
+
+#define LEDx_GPIO_CLK_DISABLE(__LED__)     do { if((__LED__) == LED2) { LED2_GPIO_CLK_DISABLE(); } } while(0)
+/**
+  * @}
+  */ 
+
+/** @defgroup STM32L4XX_NUCLEO_BUTTON BUTTON Constants
+  * @{
+  */  
+#define BUTTONn                            1
+
+/**
+  * @brief Key push-button
+  */
+#define USER_BUTTON_PIN                         GPIO_PIN_13
+#define USER_BUTTON_GPIO_PORT                   GPIOC
+#define USER_BUTTON_GPIO_CLK_ENABLE()           __HAL_RCC_GPIOC_CLK_ENABLE()   
+#define USER_BUTTON_GPIO_CLK_DISABLE()          __HAL_RCC_GPIOC_CLK_DISABLE()  
+#define USER_BUTTON_EXTI_LINE                   GPIO_PIN_13
+#define USER_BUTTON_EXTI_IRQn                   EXTI15_10_IRQn
+/* Aliases */
+#define KEY_BUTTON_PIN                          USER_BUTTON_PIN
+#define KEY_BUTTON_GPIO_PORT                    USER_BUTTON_GPIO_PORT
+#define KEY_BUTTON_GPIO_CLK_ENABLE()            USER_BUTTON_GPIO_CLK_ENABLE()
+#define KEY_BUTTON_GPIO_CLK_DISABLE()           USER_BUTTON_GPIO_CLK_DISABLE()
+#define KEY_BUTTON_EXTI_LINE                    USER_BUTTON_EXTI_LINE
+#define KEY_BUTTON_EXTI_IRQn                    USER_BUTTON_EXTI_IRQn
+
+
+#define BUTTONx_GPIO_CLK_ENABLE(__BUTTON__)    do { if((__BUTTON__) == BUTTON_USER) { USER_BUTTON_GPIO_CLK_ENABLE(); } } while(0)
+
+#define BUTTONx_GPIO_CLK_DISABLE(__BUTTON__)   do { if((__BUTTON__) == BUTTON_USER) { USER_BUTTON_GPIO_CLK_DISABLE(); } } while(0)
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L4XX_NUCLEO_BUS BUS Constants
+  * @{
+  */
+/*###################### SPI1 ###################################*/
+#define NUCLEO_SPIx                                 SPI1
+#define NUCLEO_SPIx_CLK_ENABLE()                    __HAL_RCC_SPI1_CLK_ENABLE()
+
+#define NUCLEO_SPIx_SCK_AF                          GPIO_AF5_SPI1
+#define NUCLEO_SPIx_SCK_GPIO_PORT                   GPIOA
+#define NUCLEO_SPIx_SCK_PIN                         GPIO_PIN_5
+#define NUCLEO_SPIx_SCK_GPIO_CLK_ENABLE()           __HAL_RCC_GPIOA_CLK_ENABLE()
+#define NUCLEO_SPIx_SCK_GPIO_CLK_DISABLE()          __HAL_RCC_GPIOA_CLK_DISABLE()
+
+#define NUCLEO_SPIx_MISO_MOSI_AF                    GPIO_AF5_SPI1
+#define NUCLEO_SPIx_MISO_MOSI_GPIO_PORT             GPIOA
+#define NUCLEO_SPIx_MISO_MOSI_GPIO_CLK_ENABLE()     __HAL_RCC_GPIOA_CLK_ENABLE()
+#define NUCLEO_SPIx_MISO_MOSI_GPIO_CLK_DISABLE()    __HAL_RCC_GPIOA_CLK_DISABLE()
+#define NUCLEO_SPIx_MISO_PIN                        GPIO_PIN_6
+#define NUCLEO_SPIx_MOSI_PIN                        GPIO_PIN_7
+/* Maximum Timeout values for flags waiting loops. These timeouts are not based
+   on accurate values, they just guarantee that the application will not remain
+   stuck if the SPI communication is corrupted.
+   You may modify these timeout values depending on CPU frequency and application
+   conditions (interrupts routines ...). */   
+#define NUCLEO_SPIx_TIMEOUT_MAX                   1000
+
+
+/**
+  * @brief  SD Control Lines management
+  */  
+#define SD_CS_LOW()       HAL_GPIO_WritePin(SD_CS_GPIO_PORT, SD_CS_PIN, GPIO_PIN_RESET)
+#define SD_CS_HIGH()      HAL_GPIO_WritePin(SD_CS_GPIO_PORT, SD_CS_PIN, GPIO_PIN_SET)
+    
+/**
+  * @brief  LCD Control Lines management
+  */
+#define LCD_CS_LOW()      HAL_GPIO_WritePin(LCD_CS_GPIO_PORT, LCD_CS_PIN, GPIO_PIN_RESET)
+#define LCD_CS_HIGH()     HAL_GPIO_WritePin(LCD_CS_GPIO_PORT, LCD_CS_PIN, GPIO_PIN_SET)
+#define LCD_DC_LOW()      HAL_GPIO_WritePin(LCD_DC_GPIO_PORT, LCD_DC_PIN, GPIO_PIN_RESET)
+#define LCD_DC_HIGH()     HAL_GPIO_WritePin(LCD_DC_GPIO_PORT, LCD_DC_PIN, GPIO_PIN_SET)
+
+/**
+  * @brief  SD Control Interface pins
+  */
+#define SD_CS_PIN                                 GPIO_PIN_5
+#define SD_CS_GPIO_PORT                           GPIOB
+#define SD_CS_GPIO_CLK_ENABLE()                   __HAL_RCC_GPIOB_CLK_ENABLE()
+#define SD_CS_GPIO_CLK_DISABLE()                  __HAL_RCC_GPIOB_CLK_DISABLE()
+
+/**
+  * @brief  LCD Control Interface pins
+  */
+#define LCD_CS_PIN                                 GPIO_PIN_6
+#define LCD_CS_GPIO_PORT                           GPIOB
+#define LCD_CS_GPIO_CLK_ENABLE()                   __HAL_RCC_GPIOB_CLK_ENABLE()
+#define LCD_CS_GPIO_CLK_DISABLE()                  __HAL_RCC_GPIOB_CLK_DISABLE()
+
+/**
+  * @brief  LCD Data/Command Interface pins
+  */
+#define LCD_DC_PIN                                 GPIO_PIN_9
+#define LCD_DC_GPIO_PORT                           GPIOA
+#define LCD_DC_GPIO_CLK_ENABLE()                   __HAL_RCC_GPIOA_CLK_ENABLE()
+#define LCD_DC_GPIO_CLK_DISABLE()                  __HAL_RCC_GPIOA_CLK_DISABLE()
+     
+/* Audio codec I2C address */
+#define AUDIO_I2C_ADDRESS                       ((uint16_t) 0x94)			// disco
+
+/*##################### ADC1 ###################################*/
+/**
+  * @brief  ADC Interface pins
+  *         used to detect motion of Joystick available on Adafruit 1.8" TFT shield
+  */
+#define NUCLEO_ADCx                                 ADC1
+#define NUCLEO_ADCx_CLK_ENABLE()                    __HAL_RCC_ADC_CLK_ENABLE()
+    
+#define NUCLEO_ADCx_GPIO_PORT                       GPIOB
+#define NUCLEO_ADCx_GPIO_PIN                        GPIO_PIN_0
+#define NUCLEO_ADCx_GPIO_CLK_ENABLE()               __HAL_RCC_GPIOB_CLK_ENABLE()
+#define NUCLEO_ADCx_GPIO_CLK_DISABLE()              __HAL_RCC_GPIOB_CLK_DISABLE()
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L4XX_NUCLEO_Exported_Functions
+  * @{
+  */
+uint32_t         BSP_GetVersion(void);
+
+/** @addtogroup STM32L4XX_NUCLEO_LED_Functions
+  * @{
+  */
+void             BSP_LED_Init(Led_TypeDef Led);
+void             BSP_LED_On(Led_TypeDef Led);
+void             BSP_LED_Off(Led_TypeDef Led);
+void             BSP_LED_Toggle(Led_TypeDef Led);
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L4XX_NUCLEO_BUTTON_Functions
+  * @{
+  */
+void             BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode);
+uint32_t         BSP_PB_GetState(Button_TypeDef Button);
+#ifdef HAL_ADC_MODULE_ENABLED
+uint8_t          BSP_JOY_Init(void);
+JOYState_TypeDef BSP_JOY_GetState(void);
+#endif /* HAL_ADC_MODULE_ENABLED */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */ 
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32L4XX_NUCLEO_H */
+    
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm32l4xx_nucleo_audio.c	Sat Dec 05 16:17:25 2015 +0000
@@ -0,0 +1,1422 @@
+/**
+  ******************************************************************************
+  * @file    stm32l4xx_nucleo_audio.c
+  * @author  MCD Application Team
+  * @version V1.0.1
+  * @date    16-September-2015
+  * @brief   This file provides a set of functions needed to manage the 
+  *          Audio driver for the STM32L476G-Nucleo board.
+  ******************************************************************************
+  * @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.
+  *
+  ******************************************************************************
+  */
+
+/*==============================================================================
+                                 User NOTES
+                                 
+1. How To use this driver:
+--------------------------
+   + This driver supports STM32L4xx devices on STM32L476G-Nucleo (MB1184) Nucleo boards.
+        a) to play an audio file (all functions names start by BSP_AUDIO_OUT_xxx)
+        b) to record an audio file through MP34DT01TR, ST MEMS (all functions names start by BSP_AUDIO_IN_xxx)
+
+a) PLAY A FILE:
+==============
+   + Call the function BSP_AUDIO_OUT_Init(
+                                    OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER, 
+                                                  OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
+                                    Volume      : Initial volume to be set (0 is min (mute), 100 is max (100%)
+                                    AudioFreq   : Audio frequency in Hz (8000, 16000, 22500, 32000...)
+                                                  this parameter is relative to the audio file/stream type.
+                                   )
+      This function configures all the hardware required for the audio application (codec, I2C, SAI, 
+      GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
+      If the returned value is different from AUDIO_OK or the function is stuck then the communication with
+      the audio codec has failed.
+      - OUTPUT_DEVICE_SPEAKER  : only speaker will be set as output for the audio stream.
+      - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
+      - OUTPUT_DEVICE_BOTH     : both Speaker and Headphone are used as outputs for the audio stream
+                                 at the same time.
+
+   + Call the function BSP_AUDIO_OUT_RegisterCallbacks to register user callbacks
+     required to manage audio data streaming towards the audio codec (ErrorCallback(),
+     HalfTransfer_CallBack() and TransferComplete_CallBack()).
+
+   + Call the function BSP_AUDIO_OUT_Play() to start audio playback (for the first time).
+   + Call the function BSP_AUDIO_OUT_Pause() to pause audio playabck   
+   + Call the function BSP_AUDIO_OUT_Resume() to resume audio playback.
+       Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
+          for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
+       Note. This function should be called only when the audio file is played or paused (not stopped).
+   + Call the function BSP_AUDIO_OUT_Stop() to stop audio playback.
+   + To modify the volume level, the sampling frequency, the device output mode, 
+      the mute status or the audio configuration or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(), 
+      AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetOutputMode(), BSP_AUDIO_OUT_SetMute()and 
+      BSP_AUDIO_OUT_ChangeAudioConfig().
+ 
+Driver architecture:
+--------------------
+   + This driver provides the audio layer high level API: it consists in functions
+     exported in the stm32l4xx_nucleo_audio.h file (e.g. BSP_AUDIO_OUT_Init(),
+     BSP_AUDIO_OUT_Play(), ...).
+   + This driver also includes the Media Access Layer (MAL): it consists in 
+     functions allowing to access setup the audio devices. These functions 
+     are  included as local functions into the stm32l4xx_nucleo_audio.c file
+     (e.g. AUDIO_SAIx_Init()).
+
+Known Limitations:
+------------------
+   1- Communication with the audio codec (through I2C) may be corrupted if it is interrupted by some
+      user interrupt routines (in this case, interrupts could be disabled just before the start of 
+      communication then re-enabled when it is over). Note that this communication is only done at
+      the configuration phase (BSP_AUDIO_OUT_Init() or BSP_AUDIO_OUT_Stop()) and when Volume control modification is 
+      performed (BSP_AUDIO_OUT_SetVolume() or BSP_AUDIO_OUT_SetMute()or BSP_AUDIO_OUT_SetOutputMode()). 
+      When the audio data is played, no communication is required with the audio codec.
+   2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size, 
+      File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
+   3- Supports only 16-bits audio data size.
+
+b) RECORD A FILE:
+================
+   + Call the function BSP_AUDIO_IN_Init(
+                                    AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000 ...)
+                                    )
+      This function configures all the hardware required for the audio application (DFSDM, 
+      GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if the 
+      configuration completes successfully.
+
+   + Call the function BSP_AUDIO_IN_RegisterCallbacks to register user callbacks
+     used to stream audio data toward the record buffer (ErrorCallback(),
+     HalfTransfer_CallBack() and TransferComplete_CallBack()).
+
+   + Call the function BSP_AUDIO_IN_Record(
+                            pbuf Main buffer pointer for the recorded data storing  
+                            size Current size of the recorded buffer
+                            )
+      to start recording from the microphone.
+
+   + Call the function AUDIO_IN_STOP() to stop recording 
+==============================================================================*/
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include "stm32l4xx_nucleo_audio.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup STM32L476G_NUCLEO
+  * @{
+  */
+
+/** @defgroup STM32L476G_NUCLEO_AUDIO STM32L476G-NUCLEO AUDIO
+  * @brief This file includes the low layer driver for cs43l22 Audio Codec
+  *        available on STM32L476G-Nucleo board(MB1184).
+  * @{
+  */ 
+
+/* Private typedef -----------------------------------------------------------*/
+/** @defgroup STM32L476G_NUCLEO_AUDIO_Private_Types Private Types
+  * @{
+  */
+//typedef struct
+//{
+//  AUDIO_DrvTypeDef *    AudioDrv;            /* Audio codec driver */
+//  Audio_CallbackTypeDef CbError;            /* pointer to the callback function invoked when ... */
+//  Audio_CallbackTypeDef CbHalfTransfer;     /* pointer to the callback function invoked when ... */
+//  Audio_CallbackTypeDef CbTransferComplete; /* pointer to the callback function invoked when ... */
+//} AUDIO_OUT_TypeDef;
+
+typedef struct
+{
+  DFSDM_Channel_HandleTypeDef hDfsdmLeftChannel;  /* DFSDM channel handle used for left channel */
+  DMA_HandleTypeDef           hDmaDfsdmLeft;      /* DMA handle used for DFSDM regular conversions on left channel */
+  int32_t *                   LeftRecBuff;        /* Buffers for left samples */
+  uint32_t                Frequency;        /* Record Frequency */
+  uint32_t                BitResolution;    /* Record bit resolution */
+  uint32_t                ChannelNbr;       /* Record Channel Number */
+  uint16_t *              pRecBuf;          /* Pointer to record user buffer */
+  uint32_t                RecSize;          /* Size to record in mono, double size to record in stereo */
+  Audio_CallbackTypeDef       CbError;            /* pointer to the callback function invoked when a DMA transfer fails */
+  Audio_CallbackTypeDef       CbHalfTransfer;     /* pointer to the callback function invoked when half of the DMA transfer is completed */
+  Audio_CallbackTypeDef       CbTransferComplete; /* pointer to the callback function invoked when the DMA transfer is completed */
+} AUDIO_IN_TypeDef;
+
+/**
+  * @}
+  */
+
+/* Private defines ------------------------------------------------------------*/
+/** @defgroup STM32L476G_NUCLEO_AUDIO_Private_Constants Private Constants
+  * @{
+  */
+/**
+  * @}
+  */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup STM32L476G_NUCLEO_AUDIO_Private_Macros Private Macros
+  * @{
+  */
+/*### PLAY ###*/
+/* SCK(kHz) = SAI_CK_x/(SAIClockDivider*2*256) */
+#define SAIClockDivider(__FREQUENCY__) \
+        (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 12 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 2 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 6 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 1 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 3 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 0 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 2 : 1  \
+
+/*### RECORD ###*/
+#define DFSDMOverSampling(__FREQUENCY__) \
+        (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 256 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 256 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 128 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 128 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 64 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 64  \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 32 : 16  \
+
+#define DFSDMClockDivider(__FREQUENCY__) \
+        (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 24 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 4 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 24 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 4 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 24 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 4  \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 32 : 32  \
+
+#define DFSDMFilterOrder(__FREQUENCY__) \
+        (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? DFSDM_FILTER_SINC3_ORDER \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? DFSDM_FILTER_SINC3_ORDER \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? DFSDM_FILTER_SINC3_ORDER \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? DFSDM_FILTER_SINC3_ORDER \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? DFSDM_FILTER_SINC4_ORDER \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? DFSDM_FILTER_SINC4_ORDER  \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? DFSDM_FILTER_SINC4_ORDER : DFSDM_FILTER_SINC5_ORDER  \
+
+#define DFSDMRightBitShift(__FREQUENCY__) \
+        (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 2 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 3 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 3 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 0 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 3 \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 3  \
+      : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 7 : 0  \
+
+/* Saturate the record PCM sample */
+#define SaturaLH(N, L, H) (((N)<(L))?(L):(((N)>(H))?(H):(N)))
+
+/**
+  * @}
+  */ 
+  
+/* Private variables ---------------------------------------------------------*/
+/** @defgroup STM32L476G_NUCLEO_AUDIO_Private_Variables Private Variables
+  * @{
+  */
+/* Audio output context information */
+//static AUDIO_OUT_TypeDef hAudioOut;
+
+/* Audio input context information */
+static AUDIO_IN_TypeDef hAudioIn;
+
+/* SAI DMA handle */
+static DMA_HandleTypeDef hDmaSai;
+/**
+  * @}
+  */
+
+/* Exported variables ---------------------------------------------------------*/
+/** @defgroup STM32L476G_NUCLEO_AUDIO_Exported_Variables Exported Variables
+  * @{
+  */
+/* SAIx handle */
+SAI_HandleTypeDef               BSP_AUDIO_hSai;
+    
+/* DFSDM filter handle */
+DFSDM_Filter_HandleTypeDef      BSP_AUDIO_hDfsdmLeftFilter;
+/**
+  * @}
+  */
+
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup STM32L476G_NUCLEO_AUDIO_Private_Functions Private Functions
+  * @{
+  */
+//static void    AUDIO_CODEC_Reset(void);
+//static uint8_t AUDIO_SAIx_Init(uint32_t AudioFreq);
+//static uint8_t AUDIO_SAIx_DeInit(void);
+static uint8_t AUDIO_DFSDMx_Init(uint32_t AudioFreq);
+static uint8_t AUDIO_DFSDMx_DeInit(void);
+static uint8_t AUDIO_SAIPLLConfig(uint32_t AudioFreq);
+/**
+  * @}
+  */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup STM32L476G_NUCLEO_AUDIO_Exported_Functions
+  * @{
+  */ 
+
+/**
+  * @brief  Configures the audio codec related peripherals.
+  * @param  OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
+  *                       or OUTPUT_DEVICE_BOTH.
+  * @param  Volume: Initial volume level (from 0 (Mute) to 100 (Max))
+  * @param  AudioFreq: Audio frequency used to play the audio stream.ion.  
+  * @retval BSP AUDIO status
+  * @note   The SAI PLL input clock must be configure in the user application.
+  *         The SAI PLL configuration done within this function assumes that
+  *         the SAI PLL input clock runs at 8 MHz.
+  */
+//uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, 
+//                           uint8_t Volume,
+//                           uint32_t AudioFreq)
+//{ 
+//  /* Initialize the audio output context */
+//  hAudioOut.AudioDrv           = &cs43l22_drv; 
+//  hAudioOut.CbError            = (Audio_CallbackTypeDef)NULL; 
+//  hAudioOut.CbHalfTransfer     = (Audio_CallbackTypeDef)NULL; 
+//  hAudioOut.CbTransferComplete = (Audio_CallbackTypeDef)NULL;
+//  
+//  /* Configure the SAI PLL according to the requested audio frequency */
+//  if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//        
+//  /* SAI data transfer preparation: prepare the Media to be used for the audio
+//     transfer from memory to SAI peripheral. */
+//  if (AUDIO_SAIx_Init(AudioFreq) != AUDIO_OK)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//
+//  /* Retieve audio codec identifier */
+//  if (cs43l22_drv.ReadID(AUDIO_I2C_ADDRESS) != CS43L22_ID)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//  
+//  /* Reset the audio codec Registers */
+//  AUDIO_CODEC_Reset();
+//  
+//  /* Initialize the audio codec internal registers */
+//  if (hAudioOut.AudioDrv->Init(AUDIO_I2C_ADDRESS, 
+//                               OutputDevice, 
+//                               Volume, 
+//                               AudioFreq) != 0)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//  
+//  /* Set the requested volume */
+//  BSP_AUDIO_OUT_SetVolume(Volume);
+//
+//  return AUDIO_OK;
+//}
+  
+/**
+  * @brief  De-Initializes audio codec related peripherals
+  * @retval BSP AUDIO status
+  
+  */
+//uint8_t BSP_AUDIO_OUT_DeInit(void)
+//{
+//  /* De-initializes the Audio Codec audio interface */
+//  if (AUDIO_SAIx_DeInit() != AUDIO_OK)
+//  {  
+//    return AUDIO_ERROR;
+//  }
+//
+//  /* DeInit Audio component interface */
+//  hAudioOut.AudioDrv->DeInit();
+//  
+//  return AUDIO_OK;
+//}
+
+/**
+  * @brief  Starts playing audio stream from a data buffer for a determined size. 
+  * @param  pData: pointer on PCM samples buffer 
+  * @param  Size: Number of audio data BYTES.
+  * @retval BSP AUDIO status
+  */
+//uint8_t BSP_AUDIO_OUT_Play(uint16_t* pData, uint32_t Size)
+//{
+//  /* Initiate a DMA transfer of PCM samples towards the serial audio interface */  
+//  if (HAL_SAI_Transmit_DMA(&BSP_AUDIO_hSai, (uint8_t *)pData, DMA_MAX(Size))!= HAL_OK)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//
+//  /* Call the audio Codec Play function */
+//  if (hAudioOut.AudioDrv->Play(AUDIO_I2C_ADDRESS, pData, Size) != 0)
+//  {  
+//    return AUDIO_ERROR;
+//  }
+//
+//  return AUDIO_OK;
+//  }
+
+/**
+  * @brief  Sends n-Bytes on the SAI interface.
+  * @param  pData: pointer on PCM samples buffer 
+  * @param  Size: number of data to be written
+  * @retval BSP AUDIO status
+  */
+//uint8_t BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size)
+//{
+//  /* Initiate a DMA transfer of PCM samples towards the serial audio interface */  
+//  if (HAL_SAI_Transmit_DMA(&BSP_AUDIO_hSai, (uint8_t *)pData, Size)!= HAL_OK)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//  
+//  return AUDIO_OK;
+//}
+
+/**
+  * @brief  This function Pauses the audio file stream. In case
+  *         of using DMA, the DMA Pause feature is used.
+  * @note When calling BSP_AUDIO_OUT_Pause() function for pause, only
+  *       BSP_AUDIO_OUT_Resume() function should be called for resume
+  *       (use of BSP_AUDIO_OUT_Play() function for resume could lead 
+  *       to unexpected behavior).
+  * @retval BSP AUDIO status
+  */
+//uint8_t BSP_AUDIO_OUT_Pause(void)
+//{
+//  /* Call the Audio Codec Pause function */
+//  if (hAudioOut.AudioDrv->Pause(AUDIO_I2C_ADDRESS) != 0)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//  
+//  /* Pause DMA transfer of PCM samples towards the serial audio interface */  
+//  if (HAL_SAI_DMAPause(&BSP_AUDIO_hSai)!= HAL_OK)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//  
+//  return AUDIO_OK;
+//}
+
+/**
+  * @brief  This function  Resumes the audio file stream.  
+  * @note When calling BSP_AUDIO_OUT_Pause() function for pause, only
+  *       BSP_AUDIO_OUT_Resume() function should be called for resume
+  *       (use of BSP_AUDIO_OUT_Play() function for resume could lead to 
+  *       unexpected behavior).
+  * @retval BSP AUDIO status
+  */
+//uint8_t BSP_AUDIO_OUT_Resume(void)
+//{    
+//  /* Call the Audio Codec Resume function */
+//  if (hAudioOut.AudioDrv->Resume(AUDIO_I2C_ADDRESS) != 0)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//
+//  /* Resume DMA transfer of PCM samples towards the serial audio interface */  
+//  if (HAL_SAI_DMAResume(&BSP_AUDIO_hSai)!= HAL_OK)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//  
+//  return AUDIO_OK;
+//}
+
+/**
+  * @brief  Stops audio playing and Power down the Audio Codec. 
+  * @param  Option: could be one of the following parameters 
+  *           - CODEC_PDWN_SW: for software power off (by writing registers). 
+  *                            Then no need to reconfigure the Codec after power on.
+  *           - CODEC_PDWN_HW: completely shut down the codec (physically). 
+  *                            Then need to reconfigure the Codec after power on.  
+  * @retval BSP AUDIO status
+  */
+//uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option)
+//{
+//  /* Call Audio Codec Stop function */
+//  if (hAudioOut.AudioDrv->Stop(AUDIO_I2C_ADDRESS, Option) != 0)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//  
+//  if(Option == CODEC_PDWN_HW)
+//  { 
+//    /* Wait at least 100us */
+//    HAL_Delay(1);
+//  }
+//
+//  /* Stop DMA transfer of PCM samples towards the serial audio interface */  
+//  if (HAL_SAI_DMAStop(&BSP_AUDIO_hSai)!= HAL_OK)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//  
+//  return AUDIO_OK;
+//}
+
+/**
+  * @brief  Controls the current audio volume level. 
+  * @param  Volume: Volume level to be set in percentage from 0% to 100% (0 for 
+  *         Mute and 100 for Max volume level).
+  * @retval BSP AUDIO status
+  */
+//uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume)
+//{
+//  /* Call the codec volume control function with converted volume value */
+//  if (hAudioOut.AudioDrv->SetVolume(AUDIO_I2C_ADDRESS, Volume) != 0)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//  
+//  return AUDIO_OK;
+//}
+
+/**
+  * @brief  Enables or disables the MUTE mode by software 
+  * @param  Cmd: Could be AUDIO_MUTE_ON to mute sound or AUDIO_MUTE_OFF to 
+  *         unmute the codec and restore previous volume level.
+  * @retval BSP AUDIO status
+  */
+//uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd)
+//{ 
+//  /* Call the Codec Mute function */
+//  if (hAudioOut.AudioDrv->SetMute(AUDIO_I2C_ADDRESS, Cmd) != 0)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//  
+//  return AUDIO_OK;
+//}
+
+/**
+  * @brief  Switch dynamically (while audio file is being played) the output 
+  *          target (speaker or headphone).
+  * @param  Output: The audio output target: OUTPUT_DEVICE_SPEAKER,
+  *         OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH
+  * @retval BSP AUDIO status
+  */
+//uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output)
+//{
+//  /* Call the Codec output device function */
+//  if (hAudioOut.AudioDrv->SetOutputMode(AUDIO_I2C_ADDRESS, Output) != 0)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//  
+//  return AUDIO_OK;
+//}
+
+/**
+  * @brief  Updates the audio frequency.
+  * @param  AudioFreq: Audio frequency used to play the audio stream.
+  * @note   The SAI PLL input clock must be configure in the user application.
+  *         The SAI PLL configuration done within this function assumes that
+  *         the SAI PLL input clock runs at 8 MHz.
+  * @retval BSP AUDIO status
+  */
+//uint8_t BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq)
+//{ 
+//  /* Configure the SAI PLL according to the requested audio frequency */
+//  if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//  
+//  /* Disable SAI peripheral to allow access to SAI internal registers */
+//  __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
+//  
+//  /* Update the SAI audio frequency configuration */
+//  BSP_AUDIO_hSai.Init.Mckdiv = SAIClockDivider(AudioFreq);
+//  HAL_SAI_Init(&BSP_AUDIO_hSai);
+//  
+//  /* Enable SAI peripheral to generate MCLK */
+//  __HAL_SAI_ENABLE(&BSP_AUDIO_hSai);
+//
+//  return AUDIO_OK;
+//}
+
+/**
+  * @brief  Changes the Audio Out Configuration.
+  * @param  AudioOutOption: specifies the audio out new configuration
+  *         This parameter can be any value of @ref BSP_Audio_Out_Option
+  * @note   This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
+  *         audio out configuration.
+  * @retval None
+  */
+//void BSP_AUDIO_OUT_ChangeAudioConfig(uint32_t AudioOutOption)
+//{ 
+//  /********** Playback Buffer circular/normal mode **********/
+//  if(AudioOutOption & BSP_AUDIO_OUT_CIRCULARMODE)
+//  {
+//    /* Deinitialize the Stream to update DMA mode */
+//    HAL_DMA_DeInit(BSP_AUDIO_hSai.hdmatx);
+//    
+//    /* Update the SAI audio Transfer DMA mode */
+//    BSP_AUDIO_hSai.hdmatx->Init.Mode = DMA_CIRCULAR;
+//    
+//    /* Configure the DMA Stream with new Transfer DMA mode */
+//    HAL_DMA_Init(BSP_AUDIO_hSai.hdmatx);      
+//  }
+//  else /* BSP_AUDIO_OUT_NORMALMODE */
+//  {
+//    /* Deinitialize the Stream to update DMA mode */
+//    HAL_DMA_DeInit(BSP_AUDIO_hSai.hdmatx);
+//    
+//    /* Update the SAI audio Transfer DMA mode */
+//    BSP_AUDIO_hSai.hdmatx->Init.Mode = DMA_NORMAL;
+//    
+//    /* Configure the DMA Stream with new Transfer DMA mode */
+//    HAL_DMA_Init(BSP_AUDIO_hSai.hdmatx);      
+//  }
+//  
+//  /********** Playback Buffer stereo/mono mode **********/
+//  if(AudioOutOption & BSP_AUDIO_OUT_STEREOMODE)
+//  {
+//    /* Disable SAI peripheral to allow access to SAI internal registers */
+//    __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
+//    
+//    /* Update the SAI audio frame slot configuration */
+//    BSP_AUDIO_hSai.Init.MonoStereoMode = SAI_STEREOMODE;
+//    HAL_SAI_Init(&BSP_AUDIO_hSai);
+//    
+//    /* Enable SAI peripheral to generate MCLK */
+//    __HAL_SAI_ENABLE(&BSP_AUDIO_hSai);
+//  }
+//  else /* BSP_AUDIO_OUT_MONOMODE */
+//  {
+//    /* Disable SAI peripheral to allow access to SAI internal registers */
+//    __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
+//    
+//    /* Update the SAI audio frame slot configuration */
+//    BSP_AUDIO_hSai.Init.MonoStereoMode = SAI_MONOMODE;
+//    HAL_SAI_Init(&BSP_AUDIO_hSai);
+//    
+//    /* Enable SAI peripheral to generate MCLK */
+//    __HAL_SAI_ENABLE(&BSP_AUDIO_hSai);
+//  }
+//}
+
+/**
+  * @brief  register user callback functions 
+  * @param  ErrorCallback: pointer to the error callback function
+  * @param  HalfTransferCallback: pointer to the half transfer callback function
+  * @param  TransferCompleteCallback: pointer to the transfer complete callback function
+  * @retval None
+  */
+//void BSP_AUDIO_OUT_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback,
+//                                     Audio_CallbackTypeDef HalfTransferCallback, 
+//                                     Audio_CallbackTypeDef TransferCompleteCallback)
+//{
+//  hAudioOut.CbError            = ErrorCallback; 
+//  hAudioOut.CbHalfTransfer     = HalfTransferCallback; 
+//  hAudioOut.CbTransferComplete = TransferCompleteCallback;
+//}
+
+/**
+  * @brief  Tx Transfer completed callbacks.
+  * @param  hsai: SAI handle
+  * @retval None
+  */
+//void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
+//{
+//  /* Invoke the registered 'TransferComplete' function (if any) */
+//  if (hAudioOut.CbTransferComplete != (Audio_CallbackTypeDef)NULL)
+//  {
+//    hAudioOut.CbTransferComplete();
+//  }
+//}
+
+/**
+  * @brief  Tx Half Transfer completed callbacks.
+  * @param  hsai: SAI handle
+  * @retval None
+  */
+//void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
+//{
+//  /* Invoke the registered 'HalfTransfer' callback function (if any) */
+//  if (hAudioOut.CbHalfTransfer != (Audio_CallbackTypeDef)NULL)
+//  {
+//    hAudioOut.CbHalfTransfer();
+//  }
+//}
+
+/**
+  * @brief  SAI error callbacks.
+  * @param  hsai: SAI handle
+  * @retval None
+  */
+//void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
+//{
+//  /* Invoke the registered 'ErrorCallback' callback function (if any) */
+//  if (hAudioOut.CbError != (Audio_CallbackTypeDef)NULL)
+//  {
+//    hAudioOut.CbError();
+//  }
+//}
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L476G_EVAL_AUDIO_Exported_Functions
+  * @{
+  */
+  
+/**
+  * @brief  Initializes micropone related peripherals.
+  * @note   This function assumes that the SAI input clock (through PLL_M)
+  *         is already configured and ready to be used.  
+  * @param  AudioFreq: Audio frequency to be configured for the SAI peripheral. 
+  * @param  BitRes: Audio frequency to be configured for the SAI peripheral.
+  * @param  ChnlNbr: Audio frequency to be configured for the SAI peripheral.
+  * @retval BSP AUDIO status
+  */
+uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
+{
+  /* Update the audio input context */
+  hAudioIn.Frequency          = AudioFreq;
+  hAudioIn.BitResolution      = BitRes;
+  hAudioIn.ChannelNbr         = ChnlNbr;
+  hAudioIn.CbError            = (Audio_CallbackTypeDef)NULL; 
+  hAudioIn.CbHalfTransfer     = (Audio_CallbackTypeDef)NULL; 
+  hAudioIn.CbTransferComplete = (Audio_CallbackTypeDef)NULL;
+
+  /* Configure the SAI PLL according to the requested audio frequency */
+  if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
+  {
+    return AUDIO_ERROR;
+  }
+ 
+  /* Initializes the Digital Filter for Sigma-Delta Modulators interface */
+  if(AUDIO_DFSDMx_Init(AudioFreq) != AUDIO_OK)
+  {
+    return AUDIO_ERROR;
+  }
+  
+  return AUDIO_OK;
+  }
+
+/**
+  * @brief  De-Initializes microphone related peripherals.
+  * @retval BSP AUDIO status
+
+  */
+uint8_t BSP_AUDIO_IN_DeInit(void)
+{
+  /* De-initializes the Digital Filter for Sigma-Delta Modulators interface */
+  if (AUDIO_DFSDMx_DeInit() != AUDIO_OK)
+  {
+    return AUDIO_ERROR;
+  }
+  
+  /* Reset the audio input context */
+  memset(&hAudioIn, 0, sizeof(hAudioIn));
+
+  return AUDIO_OK;
+}
+
+/**
+  * @brief  Starts audio recording.
+  * @param  pbuf: Main buffer pointer for the recorded data storing  
+  * @param  size: Current size of the recorded buffer
+  * @note   The Right channel is start at first with synchro on start of Left channel
+  * @retval BSP AUDIO status
+  */
+uint8_t BSP_AUDIO_IN_Record(uint16_t* pbuf, uint32_t size)
+{
+  hAudioIn.pRecBuf = pbuf;
+  hAudioIn.RecSize = size;
+
+  /* Allocate hAudioIn.LeftRecBuff buffer */
+#if defined(BSP_AUDIO_USE_RTOS)
+  hAudioIn.LeftRecBuff  = (int32_t *)k_malloc(size * sizeof(int32_t));
+#else
+  hAudioIn.LeftRecBuff  = (int32_t *)malloc(size * sizeof(int32_t));
+#endif
+  if(hAudioIn.LeftRecBuff == NULL)
+  {
+    return AUDIO_ERROR;
+  }
+
+  /* Call the Media layer start function for left channel */
+  if(HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmLeftFilter, 
+                                      (int32_t*)hAudioIn.LeftRecBuff, 
+                                      (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR)) != HAL_OK)
+  {
+    return AUDIO_ERROR;
+  }
+
+  return AUDIO_OK;
+}
+
+/**
+  * @brief  Updates the audio frequency.
+  * @param  AudioFreq: Audio frequency used to record the audio stream.
+  * @note   This API should be called after the BSP_AUDIO_IN_Init() to adjust the
+  *         audio frequency.
+  * @retval BSP AUDIO status
+  */
+uint8_t BSP_AUDIO_IN_SetFrequency(uint32_t AudioFreq)
+{ 
+  /* Configure the SAI PLL according to the requested audio frequency */
+  if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
+  {
+    return AUDIO_ERROR;
+  }
+
+  /* De-initializes the Digital Filter for Sigma-Delta Modulators interface */
+  if(AUDIO_DFSDMx_DeInit() != AUDIO_OK)
+  {
+    return AUDIO_ERROR;
+  }
+  
+  /* Initializes the Digital Filter for Sigma-Delta Modulators interface */
+  if(AUDIO_DFSDMx_Init(AudioFreq) != AUDIO_OK)
+  {
+    return AUDIO_ERROR;
+  }
+  
+  return AUDIO_OK;
+}
+
+/**
+  * @brief  Regular conversion complete callback. 
+  * @note   In interrupt mode, user has to read conversion value in this function
+            using HAL_DFSDM_FilterGetRegularValue.
+  * @param  hdfsdm_filter : DFSDM filter handle.
+  * @retval None
+  */
+void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
+{
+  uint32_t index;
+  uint32_t recbufsize = (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR);
+  
+  for(index = (recbufsize/2); index < recbufsize; index++)
+  {
+    hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32760, 32760));
+  }
+  
+  /* Invoke the registered 'TransferComplete' function (if any) */
+  if (hAudioIn.CbTransferComplete != (Audio_CallbackTypeDef)NULL)
+  {
+    hAudioIn.CbTransferComplete();
+  }
+}
+
+/**
+  * @brief  Half regular conversion complete callback. 
+  * @param  hdfsdm_filter : DFSDM filter handle.
+  * @retval None
+  */
+void HAL_DFSDM_FilterRegConvHalfCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
+{
+  uint32_t index;
+  uint32_t recbufsize = (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR);
+  
+  
+  for(index = 0; index < (recbufsize/2); index++)
+  {
+    hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32760, 32760));
+  }
+  
+  /* Invoke the registered 'HalfTransfer' callback function (if any) */
+  if (hAudioIn.CbHalfTransfer != (Audio_CallbackTypeDef)NULL)
+  {
+    hAudioIn.CbHalfTransfer();
+  }
+}
+
+/**
+  * @brief  Error callback. 
+  * @param  hdfsdm_filter : DFSDM filter handle.
+  * @retval None
+  */
+void HAL_DFSDM_FilterErrorCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
+{
+  /* Invoke the registered 'ErrorCallback' callback function (if any) */
+  if (hAudioIn.CbError != (Audio_CallbackTypeDef)NULL)
+  {
+    hAudioIn.CbError();
+  }
+}
+
+/**
+  * @brief  Stops audio recording.
+  * @retval BSP AUDIO status
+  */
+uint8_t BSP_AUDIO_IN_Stop(void)
+{
+  /* Call the Media layer stop function for left channel */
+  if(HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK )
+  {
+    return AUDIO_ERROR;
+  }
+
+  /* Free hAudioIn.LeftRecBuff buffer */
+#if defined(BSP_AUDIO_USE_RTOS)
+  k_free((void *)hAudioIn.LeftRecBuff);
+#else
+  free((void *)hAudioIn.LeftRecBuff);
+#endif
+  
+  return AUDIO_OK;
+}
+
+/**
+  * @brief  Pauses the audio file stream.
+  * @retval BSP AUDIO status
+  */
+uint8_t BSP_AUDIO_IN_Pause(void)
+{    
+  /* Call the Media layer stop function */
+  if(HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
+  {
+    return AUDIO_ERROR;
+  }
+  
+  return AUDIO_OK;
+}
+
+/**
+  * @brief  Resumes the audio file stream.
+  * @retval BSP AUDIO status
+  */
+uint8_t BSP_AUDIO_IN_Resume(void)
+{    
+  /* Call the Media layer start function for left channel */
+  if(HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmLeftFilter,
+                                      (int32_t*)hAudioIn.LeftRecBuff,
+                                      (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR)) != HAL_OK)
+  {
+    return AUDIO_ERROR;
+  }
+  
+  return AUDIO_OK;
+}
+
+/**
+  * @brief  register user callback functions 
+  * @param  ErrorCallback: pointer to the error callback function
+  * @param  HalfTransferCallback: pointer to the half transfer callback function
+  * @param  TransferCompleteCallback: pointer to the transfer complete callback function
+  * @retval None
+  */
+void BSP_AUDIO_IN_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback,
+                                    Audio_CallbackTypeDef HalfTransferCallback, 
+                                    Audio_CallbackTypeDef TransferCompleteCallback)
+{
+  hAudioIn.CbError            = ErrorCallback; 
+  hAudioIn.CbHalfTransfer     = HalfTransferCallback; 
+  hAudioIn.CbTransferComplete = TransferCompleteCallback;
+}
+/**
+  * @}
+  */
+
+/* private functions --------------------------------------------------------*/
+/** @addtogroup STM32L476G_NUCLEO_AUDIO_Private_Functions
+  * @{
+  */
+/**
+  * @brief  Initializes the Audio Codec audio interface (SAI).
+  * @param  AudioFreq: Audio frequency to be configured for the SAI peripheral.
+  * @note   The default SlotActive configuration is set to CODEC_AUDIOFRAME_SLOT_0123 
+  *         and user can update this configuration using 
+  * @retval BSP AUDIO status
+  */
+//static uint8_t AUDIO_SAIx_Init(uint32_t AudioFreq)
+//{
+//  /* Disable SAI peripheral to allow access to SAI internal registers */
+//  __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
+//  
+//  /* Initialize the BSP_AUDIO_hSai Instance parameter */
+//  BSP_AUDIO_hSai.Instance = AUDIO_SAIx;
+//  
+//  /* Configure SAI_Block_x 
+//  LSBFirst: Disabled 
+//  DataSize: 16 */
+//  BSP_AUDIO_hSai.Init.AudioMode      = SAI_MODEMASTER_TX;
+//  BSP_AUDIO_hSai.Init.Synchro        = SAI_ASYNCHRONOUS;
+//  BSP_AUDIO_hSai.Init.SynchroExt     = SAI_SYNCEXT_DISABLE;
+//  BSP_AUDIO_hSai.Init.OutputDrive    = SAI_OUTPUTDRIVE_ENABLE;
+//  BSP_AUDIO_hSai.Init.NoDivider      = SAI_MASTERDIVIDER_ENABLE;
+//  BSP_AUDIO_hSai.Init.FIFOThreshold  = SAI_FIFOTHRESHOLD_1QF;
+//  BSP_AUDIO_hSai.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_MCKDIV;
+//  BSP_AUDIO_hSai.Init.Mckdiv         = SAIClockDivider(AudioFreq);
+//  BSP_AUDIO_hSai.Init.MonoStereoMode = SAI_STEREOMODE;
+//  BSP_AUDIO_hSai.Init.CompandingMode = SAI_NOCOMPANDING;
+//  BSP_AUDIO_hSai.Init.TriState       = SAI_OUTPUT_NOTRELEASED;
+//  BSP_AUDIO_hSai.Init.Protocol       = SAI_FREE_PROTOCOL;
+//  BSP_AUDIO_hSai.Init.DataSize       = SAI_DATASIZE_16;
+//  BSP_AUDIO_hSai.Init.FirstBit       = SAI_FIRSTBIT_MSB;
+//  BSP_AUDIO_hSai.Init.ClockStrobing  = SAI_CLOCKSTROBING_RISINGEDGE;
+//  
+//  /* Configure SAI_Block_x Frame 
+//  Frame Length: 32
+//  Frame active Length: 16
+//  FS Definition: Start frame + Channel Side identification
+//  FS Polarity: FS active Low
+//  FS Offset: FS asserted one bit before the first bit of slot 0 */ 
+//  BSP_AUDIO_hSai.FrameInit.FrameLength = 32;
+//  BSP_AUDIO_hSai.FrameInit.ActiveFrameLength = 16;
+//  BSP_AUDIO_hSai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
+//  BSP_AUDIO_hSai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
+//  BSP_AUDIO_hSai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
+//  
+//  /* Configure SAI Block_x Slot 
+//  Slot First Bit Offset: 0
+//  Slot Size  : 16
+//  Slot Number: 2
+//  Slot Active: Slots 0 and 1 actives */
+//  BSP_AUDIO_hSai.SlotInit.FirstBitOffset = 0;
+//  BSP_AUDIO_hSai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
+//  BSP_AUDIO_hSai.SlotInit.SlotNumber = 2; 
+//  BSP_AUDIO_hSai.SlotInit.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1;
+//
+//  /* Initializes the SAI peripheral*/
+//  if (HAL_SAI_Init(&BSP_AUDIO_hSai) != HAL_OK)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//  
+//  /* Enable SAI peripheral to generate MCLK */
+//  __HAL_SAI_ENABLE(&BSP_AUDIO_hSai);
+//  
+//  return AUDIO_OK;
+//  
+//}
+
+/**
+  * @brief  De-initializes the Audio Codec audio interface (SAI).
+  * @retval BSP AUDIO status
+  */
+//static uint8_t AUDIO_SAIx_DeInit(void)
+//{
+//  /* Disable the SAI audio block */
+//  __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
+//
+//  /* De-initializes the SAI peripheral */
+//  if (HAL_SAI_DeInit(&BSP_AUDIO_hSai) != HAL_OK)
+//  {
+//    return AUDIO_ERROR;
+//  }
+//  
+//  /* Disable SAIx PLL */
+//  if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK)
+//  {
+//    return AUDIO_ERROR;
+//  }  
+//  
+//  return AUDIO_OK;
+//}
+
+/**
+  * @brief  SAI MSP Init
+  * @param  hsai : pointer to a SAI_HandleTypeDef structure
+  * @retval None
+  */
+void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai)
+{ 
+  GPIO_InitTypeDef  GPIO_InitStruct;  
+
+  /* Enable SAI clock */
+  AUDIO_SAIx_CLK_ENABLE();
+  
+  /* Enable GPIO clock */
+  AUDIO_SAIx_MCK_SCK_SD_FS_ENABLE();
+  
+  /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
+  GPIO_InitStruct.Pin = AUDIO_SAIx_FS_PIN | AUDIO_SAIx_SCK_PIN | AUDIO_SAIx_SD_PIN | AUDIO_SAIx_MCK_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+  GPIO_InitStruct.Alternate = AUDIO_SAIx_MCK_SCK_SD_FS_AF;
+  HAL_GPIO_Init(AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT, &GPIO_InitStruct);
+
+  /* Enable the DMA clock */
+  AUDIO_SAIx_DMAx_CLK_ENABLE();
+    
+  if(hsai->Instance == AUDIO_SAIx)
+  {
+    /* Configure the hDmaSai handle parameters */   
+    hDmaSai.Init.Request             = DMA_REQUEST_1;
+    hDmaSai.Init.Direction           = DMA_MEMORY_TO_PERIPH;
+    hDmaSai.Init.PeriphInc           = DMA_PINC_DISABLE;
+    hDmaSai.Init.MemInc              = DMA_MINC_ENABLE;
+    hDmaSai.Init.PeriphDataAlignment = AUDIO_SAIx_DMAx_PERIPH_DATA_SIZE;
+    hDmaSai.Init.MemDataAlignment    = AUDIO_SAIx_DMAx_MEM_DATA_SIZE;
+    hDmaSai.Init.Mode                = DMA_NORMAL;
+    hDmaSai.Init.Priority            = DMA_PRIORITY_HIGH;
+    
+    hDmaSai.Instance = AUDIO_SAIx_DMAx_CHANNEL;
+    
+    /* Associate the DMA handle */
+    __HAL_LINKDMA(hsai, hdmatx, hDmaSai);
+    
+    /* Deinitialize the Stream for new transfer */
+    HAL_DMA_DeInit(&hDmaSai);
+    
+    /* Configure the DMA Stream */
+    HAL_DMA_Init(&hDmaSai);      
+  }
+  
+  /* SAI DMA IRQ Channel configuration */
+  HAL_NVIC_SetPriority(AUDIO_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
+  HAL_NVIC_EnableIRQ(AUDIO_SAIx_DMAx_IRQ); 
+}
+
+/**
+  * @brief  SAI MSP De-init
+  * @param  hsai : pointer to a SAI_HandleTypeDef structure
+  * @retval None
+  */
+void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai)
+{
+  /* Disable SAI DMA Channel IRQ  */
+  HAL_NVIC_DisableIRQ(AUDIO_SAIx_DMAx_IRQ); 
+
+  /* Reset the DMA Stream configuration*/
+  HAL_DMA_DeInit(&hDmaSai);
+  
+  /* Disable the DMA clock */
+  AUDIO_SAIx_DMAx_CLK_DISABLE();
+    
+  /* De-initialize FS, SCK, MCK and SD pins*/
+  HAL_GPIO_DeInit(AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT, 
+                  AUDIO_SAIx_FS_PIN | AUDIO_SAIx_SCK_PIN | AUDIO_SAIx_SD_PIN | AUDIO_SAIx_MCK_PIN);
+  
+  /* Disable GPIO clock */
+  AUDIO_SAIx_MCK_SCK_SD_FS_DISABLE();
+  
+  /* Disable SAI clock */
+  AUDIO_SAIx_CLK_DISABLE();
+}
+
+/**
+  * @brief  Resets the audio codec. It restores the default configuration of the 
+  *         codec (this function shall be called before initializing the codec).
+  * @retval None
+  */
+//static void AUDIO_CODEC_Reset(void)
+//{
+//  /* Initialize the audio driver structure */
+//  hAudioOut.AudioDrv = &cs43l22_drv; 
+//  
+//  hAudioOut.AudioDrv->Reset(AUDIO_I2C_ADDRESS);
+//}
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L476G_NUCLEO_AUDIO_Private_Functions
+  * @{
+  */ 
+
+/**
+  * @brief  Initializes the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
+  * @param  AudioFreq: Audio frequency to be used to set correctly the DFSDM peripheral.
+  * @retval BSP AUDIO status
+  */
+static uint8_t AUDIO_DFSDMx_Init(uint32_t AudioFreq)
+{
+  /*####CHANNEL 2####*/
+  hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Activation   = ENABLE;
+  hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Selection    = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
+  /* Set the DFSDM clock OUT audio frequency configuration */
+  hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Divider      = DFSDMClockDivider(AudioFreq);
+  hAudioIn.hDfsdmLeftChannel.Init.Input.Multiplexer        = DFSDM_CHANNEL_EXTERNAL_INPUTS;
+  hAudioIn.hDfsdmLeftChannel.Init.Input.DataPacking        = DFSDM_CHANNEL_STANDARD_MODE;
+  hAudioIn.hDfsdmLeftChannel.Init.Input.Pins               = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
+  /* Request to sample stable data for LEFT micro on Rising edge */
+  hAudioIn.hDfsdmLeftChannel.Init.SerialInterface.Type     = DFSDM_CHANNEL_SPI_RISING;
+  hAudioIn.hDfsdmLeftChannel.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
+  hAudioIn.hDfsdmLeftChannel.Init.Awd.FilterOrder          = DFSDM_CHANNEL_SINC1_ORDER;
+  hAudioIn.hDfsdmLeftChannel.Init.Awd.Oversampling         = 10;
+  hAudioIn.hDfsdmLeftChannel.Init.Offset                   = 0;
+  hAudioIn.hDfsdmLeftChannel.Init.RightBitShift            = DFSDMRightBitShift(AudioFreq);
+
+  hAudioIn.hDfsdmLeftChannel.Instance                      = DFSDM_Channel2;
+
+    /* Init the DFSDM Channel */
+  if (HAL_DFSDM_ChannelInit(&hAudioIn.hDfsdmLeftChannel) != HAL_OK)
+  {
+    return AUDIO_ERROR;
+  }
+
+  /*####FILTER 0####*/
+  BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.Trigger         = DFSDM_FILTER_SW_TRIGGER;
+  BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.FastMode        = ENABLE;
+  BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.DmaMode         = ENABLE;
+  BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.Trigger        = DFSDM_FILTER_SW_TRIGGER;
+  BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ScanMode       = DISABLE;
+  BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.DmaMode        = DISABLE;
+  BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ExtTrigger     = DFSDM_FILTER_EXT_TRIG_TIM8_TRGO;
+  BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ExtTriggerEdge = DFSDM_FILTER_EXT_TRIG_BOTH_EDGES;
+  BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.SincOrder        = DFSDMFilterOrder(AudioFreq);
+  /* Set the DFSDM Filters Oversampling to have correct sample rate */
+  BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.Oversampling     = DFSDMOverSampling(AudioFreq);
+  BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.IntOversampling  = 1;
+  
+  BSP_AUDIO_hDfsdmLeftFilter.Instance                          = AUDIO_DFSDMx_LEFT_FILTER;
+
+    /* Init the DFSDM Filter */
+  if (HAL_DFSDM_FilterInit(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
+  {
+    return AUDIO_ERROR;
+  }
+  
+  /* Configure regular channel */
+  if (HAL_DFSDM_FilterConfigRegChannel(&BSP_AUDIO_hDfsdmLeftFilter, 
+                                      DFSDM_CHANNEL_2, 
+                                      DFSDM_CONTINUOUS_CONV_ON) != HAL_OK)
+  {
+    return AUDIO_ERROR;
+  }
+
+  return AUDIO_OK;
+}
+
+/**
+  * @brief  De-initializes the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
+  * @retval BSP AUDIO status
+  */
+static uint8_t AUDIO_DFSDMx_DeInit(void)
+{
+  /* De-initializes the DFSDM filters to allow access to DFSDM internal registers */
+  if (HAL_DFSDM_FilterDeInit(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
+  {
+    return AUDIO_ERROR;
+  }
+
+  /* De-initializes the DFSDM channels to allow access to DFSDM internal registers */
+  if (HAL_DFSDM_ChannelDeInit(&hAudioIn.hDfsdmLeftChannel) != HAL_OK)
+  {
+    return AUDIO_ERROR;
+  }
+
+  /* Disable DFSDM clock */
+  AUDIO_DFSDMx_CLK_DISABLE();
+
+  /* Disable SAIx PLL */
+  if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK)
+  {
+    return AUDIO_ERROR;
+  }  
+
+  /* DFSDM reset */
+  __HAL_RCC_DFSDM_FORCE_RESET();
+  __HAL_RCC_DFSDM_RELEASE_RESET();
+
+  return AUDIO_OK;
+}
+
+/**
+  * @brief  Initializes the DFSDM channel MSP.
+  * @param  hdfsdm_channel : DFSDM channel handle.
+  * @retval None
+  */
+void HAL_DFSDM_ChannelMspInit(DFSDM_Channel_HandleTypeDef *hdfsdm_channel)
+{
+  GPIO_InitTypeDef  GPIO_InitStruct;  
+
+  /* Enable DFSDM clock */
+  AUDIO_DFSDMx_CLK_ENABLE();
+  
+  /* Enable GPIO clock */
+  AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE();
+  
+  /* DFSDM pins configuration: DFSDM_CKOUT, DMIC_DATIN pins ------------------*/
+  GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN | AUDIO_DFSDMx_DMIC_DATIN_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+  GPIO_InitStruct.Alternate = AUDIO_DFSDMx_CKOUT_DMIC_DATIN_AF;
+  HAL_GPIO_Init(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct);
+}
+
+/**
+  * @brief  De-initializes the DFSDM channel MSP.
+  * @param  hdfsdm_channel : DFSDM channel handle.
+  * @retval None
+  */
+void HAL_DFSDM_ChannelMspDeInit(DFSDM_Channel_HandleTypeDef *hdfsdm_channel)
+{
+  GPIO_InitTypeDef  GPIO_InitStruct;
+  
+  /* Enable GPIO clock */
+  AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE();
+  
+  /* DFSDM pins configuration: DFSDM_CKOUT */
+  GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+  HAL_GPIO_Init(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct);
+  HAL_GPIO_WritePin(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, AUDIO_DFSDMx_CKOUT_PIN, GPIO_PIN_RESET);
+
+
+  /* De-initialize DMIC_DATIN pin */
+  HAL_GPIO_DeInit(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, AUDIO_DFSDMx_DMIC_DATIN_PIN);
+}
+
+/**
+  * @brief  Initializes the DFSDM filter MSP.
+  * @param  hdfsdm_filter : DFSDM filter handle.
+  * @retval None
+  */
+void HAL_DFSDM_FilterMspInit(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
+{
+  /* Enable DFSDM clock */
+  AUDIO_DFSDMx_CLK_ENABLE();
+  
+  /* Enable the DMA clock */
+  AUDIO_DFSDMx_DMAx_CLK_ENABLE();
+    
+  /* Configure the hAudioIn.hDmaDfsdmLeft handle parameters */   
+  hAudioIn.hDmaDfsdmLeft.Init.Request             = DMA_REQUEST_0;
+  hAudioIn.hDmaDfsdmLeft.Init.Direction           = DMA_PERIPH_TO_MEMORY;
+  hAudioIn.hDmaDfsdmLeft.Init.PeriphInc           = DMA_PINC_DISABLE;
+  hAudioIn.hDmaDfsdmLeft.Init.MemInc              = DMA_MINC_ENABLE;
+  hAudioIn.hDmaDfsdmLeft.Init.PeriphDataAlignment = AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE;
+  hAudioIn.hDmaDfsdmLeft.Init.MemDataAlignment    = AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE;
+  hAudioIn.hDmaDfsdmLeft.Init.Mode                = DMA_CIRCULAR;
+  hAudioIn.hDmaDfsdmLeft.Init.Priority            = DMA_PRIORITY_HIGH;
+
+  hAudioIn.hDmaDfsdmLeft.Instance               = AUDIO_DFSDMx_DMAx_LEFT_CHANNEL;
+  
+  /* Associate the DMA handle */
+  __HAL_LINKDMA(hdfsdm_filter, hdmaReg, hAudioIn.hDmaDfsdmLeft);
+  
+  /* Reset DMA handle state */
+  __HAL_DMA_RESET_HANDLE_STATE(&hAudioIn.hDmaDfsdmLeft);
+
+  /* Configure the DMA Channel */
+  HAL_DMA_Init(&hAudioIn.hDmaDfsdmLeft);      
+
+  /* DMA IRQ Channel configuration */
+    HAL_NVIC_SetPriority(AUDIO_DFSDMx_DMAx_LEFT_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
+    HAL_NVIC_EnableIRQ(AUDIO_DFSDMx_DMAx_LEFT_IRQ);
+  }
+
+ /**
+  * @brief  De-initializes the DFSDM filter MSP.
+  * @param  hdfsdm_filter : DFSDM filter handle.
+  * @retval None
+  */
+void HAL_DFSDM_FilterMspDeInit(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
+{
+  /* Disable DMA  Channel IRQ */
+  HAL_NVIC_DisableIRQ(AUDIO_DFSDMx_DMAx_LEFT_IRQ);
+
+  /* De-initialize the DMA Channel */
+  HAL_DMA_DeInit(&hAudioIn.hDmaDfsdmLeft);      
+
+  /* Disable the DMA clock */
+  AUDIO_DFSDMx_DMAx_CLK_DISABLE();
+}
+
+/**
+  * @brief  Configures the SAI PLL clock according to the required audio frequency.
+  * @param  Frequency: Audio frequency.  
+  * @retval BSP AUDIO status
+  * @note   The SAI PLL input clock must be configured in the user application.
+  *         The SAI PLL configuration done within this function assumes that
+  *         the SAI PLL input clock runs at 8 MHz.
+  */
+static uint8_t AUDIO_SAIPLLConfig(uint32_t Frequency)
+{
+  RCC_PeriphCLKInitTypeDef RCC_ExCLKInitStruct;
+
+  /* Retreive actual RCC configuration */
+  HAL_RCCEx_GetPeriphCLKConfig(&RCC_ExCLKInitStruct);
+  
+    if (   (Frequency == AUDIO_FREQUENCY_11K) 
+        || (Frequency == AUDIO_FREQUENCY_22K)
+        || (Frequency == AUDIO_FREQUENCY_44K) )
+  {
+    /* Configure PLLSAI prescalers */
+    /* SAI clock config 
+    PLLSAI1_VCO= 8 Mhz * PLLSAI1N = 8 * 24 = VCO_192M 
+    SAI_CK_x = PLLSAI1_VCO/PLLSAI1P = 192/17 = 11.294 Mhz */  
+    RCC_ExCLKInitStruct.PeriphClockSelection    = RCC_PERIPHCLK_SAI1;
+    RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N        = 24; 
+    RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P        = 17; 
+    RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK;
+    RCC_ExCLKInitStruct.Sai1ClockSelection      = RCC_SAI1CLKSOURCE_PLLSAI1;
+  }
+  else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */
+  {
+    /* SAI clock config 
+    PLLSAI1_VCO= 8 Mhz * PLLSAI1N = 8 * 43 = VCO_344M 
+    SAI_CK_x = PLLSAI1_VCO/PLLSAI1P = 344/7 = 49.142 Mhz */  
+    RCC_ExCLKInitStruct.PeriphClockSelection    = RCC_PERIPHCLK_SAI1;
+    RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N        = 43;
+    RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P        = 7;
+    RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK;
+    RCC_ExCLKInitStruct.Sai1ClockSelection      = RCC_SAI1CLKSOURCE_PLLSAI1;
+  }
+  
+  if (HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct) != HAL_OK)
+  {
+    return AUDIO_ERROR;
+  }    
+
+  return AUDIO_OK;
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm32l4xx_nucleo_audio.h	Sat Dec 05 16:17:25 2015 +0000
@@ -0,0 +1,279 @@
+/**
+  ******************************************************************************
+  * @file    stm32l4xx_nucleo_audio.h
+  * @author  MCD Application Team
+  * @version V1.0.1
+  * @date    16-September-2015
+  * @brief   This file contains the common defines and functions prototypes for
+  *          the stm32l4xx_nucleo_audio.c driver.
+  ******************************************************************************
+  * @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.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32L476G_NUCLEO_AUDIO_H
+#define __STM32L476G_NUCLEO_AUDIO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#if defined(BSP_AUDIO_USE_RTOS)
+#include "k_mem.h"
+#else
+#include <stdlib.h>
+#endif
+/* Include audio component Driver */
+//#include "cs43l22.h"
+#include "stm32l4xx_nucleo.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup STM32L476G_NUCLEO
+  * @{
+  */
+
+/** @addtogroup STM32L476G_NUCLEO_AUDIO
+  * @{
+  */
+
+/** @defgroup STM32L476G_NUCLEO_AUDIO_Exported_Types Exported Types
+  * @{
+  */
+typedef void (*Audio_CallbackTypeDef)(void);
+
+/**
+  * @}
+  */
+
+/* AUDIO FREQUENCY */
+#define AUDIO_FREQUENCY_192K          ((uint32_t)192000)
+#define AUDIO_FREQUENCY_96K           ((uint32_t)96000)
+#define AUDIO_FREQUENCY_48K           ((uint32_t)48000)
+#define AUDIO_FREQUENCY_44K           ((uint32_t)44100)
+#define AUDIO_FREQUENCY_32K           ((uint32_t)32000)
+#define AUDIO_FREQUENCY_22K           ((uint32_t)22050)
+#define AUDIO_FREQUENCY_16K           ((uint32_t)16000)
+#define AUDIO_FREQUENCY_11K           ((uint32_t)11025)
+#define AUDIO_FREQUENCY_8K            ((uint32_t)8000)  
+
+/** @defgroup STM32L476G_NUCLEO_AUDIO_Exported_Constants Exported Constants
+  * @{
+  */
+/** @defgroup BSP_Audio_Out_Option BSP Audio Out Option
+  * @{
+  */
+#define BSP_AUDIO_OUT_CIRCULARMODE      ((uint32_t)0x00000001) /* BUFFER CIRCULAR MODE */
+#define BSP_AUDIO_OUT_NORMALMODE        ((uint32_t)0x00000002) /* BUFFER NORMAL MODE   */
+#define BSP_AUDIO_OUT_STEREOMODE        ((uint32_t)0x00000004) /* STEREO MODE          */
+#define BSP_AUDIO_OUT_MONOMODE          ((uint32_t)0x00000008) /* MONO MODE            */
+/**
+  * @}
+  */
+ 
+/** @defgroup BSP_Audio_Sample_Rate BSP Audio Sample Rate
+  * @{
+  */
+#define BSP_AUDIO_FREQUENCY_96K         SAI_AUDIO_FREQUENCY_96K
+#define BSP_AUDIO_FREQUENCY_48K         SAI_AUDIO_FREQUENCY_48K
+#define BSP_AUDIO_FREQUENCY_44K         SAI_AUDIO_FREQUENCY_44K
+#define BSP_AUDIO_FREQUENCY_32K         SAI_AUDIO_FREQUENCY_32K
+#define BSP_AUDIO_FREQUENCY_22K         SAI_AUDIO_FREQUENCY_22K
+#define BSP_AUDIO_FREQUENCY_16K         SAI_AUDIO_FREQUENCY_16K
+#define BSP_AUDIO_FREQUENCY_11K         SAI_AUDIO_FREQUENCY_11K
+#define BSP_AUDIO_FREQUENCY_8K          SAI_AUDIO_FREQUENCY_8K
+/**
+  * @}
+  */
+/*------------------------------------------------------------------------------
+                          USER SAI defines parameters
+ -----------------------------------------------------------------------------*/
+/* SAI peripheral configuration defines */
+#define AUDIO_SAIx                             SAI1_Block_A
+#define AUDIO_SAIx_CLK_ENABLE()                __HAL_RCC_SAI1_CLK_ENABLE()
+#define AUDIO_SAIx_CLK_DISABLE()               __HAL_RCC_SAI1_CLK_DISABLE()
+#define AUDIO_SAIx_MCK_SCK_SD_FS_AF            GPIO_AF13_SAI1
+
+#define AUDIO_SAIx_MCK_SCK_SD_FS_ENABLE()      __HAL_RCC_GPIOE_CLK_ENABLE()
+#define AUDIO_SAIx_MCK_SCK_SD_FS_DISABLE()     __HAL_RCC_GPIOE_CLK_DISABLE()
+#define AUDIO_SAIx_FS_PIN                      GPIO_PIN_4
+#define AUDIO_SAIx_SCK_PIN                     GPIO_PIN_5
+#define AUDIO_SAIx_SD_PIN                      GPIO_PIN_6
+#define AUDIO_SAIx_MCK_PIN                     GPIO_PIN_2
+#define AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT     GPIOE
+
+/* SAI DMA Channel definitions */
+#define AUDIO_SAIx_DMAx_CLK_ENABLE()         __HAL_RCC_DMA2_CLK_ENABLE()
+#define AUDIO_SAIx_DMAx_CLK_DISABLE()        __HAL_RCC_DMA2_CLK_DISABLE()
+#define AUDIO_SAIx_DMAx_CHANNEL              DMA2_Channel1
+#define AUDIO_SAIx_DMAx_IRQ                  DMA2_Channel1_IRQn
+#define AUDIO_SAIx_DMAx_PERIPH_DATA_SIZE     DMA_PDATAALIGN_HALFWORD
+#define AUDIO_SAIx_DMAx_MEM_DATA_SIZE        DMA_MDATAALIGN_HALFWORD
+#define DMA_MAX_SZE                          (uint32_t)0xFFFF
+   
+#define AUDIO_SAIx_DMAx_IRQHandler           DMA2_Channel1_IRQHandler
+
+/* Select the interrupt preemption priority for the DMA interrupt */
+#define AUDIO_OUT_IRQ_PREPRIO           5   /* Select the preemption priority level(0 is the highest) */   
+
+/* Disable SAIx PLL */
+#define AUDIO_SAIx_PLL_DISABLE()             HAL_RCCEx_DisablePLLSAI1()
+
+/*------------------------------------------------------------------------------
+                        AUDIO IN CONFIGURATION
+------------------------------------------------------------------------------*/
+/* DFSDM Configuration defines */
+#define AUDIO_DFSDMx_LEFT_CHANNEL                       DFSDM_Channel2
+#define AUDIO_DFSDMx_LEFT_FILTER                        DFSDM_Filter0
+#define AUDIO_DFSDMx_CLK_ENABLE()                       __HAL_RCC_DFSDM_CLK_ENABLE()
+#define AUDIO_DFSDMx_CLK_DISABLE()                       __HAL_RCC_DFSDM_CLK_DISABLE()
+#define AUDIO_DFSDMx_CKOUT_PIN                          GPIO_PIN_9
+#define AUDIO_DFSDMx_DMIC_DATIN_PIN                     GPIO_PIN_7
+#define AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT         GPIOE
+#define AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
+#define AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_DISABLE() __HAL_RCC_GPIOE_CLK_DISABLE()
+#define AUDIO_DFSDMx_CKOUT_DMIC_DATIN_AF                GPIO_AF6_DFSDM
+
+/* DFSDM DMA Right and Left channels definitions */
+#define AUDIO_DFSDMx_DMAx_CLK_ENABLE()                  __HAL_RCC_DMA1_CLK_ENABLE()
+#define AUDIO_DFSDMx_DMAx_CLK_DISABLE()                 __HAL_RCC_DMA1_CLK_DISABLE()
+#define AUDIO_DFSDMx_DMAx_LEFT_CHANNEL                  DMA1_Channel4
+#define AUDIO_DFSDMx_DMAx_LEFT_IRQ                      DMA1_Channel4_IRQn
+#define AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE              DMA_PDATAALIGN_WORD
+#define AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE                 DMA_MDATAALIGN_WORD
+   
+#define AUDIO_DFSDM_DMAx_LEFT_IRQHandler                DMA1_Channel4_IRQHandler
+  
+/* Select the interrupt preemption priority and subpriority for the IT/DMA interrupt */
+#define AUDIO_IN_IRQ_PREPRIO                6   /* Select the preemption priority level(0 is the highest) */
+
+/*------------------------------------------------------------------------------
+             CONFIGURATION: Audio Driver Configuration parameters
+------------------------------------------------------------------------------*/
+
+#define AUDIODATA_SIZE                      2   /* 16-bits audio data size */
+
+/* Audio status definition */     
+#define AUDIO_OK                            0
+#define AUDIO_ERROR                         1
+#define AUDIO_TIMEOUT                       2
+
+/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */
+#define DEFAULT_AUDIO_IN_FREQ               BSP_AUDIO_FREQUENCY_16K
+#define DEFAULT_AUDIO_IN_BIT_RESOLUTION     16
+#define DEFAULT_AUDIO_IN_CHANNEL_NBR        1 /* Mono = 1, Stereo = 2 */
+#define DEFAULT_AUDIO_IN_VOLUME             64
+
+/*------------------------------------------------------------------------------
+                    OPTIONAL Configuration defines parameters
+------------------------------------------------------------------------------*/
+
+/* Delay for the Codec to be correctly reset */
+#define CODEC_RESET_DELAY           5
+
+/**
+  * @}
+  */
+ 
+/** @defgroup STM32L476G_NUCLEO_AUDIO_Exported_Variables Exported Variables
+  * @{
+  */
+extern SAI_HandleTypeDef          BSP_AUDIO_hSai;
+extern DFSDM_Filter_HandleTypeDef BSP_AUDIO_hDfsdmLeftFilter;
+
+ /**
+  * @}
+  */
+   
+/** @defgroup STM32L476G_NUCLEO_AUDIO_Exported_Macros Exported Macros
+  * @{
+  */
+#define DMA_MAX(_X_)                (((_X_) <= DMA_MAX_SZE)? (_X_):DMA_MAX_SZE)
+
+/**
+  * @}
+  */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup STM32L476G_NUCLEO_AUDIO_Exported_Functions Exported Functions
+  * @{
+  */
+uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq);
+uint8_t BSP_AUDIO_OUT_DeInit(void);
+uint8_t BSP_AUDIO_OUT_Play(uint16_t* pData, uint32_t Size);
+uint8_t BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size);
+uint8_t BSP_AUDIO_OUT_Pause(void);
+uint8_t BSP_AUDIO_OUT_Resume(void);
+uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option);
+uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume);
+uint8_t BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq);
+void    BSP_AUDIO_OUT_ChangeAudioConfig(uint32_t AudioOutOption);
+uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd);
+uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output);
+void    BSP_AUDIO_OUT_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback, 
+                                        Audio_CallbackTypeDef HalfTransferCallback, 
+                                        Audio_CallbackTypeDef TransferCompleteCallback);
+
+uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_DeInit(void);
+uint8_t BSP_AUDIO_IN_Record(uint16_t *pData, uint32_t Size);
+uint8_t BSP_AUDIO_IN_SetFrequency(uint32_t AudioFreq);
+uint8_t BSP_AUDIO_IN_Stop(void);
+uint8_t BSP_AUDIO_IN_Pause(void);
+uint8_t BSP_AUDIO_IN_Resume(void);
+void    BSP_AUDIO_IN_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback, 
+                                       Audio_CallbackTypeDef HalfTransferCallback, 
+                                       Audio_CallbackTypeDef TransferCompleteCallback);
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32L476G_NUCLEO_AUDIO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+