BSP Drivers

Dependencies:   CMSIS_STM32L4xx CMSIS_DSP_401 STM32L4xx_HAL_Driver

Dependents:   DiscoAudioRecord

Files at this revision

API Documentation at this revision

Comitter:
EricLew
Date:
Mon Nov 02 19:38:36 2015 +0000
Child:
1:996254f97479
Child:
3:5ecd65e5d28b
Commit message:
commit

Changed in this revision

Adafruit_Shield/stm32_adafruit_lcd.c Show annotated file Show diff for this revision Revisions of this file
Adafruit_Shield/stm32_adafruit_lcd.h Show annotated file Show diff for this revision Revisions of this file
Adafruit_Shield/stm32_adafruit_sd.c Show annotated file Show diff for this revision Revisions of this file
Adafruit_Shield/stm32_adafruit_sd.h Show annotated file Show diff for this revision Revisions of this file
Components/Common/accelero.h Show annotated file Show diff for this revision Revisions of this file
Components/Common/audio.h Show annotated file Show diff for this revision Revisions of this file
Components/Common/camera.h Show annotated file Show diff for this revision Revisions of this file
Components/Common/epd.h Show annotated file Show diff for this revision Revisions of this file
Components/Common/gyro.h Show annotated file Show diff for this revision Revisions of this file
Components/Common/idd.h Show annotated file Show diff for this revision Revisions of this file
Components/Common/io.h Show annotated file Show diff for this revision Revisions of this file
Components/Common/lcd.h Show annotated file Show diff for this revision Revisions of this file
Components/Common/magneto.h Show annotated file Show diff for this revision Revisions of this file
Components/Common/ts.h Show annotated file Show diff for this revision Revisions of this file
Components/Common/tsensor.h Show annotated file Show diff for this revision Revisions of this file
Components/cs43l22/cs43l22.c Show annotated file Show diff for this revision Revisions of this file
Components/cs43l22/cs43l22.h Show annotated file Show diff for this revision Revisions of this file
Components/hx8347g/hx8347g.c Show annotated file Show diff for this revision Revisions of this file
Components/hx8347g/hx8347g.h Show annotated file Show diff for this revision Revisions of this file
Components/l3gd20/l3gd20.c Show annotated file Show diff for this revision Revisions of this file
Components/l3gd20/l3gd20.h Show annotated file Show diff for this revision Revisions of this file
Components/lsm303c/lsm303c.c Show annotated file Show diff for this revision Revisions of this file
Components/lsm303c/lsm303c.h Show annotated file Show diff for this revision Revisions of this file
Components/mfxstm32l152/mfxstm32l152.c Show annotated file Show diff for this revision Revisions of this file
Components/mfxstm32l152/mfxstm32l152.h Show annotated file Show diff for this revision Revisions of this file
Components/n25q128a/n25q128a.h Show annotated file Show diff for this revision Revisions of this file
Components/n25q256a/n25q256a.h Show annotated file Show diff for this revision Revisions of this file
Components/st7735/st7735.c Show annotated file Show diff for this revision Revisions of this file
Components/st7735/st7735.h Show annotated file Show diff for this revision Revisions of this file
Components/stmpe1600/stmpe1600.c Show annotated file Show diff for this revision Revisions of this file
Components/stmpe1600/stmpe1600.h Show annotated file Show diff for this revision Revisions of this file
Components/stmpe811/stmpe811.c Show annotated file Show diff for this revision Revisions of this file
Components/stmpe811/stmpe811.h Show annotated file Show diff for this revision Revisions of this file
Components/wm8994/wm8994.c Show annotated file Show diff for this revision Revisions of this file
Components/wm8994/wm8994.h Show annotated file Show diff for this revision Revisions of this file
Disco/stm32l476g_discovery.c Show annotated file Show diff for this revision Revisions of this file
Disco/stm32l476g_discovery.h Show annotated file Show diff for this revision Revisions of this file
Disco/stm32l476g_discovery_audio.c Show annotated file Show diff for this revision Revisions of this file
Disco/stm32l476g_discovery_audio.h Show annotated file Show diff for this revision Revisions of this file
Disco/stm32l476g_discovery_compass.c Show annotated file Show diff for this revision Revisions of this file
Disco/stm32l476g_discovery_compass.h Show annotated file Show diff for this revision Revisions of this file
Disco/stm32l476g_discovery_glass_lcd.c Show annotated file Show diff for this revision Revisions of this file
Disco/stm32l476g_discovery_glass_lcd.h Show annotated file Show diff for this revision Revisions of this file
Disco/stm32l476g_discovery_gyroscope.c Show annotated file Show diff for this revision Revisions of this file
Disco/stm32l476g_discovery_gyroscope.h Show annotated file Show diff for this revision Revisions of this file
Disco/stm32l476g_discovery_idd.c Show annotated file Show diff for this revision Revisions of this file
Disco/stm32l476g_discovery_idd.h Show annotated file Show diff for this revision Revisions of this file
Disco/stm32l476g_discovery_qspi.c Show annotated file Show diff for this revision Revisions of this file
Disco/stm32l476g_discovery_qspi.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_Shield/stm32_adafruit_lcd.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,1061 @@
+/**
+  ******************************************************************************
+  * @file    stm32_adafruit_lcd.c
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    10-September-2015
+  * @brief   This file includes the driver for Liquid Crystal Display (LCD) module
+  *          mounted on the Adafruit 1.8" TFT LCD shield (reference ID 802), 
+  *          that is used with the STM32 Nucleo board through SPI interface.     
+  ******************************************************************************
+  * @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.
+  *
+  ******************************************************************************
+  */ 
+
+/* File Info : -----------------------------------------------------------------
+                                   User NOTES
+1. How To use this driver:
+--------------------------
+   - The LCD st7735 component driver MUST be included with this driver.  
+
+2. Driver description:
+---------------------
+  + Initialization steps:
+     o Initialize the LCD using the BSP_LCD_Init() function.
+  
+  + Display on LCD
+     o Clear the whole LCD using the BSP_LCD_Clear() function or only one specified 
+       string line using the BSP_LCD_ClearStringLine() function.
+     o Display a character on the specified line and column using the BSP_LCD_DisplayChar()
+       function or a complete string line using the BSP_LCD_DisplayStringAtLine() function.
+     o Display a string line on the specified position (x,y in pixel) and align mode
+       using the BSP_LCD_DisplayStringAtLine() function.          
+     o Draw and fill a basic shapes (dot, line, rectangle, circle, ellipse, ..) 
+       on LCD using a set of functions.    
+ 
+------------------------------------------------------------------------------*/
+    
+/* Includes ------------------------------------------------------------------*/
+#include "stm32_adafruit_lcd.h"
+#include "../../../Utilities/Fonts/fonts.h"
+#include "../../../Utilities/Fonts/font24.c"
+#include "../../../Utilities/Fonts/font20.c"
+#include "../../../Utilities/Fonts/font16.c"
+#include "../../../Utilities/Fonts/font12.c"
+#include "../../../Utilities/Fonts/font8.c"
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup STM32_ADAFRUIT
+  * @{
+  */
+    
+/** @addtogroup STM32_ADAFRUIT_LCD
+  * @{
+  */ 
+
+/** @defgroup STM32_ADAFRUIT_LCD_Private_TypesDefinitions
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+/** @defgroup STM32_ADAFRUIT_LCD_Private_Defines
+  * @{
+  */
+#define POLY_X(Z)             ((int32_t)((Points + (Z))->X))
+#define POLY_Y(Z)             ((int32_t)((Points + (Z))->Y))
+#define NULL                  (void *)0
+
+#define MAX_HEIGHT_FONT         17
+#define MAX_WIDTH_FONT          24
+#define OFFSET_BITMAP           54
+/**
+  * @}
+  */ 
+
+/** @defgroup STM32_ADAFRUIT_LCD_Private_Macros
+  * @{
+  */
+#define ABS(X) ((X) > 0 ? (X) : -(X)) 
+
+/**
+  * @}
+  */ 
+    
+/** @defgroup STM32_ADAFRUIT_LCD_Private_Variables
+  * @{
+  */ 
+LCD_DrawPropTypeDef DrawProp;
+
+static LCD_DrvTypeDef  *lcd_drv; 
+
+/* Max size of bitmap will based on a font24 (17x24) */
+static uint8_t bitmap[MAX_HEIGHT_FONT*MAX_WIDTH_FONT*2+OFFSET_BITMAP] = {0};
+
+/**
+  * @}
+  */ 
+
+/** @defgroup STM32_ADAFRUIT_LCD_Private_FunctionPrototypes
+  * @{
+  */ 
+static void DrawChar(uint16_t Xpos, uint16_t Ypos, const uint8_t *c);
+static void FillTriangle(uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3);
+static void SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+/**
+  * @}
+  */ 
+
+
+/** @defgroup STM32_ADAFRUIT_LCD_Private_Functions
+  * @{
+  */
+  
+/**
+  * @brief  Initializes the LCD.
+  * @param  None
+  * @retval LCD state
+  */
+uint8_t BSP_LCD_Init(void)
+{ 
+  uint8_t ret = LCD_ERROR;
+  
+  /* Default value for draw propriety */
+  DrawProp.BackColor = 0xFFFF;
+  DrawProp.pFont     = &Font24;
+  DrawProp.TextColor = 0x0000;
+  
+  lcd_drv = &st7735_drv;
+  
+  /* LCD Init */   
+  lcd_drv->Init();
+  
+  /* Clear the LCD screen */
+  BSP_LCD_Clear(LCD_COLOR_WHITE);
+  
+  /* Initialize the font */
+  BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
+  
+  ret = LCD_OK;
+  
+  return ret;
+}
+
+/**
+  * @brief  Gets the LCD X size.
+  * @param  None    
+  * @retval Used LCD X size
+  */
+uint32_t BSP_LCD_GetXSize(void)
+{
+  return(lcd_drv->GetLcdPixelWidth());
+}
+
+/**
+  * @brief  Gets the LCD Y size.
+  * @param  None   
+  * @retval Used LCD Y size
+  */
+uint32_t BSP_LCD_GetYSize(void)
+{
+  return(lcd_drv->GetLcdPixelHeight());
+}
+
+/**
+  * @brief  Gets the LCD text color.
+  * @param  None 
+  * @retval Used text color.
+  */
+uint16_t BSP_LCD_GetTextColor(void)
+{
+  return DrawProp.TextColor;
+}
+
+/**
+  * @brief  Gets the LCD background color.
+  * @param  None
+  * @retval Used background color
+  */
+uint16_t BSP_LCD_GetBackColor(void)
+{
+  return DrawProp.BackColor;
+}
+
+/**
+  * @brief  Sets the LCD text color.
+  * @param  Color: Text color code RGB(5-6-5)
+  * @retval None
+  */
+void BSP_LCD_SetTextColor(uint16_t Color)
+{
+  DrawProp.TextColor = Color;
+}
+
+/**
+  * @brief  Sets the LCD background color.
+  * @param  Color: Background color code RGB(5-6-5)
+  * @retval None
+  */
+void BSP_LCD_SetBackColor(uint16_t Color)
+{
+  DrawProp.BackColor = Color;
+}
+
+/**
+  * @brief  Sets the LCD text font.
+  * @param  fonts: Font to be used
+  * @retval None
+  */
+void BSP_LCD_SetFont(sFONT *pFonts)
+{
+  DrawProp.pFont = pFonts;
+}
+
+/**
+  * @brief  Gets the LCD text font.
+  * @param  None
+  * @retval Used font
+  */
+sFONT *BSP_LCD_GetFont(void)
+{
+  return DrawProp.pFont;
+}
+
+/**
+  * @brief  Clears the hole LCD.
+  * @param  Color: Color of the background
+  * @retval None
+  */
+void BSP_LCD_Clear(uint16_t Color)
+{ 
+  uint32_t counter = 0;
+  uint32_t color_backup = DrawProp.TextColor; 
+  DrawProp.TextColor = Color;
+  
+  for(counter = 0; counter < BSP_LCD_GetYSize(); counter++)
+  {
+    BSP_LCD_DrawHLine(0, counter, BSP_LCD_GetXSize());
+  }
+  DrawProp.TextColor = color_backup; 
+  BSP_LCD_SetTextColor(DrawProp.TextColor);
+}
+
+/**
+  * @brief  Clears the selected line.
+  * @param  Line: Line to be cleared
+  *          This parameter can be one of the following values:
+  *            @arg  0..9: if the Current fonts is Font16x24
+  *            @arg  0..19: if the Current fonts is Font12x12 or Font8x12
+  *            @arg  0..29: if the Current fonts is Font8x8
+  * @retval None
+  */
+void BSP_LCD_ClearStringLine(uint16_t Line)
+{ 
+  uint32_t color_backup = DrawProp.TextColor; 
+  DrawProp.TextColor = DrawProp.BackColor;;
+    
+  /* Draw a rectangle with background color */
+  BSP_LCD_FillRect(0, (Line * DrawProp.pFont->Height), BSP_LCD_GetXSize(), DrawProp.pFont->Height);
+  
+  DrawProp.TextColor = color_backup;
+  BSP_LCD_SetTextColor(DrawProp.TextColor);
+}
+
+/**
+  * @brief  Displays one character.
+  * @param  Xpos: Start column address
+  * @param  Ypos: Line where to display the character shape.
+  * @param  Ascii: Character ascii code
+  *           This parameter must be a number between Min_Data = 0x20 and Max_Data = 0x7E 
+  * @retval None
+  */
+void BSP_LCD_DisplayChar(uint16_t Xpos, uint16_t Ypos, uint8_t Ascii)
+{
+  DrawChar(Xpos, Ypos, &DrawProp.pFont->table[(Ascii-' ') *\
+    DrawProp.pFont->Height * ((DrawProp.pFont->Width + 7) / 8)]);
+}
+
+/**
+  * @brief  Displays characters on the LCD.
+  * @param  Xpos: X position (in pixel)
+  * @param  Ypos: Y position (in pixel)   
+  * @param  Text: Pointer to string to display on LCD
+  * @param  Mode: Display mode
+  *          This parameter can be one of the following values:
+  *            @arg  CENTER_MODE
+  *            @arg  RIGHT_MODE
+  *            @arg  LEFT_MODE   
+  * @retval None
+  */
+void BSP_LCD_DisplayStringAt(uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Line_ModeTypdef Mode)
+{
+  uint16_t refcolumn = 1, i = 0;
+  uint32_t size = 0, xsize = 0; 
+  uint8_t  *ptr = Text;
+  
+  /* Get the text size */
+  while (*ptr++) size ++ ;
+  
+  /* Characters number per line */
+  xsize = (BSP_LCD_GetXSize()/DrawProp.pFont->Width);
+  
+  switch (Mode)
+  {
+  case CENTER_MODE:
+    {
+      refcolumn = Xpos + ((xsize - size)* DrawProp.pFont->Width) / 2;
+      break;
+    }
+  case LEFT_MODE:
+    {
+      refcolumn = Xpos;
+      break;
+    }
+  case RIGHT_MODE:
+    {
+      refcolumn =  - Xpos + ((xsize - size)*DrawProp.pFont->Width);
+      break;
+    }    
+  default:
+    {
+      refcolumn = Xpos;
+      break;
+    }
+  }
+  
+  /* Send the string character by character on lCD */
+  while ((*Text != 0) & (((BSP_LCD_GetXSize() - (i*DrawProp.pFont->Width)) & 0xFFFF) >= DrawProp.pFont->Width))
+  {
+    /* Display one character on LCD */
+    BSP_LCD_DisplayChar(refcolumn, Ypos, *Text);
+    /* Decrement the column position by 16 */
+    refcolumn += DrawProp.pFont->Width;
+    /* Point on the next character */
+    Text++;
+    i++;
+  }
+}
+
+/**
+  * @brief  Displays a character on the LCD.
+  * @param  Line: Line where to display the character shape
+  *          This parameter can be one of the following values:
+  *            @arg  0..19: if the Current fonts is Font8
+  *            @arg  0..12: if the Current fonts is Font12
+  *            @arg  0...9: if the Current fonts is Font16
+  *            @arg  0...7: if the Current fonts is Font20
+  *            @arg  0...5: if the Current fonts is Font24
+  * @param  ptr: Pointer to string to display on LCD
+  * @retval None
+  */
+void BSP_LCD_DisplayStringAtLine(uint16_t Line, uint8_t *ptr)
+{
+  BSP_LCD_DisplayStringAt(0, LINE(Line), ptr, LEFT_MODE);
+}
+
+/**
+  * @brief  Draws a pixel on LCD.
+  * @param  Xpos: X position 
+  * @param  Ypos: Y position
+  * @param  RGB_Code: Pixel color in RGB mode (5-6-5)  
+  * @retval None
+  */
+void BSP_LCD_DrawPixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGB_Code)
+{
+  if(lcd_drv->WritePixel != NULL)
+  {
+    lcd_drv->WritePixel(Xpos, Ypos, RGB_Code);
+  }
+}
+  
+/**
+  * @brief  Draws an horizontal line.
+  * @param  Xpos: X position
+  * @param  Ypos: Y position
+  * @param  Length: Line length
+  * @retval None
+  */
+void BSP_LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length)
+{
+  uint32_t index = 0;
+  
+  if(lcd_drv->DrawHLine != NULL)
+  {
+    lcd_drv->DrawHLine(DrawProp.TextColor, Xpos, Ypos, Length);
+  }
+  else
+  {
+    for(index = 0; index < Length; index++)
+    {
+      BSP_LCD_DrawPixel((Xpos + index), Ypos, DrawProp.TextColor);
+    }
+  }
+}
+
+/**
+  * @brief  Draws a vertical line.
+  * @param  Xpos: X position
+  * @param  Ypos: Y position
+  * @param  Length: Line length
+  * @retval None
+  */
+void BSP_LCD_DrawVLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length)
+{
+  uint32_t index = 0;
+  
+  if(lcd_drv->DrawVLine != NULL)
+  {
+    lcd_drv->DrawVLine(DrawProp.TextColor, Xpos, Ypos, Length);
+  }
+  else
+  {
+    for(index = 0; index < Length; index++)
+    {
+      BSP_LCD_DrawPixel(Xpos, Ypos + index, DrawProp.TextColor);
+    }
+  }
+}
+
+/**
+  * @brief  Draws an uni-line (between two points).
+  * @param  x1: Point 1 X position
+  * @param  y1: Point 1 Y position
+  * @param  x2: Point 2 X position
+  * @param  y2: Point 2 Y position
+  * @retval None
+  */
+void BSP_LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
+{
+  int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, 
+  yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0, 
+  curpixel = 0;
+  
+  deltax = ABS(x2 - x1);        /* The difference between the x's */
+  deltay = ABS(y2 - y1);        /* The difference between the y's */
+  x = x1;                       /* Start x off at the first pixel */
+  y = y1;                       /* Start y off at the first pixel */
+  
+  if (x2 >= x1)                 /* The x-values are increasing */
+  {
+    xinc1 = 1;
+    xinc2 = 1;
+  }
+  else                          /* The x-values are decreasing */
+  {
+    xinc1 = -1;
+    xinc2 = -1;
+  }
+  
+  if (y2 >= y1)                 /* The y-values are increasing */
+  {
+    yinc1 = 1;
+    yinc2 = 1;
+  }
+  else                          /* The y-values are decreasing */
+  {
+    yinc1 = -1;
+    yinc2 = -1;
+  }
+  
+  if (deltax >= deltay)         /* There is at least one x-value for every y-value */
+  {
+    xinc1 = 0;                  /* Don't change the x when numerator >= denominator */
+    yinc2 = 0;                  /* Don't change the y for every iteration */
+    den = deltax;
+    num = deltax / 2;
+    numadd = deltay;
+    numpixels = deltax;         /* There are more x-values than y-values */
+  }
+  else                          /* There is at least one y-value for every x-value */
+  {
+    xinc2 = 0;                  /* Don't change the x for every iteration */
+    yinc1 = 0;                  /* Don't change the y when numerator >= denominator */
+    den = deltay;
+    num = deltay / 2;
+    numadd = deltax;
+    numpixels = deltay;         /* There are more y-values than x-values */
+  }
+  
+  for (curpixel = 0; curpixel <= numpixels; curpixel++)
+  {
+    BSP_LCD_DrawPixel(x, y, DrawProp.TextColor);  /* Draw the current pixel */
+    num += numadd;                            /* Increase the numerator by the top of the fraction */
+    if (num >= den)                           /* Check if numerator >= denominator */
+    {
+      num -= den;                             /* Calculate the new numerator value */
+      x += xinc1;                             /* Change the x as appropriate */
+      y += yinc1;                             /* Change the y as appropriate */
+    }
+    x += xinc2;                               /* Change the x as appropriate */
+    y += yinc2;                               /* Change the y as appropriate */
+  }
+}
+
+/**
+  * @brief  Draws a rectangle.
+  * @param  Xpos: X position
+  * @param  Ypos: Y position
+  * @param  Width: Rectangle width  
+  * @param  Height: Rectangle height
+  * @retval None
+  */
+void BSP_LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
+{
+  /* Draw horizontal lines */
+  BSP_LCD_DrawHLine(Xpos, Ypos, Width);
+  BSP_LCD_DrawHLine(Xpos, (Ypos+ Height), Width);
+  
+  /* Draw vertical lines */
+  BSP_LCD_DrawVLine(Xpos, Ypos, Height);
+  BSP_LCD_DrawVLine((Xpos + Width), Ypos, Height);
+}
+                            
+/**
+  * @brief  Draws a circle.
+  * @param  Xpos: X position
+  * @param  Ypos: Y position
+  * @param  Radius: Circle radius
+  * @retval None
+  */
+void BSP_LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
+{
+  int32_t  D;       /* Decision Variable */ 
+  uint32_t  CurX;   /* Current X Value */
+  uint32_t  CurY;   /* Current Y Value */ 
+  
+  D = 3 - (Radius << 1);
+  CurX = 0;
+  CurY = Radius;
+  
+  while (CurX <= CurY)
+  {
+    BSP_LCD_DrawPixel((Xpos + CurX), (Ypos - CurY), DrawProp.TextColor);
+
+    BSP_LCD_DrawPixel((Xpos - CurX), (Ypos - CurY), DrawProp.TextColor);
+
+    BSP_LCD_DrawPixel((Xpos + CurY), (Ypos - CurX), DrawProp.TextColor);
+
+    BSP_LCD_DrawPixel((Xpos - CurY), (Ypos - CurX), DrawProp.TextColor);
+
+    BSP_LCD_DrawPixel((Xpos + CurX), (Ypos + CurY), DrawProp.TextColor);
+
+    BSP_LCD_DrawPixel((Xpos - CurX), (Ypos + CurY), DrawProp.TextColor);
+
+    BSP_LCD_DrawPixel((Xpos + CurY), (Ypos + CurX), DrawProp.TextColor);
+
+    BSP_LCD_DrawPixel((Xpos - CurY), (Ypos + CurX), DrawProp.TextColor);   
+
+    /* Initialize the font */
+    BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
+
+    if (D < 0)
+    { 
+      D += (CurX << 2) + 6;
+    }
+    else
+    {
+      D += ((CurX - CurY) << 2) + 10;
+      CurY--;
+    }
+    CurX++;
+  } 
+}
+
+/**
+  * @brief  Draws an poly-line (between many points).
+  * @param  Points: Pointer to the points array
+  * @param  PointCount: Number of points
+  * @retval None
+  */
+void BSP_LCD_DrawPolygon(pPoint Points, uint16_t PointCount)
+{
+  int16_t X = 0, Y = 0;
+
+  if(PointCount < 2)
+  {
+    return;
+  }
+
+  BSP_LCD_DrawLine(Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y);
+  
+  while(--PointCount)
+  {
+    X = Points->X;
+    Y = Points->Y;
+    Points++;
+    BSP_LCD_DrawLine(X, Y, Points->X, Points->Y);
+  }
+}
+
+/**
+  * @brief  Draws an ellipse on LCD.
+  * @param  Xpos: X position
+  * @param  Ypos: Y position
+  * @param  XRadius: Ellipse X radius
+  * @param  YRadius: Ellipse Y radius
+  * @retval None
+  */
+void BSP_LCD_DrawEllipse(int Xpos, int Ypos, int XRadius, int YRadius)
+{
+  int x = 0, y = -YRadius, err = 2-2*XRadius, e2;
+  float K = 0, rad1 = 0, rad2 = 0;
+  
+  rad1 = XRadius;
+  rad2 = YRadius;
+  
+  K = (float)(rad2/rad1);
+  
+  do {      
+    BSP_LCD_DrawPixel((Xpos-(uint16_t)(x/K)), (Ypos+y), DrawProp.TextColor);
+    BSP_LCD_DrawPixel((Xpos+(uint16_t)(x/K)), (Ypos+y), DrawProp.TextColor);
+    BSP_LCD_DrawPixel((Xpos+(uint16_t)(x/K)), (Ypos-y), DrawProp.TextColor);
+    BSP_LCD_DrawPixel((Xpos-(uint16_t)(x/K)), (Ypos-y), DrawProp.TextColor);      
+    
+    e2 = err;
+    if (e2 <= x) {
+      err += ++x*2+1;
+      if (-y == x && e2 <= y) e2 = 0;
+    }
+    if (e2 > y) err += ++y*2+1;     
+  }
+  while (y <= 0);
+}
+
+/**
+  * @brief  Draws a bitmap picture loaded in the STM32 MCU internal memory.
+  * @param  Xpos: Bmp X position in the LCD
+  * @param  Ypos: Bmp Y position in the LCD
+  * @param  pBmp: Pointer to Bmp picture address
+  * @retval None
+  */
+void BSP_LCD_DrawBitmap(uint16_t Xpos, uint16_t Ypos, uint8_t *pBmp)
+{
+  uint32_t height = 0, width  = 0;
+  
+  /* Read bitmap width */
+  width = *(uint16_t *) (pBmp + 18);
+  width |= (*(uint16_t *) (pBmp + 20)) << 16;
+  
+  /* Read bitmap height */
+  height = *(uint16_t *) (pBmp + 22);
+  height |= (*(uint16_t *) (pBmp + 24)) << 16; 
+  
+  /* Remap Ypos, st7735 works with inverted X in case of bitmap */
+  /* X = 0, cursor is on Top corner */
+  if(lcd_drv == &st7735_drv)
+  {
+    Ypos = BSP_LCD_GetYSize() - Ypos - height;
+  }
+  
+  SetDisplayWindow(Xpos, Ypos, width, height);
+  
+  if(lcd_drv->DrawBitmap != NULL)
+  {
+    lcd_drv->DrawBitmap(Xpos, Ypos, pBmp);
+  } 
+  SetDisplayWindow(0, 0, BSP_LCD_GetXSize(), BSP_LCD_GetYSize());
+}
+
+/**
+  * @brief  Draws a full rectangle.
+  * @param  Xpos: X position
+  * @param  Ypos: Y position
+  * @param  Width: Rectangle width  
+  * @param  Height: Rectangle height
+  * @retval None
+  */
+void BSP_LCD_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
+{
+  BSP_LCD_SetTextColor(DrawProp.TextColor);
+  do
+  {
+    BSP_LCD_DrawHLine(Xpos, Ypos++, Width);    
+  }
+  while(Height--);
+}
+
+/**
+  * @brief  Draws a full circle.
+  * @param  Xpos: X position
+  * @param  Ypos: Y position
+  * @param  Radius: Circle radius
+  * @retval None
+  */
+void BSP_LCD_FillCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
+{
+  int32_t  D;        /* Decision Variable */ 
+  uint32_t  CurX;    /* Current X Value */
+  uint32_t  CurY;    /* Current Y Value */ 
+  
+  D = 3 - (Radius << 1);
+
+  CurX = 0;
+  CurY = Radius;
+  
+  BSP_LCD_SetTextColor(DrawProp.TextColor);
+
+  while (CurX <= CurY)
+  {
+    if(CurY > 0) 
+    {
+      BSP_LCD_DrawHLine(Xpos - CurY, Ypos + CurX, 2*CurY);
+      BSP_LCD_DrawHLine(Xpos - CurY, Ypos - CurX, 2*CurY);
+    }
+
+    if(CurX > 0) 
+    {
+      BSP_LCD_DrawHLine(Xpos - CurX, Ypos - CurY, 2*CurX);
+      BSP_LCD_DrawHLine(Xpos - CurX, Ypos + CurY, 2*CurX);
+    }
+    if (D < 0)
+    { 
+      D += (CurX << 2) + 6;
+    }
+    else
+    {
+      D += ((CurX - CurY) << 2) + 10;
+      CurY--;
+    }
+    CurX++;
+  }
+
+  BSP_LCD_SetTextColor(DrawProp.TextColor);
+  BSP_LCD_DrawCircle(Xpos, Ypos, Radius);
+}
+
+/**
+  * @brief  Draws a full poly-line (between many points).
+  * @param  Points: Pointer to the points array
+  * @param  PointCount: Number of points
+  * @retval None
+  */
+void BSP_LCD_FillPolygon(pPoint Points, uint16_t PointCount)
+{
+  int16_t X = 0, Y = 0, X2 = 0, Y2 = 0, X_center = 0, Y_center = 0, X_first = 0, Y_first = 0, pixelX = 0, pixelY = 0, counter = 0;
+  uint16_t  IMAGE_LEFT = 0, IMAGE_RIGHT = 0, IMAGE_TOP = 0, IMAGE_BOTTOM = 0;  
+  
+  IMAGE_LEFT = IMAGE_RIGHT = Points->X;
+  IMAGE_TOP= IMAGE_BOTTOM = Points->Y;
+  
+  for(counter = 1; counter < PointCount; counter++)
+  {
+    pixelX = POLY_X(counter);
+    if(pixelX < IMAGE_LEFT)
+    {
+      IMAGE_LEFT = pixelX;
+    }
+    if(pixelX > IMAGE_RIGHT)
+    {
+      IMAGE_RIGHT = pixelX;
+    }
+    
+    pixelY = POLY_Y(counter);
+    if(pixelY < IMAGE_TOP)
+    {
+      IMAGE_TOP = pixelY;
+    }
+    if(pixelY > IMAGE_BOTTOM)
+    {
+      IMAGE_BOTTOM = pixelY;
+    }
+  }  
+  
+  if(PointCount < 2)
+  {
+    return;
+  }
+  
+  X_center = (IMAGE_LEFT + IMAGE_RIGHT)/2;
+  Y_center = (IMAGE_BOTTOM + IMAGE_TOP)/2;
+  
+  X_first = Points->X;
+  Y_first = Points->Y;
+  
+  while(--PointCount)
+  {
+    X = Points->X;
+    Y = Points->Y;
+    Points++;
+    X2 = Points->X;
+    Y2 = Points->Y;    
+    
+    FillTriangle(X, X2, X_center, Y, Y2, Y_center);
+    FillTriangle(X, X_center, X2, Y, Y_center, Y2);
+    FillTriangle(X_center, X2, X, Y_center, Y2, Y);   
+  }
+  
+  FillTriangle(X_first, X2, X_center, Y_first, Y2, Y_center);
+  FillTriangle(X_first, X_center, X2, Y_first, Y_center, Y2);
+  FillTriangle(X_center, X2, X_first, Y_center, Y2, Y_first);   
+}
+
+/**
+  * @brief  Draws a full ellipse.
+  * @param  Xpos: X position
+  * @param  Ypos: Y position
+  * @param  XRadius: Ellipse X radius
+  * @param  YRadius: Ellipse Y radius  
+  * @retval None
+  */
+void BSP_LCD_FillEllipse(int Xpos, int Ypos, int XRadius, int YRadius)
+{
+  int x = 0, y = -YRadius, err = 2-2*XRadius, e2;
+  float K = 0, rad1 = 0, rad2 = 0;
+  
+  rad1 = XRadius;
+  rad2 = YRadius;
+  
+  K = (float)(rad2/rad1);    
+  
+  do 
+  { 
+    BSP_LCD_DrawHLine((Xpos-(uint16_t)(x/K)), (Ypos+y), (2*(uint16_t)(x/K) + 1));
+    BSP_LCD_DrawHLine((Xpos-(uint16_t)(x/K)), (Ypos-y), (2*(uint16_t)(x/K) + 1));
+    
+    e2 = err;
+    if (e2 <= x) 
+    {
+      err += ++x*2+1;
+      if (-y == x && e2 <= y) e2 = 0;
+    }
+    if (e2 > y) err += ++y*2+1;
+  }
+  while (y <= 0);
+}
+
+/**
+  * @brief  Enables the display.
+  * @param  None
+  * @retval None
+  */
+void BSP_LCD_DisplayOn(void)
+{
+  lcd_drv->DisplayOn();
+}
+
+/**
+  * @brief  Disables the display.
+  * @param  None
+  * @retval None
+  */
+void BSP_LCD_DisplayOff(void)
+{
+  lcd_drv->DisplayOff();
+}
+
+/*******************************************************************************
+                            Static Functions
+*******************************************************************************/
+
+/**
+  * @brief  Draws a character on LCD.
+  * @param  Xpos: Line where to display the character shape
+  * @param  Ypos: Start column address
+  * @param  pChar: Pointer to the character data
+  * @retval None
+  */
+static void DrawChar(uint16_t Xpos, uint16_t Ypos, const uint8_t *pChar)
+{
+  uint32_t counterh = 0, counterw = 0, index = 0;
+  uint16_t height = 0, width = 0;
+  uint8_t offset = 0;
+  uint8_t *pchar = NULL;
+  uint32_t line = 0;
+  
+  height = DrawProp.pFont->Height;
+  width  = DrawProp.pFont->Width;
+  
+  /* Fill bitmap header*/
+  *(uint16_t *) (bitmap + 2) = (uint16_t)(height*width*2+OFFSET_BITMAP);
+  *(uint16_t *) (bitmap + 4) = (uint16_t)((height*width*2+OFFSET_BITMAP)>>16);
+  *(uint16_t *) (bitmap + 10) = OFFSET_BITMAP;
+  *(uint16_t *) (bitmap + 18) = (uint16_t)(width);
+  *(uint16_t *) (bitmap + 20) = (uint16_t)((width)>>16);
+  *(uint16_t *) (bitmap + 22) = (uint16_t)(height);
+  *(uint16_t *) (bitmap + 24) = (uint16_t)((height)>>16);
+  
+  offset =  8 *((width + 7)/8) - width ;
+  
+  for(counterh = 0; counterh < height; counterh++)
+  {
+    pchar = ((uint8_t *)pChar + (width + 7)/8 * counterh);
+    
+    if(((width + 7)/8) == 3)
+    {
+      line =  (pchar[0]<< 16) | (pchar[1]<< 8) | pchar[2];
+    }
+    
+    if(((width + 7)/8) == 2)
+    {
+      line =  (pchar[0]<< 8) | pchar[1];
+    }
+    
+    if(((width + 7)/8) == 1)
+    {
+      line =  pchar[0];
+    }    
+    
+    for (counterw = 0; counterw < width; counterw++)
+    {
+      /* Image in the bitmap is written from the bottom to the top */
+      /* Need to invert image in the bitmap */
+      index = (((height-counterh-1)*width)+(counterw))*2+OFFSET_BITMAP;
+      if(line & (1 << (width- counterw + offset- 1))) 
+      {
+        bitmap[index] = (uint8_t)DrawProp.TextColor;
+        bitmap[index+1] = (uint8_t)(DrawProp.TextColor >> 8);
+      }
+      else
+      {
+        bitmap[index] = (uint8_t)DrawProp.BackColor;
+        bitmap[index+1] = (uint8_t)(DrawProp.BackColor >> 8);
+      } 
+    }
+  }
+  
+  BSP_LCD_DrawBitmap(Xpos, Ypos, bitmap);
+}
+
+/**
+  * @brief  Fills a triangle (between 3 points).
+  * @param  Points: Pointer to the points array
+  * @param  x1: Point 1 X position
+  * @param  y1: Point 1 Y position
+  * @param  x2: Point 2 X position
+  * @param  y2: Point 2 Y position
+  * @param  x3: Point 3 X position
+  * @param  y3: Point 3 Y position
+  * @retval None
+  */
+static void FillTriangle(uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3)
+{ 
+  int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, 
+  yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0, 
+  curpixel = 0;
+  
+  deltax = ABS(x2 - x1);        /* The difference between the x's */
+  deltay = ABS(y2 - y1);        /* The difference between the y's */
+  x = x1;                       /* Start x off at the first pixel */
+  y = y1;                       /* Start y off at the first pixel */
+  
+  if (x2 >= x1)                 /* The x-values are increasing */
+  {
+    xinc1 = 1;
+    xinc2 = 1;
+  }
+  else                          /* The x-values are decreasing */
+  {
+    xinc1 = -1;
+    xinc2 = -1;
+  }
+  
+  if (y2 >= y1)                 /* The y-values are increasing */
+  {
+    yinc1 = 1;
+    yinc2 = 1;
+  }
+  else                          /* The y-values are decreasing */
+  {
+    yinc1 = -1;
+    yinc2 = -1;
+  }
+  
+  if (deltax >= deltay)         /* There is at least one x-value for every y-value */
+  {
+    xinc1 = 0;                  /* Don't change the x when numerator >= denominator */
+    yinc2 = 0;                  /* Don't change the y for every iteration */
+    den = deltax;
+    num = deltax / 2;
+    numadd = deltay;
+    numpixels = deltax;         /* There are more x-values than y-values */
+  }
+  else                          /* There is at least one y-value for every x-value */
+  {
+    xinc2 = 0;                  /* Don't change the x for every iteration */
+    yinc1 = 0;                  /* Don't change the y when numerator >= denominator */
+    den = deltay;
+    num = deltay / 2;
+    numadd = deltax;
+    numpixels = deltay;         /* There are more y-values than x-values */
+  }
+  
+  for (curpixel = 0; curpixel <= numpixels; curpixel++)
+  {
+    BSP_LCD_DrawLine(x, y, x3, y3);
+    
+    num += numadd;              /* Increase the numerator by the top of the fraction */
+    if (num >= den)             /* Check if numerator >= denominator */
+    {
+      num -= den;               /* Calculate the new numerator value */
+      x += xinc1;               /* Change the x as appropriate */
+      y += yinc1;               /* Change the y as appropriate */
+    }
+    x += xinc2;                 /* Change the x as appropriate */
+    y += yinc2;                 /* Change the y as appropriate */
+  } 
+}
+
+/**
+  * @brief  Sets display window.
+  * @param  LayerIndex: layer index
+  * @param  Xpos: LCD X position
+  * @param  Ypos: LCD Y position
+  * @param  Width: LCD window width
+  * @param  Height: LCD window height  
+  * @retval None
+  */
+static void SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
+{
+  if(lcd_drv->SetDisplayWindow != NULL)
+  {
+    lcd_drv->SetDisplayWindow(Xpos, Ypos, Width, Height);
+  }  
+}
+
+/**
+  * @}
+  */  
+  
+/**
+  * @}
+  */ 
+  
+/**
+  * @}
+  */     
+
+/**
+  * @}
+  */  
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_Shield/stm32_adafruit_lcd.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,198 @@
+/**
+  ******************************************************************************
+  * @file    stm32_adafruit_lcd.h
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    10-September-2015
+  * @brief   This file contains the common defines and functions prototypes for
+  *          the stm32_adafruit_lcd.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 __STM32_ADAFRUIT_LCD_H
+#define __STM32_ADAFRUIT_LCD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+/* Includes ------------------------------------------------------------------*/
+#include "../Components/st7735/st7735.h"
+#include "../../../Utilities/Fonts/fonts.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup STM32_ADAFRUIT
+  * @{
+  */
+ 
+/** @addtogroup STM32_ADAFRUIT_LCD
+  * @{
+  */ 
+
+
+/** @defgroup STM32_ADAFRUIT_LCD_Exported_Types
+  * @{
+  */
+   
+/** 
+  * @brief  Draw Properties structures definition
+  */ 
+typedef struct 
+{ 
+  uint32_t TextColor;
+  uint32_t BackColor;
+  sFONT    *pFont; 
+
+}LCD_DrawPropTypeDef;
+
+/** 
+  * @brief  Point structures definition
+  */ 
+typedef struct 
+{
+  int16_t X;
+  int16_t Y;
+
+}Point, * pPoint;
+
+/** 
+  * @brief  Line mode structures definition
+  */ 
+typedef enum
+{
+  CENTER_MODE             = 0x01,    /*!< Center mode */
+  RIGHT_MODE              = 0x02,    /*!< Right mode  */
+  LEFT_MODE               = 0x03     /*!< Left mode   */
+
+}Line_ModeTypdef;
+
+/**
+  * @}
+  */ 
+
+/** @defgroup STM32_ADAFRUIT_LCD_Exported_Constants
+  * @{
+  */
+  
+#define __IO    volatile  
+
+/** 
+  * @brief  LCD status structure definition  
+  */     
+#define LCD_OK         0x00
+#define LCD_ERROR      0x01
+#define LCD_TIMEOUT    0x02
+
+/** 
+  * @brief  LCD color  
+  */
+#define LCD_COLOR_BLACK         0x0000
+#define LCD_COLOR_GREY          0xF7DE          
+#define LCD_COLOR_BLUE          0x001F
+#define LCD_COLOR_RED           0xF800
+#define LCD_COLOR_GREEN         0x07E0
+#define LCD_COLOR_CYAN          0x07FF
+#define LCD_COLOR_MAGENTA       0xF81F
+#define LCD_COLOR_YELLOW        0xFFE0
+#define LCD_COLOR_WHITE         0xFFFF
+
+/** 
+  * @brief LCD default font 
+  */ 
+#define LCD_DEFAULT_FONT         Font8
+
+/**
+  * @}
+  */
+
+/** @defgroup STM32_ADAFRUIT_LCD_Exported_Functions
+  * @{
+  */   
+uint8_t  BSP_LCD_Init(void);
+uint32_t BSP_LCD_GetXSize(void);
+uint32_t BSP_LCD_GetYSize(void);
+ 
+uint16_t BSP_LCD_GetTextColor(void);
+uint16_t BSP_LCD_GetBackColor(void);
+void     BSP_LCD_SetTextColor(__IO uint16_t Color);
+void     BSP_LCD_SetBackColor(__IO uint16_t Color);
+void     BSP_LCD_SetFont(sFONT *fonts);
+sFONT    *BSP_LCD_GetFont(void);
+
+void     BSP_LCD_Clear(uint16_t Color);
+void     BSP_LCD_ClearStringLine(uint16_t Line);
+void     BSP_LCD_DisplayStringAtLine(uint16_t Line, uint8_t *ptr);
+void     BSP_LCD_DisplayStringAt(uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Line_ModeTypdef Mode);
+void     BSP_LCD_DisplayChar(uint16_t Xpos, uint16_t Ypos, uint8_t Ascii);
+
+void     BSP_LCD_DrawPixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGB_Code);
+void     BSP_LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length);
+void     BSP_LCD_DrawVLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length);
+void     BSP_LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+void     BSP_LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+void     BSP_LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+void     BSP_LCD_DrawPolygon(pPoint Points, uint16_t PointCount);
+void     BSP_LCD_DrawEllipse(int Xpos, int Ypos, int XRadius, int YRadius);
+void     BSP_LCD_DrawBitmap(uint16_t Xpos, uint16_t Ypos, uint8_t *pBmp);
+void     BSP_LCD_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+void     BSP_LCD_FillCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+void     BSP_LCD_FillPolygon(pPoint Points, uint16_t PointCount);
+void     BSP_LCD_FillEllipse(int Xpos, int Ypos, int XRadius, int YRadius);
+
+void     BSP_LCD_DisplayOff(void);
+void     BSP_LCD_DisplayOn(void);
+
+/**
+  * @}
+  */
+  
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32_ADAFRUIT_LCD_H */
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_Shield/stm32_adafruit_sd.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,1025 @@
+/**
+  ******************************************************************************
+  * @file    stm32_adafruit_sd.c
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    10-September-2015
+  * @brief   This file provides a set of functions needed to manage the SD card
+  *          mounted on the Adafruit 1.8" TFT LCD shield (reference ID 802),
+  *          that is used with the STM32 Nucleo board through SPI interface.
+  *          It implements a high level communication layer for read and write 
+  *          from/to this memory. The needed STM32XXxx hardware resources (SPI and 
+  *          GPIO) are defined in stm32XXxx_nucleo.h file, and the initialization is 
+  *          performed in SD_IO_Init() function declared in stm32XXxx_nucleo.c 
+  *          file.
+  *          You can easily tailor this driver to any other development board, 
+  *          by just adapting the defines for hardware resources and 
+  *          SD_IO_Init() function.
+  *            
+  *          +-------------------------------------------------------+
+  *          |                     Pin assignment                    |
+  *          +-------------------------+---------------+-------------+
+  *          |  STM32XXxx SPI Pins     |     SD        |    Pin      |
+  *          +-------------------------+---------------+-------------+
+  *          | SD_SPI_CS_PIN           |   ChipSelect  |    1        |
+  *          | SD_SPI_MOSI_PIN / MOSI  |   DataIn      |    2        |
+  *          |                         |   GND         |    3 (0 V)  |
+  *          |                         |   VDD         |    4 (3.3 V)|
+  *          | SD_SPI_SCK_PIN / SCLK   |   Clock       |    5        |
+  *          |                         |   GND         |    6 (0 V)  |
+  *          | SD_SPI_MISO_PIN / MISO  |   DataOut     |    7        |
+  *          +-------------------------+---------------+-------------+
+  ******************************************************************************
+  * @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.
+  *
+  ******************************************************************************
+  */ 
+
+/* File Info : -----------------------------------------------------------------
+                                   User NOTES
+1. How to use this driver:
+--------------------------
+   - This driver does not need a specific component driver for the micro SD device
+     to be included with.
+
+2. Driver description:
+---------------------
+  + Initialization steps:
+     o Initialize the micro SD card using the BSP_SD_Init() function. 
+     o Checking the SD card presence is not managed because SD detection pin is
+       not physically mapped on the Adafruit shield.
+     o The function BSP_SD_GetCardInfo() is used to get the micro SD card information 
+       which is stored in the structure "SD_CardInfo".
+  
+  + Micro SD card operations
+     o The micro SD card can be accessed with read/write block(s) operations once 
+       it is ready for access. The access can be performed in polling 
+       mode by calling the functions BSP_SD_ReadBlocks()/BSP_SD_WriteBlocks()
+       
+     o The SD erase block(s) is performed using the function BSP_SD_Erase() with 
+       specifying the number of blocks to erase.
+     o The SD runtime status is returned when calling the function BSP_SD_GetStatus().
+     
+------------------------------------------------------------------------------*/ 
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32_adafruit_sd.h"
+#include "stdlib.h"
+#include "string.h"
+#include "stdio.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup STM32_ADAFRUIT
+  * @{
+  */ 
+  
+/** @defgroup STM32_ADAFRUIT_SD
+  * @{
+  */ 
+  
+/* Private typedef -----------------------------------------------------------*/
+
+/** @defgroup STM32_ADAFRUIT_SD_Private_Types_Definitions
+  * @{
+  */ 
+typedef struct {
+  uint8_t r1;
+  uint8_t r2;
+  uint8_t r3;
+  uint8_t r4;
+  uint8_t r5;
+} SD_CmdAnswer_typedef;
+  
+/**
+  * @}
+  */
+  
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup STM32_ADAFRUIT_SD_Private_Defines
+  * @{
+  */
+#define SD_DUMMY_BYTE            0xFF
+
+#define SD_MAX_FRAME_LENGTH        17    /* Lenght = 16 + 1 */
+#define SD_CMD_LENGTH               6
+
+#define SD_MAX_TRY                100    /* Number of try */
+
+#define SD_CSD_STRUCT_V1          0x2    /* CSD struct version V1 */
+#define SD_CSD_STRUCT_V2          0x1    /* CSD struct version V2 */
+
+
+/**
+  * @brief  SD ansewer format
+  */ 
+typedef enum {
+ SD_ANSWER_R1_EXPECTED,
+ SD_ANSWER_R1B_EXPECTED,
+ SD_ANSWER_R2_EXPECTED,
+ SD_ANSWER_R3_EXPECTED,
+ SD_ANSWER_R4R5_EXPECTED,
+ SD_ANSWER_R7_EXPECTED,
+}SD_Answer_type;
+
+/**
+  * @brief  Start Data tokens:
+  *         Tokens (necessary because at nop/idle (and CS active) only 0xff is 
+  *         on the data/command line)  
+  */ 
+#define SD_TOKEN_START_DATA_SINGLE_BLOCK_READ    0xFE  /* Data token start byte, Start Single Block Read */
+#define SD_TOKEN_START_DATA_MULTIPLE_BLOCK_READ  0xFE  /* Data token start byte, Start Multiple Block Read */
+#define SD_TOKEN_START_DATA_SINGLE_BLOCK_WRITE   0xFE  /* Data token start byte, Start Single Block Write */
+#define SD_TOKEN_START_DATA_MULTIPLE_BLOCK_WRITE 0xFD  /* Data token start byte, Start Multiple Block Write */
+#define SD_TOKEN_STOP_DATA_MULTIPLE_BLOCK_WRITE  0xFD  /* Data toke stop byte, Stop Multiple Block Write */
+
+/**
+  * @brief  Commands: CMDxx = CMD-number | 0x40
+  */
+#define SD_CMD_GO_IDLE_STATE          0   /* CMD0 = 0x40  */
+#define SD_CMD_SEND_OP_COND           1   /* CMD1 = 0x41  */
+#define SD_CMD_SEND_IF_COND           8   /* CMD8 = 0x48  */
+#define SD_CMD_SEND_CSD               9   /* CMD9 = 0x49  */
+#define SD_CMD_SEND_CID               10  /* CMD10 = 0x4A */
+#define SD_CMD_STOP_TRANSMISSION      12  /* CMD12 = 0x4C */
+#define SD_CMD_SEND_STATUS            13  /* CMD13 = 0x4D */
+#define SD_CMD_SET_BLOCKLEN           16  /* CMD16 = 0x50 */
+#define SD_CMD_READ_SINGLE_BLOCK      17  /* CMD17 = 0x51 */
+#define SD_CMD_READ_MULT_BLOCK        18  /* CMD18 = 0x52 */
+#define SD_CMD_SET_BLOCK_COUNT        23  /* CMD23 = 0x57 */
+#define SD_CMD_WRITE_SINGLE_BLOCK     24  /* CMD24 = 0x58 */
+#define SD_CMD_WRITE_MULT_BLOCK       25  /* CMD25 = 0x59 */
+#define SD_CMD_PROG_CSD               27  /* CMD27 = 0x5B */
+#define SD_CMD_SET_WRITE_PROT         28  /* CMD28 = 0x5C */
+#define SD_CMD_CLR_WRITE_PROT         29  /* CMD29 = 0x5D */
+#define SD_CMD_SEND_WRITE_PROT        30  /* CMD30 = 0x5E */
+#define SD_CMD_SD_ERASE_GRP_START     32  /* CMD32 = 0x60 */
+#define SD_CMD_SD_ERASE_GRP_END       33  /* CMD33 = 0x61 */
+#define SD_CMD_UNTAG_SECTOR           34  /* CMD34 = 0x62 */
+#define SD_CMD_ERASE_GRP_START        35  /* CMD35 = 0x63 */
+#define SD_CMD_ERASE_GRP_END          36  /* CMD36 = 0x64 */
+#define SD_CMD_UNTAG_ERASE_GROUP      37  /* CMD37 = 0x65 */
+#define SD_CMD_ERASE                  38  /* CMD38 = 0x66 */
+#define SD_CMD_SD_APP_OP_COND         41  /* CMD41 = 0x69 */
+#define SD_CMD_APP_CMD                55  /* CMD55 = 0x77 */
+#define SD_CMD_READ_OCR               58  /* CMD55 = 0x79 */
+
+/**
+  * @brief  SD reponses and error flags
+  */
+typedef enum
+{
+/* R1 answer value */  
+  SD_R1_NO_ERROR            = (0x00),
+  SD_R1_IN_IDLE_STATE       = (0x01),
+  SD_R1_ERASE_RESET         = (0x02),
+  SD_R1_ILLEGAL_COMMAND     = (0x04),
+  SD_R1_COM_CRC_ERROR       = (0x08),
+  SD_R1_ERASE_SEQUENCE_ERROR= (0x10),
+  SD_R1_ADDRESS_ERROR       = (0x20),
+  SD_R1_PARAMETER_ERROR     = (0x40),
+
+/* R2 answer value */
+  SD_R2_NO_ERROR            = 0x00,
+  SD_R2_CARD_LOCKED         = 0x01,
+  SD_R2_LOCKUNLOCK_ERROR    = 0x02,
+  SD_R2_ERROR               = 0x04,
+  SD_R2_CC_ERROR            = 0x08,
+  SD_R2_CARD_ECC_FAILED     = 0x10,
+  SD_R2_WP_VIOLATION        = 0x20,
+  SD_R2_ERASE_PARAM         = 0x40,
+  SD_R2_OUTOFRANGE          = 0x80,
+  
+/**
+  * @brief  Data response error
+  */
+  SD_DATA_OK                = (0x05),
+  SD_DATA_CRC_ERROR         = (0x0B),
+  SD_DATA_WRITE_ERROR       = (0x0D),
+  SD_DATA_OTHER_ERROR       = (0xFF)
+} SD_Error;
+
+/**
+  * @}
+  */
+  
+/* Private macro -------------------------------------------------------------*/
+
+/** @defgroup STM32_ADAFRUIT_SD_Private_Macros
+  * @{
+  */  
+
+/**
+  * @}
+  */
+  
+/* Private variables ---------------------------------------------------------*/
+
+/** @defgroup STM32_ADAFRUIT_SD_Private_Variables
+  * @{
+  */       
+__IO uint8_t SdStatus = SD_NOT_PRESENT;
+
+/* flag_SDHC :
+      0 :  Standard capacity
+      1 : High capacity
+*/
+uint16_t flag_SDHC = 0; 
+
+/**
+  * @}
+  */ 
+
+/* Private function prototypes -----------------------------------------------*/
+static uint8_t SD_GetCIDRegister(SD_CID* Cid);
+static uint8_t SD_GetCSDRegister(SD_CSD* Csd);
+static uint8_t SD_GetDataResponse(void);
+static uint8_t SD_GoIdleState(void);
+static SD_CmdAnswer_typedef SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Answer);
+static uint8_t SD_WaitData(uint8_t data);
+static uint8_t SD_ReadData(void);
+/** @defgroup STM32_ADAFRUIT_SD_Private_Function_Prototypes
+  * @{
+  */ 
+/**
+  * @}
+  */
+ 
+/* Private functions ---------------------------------------------------------*/
+    
+/** @defgroup STM32_ADAFRUIT_SD_Private_Functions
+  * @{
+  */ 
+  
+/**
+  * @brief  Initializes the SD/SD communication.
+  * @param  None
+  * @retval The SD Response: 
+  *         - MSD_ERROR: Sequence failed
+  *         - MSD_OK: Sequence succeed
+  */
+uint8_t BSP_SD_Init(void)
+{ 
+  /* Configure IO functionalities for SD pin */
+  SD_IO_Init();
+
+  /* SD detection pin is not physically mapped on the Adafruit shield */
+  SdStatus = SD_PRESENT;
+  
+  /* SD initialized and set to SPI mode properly */
+  return SD_GoIdleState();
+}
+
+/**
+  * @brief  Returns information about specific card.
+  * @param  pCardInfo: Pointer to a SD_CardInfo structure that contains all SD 
+  *         card information.
+  * @retval The SD Response:
+  *         - MSD_ERROR: Sequence failed
+  *         - MSD_OK: Sequence succeed
+  */
+uint8_t BSP_SD_GetCardInfo(SD_CardInfo *pCardInfo)
+{
+  uint8_t status;
+
+  status = SD_GetCSDRegister(&(pCardInfo->Csd));
+  status|= SD_GetCIDRegister(&(pCardInfo->Cid));
+  if(flag_SDHC == 1 )
+  {
+    pCardInfo->CardBlockSize = 512;
+    pCardInfo->CardCapacity = (pCardInfo->Csd.version.v2.DeviceSize + 1) * pCardInfo->CardBlockSize;
+  }
+  else
+  {
+    pCardInfo->CardCapacity = (pCardInfo->Csd.version.v1.DeviceSize + 1) ;
+    pCardInfo->CardCapacity *= (1 << (pCardInfo->Csd.version.v1.DeviceSizeMul + 2));
+    pCardInfo->CardBlockSize = 1 << (pCardInfo->Csd.RdBlockLen);
+    pCardInfo->CardCapacity *= pCardInfo->CardBlockSize;
+  }
+  
+  return status;
+}
+
+/**
+  * @brief  Reads block(s) from a specified address in the SD card, in polling mode. 
+  * @param  pData: Pointer to the buffer that will contain the data to transmit
+  * @param  ReadAddr: Address from where data is to be read  
+  * @param  BlockSize: SD card data block size, that should be 512
+  * @param  NumOfBlocks: Number of SD blocks to read 
+  * @retval SD status
+  */
+uint8_t BSP_SD_ReadBlocks(uint32_t* pData, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks)
+{
+  uint32_t offset = 0;
+  uint8_t retr = BSP_SD_ERROR;
+  uint8_t *ptr = NULL;
+  SD_CmdAnswer_typedef response;
+  
+  /* Send CMD16 (SD_CMD_SET_BLOCKLEN) to set the size of the block and 
+     Check if the SD acknowledged the set block length command: R1 response (0x00: no errors) */
+  response = SD_SendCmd(SD_CMD_SET_BLOCKLEN, BlockSize, 0xFF, SD_ANSWER_R1_EXPECTED);
+  SD_IO_CSState(1);
+  SD_IO_WriteByte(SD_DUMMY_BYTE);
+  if ( response.r1 != SD_R1_NO_ERROR)
+  {
+     goto error;
+  }
+  
+  ptr = malloc(sizeof(uint8_t)*BlockSize);
+  if( ptr == NULL )
+  {
+     goto error;
+  }
+  memset(ptr, SD_DUMMY_BYTE, sizeof(uint8_t)*BlockSize);
+
+  /* Data transfer */
+  while (NumberOfBlocks--)
+  {
+    /* Send CMD17 (SD_CMD_READ_SINGLE_BLOCK) to read one block */
+    /* Check if the SD acknowledged the read block command: R1 response (0x00: no errors) */
+    response = SD_SendCmd(SD_CMD_READ_SINGLE_BLOCK, (ReadAddr + offset)/(flag_SDHC == 1 ?BlockSize: 1), 0xFF, SD_ANSWER_R1_EXPECTED);
+    if ( response.r1 != SD_R1_NO_ERROR)
+    {
+      goto error;
+    }
+
+    /* Now look for the data token to signify the start of the data */
+    if (SD_WaitData(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ) == BSP_SD_OK)
+    {
+      /* Read the SD block data : read NumByteToRead data */
+      SD_IO_WriteReadData(ptr, (uint8_t*)pData + offset, BlockSize);
+
+      /* Set next read address*/
+      offset += BlockSize;
+      /* get CRC bytes (not really needed by us, but required by SD) */
+      SD_IO_WriteByte(SD_DUMMY_BYTE);
+      SD_IO_WriteByte(SD_DUMMY_BYTE);      
+    }
+    else
+    {
+      goto error;
+    }
+    
+    /* End the command data read cycle */
+    SD_IO_CSState(1);
+    SD_IO_WriteByte(SD_DUMMY_BYTE);
+  }
+  
+  retr = BSP_SD_OK;
+  
+error :  
+  /* Send dummy byte: 8 Clock pulses of delay */
+  SD_IO_CSState(1);
+  SD_IO_WriteByte(SD_DUMMY_BYTE);
+  if(ptr != NULL) free(ptr);
+  
+  /* Return the reponse */
+  return retr;
+}
+
+/**
+  * @brief  Writes block(s) to a specified address in the SD card, in polling mode. 
+  * @param  pData: Pointer to the buffer that will contain the data to transmit
+  * @param  WriteAddr: Address from where data is to be written  
+  * @param  BlockSize: SD card data block size, that should be 512
+  * @param  NumOfBlocks: Number of SD blocks to write
+  * @retval SD status
+  */
+uint8_t BSP_SD_WriteBlocks(uint32_t* pData, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks)
+{
+  uint32_t offset = 0;
+  uint8_t retr = BSP_SD_ERROR;
+  uint8_t *ptr = NULL;
+  SD_CmdAnswer_typedef response;
+  
+  /* Send CMD16 (SD_CMD_SET_BLOCKLEN) to set the size of the block and 
+     Check if the SD acknowledged the set block length command: R1 response (0x00: no errors) */
+  response = SD_SendCmd(SD_CMD_SET_BLOCKLEN, BlockSize, 0xFF, SD_ANSWER_R1_EXPECTED);
+  SD_IO_CSState(1);
+  SD_IO_WriteByte(SD_DUMMY_BYTE);
+  if ( response.r1 != SD_R1_NO_ERROR)
+  {
+    goto error;
+  }
+  
+  ptr = malloc(sizeof(uint8_t)*BlockSize);
+  if (ptr == NULL)
+  {
+    goto error;
+  }
+  
+  /* Data transfer */
+  while (NumberOfBlocks--)
+  {
+    /* Send CMD24 (SD_CMD_WRITE_SINGLE_BLOCK) to write blocks  and
+       Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */
+    response = SD_SendCmd(SD_CMD_WRITE_SINGLE_BLOCK, (WriteAddr + offset)/(flag_SDHC == 1 ? BlockSize: 1), 0xFF, SD_ANSWER_R1_EXPECTED);
+    if (response.r1 != SD_R1_NO_ERROR)
+    {
+      goto error;
+    }
+    
+    /* Send dummy byte for NWR timing : one byte between CMDWRITE and TOKEN */
+    SD_IO_WriteByte(SD_DUMMY_BYTE);
+    SD_IO_WriteByte(SD_DUMMY_BYTE);
+
+    /* Send the data token to signify the start of the data */
+    SD_IO_WriteByte(SD_TOKEN_START_DATA_SINGLE_BLOCK_WRITE);
+
+    /* Write the block data to SD */
+    SD_IO_WriteReadData((uint8_t*)pData + offset, ptr, BlockSize);
+    
+    /* Set next write address */
+    offset += BlockSize;
+
+    /* Put CRC bytes (not really needed by us, but required by SD) */
+    SD_IO_WriteByte(SD_DUMMY_BYTE);
+    SD_IO_WriteByte(SD_DUMMY_BYTE);
+
+    /* Read data response */
+    if (SD_GetDataResponse() != SD_DATA_OK)
+    {
+      /* Set response value to failure */
+      goto error;
+    }
+
+    SD_IO_CSState(1);    
+    SD_IO_WriteByte(SD_DUMMY_BYTE);
+  }
+  retr = BSP_SD_OK;
+  
+error :
+  if(ptr != NULL) free(ptr);
+  /* Send dummy byte: 8 Clock pulses of delay */
+  SD_IO_CSState(1);    
+  SD_IO_WriteByte(SD_DUMMY_BYTE);
+  
+  /* Return the reponse */
+  return retr;
+}
+
+/**
+  * @brief  Erases the specified memory area of the given SD card. 
+  * @param  StartAddr: Start byte address
+  * @param  EndAddr: End byte address
+  * @retval SD status
+  */
+uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr)
+{
+  uint8_t retr = BSP_SD_ERROR;
+  SD_CmdAnswer_typedef response;
+
+  /* Send CMD32 (Erase group start) and check if the SD acknowledged the erase command: R1 response (0x00: no errors) */
+  response = SD_SendCmd(SD_CMD_SD_ERASE_GRP_START, StartAddr, 0xFF, SD_ANSWER_R1_EXPECTED);
+  SD_IO_CSState(1);    
+  SD_IO_WriteByte(SD_DUMMY_BYTE);  if (response.r1 == SD_R1_NO_ERROR)
+  {
+    /* Send CMD33 (Erase group end) and Check if the SD acknowledged the erase command: R1 response (0x00: no errors) */
+    response = SD_SendCmd(SD_CMD_SD_ERASE_GRP_END, EndAddr, 0xFF, SD_ANSWER_R1_EXPECTED);
+    SD_IO_CSState(1);    
+    SD_IO_WriteByte(SD_DUMMY_BYTE);
+    if (response.r1 == SD_R1_NO_ERROR)
+    {
+      /* Send CMD38 (Erase) and Check if the SD acknowledged the erase command: R1 response (0x00: no errors) */
+      response = SD_SendCmd(SD_CMD_ERASE, 0, 0xFF, SD_ANSWER_R1B_EXPECTED);
+      if (response.r1 == SD_R1_NO_ERROR)
+      {
+        retr = BSP_SD_OK;
+      }
+      SD_IO_CSState(1);    
+      SD_IO_WriteByte(SD_DUMMY_BYTE);
+    }
+  }
+  
+  /* Return the reponse */
+  return retr;
+}
+
+/**
+  * @brief  Returns the SD status.
+  * @param  None
+  * @retval The SD status.
+  */
+uint8_t BSP_SD_GetStatus(void)
+{
+  SD_CmdAnswer_typedef retr;
+  
+  /* Send CMD13 (SD_SEND_STATUS) to get SD status */
+  retr = SD_SendCmd(SD_CMD_SEND_STATUS, 0, 0xFF, SD_ANSWER_R2_EXPECTED);
+  SD_IO_CSState(1);    
+  SD_IO_WriteByte(SD_DUMMY_BYTE);
+  
+  /* Find SD status according to card state */
+  if(( retr.r1 == SD_R1_NO_ERROR) && ( retr.r2 == SD_R2_NO_ERROR))
+  {
+    return BSP_SD_OK;
+  }
+
+  return BSP_SD_ERROR;
+}
+
+/**
+  * @brief  Reads the SD card SCD register.
+  *         Reading the contents of the CSD register in SPI mode is a simple 
+  *         read-block transaction.
+  * @param  Csd: pointer on an SCD register structure
+  * @retval SD status
+  */
+uint8_t SD_GetCSDRegister(SD_CSD* Csd)
+{
+  uint16_t counter = 0;
+  uint8_t CSD_Tab[16];
+  uint8_t retr = BSP_SD_ERROR;
+  SD_CmdAnswer_typedef response;
+  
+  /* Send CMD9 (CSD register) or CMD10(CSD register) and Wait for response in the R1 format (0x00 is no errors) */
+  response = SD_SendCmd(SD_CMD_SEND_CSD, 0, 0xFF, SD_ANSWER_R1_EXPECTED);
+  if(response.r1 == SD_R1_NO_ERROR)
+  {
+    if (SD_WaitData(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ) == BSP_SD_OK)
+    {
+      for (counter = 0; counter < 16; counter++)
+      {
+        /* Store CSD register value on CSD_Tab */
+        CSD_Tab[counter] = SD_IO_WriteByte(SD_DUMMY_BYTE);
+      }
+      
+      /* Get CRC bytes (not really needed by us, but required by SD) */
+      SD_IO_WriteByte(SD_DUMMY_BYTE);
+      SD_IO_WriteByte(SD_DUMMY_BYTE);
+
+      /*************************************************************************
+        CSD header decoding 
+      *************************************************************************/
+      
+      /* Byte 0 */
+      Csd->CSDStruct = (CSD_Tab[0] & 0xC0) >> 6;
+      Csd->Reserved1 =  CSD_Tab[0] & 0x3F;
+      
+      /* Byte 1 */
+      Csd->TAAC = CSD_Tab[1];
+      
+      /* Byte 2 */
+      Csd->NSAC = CSD_Tab[2];
+      
+      /* Byte 3 */
+      Csd->MaxBusClkFrec = CSD_Tab[3];
+      
+      /* Byte 4/5 */
+      Csd->CardComdClasses = (CSD_Tab[4] << 4) | ((CSD_Tab[5] & 0xF0) >> 4);
+      Csd->RdBlockLen = CSD_Tab[5] & 0x0F;
+      
+      /* Byte 6 */
+      Csd->PartBlockRead   = (CSD_Tab[6] & 0x80) >> 7;
+      Csd->WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6;
+      Csd->RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5;
+      Csd->DSRImpl         = (CSD_Tab[6] & 0x10) >> 4;
+
+      /*************************************************************************
+        CSD v1/v2 decoding  
+      *************************************************************************/
+     
+      if(flag_SDHC == 0)
+      {
+        Csd->version.v1.Reserved1 = ((CSD_Tab[6] & 0x0C) >> 2);
+        
+        Csd->version.v1.DeviceSize =  ((CSD_Tab[6] & 0x03) << 10) 
+                                    |  (CSD_Tab[7] << 2)
+                                    | ((CSD_Tab[8] & 0xC0) >> 6);
+        Csd->version.v1.MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3;
+        Csd->version.v1.MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07);
+        Csd->version.v1.MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5;
+        Csd->version.v1.MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2;
+        Csd->version.v1.DeviceSizeMul = ((CSD_Tab[9] & 0x03) << 1)
+                                       |((CSD_Tab[10] & 0x80) >> 7);
+      }
+      else
+      {
+        Csd->version.v2.Reserved1 = ((CSD_Tab[6] & 0x0F) << 2) | ((CSD_Tab[7] & 0xC0) >> 6);
+        Csd->version.v2.DeviceSize= ((CSD_Tab[7] & 0x3F) << 16) | (CSD_Tab[8] << 8) | CSD_Tab[9];    
+        Csd->version.v2.Reserved2 = ((CSD_Tab[10] & 0x80) >> 8);
+      }    
+            
+      Csd->EraseSingleBlockEnable = (CSD_Tab[10] & 0x40) >> 6;
+      Csd->EraseSectorSize   = ((CSD_Tab[10] & 0x3F) << 1)
+                              |((CSD_Tab[11] & 0x80) >> 7);
+      Csd->WrProtectGrSize   = (CSD_Tab[11] & 0x7F);
+      Csd->WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7;
+      Csd->Reserved2         = (CSD_Tab[12] & 0x60) >> 5;
+      Csd->WrSpeedFact       = (CSD_Tab[12] & 0x1C) >> 2;
+      Csd->MaxWrBlockLen     = ((CSD_Tab[12] & 0x03) << 2)
+                              |((CSD_Tab[13] & 0xC0) >> 6);
+      Csd->WriteBlockPartial = (CSD_Tab[13] & 0x20) >> 5;
+      Csd->Reserved3         = (CSD_Tab[13] & 0x1F);
+      Csd->FileFormatGrouop  = (CSD_Tab[14] & 0x80) >> 7;
+      Csd->CopyFlag          = (CSD_Tab[14] & 0x40) >> 6;
+      Csd->PermWrProtect     = (CSD_Tab[14] & 0x20) >> 5;
+      Csd->TempWrProtect     = (CSD_Tab[14] & 0x10) >> 4;
+      Csd->FileFormat        = (CSD_Tab[14] & 0x0C) >> 2;
+      Csd->Reserved4         = (CSD_Tab[14] & 0x03);
+      Csd->crc               = (CSD_Tab[15] & 0xFE) >> 1;
+      Csd->Reserved5         = (CSD_Tab[15] & 0x01);
+      
+      retr = BSP_SD_OK;
+    }
+  }
+  
+  /* Send dummy byte: 8 Clock pulses of delay */
+  SD_IO_CSState(1);
+  SD_IO_WriteByte(SD_DUMMY_BYTE);
+  
+  /* Return the reponse */
+  return retr;
+}
+
+/**
+  * @brief  Reads the SD card CID register.
+  *         Reading the contents of the CID register in SPI mode is a simple 
+  *         read-block transaction.
+  * @param  Cid: pointer on an CID register structure
+  * @retval SD status
+  */
+uint8_t SD_GetCIDRegister(SD_CID* Cid)
+{
+  uint32_t counter = 0;
+  uint8_t retr = BSP_SD_ERROR;
+  uint8_t CID_Tab[16];
+  SD_CmdAnswer_typedef response;
+  
+  /* Send CMD10 (CID register) and Wait for response in the R1 format (0x00 is no errors) */
+  response = SD_SendCmd(SD_CMD_SEND_CID, 0, 0xFF, SD_ANSWER_R1_EXPECTED);
+  if(response.r1 == SD_R1_NO_ERROR)
+  {
+    if(SD_WaitData(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ) == BSP_SD_OK)
+    {
+      /* Store CID register value on CID_Tab */
+      for (counter = 0; counter < 16; counter++)
+      {
+        CID_Tab[counter] = SD_IO_WriteByte(SD_DUMMY_BYTE);
+      }
+      
+      /* Get CRC bytes (not really needed by us, but required by SD) */
+      SD_IO_WriteByte(SD_DUMMY_BYTE);
+      SD_IO_WriteByte(SD_DUMMY_BYTE);
+      
+      /* Byte 0 */
+      Cid->ManufacturerID = CID_Tab[0];
+      
+      /* Byte 1 */
+      Cid->OEM_AppliID = CID_Tab[1] << 8;
+      
+      /* Byte 2 */
+      Cid->OEM_AppliID |= CID_Tab[2];
+      
+      /* Byte 3 */
+      Cid->ProdName1 = CID_Tab[3] << 24;
+      
+      /* Byte 4 */
+      Cid->ProdName1 |= CID_Tab[4] << 16;
+      
+      /* Byte 5 */
+      Cid->ProdName1 |= CID_Tab[5] << 8;
+      
+      /* Byte 6 */
+      Cid->ProdName1 |= CID_Tab[6];
+      
+      /* Byte 7 */
+      Cid->ProdName2 = CID_Tab[7];
+      
+      /* Byte 8 */
+      Cid->ProdRev = CID_Tab[8];
+      
+      /* Byte 9 */
+      Cid->ProdSN = CID_Tab[9] << 24;
+      
+      /* Byte 10 */
+      Cid->ProdSN |= CID_Tab[10] << 16;
+      
+      /* Byte 11 */
+      Cid->ProdSN |= CID_Tab[11] << 8;
+      
+      /* Byte 12 */
+      Cid->ProdSN |= CID_Tab[12];
+      
+      /* Byte 13 */
+      Cid->Reserved1 |= (CID_Tab[13] & 0xF0) >> 4;
+      Cid->ManufactDate = (CID_Tab[13] & 0x0F) << 8;
+      
+      /* Byte 14 */
+      Cid->ManufactDate |= CID_Tab[14];
+      
+      /* Byte 15 */
+      Cid->CID_CRC = (CID_Tab[15] & 0xFE) >> 1;
+      Cid->Reserved2 = 1;
+
+      retr = BSP_SD_OK;
+    }
+  }
+  
+  /* Send dummy byte: 8 Clock pulses of delay */
+  SD_IO_CSState(1);
+  SD_IO_WriteByte(SD_DUMMY_BYTE);
+  
+  /* Return the reponse */
+  return retr;
+}
+
+/**
+  * @brief  Sends 5 bytes command to the SD card and get response
+  * @param  Cmd: The user expected command to send to SD card.
+  * @param  Arg: The command argument.
+  * @param  Crc: The CRC.
+  * @param  Answer: SD_ANSWER_NOT_EXPECTED or SD_ANSWER_EXPECTED
+  * @retval SD status
+  */
+SD_CmdAnswer_typedef SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Answer)
+{
+  uint8_t frame[SD_CMD_LENGTH], frameout[SD_CMD_LENGTH];
+  SD_CmdAnswer_typedef retr = {0xFF, 0xFF , 0xFF, 0xFF, 0xFF};
+
+  /* R1 Lenght = NCS(0)+ 6 Bytes command + NCR(min1 max8) + 1 Bytes answer + NEC(0) = 15bytes */
+  /* R1b identical to R1 + Busy information                                                   */
+  /* R2 Lenght = NCS(0)+ 6 Bytes command + NCR(min1 max8) + 2 Bytes answer + NEC(0) = 16bytes */
+  
+  /* Prepare Frame to send */
+  frame[0] = (Cmd | 0x40);         /* Construct byte 1 */
+  frame[1] = (uint8_t)(Arg >> 24); /* Construct byte 2 */
+  frame[2] = (uint8_t)(Arg >> 16); /* Construct byte 3 */
+  frame[3] = (uint8_t)(Arg >> 8);  /* Construct byte 4 */
+  frame[4] = (uint8_t)(Arg);       /* Construct byte 5 */
+  frame[5] = (Crc | 0x01);         /* Construct byte 6 */
+    
+  /* Send the command */
+  SD_IO_CSState(0);
+  SD_IO_WriteReadData(frame, frameout, SD_CMD_LENGTH); /* Send the Cmd bytes */
+  
+  switch(Answer)
+  {
+  case SD_ANSWER_R1_EXPECTED :
+    retr.r1 = SD_ReadData();
+    break;
+  case SD_ANSWER_R1B_EXPECTED :
+    retr.r1 = SD_ReadData();
+    retr.r2 = SD_IO_WriteByte(SD_DUMMY_BYTE);
+    /* Set CS High */
+    SD_IO_CSState(1);
+    HAL_Delay(1);
+    /* Set CS Low */
+    SD_IO_CSState(0);
+    
+    /* Wait IO line return 0xFF */
+    while (SD_IO_WriteByte(SD_DUMMY_BYTE) != 0xFF); 
+    break;
+  case SD_ANSWER_R2_EXPECTED :
+    retr.r1 = SD_ReadData();
+    retr.r2 = SD_IO_WriteByte(SD_DUMMY_BYTE);
+    break;
+  case SD_ANSWER_R3_EXPECTED :
+  case SD_ANSWER_R7_EXPECTED :
+    retr.r1 = SD_ReadData();
+    retr.r2 = SD_IO_WriteByte(SD_DUMMY_BYTE);
+    retr.r3 = SD_IO_WriteByte(SD_DUMMY_BYTE);
+    retr.r4 = SD_IO_WriteByte(SD_DUMMY_BYTE);
+    retr.r5 = SD_IO_WriteByte(SD_DUMMY_BYTE);
+    break;
+  }  
+  return retr;
+}
+
+/**
+  * @brief  Gets the SD card data response and check the busy flag.
+  * @param  None
+  * @retval The SD status: Read data response xxx0<status>1
+  *         - status 010: Data accecpted
+  *         - status 101: Data rejected due to a crc error
+  *         - status 110: Data rejected due to a Write error.
+  *         - status 111: Data rejected due to other error.
+  */
+uint8_t SD_GetDataResponse(void)
+{
+  uint8_t dataresponse;
+  uint8_t rvalue = SD_DATA_OTHER_ERROR;
+  
+  dataresponse = SD_IO_WriteByte(SD_DUMMY_BYTE);
+  SD_IO_WriteByte(SD_DUMMY_BYTE); /* read the busy response byte*/
+ 
+  /* Mask unused bits */
+  switch (dataresponse & 0x1F)
+  {
+  case SD_DATA_OK:
+    rvalue = SD_DATA_OK;
+    
+    /* Set CS High */
+    SD_IO_CSState(1);
+    /* Set CS Low */
+    SD_IO_CSState(0);
+
+    /* Wait IO line return 0xFF */
+    while (SD_IO_WriteByte(SD_DUMMY_BYTE) != 0xFF);
+    break;
+  case SD_DATA_CRC_ERROR:
+    rvalue =  SD_DATA_CRC_ERROR;
+  case SD_DATA_WRITE_ERROR:
+    rvalue = SD_DATA_WRITE_ERROR;
+  }
+  
+  /* Return response */
+  return rvalue;
+}
+
+
+/**
+  * @brief  Put the SD in Idle state.
+  * @param  None
+  * @retval SD status
+  */
+uint8_t SD_GoIdleState(void)
+{
+  SD_CmdAnswer_typedef response;
+  __IO uint8_t counter = 0;
+  /* Send CMD0 (SD_CMD_GO_IDLE_STATE) to put SD in SPI mode and 
+     wait for In Idle State Response (R1 Format) equal to 0x01 */
+  do{
+    counter++;
+    response = SD_SendCmd(SD_CMD_GO_IDLE_STATE, 0, 0x95, SD_ANSWER_R1_EXPECTED);
+    SD_IO_CSState(1);
+    SD_IO_WriteByte(SD_DUMMY_BYTE);
+    if(counter >= SD_MAX_TRY)
+    {
+      return BSP_SD_ERROR;
+    }
+  }
+  while(response.r1 != SD_R1_IN_IDLE_STATE);
+  
+    
+  /* Send CMD8 (SD_CMD_SEND_IF_COND) to check the power supply status 
+     and wait until response (R7 Format) equal to 0xAA and */
+  response = SD_SendCmd(SD_CMD_SEND_IF_COND, 0x1AA, 0x87, SD_ANSWER_R7_EXPECTED);
+  SD_IO_CSState(1);
+  SD_IO_WriteByte(SD_DUMMY_BYTE);
+  if((response.r1  & SD_R1_ILLEGAL_COMMAND) == SD_R1_ILLEGAL_COMMAND)
+  {
+    /* initialise card V1 */
+    do
+    {
+      /* initialise card V1 */
+      /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ 
+      response = SD_SendCmd(SD_CMD_APP_CMD, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED);
+      SD_IO_CSState(1);
+      SD_IO_WriteByte(SD_DUMMY_BYTE);
+      
+      /* Send ACMD41 (SD_CMD_SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors) */
+      response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED);
+      SD_IO_CSState(1);
+      SD_IO_WriteByte(SD_DUMMY_BYTE);
+    }
+    while(response.r1 == SD_R1_IN_IDLE_STATE);
+    flag_SDHC = 0;
+  } 
+  else if(response.r1 == SD_R1_IN_IDLE_STATE)
+  {
+      /* initialise card V2 */
+    do {
+      
+      /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ 
+      response = SD_SendCmd(SD_CMD_APP_CMD, 0, 0xFF, SD_ANSWER_R1_EXPECTED);
+      SD_IO_CSState(1);
+      SD_IO_WriteByte(SD_DUMMY_BYTE);
+      
+      /* Send ACMD41 (SD_CMD_SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors) */
+      response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x40000000, 0xFF, SD_ANSWER_R1_EXPECTED);
+      SD_IO_CSState(1);
+      SD_IO_WriteByte(SD_DUMMY_BYTE);
+    }
+    while(response.r1 == SD_R1_IN_IDLE_STATE);
+    
+    if((response.r1 & SD_R1_ILLEGAL_COMMAND) == SD_R1_ILLEGAL_COMMAND)
+    {
+      do {
+        /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ 
+        response = SD_SendCmd(SD_CMD_APP_CMD, 0, 0xFF, SD_ANSWER_R1_EXPECTED);
+        SD_IO_CSState(1);
+        SD_IO_WriteByte(SD_DUMMY_BYTE);
+        if(response.r1 != SD_R1_IN_IDLE_STATE)
+        {
+          return BSP_SD_ERROR;
+        }
+        /* Send ACMD41 (SD_CMD_SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors) */
+        response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED);
+        SD_IO_CSState(1);
+        SD_IO_WriteByte(SD_DUMMY_BYTE);
+      }
+      while(response.r1 == SD_R1_IN_IDLE_STATE);        
+    }  
+    
+    /* Send CMD58 (SD_CMD_READ_OCR) to initialize SDHC or SDXC cards: R3 response (0x00: no errors) */
+    response = SD_SendCmd(SD_CMD_READ_OCR, 0x00000000, 0xFF, SD_ANSWER_R3_EXPECTED);
+    SD_IO_CSState(1);
+    SD_IO_WriteByte(SD_DUMMY_BYTE);
+    if(response.r1 != SD_R1_NO_ERROR)
+    {
+      return BSP_SD_ERROR;
+    } 
+    flag_SDHC = (response.r2 & 0x40) >> 6;
+  }
+  else
+  {
+    return BSP_SD_ERROR;
+  }
+  
+  return BSP_SD_OK; 
+}
+
+/**
+  * @brief  Waits a data until a value different from SD_DUMMY_BITE
+  * @param  None
+  * @retval the value read
+  */
+uint8_t SD_ReadData(void)
+{
+  uint8_t timeout = 0x08;
+  uint8_t readvalue;
+ 
+  /* Check if response is got or a timeout is happen */
+  do {
+    readvalue = SD_IO_WriteByte(SD_DUMMY_BYTE);
+    timeout--;
+    
+  }while ((readvalue == SD_DUMMY_BYTE) && timeout);
+
+  /* Right response got */
+  return readvalue;
+}
+
+/**
+  * @brief  Waits a data from the SD card
+  * @param  data : Expected data from the SD card
+  * @retval BSP_SD_OK or BSP_SD_TIMEOUT
+  */
+uint8_t SD_WaitData(uint8_t data)
+{
+  uint16_t timeout = 0xFFFF;
+  uint8_t readvalue;
+  
+  /* Check if response is got or a timeout is happen */
+  
+  do {
+    readvalue = SD_IO_WriteByte(SD_DUMMY_BYTE);
+    timeout--;
+  }while ((readvalue != data) && timeout);
+
+  if (timeout == 0)
+  {
+    /* After time out */
+    return BSP_SD_TIMEOUT;
+  }
+
+  /* Right response got */
+  return BSP_SD_OK;
+}
+
+/**
+  * @}
+  */  
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_Shield/stm32_adafruit_sd.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,241 @@
+/**
+  ******************************************************************************
+  * @file    stm32_adafruit_sd.h
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    10-September-2015
+  * @brief   This file contains the common defines and functions prototypes for
+  *          the stm32_adafruit_sd.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 __STM32_ADAFRUIT_SD_H
+#define __STM32_ADAFRUIT_SD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup BSP
+  * @{
+  */ 
+#define __IO    volatile   
+   
+/** @addtogroup STM32_ADAFRUIT
+  * @{
+  */
+    
+/** @defgroup STM32_ADAFRUIT_SD
+  * @{
+  */    
+
+/** @defgroup STM32_ADAFRUIT_SD_Exported_Types
+  * @{
+  */
+   
+/** 
+  * @brief  SD status structure definition  
+  */     
+enum {    
+      BSP_SD_OK = 0x00,      
+      MSD_OK = 0x00,
+      BSP_SD_ERROR = 0x01,
+      BSP_SD_TIMEOUT
+};
+   
+typedef struct              
+{
+  uint8_t  Reserved1:2;               /* Reserved */
+  uint16_t DeviceSize:12;             /* Device Size */
+  uint8_t  MaxRdCurrentVDDMin:3;      /* Max. read current @ VDD min */
+  uint8_t  MaxRdCurrentVDDMax:3;      /* Max. read current @ VDD max */
+  uint8_t  MaxWrCurrentVDDMin:3;      /* Max. write current @ VDD min */
+  uint8_t  MaxWrCurrentVDDMax:3;      /* Max. write current @ VDD max */
+  uint8_t  DeviceSizeMul:3;           /* Device size multiplier */
+} struct_v1;
+
+
+typedef struct              
+{
+  uint8_t  Reserved1:6;               /* Reserved */
+  uint32_t DeviceSize:22;             /* Device Size */
+  uint8_t  Reserved2:1;               /* Reserved */
+} struct_v2;
+
+/** 
+  * @brief  Card Specific Data: CSD Register
+  */ 
+typedef struct
+{
+  /* Header part */
+  uint8_t  CSDStruct:2;            /* CSD structure */
+  uint8_t  Reserved1:6;            /* Reserved */
+  uint8_t  TAAC:8;                 /* Data read access-time 1 */
+  uint8_t  NSAC:8;                 /* Data read access-time 2 in CLK cycles */
+  uint8_t  MaxBusClkFrec:8;        /* Max. bus clock frequency */
+  uint16_t CardComdClasses:12;      /* Card command classes */
+  uint8_t  RdBlockLen:4;           /* Max. read data block length */
+  uint8_t  PartBlockRead:1;        /* Partial blocks for read allowed */
+  uint8_t  WrBlockMisalign:1;      /* Write block misalignment */
+  uint8_t  RdBlockMisalign:1;      /* Read block misalignment */
+  uint8_t  DSRImpl:1;              /* DSR implemented */
+  
+  /* v1 or v2 struct */
+  union csd_version {
+    struct_v1 v1;
+    struct_v2 v2;
+  } version;
+  
+  uint8_t  EraseSingleBlockEnable:1;  /* Erase single block enable */
+  uint8_t  EraseSectorSize:7;         /* Erase group size multiplier */
+  uint8_t  WrProtectGrSize:7;         /* Write protect group size */
+  uint8_t  WrProtectGrEnable:1;       /* Write protect group enable */
+  uint8_t  Reserved2:2;               /* Reserved */
+  uint8_t  WrSpeedFact:3;             /* Write speed factor */
+  uint8_t  MaxWrBlockLen:4;           /* Max. write data block length */
+  uint8_t  WriteBlockPartial:1;       /* Partial blocks for write allowed */
+  uint8_t  Reserved3:5;               /* Reserved */
+  uint8_t  FileFormatGrouop:1;        /* File format group */
+  uint8_t  CopyFlag:1;                /* Copy flag (OTP) */
+  uint8_t  PermWrProtect:1;           /* Permanent write protection */
+  uint8_t  TempWrProtect:1;           /* Temporary write protection */
+  uint8_t  FileFormat:2;              /* File Format */
+  uint8_t  Reserved4:2;               /* Reserved */
+  uint8_t  crc:7;                     /* Reserved */
+  uint8_t  Reserved5:1;               /* always 1*/
+  
+} SD_CSD;
+
+/** 
+  * @brief  Card Identification Data: CID Register   
+  */
+typedef struct
+{
+  __IO uint8_t  ManufacturerID;       /* ManufacturerID */
+  __IO uint16_t OEM_AppliID;          /* OEM/Application ID */
+  __IO uint32_t ProdName1;            /* Product Name part1 */
+  __IO uint8_t  ProdName2;            /* Product Name part2*/
+  __IO uint8_t  ProdRev;              /* Product Revision */
+  __IO uint32_t ProdSN;               /* Product Serial Number */
+  __IO uint8_t  Reserved1;            /* Reserved1 */
+  __IO uint16_t ManufactDate;         /* Manufacturing Date */
+  __IO uint8_t  CID_CRC;              /* CID CRC */
+  __IO uint8_t  Reserved2;            /* always 1 */
+} SD_CID;
+
+/** 
+  * @brief SD Card information 
+  */
+typedef struct
+{
+  SD_CSD Csd;
+  SD_CID Cid;
+  uint32_t CardCapacity;  /* Card Capacity */
+  uint32_t CardBlockSize; /* Card Block Size */
+} SD_CardInfo;
+
+/**
+  * @}
+  */
+  
+/** @defgroup STM32_ADAFRUIT_SPI_SD_Exported_Constants
+  * @{
+  */ 
+  
+/**
+  * @brief  Block Size
+  */
+#define SD_BLOCK_SIZE    0x200
+
+/**
+  * @brief  SD detection on its memory slot
+  */
+#define SD_PRESENT               ((uint8_t)0x01)
+#define SD_NOT_PRESENT           ((uint8_t)0x00)
+   
+/**
+  * @}
+  */
+  
+/** @defgroup STM32_ADAFRUIT_SD_Exported_Macro
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+/** @defgroup STM32_ADAFRUIT_SD_Exported_Functions
+  * @{
+  */   
+uint8_t BSP_SD_Init(void);
+uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks);
+uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks);
+uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr);
+uint8_t BSP_SD_GetStatus(void);
+uint8_t BSP_SD_GetCardInfo(SD_CardInfo *pCardInfo);
+   
+/* Link functions for SD Card peripheral*/
+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);
+
+/* Link function for HAL delay */
+void HAL_Delay(__IO uint32_t Delay);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32_ADAFRUIT_SD_H */
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/Common/accelero.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,144 @@
+/**
+  ******************************************************************************
+  * @file    accelero.h
+  * @author  MCD Application Team
+  * @version V4.0.1
+  * @date    21-July-2015
+  * @brief   This header file contains the functions prototypes for the Accelerometer 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 __ACCELERO_H
+#define __ACCELERO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Components
+  * @{
+  */
+    
+/** @addtogroup ACCELERO
+  * @{
+  */
+
+/** @defgroup ACCELERO_Exported_Types
+  * @{
+  */ 
+
+/** @defgroup ACCELERO_Driver_structure  Accelerometer Driver structure
+  * @{
+  */
+typedef struct
+{  
+  void      (*Init)(uint16_t);
+  void      (*DeInit)(void); 
+  uint8_t   (*ReadID)(void);
+  void      (*Reset)(void);
+  void      (*LowPower)(void);
+  void      (*ConfigIT)(void);
+  void      (*EnableIT)(uint8_t);
+  void      (*DisableIT)(uint8_t);
+  uint8_t   (*ITStatus)(uint16_t);
+  void      (*ClearIT)(void);
+  void      (*FilterConfig)(uint8_t);
+  void      (*FilterCmd)(uint8_t);
+  void      (*GetXYZ)(int16_t *);
+}ACCELERO_DrvTypeDef;
+/**
+  * @}
+  */
+
+/** @defgroup ACCELERO_Configuration_structure  Accelerometer Configuration structure
+  * @{
+  */
+
+/* ACCELERO struct */
+typedef struct
+{
+  uint8_t Power_Mode;                         /* Power-down/Normal Mode */
+  uint8_t AccOutput_DataRate;                 /* OUT data rate */
+  uint8_t Axes_Enable;                        /* Axes enable */
+  uint8_t High_Resolution;                    /* High Resolution enabling/disabling */
+  uint8_t BlockData_Update;                   /* Block Data Update */
+  uint8_t Endianness;                         /* Endian Data selection */
+  uint8_t AccFull_Scale;                      /* Full Scale selection */
+  uint8_t Communication_Mode;
+}ACCELERO_InitTypeDef;
+
+/* ACCELERO High Pass Filter struct */
+typedef struct
+{
+  uint8_t HighPassFilter_Mode_Selection;      /* Internal filter mode */
+  uint8_t HighPassFilter_CutOff_Frequency;    /* High pass filter cut-off frequency */
+  uint8_t HighPassFilter_AOI1;                /* HPF_enabling/disabling for AOI function on interrupt 1 */
+  uint8_t HighPassFilter_AOI2;                /* HPF_enabling/disabling for AOI function on interrupt 2 */
+  uint8_t HighPassFilter_Data_Sel;
+  uint8_t HighPassFilter_Stat;
+}ACCELERO_FilterConfigTypeDef;
+
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ACCELERO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/Common/audio.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,123 @@
+/**
+  ******************************************************************************
+  * @file    audio.h
+  * @author  MCD Application Team
+  * @version V4.0.1
+  * @date    21-July-2015
+  * @brief   This header file contains the common defines and functions prototypes
+  *          for the Audio 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 __AUDIO_H
+#define __AUDIO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Components
+  * @{
+  */
+    
+/** @addtogroup AUDIO
+  * @{
+  */
+
+/** @defgroup AUDIO_Exported_Constants
+  * @{
+  */
+
+/* Codec audio Standards */
+#define CODEC_STANDARD                0x04
+#define I2S_STANDARD                  I2S_STANDARD_PHILIPS
+
+/**
+  * @}
+  */
+
+/** @defgroup AUDIO_Exported_Types
+  * @{
+  */
+
+/** @defgroup AUDIO_Driver_structure  Audio Driver structure
+  * @{
+  */
+typedef struct
+{
+  uint32_t  (*Init)(uint16_t, uint16_t, uint8_t, uint32_t);
+  void      (*DeInit)(void);
+  uint32_t  (*ReadID)(uint16_t);
+  uint32_t  (*Play)(uint16_t, uint16_t*, uint16_t);
+  uint32_t  (*Pause)(uint16_t);
+  uint32_t  (*Resume)(uint16_t);
+  uint32_t  (*Stop)(uint16_t, uint32_t);
+  uint32_t  (*SetFrequency)(uint16_t, uint32_t);
+  uint32_t  (*SetVolume)(uint16_t, uint8_t);
+  uint32_t  (*SetMute)(uint16_t, uint32_t);
+  uint32_t  (*SetOutputMode)(uint16_t, uint8_t);
+  uint32_t  (*Reset)(uint16_t);
+}AUDIO_DrvTypeDef;
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AUDIO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/Common/camera.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,142 @@
+/**
+  ******************************************************************************
+  * @file    camera.h
+  * @author  MCD Application Team
+  * @version V4.0.1
+  * @date    21-July-2015
+  * @brief   This header file contains the common defines and functions prototypes
+  *          for the camera 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 __CAMERA_H
+#define __CAMERA_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Components
+  * @{
+  */
+    
+/** @addtogroup CAMERA
+  * @{
+  */
+
+
+/** @defgroup CAMERA_Exported_Types
+  * @{
+  */ 
+
+/** @defgroup CAMERA_Driver_structure  Camera Driver structure
+  * @{
+  */
+typedef struct
+{
+  void     (*Init)(uint16_t, uint32_t);
+  uint16_t (*ReadID)(uint16_t);  
+  void     (*Config)(uint16_t, uint32_t, uint32_t, uint32_t);
+}CAMERA_DrvTypeDef;
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup CAMERA_Exported_Constants
+  * @{
+  */
+#define CAMERA_R160x120                 0x00   /* QQVGA Resolution                     */
+#define CAMERA_R320x240                 0x01   /* QVGA Resolution                      */
+#define CAMERA_R480x272                 0x02   /* 480x272 Resolution                   */
+#define CAMERA_R640x480                 0x03   /* VGA Resolution                       */  
+
+#define CAMERA_CONTRAST_BRIGHTNESS      0x00   /* Camera contrast brightness features  */
+#define CAMERA_BLACK_WHITE              0x01   /* Camera black white feature           */
+#define CAMERA_COLOR_EFFECT             0x03   /* Camera color effect feature          */
+
+#define CAMERA_BRIGHTNESS_LEVEL0        0x00   /* Brightness level -2         */
+#define CAMERA_BRIGHTNESS_LEVEL1        0x01   /* Brightness level -1         */
+#define CAMERA_BRIGHTNESS_LEVEL2        0x02   /* Brightness level 0          */
+#define CAMERA_BRIGHTNESS_LEVEL3        0x03   /* Brightness level +1         */
+#define CAMERA_BRIGHTNESS_LEVEL4        0x04   /* Brightness level +2         */
+
+#define CAMERA_CONTRAST_LEVEL0          0x05   /* Contrast level -2           */
+#define CAMERA_CONTRAST_LEVEL1          0x06   /* Contrast level -1           */
+#define CAMERA_CONTRAST_LEVEL2          0x07   /* Contrast level  0           */
+#define CAMERA_CONTRAST_LEVEL3          0x08   /* Contrast level +1           */
+#define CAMERA_CONTRAST_LEVEL4          0x09   /* Contrast level +2           */    
+    
+#define CAMERA_BLACK_WHITE_BW           0x00   /* Black and white effect      */
+#define CAMERA_BLACK_WHITE_NEGATIVE     0x01   /* Negative effect             */
+#define CAMERA_BLACK_WHITE_BW_NEGATIVE  0x02   /* BW and Negative effect      */
+#define CAMERA_BLACK_WHITE_NORMAL       0x03   /* Normal effect               */
+                                        
+#define CAMERA_COLOR_EFFECT_NONE        0x00   /* No effects                  */
+#define CAMERA_COLOR_EFFECT_BLUE        0x01   /* Blue effect                 */
+#define CAMERA_COLOR_EFFECT_GREEN       0x02   /* Green effect                */
+#define CAMERA_COLOR_EFFECT_RED         0x03   /* Red effect                  */
+#define CAMERA_COLOR_EFFECT_ANTIQUE     0x04   /* Antique effect              */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CAMERA_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/Common/epd.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,116 @@
+/**
+  ******************************************************************************
+  * @file    epd.h
+  * @author  MCD Application Team
+  * @version V4.0.1
+  * @date    21-July-2015
+  * @brief   This file contains all the functions prototypes for the 
+  *          EPD (E Paper Display) 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 __EPD_H
+#define __EPD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Components
+  * @{
+  */
+  
+/** @addtogroup Common
+  * @{
+  */
+
+/** @addtogroup EPD
+  * @{
+  */
+
+/** @defgroup EPD_Exported_Types
+  * @{
+  */
+
+/** @defgroup EPD_Driver_structure  E Paper Display Driver structure
+  * @{
+  */
+typedef struct
+{
+  void     (*Init)(void);
+  void     (*WritePixel)(uint8_t);
+
+  /* Optimized operation */
+  void     (*SetDisplayWindow)(uint16_t, uint16_t, uint16_t, uint16_t);
+  void     (*RefreshDisplay)(void);
+  void     (*CloseChargePump)(void);
+
+  uint16_t (*GetEpdPixelWidth)(void);
+  uint16_t (*GetEpdPixelHeight)(void);
+  void     (*DrawImage)(uint16_t, uint16_t, uint16_t, uint16_t, uint8_t*);
+}
+EPD_DrvTypeDef;
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EPD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/Common/gyro.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,146 @@
+/**
+  ******************************************************************************
+  * @file    gyro.h
+  * @author  MCD Application Team
+  * @version V4.0.1
+  * @date    21-July-2015
+  * @brief   This header file contains the functions prototypes for the gyroscope 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 __GYRO_H
+#define __GYRO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Components
+  * @{
+  */
+    
+/** @addtogroup GYRO
+  * @{
+  */
+
+/** @defgroup GYRO_Exported_Types
+  * @{
+  */
+
+/** @defgroup GYRO_Driver_structure  Gyroscope Driver structure
+  * @{
+  */
+typedef struct
+{  
+  void       (*Init)(uint16_t);
+  void       (*DeInit)(void); 
+  uint8_t    (*ReadID)(void);
+  void       (*Reset)(void);
+  void       (*LowPower)(uint16_t);   
+  void       (*ConfigIT)(uint16_t); 
+  void       (*EnableIT)(uint8_t);
+  void       (*DisableIT)(uint8_t);  
+  uint8_t    (*ITStatus)(uint16_t, uint16_t);   
+  void       (*ClearIT)(uint16_t, uint16_t); 
+  void       (*FilterConfig)(uint8_t);  
+  void       (*FilterCmd)(uint8_t);  
+  void       (*GetXYZ)(float *);
+}GYRO_DrvTypeDef;
+/**
+  * @}
+  */
+
+/** @defgroup GYRO_Config_structure  Gyroscope Configuration structure
+  * @{
+  */
+
+typedef struct
+{
+  uint8_t Power_Mode;                         /* Power-down/Sleep/Normal Mode */
+  uint8_t Output_DataRate;                    /* OUT data rate */
+  uint8_t Axes_Enable;                        /* Axes enable */
+  uint8_t Band_Width;                         /* Bandwidth selection */
+  uint8_t BlockData_Update;                   /* Block Data Update */
+  uint8_t Endianness;                         /* Endian Data selection */
+  uint8_t Full_Scale;                         /* Full Scale selection */
+}GYRO_InitTypeDef;
+
+/* GYRO High Pass Filter struct */
+typedef struct
+{
+  uint8_t HighPassFilter_Mode_Selection;      /* Internal filter mode */
+  uint8_t HighPassFilter_CutOff_Frequency;    /* High pass filter cut-off frequency */
+}GYRO_FilterConfigTypeDef;
+
+/*GYRO Interrupt struct */
+typedef struct
+{
+  uint8_t Latch_Request;                      /* Latch interrupt request into CLICK_SRC register */
+  uint8_t Interrupt_Axes;                     /* X, Y, Z Axes Interrupts */ 
+  uint8_t Interrupt_ActiveEdge;               /* Interrupt Active edge */
+}GYRO_InterruptConfigTypeDef;  
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __GYRO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/Common/idd.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,169 @@
+/**
+  ******************************************************************************
+  * @file    idd.h
+  * @author  MCD Application Team
+  * @version V4.0.1
+  * @date    21-July-2015
+  * @brief   This file contains all the functions prototypes for the IDD 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 __IDD_H
+#define __IDD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Components
+  * @{
+  */
+    
+/** @addtogroup IDD
+  * @{
+  */
+
+/** @defgroup IDD_Exported_Types IDD Exported Types
+  * @{
+  */
+
+/** @defgroup IDD_Config_structure  IDD Configuration structure
+  * @{
+  */
+typedef struct
+{
+  uint16_t AmpliGain;       /*!< Specifies ampli gain value
+                                 */
+  uint16_t VddMin;          /*!< Specifies minimum MCU VDD can reach to protect MCU from reset
+                                  */
+  uint16_t Shunt0Value;     /*!< Specifies value of Shunt 0 if existing
+                                 */
+  uint16_t Shunt1Value;     /*!< Specifies value of Shunt 1 if existing
+                                 */
+  uint16_t Shunt2Value;     /*!< Specifies value of Shunt 2 if existing
+                                 */
+  uint16_t Shunt3Value;     /*!< Specifies value of Shunt 3 if existing
+                                 */
+  uint16_t Shunt4Value;     /*!< Specifies value of Shunt 4 if existing
+                                  */
+  uint16_t Shunt0StabDelay; /*!< Specifies delay of Shunt 0 stabilization if existing
+                                  */
+  uint16_t Shunt1StabDelay; /*!< Specifies delay of Shunt 1 stabilization if existing
+                                  */
+  uint16_t Shunt2StabDelay; /*!< Specifies delay of Shunt 2 stabilization if existing
+                                  */
+  uint16_t Shunt3StabDelay; /*!< Specifies delay of Shunt 3 stabilization if existing
+                                  */
+  uint16_t Shunt4StabDelay; /*!< Specifies delay of Shunt 4 stabilization if existing
+                                  */
+  uint8_t ShuntNbOnBoard;   /*!< Specifies number of shunts that are present on board
+                                 This parameter can be a value of @ref IDD_shunt_number */
+  uint8_t ShuntNbUsed;      /*!< Specifies number of shunts used for measurement
+                                 This parameter can be a value of @ref IDD_shunt_number */
+  uint8_t VrefMeasurement;  /*!< Specifies if Vref is automatically measured before each Idd measurement
+                                 This parameter can be a value of @ref IDD_Vref_Measurement */
+  uint8_t Calibration;      /*!< Specifies if calibration is done before each Idd measurement
+                                  */
+  uint8_t PreDelayUnit;     /*!< Specifies Pre delay unit 
+                                 This parameter can be a value of @ref IDD_PreDelay */
+  uint8_t PreDelayValue;    /*!< Specifies Pre delay value in selected unit
+                                  */
+  uint8_t MeasureNb;        /*!< Specifies number of Measure to be performed 
+                                 This parameter can be a value between 1 and 256 */
+  uint8_t DeltaDelayUnit;   /*!< Specifies Delta delay unit
+                                  This parameter can be a value of @ref IDD_DeltaDelay */
+  uint8_t DeltaDelayValue;  /*!< Specifies Delta delay between 2 measures
+                                  value can be between 1 and 128 */
+}IDD_ConfigTypeDef;
+/**
+  * @}
+  */
+
+/** @defgroup IDD_Driver_structure  IDD Driver structure
+  * @{
+  */
+typedef struct
+{
+  void       (*Init)(uint16_t);
+  void       (*DeInit)(uint16_t);
+  uint16_t   (*ReadID)(uint16_t);
+  void       (*Reset)(uint16_t);
+  void       (*LowPower)(uint16_t);
+  void       (*WakeUp)(uint16_t);
+  void       (*Start)(uint16_t);
+  void       (*Config)(uint16_t,IDD_ConfigTypeDef);
+  void       (*GetValue)(uint16_t, uint32_t *);
+  void       (*EnableIT)(uint16_t);
+  void       (*ClearIT)(uint16_t);
+  uint8_t    (*GetITStatus)(uint16_t);
+  void       (*DisableIT)(uint16_t);
+  void       (*ErrorEnableIT)(uint16_t);
+  void       (*ErrorClearIT)(uint16_t);
+  uint8_t    (*ErrorGetITStatus)(uint16_t);
+  void       (*ErrorDisableIT)(uint16_t);
+  uint8_t    (*ErrorGetSrc)(uint16_t);
+  uint8_t    (*ErrorGetCode)(uint16_t);
+}IDD_DrvTypeDef;
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __IDD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/Common/io.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,151 @@
+/**
+  ******************************************************************************
+  * @file    io.h
+  * @author  MCD Application Team
+  * @version V4.0.1
+  * @date    21-July-2015
+  * @brief   This file contains all the functions prototypes for the IO 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 __IO_H
+#define __IO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Components
+  * @{
+  */
+    
+/** @addtogroup IO
+  * @{
+  */
+
+/** @defgroup IO_Exported_Types
+  * @{
+  */
+
+/**
+  * @brief  IO Bit SET and Bit RESET enumeration
+  */
+typedef enum
+{
+  IO_PIN_RESET = 0,
+  IO_PIN_SET
+}IO_PinState;
+
+typedef enum
+{
+   IO_MODE_INPUT = 0,   /* input floating */
+   IO_MODE_OUTPUT,      /* output Push Pull */
+   IO_MODE_IT_RISING_EDGE,   /* float input - irq detect on rising edge */
+   IO_MODE_IT_FALLING_EDGE,  /* float input - irq detect on falling edge */
+   IO_MODE_IT_LOW_LEVEL,     /* float input - irq detect on low level */
+   IO_MODE_IT_HIGH_LEVEL,    /* float input - irq detect on high level */
+   /* following modes only available on MFX*/
+   IO_MODE_ANALOG,           /* analog mode */
+   IO_MODE_OFF,              /* when pin isn't used*/
+   IO_MODE_INPUT_PU,         /* input with internal pull up resistor */
+   IO_MODE_INPUT_PD,         /* input with internal pull down resistor */
+   IO_MODE_OUTPUT_OD,          /* Open Drain output without internal resistor */
+   IO_MODE_OUTPUT_OD_PU,       /* Open Drain output with  internal pullup resistor */
+   IO_MODE_OUTPUT_OD_PD,       /* Open Drain output with  internal pulldown resistor */
+   IO_MODE_OUTPUT_PP,          /* PushPull output without internal resistor */
+   IO_MODE_OUTPUT_PP_PU,       /* PushPull output with  internal pullup resistor */
+   IO_MODE_OUTPUT_PP_PD,       /* PushPull output with  internal pulldown resistor */
+   IO_MODE_IT_RISING_EDGE_PU,   /* push up resistor input - irq on rising edge  */
+   IO_MODE_IT_RISING_EDGE_PD,   /* push dw resistor input - irq on rising edge  */
+   IO_MODE_IT_FALLING_EDGE_PU,  /* push up resistor input - irq on falling edge */
+   IO_MODE_IT_FALLING_EDGE_PD,  /* push dw resistor input - irq on falling edge */
+   IO_MODE_IT_LOW_LEVEL_PU,     /* push up resistor input - irq detect on low level */
+   IO_MODE_IT_LOW_LEVEL_PD,     /* push dw resistor input - irq detect on low level */
+   IO_MODE_IT_HIGH_LEVEL_PU,    /* push up resistor input - irq detect on high level */
+   IO_MODE_IT_HIGH_LEVEL_PD,    /* push dw resistor input - irq detect on high level */
+
+}IO_ModeTypedef;
+
+/** @defgroup IO_Driver_structure  IO Driver structure
+  * @{
+  */
+typedef struct
+{  
+  void       (*Init)(uint16_t);
+  uint16_t   (*ReadID)(uint16_t);
+  void       (*Reset)(uint16_t);
+  
+  void       (*Start)(uint16_t, uint32_t);
+  uint8_t    (*Config)(uint16_t, uint32_t, IO_ModeTypedef);
+  void       (*WritePin)(uint16_t, uint32_t, uint8_t);
+  uint32_t   (*ReadPin)(uint16_t, uint32_t);
+  
+  void       (*EnableIT)(uint16_t);
+  void       (*DisableIT)(uint16_t);
+  uint32_t    (*ITStatus)(uint16_t, uint32_t);
+  void       (*ClearIT)(uint16_t, uint32_t);
+    
+}IO_DrvTypeDef;
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __IO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/Common/lcd.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,115 @@
+/**
+  ******************************************************************************
+  * @file    lcd.h
+  * @author  MCD Application Team
+  * @version V4.0.1
+  * @date    21-July-2015
+  * @brief   This file contains all the functions prototypes for the LCD 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 __LCD_H
+#define __LCD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+   
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Components
+  * @{
+  */
+
+/** @addtogroup LCD
+  * @{
+  */
+ 
+/** @defgroup LCD_Exported_Types
+  * @{
+  */
+
+/** @defgroup LCD_Driver_structure  LCD Driver structure
+  * @{
+  */
+typedef struct
+{
+  void     (*Init)(void);
+  uint16_t (*ReadID)(void);
+  void     (*DisplayOn)(void);
+  void     (*DisplayOff)(void);
+  void     (*SetCursor)(uint16_t, uint16_t);
+  void     (*WritePixel)(uint16_t, uint16_t, uint16_t);
+  uint16_t (*ReadPixel)(uint16_t, uint16_t);
+  
+   /* Optimized operation */
+  void     (*SetDisplayWindow)(uint16_t, uint16_t, uint16_t, uint16_t);
+  void     (*DrawHLine)(uint16_t, uint16_t, uint16_t, uint16_t);
+  void     (*DrawVLine)(uint16_t, uint16_t, uint16_t, uint16_t);
+  
+  uint16_t (*GetLcdPixelWidth)(void);
+  uint16_t (*GetLcdPixelHeight)(void);
+  void     (*DrawBitmap)(uint16_t, uint16_t, uint8_t*);
+  void     (*DrawRGBImage)(uint16_t, uint16_t, uint16_t, uint16_t, uint8_t*);
+}LCD_DrvTypeDef;    
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LCD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/Common/magneto.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,126 @@
+/**
+  ******************************************************************************
+  * @file    magneto.h
+  * @author  MCD Application Team
+  * @version V4.0.1
+  * @date    21-July-2015
+  * @brief   This header file contains the functions prototypes for the MAGNETO 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 __MAGNETO_H
+#define __MAGNETO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Components
+  * @{
+  */
+    
+/** @addtogroup MAGNETO
+  * @{
+  */
+
+/** @defgroup MAGNETO_Exported_Types
+  * @{
+  */ 
+
+/** @defgroup MAGNETO_Config_structure  Magnetometer Configuration structure
+  * @{
+  */
+typedef struct
+{
+  uint8_t Register1;
+  uint8_t Register2;
+  uint8_t Register3;
+  uint8_t Register4;
+  uint8_t Register5;
+}MAGNETO_InitTypeDef;
+/**
+  * @}
+  */
+
+/** @defgroup MAGNETO_Driver_structure  Magnetometer Driver structure
+  * @{
+  */
+typedef struct
+{  
+  void      (*Init)(MAGNETO_InitTypeDef);
+  void      (*DeInit)(void); 
+  uint8_t   (*ReadID)(void);
+  void      (*Reset)(void);
+  void      (*LowPower)(void);
+  void      (*ConfigIT)(void);
+  void      (*EnableIT)(uint8_t);
+  void      (*DisableIT)(uint8_t);
+  uint8_t   (*ITStatus)(uint16_t);
+  void      (*ClearIT)(void);
+  void      (*FilterConfig)(uint8_t);
+  void      (*FilterCmd)(uint8_t);
+  void      (*GetXYZ)(int16_t *);
+}MAGNETO_DrvTypeDef;
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MAGNETO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/Common/ts.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,108 @@
+/**
+  ******************************************************************************
+  * @file    ts.h
+  * @author  MCD Application Team
+  * @version V4.0.1
+  * @date    21-July-2015
+  * @brief   This file contains all the functions prototypes for the Touch Screen 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 __TS_H
+#define __TS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h> 
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Components
+  * @{
+  */
+    
+/** @addtogroup TS
+  * @{
+  */
+
+/** @defgroup TS_Exported_Types
+  * @{
+  */
+
+/** @defgroup TS_Driver_structure  Touch Sensor Driver structure
+  * @{
+  */
+typedef struct
+{  
+  void       (*Init)(uint16_t);
+  uint16_t   (*ReadID)(uint16_t);
+  void       (*Reset)(uint16_t);
+  void       (*Start)(uint16_t);
+  uint8_t    (*DetectTouch)(uint16_t);
+  void       (*GetXY)(uint16_t, uint16_t*, uint16_t*);
+  void       (*EnableIT)(uint16_t);
+  void       (*ClearIT)(uint16_t);
+  uint8_t    (*GetITStatus)(uint16_t);
+  void       (*DisableIT)(uint16_t);
+}TS_DrvTypeDef;
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/Common/tsensor.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,119 @@
+/**
+  ******************************************************************************
+  * @file    tsensor.h
+  * @author  MCD Application Team
+  * @version V4.0.1
+  * @date    21-July-2015
+  * @brief   This header file contains the functions prototypes for the
+  *          Temperature Sensor 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 __TSENSOR_H
+#define __TSENSOR_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Components
+  * @{
+  */
+    
+/** @addtogroup TSENSOR
+  * @{
+  */
+
+/** @defgroup TSENSOR_Exported_Types
+  * @{
+  */ 
+
+/** @defgroup TSENSOR_Config_structure  Temperature Sensor Configuration structure
+  * @{
+  */
+typedef struct
+{
+  uint8_t AlertMode;            /* Alert Mode Temperature out of range*/
+  uint8_t ConversionMode;       /* Continuous/One Shot Mode */
+  uint8_t ConversionResolution; /* Temperature Resolution */
+  uint8_t ConversionRate;       /* Number of measure per second */
+  uint8_t TemperatureLimitHigh; /* High Temperature Limit Range */
+  uint8_t TemperatureLimitLow;  /* Low Temperature Limit Range */
+}TSENSOR_InitTypeDef;
+/**
+  * @}
+  */
+
+/** @defgroup TSENSOR_Driver_structure  Temperature Sensor Driver structure
+  * @{
+  */
+typedef struct
+{  
+  void       (*Init)(uint16_t, TSENSOR_InitTypeDef *);
+  uint8_t    (*IsReady)(uint16_t, uint32_t);
+  uint8_t    (*ReadStatus)(uint16_t);
+  uint16_t   (*ReadTemp)(uint16_t); 
+}TSENSOR_DrvTypeDef;
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TSENSOR_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/cs43l22/cs43l22.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,494 @@
+/**
+  ******************************************************************************
+  * @file    cs43l22.c
+  * @author  MCD Application Team
+  * @version V2.0.1
+  * @date    16-September-2015
+  * @brief   This file provides the CS43L22 Audio Codec 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.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "cs43l22.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+  
+/** @addtogroup Components
+  * @{
+  */ 
+
+/** @addtogroup cs43l22
+  * @brief     This file provides a set of functions needed to drive the 
+  *            CS43l22 audio codec.
+  * @{
+  */
+
+/** @defgroup CS43L22_Private_Types
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+  
+/** @defgroup CS43L22_Private_Defines
+  * @{
+  */
+/* Uncomment this line to enable verifying data sent to codec after each write 
+   operation (for debug purpose) */
+#if !defined (VERIFY_WRITTENDATA)  
+/* #define VERIFY_WRITTENDATA */
+#endif /* VERIFY_WRITTENDATA */
+/**
+  * @}
+  */ 
+
+/** @defgroup CS43L22_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+  
+/** @defgroup CS43L22_Private_Variables
+  * @{
+  */
+
+/* Audio codec driver structure initialization */  
+AUDIO_DrvTypeDef cs43l22_drv = 
+{
+  cs43l22_Init,
+  cs43l22_DeInit,
+  cs43l22_ReadID,
+
+  cs43l22_Play,
+  cs43l22_Pause,
+  cs43l22_Resume,
+  cs43l22_Stop,  
+  
+  cs43l22_SetFrequency,  
+  cs43l22_SetVolume,
+  cs43l22_SetMute,  
+  cs43l22_SetOutputMode,
+  cs43l22_Reset,
+};
+
+static uint8_t Is_cs43l22_Stop = 1;
+
+volatile uint8_t OutputDev = 0;
+
+/**
+  * @}
+  */ 
+
+/** @defgroup CS43L22_Function_Prototypes
+  * @{
+  */
+static uint8_t CODEC_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value);
+/**
+  * @}
+  */ 
+
+/** @defgroup CS43L22_Private_Functions
+  * @{
+  */ 
+
+/**
+  * @brief Initializes the audio codec and the control interface.
+  * @param DeviceAddr: Device address on communication Bus.   
+  * @param OutputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
+  *                       OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO .
+  * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t cs43l22_Init(uint16_t DeviceAddr, uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq)
+{
+  uint32_t counter = 0;
+  
+  /* Initialize the Control interface of the Audio Codec */
+  AUDIO_IO_Init();     
+    
+  /* Keep Codec powered OFF */
+  counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x01);  
+  
+  /*Save Output device for mute ON/OFF procedure*/
+  switch (OutputDevice)
+  {
+  case OUTPUT_DEVICE_SPEAKER:
+    OutputDev = 0xFA;
+    break;
+    
+  case OUTPUT_DEVICE_HEADPHONE:
+    OutputDev = 0xAF;
+    break;
+    
+  case OUTPUT_DEVICE_BOTH:
+    OutputDev = 0xAA;
+    break;
+    
+  case OUTPUT_DEVICE_AUTO:
+    OutputDev = 0x05;
+    break;    
+    
+  default:
+    OutputDev = 0x05;
+    break;    
+  }
+  
+  counter += CODEC_IO_Write(DeviceAddr, 0x04, OutputDev);
+  
+  /* Clock configuration: Auto detection */  
+  counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x81);
+  
+  /* Set the Slave Mode and the audio Standard */  
+  counter += CODEC_IO_Write(DeviceAddr, 0x06, CODEC_STANDARD);
+  
+  /* Set the Master volume */
+  counter += cs43l22_SetVolume(DeviceAddr, Volume);
+  
+  /* If the Speaker is enabled, set the Mono mode and volume attenuation level */
+  if(OutputDevice != OUTPUT_DEVICE_HEADPHONE)
+  {
+    /* Set the Speaker Mono mode */  
+    counter += CODEC_IO_Write(DeviceAddr, 0x0F , 0x06);
+    
+    /* Set the Speaker attenuation level */  
+    counter += CODEC_IO_Write(DeviceAddr, 0x24, 0x00);
+    counter += CODEC_IO_Write(DeviceAddr, 0x25, 0x00);
+  }
+  
+  /* Additional configuration for the CODEC. These configurations are done to reduce
+  the time needed for the Codec to power off. If these configurations are removed, 
+  then a long delay should be added between powering off the Codec and switching 
+  off the I2S peripheral MCLK clock (which is the operating clock for Codec).
+  If this delay is not inserted, then the codec will not shut down properly and
+  it results in high noise after shut down. */
+  
+  /* Disable the analog soft ramp */
+  counter += CODEC_IO_Write(DeviceAddr, 0x0A, 0x00);
+  /* Disable the digital soft ramp */
+  counter += CODEC_IO_Write(DeviceAddr, 0x0E, 0x04);
+  /* Disable the limiter attack level */
+  counter += CODEC_IO_Write(DeviceAddr, 0x27, 0x00);
+  /* Adjust Bass and Treble levels */
+  counter += CODEC_IO_Write(DeviceAddr, 0x1F, 0x0F);
+  /* Adjust PCM volume level */
+  counter += CODEC_IO_Write(DeviceAddr, 0x1A, 0x0A);
+  counter += CODEC_IO_Write(DeviceAddr, 0x1B, 0x0A);
+  
+  /* Return communication control value */
+  return counter;  
+}
+
+/**
+  * @brief  Deinitializes the audio codec.
+  * @param  None
+  * @retval  None
+  */
+void cs43l22_DeInit(void)
+{
+  /* Deinitialize Audio Codec interface */
+  AUDIO_IO_DeInit();
+}
+
+/**
+  * @brief  Get the CS43L22 ID.
+  * @param DeviceAddr: Device address on communication Bus.   
+  * @retval The CS43L22 ID 
+  */
+uint32_t cs43l22_ReadID(uint16_t DeviceAddr)
+{
+  uint8_t Value;
+  /* Initialize the Control interface of the Audio Codec */
+  AUDIO_IO_Init(); 
+  
+  Value = AUDIO_IO_Read(DeviceAddr, CS43L22_CHIPID_ADDR);
+  Value = (Value & CS43L22_ID_MASK);
+  
+  return((uint32_t) Value);
+}
+
+/**
+  * @brief Start the audio Codec play feature.
+  * @note For this codec no Play options are required.
+  * @param DeviceAddr: Device address on communication Bus.   
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t cs43l22_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size)
+{
+  uint32_t counter = 0;
+  
+  if(Is_cs43l22_Stop == 1)
+  {
+    /* Enable the digital soft ramp */
+    counter += CODEC_IO_Write(DeviceAddr, 0x0E, 0x06);
+  
+    /* Enable Output device */  
+    counter += cs43l22_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
+    
+    /* Power on the Codec */
+    counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x9E);  
+    Is_cs43l22_Stop = 0;
+  }
+  
+  /* Return communication control value */
+  return counter;  
+}
+
+/**
+  * @brief Pauses playing on the audio codec.
+  * @param DeviceAddr: Device address on communication Bus. 
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t cs43l22_Pause(uint16_t DeviceAddr)
+{  
+  uint32_t counter = 0;
+ 
+  /* Pause the audio file playing */
+  /* Mute the output first */
+  counter += cs43l22_SetMute(DeviceAddr, AUDIO_MUTE_ON);
+  
+  /* Put the Codec in Power save mode */    
+  counter += CODEC_IO_Write(DeviceAddr,0x02, 0x01);
+ 
+  return counter;
+}
+
+/**
+  * @brief Resumes playing on the audio codec.
+  * @param DeviceAddr: Device address on communication Bus. 
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t cs43l22_Resume(uint16_t DeviceAddr)
+{
+  uint32_t counter = 0;
+  volatile uint32_t index = 0x00;
+  /* Resumes the audio file playing */  
+  /* Unmute the output first */
+  counter += cs43l22_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
+
+  for(index = 0x00; index < 0xFF; index++);
+  
+  counter += CODEC_IO_Write(DeviceAddr,0x04, OutputDev);
+
+  /* Exit the Power save mode */
+  counter += CODEC_IO_Write(DeviceAddr,0x02, 0x9E); 
+  
+  return counter;
+}
+
+/**
+  * @brief Stops audio Codec playing. It powers down the codec.
+  * @param DeviceAddr: Device address on communication Bus. 
+  * @param CodecPdwnMode: selects the  power down mode.
+  *          - CODEC_PDWN_HW: Physically power down the codec. When resuming from this
+  *                           mode, the codec is set to default configuration 
+  *                           (user should re-Initialize the codec in order to 
+  *                            play again the audio stream).
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t cs43l22_Stop(uint16_t DeviceAddr, uint32_t CodecPdwnMode)
+{
+  uint32_t counter = 0;
+  
+  /* Mute the output first */
+  counter += cs43l22_SetMute(DeviceAddr, AUDIO_MUTE_ON);
+
+  /* Disable the digital soft ramp */
+  counter += CODEC_IO_Write(DeviceAddr, 0x0E, 0x04);
+  
+  /* Power down the DAC and the speaker (PMDAC and PMSPK bits)*/
+  counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x9F);
+  
+  Is_cs43l22_Stop = 1;
+  return counter;    
+}
+
+/**
+  * @brief Sets higher or lower the codec volume level.
+  * @param DeviceAddr: Device address on communication Bus.   
+  * @param Volume: a byte value from 0 to 255 (refer to codec registers 
+  *         description for more details).
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t cs43l22_SetVolume(uint16_t DeviceAddr, uint8_t Volume)
+{
+  uint32_t counter = 0;
+  uint8_t convertedvol = VOLUME_CONVERT(Volume);
+
+  if(Volume > 0xE6)
+  {
+    /* Set the Master volume */
+    counter += CODEC_IO_Write(DeviceAddr, 0x20, convertedvol - 0xE7); 
+    counter += CODEC_IO_Write(DeviceAddr, 0x21, convertedvol - 0xE7);     
+  }
+  else
+  {
+    /* Set the Master volume */
+    counter += CODEC_IO_Write(DeviceAddr, 0x20, convertedvol + 0x19); 
+    counter += CODEC_IO_Write(DeviceAddr, 0x21, convertedvol + 0x19); 
+  }
+
+  return counter;
+}
+
+/**
+  * @brief Sets new frequency.
+  * @param DeviceAddr: Device address on communication Bus.   
+  * @param AudioFreq: Audio frequency used to play the audio stream.
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t cs43l22_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq)
+{
+  return 0;
+}
+
+/**
+  * @brief Enables or disables the mute feature on the audio codec.
+  * @param DeviceAddr: Device address on communication Bus.   
+  * @param Cmd: AUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the
+  *             mute mode.
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t cs43l22_SetMute(uint16_t DeviceAddr, uint32_t Cmd)
+{
+  uint32_t counter = 0;
+  
+  /* Set the Mute mode */
+  if(Cmd == AUDIO_MUTE_ON)
+  {
+    counter += CODEC_IO_Write(DeviceAddr, 0x04, 0xFF);
+    counter += CODEC_IO_Write(DeviceAddr, 0x22, 0x01);
+    counter += CODEC_IO_Write(DeviceAddr, 0x23, 0x01);
+  }
+  else /* AUDIO_MUTE_OFF Disable the Mute */
+  {
+    counter += CODEC_IO_Write(DeviceAddr, 0x22, 0x00);
+    counter += CODEC_IO_Write(DeviceAddr, 0x23, 0x00);
+    counter += CODEC_IO_Write(DeviceAddr, 0x04, OutputDev);
+  }
+  return counter;
+}
+
+/**
+  * @brief Switch dynamically (while audio file is played) the output target 
+  *         (speaker or headphone).
+  * @note This function modifies a global variable of the audio codec driver: OutputDev.
+  * @param DeviceAddr: Device address on communication Bus.
+  * @param Output: specifies the audio output target: OUTPUT_DEVICE_SPEAKER,
+  *         OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO 
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t cs43l22_SetOutputMode(uint16_t DeviceAddr, uint8_t Output)
+{
+  uint32_t counter = 0; 
+  
+  switch (Output) 
+  {
+    case OUTPUT_DEVICE_SPEAKER:
+      counter += CODEC_IO_Write(DeviceAddr, 0x04, 0xFA); /* SPK always ON & HP always OFF */
+      OutputDev = 0xFA;
+      break;
+      
+    case OUTPUT_DEVICE_HEADPHONE:
+      counter += CODEC_IO_Write(DeviceAddr, 0x04, 0xAF); /* SPK always OFF & HP always ON */
+      OutputDev = 0xAF;
+      break;
+      
+    case OUTPUT_DEVICE_BOTH:
+      counter += CODEC_IO_Write(DeviceAddr, 0x04, 0xAA); /* SPK always ON & HP always ON */
+      OutputDev = 0xAA;
+      break;
+      
+    case OUTPUT_DEVICE_AUTO:
+      counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x05); /* Detect the HP or the SPK automatically */
+      OutputDev = 0x05;
+      break;    
+      
+    default:
+      counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x05); /* Detect the HP or the SPK automatically */
+      OutputDev = 0x05;
+      break;
+  }  
+  return counter;
+}
+
+/**
+  * @brief Resets cs43l22 registers.
+  * @param DeviceAddr: Device address on communication Bus. 
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t cs43l22_Reset(uint16_t DeviceAddr)
+{
+  return 0;
+}
+
+/**
+  * @brief  Writes/Read a single data.
+  * @param  Addr: I2C address
+  * @param  Reg: Reg address 
+  * @param  Value: Data to be written
+  * @retval None
+  */
+static uint8_t CODEC_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value)
+{
+  uint32_t result = 0;
+  
+  AUDIO_IO_Write(Addr, Reg, Value);
+  
+#ifdef VERIFY_WRITTENDATA
+  /* Verify that the data has been correctly written */  
+  result = (AUDIO_IO_Read(Addr, Reg) == Value)? 0:1;
+#endif /* VERIFY_WRITTENDATA */
+  
+  return result;
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/cs43l22/cs43l22.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,189 @@
+/**
+  ******************************************************************************
+  * @file    cs43l22.h
+  * @author  MCD Application Team
+  * @version V2.0.1
+  * @date    16-September-2015
+  * @brief   This file contains all the functions prototypes for the cs43l22.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 __CS43l22_H
+#define __CS43l22_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "../Common/audio.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup Component
+  * @{
+  */ 
+  
+/** @addtogroup CS43l22
+  * @{
+  */
+
+/** @defgroup CS43l22_Exported_Types
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup CS43l22_Exported_Constants
+  * @{
+  */ 
+
+/******************************************************************************/
+/***************************  Codec User defines ******************************/
+/******************************************************************************/
+/* Codec output DEVICE */
+#define OUTPUT_DEVICE_SPEAKER         1
+#define OUTPUT_DEVICE_HEADPHONE       2
+#define OUTPUT_DEVICE_BOTH            3
+#define OUTPUT_DEVICE_AUTO            4
+
+/* Volume Levels values */
+#define DEFAULT_VOLMIN                0x00
+#define DEFAULT_VOLMAX                0xFF
+#define DEFAULT_VOLSTEP               0x04
+
+#define AUDIO_PAUSE                   0
+#define AUDIO_RESUME                  1
+
+/* Codec POWER DOWN modes */
+#define CODEC_PDWN_HW                 1
+#define CODEC_PDWN_SW                 2
+
+/* MUTE commands */
+#define AUDIO_MUTE_ON                 1
+#define AUDIO_MUTE_OFF                0
+
+/* 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)  
+
+/******************************************************************************/
+/****************************** REGISTER MAPPING ******************************/
+/******************************************************************************/
+/** 
+  * @brief  CS43L22 ID  
+  */  
+#define  CS43L22_ID            0xE0
+#define  CS43L22_ID_MASK       0xF8
+/**
+  * @brief Chip ID Register: Chip I.D. and Revision Register
+  *  Read only register
+  *  Default value: 0x01
+  *  [7:3] CHIPID[4:0]: I.D. code for the CS43L22.
+  *        Default value: 11100b
+  *  [2:0] REVID[2:0]: CS43L22 revision level.
+  *        Default value: 
+  *        000 - Rev A0
+  *        001 - Rev A1
+  *        010 - Rev B0
+  *        011 - Rev B1
+  */
+#define CS43L22_CHIPID_ADDR    0x01
+
+/**
+  * @}
+  */ 
+
+/** @defgroup CS43l22_Exported_Macros
+  * @{
+  */
+#define VOLUME_CONVERT(Volume)    (((Volume) > 100)? 100:((uint8_t)(((Volume) * 255) / 100)))
+/**
+  * @}
+  */ 
+
+/** @defgroup CS43l22_Exported_Functions
+  * @{
+  */
+    
+/*------------------------------------------------------------------------------
+                           Audio Codec functions 
+------------------------------------------------------------------------------*/
+/* High Layer codec functions */
+uint32_t cs43l22_Init(uint16_t DeviceAddr, uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq);
+void     cs43l22_DeInit(void);
+uint32_t cs43l22_ReadID(uint16_t DeviceAddr);
+uint32_t cs43l22_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size);
+uint32_t cs43l22_Pause(uint16_t DeviceAddr);
+uint32_t cs43l22_Resume(uint16_t DeviceAddr);
+uint32_t cs43l22_Stop(uint16_t DeviceAddr, uint32_t Cmd);
+uint32_t cs43l22_SetVolume(uint16_t DeviceAddr, uint8_t Volume);
+uint32_t cs43l22_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq);
+uint32_t cs43l22_SetMute(uint16_t DeviceAddr, uint32_t Cmd);
+uint32_t cs43l22_SetOutputMode(uint16_t DeviceAddr, uint8_t Output);
+uint32_t cs43l22_Reset(uint16_t DeviceAddr);
+
+/* AUDIO IO functions */
+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);
+
+/* Audio driver structure */
+extern AUDIO_DrvTypeDef   cs43l22_drv;
+
+#endif /* __CS43l22_H */
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */ 
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/hx8347g/hx8347g.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,482 @@
+/**
+  ******************************************************************************
+  * @file    hx8347g.c
+  * @author  MCD Application Team
+  * @version V1.1.0
+  * @date    10-February-2015
+  * @brief   This file includes the LCD driver for HX8347G LCD.
+  ******************************************************************************
+  * @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 "hx8347g.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup Components
+  * @{
+  */ 
+  
+/** @addtogroup HX8347G
+  * @brief     This file provides a set of functions needed to drive the 
+  *            HX8347G LCD.
+  * @{
+  */
+
+/** @defgroup HX8347G_Private_TypesDefinitions
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+/** @defgroup HX8347G_Private_Defines
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+  
+/** @defgroup HX8347G_Private_Macros
+  * @{
+  */
+     
+/**
+  * @}
+  */  
+
+/** @defgroup HX8347G_Private_Variables
+  * @{
+  */ 
+LCD_DrvTypeDef   hx8347g_drv = 
+{
+  hx8347g_Init,
+  hx8347g_ReadID,
+  hx8347g_DisplayOn,
+  hx8347g_DisplayOff,
+  hx8347g_SetCursor,
+  hx8347g_WritePixel,
+  hx8347g_ReadPixel,
+  hx8347g_SetDisplayWindow,
+  hx8347g_DrawHLine,
+  hx8347g_DrawVLine,
+  hx8347g_GetLcdPixelWidth,
+  hx8347g_GetLcdPixelHeight,
+  hx8347g_DrawBitmap,  
+};
+
+static uint8_t Is_hx8347g_Initialized = 0;
+static uint16_t ArrayRGB[320] = {0};
+
+/**
+  * @}
+  */ 
+  
+/** @defgroup HX8347G_Private_FunctionPrototypes
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+  
+/** @defgroup HX8347G_Private_Functions
+  * @{
+  */   
+
+/**
+  * @brief  Initialise the HX8347G LCD Component.
+  * @param  None
+  * @retval None
+  */
+void hx8347g_Init(void)
+{  
+  if(Is_hx8347g_Initialized == 0)
+  {
+    Is_hx8347g_Initialized = 1;
+    /* Initialise HX8347G low level bus layer --------------------------------*/
+    LCD_IO_Init();
+    
+    /* Driving ability setting */
+    hx8347g_WriteReg(LCD_REG_234, 0x00);
+    hx8347g_WriteReg(LCD_REG_235, 0x20);
+    hx8347g_WriteReg(LCD_REG_236, 0x0C);
+    hx8347g_WriteReg(LCD_REG_237, 0xC4);
+    hx8347g_WriteReg(LCD_REG_232, 0x40);
+    hx8347g_WriteReg(LCD_REG_233, 0x38);
+    hx8347g_WriteReg(LCD_REG_241, 0x01);
+    hx8347g_WriteReg(LCD_REG_242, 0x10);
+    hx8347g_WriteReg(LCD_REG_39, 0xA3);
+
+    /* Adjust the Gamma Curve */
+    hx8347g_WriteReg(LCD_REG_64, 0x01);
+    hx8347g_WriteReg(LCD_REG_65, 0x00);
+    hx8347g_WriteReg(LCD_REG_66, 0x00);
+    hx8347g_WriteReg(LCD_REG_67, 0x10);
+    hx8347g_WriteReg(LCD_REG_68, 0x0E);
+    hx8347g_WriteReg(LCD_REG_69, 0x24);
+    hx8347g_WriteReg(LCD_REG_70, 0x04);
+    hx8347g_WriteReg(LCD_REG_71, 0x50);
+    hx8347g_WriteReg(LCD_REG_72, 0x02);
+    hx8347g_WriteReg(LCD_REG_73, 0x13);
+    hx8347g_WriteReg(LCD_REG_74, 0x19);
+    hx8347g_WriteReg(LCD_REG_75, 0x19);
+    hx8347g_WriteReg(LCD_REG_76, 0x16);
+    hx8347g_WriteReg(LCD_REG_80, 0x1B);
+    hx8347g_WriteReg(LCD_REG_81, 0x31);
+    hx8347g_WriteReg(LCD_REG_82, 0x2F);
+    hx8347g_WriteReg(LCD_REG_83, 0x3F);
+    hx8347g_WriteReg(LCD_REG_84, 0x3F);
+    hx8347g_WriteReg(LCD_REG_85, 0x3E);
+    hx8347g_WriteReg(LCD_REG_86, 0x2F);
+    hx8347g_WriteReg(LCD_REG_87, 0x7B);
+    hx8347g_WriteReg(LCD_REG_88, 0x09);
+    hx8347g_WriteReg(LCD_REG_89, 0x06);
+    hx8347g_WriteReg(LCD_REG_90, 0x06);
+    hx8347g_WriteReg(LCD_REG_91, 0x0C);
+    hx8347g_WriteReg(LCD_REG_92, 0x1D);
+    hx8347g_WriteReg(LCD_REG_93, 0xCC);
+
+    /* Power voltage setting */
+    hx8347g_WriteReg(LCD_REG_27, 0x1B);
+    hx8347g_WriteReg(LCD_REG_26, 0x01);
+    hx8347g_WriteReg(LCD_REG_36, 0x2F);
+    hx8347g_WriteReg(LCD_REG_37, 0x57);
+    /*****VCOM offset ****/
+    hx8347g_WriteReg(LCD_REG_35, 0x86);
+
+    hx8347g_DisplayOn();
+
+    /* Set GRAM Area - Partial Display Control */
+    hx8347g_WriteReg(LCD_REG_1, 0x00); /* DP_STB = 0, DP_STB_S = 0, SCROLL = 0, */
+    hx8347g_SetDisplayWindow(0, 0, hx8347g_GetLcdPixelWidth(), hx8347g_GetLcdPixelHeight());
+    hx8347g_WriteReg(LCD_REG_22, 0xA0); /* Memory access control: MY = 1, MX = 0, MV = 1, ML = 0 */
+  }
+  
+  /* Set the Cursor */ 
+  hx8347g_SetCursor(0, 0);
+    
+  /* Prepare to write GRAM */
+  LCD_IO_WriteReg(LCD_REG_34);
+}
+
+/**
+  * @brief  Enables the Display.
+  * @param  None
+  * @retval None
+  */
+void hx8347g_DisplayOn(void)
+{
+  /* Power On sequence ---------------------------------------------------------*/
+  hx8347g_WriteReg(LCD_REG_24, 0x36); /* Display frame rate = 70Hz RADJ = '0110' */
+  hx8347g_WriteReg(LCD_REG_25, 0x01); /* OSC_EN = 1 */
+  hx8347g_WriteReg(LCD_REG_28, 0x06); /* AP[2:0] = 111 */
+  hx8347g_WriteReg(LCD_REG_31, 0x90); /* GAS=1, VOMG=00, PON=1, DK=0, XDK=0, DVDH_TRI=0, STB=0*/
+  LCD_Delay(10);
+  /* 262k/65k color selection */
+  hx8347g_WriteReg(LCD_REG_23, 0x05); /* default 0x06 262k color,  0x05 65k color */
+  /* SET PANEL */
+  hx8347g_WriteReg(LCD_REG_54, 0x09); /* SS_PANEL = 1, GS_PANEL = 0,REV_PANEL = 0, BGR_PANEL = 1 */
+ 
+  /* Display On */
+  hx8347g_WriteReg(LCD_REG_40, 0x38);
+  LCD_Delay(60);
+  hx8347g_WriteReg(LCD_REG_40, 0x3C);
+}
+
+/**
+  * @brief  Disables the Display.
+  * @param  None
+  * @retval None
+  */
+void hx8347g_DisplayOff(void)
+{
+  /* Display Off */
+  hx8347g_WriteReg(LCD_REG_40, 0x38);
+  LCD_Delay(60);
+  hx8347g_WriteReg(LCD_REG_40, 0x04);
+
+  /* Power Off sequence ---------------------------------------------------------*/
+  hx8347g_WriteReg(LCD_REG_23, 0x0000); /* default 0x06 262k color,  0x05 65k color */
+  hx8347g_WriteReg(LCD_REG_24, 0x0000); /* Display frame rate = 70Hz RADJ = '0110' */
+  hx8347g_WriteReg(LCD_REG_25, 0x0000); /* OSC_EN = 1 */
+  hx8347g_WriteReg(LCD_REG_28, 0x0000); /* AP[2:0] = 111 */
+  hx8347g_WriteReg(LCD_REG_31, 0x0000); /* GAS=1, VOMG=00, PON=1, DK=0, XDK=0, DVDH_TRI=0, STB=0*/
+  hx8347g_WriteReg(LCD_REG_54, 0x0000); /* SS_PANEL = 1, GS_PANEL = 0,REV_PANEL = 0, BGR_PANEL = 1 */
+}
+
+/**
+  * @brief  Get the LCD pixel Width.
+  * @param  None
+  * @retval The Lcd Pixel Width
+  */
+uint16_t hx8347g_GetLcdPixelWidth(void)
+{
+ return (uint16_t)HX8347G_LCD_PIXEL_WIDTH;
+}
+
+/**
+  * @brief  Get the LCD pixel Height.
+  * @param  None
+  * @retval The Lcd Pixel Height
+  */
+uint16_t hx8347g_GetLcdPixelHeight(void)
+{
+ return (uint16_t)HX8347G_LCD_PIXEL_HEIGHT;
+}
+
+/**
+  * @brief  Get the HX8347G ID.
+  * @param  None
+  * @retval The HX8347G ID 
+  */
+uint16_t hx8347g_ReadID(void)
+{
+  if(Is_hx8347g_Initialized == 0)
+  {
+    LCD_IO_Init();
+  }
+  return (hx8347g_ReadReg(0x00));
+}
+
+/**
+  * @brief  Set Cursor position.
+  * @param  Xpos: specifies the X position.
+  * @param  Ypos: specifies the Y position.
+  * @retval None
+  */
+void hx8347g_SetCursor(uint16_t Xpos, uint16_t Ypos)
+{
+  hx8347g_WriteReg(LCD_REG_6, 0x00);
+  hx8347g_WriteReg(LCD_REG_7, Xpos);
+  hx8347g_WriteReg(LCD_REG_2, Ypos >> 8);
+  hx8347g_WriteReg(LCD_REG_3, Ypos & 0xFF);
+}
+
+/**
+  * @brief  Write pixel.   
+  * @param  Xpos: specifies the X position.
+  * @param  Ypos: specifies the Y position.
+* @param  RGBCode: the RGB pixel color
+  * @retval None
+  */
+void hx8347g_WritePixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGBCode)
+{
+  /* Set Cursor */
+  hx8347g_SetCursor(Xpos, Ypos);
+  
+  /* Prepare to write GRAM */
+  LCD_IO_WriteReg(LCD_REG_34);
+
+  /* Write 16-bit GRAM Reg */
+  LCD_IO_WriteMultipleData((uint8_t*)&RGBCode, 2);
+}
+
+/**
+  * @brief  Read pixel.
+  * @param  None
+  * @retval the RGB pixel color
+  */
+uint16_t hx8347g_ReadPixel(uint16_t Xpos, uint16_t Ypos)
+{
+  /* Set Cursor */
+  hx8347g_SetCursor(Xpos, Ypos);
+
+  /* Dummy read */
+  LCD_IO_ReadData(LCD_REG_34);
+  
+  /* Read 16-bit Reg */
+  return (LCD_IO_ReadData(LCD_REG_34));
+}
+
+/**
+  * @brief  Writes to the selected LCD register.
+* @param  LCDReg:      address of the selected register.
+* @param  LCDRegValue: value to write to the selected register.
+  * @retval None
+  */
+void hx8347g_WriteReg(uint8_t LCDReg, uint16_t LCDRegValue)
+{
+  LCD_IO_WriteReg(LCDReg);
+  
+  /* Write 16-bit GRAM Reg */
+  LCD_IO_WriteMultipleData((uint8_t*)&LCDRegValue, 2);
+}
+
+/**
+  * @brief  Reads the selected LCD Register.
+* @param  LCDReg: address of the selected register.
+  * @retval LCD Register Value.
+  */
+uint16_t hx8347g_ReadReg(uint8_t LCDReg)
+{
+  /* Read 16-bit Reg */
+  return (LCD_IO_ReadData(LCDReg));
+}
+
+/**
+  * @brief  Sets a display window
+  * @param  Xpos:   specifies the X bottom left position.
+  * @param  Ypos:   specifies the Y bottom left position.
+  * @param  Height: display window height.
+  * @param  Width:  display window width.
+  * @retval None
+  */
+void hx8347g_SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
+{
+  /* Horizontal GRAM Start Address */
+  hx8347g_WriteReg(LCD_REG_6, (Xpos) >> 8); /* SP */
+  hx8347g_WriteReg(LCD_REG_7, (Xpos) & 0xFF); /* SP */
+
+  /* Horizontal GRAM End Address */
+  hx8347g_WriteReg(LCD_REG_8, (Xpos + Height - 1) >> 8); /* EP */
+  hx8347g_WriteReg(LCD_REG_9, (Xpos + Height - 1) & 0xFF); /* EP */
+
+  /* Vertical GRAM Start Address */
+  hx8347g_WriteReg(LCD_REG_2, (Ypos) >> 8); /* SC */
+  hx8347g_WriteReg(LCD_REG_3, (Ypos) & 0xFF); /* SC */
+
+  /* Vertical GRAM End Address */
+  hx8347g_WriteReg(LCD_REG_4, (Ypos + Width - 1) >> 8); /* EC */
+  hx8347g_WriteReg(LCD_REG_5, (Ypos + Width - 1) & 0xFF); /* EC */
+}
+
+/**
+  * @brief  Draw vertical line.
+* @param  RGBCode: Specifies the RGB color   
+  * @param  Xpos:     specifies the X position.
+  * @param  Ypos:     specifies the Y position.
+  * @param  Length:   specifies the Line length.  
+  * @retval None
+  */
+void hx8347g_DrawHLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length)
+{
+  uint32_t i = 0;
+  
+  /* Set Cursor */
+  hx8347g_SetCursor(Xpos, Ypos); 
+  
+  /* Prepare to write GRAM */
+  LCD_IO_WriteReg(LCD_REG_34);
+
+  /* Sent a complete line */
+  for(i = 0; i < Length; i++)
+  {
+    ArrayRGB[i] = RGBCode;
+  }  
+
+  LCD_IO_WriteMultipleData((uint8_t*)&ArrayRGB[0], Length * 2);
+}
+
+/**
+  * @brief  Draw vertical line.
+* @param  RGBCode: Specifies the RGB color    
+  * @param  Xpos:     specifies the X position.
+  * @param  Ypos:     specifies the Y position.
+  * @param  Length:   specifies the Line length.  
+  * @retval None
+  */
+void hx8347g_DrawVLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length)
+{
+  uint16_t counter = 0;
+  
+  /* Set Cursor */
+  hx8347g_SetCursor(Xpos, Ypos);
+
+  /* Prepare to write GRAM */
+  LCD_IO_WriteReg(LCD_REG_34);
+
+  /* Fill a complete vertical line */
+  for(counter = 0; counter < Length; counter++)
+  {
+    ArrayRGB[counter] = RGBCode;
+  }
+  
+  /* Write 16-bit GRAM Reg */
+  LCD_IO_WriteMultipleData((uint8_t*)&ArrayRGB[0], Length * 2);
+}
+
+/**
+  * @brief  Displays a bitmap picture loaded in the internal Flash.
+  * @param  BmpAddress: Bmp picture address in the internal Flash.
+  * @retval None
+  */
+void hx8347g_DrawBitmap(uint16_t Xpos, uint16_t Ypos, uint8_t *pbmp)
+{
+  uint32_t index = 0, size = 0;
+  
+  /* Read bitmap size */
+  size = *(volatile uint16_t *) (pbmp + 2);
+  size |= (*(volatile uint16_t *) (pbmp + 4)) << 16;
+  /* Get bitmap data address offset */
+  index = *(volatile uint16_t *) (pbmp + 10);
+  index |= (*(volatile uint16_t *) (pbmp + 12)) << 16;
+  size = (size - index)/2;
+  pbmp += index;
+  
+  /* Set GRAM write direction and BGR = 0 */
+  /* Memory access control: MY = 1, MX = 0, MV = 1, ML = 0 */
+  hx8347g_WriteReg(LCD_REG_22, 0xE0);
+
+  /* Set Cursor */
+  hx8347g_SetCursor(Xpos, Ypos);  
+  
+  /* Prepare to write GRAM */
+  LCD_IO_WriteReg(LCD_REG_34);
+ 
+  LCD_IO_WriteMultipleData((uint8_t*)pbmp, size*2);
+ 
+  /* Set GRAM write direction and BGR = 0 */
+  /* Memory access control: MY = 1, MX = 1, MV = 1, ML = 0 */
+  hx8347g_WriteReg(LCD_REG_22, 0xA0);
+}
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+  
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+  
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/hx8347g/hx8347g.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,275 @@
+/**
+  ******************************************************************************
+  * @file    hx8347g.h
+  * @author  MCD Application Team
+  * @version V1.1.0
+  * @date    10-February-2015
+  * @brief   This file contains all the functions prototypes for the hx8347g.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 __HX8347G_H
+#define __HX8347G_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+/* Includes ------------------------------------------------------------------*/
+#include "../Common/lcd.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup Components
+  * @{
+  */ 
+  
+/** @addtogroup hx8347g
+  * @{
+  */
+
+/** @defgroup HX8347G_Exported_Types
+  * @{
+  */
+   
+/**
+  * @}
+  */ 
+
+/** @defgroup HX8347G_Exported_Constants
+  * @{
+  */
+/** 
+  * @brief  HX8347G ID  
+  */  
+#define  HX8347G_ID    0x0075
+   
+/** 
+  * @brief  HX8347G Size  
+  */  
+#define  HX8347G_LCD_PIXEL_WIDTH    ((uint16_t)320)
+#define  HX8347G_LCD_PIXEL_HEIGHT   ((uint16_t)240)
+   
+/** 
+  * @brief  HX8347G Registers  
+  */ 
+#define LCD_REG_0             0x00
+#define LCD_REG_1             0x01
+#define LCD_REG_2             0x02
+#define LCD_REG_3             0x03
+#define LCD_REG_4             0x04
+#define LCD_REG_5             0x05
+#define LCD_REG_6             0x06
+#define LCD_REG_7             0x07
+#define LCD_REG_8             0x08
+#define LCD_REG_9             0x09
+#define LCD_REG_10            0x0A
+#define LCD_REG_11            0x0B
+#define LCD_REG_12            0x0C
+#define LCD_REG_13            0x0D
+#define LCD_REG_14            0x0E
+#define LCD_REG_15            0x0F
+#define LCD_REG_16            0x10
+#define LCD_REG_17            0x11
+#define LCD_REG_18            0x12
+#define LCD_REG_19            0x13
+#define LCD_REG_20            0x14
+#define LCD_REG_21            0x15
+#define LCD_REG_22            0x16
+#define LCD_REG_23            0x17
+#define LCD_REG_24            0x18
+#define LCD_REG_25            0x19
+#define LCD_REG_26            0x1A
+#define LCD_REG_27            0x1B
+#define LCD_REG_28            0x1C
+#define LCD_REG_29            0x1D
+#define LCD_REG_30            0x1E
+#define LCD_REG_31            0x1F
+#define LCD_REG_32            0x20
+#define LCD_REG_33            0x21
+#define LCD_REG_34            0x22
+#define LCD_REG_35            0x23
+#define LCD_REG_36            0x24
+#define LCD_REG_37            0x25
+#define LCD_REG_38            0x26
+#define LCD_REG_39            0x27
+#define LCD_REG_40            0x28
+#define LCD_REG_41            0x29
+#define LCD_REG_42            0x2A
+#define LCD_REG_43            0x2B
+#define LCD_REG_44            0x2C
+#define LCD_REG_45            0x2D
+#define LCD_REG_46            0x2E
+#define LCD_REG_47            0x2F
+#define LCD_REG_48            0x30
+#define LCD_REG_49            0x31
+#define LCD_REG_50            0x32
+#define LCD_REG_51            0x33
+#define LCD_REG_52            0x34
+#define LCD_REG_53            0x35
+#define LCD_REG_54            0x36
+#define LCD_REG_55            0x37
+#define LCD_REG_56            0x38
+#define LCD_REG_57            0x39
+#define LCD_REG_58            0x3A
+#define LCD_REG_59            0x3B
+#define LCD_REG_60            0x3C
+#define LCD_REG_61            0x3D
+#define LCD_REG_62            0x3E
+#define LCD_REG_63            0x3F
+#define LCD_REG_64            0x40
+#define LCD_REG_65            0x41
+#define LCD_REG_66            0x42
+#define LCD_REG_67            0x43
+#define LCD_REG_68            0x44
+#define LCD_REG_69            0x45
+#define LCD_REG_70            0x46
+#define LCD_REG_71            0x47
+#define LCD_REG_72            0x48
+#define LCD_REG_73            0x49
+#define LCD_REG_74            0x4A
+#define LCD_REG_75            0x4B
+#define LCD_REG_76            0x4C
+#define LCD_REG_77            0x4D
+#define LCD_REG_78            0x4E
+#define LCD_REG_79            0x4F
+#define LCD_REG_80            0x50
+#define LCD_REG_81            0x51
+#define LCD_REG_82            0x52
+#define LCD_REG_83            0x53
+#define LCD_REG_84            0x54
+#define LCD_REG_85            0x55
+#define LCD_REG_86            0x56
+#define LCD_REG_87            0x57
+#define LCD_REG_88            0x58
+#define LCD_REG_89            0x59
+#define LCD_REG_90            0x5A
+#define LCD_REG_91            0x5B
+#define LCD_REG_92            0x5C
+#define LCD_REG_93            0x5D
+#define LCD_REG_94            0x5E
+#define LCD_REG_95            0x5F
+#define LCD_REG_96            0x60
+#define LCD_REG_97            0x61
+#define LCD_REG_98            0x62
+#define LCD_REG_99            0x63
+#define LCD_REG_104           0x68
+#define LCD_REG_105           0x69
+#define LCD_REG_112           0x70
+#define LCD_REG_113           0x71
+#define LCD_REG_132           0x84
+#define LCD_REG_133           0x85
+#define LCD_REG_195           0xC3
+#define LCD_REG_197           0xC5
+#define LCD_REG_199           0xC7
+#define LCD_REG_203           0xCB
+#define LCD_REG_204           0xCC
+#define LCD_REG_205           0xCD
+#define LCD_REG_206           0xCE
+#define LCD_REG_207           0xCF
+#define LCD_REG_208           0xD0
+#define LCD_REG_209           0xD1
+#define LCD_REG_210           0xD2
+#define LCD_REG_211           0xD3
+#define LCD_REG_232           0xE8
+#define LCD_REG_233           0xE9
+#define LCD_REG_234           0xEA
+#define LCD_REG_235           0xEB
+#define LCD_REG_236           0xEC
+#define LCD_REG_237           0xED
+#define LCD_REG_241           0xF1
+#define LCD_REG_242           0xF2
+#define LCD_REG_255           0xFF
+
+/**
+  * @}
+  */
+  
+/** @defgroup HX8347G_Exported_Functions
+  * @{
+  */ 
+void     hx8347g_Init(void);
+uint16_t hx8347g_ReadID(void);
+void     hx8347g_WriteReg(uint8_t LCDReg, uint16_t LCDRegValue);
+uint16_t hx8347g_ReadReg(uint8_t LCDReg);
+
+void     hx8347g_DisplayOn(void);
+void     hx8347g_DisplayOff(void);
+void     hx8347g_SetCursor(uint16_t Xpos, uint16_t Ypos);
+void     hx8347g_WritePixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGBCode);
+uint16_t hx8347g_ReadPixel(uint16_t Xpos, uint16_t Ypos);
+
+void     hx8347g_DrawHLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length);
+void     hx8347g_DrawVLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length);
+void     hx8347g_DrawBitmap(uint16_t Xpos, uint16_t Ypos, uint8_t *pbmp);
+
+void     hx8347g_SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+
+
+uint16_t hx8347g_GetLcdPixelWidth(void);
+uint16_t hx8347g_GetLcdPixelHeight(void);
+
+/* LCD driver structure */
+extern LCD_DrvTypeDef   hx8347g_drv;
+
+/* LCD IO functions */
+void     LCD_IO_Init(void);
+void     LCD_IO_WriteMultipleData(uint8_t *pData, uint32_t Size);
+void     LCD_IO_WriteReg(uint8_t Reg);
+uint16_t LCD_IO_ReadData(uint16_t Reg);
+void     LCD_Delay (uint32_t delay);
+/**
+  * @}
+  */ 
+      
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HX8347G_H */
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+  
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/l3gd20/l3gd20.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,417 @@
+/**
+  ******************************************************************************
+  * @file    l3gd20.c
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    26-June-2015
+  * @brief   This file provides a set of functions needed to manage the L3GD20,
+  *          ST MEMS motion sensor, 3-axis digital output gyroscope.  
+  ******************************************************************************
+  * @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 "l3gd20.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup Components
+  * @{
+  */ 
+
+/** @addtogroup L3GD20
+  * @{
+  */
+
+/** @defgroup L3GD20_Private_TypesDefinitions
+  * @{
+  */
+  
+/**
+  * @}
+  */
+
+/** @defgroup L3GD20_Private_Defines
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup L3GD20_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+  
+/** @defgroup L3GD20_Private_Variables
+  * @{
+  */ 
+GYRO_DrvTypeDef L3gd20Drv =
+{
+  L3GD20_Init,
+  L3GD20_DeInit,
+  L3GD20_ReadID,
+  L3GD20_RebootCmd,
+  L3GD20_LowPower,
+  L3GD20_INT1InterruptConfig,
+  L3GD20_EnableIT,
+  L3GD20_DisableIT,
+  0,
+  0,
+  L3GD20_FilterConfig,
+  L3GD20_FilterCmd,
+  L3GD20_ReadXYZAngRate
+};
+
+/**
+  * @}
+  */
+
+/** @defgroup L3GD20_Private_FunctionPrototypes
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup L3GD20_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Set L3GD20 Initialization.
+  * @param  L3GD20_InitStruct: pointer to a L3GD20_InitTypeDef structure 
+  *         that contains the configuration setting for the L3GD20.
+  * @retval None
+  */
+void L3GD20_Init(uint16_t InitStruct)
+{  
+  uint8_t ctrl = 0x00;
+  
+  /* Configure the low level interface */
+  GYRO_IO_Init();
+  
+  /* Write value to MEMS CTRL_REG1 register */
+  ctrl = (uint8_t) InitStruct;
+  GYRO_IO_Write(&ctrl, L3GD20_CTRL_REG1_ADDR, 1);
+  
+  /* Write value to MEMS CTRL_REG4 register */  
+  ctrl = (uint8_t) (InitStruct >> 8);
+  GYRO_IO_Write(&ctrl, L3GD20_CTRL_REG4_ADDR, 1);
+}
+
+
+
+/**
+  * @brief L3GD20 De-initialization
+  * @param  None
+  * @retval None
+  */
+void L3GD20_DeInit(void)
+{
+}
+
+/**
+  * @brief  Read ID address of L3GD20
+  * @param  None
+  * @retval ID name
+  */
+uint8_t L3GD20_ReadID(void)
+{
+  uint8_t tmp;
+  
+  /* Configure the low level interface */
+  GYRO_IO_Init();
+  
+  /* Read WHO I AM register */
+  GYRO_IO_Read(&tmp, L3GD20_WHO_AM_I_ADDR, 1);
+  
+  /* Return the ID */
+  return (uint8_t)tmp;
+}
+
+/**
+  * @brief  Reboot memory content of L3GD20
+  * @param  None
+  * @retval None
+  */
+void L3GD20_RebootCmd(void)
+{
+  uint8_t tmpreg;
+  
+  /* Read CTRL_REG5 register */
+  GYRO_IO_Read(&tmpreg, L3GD20_CTRL_REG5_ADDR, 1);
+  
+  /* Enable or Disable the reboot memory */
+  tmpreg |= L3GD20_BOOT_REBOOTMEMORY;
+  
+  /* Write value to MEMS CTRL_REG5 register */
+  GYRO_IO_Write(&tmpreg, L3GD20_CTRL_REG5_ADDR, 1);
+}
+
+/**
+  * @brief Set L3GD20 in low-power mode
+  * @param 
+  * @retval  None
+  */
+void L3GD20_LowPower(uint16_t InitStruct)
+{  
+  uint8_t ctrl = 0x00;
+
+  /* Write value to MEMS CTRL_REG1 register */
+  ctrl = (uint8_t) InitStruct;
+  GYRO_IO_Write(&ctrl, L3GD20_CTRL_REG1_ADDR, 1);
+}
+
+/**
+  * @brief  Set L3GD20 Interrupt INT1 configuration
+  * @param  Int1Config: the configuration setting for the L3GD20 Interrupt.
+  * @retval None
+  */
+void L3GD20_INT1InterruptConfig(uint16_t Int1Config)
+{
+  uint8_t ctrl_cfr = 0x00, ctrl3 = 0x00;
+  
+  /* Read INT1_CFG register */
+  GYRO_IO_Read(&ctrl_cfr, L3GD20_INT1_CFG_ADDR, 1);
+  
+  /* Read CTRL_REG3 register */
+  GYRO_IO_Read(&ctrl3, L3GD20_CTRL_REG3_ADDR, 1);
+  
+  ctrl_cfr &= 0x80;
+  ctrl_cfr |= ((uint8_t) Int1Config >> 8);
+  
+  ctrl3 &= 0xDF;
+  ctrl3 |= ((uint8_t) Int1Config);   
+  
+  /* Write value to MEMS INT1_CFG register */
+  GYRO_IO_Write(&ctrl_cfr, L3GD20_INT1_CFG_ADDR, 1);
+  
+  /* Write value to MEMS CTRL_REG3 register */
+  GYRO_IO_Write(&ctrl3, L3GD20_CTRL_REG3_ADDR, 1);
+}
+
+/**
+  * @brief  Enable INT1 or INT2 interrupt
+  * @param  IntSel: choice of INT1 or INT2 
+  *      This parameter can be: 
+  *        @arg L3GD20_INT1
+  *        @arg L3GD20_INT2   
+  * @retval None
+  */
+void L3GD20_EnableIT(uint8_t IntSel)
+{  
+  uint8_t tmpreg;
+  
+  /* Read CTRL_REG3 register */
+  GYRO_IO_Read(&tmpreg, L3GD20_CTRL_REG3_ADDR, 1);
+  
+  if(IntSel == L3GD20_INT1)
+  {
+    tmpreg &= 0x7F;	
+    tmpreg |= L3GD20_INT1INTERRUPT_ENABLE;
+  }
+  else if(IntSel == L3GD20_INT2)
+  {
+    tmpreg &= 0xF7;
+    tmpreg |= L3GD20_INT2INTERRUPT_ENABLE;
+  }
+  
+  /* Write value to MEMS CTRL_REG3 register */
+  GYRO_IO_Write(&tmpreg, L3GD20_CTRL_REG3_ADDR, 1);
+}
+
+/**
+  * @brief  Disable  INT1 or INT2 interrupt
+  * @param  IntSel: choice of INT1 or INT2 
+  *      This parameter can be: 
+  *        @arg L3GD20_INT1
+  *        @arg L3GD20_INT2   
+  * @retval None
+  */
+void L3GD20_DisableIT(uint8_t IntSel)
+{  
+  uint8_t tmpreg;
+  
+  /* Read CTRL_REG3 register */
+  GYRO_IO_Read(&tmpreg, L3GD20_CTRL_REG3_ADDR, 1);
+  
+  if(IntSel == L3GD20_INT1)
+  {
+    tmpreg &= 0x7F;	
+    tmpreg |= L3GD20_INT1INTERRUPT_DISABLE;
+  }
+  else if(IntSel == L3GD20_INT2)
+  {
+    tmpreg &= 0xF7;
+    tmpreg |= L3GD20_INT2INTERRUPT_DISABLE;
+  }
+  
+  /* Write value to MEMS CTRL_REG3 register */
+  GYRO_IO_Write(&tmpreg, L3GD20_CTRL_REG3_ADDR, 1);
+}
+
+/**
+  * @brief  Set High Pass Filter Modality
+  * @param  FilterStruct: contains the configuration setting for the L3GD20.        
+  * @retval None
+  */
+void L3GD20_FilterConfig(uint8_t FilterStruct) 
+{
+  uint8_t tmpreg;
+  
+  /* Read CTRL_REG2 register */
+  GYRO_IO_Read(&tmpreg, L3GD20_CTRL_REG2_ADDR, 1);
+  
+  tmpreg &= 0xC0;
+  
+  /* Configure MEMS: mode and cutoff frequency */
+  tmpreg |= FilterStruct;
+  
+  /* Write value to MEMS CTRL_REG2 register */
+  GYRO_IO_Write(&tmpreg, L3GD20_CTRL_REG2_ADDR, 1);
+}
+
+/**
+  * @brief  Enable or Disable High Pass Filter
+  * @param  HighPassFilterState: new state of the High Pass Filter feature.
+  *      This parameter can be: 
+  *         @arg: L3GD20_HIGHPASSFILTER_DISABLE 
+  *         @arg: L3GD20_HIGHPASSFILTER_ENABLE          
+  * @retval None
+  */
+void L3GD20_FilterCmd(uint8_t HighPassFilterState)
+{
+  uint8_t tmpreg;
+  
+  /* Read CTRL_REG5 register */
+  GYRO_IO_Read(&tmpreg, L3GD20_CTRL_REG5_ADDR, 1);
+  
+  tmpreg &= 0xEF;
+  
+  tmpreg |= HighPassFilterState;
+  
+  /* Write value to MEMS CTRL_REG5 register */
+  GYRO_IO_Write(&tmpreg, L3GD20_CTRL_REG5_ADDR, 1);
+}
+
+/**
+  * @brief  Get status for L3GD20 data
+  * @param  None         
+  * @retval Data status in a L3GD20 Data
+  */
+uint8_t L3GD20_GetDataStatus(void)
+{
+  uint8_t tmpreg;
+  
+  /* Read STATUS_REG register */
+  GYRO_IO_Read(&tmpreg, L3GD20_STATUS_REG_ADDR, 1);
+  
+  return tmpreg;
+}
+
+/**
+* @brief  Calculate the L3GD20 angular data.
+* @param  pfData: Data out pointer
+* @retval None
+*/
+void L3GD20_ReadXYZAngRate(float *pfData)
+{
+  uint8_t tmpbuffer[6] ={0};
+  int16_t RawData[3] = {0};
+  uint8_t tmpreg = 0;
+  float sensitivity = 0;
+  int i =0;
+  
+  GYRO_IO_Read(&tmpreg,L3GD20_CTRL_REG4_ADDR,1);
+  
+  GYRO_IO_Read(tmpbuffer,L3GD20_OUT_X_L_ADDR,6);
+  
+  /* check in the control register 4 the data alignment (Big Endian or Little Endian)*/
+  if(!(tmpreg & L3GD20_BLE_MSB))
+  {
+    for(i=0; i<3; i++)
+    {
+      RawData[i]=(int16_t)(((uint16_t)tmpbuffer[2*i+1] << 8) + tmpbuffer[2*i]);
+    }
+  }
+  else
+  {
+    for(i=0; i<3; i++)
+    {
+      RawData[i]=(int16_t)(((uint16_t)tmpbuffer[2*i] << 8) + tmpbuffer[2*i+1]);
+    }
+  }
+  
+  /* Switch the sensitivity value set in the CRTL4 */
+  switch(tmpreg & L3GD20_FULLSCALE_SELECTION)
+  {
+  case L3GD20_FULLSCALE_250:
+    sensitivity=L3GD20_SENSITIVITY_250DPS;
+    break;
+    
+  case L3GD20_FULLSCALE_500:
+    sensitivity=L3GD20_SENSITIVITY_500DPS;
+    break;
+    
+  case L3GD20_FULLSCALE_2000:
+    sensitivity=L3GD20_SENSITIVITY_2000DPS;
+    break;
+  }
+  /* Divide by sensitivity */
+  for(i=0; i<3; i++)
+  {
+    pfData[i]=(float)(RawData[i] * sensitivity);
+  }
+}
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/     
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/l3gd20/l3gd20.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,325 @@
+/**
+  ******************************************************************************
+  * @file    l3gd20.h
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    26-June-2015
+  * @brief   This file contains all the functions prototypes for the l3gd20.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 __L3GD20_H
+#define __L3GD20_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "../Common/gyro.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup Components
+  * @{
+  */ 
+
+/** @addtogroup L3GD20
+  * @{
+  */
+  
+/** @defgroup L3GD20_Exported_Constants
+  * @{
+  */
+
+/******************************************************************************/
+/*************************** START REGISTER MAPPING  **************************/
+/******************************************************************************/
+#define L3GD20_WHO_AM_I_ADDR          0x0F  /* device identification register */
+#define L3GD20_CTRL_REG1_ADDR         0x20  /* Control register 1 */
+#define L3GD20_CTRL_REG2_ADDR         0x21  /* Control register 2 */
+#define L3GD20_CTRL_REG3_ADDR         0x22  /* Control register 3 */
+#define L3GD20_CTRL_REG4_ADDR         0x23  /* Control register 4 */
+#define L3GD20_CTRL_REG5_ADDR         0x24  /* Control register 5 */
+#define L3GD20_REFERENCE_REG_ADDR     0x25  /* Reference register */
+#define L3GD20_OUT_TEMP_ADDR          0x26  /* Out temp register */
+#define L3GD20_STATUS_REG_ADDR        0x27  /* Status register */
+#define L3GD20_OUT_X_L_ADDR           0x28  /* Output Register X */
+#define L3GD20_OUT_X_H_ADDR           0x29  /* Output Register X */
+#define L3GD20_OUT_Y_L_ADDR           0x2A  /* Output Register Y */
+#define L3GD20_OUT_Y_H_ADDR           0x2B  /* Output Register Y */
+#define L3GD20_OUT_Z_L_ADDR           0x2C  /* Output Register Z */
+#define L3GD20_OUT_Z_H_ADDR           0x2D  /* Output Register Z */ 
+#define L3GD20_FIFO_CTRL_REG_ADDR     0x2E  /* Fifo control Register */
+#define L3GD20_FIFO_SRC_REG_ADDR      0x2F  /* Fifo src Register */
+
+#define L3GD20_INT1_CFG_ADDR          0x30  /* Interrupt 1 configuration Register */
+#define L3GD20_INT1_SRC_ADDR          0x31  /* Interrupt 1 source Register */
+#define L3GD20_INT1_TSH_XH_ADDR       0x32  /* Interrupt 1 Threshold X register */
+#define L3GD20_INT1_TSH_XL_ADDR       0x33  /* Interrupt 1 Threshold X register */
+#define L3GD20_INT1_TSH_YH_ADDR       0x34  /* Interrupt 1 Threshold Y register */
+#define L3GD20_INT1_TSH_YL_ADDR       0x35  /* Interrupt 1 Threshold Y register */
+#define L3GD20_INT1_TSH_ZH_ADDR       0x36  /* Interrupt 1 Threshold Z register */
+#define L3GD20_INT1_TSH_ZL_ADDR       0x37  /* Interrupt 1 Threshold Z register */
+#define L3GD20_INT1_DURATION_ADDR     0x38  /* Interrupt 1 DURATION register */
+
+/******************************************************************************/
+/**************************** END REGISTER MAPPING  ***************************/
+/******************************************************************************/
+
+#define I_AM_L3GD20                 ((uint8_t)0xD4)
+#define I_AM_L3GD20_TR              ((uint8_t)0xD5)
+
+/** @defgroup Power_Mode_selection 
+  * @{
+  */
+#define L3GD20_MODE_POWERDOWN       ((uint8_t)0x00)
+#define L3GD20_MODE_ACTIVE          ((uint8_t)0x08)
+/**
+  * @}
+  */
+
+/** @defgroup OutPut_DataRate_Selection 
+  * @{
+  */
+#define L3GD20_OUTPUT_DATARATE_1    ((uint8_t)0x00)
+#define L3GD20_OUTPUT_DATARATE_2    ((uint8_t)0x40)
+#define L3GD20_OUTPUT_DATARATE_3    ((uint8_t)0x80)
+#define L3GD20_OUTPUT_DATARATE_4    ((uint8_t)0xC0)
+/**
+  * @}
+  */
+
+/** @defgroup Axes_Selection 
+  * @{
+  */
+#define L3GD20_X_ENABLE            ((uint8_t)0x02)
+#define L3GD20_Y_ENABLE            ((uint8_t)0x01)
+#define L3GD20_Z_ENABLE            ((uint8_t)0x04)
+#define L3GD20_AXES_ENABLE         ((uint8_t)0x07)
+#define L3GD20_AXES_DISABLE        ((uint8_t)0x00)
+/**
+  * @}
+  */
+
+/** @defgroup Bandwidth_Selection 
+  * @{
+  */
+#define L3GD20_BANDWIDTH_1         ((uint8_t)0x00)
+#define L3GD20_BANDWIDTH_2         ((uint8_t)0x10)
+#define L3GD20_BANDWIDTH_3         ((uint8_t)0x20)
+#define L3GD20_BANDWIDTH_4         ((uint8_t)0x30)
+/**
+  * @}
+  */
+
+/** @defgroup Full_Scale_Selection 
+  * @{
+  */
+#define L3GD20_FULLSCALE_250       ((uint8_t)0x00)
+#define L3GD20_FULLSCALE_500       ((uint8_t)0x10)
+#define L3GD20_FULLSCALE_2000      ((uint8_t)0x20) 
+#define L3GD20_FULLSCALE_SELECTION ((uint8_t)0x30)
+/**
+  * @}
+  */
+
+/** @defgroup Full_Scale_Sensitivity 
+  * @{
+  */
+#define L3GD20_SENSITIVITY_250DPS  ((float)8.75f)         /*!< gyroscope sensitivity with 250 dps full scale [DPS/LSB]  */
+#define L3GD20_SENSITIVITY_500DPS  ((float)17.50f)        /*!< gyroscope sensitivity with 500 dps full scale [DPS/LSB]  */
+#define L3GD20_SENSITIVITY_2000DPS ((float)70.00f)        /*!< gyroscope sensitivity with 2000 dps full scale [DPS/LSB] */
+/**
+  * @}
+  */
+
+  
+/** @defgroup Block_Data_Update 
+  * @{
+  */  
+#define L3GD20_BlockDataUpdate_Continous   ((uint8_t)0x00)
+#define L3GD20_BlockDataUpdate_Single      ((uint8_t)0x80)
+/**
+  * @}
+  */
+  
+/** @defgroup Endian_Data_selection
+  * @{
+  */  
+#define L3GD20_BLE_LSB                     ((uint8_t)0x00)
+#define L3GD20_BLE_MSB	                   ((uint8_t)0x40)
+/**
+  * @}
+  */
+  
+/** @defgroup High_Pass_Filter_status 
+  * @{
+  */   
+#define L3GD20_HIGHPASSFILTER_DISABLE      ((uint8_t)0x00)
+#define L3GD20_HIGHPASSFILTER_ENABLE	     ((uint8_t)0x10)
+/**
+  * @}
+  */
+
+/** @defgroup INT1_INT2_selection 
+  * @{
+  */   
+#define L3GD20_INT1                        ((uint8_t)0x00)
+#define L3GD20_INT2                        ((uint8_t)0x01)
+/**
+  * @}
+  */
+
+/** @defgroup INT1_Interrupt_status 
+  * @{
+  */   
+#define L3GD20_INT1INTERRUPT_DISABLE       ((uint8_t)0x00)
+#define L3GD20_INT1INTERRUPT_ENABLE        ((uint8_t)0x80)
+/**
+  * @}
+  */
+
+/** @defgroup INT2_Interrupt_status 
+  * @{
+  */   
+#define L3GD20_INT2INTERRUPT_DISABLE       ((uint8_t)0x00)
+#define L3GD20_INT2INTERRUPT_ENABLE        ((uint8_t)0x08)
+/**
+  * @}
+  */
+
+/** @defgroup INT1_Interrupt_ActiveEdge 
+  * @{
+  */   
+#define L3GD20_INT1INTERRUPT_LOW_EDGE      ((uint8_t)0x20)
+#define L3GD20_INT1INTERRUPT_HIGH_EDGE     ((uint8_t)0x00)
+/**
+  * @}
+  */
+  
+/** @defgroup Boot_Mode_selection 
+  * @{
+  */
+#define L3GD20_BOOT_NORMALMODE             ((uint8_t)0x00)
+#define L3GD20_BOOT_REBOOTMEMORY           ((uint8_t)0x80)
+/**
+  * @}
+  */  
+ 
+/** @defgroup High_Pass_Filter_Mode 
+  * @{
+  */   
+#define L3GD20_HPM_NORMAL_MODE_RES         ((uint8_t)0x00)
+#define L3GD20_HPM_REF_SIGNAL              ((uint8_t)0x10)
+#define L3GD20_HPM_NORMAL_MODE             ((uint8_t)0x20)
+#define L3GD20_HPM_AUTORESET_INT           ((uint8_t)0x30)
+/**
+  * @}
+  */
+
+/** @defgroup High_Pass_CUT OFF_Frequency 
+  * @{
+  */   
+#define L3GD20_HPFCF_0              0x00
+#define L3GD20_HPFCF_1              0x01
+#define L3GD20_HPFCF_2              0x02
+#define L3GD20_HPFCF_3              0x03
+#define L3GD20_HPFCF_4              0x04
+#define L3GD20_HPFCF_5              0x05
+#define L3GD20_HPFCF_6              0x06
+#define L3GD20_HPFCF_7              0x07
+#define L3GD20_HPFCF_8              0x08
+#define L3GD20_HPFCF_9              0x09
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+/** @defgroup L3GD20_Exported_Functions
+  * @{
+  */
+/* Sensor Configuration Functions */ 
+void    L3GD20_Init(uint16_t InitStruct);
+void    L3GD20_DeInit(void);
+void    L3GD20_LowPower(uint16_t InitStruct);
+uint8_t L3GD20_ReadID(void);
+void    L3GD20_RebootCmd(void);
+
+/* Interrupt Configuration Functions */
+void    L3GD20_INT1InterruptConfig(uint16_t Int1Config);
+void    L3GD20_EnableIT(uint8_t IntSel);
+void    L3GD20_DisableIT(uint8_t IntSel);
+
+/* High Pass Filter Configuration Functions */
+void    L3GD20_FilterConfig(uint8_t FilterStruct);
+void    L3GD20_FilterCmd(uint8_t HighPassFilterState);
+void    L3GD20_ReadXYZAngRate(float *pfData);
+uint8_t L3GD20_GetDataStatus(void);
+
+/* Gyroscope IO functions */
+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);
+
+/* Gyroscope driver structure */
+extern GYRO_DrvTypeDef L3gd20Drv;
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */ 
+  
+/**
+  * @}
+  */ 
+
+#ifdef __cplusplus
+  }
+#endif
+  
+#endif /* __L3GD20_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/lsm303c/lsm303c.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,445 @@
+/**
+  ******************************************************************************
+  * @file    lsm303c.c
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    24-June-2015
+  * @brief   This file provides a set of functions needed to manage the LSM303C
+  *          MEMS accelerometer.
+  ******************************************************************************
+  * @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 "lsm303c.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup Components
+  * @{
+  */ 
+
+/** @addtogroup LSM303C
+  * @{
+  */
+
+/** @defgroup LSM303C_Private_TypesDefinitions
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup LSM303C_Private_Defines
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup LSM303C_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+
+/** @defgroup LSM303C_Private_Functions
+  * @{
+  */
+
+/* ACCELEROMETER functions */
+void    LSM303C_AccInit(uint16_t InitStruct);
+void    LSM303C_AccDeInit(void);
+uint8_t LSM303C_AccReadID(void);
+void    LSM303C_AccLowPower(void);
+void    LSM303C_AccFilterConfig(uint8_t FilterStruct);
+void    LSM303C_AccFilterCmd(uint8_t HighPassFilterState);
+void    LSM303C_AccReadXYZ(int16_t* pData);
+void    LSM303C_AccFilterClickCmd(uint8_t HighPassFilterClickState);
+void    LSM303C_AccIT1Enable(uint8_t LSM303C_IT);
+void    LSM303C_AccIT1Disable(uint8_t LSM303C_IT);
+void    LSM303C_AccIT2Enable(uint8_t LSM303C_IT);
+void    LSM303C_AccIT2Disable(uint8_t LSM303C_IT);
+void    LSM303C_AccClickITEnable(uint8_t ITClick);
+void    LSM303C_AccClickITDisable(uint8_t ITClick);
+void    LSM303C_AccZClickITConfig(void);
+
+/* MAGNETOMETER functions */
+void    LSM303C_MagInit(MAGNETO_InitTypeDef LSM303C_InitStruct);
+void    LSM303C_MagDeInit(void);
+uint8_t LSM303C_MagReadID(void);
+void    LSM303C_MagLowPower(void);
+void    LSM303C_MagReadXYZ(int16_t* pData);
+uint8_t LSM303C_MagGetDataStatus(void);
+
+
+/* COMPASS / ACCELERO IO functions */
+extern void    ACCELERO_IO_Init(void);
+extern void    ACCELERO_IO_ITConfig(void);
+extern void    ACCELERO_IO_Write(uint8_t RegisterAddr, uint8_t Value);
+extern uint8_t ACCELERO_IO_Read(uint8_t RegisterAddr);
+
+/* COMPASS IO function */
+extern void    MAGNETO_IO_Init(void);
+extern void    MAGNETO_IO_ITConfig(void);
+extern void    MAGNETO_IO_Write(uint8_t RegisterAddr, uint8_t Value);
+extern uint8_t MAGNETO_IO_Read(uint8_t RegisterAddr);
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup LSM303C_Private_Variables
+  * @{
+  */ 
+ACCELERO_DrvTypeDef Lsm303cDrv_accelero =
+{
+  LSM303C_AccInit,
+  LSM303C_AccDeInit,
+  LSM303C_AccReadID,
+  0,
+  LSM303C_AccLowPower,
+  0,
+  0,
+  0,
+  0,
+  0,
+  LSM303C_AccFilterConfig,
+  0,
+  LSM303C_AccReadXYZ
+};
+
+MAGNETO_DrvTypeDef Lsm303cDrv_magneto =
+{
+  LSM303C_MagInit,
+  LSM303C_MagDeInit,
+  LSM303C_MagReadID,
+  0,
+  LSM303C_MagLowPower,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  LSM303C_MagReadXYZ
+  
+};
+
+/**
+  * @}
+  */
+
+
+/**
+  * @brief  Set LSM303C Accelerometer Initialization.
+  * @param  InitStruct: Init parameters
+  * @retval None
+  */
+void LSM303C_AccInit(uint16_t InitStruct)
+{  
+  uint8_t ctrl = 0x00;
+  
+  /*  Low level init */
+  ACCELERO_IO_Init();
+  
+  /* Write value to ACC MEMS CTRL_REG1 register */
+  ctrl = (uint8_t) InitStruct;
+  ACCELERO_IO_Write(LSM303C_CTRL_REG1_A, ctrl);
+  
+  /* Write value to ACC MEMS CTRL_REG4 register */
+  ctrl = ((uint8_t) (InitStruct >> 8));
+  ACCELERO_IO_Write(LSM303C_CTRL_REG4_A, ctrl);
+}
+
+/**
+  * @brief  LSM303C Accelerometer De-initialization.
+  * @param  None
+  * @retval None
+  */
+void LSM303C_AccDeInit(void)
+{  
+}
+
+/**
+  * @brief  Read LSM303C ID.
+  * @param  None
+  * @retval ID 
+  */
+uint8_t LSM303C_AccReadID(void)
+{  
+  uint8_t ctrl = 0x00;
+  
+  /* Low level init */
+  ACCELERO_IO_Init();
+  
+  /* Enabled SPI/I2C read communication */
+  ACCELERO_IO_Write(LSM303C_CTRL_REG4_A, 0x5);
+  
+  /* Read value at Who am I register address */
+  ctrl = ACCELERO_IO_Read(LSM303C_WHO_AM_I_ADDR);
+  
+  return ctrl;
+}
+
+/**
+  * @brief  Put Accelerometer in power down mode.
+  * @param  None
+  * @retval None 
+  */
+void LSM303C_AccLowPower(void)
+{  
+  uint8_t ctrl = 0x00;
+  
+  /* Read control register 1 value */
+  ctrl = ACCELERO_IO_Read(LSM303C_CTRL_REG1_A);
+
+  /* Clear ODR bits */
+  ctrl &= ~(LSM303C_ACC_ODR_BITPOSITION);
+
+  /* Set Power down */
+  ctrl |= LSM303C_ACC_ODR_OFF;
+  
+  /* write back control register */
+  ACCELERO_IO_Write(LSM303C_CTRL_REG1_A, ctrl);
+}
+
+/**
+  * @brief  Set High Pass Filter Modality
+  * @param  FilterStruct: contains data for filter config
+  * @retval None
+  */
+void LSM303C_AccFilterConfig(uint8_t FilterStruct) 
+{
+  uint8_t tmpreg;
+  
+//  /* Read CTRL_REG2 register */
+//  tmpreg = ACCELERO_IO_Read(LSM303C_CTRL_REG2_A);
+//  
+//  tmpreg &= 0x0C;
+  tmpreg = FilterStruct;
+  
+  /* Write value to ACC MEMS CTRL_REG2 register */
+  ACCELERO_IO_Write(LSM303C_CTRL_REG2_A, tmpreg);
+}
+
+/**
+  * @brief  Read X, Y & Z Acceleration values 
+  * @param  pData: Data out pointer
+  * @retval None
+  */
+void LSM303C_AccReadXYZ(int16_t* pData)
+{
+  int16_t pnRawData[3];
+  uint8_t ctrlx[2]={0,0};
+  uint8_t buffer[6];
+  uint8_t i = 0;
+  uint8_t sensitivity = LSM303C_ACC_SENSITIVITY_2G;
+  
+  /* Read the acceleration control register content */
+  ctrlx[0] = ACCELERO_IO_Read(LSM303C_CTRL_REG4_A);
+  ctrlx[1] = ACCELERO_IO_Read(LSM303C_CTRL_REG5_A);
+  
+  /* Read output register X, Y & Z acceleration */
+  buffer[0] = ACCELERO_IO_Read(LSM303C_OUT_X_L_A); 
+  buffer[1] = ACCELERO_IO_Read(LSM303C_OUT_X_H_A);
+  buffer[2] = ACCELERO_IO_Read(LSM303C_OUT_Y_L_A);
+  buffer[3] = ACCELERO_IO_Read(LSM303C_OUT_Y_H_A);
+  buffer[4] = ACCELERO_IO_Read(LSM303C_OUT_Z_L_A);
+  buffer[5] = ACCELERO_IO_Read(LSM303C_OUT_Z_H_A);
+  
+  for(i=0; i<3; i++)
+  {
+    pnRawData[i]=((int16_t)((uint16_t)buffer[2*i+1] << 8) + buffer[2*i]);
+  }
+  
+  /* Normal mode */
+  /* Switch the sensitivity value set in the CRTL4 */
+  switch(ctrlx[0] & LSM303C_ACC_FULLSCALE_8G)
+  {
+  case LSM303C_ACC_FULLSCALE_2G:
+    sensitivity = LSM303C_ACC_SENSITIVITY_2G;
+    break;
+  case LSM303C_ACC_FULLSCALE_4G:
+    sensitivity = LSM303C_ACC_SENSITIVITY_4G;
+    break;
+  case LSM303C_ACC_FULLSCALE_8G:
+    sensitivity = LSM303C_ACC_SENSITIVITY_8G;
+    break;
+  }
+  
+  /* Obtain the mg value for the three axis */
+  for(i=0; i<3; i++)
+  {
+    pData[i]=(pnRawData[i] * sensitivity);
+  }
+}
+
+/***********************************************************************************************
+  Magnetometer driver 
+***********************************************************************************************/
+
+/**
+  * @brief  Set LSM303C Magnetometer Initialization.
+  * @param  LSM303C_InitStruct: pointer to a LSM303C_MagInitTypeDef structure 
+  *         that contains the configuration setting for the LSM303C.
+  * @retval None
+  */
+void LSM303C_MagInit(MAGNETO_InitTypeDef LSM303C_InitStruct)
+{  
+  MAGNETO_IO_Write(LSM303C_CTRL_REG1_M, LSM303C_InitStruct.Register1);
+  MAGNETO_IO_Write(LSM303C_CTRL_REG2_M, LSM303C_InitStruct.Register2);
+  MAGNETO_IO_Write(LSM303C_CTRL_REG3_M, LSM303C_InitStruct.Register3);
+  MAGNETO_IO_Write(LSM303C_CTRL_REG4_M, LSM303C_InitStruct.Register4);
+  MAGNETO_IO_Write(LSM303C_CTRL_REG5_M, LSM303C_InitStruct.Register5);
+}
+
+/**
+  * @brief  LSM303C Magnetometer De-initialization.
+  * @param  None
+  * @retval None
+  */
+void LSM303C_MagDeInit(void)
+{  
+}
+
+/**
+  * @brief  Read LSM303C ID.
+  * @param  None
+  * @retval ID 
+  */
+uint8_t LSM303C_MagReadID(void)
+{  
+  /* Low level init */
+  MAGNETO_IO_Init();
+  
+  /* Enabled the SPI/I2C read operation */
+  MAGNETO_IO_Write(LSM303C_CTRL_REG3_M, 0x84);
+  
+  /* Read value at Who am I register address */
+  return MAGNETO_IO_Read(LSM303C_WHO_AM_I_ADDR);
+}
+
+/**
+  * @brief  Put Magnetometer in power down mode.
+  * @param  None
+  * @retval None 
+  */
+void LSM303C_MagLowPower(void)
+{  
+  uint8_t ctrl = 0x00;
+  
+  /* Read control register 1 value */
+  ctrl = MAGNETO_IO_Read(LSM303C_CTRL_REG3_M);
+
+  /* Clear ODR bits */
+  ctrl &= ~(LSM303C_MAG_SELECTION_MODE);
+
+  /* Set Power down */
+  ctrl |= LSM303C_MAG_POWERDOWN2_MODE;
+  
+  /* write back control register */
+  MAGNETO_IO_Write(LSM303C_CTRL_REG3_M, ctrl);
+}
+
+/**
+  * @brief  Get status for Mag LSM303C data
+  * @param  None
+  * @retval Data status in a LSM303C Data register
+  */
+uint8_t LSM303C_MagGetDataStatus(void)
+{
+  /* Read Mag STATUS register */
+  return MAGNETO_IO_Read(LSM303C_STATUS_REG_M);
+}
+
+/**
+  * @brief  Read X, Y & Z Magnetometer values 
+  * @param  pData: Data out pointer
+  * @retval None
+  */
+void LSM303C_MagReadXYZ(int16_t* pData)
+{
+  uint8_t ctrlx;
+  uint8_t buffer[6];
+  uint8_t i=0;
+  
+  /* Read the magnetometer control register content */
+  ctrlx = MAGNETO_IO_Read(LSM303C_CTRL_REG4_M);
+
+  /* Read output register X, Y & Z magnetometer */
+  buffer[0] = MAGNETO_IO_Read(LSM303C_OUT_X_L_M); 
+  buffer[1] = MAGNETO_IO_Read(LSM303C_OUT_X_H_M);
+  buffer[2] = MAGNETO_IO_Read(LSM303C_OUT_Y_L_M);
+  buffer[3] = MAGNETO_IO_Read(LSM303C_OUT_Y_H_M);
+  buffer[4] = MAGNETO_IO_Read(LSM303C_OUT_Z_L_M);
+  buffer[5] = MAGNETO_IO_Read(LSM303C_OUT_Z_H_M);
+  
+  /* Check in the control register4 the data alignment*/
+  if((ctrlx & LSM303C_MAG_BLE_MSB)) 
+  {
+    for(i=0; i<3; i++)
+    {
+      pData[i]=((int16_t)((uint16_t)buffer[2*i] << 8) + buffer[2*i+1]);
+    }
+  }
+  else
+  {
+    for(i=0; i<3; i++)
+    {
+      pData[i]=((int16_t)((uint16_t)buffer[2*i+1] << 8) + buffer[2*i]);
+    }
+  }
+}
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+  
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+  
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/     
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/lsm303c/lsm303c.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,567 @@
+/**
+  ******************************************************************************
+  * @file    lsm303c.h
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    24-June-2015
+  * @brief   This file contains all the functions prototypes for the LSM303C.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 __LSM303C_H
+#define __LSM303C_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "../Common/accelero.h"
+#include "../Common/magneto.h"
+   
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup Components
+  * @{
+  */ 
+   
+/** @addtogroup LSM303C
+  * @{
+  */
+  
+/** @defgroup LSM303C_Exported_Types
+  * @{
+  */
+
+/**
+  * @}
+  */
+ 
+/******************************************************************************/
+/*************************** START REGISTER MAPPING  **************************/
+/******************************************************************************/
+/* Acceleration Registers */
+#define LSM303C_WHO_AM_I_ADDR             0x0F  /* device identification register */
+#define LSM303C_ACT_THS_A                 0x1E
+#define LSM303C_ACT_DUR_A                 0x1F
+#define LSM303C_CTRL_REG1_A               0x20  /* Control register 1 acceleration */
+#define LSM303C_CTRL_REG2_A               0x21  /* Control register 2 acceleration */
+#define LSM303C_CTRL_REG3_A               0x22  /* Control register 3 acceleration */
+#define LSM303C_CTRL_REG4_A               0x23  /* Control register 4 acceleration */
+#define LSM303C_CTRL_REG5_A               0x24  /* Control register 5 acceleration */
+#define LSM303C_CTRL_REG6_A               0x25  /* Control register 6 acceleration */
+#define LSM303C_CTRL_REG7_A               0x26  /* Control register 6 acceleration */   
+#define LSM303C_STATUS_REG_A              0x27  /* Status register acceleration */
+#define LSM303C_OUT_X_L_A                 0x28  /* Output Register X acceleration */
+#define LSM303C_OUT_X_H_A                 0x29  /* Output Register X acceleration */
+#define LSM303C_OUT_Y_L_A                 0x2A  /* Output Register Y acceleration */
+#define LSM303C_OUT_Y_H_A                 0x2B  /* Output Register Y acceleration */
+#define LSM303C_OUT_Z_L_A                 0x2C  /* Output Register Z acceleration */
+#define LSM303C_OUT_Z_H_A                 0x2D  /* Output Register Z acceleration */ 
+#define LSM303C_FIFO_CTRL                 0x2E  /* Fifo control Register acceleration */
+#define LSM303C_FIFO_SRC                  0x2F  /* Fifo src Register acceleration */
+
+#define LSM303C_IG_CFG1_A                 0x30  /* Interrupt 1 configuration Register acceleration */
+#define LSM303C_IG_SRC1_A                 0x31  /* Interrupt 1 source Register acceleration */
+#define LSM303C_IG_THS_X1_A               0x32
+#define LSM303C_IG_THS_Y1_A               0x33
+#define LSM303C_IG_THS_Z1_A               0x34
+   
+#define LSM303C_IG_DUR1_A                 0x32
+#define LSM303C_INT1_DURATION_A           0x33  /* Interrupt 1 DURATION register acceleration */
+
+#define LSM303C_INT2_CFG_A                0x34  /* Interrupt 2 configuration Register acceleration */
+#define LSM303C_INT2_SOURCE_A             0x35  /* Interrupt 2 source Register acceleration */
+#define LSM303C_INT2_THS_A                0x36  /* Interrupt 2 Threshold register acceleration */
+#define LSM303C_INT2_DURATION_A           0x37  /* Interrupt 2 DURATION register acceleration */
+
+#define LSM303C_CLICK_CFG_A               0x38  /* Click configuration Register acceleration */
+#define LSM303C_CLICK_SOURCE_A            0x39  /* Click 2 source Register acceleration */
+#define LSM303C_CLICK_THS_A               0x3A  /* Click 2 Threshold register acceleration */
+
+#define LSM303C_TIME_LIMIT_A              0x3B  /* Time Limit Register acceleration */
+#define LSM303C_TIME_LATENCY_A            0x3C  /* Time Latency Register acceleration */
+#define LSM303C_TIME_WINDOW_A             0x3D  /* Time window register acceleration */
+
+/* Magnetic field Registers */
+#define LSM303C_CTRL_REG1_M               0x20  /* Magnetic control register 1 */
+#define LSM303C_CTRL_REG2_M               0x21  /* Magnetic control register 2 */
+#define LSM303C_CTRL_REG3_M               0x22  /* Magnetic control register 3 */
+#define LSM303C_CTRL_REG4_M               0x23  /* Magnetic control register 4 */
+#define LSM303C_CTRL_REG5_M               0x24  /* Magnetic control register 5 */   
+
+#define LSM303C_STATUS_REG_M              0x27  /* Magnetic status register M  */
+
+#define LSM303C_OUT_X_L_M                 0x28  /* Output Register X magnetic field */
+#define LSM303C_OUT_X_H_M                 0x29  /* Output Register X magnetic field */
+#define LSM303C_OUT_Y_L_M                 0x2A  /* Output Register Y magnetic field */
+#define LSM303C_OUT_Y_H_M                 0x2B  /* Output Register Y magnetic field */
+#define LSM303C_OUT_Z_L_M                 0x2C  /* Output Register Z magnetic field */ 
+#define LSM303C_OUT_Z_H_M                 0x2D  /* Output Register Z magnetic field */
+
+#define LSM303C_TEMP_OUT_L_M              0x2E  /* Temperature Register magnetic field */
+#define LSM303C_TEMP_OUT_H_M              0x2F  /* Temperature Register magnetic field */
+
+#define LSM303C_INT_CFG_M                 0x30  /* Axis interrupt configuration        */
+#define LSM303C_INT_SRC_M                 0x31  /* Axis interrupt source               */
+#define LSM303C_INT_THS_L_M               0x32  /* Interrupt threshold L               */
+#define LSM303C_INT_THS_H_M               0x33  /* Interrupt threshold M               */ 
+     
+
+/******************************************************************************/
+/**************************** END REGISTER MAPPING  ***************************/
+/******************************************************************************/
+
+/** @defgroup Power_Mode_selection
+  * @{
+  */
+#define LMS303C_ACC_ID                      ((uint8_t)0x41)
+#define LMS303C_MAG_ID                      ((uint8_t)0x3D)
+/**
+  * @}
+  */
+
+/** @defgroup Acc_OutPut_DataRate_Selection
+  * @{
+  */
+#define LSM303C_ACC_ODR_BITPOSITION         ((uint8_t)0x70)  /*!< Output Data Rate bit position */
+#define LSM303C_ACC_ODR_OFF                 ((uint8_t)0x00)  /*!< Output Data Rate powerdown */
+#define LSM303C_ACC_ODR_10_HZ               ((uint8_t)0x10)  /*!< Output Data Rate = 10 Hz */
+#define LSM303C_ACC_ODR_50_HZ               ((uint8_t)0x20)  /*!< Output Data Rate = 50 Hz */
+#define LSM303C_ACC_ODR_100_HZ              ((uint8_t)0x30)  /*!< Output Data Rate = 100 Hz */
+#define LSM303C_ACC_ODR_200_HZ              ((uint8_t)0x40)  /*!< Output Data Rate = 200 Hz */
+#define LSM303C_ACC_ODR_400_HZ              ((uint8_t)0x50)  /*!< Output Data Rate = 400 Hz */
+#define LSM303C_ACC_ODR_800_HZ              ((uint8_t)0x60)  /*!< Output Data Rate = 800 Hz */
+
+/**
+  * @}
+  */
+
+/** @defgroup Acc_Axes_Selection
+  * @{
+  */
+#define LSM303C_ACC_X_ENABLE                ((uint8_t)0x01)
+#define LSM303C_ACC_Y_ENABLE                ((uint8_t)0x02)
+#define LSM303C_ACC_Z_ENABLE                ((uint8_t)0x04)
+#define LSM303C_ACC_AXES_ENABLE             ((uint8_t)0x07)
+#define LSM303C_ACC_AXES_DISABLE            ((uint8_t)0x00)
+/**
+  * @}
+  */
+
+/** @defgroup Acc_High_Resolution
+  * @{
+  */
+#define LSM303C_ACC_HR_ENABLE               ((uint8_t)0x80)
+#define LSM303C_ACC_HR_DISABLE              ((uint8_t)0x00)
+/**
+  * @}
+  */
+
+/** @defgroup Communication_Mode 
+  * @{
+  */ 
+#define  LSM303C_ACC_I2C_MODE          ((uint8_t) 0x02)
+#define  LSM303C_ACC_SPI_MODE          ((uint8_t) 0x01)
+/**
+  * @}
+  */
+    
+/** @defgroup Acc_Full_Scale_Selection
+  * @{
+  */
+#define LSM303C_ACC_FULLSCALE_2G            ((uint8_t)0x00)  /*!< ±2 g */
+#define LSM303C_ACC_FULLSCALE_4G            ((uint8_t)0x20)  /*!< ±4 g */
+#define LSM303C_ACC_FULLSCALE_8G            ((uint8_t)0x30)  /*!< ±8 g */
+/**
+  * @}
+  */
+
+/** @defgroup Acc_Full_Scale_Selection
+  * @{
+  */
+#define LSM303C_ACC_SENSITIVITY_2G     ((uint8_t)1)  /*!< accelerometer sensitivity with 2 g full scale [mg/LSB] */
+#define LSM303C_ACC_SENSITIVITY_4G     ((uint8_t)2)  /*!< accelerometer sensitivity with 4 g full scale [mg/LSB] */
+#define LSM303C_ACC_SENSITIVITY_8G     ((uint8_t)4)  /*!< accelerometer sensitivity with 8 g full scale [mg/LSB] */
+#define LSM303C_ACC_SENSITIVITY_16G    ((uint8_t)12) /*!< accelerometer sensitivity with 12 g full scale [mg/LSB] */
+/**
+  * @}
+  */
+
+/** @defgroup Acc_Block_Data_Update
+  * @{
+  */  
+#define LSM303C_ACC_BDU_CONTINUOUS   ((uint8_t)0x00) /*!< Continuos Update */
+#define LSM303C_ACC_BDU_MSBLSB       ((uint8_t)0x08) /*!< Single Update: output registers not updated until MSB and LSB reading */
+/**
+  * @}
+  */
+  
+/** @defgroup Acc_Endian_Data_selection
+  * @{
+  */  
+#define LSM303C_ACC_BLE_LSB                 ((uint8_t)0x00) /*!< Little Endian: data LSB @ lower address */
+#define LSM303C_ACC_BLE_MSB                 ((uint8_t)0x40) /*!< Big Endian: data MSB @ lower address */
+/**
+  * @}
+  */
+  
+/** @defgroup Acc_High_Pass_Filter_Mode
+  * @{
+  */   
+#define LSM303C_ACC_HPM_REF_SIGNAL          ((uint8_t)0x08)
+#define LSM303C_ACC_HPM_NORMAL_MODE         ((uint8_t)0x00)
+/**
+  * @}
+  */
+
+/** @defgroup Acc_High_Pass_CUT OFF_Frequency
+  * @{
+  */   
+#define LSM303C_ACC_DFC1_ODRDIV50       ((uint8_t)0x00)
+#define LSM303C_ACC_DFC1_ODRDIV100      ((uint8_t)0x20)
+#define LSM303C_ACC_DFC1_ODRDIV9        ((uint8_t)0x40)
+#define LSM303C_ACC_DFC1_ODRDIV400      ((uint8_t)0x60)
+/**
+  * @}
+  */
+    
+/** @defgroup Acc_High_Pass_Filter_status
+  * @{
+  */   
+#define LSM303C_ACC_HPF_DISABLE         ((uint8_t)0x00)
+#define LSM303C_ACC_HPF_ENABLE          ((uint8_t)0x08)
+/**
+  * @}
+  */
+  
+/** @defgroup Acc_High_Pass_Filter_Click_status
+  * @{
+  */   
+#define LSM303C_ACC_HPF_CLICK_DISABLE   ((uint8_t)0x00)
+#define LSM303C_ACC_HPF_CLICK_ENABLE    ((uint8_t)0x04)
+/**
+  * @}
+  */
+
+/** @defgroup Acc_High_Pass_Filter_HPI2S_status
+  * @{
+  */   
+#define LSM303C_ACC_HPI2S_INT1_DISABLE  ((uint8_t)0x00)
+#define LSM303C_ACC_HPI2S_INT1_ENABLE	  ((uint8_t)0x01)
+#define LSM303C_ACC_HPI2S_INT2_DISABLE  ((uint8_t)0x00)
+#define LSM303C_ACC_HPI2S_INT2_ENABLE   ((uint8_t)0x02)
+/**
+  * @}
+  */ 
+
+/** @defgroup Acc_Interrupt1_Configuration_definition
+  * @{
+  */
+#define LSM303C_IT1_CLICK               ((uint8_t)0x80)
+#define LSM303C_IT1_AOI1                ((uint8_t)0x40)
+#define LSM303C_IT1_AOI2                ((uint8_t)0x20)
+#define LSM303C_IT1_DRY1                ((uint8_t)0x10)
+#define LSM303C_IT1_DRY2                ((uint8_t)0x08)
+#define LSM303C_IT1_WTM                 ((uint8_t)0x04)
+#define LSM303C_IT1_OVERRUN             ((uint8_t)0x02)
+/**
+  * @}
+  */  
+ 
+/** @defgroup Acc_Interrupt2_Configuration_definition
+  * @{
+  */
+#define LSM303C_IT2_CLICK               ((uint8_t)0x80)
+#define LSM303C_IT2_INT1                ((uint8_t)0x40)
+#define LSM303C_IT2_INT2                ((uint8_t)0x20)
+#define LSM303C_IT2_BOOT                ((uint8_t)0x10)
+#define LSM303C_IT2_ACT                 ((uint8_t)0x08)
+#define LSM303C_IT2_HLACTIVE            ((uint8_t)0x02)
+/**
+  * @}
+  */ 
+
+/** @defgroup Acc_INT_Combination_Status
+  * @{
+  */   
+#define LSM303C_OR_COMBINATION          ((uint8_t)0x00)  /*!< OR combination of enabled IRQs */
+#define LSM303C_AND_COMBINATION         ((uint8_t)0x80)  /*!< AND combination of enabled IRQs */
+#define LSM303C_MOV_RECOGNITION         ((uint8_t)0x40)  /*!< 6D movement recognition */
+#define LSM303C_POS_RECOGNITION         ((uint8_t)0xC0)  /*!< 6D position recognition */
+/**
+  * @}
+  */
+
+/** @defgroup Acc_INT_Axes
+  * @{
+  */   
+#define LSM303C_Z_HIGH                  ((uint8_t)0x20)  /*!< Z High enabled IRQs */
+#define LSM303C_Z_LOW                   ((uint8_t)0x10)  /*!< Z low enabled IRQs */
+#define LSM303C_Y_HIGH                  ((uint8_t)0x08)  /*!< Y High enabled IRQs */
+#define LSM303C_Y_LOW                   ((uint8_t)0x04)  /*!< Y low enabled IRQs */
+#define LSM303C_X_HIGH                  ((uint8_t)0x02)  /*!< X High enabled IRQs */
+#define LSM303C_X_LOW                   ((uint8_t)0x01)  /*!< X low enabled IRQs */
+/**
+  * @}
+  */
+      
+/** @defgroup Acc_INT_Click
+* @{
+*/   
+#define LSM303C_Z_DOUBLE_CLICK          ((uint8_t)0x20)  /*!< Z double click IRQs */
+#define LSM303C_Z_SINGLE_CLICK          ((uint8_t)0x10)  /*!< Z single click IRQs */
+#define LSM303C_Y_DOUBLE_CLICK          ((uint8_t)0x08)  /*!< Y double click IRQs */
+#define LSM303C_Y_SINGLE_CLICK          ((uint8_t)0x04)  /*!< Y single click IRQs */
+#define LSM303C_X_DOUBLE_CLICK          ((uint8_t)0x02)  /*!< X double click IRQs */
+#define LSM303C_X_SINGLE_CLICK          ((uint8_t)0x01)  /*!< X single click IRQs */
+/**
+* @}
+*/
+  
+/** @defgroup Acc_INT1_Interrupt_status
+  * @{
+  */   
+#define LSM303C_INT1INTERRUPT_DISABLE   ((uint8_t)0x00)
+#define LSM303C_INT1INTERRUPT_ENABLE    ((uint8_t)0x80)
+/**
+  * @}
+  */
+
+/** @defgroup Acc_INT1_Interrupt_ActiveEdge
+  * @{
+  */   
+#define LSM303C_INT1INTERRUPT_LOW_EDGE  ((uint8_t)0x20)
+#define LSM303C_INT1INTERRUPT_HIGH_EDGE ((uint8_t)0x00)
+/**
+  * @}
+  */
+
+   
+/** @defgroup Mag_Temperature_Sensor
+  * @{
+  */ 
+#define LSM303C_MAG_TEMPSENSOR_ENABLE        ((uint8_t) 0x80)   /*!< Temp sensor Enable */
+#define LSM303C_MAG_TEMPSENSOR_DISABLE       ((uint8_t) 0x00)   /*!< Temp sensor Disable */
+/**
+  * @}
+  */
+
+/** @defgroup Mag_XY-axis_Operating_Mode
+  * @{
+  */ 
+#define LSM303C_MAG_OM_XY_LOWPOWER           ((uint8_t) 0x00 << 5)
+#define LSM303C_MAG_OM_XY_MEDIUM             ((uint8_t) 0x01 << 5)
+#define LSM303C_MAG_OM_XY_HIGH               ((uint8_t) 0x02 << 5)
+#define LSM303C_MAG_OM_XY_ULTRAHIGH          ((uint8_t) 0x03 << 5)
+
+   /**
+  * @}
+  */
+   
+   
+/** @defgroup Mag_Data_Rate
+  * @{
+  */ 
+#define LSM303C_MAG_ODR_0_625_HZ             ((uint8_t) 0x00 << 2)  /*!< Output Data Rate = 0.625 Hz */
+#define LSM303C_MAG_ODR_1_25_HZ              ((uint8_t) 0x01 << 2)  /*!< Output Data Rate = 1.25 Hz  */
+#define LSM303C_MAG_ODR_2_5_HZ               ((uint8_t) 0x02 << 2)  /*!< Output Data Rate = 2.5 Hz   */
+#define LSM303C_MAG_ODR_5_0_HZ               ((uint8_t) 0x03 << 2)  /*!< Output Data Rate = 5.0 Hz   */
+#define LSM303C_MAG_ODR_10_HZ                ((uint8_t) 0x04 << 2)  /*!< Output Data Rate = 10 Hz    */
+#define LSM303C_MAG_ODR_20_HZ                ((uint8_t) 0x05 << 2)  /*!< Output Data Rate = 20 Hz    */
+#define LSM303C_MAG_ODR_40_HZ                ((uint8_t) 0x06 << 2)  /*!< Output Data Rate = 40 Hz    */
+#define LSM303C_MAG_ODR_80_HZ                ((uint8_t) 0x07 << 2)  /*!< Output Data Rate = 80 Hz    */
+/**
+  * @}
+  */
+
+/** @defgroup Mag_Data_Rate
+  * @{
+  */ 
+#define LMS303C_MAG_SELFTEST_DISABLE         ((uint8_t 0x00)     
+#define LMS303C_MAG_SELFTEST_ENABLE          ((uint8_t 0x01)
+   
+/** @defgroup Mag_Full_Scale
+  * @{
+  */ 
+#define LSM303C_MAG_FS_DEFAULT               ((uint8_t) 0x00 << 5)  
+#define LSM303C_MAG_FS_16_GA                 ((uint8_t) 0x03 << 5)  /*!< Full scale = ±16 Gauss */
+/**
+  * @}
+  */ 
+
+/** @defgroup Mag_Reboot
+  * @{
+  */ 
+#define LSM303C_MAG_REBOOT_DEFAULT           ((uint8_t) 0x00 << 3)
+#define LSM303C_MAG_REBOOT_ENABLE            ((uint8_t) 0x01 << 3)
+/**
+  * @}
+  */ 
+   
+/** @defgroup Mag_Soft_reset
+  * @{
+  */ 
+#define LSM303C_MAG_SOFT_RESET_DEFAULT       ((uint8_t) 0x00 << 2)
+#define LSM303C_MAG_SOFT_RESET_ENABLE        ((uint8_t) 0x01 << 2)
+/**
+  * @}
+  */ 
+   
+/** @defgroup Mag_Communication_Mode 
+  * @{
+  */ 
+#define LSM303C_MAG_I2C_MODE                 ((uint8_t) 0x80)
+#define LSM303C_MAG_SPI_MODE                 ((uint8_t) 0x04)
+/**
+  * @}
+  */
+   
+/** @defgroup Mag_Lowpower_mode_config 
+  * @{
+  */ 
+#define LSM303C_MAG_CONFIG_NORMAL_MODE       ((uint8_t) 0x00)
+#define LSM303C_MAG_CONFIG_LOWPOWER_MODE     ((uint8_t) 0x20)
+/**
+  * @}
+  */   
+   
+/** @defgroup Mag_Operation_Mode 
+  * @{
+  */ 
+#define LSM303C_MAG_SELECTION_MODE           ((uint8_t) 0x03)
+#define LSM303C_MAG_CONTINUOUS_MODE          ((uint8_t) 0x00)
+#define LSM303C_MAG_SINGLE_MODE              ((uint8_t) 0x01)
+#define LSM303C_MAG_POWERDOWN1_MODE          ((uint8_t) 0x02)
+#define LSM303C_MAG_POWERDOWN2_MODE          ((uint8_t) 0x03)
+   
+/**
+  * @}
+  */
+
+/** @defgroup Mag_Z-axis_Operation_Mode 
+  * @{
+  */ 
+#define LSM303C_MAG_OM_Z_LOWPOWER            ((uint8_t) 0x00 << 2)
+#define LSM303C_MAG_OM_Z_MEDIUM              ((uint8_t) 0x01 << 2)
+#define LSM303C_MAG_OM_Z_HIGH                ((uint8_t) 0x02 << 2)
+#define LSM303C_MAG_OM_Z_ULTRAHIGH           ((uint8_t) 0x03 << 2)   
+   
+/**
+  * @}
+  */   
+
+/** @defgroup Mag_Big_little-endian_selection 
+  * @{
+  */ 
+#define LSM303C_MAG_BLE_LSB                  ((uint8_t) 0x00)
+#define LSM303C_MAG_BLE_MSB                  ((uint8_t) 0x02)
+/**
+  * @}
+  */   
+
+/** @defgroup Mag_Bloc_update_magnetic_data 
+  * @{
+  */ 
+#define LSM303C_MAG_BDU_CONTINUOUS           ((uint8_t) 0x00)
+#define LSM303C_MAG_BDU_MSBLSB              ((uint8_t) 0x40)
+/**
+  * @}
+  */      
+   
+/**
+ * @defgroup Magnetometer_Sensitivity
+ * @{
+ */
+#define LSM303C_M_SENSITIVITY_XY_1_3Ga     1100  /*!< magnetometer X Y axes sensitivity for 1.3 Ga full scale [LSB/Ga] */
+#define LSM303C_M_SENSITIVITY_XY_1_9Ga     855   /*!< magnetometer X Y axes sensitivity for 1.9 Ga full scale [LSB/Ga] */
+#define LSM303C_M_SENSITIVITY_XY_2_5Ga     670   /*!< magnetometer X Y axes sensitivity for 2.5 Ga full scale [LSB/Ga] */
+#define LSM303C_M_SENSITIVITY_XY_4Ga       450   /*!< magnetometer X Y axes sensitivity for 4 Ga full scale [LSB/Ga] */
+#define LSM303C_M_SENSITIVITY_XY_4_7Ga     400   /*!< magnetometer X Y axes sensitivity for 4.7 Ga full scale [LSB/Ga] */
+#define LSM303C_M_SENSITIVITY_XY_5_6Ga     330   /*!< magnetometer X Y axes sensitivity for 5.6 Ga full scale [LSB/Ga] */
+#define LSM303C_M_SENSITIVITY_XY_8_1Ga     230   /*!< magnetometer X Y axes sensitivity for 8.1 Ga full scale [LSB/Ga] */
+#define LSM303C_M_SENSITIVITY_Z_1_3Ga      980   /*!< magnetometer Z axis sensitivity for 1.3 Ga full scale [LSB/Ga] */
+#define LSM303C_M_SENSITIVITY_Z_1_9Ga      760   /*!< magnetometer Z axis sensitivity for 1.9 Ga full scale [LSB/Ga] */
+#define LSM303C_M_SENSITIVITY_Z_2_5Ga      600   /*!< magnetometer Z axis sensitivity for 2.5 Ga full scale [LSB/Ga] */
+#define LSM303C_M_SENSITIVITY_Z_4Ga        400   /*!< magnetometer Z axis sensitivity for 4 Ga full scale [LSB/Ga] */
+#define LSM303C_M_SENSITIVITY_Z_4_7Ga      355   /*!< magnetometer Z axis sensitivity for 4.7 Ga full scale [LSB/Ga] */
+#define LSM303C_M_SENSITIVITY_Z_5_6Ga      295   /*!< magnetometer Z axis sensitivity for 5.6 Ga full scale [LSB/Ga] */
+#define LSM303C_M_SENSITIVITY_Z_8_1Ga      205   /*!< magnetometer Z axis sensitivity for 8.1 Ga full scale [LSB/Ga] */
+/**
+ * @}
+ */
+
+/** @defgroup Mag_Working_Mode
+  * @{
+  */ 
+#define LSM303C_CONTINUOUS_CONVERSION     ((uint8_t) 0x00)   /*!< Continuous-Conversion Mode */
+#define LSM303C_SINGLE_CONVERSION         ((uint8_t) 0x01)   /*!< Single-Conversion Mode */
+#define LSM303C_SLEEP                     ((uint8_t) 0x02)   /*!< Sleep Mode */                       
+/**
+  * @}
+  */
+
+  
+/** @defgroup LSM303C_Exported_Functions
+  * @{
+  */
+
+
+/* ACC driver structure */
+extern ACCELERO_DrvTypeDef Lsm303cDrv_accelero;
+extern MAGNETO_DrvTypeDef  Lsm303cDrv_magneto;
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */ 
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LSM303C_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/mfxstm32l152/mfxstm32l152.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,1585 @@
+/** 
+  ******************************************************************************
+  * @file    mfxstm32l152.c
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    24-June-2015
+  * @brief   This file provides a set of functions needed to manage the MFXSTM32L152
+  *          IO Expander devices.
+  ******************************************************************************
+  * @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 "mfxstm32l152.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Component
+  * @{
+  */ 
+  
+/** @defgroup MFXSTM32L152
+  * @{
+  */   
+  
+/* Private typedef -----------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Types_Definitions
+  * @{
+  */ 
+ 
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Defines
+  * @{
+  */ 
+#define MFXSTM32L152_MAX_INSTANCE         3
+
+/* Private macro -------------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Macros
+  * @{
+  */ 
+  
+/* Private variables ---------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Variables
+  * @{
+  */ 
+
+/* Touch screen driver structure initialization */  
+TS_DrvTypeDef mfxstm32l152_ts_drv = 
+{
+  mfxstm32l152_Init,
+  mfxstm32l152_ReadID,
+  mfxstm32l152_Reset,
+  
+  mfxstm32l152_TS_Start,
+  mfxstm32l152_TS_DetectTouch,
+  mfxstm32l152_TS_GetXY,
+  
+  mfxstm32l152_TS_EnableIT,
+  mfxstm32l152_TS_ClearIT,
+  mfxstm32l152_TS_ITStatus,
+  mfxstm32l152_TS_DisableIT,
+};
+
+/* IO driver structure initialization */ 
+IO_DrvTypeDef mfxstm32l152_io_drv = 
+{
+  mfxstm32l152_Init,
+  mfxstm32l152_ReadID,
+  mfxstm32l152_Reset,
+  
+  mfxstm32l152_IO_Start,
+  mfxstm32l152_IO_Config,
+  mfxstm32l152_IO_WritePin,
+  mfxstm32l152_IO_ReadPin,
+  
+  mfxstm32l152_IO_EnableIT,
+  mfxstm32l152_IO_DisableIT,
+  mfxstm32l152_IO_ITStatus,
+  mfxstm32l152_IO_ClearIT,
+};
+
+/* IDD driver structure initialization */
+IDD_DrvTypeDef mfxstm32l152_idd_drv =
+{
+  mfxstm32l152_Init,
+  mfxstm32l152_DeInit,
+  mfxstm32l152_ReadID,
+  mfxstm32l152_Reset,
+  mfxstm32l152_LowPower,
+  mfxstm32l152_WakeUp,
+
+  mfxstm32l152_IDD_Start,
+  mfxstm32l152_IDD_Config,
+  mfxstm32l152_IDD_GetValue,
+
+  mfxstm32l152_IDD_EnableIT,
+  mfxstm32l152_IDD_ClearIT,
+  mfxstm32l152_IDD_GetITStatus,
+  mfxstm32l152_IDD_DisableIT,
+
+  mfxstm32l152_Error_EnableIT,
+  mfxstm32l152_Error_ClearIT,
+  mfxstm32l152_Error_GetITStatus,
+  mfxstm32l152_Error_DisableIT,
+  mfxstm32l152_Error_ReadSrc,
+  mfxstm32l152_Error_ReadMsg
+};
+
+
+/* mfxstm32l152 instances by address */
+uint8_t mfxstm32l152[MFXSTM32L152_MAX_INSTANCE] = {0};
+/**
+  * @}
+  */ 
+    
+/* Private function prototypes -----------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Function_Prototypes
+  * @{
+  */
+static uint8_t mfxstm32l152_GetInstance(uint16_t DeviceAddr); 
+static uint8_t  mfxstm32l152_ReleaseInstance(uint16_t DeviceAddr);
+static void mfxstm32l152_reg24_setPinValue(uint16_t DeviceAddr, uint8_t RegisterAddr, uint32_t PinPosition, uint8_t PinValue );
+
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Initialize the mfxstm32l152 and configure the needed hardware resources
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval None
+  */
+void mfxstm32l152_Init(uint16_t DeviceAddr)
+{
+  uint8_t instance;
+  uint8_t empty;
+  
+  /* Check if device instance already exists */
+  instance = mfxstm32l152_GetInstance(DeviceAddr);
+  
+  /* To prevent double initialization */
+  if(instance == 0xFF)
+  {
+    /* Look for empty instance */
+    empty = mfxstm32l152_GetInstance(0);
+    
+    if(empty < MFXSTM32L152_MAX_INSTANCE)
+    {
+      /* Register the current device instance */
+      mfxstm32l152[empty] = DeviceAddr;
+      
+      /* Initialize IO BUS layer */
+      MFX_IO_Init();
+    }
+  }
+  
+  mfxstm32l152_SetIrqOutPinPolarity(DeviceAddr, MFXSTM32L152_OUT_PIN_POLARITY_HIGH);
+  mfxstm32l152_SetIrqOutPinType(DeviceAddr, MFXSTM32L152_OUT_PIN_TYPE_PUSHPULL);
+}
+
+/**
+  * @brief  DeInitialize the mfxstm32l152 and unconfigure the needed hardware resources
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval None
+  */
+void mfxstm32l152_DeInit(uint16_t DeviceAddr)
+{
+  uint8_t instance;
+  
+  /* release existing instance */
+  instance = mfxstm32l152_ReleaseInstance(DeviceAddr);
+  
+  /* De-Init only if instance was previously registered */
+  if(instance != 0xFF)
+  {
+    /* De-Initialize IO BUS layer */
+    MFX_IO_DeInit();
+  }
+}
+
+/**
+  * @brief  Reset the mfxstm32l152 by Software.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @retval None
+  */
+void mfxstm32l152_Reset(uint16_t DeviceAddr)
+{
+  /* Soft Reset */  
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, MFXSTM32L152_SWRST);
+
+  /* Wait for a delay to ensure registers erasing */
+  MFX_IO_Delay(10);
+}
+
+/**
+  * @brief  Put mfxstm32l152 Device in Low Power standby mode
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval None
+  */
+void  mfxstm32l152_LowPower(uint16_t DeviceAddr)
+{
+  /* Enter standby mode */
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, MFXSTM32L152_STANDBY);
+
+  /* enable wakeup pin */
+  MFX_IO_EnableWakeupPin();
+}
+
+/**
+  * @brief  WakeUp mfxstm32l152 from standby mode
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval None
+  */
+void  mfxstm32l152_WakeUp(uint16_t DeviceAddr)
+{
+  uint8_t instance;
+  
+  /* Check if device instance already exists */
+  instance = mfxstm32l152_GetInstance(DeviceAddr);
+  
+  /* if instance does not exist, first initialize pins*/
+  if(instance == 0xFF)
+  {
+    /* enable wakeup pin */
+    MFX_IO_EnableWakeupPin();
+  }
+
+  /* toggle wakeup pin */
+  MFX_IO_Wakeup();
+}
+
+/**
+  * @brief  Read the MFXSTM32L152 IO Expander device ID.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @retval The Device ID (two bytes).
+  */
+uint16_t mfxstm32l152_ReadID(uint16_t DeviceAddr)
+{
+  uint8_t id;
+  
+  /* Wait for a delay to ensure the state of registers */
+  MFX_IO_Delay(1);
+
+  /* Initialize IO BUS layer */
+  MFX_IO_Init();
+  
+  id = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_ID);
+  
+  /* Return the device ID value */
+  return (id);
+}
+
+/**
+  * @brief  Read the MFXSTM32L152 device firmware version.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @retval The Device FW version (two bytes).
+  */
+uint16_t mfxstm32l152_ReadFwVersion(uint16_t DeviceAddr)
+{
+  uint8_t  data[2];
+
+  MFX_IO_ReadMultiple((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_FW_VERSION_MSB, data, sizeof(data)) ;
+
+  /* Recompose MFX firmware value */
+  return ((data[0] << 8) | data[1]);
+}
+
+/**
+  * @brief  Enable the interrupt mode for the selected IT source
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param Source: The interrupt source to be configured, could be:
+  *   @arg  MFXSTM32L152_IRQ_GPIO: IO interrupt 
+  *   @arg  MFXSTM32L152_IRQ_IDD : IDD interrupt    
+  *   @arg  MFXSTM32L152_IRQ_ERROR : Error interrupt    
+  *   @arg  MFXSTM32L152_IRQ_TS_DET : Touch Screen Controller Touch Detected interrupt  
+  *   @arg  MFXSTM32L152_IRQ_TS_NE : Touch Screen FIFO Not Empty  
+  *   @arg  MFXSTM32L152_IRQ_TS_TH : Touch Screen FIFO threshold triggered  
+  *   @arg  MFXSTM32L152_IRQ_TS_FULL : Touch Screen FIFO Full  
+  *   @arg  MFXSTM32L152_IRQ_TS_OVF : Touch Screen FIFO Overflow  
+  * @retval None
+  */  
+void mfxstm32l152_EnableITSource(uint16_t DeviceAddr, uint8_t Source)
+{
+  uint8_t tmp = 0;
+  
+  /* Get the current value of the INT_EN register */
+  tmp = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_SRC_EN);
+
+  /* Set the interrupts to be Enabled */    
+  tmp |= Source; 
+  
+  /* Set the register */
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_SRC_EN, tmp);
+}
+
+/**
+  * @brief  Disable the interrupt mode for the selected IT source
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  Source: The interrupt source to be configured, could be:
+  *   @arg  MFXSTM32L152_IRQ_GPIO: IO interrupt 
+  *   @arg  MFXSTM32L152_IRQ_IDD : IDD interrupt    
+  *   @arg  MFXSTM32L152_IRQ_ERROR : Error interrupt    
+  *   @arg  MFXSTM32L152_IRQ_TS_DET : Touch Screen Controller Touch Detected interrupt  
+  *   @arg  MFXSTM32L152_IRQ_TS_NE : Touch Screen FIFO Not Empty  
+  *   @arg  MFXSTM32L152_IRQ_TS_TH : Touch Screen FIFO threshold triggered  
+  *   @arg  MFXSTM32L152_IRQ_TS_FULL : Touch Screen FIFO Full  
+  *   @arg  MFXSTM32L152_IRQ_TS_OVF : Touch Screen FIFO Overflow  
+  * @retval None
+  */
+void mfxstm32l152_DisableITSource(uint16_t DeviceAddr, uint8_t Source)
+{
+  uint8_t tmp = 0;
+  
+  /* Get the current value of the INT_EN register */
+  tmp = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_SRC_EN);
+
+  /* Set the interrupts to be Enabled */    
+  tmp &= ~Source; 
+  
+  /* Set the register */
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_SRC_EN, tmp);
+}
+
+
+/**
+  * @brief  Returns the selected Global interrupt source pending bit value
+  * @param  DeviceAddr: Device address on communication Bus. 
+  * @param  Source: the Global interrupt source to be checked, could be:
+  *   @arg  MFXSTM32L152_IRQ_GPIO: IO interrupt 
+  *   @arg  MFXSTM32L152_IRQ_IDD : IDD interrupt    
+  *   @arg  MFXSTM32L152_IRQ_ERROR : Error interrupt    
+  *   @arg  MFXSTM32L152_IRQ_TS_DET : Touch Screen Controller Touch Detected interrupt  
+  *   @arg  MFXSTM32L152_IRQ_TS_NE : Touch Screen FIFO Not Empty  
+  *   @arg  MFXSTM32L152_IRQ_TS_TH : Touch Screen FIFO threshold triggered  
+  *   @arg  MFXSTM32L152_IRQ_TS_FULL : Touch Screen FIFO Full  
+  *   @arg  MFXSTM32L152_IRQ_TS_OVF : Touch Screen FIFO Overflow  
+  * @retval The value of the checked Global interrupt source status.
+  */
+uint8_t mfxstm32l152_GlobalITStatus(uint16_t DeviceAddr, uint8_t Source)
+{
+  /* Return the global IT source status (pending or not)*/
+  return((MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_PENDING) & Source));
+}
+
+/**
+  * @brief  Clear the selected Global interrupt pending bit(s)
+  * @param  DeviceAddr: Device address on communication Bus. 
+  * @param  Source: the Global interrupt source to be cleared, could be any combination
+  *         of the below values. The acknowledge signal for MFXSTM32L152_GPIOs configured in input 
+  *         with interrupt is not on this register but in IRQ_GPI_ACK1, IRQ_GPI_ACK2 registers.          
+  *   @arg  MFXSTM32L152_IRQ_IDD : IDD interrupt    
+  *   @arg  MFXSTM32L152_IRQ_ERROR : Error interrupt    
+  *   @arg  MFXSTM32L152_IRQ_TS_DET : Touch Screen Controller Touch Detected interrupt  
+  *   @arg  MFXSTM32L152_IRQ_TS_NE : Touch Screen FIFO Not Empty  
+  *   @arg  MFXSTM32L152_IRQ_TS_TH : Touch Screen FIFO threshold triggered  
+  *   @arg  MFXSTM32L152_IRQ_TS_FULL : Touch Screen FIFO Full  
+  *   @arg  MFXSTM32L152_IRQ_TS_OVF : Touch Screen FIFO Overflow  
+  *  /\/\ IMPORTANT NOTE /\/\ must not use MFXSTM32L152_IRQ_GPIO as argument, see IRQ_GPI_ACK1 and IRQ_GPI_ACK2 registers 
+  * @retval None
+  */
+void mfxstm32l152_ClearGlobalIT(uint16_t DeviceAddr, uint8_t Source)
+{
+  /* Write 1 to the bits that have to be cleared */
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_ACK, Source);
+}
+
+/**
+  * @brief  Set the global interrupt Polarity of IRQ_OUT_PIN.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  Polarity: the IT mode polarity, could be one of the following values:
+  *   @arg  MFXSTM32L152_OUT_PIN_POLARITY_LOW: Interrupt output line is active Low edge      
+  *   @arg  MFXSTM32L152_OUT_PIN_POLARITY_HIGH: Interrupt line output is active High edge              
+  * @retval None
+  */
+void mfxstm32l152_SetIrqOutPinPolarity(uint16_t DeviceAddr, uint8_t Polarity)
+{
+  uint8_t tmp = 0;
+  
+  /* Get the current register value */ 
+  tmp = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_MFX_IRQ_OUT);
+  
+  /* Mask the polarity bits */
+  tmp &= ~(uint8_t)0x02;
+    
+  /* Modify the Interrupt Output line configuration */
+  tmp |= Polarity;
+  
+  /* Set the new register value */
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_MFX_IRQ_OUT, tmp);
+
+  /* Wait for 1 ms for MFX to change IRQ_out pin config, before activate it */
+  MFX_IO_Delay(1);
+  
+}
+
+/**
+  * @brief  Set the global interrupt Type of IRQ_OUT_PIN. 
+  * @param  DeviceAddr: Device address on communication Bus.      
+  * @param  Type: Interrupt line activity type, could be one of the following values:
+  *   @arg  MFXSTM32L152_OUT_PIN_TYPE_OPENDRAIN: Open Drain output Interrupt line          
+  *   @arg  MFXSTM32L152_OUT_PIN_TYPE_PUSHPULL: Push Pull output Interrupt line            
+  * @retval None
+  */
+void mfxstm32l152_SetIrqOutPinType(uint16_t DeviceAddr, uint8_t Type)
+{
+  uint8_t tmp = 0;
+  
+  /* Get the current register value */ 
+  tmp = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_MFX_IRQ_OUT);
+  
+  /* Mask the type bits */
+  tmp &= ~(uint8_t)0x01;
+    
+  /* Modify the Interrupt Output line configuration */
+  tmp |= Type;
+  
+  /* Set the new register value */
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_MFX_IRQ_OUT, tmp);
+
+  /* Wait for 1 ms for MFX to change IRQ_out pin config, before activate it */
+  MFX_IO_Delay(1);
+  
+}
+
+
+/* ------------------------------------------------------------------ */
+/* ----------------------- GPIO ------------------------------------- */
+/* ------------------------------------------------------------------ */
+
+
+/**
+  * @brief  Start the IO functionality used and enable the AF for selected IO pin(s).
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  AF_en: 0 to disable, else enabled. 
+  * @retval None
+  */
+void mfxstm32l152_IO_Start(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  uint8_t mode;
+  
+  /* Get the current register value */
+  mode = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL);
+  
+  /* Set the IO Functionalities to be Enabled */    
+  mode |= MFXSTM32L152_GPIO_EN;  
+  
+  /* Enable ALTERNATE functions */
+  /* AGPIO[0..3] can be either IDD or GPIO */ 
+  /* AGPIO[4..7] can be either TS or GPIO */ 
+  /* if IDD or TS are enabled no matter the value this bit GPIO are not available for those pins */
+  /*  however the MFX will waste some cycles to to handle these potential GPIO (pooling, etc) */ 
+  /* so if IDD and TS are both active it is better to let ALTERNATE off (0) */
+  /* if however IDD or TS are not connected then set it on gives more GPIOs availability */
+  /* remind that AGPIO are less efficient then normal GPIO (They use pooling rather then EXTI */
+  if (IO_Pin > 0xFFFF)
+  {
+    mode |= MFXSTM32L152_ALTERNATE_GPIO_EN;  
+  }
+  else
+  {
+    mode &= ~MFXSTM32L152_ALTERNATE_GPIO_EN;  
+  }  
+
+  /* Write the new register value */  
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode);
+  
+  /* Wait for 1 ms for MFX to change IRQ_out pin config, before activate it */
+  MFX_IO_Delay(1);
+}
+
+/**
+  * @brief  Configures the IO pin(s) according to IO mode structure value.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  IO_Pin: The output pin to be set or reset. This parameter can be one 
+  *         of the following values:   
+  *   @arg  MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+  * @param  IO_Mode: The IO pin mode to configure, could be one of the following values:
+  *   @arg  IO_MODE_INPUT
+  *   @arg  IO_MODE_OUTPUT
+  *   @arg  IO_MODE_IT_RISING_EDGE
+  *   @arg  IO_MODE_IT_FALLING_EDGE
+  *   @arg  IO_MODE_IT_LOW_LEVEL
+  *   @arg  IO_MODE_IT_HIGH_LEVEL            
+  *   @arg  IO_MODE_INPUT_PU,
+  *   @arg  IO_MODE_INPUT_PD,
+  *   @arg  IO_MODE_OUTPUT_OD_PU,
+  *   @arg  IO_MODE_OUTPUT_OD_PD,
+  *   @arg  IO_MODE_OUTPUT_PP_PU,
+  *   @arg  IO_MODE_OUTPUT_PP_PD,
+  *   @arg  IO_MODE_IT_RISING_EDGE_PU
+  *   @arg  IO_MODE_IT_FALLING_EDGE_PU
+  *   @arg  IO_MODE_IT_LOW_LEVEL_PU
+  *   @arg  IO_MODE_IT_HIGH_LEVEL_PU
+  *   @arg  IO_MODE_IT_RISING_EDGE_PD
+  *   @arg  IO_MODE_IT_FALLING_EDGE_PD
+  *   @arg  IO_MODE_IT_LOW_LEVEL_PD
+  *   @arg  IO_MODE_IT_HIGH_LEVEL_PD
+  * @retval None
+  */
+uint8_t mfxstm32l152_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode)
+{
+  uint8_t error_code = 0;
+
+  /* Configure IO pin according to selected IO mode */
+  switch(IO_Mode)
+  {
+  case IO_MODE_OFF: /* Off or analog mode */
+  case IO_MODE_ANALOG: /* Off or analog mode */
+    mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+    break;
+
+  case IO_MODE_INPUT: /* Input mode */
+    mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+    break;
+    
+  case IO_MODE_INPUT_PU: /* Input mode */
+    mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+    break;
+    
+  case IO_MODE_INPUT_PD: /* Input mode */
+    mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+    break;
+
+  case IO_MODE_OUTPUT: /* Output mode */
+  case IO_MODE_OUTPUT_PP_PD: /* Output mode */
+    mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_OUT);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPO_PUSH_PULL);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+    break;
+
+  case IO_MODE_OUTPUT_PP_PU: /* Output mode */
+    mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_OUT);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPO_PUSH_PULL);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+    break;
+
+  case IO_MODE_OUTPUT_OD_PD: /* Output mode */
+    mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_OUT);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPO_OPEN_DRAIN);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+    break;
+
+  case IO_MODE_OUTPUT_OD_PU: /* Output mode */
+    mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_OUT);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPO_OPEN_DRAIN);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+    break;
+
+  case IO_MODE_IT_RISING_EDGE: /* Interrupt rising edge mode */
+    mfxstm32l152_IO_EnableIT(DeviceAddr);
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); 
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+    mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);
+    mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);
+    mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+    break;
+
+  case IO_MODE_IT_RISING_EDGE_PU: /* Interrupt rising edge mode */
+    mfxstm32l152_IO_EnableIT(DeviceAddr);
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+    mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);
+    mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);
+    mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin);  /* last to do: enable IT */
+    break;
+
+  case IO_MODE_IT_RISING_EDGE_PD: /* Interrupt rising edge mode */
+    mfxstm32l152_IO_EnableIT(DeviceAddr);
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+    mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);      
+    mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE); 
+    mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin);  /* last to do: enable IT */
+    break;
+
+  case IO_MODE_IT_FALLING_EDGE: /* Interrupt falling edge mode */
+    mfxstm32l152_IO_EnableIT(DeviceAddr);
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+    mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);
+    mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);
+    mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin);  /* last to do: enable IT */
+    break;
+
+  case IO_MODE_IT_FALLING_EDGE_PU: /* Interrupt falling edge mode */
+    mfxstm32l152_IO_EnableIT(DeviceAddr);
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+    mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);
+    mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);
+    mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin);  /* last to do: enable IT */
+    break;
+
+  case IO_MODE_IT_FALLING_EDGE_PD: /* Interrupt falling edge mode */
+    mfxstm32l152_IO_EnableIT(DeviceAddr);
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); 
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+    mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);    
+    mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE); 
+    mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin);  /* last to do: enable IT */
+    break;
+
+  case IO_MODE_IT_LOW_LEVEL: /* Low level interrupt mode */
+    mfxstm32l152_IO_EnableIT(DeviceAddr);
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); 
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+    mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+    mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);
+    mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin);  /* last to do: enable IT */
+    break;
+
+  case IO_MODE_IT_LOW_LEVEL_PU: /* Low level interrupt mode */
+    mfxstm32l152_IO_EnableIT(DeviceAddr);
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+    mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+    mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);
+    mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin);  /* last to do: enable IT */
+    break;
+
+  case IO_MODE_IT_LOW_LEVEL_PD: /* Low level interrupt mode */
+    mfxstm32l152_IO_EnableIT(DeviceAddr);
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+    mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+    mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);      
+    mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin);  /* last to do: enable IT */
+    break;
+    
+  case IO_MODE_IT_HIGH_LEVEL: /* High level interrupt mode */
+    mfxstm32l152_IO_EnableIT(DeviceAddr);
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN); 
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+    mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+    mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);
+    mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin);  /* last to do: enable IT */
+    break;
+
+  case IO_MODE_IT_HIGH_LEVEL_PU: /* High level interrupt mode */
+    mfxstm32l152_IO_EnableIT(DeviceAddr);
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+    mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+    mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);
+    mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin);  /* last to do: enable IT */
+    break;
+
+  case IO_MODE_IT_HIGH_LEVEL_PD: /* High level interrupt mode */
+    mfxstm32l152_IO_EnableIT(DeviceAddr);
+    mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+    mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+    mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+    mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);  
+    mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin);  /* last to do: enable IT */
+    break;    
+  
+  default:
+    error_code = (uint8_t) IO_Mode;
+    break;    
+  } 
+
+  return error_code;
+}
+
+/**
+  * @brief  Initialize the selected IO pin direction.
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  IO_Pin: The IO pin to be configured. This parameter could be any 
+  *         combination of the following values:
+  *   @arg  MFXSTM32L152_GPIO_PIN_x: Where x can be from 0 to 23.   
+  * @param  Direction: could be MFXSTM32L152_GPIO_DIR_IN or MFXSTM32L152_GPIO_DIR_OUT.      
+  * @retval None
+  */
+void mfxstm32l152_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction)
+{
+  mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_DIR1, IO_Pin, Direction);
+}
+
+/**
+  * @brief  Set the global interrupt Type. 
+  * @param  DeviceAddr: Device address on communication Bus.      
+  * @param  IO_Pin: The IO pin to be configured. This parameter could be any 
+  *         combination of the following values:
+  *   @arg  MFXSTM32L152_GPIO_PIN_x: Where x can be from 0 to 23.   
+  * @param  Evt: Interrupt line activity type, could be one of the following values:
+  *   @arg  MFXSTM32L152_IRQ_GPI_EVT_LEVEL: Interrupt line is active in level model         
+  *   @arg  MFXSTM32L152_IRQ_GPI_EVT_EDGE: Interrupt line is active in edge model           
+  * @retval None
+  */
+void mfxstm32l152_IO_SetIrqEvtMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Evt)
+{
+  mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_EVT1, IO_Pin, Evt);
+  MFX_IO_Delay(1);
+}
+
+/**
+  * @brief  Configure the Edge for which a transition is detectable for the
+  *         selected pin.
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  IO_Pin: The IO pin to be configured. This parameter could be any 
+  *         combination of the following values:
+  *   @arg  MFXSTM32L152_GPIO_PIN_x: Where x can be from 0 to 23.  
+  * @param  Evt: Interrupt line activity type, could be one of the following values:
+  *   @arg  MFXSTM32L152_IRQ_GPI_TYPE_LLFE: Interrupt line is active in Low Level or Falling Edge         
+  *   @arg  MFXSTM32L152_IRQ_GPI_TYPE_HLRE: Interrupt line is active in High Level or Rising Edge           
+  * @retval None
+  */
+void mfxstm32l152_IO_SetIrqTypeMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Type)
+{
+  mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_TYPE1, IO_Pin, Type);
+  MFX_IO_Delay(1);
+}
+
+/**
+  * @brief  When GPIO is in output mode, puts the corresponding GPO in High (1) or Low (0) level.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  IO_Pin: The output pin to be set or reset. This parameter can be one 
+  *         of the following values:
+  *   @arg  MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23. 
+  * @param PinState: The new IO pin state.
+  * @retval None
+  */
+void mfxstm32l152_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState)
+{
+  /* Apply the bit value to the selected pin */
+  if (PinState != 0)
+  {
+    /* Set the SET register */
+	mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPO_SET1, IO_Pin, 1);
+  }
+  else
+  {
+    /* Set the CLEAR register */
+	mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPO_CLR1, IO_Pin, 1);
+  } 
+}
+
+/**
+  * @brief  Return the state of the selected IO pin(s).
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  IO_Pin: The output pin to be set or reset. This parameter can be one 
+  *         of the following values:
+  *   @arg  MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23. 
+  * @retval IO pin(s) state.
+  */
+uint32_t mfxstm32l152_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  uint8_t tmp1;
+  uint16_t tmp2;
+  uint32_t tmp3;
+  
+  tmp1 = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_STATE1);
+  tmp2 = (uint16_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_STATE2);
+  tmp3 = (uint32_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_STATE3);
+  tmp3 = tmp1 + (tmp2 << 8) + (tmp3 << 16);
+  
+  return(tmp3 & IO_Pin);
+}
+
+/**
+  * @brief  Enable the global IO interrupt source.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @retval None
+  */
+void mfxstm32l152_IO_EnableIT(uint16_t DeviceAddr)
+{ 
+  MFX_IO_ITConfig();
+    
+  /* Enable global IO IT source */
+  mfxstm32l152_EnableITSource(DeviceAddr, MFXSTM32L152_IRQ_GPIO);
+}
+
+/**
+  * @brief  Disable the global IO interrupt source.
+  * @param  DeviceAddr: Device address on communication Bus.   
+  * @retval None
+  */
+void mfxstm32l152_IO_DisableIT(uint16_t DeviceAddr)
+{
+  /* Disable global IO IT source */
+  mfxstm32l152_DisableITSource(DeviceAddr, MFXSTM32L152_IRQ_GPIO);    
+}
+  
+/**
+  * @brief  Enable interrupt mode for the selected IO pin(s).
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  IO_Pin: The IO interrupt to be enabled. This parameter could be any 
+  *         combination of the following values:
+  *   @arg  MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+  * @retval None
+  */
+void mfxstm32l152_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_SRC1, IO_Pin, 1);
+}
+
+/**
+  * @brief  Disable interrupt mode for the selected IO pin(s).
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  IO_Pin: The IO interrupt to be disabled. This parameter could be any 
+  *         combination of the following values:
+  *   @arg  MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+  * @retval None
+  */
+void mfxstm32l152_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_SRC1, IO_Pin, 0);
+}
+
+
+/**
+  * @brief  Check the status of the selected IO interrupt pending bit
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  IO_Pin: The IO interrupt to be checked could be:
+  *   @arg  MFXSTM32L152_GPIO_PIN_x Where x can be from 0 to 23.             
+  * @retval Status of the checked IO pin(s).
+  */
+uint32_t mfxstm32l152_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  /* Get the Interrupt status */
+  uint8_t tmp1;
+  uint16_t tmp2;
+  uint32_t tmp3;
+
+  tmp1 = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING1);
+  tmp2 = (uint16_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING2);
+  tmp3 = (uint32_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING3);
+  tmp3 = tmp1 + (tmp2 << 8) + (tmp3 << 16);
+  
+  return(tmp3 & IO_Pin);
+}
+
+/**
+  * @brief  Clear the selected IO interrupt pending bit(s). It clear automatically also the general MFXSTM32L152_REG_ADR_IRQ_PENDING
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  IO_Pin: the IO interrupt to be cleared, could be:
+  *   @arg  MFXSTM32L152_GPIO_PIN_x: Where x can be from 0 to 23.            
+  * @retval None
+  */
+void mfxstm32l152_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  /* Clear the IO IT pending bit(s) by acknowledging */
+  /* it cleans automatically also the Global IRQ_GPIO */
+  /* normally this function is called under interrupt */
+  uint8_t pin_0_7, pin_8_15, pin_16_23;
+
+  pin_0_7   = IO_Pin & 0x0000ff;
+  pin_8_15  = IO_Pin >> 8;
+  pin_8_15   = pin_8_15 & 0x00ff;
+  pin_16_23 = IO_Pin >> 16;
+
+  if (pin_0_7)
+  {
+    MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_ACK1, pin_0_7);
+  }
+  if (pin_8_15)
+  {
+    MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_ACK2, pin_8_15);
+  }
+  if (pin_16_23)
+  {
+    MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_ACK3, pin_16_23);
+  }
+}
+
+
+/**
+  * @brief  Enable the AF for aGPIO.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @retval None
+  */
+void mfxstm32l152_IO_EnableAF(uint16_t DeviceAddr)
+{
+  uint8_t mode;
+
+  /* Get the current register value */
+  mode = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL);
+  
+  /* Enable ALTERNATE functions */
+  /* AGPIO[0..3] can be either IDD or GPIO */ 
+  /* AGPIO[4..7] can be either TS or GPIO */ 
+  /* if IDD or TS are enabled no matter the value this bit GPIO are not available for those pins */
+  /*  however the MFX will waste some cycles to to handle these potential GPIO (pooling, etc) */ 
+  /* so if IDD and TS are both active it is better to let ALTERNATE disabled (0) */
+  /* if however IDD or TS are not connected then set it on gives more GPIOs availability */
+  /* remind that AGPIO are less efficient then normal GPIO (they use pooling rather then EXTI) */
+  mode |= MFXSTM32L152_ALTERNATE_GPIO_EN;  
+ 
+  /* Write the new register value */  
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode);
+}
+
+/**
+  * @brief  Disable the AF for aGPIO.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @retval None
+  */
+ void mfxstm32l152_IO_DisableAF(uint16_t DeviceAddr)
+{
+  uint8_t mode;
+
+  /* Get the current register value */
+  mode = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL);
+  
+  /* Enable ALTERNATE functions */
+  /* AGPIO[0..3] can be either IDD or GPIO */ 
+  /* AGPIO[4..7] can be either TS or GPIO */ 
+  /* if IDD or TS are enabled no matter the value this bit GPIO are not available for those pins */
+  /*  however the MFX will waste some cycles to to handle these potential GPIO (pooling, etc) */ 
+  /* so if IDD and TS are both active it is better to let ALTERNATE disabled (0) */
+  /* if however IDD or TS are not connected then set it on gives more GPIOs availability */
+  /* remind that AGPIO are less efficient then normal GPIO (they use pooling rather then EXTI) */
+  mode &= ~MFXSTM32L152_ALTERNATE_GPIO_EN;  
+ 
+  /* Write the new register value */  
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode);
+  
+}
+
+
+/* ------------------------------------------------------------------ */
+/* --------------------- TOUCH SCREEN ------------------------------- */
+/* ------------------------------------------------------------------ */
+
+/**
+  * @brief  Configures the touch Screen Controller (Single point detection)
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval None.
+  */
+void mfxstm32l152_TS_Start(uint16_t DeviceAddr)
+{
+  uint8_t mode;
+
+  /* Get the current register value */
+  mode = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL);
+  
+  /* Set the Functionalities to be Enabled */    
+  mode |= MFXSTM32L152_TS_EN;  
+  
+  /* Set the new register value */  
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode);
+     
+  /* Wait for 2 ms */
+  MFX_IO_Delay(2); 
+  
+  /* Select 2 nF filter capacitor */
+  /* Configuration: 
+     - Touch average control    : 4 samples
+     - Touch delay time         : 500 uS
+     - Panel driver setting time: 500 uS 
+  */
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_SETTLING, 0x32);
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_TOUCH_DET_DELAY, 0x5);
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_AVE, 0x04);
+  
+  /* Configure the Touch FIFO threshold: single point reading */
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_FIFO_TH, 0x01);
+  
+  /* Clear the FIFO memory content. */
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_FIFO_TH, MFXSTM32L152_TS_CLEAR_FIFO);
+
+  /* Touch screen control configuration :
+     - No window tracking index
+   */
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_TRACK, 0x00);
+  
+ 
+  /*  Clear all the IT status pending bits if any */
+  mfxstm32l152_IO_ClearIT(DeviceAddr, 0xFFFFFF);
+
+  /* Wait for 1 ms delay */
+  MFX_IO_Delay(1);
+}
+
+/**
+  * @brief  Return if there is touch detected or not.
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval Touch detected state.
+  */
+uint8_t mfxstm32l152_TS_DetectTouch(uint16_t DeviceAddr)
+{
+  uint8_t state;
+  uint8_t ret = 0;
+ 
+  state = MFX_IO_Read(DeviceAddr, MFXSTM32L152_TS_FIFO_STA);
+  state = ((state & (uint8_t)MFXSTM32L152_TS_CTRL_STATUS) == (uint8_t)MFXSTM32L152_TS_CTRL_STATUS);
+  
+  if(state > 0)
+  {
+    if(MFX_IO_Read(DeviceAddr, MFXSTM32L152_TS_FIFO_LEVEL) > 0)
+    {
+      ret = 1;
+    }
+  }
+  
+  return ret;
+}
+
+/**
+  * @brief  Get the touch screen X and Y positions values
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  X: Pointer to X position value
+  * @param  Y: Pointer to Y position value   
+  * @retval None.
+  */
+void mfxstm32l152_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y)
+{
+  uint8_t  data_xy[3];
+
+  MFX_IO_ReadMultiple(DeviceAddr, MFXSTM32L152_TS_XY_DATA, data_xy, sizeof(data_xy)) ;
+  
+  /* Calculate positions values */
+  *X = (data_xy[1]<<4) + (data_xy[0]>>4); 
+  *Y = (data_xy[2]<<4) + (data_xy[0]&4); 
+
+  /* Reset the FIFO memory content. */
+  MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_FIFO_TH, MFXSTM32L152_TS_CLEAR_FIFO);
+}
+
+/**
+  * @brief  Configure the selected source to generate a global interrupt or not
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @retval None
+  */
+void mfxstm32l152_TS_EnableIT(uint16_t DeviceAddr)
+{
+  MFX_IO_ITConfig();
+  
+  /* Enable global TS IT source */
+  mfxstm32l152_EnableITSource(DeviceAddr, MFXSTM32L152_IRQ_TS_DET);
+}
+
+/**
+  * @brief  Configure the selected source to generate a global interrupt or not
+  * @param  DeviceAddr: Device address on communication Bus.    
+  * @retval None
+  */
+void mfxstm32l152_TS_DisableIT(uint16_t DeviceAddr)
+{
+  /* Disable global TS IT source */
+  mfxstm32l152_DisableITSource(DeviceAddr, MFXSTM32L152_IRQ_TS_DET);    
+}
+
+/**
+  * @brief  Configure the selected source to generate a global interrupt or not
+  * @param  DeviceAddr: Device address on communication Bus.    
+  * @retval TS interrupts status
+  */
+uint8_t mfxstm32l152_TS_ITStatus(uint16_t DeviceAddr)
+{
+  /* Return TS interrupts status */
+  return(mfxstm32l152_GlobalITStatus(DeviceAddr, MFXSTM32L152_IRQ_TS));
+}
+
+/**
+  * @brief  Configure the selected source to generate a global interrupt or not
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @retval None
+  */
+void mfxstm32l152_TS_ClearIT(uint16_t DeviceAddr)
+{
+  /* Clear the global TS IT source */
+  mfxstm32l152_ClearGlobalIT(DeviceAddr, MFXSTM32L152_IRQ_TS);
+}
+
+/* ------------------------------------------------------------------ */
+/* --------------------- IDD MEASUREMENT ---------------------------- */
+/* ------------------------------------------------------------------ */
+
+/**
+  * @brief  Launch IDD current measurement
+  * @param  DeviceAddr: Device address on communication Bus
+  * @retval None.
+  */
+void mfxstm32l152_IDD_Start(uint16_t DeviceAddr)
+{
+  uint8_t mode = 0;
+
+  /* Get the current register value */
+  mode = MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL);
+
+  /* Set the Functionalities to be enabled */
+  mode |= MFXSTM32L152_IDD_CTRL_REQ;
+
+  /* Start measurement campaign */
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL, mode);
+}
+
+/**
+  * @brief  Configures the IDD current measurement
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  MfxIddConfig: Parameters depending on hardware config.
+  * @retval None
+  */
+void mfxstm32l152_IDD_Config(uint16_t DeviceAddr, IDD_ConfigTypeDef MfxIddConfig)
+{
+  uint8_t value = 0;
+  uint8_t mode = 0;
+
+  /* Get the current register value */
+  mode = MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL);
+
+  if((mode & MFXSTM32L152_IDD_EN) != MFXSTM32L152_IDD_EN)
+  {
+    /* Set the Functionalities to be enabled */
+    mode |= MFXSTM32L152_IDD_EN;
+
+    /* Set the new register value */
+    MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode);
+  }
+
+  /* Control register setting: number of shunts */
+  value =  ((MfxIddConfig.ShuntNbUsed << 1) & MFXSTM32L152_IDD_CTRL_SHUNT_NB);
+  value |= (MfxIddConfig.VrefMeasurement & MFXSTM32L152_IDD_CTRL_VREF_DIS);
+  value |= (MfxIddConfig.Calibration & MFXSTM32L152_IDD_CTRL_CAL_DIS);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL, value);
+
+  /* Idd pre delay configuration: unit and value*/
+  value = (MfxIddConfig.PreDelayUnit & MFXSTM32L152_IDD_PREDELAY_UNIT) |
+          (MfxIddConfig.PreDelayValue & MFXSTM32L152_IDD_PREDELAY_VALUE);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_PRE_DELAY, value);
+
+  /* Shunt 0 register value: MSB then LSB */
+  value = (uint8_t) (MfxIddConfig.Shunt0Value >> 8);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT0_MSB, value);
+  value = (uint8_t) (MfxIddConfig.Shunt0Value);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT0_LSB, value);
+
+  /* Shunt 1 register value: MSB then LSB */
+  value = (uint8_t) (MfxIddConfig.Shunt1Value >> 8);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT1_MSB, value);
+  value = (uint8_t) (MfxIddConfig.Shunt1Value);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT1_LSB, value);
+
+  /* Shunt 2 register value: MSB then LSB */
+  value = (uint8_t) (MfxIddConfig.Shunt2Value >> 8);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT2_MSB, value);
+  value = (uint8_t) (MfxIddConfig.Shunt2Value);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT2_LSB, value);
+
+  /* Shunt 3 register value: MSB then LSB */
+  value = (uint8_t) (MfxIddConfig.Shunt3Value >> 8);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT3_MSB, value);
+  value = (uint8_t) (MfxIddConfig.Shunt3Value);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT3_LSB, value);
+
+  /* Shunt 4 register value: MSB then LSB */
+  value = (uint8_t) (MfxIddConfig.Shunt4Value >> 8);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT4_MSB, value);
+  value = (uint8_t) (MfxIddConfig.Shunt4Value);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT4_LSB, value);
+
+  /* Shunt 0 stabilization delay */
+  value = MfxIddConfig.Shunt0StabDelay;
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH0_STABILIZATION, value);
+
+  /* Shunt 1 stabilization delay */
+  value = MfxIddConfig.Shunt1StabDelay;
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH1_STABILIZATION, value);
+
+  /* Shunt 2 stabilization delay */
+  value = MfxIddConfig.Shunt2StabDelay;
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH2_STABILIZATION, value);
+
+  /* Shunt 3 stabilization delay */
+  value = MfxIddConfig.Shunt3StabDelay;
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH3_STABILIZATION, value);
+
+  /* Shunt 4 stabilization delay */
+  value = MfxIddConfig.Shunt4StabDelay;
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH4_STABILIZATION, value);
+
+  /* Idd ampli gain value: MSB then LSB */
+  value = (uint8_t) (MfxIddConfig.AmpliGain >> 8);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_GAIN_MSB, value);
+  value = (uint8_t) (MfxIddConfig.AmpliGain);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_GAIN_LSB, value);
+
+  /* Idd VDD min value: MSB then LSB */
+  value = (uint8_t) (MfxIddConfig.VddMin >> 8);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_VDD_MIN_MSB, value);
+  value = (uint8_t) (MfxIddConfig.VddMin);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_VDD_MIN_LSB, value);
+
+  /* Idd number of measurements */
+  value = MfxIddConfig.MeasureNb;
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_NBR_OF_MEAS, value);
+
+  /* Idd delta delay configuration: unit and value */
+  value = (MfxIddConfig.DeltaDelayUnit & MFXSTM32L152_IDD_DELTADELAY_UNIT) |
+          (MfxIddConfig.DeltaDelayValue & MFXSTM32L152_IDD_DELTADELAY_VALUE);
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_MEAS_DELTA_DELAY, value);
+
+  /* Idd number of shut on board */
+  value = MfxIddConfig.ShuntNbOnBoard;
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNTS_ON_BOARD, value);
+}
+
+/**
+  * @brief  This function allows to modify number of shunt used for a measurement
+  * @param  DeviceAddr: Device address on communication Bus
+  * @retval None.
+  */
+void mfxstm32l152_IDD_ConfigShuntNbLimit(uint16_t DeviceAddr, uint8_t ShuntNbLimit)
+{
+  uint8_t mode = 0;
+
+  /* Get the current register value */
+  mode = MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL);
+
+  /* Clear number of shunt limit */
+  mode &= ~(MFXSTM32L152_IDD_CTRL_SHUNT_NB);
+
+  /* Clear number of shunt limit */
+  mode |= ((ShuntNbLimit << 1) & MFXSTM32L152_IDD_CTRL_SHUNT_NB);
+
+  /* Write noewx desired limit */
+  MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL, mode);
+}
+
+/**
+  * @brief  Get Idd current value
+  * @param  DeviceAddr: Device address on communication Bus
+  * @param  ReadValue: Pointer on value to be read
+  * @retval Idd value in 10 nA.
+  */
+void mfxstm32l152_IDD_GetValue(uint16_t DeviceAddr, uint32_t *ReadValue)
+{
+  uint8_t  data[3];
+
+  MFX_IO_ReadMultiple((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_VALUE_MSB, data, sizeof(data)) ;
+
+  /* Recompose Idd current value */
+  *ReadValue = (data[0] << 16) | (data[1] << 8) | data[2];
+
+}
+
+/**
+  * @brief  Get Last shunt used for measurement
+  * @param  DeviceAddr: Device address on communication Bus
+  * @retval Last shunt used 
+  */
+uint8_t  mfxstm32l152_IDD_GetShuntUsed(uint16_t DeviceAddr)
+{
+  return(MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT_USED));
+}
+
+/**
+  * @brief  Configure mfx to enable Idd interrupt
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval None
+  */
+void mfxstm32l152_IDD_EnableIT(uint16_t DeviceAddr)
+{
+  MFX_IO_ITConfig();
+
+  /* Enable global IDD interrupt source */
+  mfxstm32l152_EnableITSource(DeviceAddr, MFXSTM32L152_IRQ_IDD);
+}
+
+/**
+  * @brief  Clear Idd global interrupt
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval None
+  */
+void mfxstm32l152_IDD_ClearIT(uint16_t DeviceAddr)
+{
+  /* Clear the global IDD interrupt source */
+  mfxstm32l152_ClearGlobalIT(DeviceAddr, MFXSTM32L152_IRQ_IDD);
+}
+
+/**
+  * @brief  get Idd interrupt status
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval IDD interrupts status
+  */
+uint8_t mfxstm32l152_IDD_GetITStatus(uint16_t DeviceAddr)
+{
+  /* Return IDD interrupt status */
+  return(mfxstm32l152_GlobalITStatus(DeviceAddr, MFXSTM32L152_IRQ_IDD));
+}
+
+/**
+  * @brief  disable Idd interrupt
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval None.
+  */
+void mfxstm32l152_IDD_DisableIT(uint16_t DeviceAddr)
+{
+  /* Disable global IDD interrupt source */
+  mfxstm32l152_DisableITSource(DeviceAddr, MFXSTM32L152_IRQ_IDD);
+}
+
+
+/* ------------------------------------------------------------------ */
+/* --------------------- ERROR MANAGEMENT --------------------------- */
+/* ------------------------------------------------------------------ */
+
+/**
+  * @brief  Read Error Source.
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval Error message code with error source
+  */
+uint8_t mfxstm32l152_Error_ReadSrc(uint16_t DeviceAddr)
+{
+  /* Get the current source register value */
+  return(MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_ERROR_SRC));
+}
+
+/**
+  * @brief  Read Error Message
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval Error message code with error source
+  */
+uint8_t mfxstm32l152_Error_ReadMsg(uint16_t DeviceAddr)
+{
+  /* Get the current message register value */
+  return(MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_ERROR_MSG));
+}
+
+/**
+  * @brief  Enable Error global interrupt
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval None
+  */
+
+void mfxstm32l152_Error_EnableIT(uint16_t DeviceAddr)
+{
+  MFX_IO_ITConfig();
+
+  /* Enable global Error interrupt source */
+  mfxstm32l152_EnableITSource(DeviceAddr, MFXSTM32L152_IRQ_ERROR);
+}
+
+/**
+  * @brief  Clear Error global interrupt
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval None
+  */
+void mfxstm32l152_Error_ClearIT(uint16_t DeviceAddr)
+{
+  /* Clear the global Error interrupt source */
+  mfxstm32l152_ClearGlobalIT(DeviceAddr, MFXSTM32L152_IRQ_ERROR);
+}
+
+/**
+  * @brief  get Error interrupt status
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval Error interrupts status
+  */
+uint8_t mfxstm32l152_Error_GetITStatus(uint16_t DeviceAddr)
+{
+  /* Return Error interrupt status */
+  return(mfxstm32l152_GlobalITStatus(DeviceAddr, MFXSTM32L152_IRQ_ERROR));
+}
+
+/**
+  * @brief  disable Error interrupt
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval None.
+  */
+void mfxstm32l152_Error_DisableIT(uint16_t DeviceAddr)
+{
+  /* Disable global Error interrupt source */
+  mfxstm32l152_DisableITSource(DeviceAddr, MFXSTM32L152_IRQ_ERROR);
+}
+
+/**
+  * @brief  FOR DEBUG ONLY
+  */
+uint8_t mfxstm32l152_ReadReg(uint16_t DeviceAddr, uint8_t RegAddr)
+{
+  /* Get the current register value */ 
+  return(MFX_IO_Read((uint8_t) DeviceAddr, RegAddr));
+}
+
+void mfxstm32l152_WriteReg(uint16_t DeviceAddr, uint8_t RegAddr, uint8_t Value)
+{
+  /* set the current register value */ 
+  MFX_IO_Write((uint8_t) DeviceAddr, RegAddr, Value);
+}
+
+/* ------------------------------------------------------------------ */
+/* ----------------------- Private functions ------------------------ */
+/* ------------------------------------------------------------------ */
+/**
+  * @brief  Check if the device instance of the selected address is already registered
+  *         and return its index  
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval Index of the device instance if registered, 0xFF if not.
+  */
+static uint8_t mfxstm32l152_GetInstance(uint16_t DeviceAddr)
+{
+  uint8_t idx = 0;
+  
+  /* Check all the registered instances */
+  for(idx = 0; idx < MFXSTM32L152_MAX_INSTANCE ; idx ++)
+  {
+    if(mfxstm32l152[idx] == DeviceAddr)
+    {
+      return idx; 
+    }
+  }
+  
+  return 0xFF;
+}
+
+/**
+  * @brief  Release registered device instance
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval Index of released device instance, 0xFF if not.
+  */
+static uint8_t mfxstm32l152_ReleaseInstance(uint16_t DeviceAddr)
+{
+  uint8_t idx = 0;
+  
+  /* Check for all the registered instances */
+  for(idx = 0; idx < MFXSTM32L152_MAX_INSTANCE ; idx ++)
+  {
+    if(mfxstm32l152[idx] == DeviceAddr)
+    {
+      mfxstm32l152[idx] = 0;
+      return idx;
+    }
+  }
+  return 0xFF;
+}
+
+/**
+  * @brief  Internal routine
+  * @param  DeviceAddr: Device address on communication Bus. 
+  * @param  RegisterAddr: Register Address
+  * @param  PinPosition: Pin [0:23]
+  * @param  PinValue: 0/1
+  * @retval None
+  */
+void mfxstm32l152_reg24_setPinValue(uint16_t DeviceAddr, uint8_t RegisterAddr, uint32_t PinPosition, uint8_t PinValue )
+{
+  uint8_t tmp = 0;
+  uint8_t pin_0_7, pin_8_15, pin_16_23;
+
+  pin_0_7   = PinPosition & 0x0000ff;
+  pin_8_15  = PinPosition >> 8;
+  pin_8_15   = pin_8_15 & 0x00ff;
+  pin_16_23 = PinPosition >> 16;
+  
+  if (pin_0_7)
+  {  
+    /* Get the current register value */ 
+    tmp = MFX_IO_Read(DeviceAddr, RegisterAddr);
+  
+    /* Set the selected pin direction */
+    if (PinValue != 0)
+    {
+      tmp |= (uint8_t)pin_0_7;
+    }  
+    else 
+    {
+      tmp &= ~(uint8_t)pin_0_7;
+    }
+  
+    /* Set the new register value */
+    MFX_IO_Write(DeviceAddr, RegisterAddr, tmp);
+  }
+
+  if (pin_8_15)
+  {
+    /* Get the current register value */ 
+    tmp = MFX_IO_Read(DeviceAddr, RegisterAddr+1);
+  
+    /* Set the selected pin direction */
+    if (PinValue != 0)
+    {
+      tmp |= (uint8_t)pin_8_15;
+    }  
+    else 
+    {
+      tmp &= ~(uint8_t)pin_8_15;
+    }
+  
+    /* Set the new register value */
+    MFX_IO_Write(DeviceAddr, RegisterAddr+1, tmp);
+  }  
+
+  if (pin_16_23)
+  {
+    /* Get the current register value */ 
+    tmp = MFX_IO_Read(DeviceAddr, RegisterAddr+2);
+  
+    /* Set the selected pin direction */
+    if (PinValue != 0)
+    {
+      tmp |= (uint8_t)pin_16_23;
+    }  
+    else 
+    {
+      tmp &= ~(uint8_t)pin_16_23;
+    }
+  
+    /* Set the new register value */
+    MFX_IO_Write(DeviceAddr, RegisterAddr+2, tmp);
+  } 
+}
+
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */      
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/mfxstm32l152/mfxstm32l152.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,669 @@
+/**
+  ******************************************************************************
+  * @file    mfxstm32l152.h
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    24-June-2015
+  * @brief   This file contains all the functions prototypes for the
+  *          mfxstm32l152.c IO expander 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 __MFXSTM32L152_H
+#define __MFXSTM32L152_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif   
+   
+/* Includes ------------------------------------------------------------------*/
+#include "../Common/ts.h"
+#include "../Common/io.h"
+#include "../Common/idd.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup Component
+  * @{
+  */
+    
+/** @defgroup MFXSTM32L152
+  * @{
+  */    
+
+/* Exported types ------------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Exported_Types
+  * @{
+  */ 
+typedef struct
+{
+  uint8_t SYS_CTRL;
+  uint8_t ERROR_SRC;
+  uint8_t ERROR_MSG;
+  uint8_t IRQ_OUT;
+  uint8_t IRQ_SRC_EN;
+  uint8_t IRQ_PENDING;
+  uint8_t IDD_CTRL;
+  uint8_t IDD_PRE_DELAY;
+  uint8_t IDD_SHUNT0_MSB;
+  uint8_t IDD_SHUNT0_LSB;
+  uint8_t IDD_SHUNT1_MSB;
+  uint8_t IDD_SHUNT1_LSB;
+  uint8_t IDD_SHUNT2_MSB;
+  uint8_t IDD_SHUNT2_LSB;
+  uint8_t IDD_SHUNT3_MSB;
+  uint8_t IDD_SHUNT3_LSB;
+  uint8_t IDD_SHUNT4_MSB;
+  uint8_t IDD_SHUNT4_LSB;
+  uint8_t IDD_GAIN_MSB;
+  uint8_t IDD_GAIN_LSB;
+  uint8_t IDD_VDD_MIN_MSB;
+  uint8_t IDD_VDD_MIN_LSB;
+  uint8_t IDD_VALUE_MSB;
+  uint8_t IDD_VALUE_MID;
+  uint8_t IDD_VALUE_LSB;
+  uint8_t IDD_CAL_OFFSET_MSB;
+  uint8_t IDD_CAL_OFFSET_LSB;
+  uint8_t IDD_SHUNT_USED;
+}IDD_dbgTypeDef;
+
+/**
+  * @}
+  */
+
+/* Exported constants --------------------------------------------------------*/
+  
+/** @defgroup MFXSTM32L152_Exported_Constants
+  * @{
+  */ 
+
+ /**
+  * @brief  MFX COMMON defines
+  */
+   
+ /**
+  * @brief  Register address: chip IDs (R)
+  */
+#define MFXSTM32L152_REG_ADR_ID                 ((uint8_t)0x00)
+ /**
+  * @brief  Register address: chip FW_VERSION  (R)
+  */
+#define MFXSTM32L152_REG_ADR_FW_VERSION_MSB     ((uint8_t)0x01)
+#define MFXSTM32L152_REG_ADR_FW_VERSION_LSB     ((uint8_t)0x00)
+ /**
+  * @brief  Register address: System Control Register (R/W)
+  */
+#define MFXSTM32L152_REG_ADR_SYS_CTRL           ((uint8_t)0x40)
+ /**
+  * @brief  Register address: Vdd monitoring (R)
+  */
+#define MFXSTM32L152_REG_ADR_VDD_REF_MSB        ((uint8_t)0x06)
+#define MFXSTM32L152_REG_ADR_VDD_REF_LSB        ((uint8_t)0x07)
+ /**
+  * @brief  Register address: Error source
+  */
+#define MFXSTM32L152_REG_ADR_ERROR_SRC          ((uint8_t)0x03)
+ /**
+  * @brief  Register address: Error Message
+  */
+#define MFXSTM32L152_REG_ADR_ERROR_MSG          ((uint8_t)0x04)
+
+ /**
+  * @brief  Reg Addr IRQs: to config the pin that informs Main MCU that MFX events appear
+  */
+#define MFXSTM32L152_REG_ADR_MFX_IRQ_OUT        ((uint8_t)0x41)
+ /**
+  * @brief  Reg Addr IRQs: to select the events which activate the MFXSTM32L152_IRQ_OUT signal
+  */
+#define MFXSTM32L152_REG_ADR_IRQ_SRC_EN         ((uint8_t)0x42)
+ /**
+  * @brief  Reg Addr IRQs: the Main MCU must read the IRQ_PENDING register to know the interrupt reason
+  */
+#define MFXSTM32L152_REG_ADR_IRQ_PENDING        ((uint8_t)0x08)
+ /**
+  * @brief  Reg Addr IRQs: the Main MCU must acknowledge it thanks to a writing access to the IRQ_ACK register
+  */
+#define MFXSTM32L152_REG_ADR_IRQ_ACK            ((uint8_t)0x44)
+   
+  /**
+  * @brief  MFXSTM32L152_REG_ADR_ID choices
+  */
+#define MFXSTM32L152_ID_1                    ((uint8_t)0x7B)
+#define MFXSTM32L152_ID_2                    ((uint8_t)0x79)
+   
+  /**
+  * @brief  MFXSTM32L152_REG_ADR_SYS_CTRL choices
+  */
+#define MFXSTM32L152_SWRST                    ((uint8_t)0x80)
+#define MFXSTM32L152_STANDBY                  ((uint8_t)0x40)
+#define MFXSTM32L152_ALTERNATE_GPIO_EN        ((uint8_t)0x08) /* by the way if IDD and TS are enabled they take automatically the AF pins*/
+#define MFXSTM32L152_IDD_EN                   ((uint8_t)0x04)
+#define MFXSTM32L152_TS_EN                    ((uint8_t)0x02)
+#define MFXSTM32L152_GPIO_EN                  ((uint8_t)0x01)
+
+  /**
+  * @brief  MFXSTM32L152_REG_ADR_ERROR_SRC choices
+  */
+#define MFXSTM32L152_IDD_ERROR_SRC             ((uint8_t)0x04)  /* Error raised by Idd */
+#define MFXSTM32L152_TS_ERROR_SRC              ((uint8_t)0x02)  /* Error raised by Touch Screen */
+#define MFXSTM32L152_GPIO_ERROR_SRC            ((uint8_t)0x01)  /* Error raised by Gpio */
+
+ /**
+  * @brief  MFXSTM32L152_REG_ADR_MFX_IRQ_OUT choices
+  */
+#define MFXSTM32L152_OUT_PIN_TYPE_OPENDRAIN   ((uint8_t)0x00)
+#define MFXSTM32L152_OUT_PIN_TYPE_PUSHPULL    ((uint8_t)0x01)
+#define MFXSTM32L152_OUT_PIN_POLARITY_LOW     ((uint8_t)0x00)
+#define MFXSTM32L152_OUT_PIN_POLARITY_HIGH    ((uint8_t)0x02)
+
+ /**
+   * @brief  REG_ADR_IRQ_SRC_EN, REG_ADR_IRQ_PENDING & REG_ADR_IRQ_ACK choices
+  */
+#define MFXSTM32L152_IRQ_TS_OVF               ((uint8_t)0x80)  /* TouchScreen FIFO Overflow irq*/
+#define MFXSTM32L152_IRQ_TS_FULL              ((uint8_t)0x40)  /* TouchScreen FIFO Full irq*/
+#define MFXSTM32L152_IRQ_TS_TH                ((uint8_t)0x20)  /* TouchScreen FIFO threshold triggered irq*/
+#define MFXSTM32L152_IRQ_TS_NE                ((uint8_t)0x10)  /* TouchScreen FIFO Not Empty irq*/
+#define MFXSTM32L152_IRQ_TS_DET               ((uint8_t)0x08)  /* TouchScreen Detect irq*/
+#define MFXSTM32L152_IRQ_ERROR                ((uint8_t)0x04)  /* Error message from MFXSTM32L152 firmware irq */
+#define MFXSTM32L152_IRQ_IDD                  ((uint8_t)0x02)  /* IDD function irq */
+#define MFXSTM32L152_IRQ_GPIO                 ((uint8_t)0x01)  /* General GPIO irq (only for SRC_EN and PENDING) */
+#define MFXSTM32L152_IRQ_ALL                  ((uint8_t)0xFF)  /* All global interrupts          */
+#define MFXSTM32L152_IRQ_TS                  (MFXSTM32L152_IRQ_TS_DET | MFXSTM32L152_IRQ_TS_NE |  MFXSTM32L152_IRQ_TS_TH | MFXSTM32L152_IRQ_TS_FULL | MFXSTM32L152_IRQ_TS_OVF ) 
+
+   
+ /**
+  * @brief  GPIO: 24 programmable input/output called MFXSTM32L152_GPIO[23:0] are provided
+  */
+
+ /**
+   * @brief  Reg addr: GPIO DIRECTION (R/W): GPIO pins direction: (0) input, (1) output.
+  */
+#define MFXSTM32L152_REG_ADR_GPIO_DIR1          ((uint8_t)0x60)  /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPIO_DIR2          ((uint8_t)0x61)  /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPIO_DIR3          ((uint8_t)0x62)  /* agpio [0:7] */
+ /**
+  * @brief  Reg addr: GPIO TYPE (R/W): If GPIO in output: (0) output push pull, (1) output open drain.
+  *                          If GPIO in input: (0) input without pull resistor, (1) input with pull resistor.
+  */
+#define MFXSTM32L152_REG_ADR_GPIO_TYPE1         ((uint8_t)0x64)  /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPIO_TYPE2         ((uint8_t)0x65)  /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPIO_TYPE3         ((uint8_t)0x66)  /* agpio [0:7] */
+ /**
+  * @brief  Reg addr: GPIO PULL_UP_PULL_DOWN (R/W):  discussion open with Jean Claude
+  */
+#define MFXSTM32L152_REG_ADR_GPIO_PUPD1         ((uint8_t)0x68)  /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPIO_PUPD2         ((uint8_t)0x69)  /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPIO_PUPD3         ((uint8_t)0x6A)  /* agpio [0:7] */
+ /**
+  * @brief  Reg addr: GPIO SET (W): When GPIO is in output mode, write (1) puts the corresponding GPO in High level.
+  */
+#define MFXSTM32L152_REG_ADR_GPO_SET1           ((uint8_t)0x6C)  /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPO_SET2           ((uint8_t)0x6D)  /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPO_SET3           ((uint8_t)0x6E)  /* agpio [0:7] */
+ /**
+  * @brief  Reg addr: GPIO CLEAR (W): When GPIO is in output mode, write (1) puts the corresponding GPO in Low level.
+  */
+#define MFXSTM32L152_REG_ADR_GPO_CLR1           ((uint8_t)0x70)  /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPO_CLR2           ((uint8_t)0x71)  /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPO_CLR3           ((uint8_t)0x72)  /* agpio [0:7] */
+ /**
+  * @brief  Reg addr: GPIO STATE (R): Give state of the GPIO pin.
+  */
+#define MFXSTM32L152_REG_ADR_GPIO_STATE1         ((uint8_t)0x10)  /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPIO_STATE2         ((uint8_t)0x11)  /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPIO_STATE3         ((uint8_t)0x12)  /* agpio [0:7] */
+
+  /**
+  * @brief  GPIO IRQ_GPIs
+  */
+/* GPIOs can INDIVIDUALLY generate interruption to the Main MCU thanks to the MFXSTM32L152_IRQ_OUT signal */
+/* the general MFXSTM32L152_IRQ_GPIO_SRC_EN shall be enabled too          */
+  /**
+  * @brief  GPIO IRQ_GPI_SRC1/2/3 (R/W): registers enable or not the feature to generate irq
+  */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_SRC1       ((uint8_t)0x48)  /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_SRC2       ((uint8_t)0x49)  /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_SRC3       ((uint8_t)0x4A)  /* agpio [0:7] */
+  /**
+  * @brief  GPIO IRQ_GPI_EVT1/2/3 (R/W): Irq generated on level (0) or edge (1).
+  */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_EVT1       ((uint8_t)0x4C)  /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_EVT2       ((uint8_t)0x4D)  /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_EVT3       ((uint8_t)0x4E)  /* agpio [0:7] */
+  /**
+  * @brief  GPIO IRQ_GPI_TYPE1/2/3 (R/W): Irq generated on (0) : Low level or Falling edge. (1) : High level or Rising edge.
+  */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_TYPE1      ((uint8_t)0x50)  /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_TYPE2      ((uint8_t)0x51)  /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_TYPE3      ((uint8_t)0x52)  /* agpio [0:7] */
+  /**
+  * @brief  GPIO IRQ_GPI_PENDING1/2/3 (R): irq occurs
+  */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING1   ((uint8_t)0x0C)  /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING2   ((uint8_t)0x0D)  /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING3   ((uint8_t)0x0E)  /* agpio [0:7] */
+  /**
+  * @brief  GPIO IRQ_GPI_ACK1/2/3 (W): Write (1) to acknowledge IRQ event
+  */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_ACK1       ((uint8_t)0x54)  /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_ACK2       ((uint8_t)0x55)  /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_ACK3       ((uint8_t)0x56)  /* agpio [0:7] */
+
+   
+ /**
+  * @brief  GPIO: IO Pins definition
+  */
+#define MFXSTM32L152_GPIO_PIN_0                  ((uint32_t)0x0001)
+#define MFXSTM32L152_GPIO_PIN_1                  ((uint32_t)0x0002)
+#define MFXSTM32L152_GPIO_PIN_2                  ((uint32_t)0x0004)
+#define MFXSTM32L152_GPIO_PIN_3                  ((uint32_t)0x0008)
+#define MFXSTM32L152_GPIO_PIN_4                  ((uint32_t)0x0010)
+#define MFXSTM32L152_GPIO_PIN_5                  ((uint32_t)0x0020)
+#define MFXSTM32L152_GPIO_PIN_6                  ((uint32_t)0x0040)
+#define MFXSTM32L152_GPIO_PIN_7                  ((uint32_t)0x0080)
+
+#define MFXSTM32L152_GPIO_PIN_8                  ((uint32_t)0x0100) 
+#define MFXSTM32L152_GPIO_PIN_9                  ((uint32_t)0x0200) 
+#define MFXSTM32L152_GPIO_PIN_10                 ((uint32_t)0x0400) 
+#define MFXSTM32L152_GPIO_PIN_11                 ((uint32_t)0x0800)
+#define MFXSTM32L152_GPIO_PIN_12                 ((uint32_t)0x1000) 
+#define MFXSTM32L152_GPIO_PIN_13                 ((uint32_t)0x2000) 
+#define MFXSTM32L152_GPIO_PIN_14                 ((uint32_t)0x4000) 
+#define MFXSTM32L152_GPIO_PIN_15                 ((uint32_t)0x8000) 
+
+#define MFXSTM32L152_GPIO_PIN_16               ((uint32_t)0x010000)
+#define MFXSTM32L152_GPIO_PIN_17               ((uint32_t)0x020000)
+#define MFXSTM32L152_GPIO_PIN_18               ((uint32_t)0x040000)
+#define MFXSTM32L152_GPIO_PIN_19               ((uint32_t)0x080000)
+#define MFXSTM32L152_GPIO_PIN_20               ((uint32_t)0x100000)
+#define MFXSTM32L152_GPIO_PIN_21               ((uint32_t)0x200000)
+#define MFXSTM32L152_GPIO_PIN_22               ((uint32_t)0x400000)
+#define MFXSTM32L152_GPIO_PIN_23               ((uint32_t)0x800000)
+
+#define MFXSTM32L152_AGPIO_PIN_0               MFXSTM32L152_GPIO_PIN_16
+#define MFXSTM32L152_AGPIO_PIN_1               MFXSTM32L152_GPIO_PIN_17
+#define MFXSTM32L152_AGPIO_PIN_2               MFXSTM32L152_GPIO_PIN_18
+#define MFXSTM32L152_AGPIO_PIN_3               MFXSTM32L152_GPIO_PIN_19
+#define MFXSTM32L152_AGPIO_PIN_4               MFXSTM32L152_GPIO_PIN_20
+#define MFXSTM32L152_AGPIO_PIN_5               MFXSTM32L152_GPIO_PIN_21
+#define MFXSTM32L152_AGPIO_PIN_6               MFXSTM32L152_GPIO_PIN_22
+#define MFXSTM32L152_AGPIO_PIN_7               MFXSTM32L152_GPIO_PIN_23
+
+#define MFXSTM32L152_GPIO_PINS_ALL             ((uint32_t)0xFFFFFF)
+
+ /**
+  * @brief  GPIO: constant
+  */
+#define MFXSTM32L152_GPIO_DIR_IN                ((uint8_t)0x0)  
+#define MFXSTM32L152_GPIO_DIR_OUT               ((uint8_t)0x1)  
+#define MFXSTM32L152_IRQ_GPI_EVT_LEVEL          ((uint8_t)0x0)  
+#define MFXSTM32L152_IRQ_GPI_EVT_EDGE           ((uint8_t)0x1)  
+#define MFXSTM32L152_IRQ_GPI_TYPE_LLFE          ((uint8_t)0x0)  /* Low Level Falling Edge */
+#define MFXSTM32L152_IRQ_GPI_TYPE_HLRE          ((uint8_t)0x1)  /*High Level Raising Edge */
+#define MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR  ((uint8_t)0x0)  
+#define MFXSTM32L152_GPI_WITH_PULL_RESISTOR     ((uint8_t)0x1)  
+#define MFXSTM32L152_GPO_PUSH_PULL              ((uint8_t)0x0)  
+#define MFXSTM32L152_GPO_OPEN_DRAIN             ((uint8_t)0x1)  
+#define MFXSTM32L152_GPIO_PULL_DOWN             ((uint8_t)0x0)  
+#define MFXSTM32L152_GPIO_PULL_UP               ((uint8_t)0x1)   
+   
+   
+  /**
+  * @brief  TOUCH SCREEN Registers
+  */
+
+  /**
+  * @brief  Touch Screen Registers
+  */
+#define MFXSTM32L152_TS_SETTLING            ((uint8_t)0xA0)
+#define MFXSTM32L152_TS_TOUCH_DET_DELAY     ((uint8_t)0xA1)
+#define MFXSTM32L152_TS_AVE                 ((uint8_t)0xA2)
+#define MFXSTM32L152_TS_TRACK               ((uint8_t)0xA3)
+#define MFXSTM32L152_TS_FIFO_TH             ((uint8_t)0xA4)
+#define MFXSTM32L152_TS_FIFO_STA            ((uint8_t)0x20)
+#define MFXSTM32L152_TS_FIFO_LEVEL          ((uint8_t)0x21)
+#define MFXSTM32L152_TS_XY_DATA             ((uint8_t)0x24)
+
+  /**
+  * @brief TS registers masks
+  */
+#define MFXSTM32L152_TS_CTRL_STATUS         ((uint8_t)0x08)
+#define MFXSTM32L152_TS_CLEAR_FIFO          ((uint8_t)0x80)
+
+
+/**
+  * @brief  Register address: Idd control register (R/W)
+  */
+#define MFXSTM32L152_REG_ADR_IDD_CTRL           ((uint8_t)0x80)
+
+/**
+  * @brief  Register address: Idd pre delay  register (R/W)
+  */
+#define MFXSTM32L152_REG_ADR_IDD_PRE_DELAY      ((uint8_t)0x81)
+
+/**
+  * @brief  Register address: Idd Shunt registers (R/W)
+  */
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT0_MSB     ((uint8_t)0x82)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT0_LSB     ((uint8_t)0x83)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT1_MSB     ((uint8_t)0x84)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT1_LSB     ((uint8_t)0x85)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT2_MSB     ((uint8_t)0x86)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT2_LSB     ((uint8_t)0x87)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT3_MSB     ((uint8_t)0x88)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT3_LSB     ((uint8_t)0x89)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT4_MSB     ((uint8_t)0x8A)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT4_LSB     ((uint8_t)0x8B)
+
+/**
+  * @brief  Register address: Idd ampli gain register (R/W)
+  */
+#define MFXSTM32L152_REG_ADR_IDD_GAIN_MSB       ((uint8_t)0x8C)
+#define MFXSTM32L152_REG_ADR_IDD_GAIN_LSB       ((uint8_t)0x8D)
+
+/**
+  * @brief  Register address: Idd VDD min register (R/W)
+  */
+#define MFXSTM32L152_REG_ADR_IDD_VDD_MIN_MSB    ((uint8_t)0x8E)
+#define MFXSTM32L152_REG_ADR_IDD_VDD_MIN_LSB    ((uint8_t)0x8F)
+
+/**
+  * @brief  Register address: Idd value register (R)
+  */
+#define MFXSTM32L152_REG_ADR_IDD_VALUE_MSB      ((uint8_t)0x14)
+#define MFXSTM32L152_REG_ADR_IDD_VALUE_MID      ((uint8_t)0x15)
+#define MFXSTM32L152_REG_ADR_IDD_VALUE_LSB      ((uint8_t)0x16)
+
+/**
+  * @brief  Register address: Idd calibration offset register (R)
+  */
+#define MFXSTM32L152_REG_ADR_IDD_CAL_OFFSET_MSB ((uint8_t)0x18)
+#define MFXSTM32L152_REG_ADR_IDD_CAL_OFFSET_LSB ((uint8_t)0x19)
+
+/**
+  * @brief  Register address: Idd shunt used offset register (R)
+  */
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT_USED     ((uint8_t)0x1A)
+
+/**
+  * @brief  Register address: shunt stabilisation delay registers (R/W)
+  */
+#define MFXSTM32L152_REG_ADR_IDD_SH0_STABILIZATION  ((uint8_t)0x90)
+#define MFXSTM32L152_REG_ADR_IDD_SH1_STABILIZATION  ((uint8_t)0x91)
+#define MFXSTM32L152_REG_ADR_IDD_SH2_STABILIZATION  ((uint8_t)0x92)
+#define MFXSTM32L152_REG_ADR_IDD_SH3_STABILIZATION  ((uint8_t)0x93)
+#define MFXSTM32L152_REG_ADR_IDD_SH4_STABILIZATION  ((uint8_t)0x94)
+
+/**
+  * @brief  Register address: Idd number of measurements register (R/W)
+  */
+#define MFXSTM32L152_REG_ADR_IDD_NBR_OF_MEAS    ((uint8_t)0x96)
+
+/**
+  * @brief  Register address: Idd delta delay between 2 measurements register (R/W)
+  */
+#define MFXSTM32L152_REG_ADR_IDD_MEAS_DELTA_DELAY  ((uint8_t)0x97)
+
+/**
+  * @brief  Register address: Idd number of shunt on board register (R/W)
+  */
+#define MFXSTM32L152_REG_ADR_IDD_SHUNTS_ON_BOARD  ((uint8_t)0x98)
+
+ 
+
+/** @defgroup IDD_Control_Register_Defines  IDD Control Register Defines
+  * @{
+  */
+/**
+  * @brief  IDD control register masks
+  */
+#define MFXSTM32L152_IDD_CTRL_REQ                       ((uint8_t)0x01)
+#define MFXSTM32L152_IDD_CTRL_SHUNT_NB                  ((uint8_t)0x0E)
+#define MFXSTM32L152_IDD_CTRL_VREF_DIS                  ((uint8_t)0x40)
+#define MFXSTM32L152_IDD_CTRL_CAL_DIS                   ((uint8_t)0x80)
+
+/**
+  * @brief  IDD Shunt Number
+  */
+#define MFXSTM32L152_IDD_SHUNT_NB_1                     ((uint8_t) 0x01)
+#define MFXSTM32L152_IDD_SHUNT_NB_2                     ((uint8_t) 0x02)
+#define MFXSTM32L152_IDD_SHUNT_NB_3                     ((uint8_t) 0x03)
+#define MFXSTM32L152_IDD_SHUNT_NB_4                     ((uint8_t) 0x04)
+#define MFXSTM32L152_IDD_SHUNT_NB_5                     ((uint8_t) 0x05)
+
+/**
+  * @brief  Vref Measurement
+  */
+#define MFXSTM32L152_IDD_VREF_AUTO_MEASUREMENT_ENABLE   ((uint8_t) 0x00)
+#define MFXSTM32L152_IDD_VREF_AUTO_MEASUREMENT_DISABLE  ((uint8_t) 0x70)
+
+/**
+  * @brief  IDD Calibration
+  */
+#define MFXSTM32L152_IDD_AUTO_CALIBRATION_ENABLE        ((uint8_t) 0x00)
+#define MFXSTM32L152_IDD_AUTO_CALIBRATION_DISABLE       ((uint8_t) 0x80)
+/**
+  * @}
+  */
+
+/** @defgroup IDD_PreDelay_Defines  IDD PreDelay Defines
+  * @{
+  */
+/**
+  * @brief  IDD PreDelay masks
+  */
+#define MFXSTM32L152_IDD_PREDELAY_UNIT                  ((uint8_t) 0x80)
+#define MFXSTM32L152_IDD_PREDELAY_VALUE                 ((uint8_t) 0x7F)
+
+
+/**
+  * @brief  IDD PreDelay unit
+  */
+#define MFXSTM32L152_IDD_PREDELAY_0_5_MS                ((uint8_t) 0x00)
+#define MFXSTM32L152_IDD_PREDELAY_20_MS                 ((uint8_t) 0x80)
+/**
+  * @}
+  */
+
+/** @defgroup IDD_DeltaDelay_Defines  IDD Delta DElay Defines
+  * @{
+  */
+/**
+  * @brief  IDD Delta Delay masks
+  */
+#define MFXSTM32L152_IDD_DELTADELAY_UNIT                ((uint8_t) 0x80)
+#define MFXSTM32L152_IDD_DELTADELAY_VALUE               ((uint8_t) 0x7F)
+
+
+/**
+  * @brief  IDD Delta Delay unit
+  */
+#define MFXSTM32L152_IDD_DELTADELAY_0_5_MS              ((uint8_t) 0x00)
+#define MFXSTM32L152_IDD_DELTADELAY_20_MS               ((uint8_t) 0x80)
+
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+ 
+/* Exported macro ------------------------------------------------------------*/
+   
+/** @defgroup MFXSTM32L152_Exported_Macros
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+/* Exported functions --------------------------------------------------------*/
+  
+/** @defgroup MFXSTM32L152_Exported_Functions
+  * @{
+  */
+
+/** 
+  * @brief MFXSTM32L152 Control functions
+  */
+void     mfxstm32l152_Init(uint16_t DeviceAddr);
+void     mfxstm32l152_DeInit(uint16_t DeviceAddr);
+void     mfxstm32l152_Reset(uint16_t DeviceAddr);
+uint16_t mfxstm32l152_ReadID(uint16_t DeviceAddr);
+uint16_t mfxstm32l152_ReadFwVersion(uint16_t DeviceAddr);
+void     mfxstm32l152_LowPower(uint16_t DeviceAddr);
+void     mfxstm32l152_WakeUp(uint16_t DeviceAddr);
+
+void     mfxstm32l152_EnableITSource(uint16_t DeviceAddr, uint8_t Source);
+void     mfxstm32l152_DisableITSource(uint16_t DeviceAddr, uint8_t Source);
+uint8_t  mfxstm32l152_GlobalITStatus(uint16_t DeviceAddr, uint8_t Source);
+void     mfxstm32l152_ClearGlobalIT(uint16_t DeviceAddr, uint8_t Source);
+
+void     mfxstm32l152_SetIrqOutPinPolarity(uint16_t DeviceAddr, uint8_t Polarity);
+void     mfxstm32l152_SetIrqOutPinType(uint16_t DeviceAddr, uint8_t Type);
+
+
+/** 
+  * @brief MFXSTM32L152 IO functionalities functions
+  */
+void     mfxstm32l152_IO_Start(uint16_t DeviceAddr, uint32_t IO_Pin);
+uint8_t  mfxstm32l152_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode);
+void     mfxstm32l152_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState);
+uint32_t mfxstm32l152_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin);
+void     mfxstm32l152_IO_EnableIT(uint16_t DeviceAddr);
+void     mfxstm32l152_IO_DisableIT(uint16_t DeviceAddr);
+uint32_t mfxstm32l152_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin);
+void     mfxstm32l152_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin);
+
+void     mfxstm32l152_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction);
+void     mfxstm32l152_IO_EnableAF(uint16_t DeviceAddr);
+void     mfxstm32l152_IO_DisableAF(uint16_t DeviceAddr);
+void     mfxstm32l152_IO_SetIrqTypeMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Type);
+void     mfxstm32l152_IO_SetIrqEvtMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Evt);
+void     mfxstm32l152_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin);
+void     mfxstm32l152_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin);
+
+/** 
+  * @brief MFXSTM32L152 Touch screen functionalities functions
+  */
+void     mfxstm32l152_TS_Start(uint16_t DeviceAddr);
+uint8_t  mfxstm32l152_TS_DetectTouch(uint16_t DeviceAddr);
+void     mfxstm32l152_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y);
+void     mfxstm32l152_TS_EnableIT(uint16_t DeviceAddr);
+void     mfxstm32l152_TS_DisableIT(uint16_t DeviceAddr);
+uint8_t  mfxstm32l152_TS_ITStatus (uint16_t DeviceAddr);
+void     mfxstm32l152_TS_ClearIT (uint16_t DeviceAddr);
+
+/**
+  * @brief MFXSTM32L152 IDD current measurement functionalities functions
+  */
+void     mfxstm32l152_IDD_Start(uint16_t DeviceAddr);
+void     mfxstm32l152_IDD_Config(uint16_t DeviceAddr, IDD_ConfigTypeDef MfxIddConfig);
+void     mfxstm32l152_IDD_ConfigShuntNbLimit(uint16_t DeviceAddr, uint8_t ShuntNbLimit);
+void     mfxstm32l152_IDD_GetValue(uint16_t DeviceAddr, uint32_t *ReadValue);
+uint8_t  mfxstm32l152_IDD_GetShuntUsed(uint16_t DeviceAddr);
+void     mfxstm32l152_IDD_EnableIT(uint16_t DeviceAddr);
+void     mfxstm32l152_IDD_ClearIT(uint16_t DeviceAddr);
+uint8_t  mfxstm32l152_IDD_GetITStatus(uint16_t DeviceAddr);
+void     mfxstm32l152_IDD_DisableIT(uint16_t DeviceAddr);
+
+/**
+  * @brief MFXSTM32L152 Error management functions
+  */
+uint8_t  mfxstm32l152_Error_ReadSrc(uint16_t DeviceAddr);
+uint8_t  mfxstm32l152_Error_ReadMsg(uint16_t DeviceAddr);
+void     mfxstm32l152_Error_EnableIT(uint16_t DeviceAddr);
+void     mfxstm32l152_Error_ClearIT(uint16_t DeviceAddr);
+uint8_t  mfxstm32l152_Error_GetITStatus(uint16_t DeviceAddr);
+void     mfxstm32l152_Error_DisableIT(uint16_t DeviceAddr);
+
+uint8_t  mfxstm32l152_ReadReg(uint16_t DeviceAddr, uint8_t RegAddr);
+void     mfxstm32l152_WriteReg(uint16_t DeviceAddr, uint8_t RegAddr, uint8_t Value);
+
+
+
+/** 
+  * @brief iobus prototypes (they should be defined in common/stm32_iobus.h)
+  */
+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);
+uint16_t MFX_IO_ReadMultiple(uint16_t addr, uint8_t reg, uint8_t *buffer, uint16_t length);
+
+/**
+  * @}
+  */ 
+
+/* Touch screen driver structure */
+extern TS_DrvTypeDef mfxstm32l152_ts_drv;
+
+/* IO driver structure */
+extern IO_DrvTypeDef mfxstm32l152_io_drv;
+
+/* IDD driver structure */
+extern IDD_DrvTypeDef mfxstm32l152_idd_drv;
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __MFXSTM32L152_H */
+
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */       
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/n25q128a/n25q128a.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,220 @@
+/**
+  ******************************************************************************
+  * @file    n25q128a.h
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    29-May-2015
+  * @brief   This file contains all the description of the N25Q128A QSPI memory.
+  ******************************************************************************
+  * @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 __N25Q128A_H
+#define __N25Q128A_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+/* Includes ------------------------------------------------------------------*/
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup Components
+  * @{
+  */ 
+  
+/** @addtogroup n25q128a
+  * @{
+  */
+
+/** @defgroup N25Q128A_Exported_Types
+  * @{
+  */
+   
+/**
+  * @}
+  */ 
+
+/** @defgroup N25Q128A_Exported_Constants
+  * @{
+  */
+   
+/** 
+  * @brief  N25Q128A Configuration  
+  */  
+#define N25Q128A_FLASH_SIZE                  0x1000000 /* 128 MBits => 16MBytes */
+#define N25Q128A_SECTOR_SIZE                 0x10000   /* 256 sectors of 64KBytes */
+#define N25Q128A_SUBSECTOR_SIZE              0x1000    /* 4096 subsectors of 4kBytes */
+#define N25Q128A_PAGE_SIZE                   0x100     /* 65536 pages of 256 bytes */
+
+#define N25Q128A_DUMMY_CYCLES_READ           8
+#define N25Q128A_DUMMY_CYCLES_READ_QUAD      10
+
+#define N25Q128A_BULK_ERASE_MAX_TIME         250000
+#define N25Q128A_SECTOR_ERASE_MAX_TIME       3000
+#define N25Q128A_SUBSECTOR_ERASE_MAX_TIME    800
+
+/** 
+  * @brief  N25Q128A Commands  
+  */  
+/* Reset Operations */
+#define RESET_ENABLE_CMD                     0x66
+#define RESET_MEMORY_CMD                     0x99
+
+/* Identification Operations */
+#define READ_ID_CMD                          0x9E
+#define READ_ID_CMD2                         0x9F
+#define MULTIPLE_IO_READ_ID_CMD              0xAF
+#define READ_SERIAL_FLASH_DISCO_PARAM_CMD    0x5A
+
+/* Read Operations */
+#define READ_CMD                             0x03
+#define FAST_READ_CMD                        0x0B
+#define DUAL_OUT_FAST_READ_CMD               0x3B
+#define DUAL_INOUT_FAST_READ_CMD             0xBB
+#define QUAD_OUT_FAST_READ_CMD               0x6B
+#define QUAD_INOUT_FAST_READ_CMD             0xEB
+
+/* Write Operations */
+#define WRITE_ENABLE_CMD                     0x06
+#define WRITE_DISABLE_CMD                    0x04
+
+/* Register Operations */
+#define READ_STATUS_REG_CMD                  0x05
+#define WRITE_STATUS_REG_CMD                 0x01
+
+#define READ_LOCK_REG_CMD                    0xE8
+#define WRITE_LOCK_REG_CMD                   0xE5
+
+#define READ_FLAG_STATUS_REG_CMD             0x70
+#define CLEAR_FLAG_STATUS_REG_CMD            0x50
+
+#define READ_NONVOL_CFG_REG_CMD              0xB5
+#define WRITE_NONVOL_CFG_REG_CMD             0xB1
+
+#define READ_VOL_CFG_REG_CMD                 0x85
+#define WRITE_VOL_CFG_REG_CMD                0x81
+
+#define READ_ENHANCED_VOL_CFG_REG_CMD        0x65
+#define WRITE_ENHANCED_VOL_CFG_REG_CMD       0x61
+
+/* Program Operations */
+#define PAGE_PROG_CMD                        0x02
+#define DUAL_IN_FAST_PROG_CMD                0xA2
+#define EXT_DUAL_IN_FAST_PROG_CMD            0xD2
+#define QUAD_IN_FAST_PROG_CMD                0x32
+#define EXT_QUAD_IN_FAST_PROG_CMD            0x12
+
+/* Erase Operations */
+#define SUBSECTOR_ERASE_CMD                  0x20
+#define SECTOR_ERASE_CMD                     0xD8
+#define BULK_ERASE_CMD                       0xC7
+
+#define PROG_ERASE_RESUME_CMD                0x7A
+#define PROG_ERASE_SUSPEND_CMD               0x75
+
+/* One-Time Programmable Operations */
+#define READ_OTP_ARRAY_CMD                   0x4B
+#define PROG_OTP_ARRAY_CMD                   0x42
+
+/** 
+  * @brief  N25Q128A Registers  
+  */ 
+/* Status Register */
+#define N25Q128A_SR_WIP                      ((uint8_t)0x01)    /*!< Write in progress */
+#define N25Q128A_SR_WREN                     ((uint8_t)0x02)    /*!< Write enable latch */
+#define N25Q128A_SR_BLOCKPR                  ((uint8_t)0x5C)    /*!< Block protected against program and erase operations */
+#define N25Q128A_SR_PRBOTTOM                 ((uint8_t)0x20)    /*!< Protected memory area defined by BLOCKPR starts from top or bottom */
+#define N25Q128A_SR_SRWREN                   ((uint8_t)0x80)    /*!< Status register write enable/disable */
+
+/* Nonvolatile Configuration Register */
+#define N25Q128A_NVCR_LOCK                   ((uint16_t)0x0001) /*!< Lock nonvolatile configuration register */
+#define N25Q128A_NVCR_DUAL                   ((uint16_t)0x0004) /*!< Dual I/O protocol */
+#define N25Q128A_NVCR_QUAB                   ((uint16_t)0x0008) /*!< Quad I/O protocol */
+#define N25Q128A_NVCR_RH                     ((uint16_t)0x0010) /*!< Reset/hold */
+#define N25Q128A_NVCR_ODS                    ((uint16_t)0x01C0) /*!< Output driver strength */
+#define N25Q128A_NVCR_XIP                    ((uint16_t)0x0E00) /*!< XIP mode at power-on reset */
+#define N25Q128A_NVCR_NB_DUMMY               ((uint16_t)0xF000) /*!< Number of dummy clock cycles */
+
+/* Volatile Configuration Register */
+#define N25Q128A_VCR_WRAP                    ((uint8_t)0x03)    /*!< Wrap */
+#define N25Q128A_VCR_XIP                     ((uint8_t)0x08)    /*!< XIP */
+#define N25Q128A_VCR_NB_DUMMY                ((uint8_t)0xF0)    /*!< Number of dummy clock cycles */
+
+/* Enhanced Volatile Configuration Register */
+#define N25Q128A_EVCR_ODS                    ((uint8_t)0x07)    /*!< Output driver strength */
+#define N25Q128A_EVCR_VPPA                   ((uint8_t)0x08)    /*!< Vpp accelerator */
+#define N25Q128A_EVCR_RH                     ((uint8_t)0x10)    /*!< Reset/hold */
+#define N25Q128A_EVCR_DUAL                   ((uint8_t)0x40)    /*!< Dual I/O protocol */
+#define N25Q128A_EVCR_QUAD                   ((uint8_t)0x80)    /*!< Quad I/O protocol */
+
+/* Flag Status Register */
+#define N25Q128A_FSR_PRERR                   ((uint8_t)0x02)    /*!< Protection error */
+#define N25Q128A_FSR_PGSUS                   ((uint8_t)0x04)    /*!< Program operation suspended */
+#define N25Q128A_FSR_VPPERR                  ((uint8_t)0x08)    /*!< Invalid voltage during program or erase */
+#define N25Q128A_FSR_PGERR                   ((uint8_t)0x10)    /*!< Program error */
+#define N25Q128A_FSR_ERERR                   ((uint8_t)0x20)    /*!< Erase error */
+#define N25Q128A_FSR_ERSUS                   ((uint8_t)0x40)    /*!< Erase operation suspended */
+#define N25Q128A_FSR_READY                   ((uint8_t)0x80)    /*!< Ready or command in progress */
+
+/**
+  * @}
+  */
+  
+/** @defgroup N25Q128A_Exported_Functions
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+      
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+  
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __N25Q128A_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/n25q256a/n25q256a.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,262 @@
+/**
+  ******************************************************************************
+  * @file    n25q256a.h
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    02-March-2015
+  * @brief   This file contains all the description of the N25Q256A QSPI memory.
+  ******************************************************************************
+  * @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 __N25Q256A_H
+#define __N25Q256A_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+/* Includes ------------------------------------------------------------------*/
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup Components
+  * @{
+  */ 
+  
+/** @addtogroup n25q256a
+  * @{
+  */
+
+/** @defgroup N25Q256A_Exported_Types
+  * @{
+  */
+   
+/**
+  * @}
+  */ 
+
+/** @defgroup N25Q256A_Exported_Constants
+  * @{
+  */
+   
+/** 
+  * @brief  N25Q256A Configuration  
+  */  
+#define N25Q256A_FLASH_SIZE                  0x2000000 /* 256 MBits => 32MBytes */
+#define N25Q256A_SECTOR_SIZE                 0x10000   /* 512 sectors of 64KBytes */
+#define N25Q256A_SUBSECTOR_SIZE              0x1000    /* 8192 subsectors of 4kBytes */
+#define N25Q256A_PAGE_SIZE                   0x100     /* 131072 pages of 256 bytes */
+
+#define N25Q256A_DUMMY_CYCLES_READ           8
+#define N25Q256A_DUMMY_CYCLES_READ_QUAD      10
+#define N25Q256A_DUMMY_CYCLES_READ_DTR       6
+#define N25Q256A_DUMMY_CYCLES_READ_QUAD_DTR  8
+
+#define N25Q256A_BULK_ERASE_MAX_TIME         480000
+#define N25Q256A_SECTOR_ERASE_MAX_TIME       3000
+#define N25Q256A_SUBSECTOR_ERASE_MAX_TIME    800
+
+/** 
+  * @brief  N25Q256A Commands  
+  */  
+/* Reset Operations */
+#define RESET_ENABLE_CMD                     0x66
+#define RESET_MEMORY_CMD                     0x99
+
+/* Identification Operations */
+#define READ_ID_CMD                          0x9E
+#define READ_ID_CMD2                         0x9F
+#define MULTIPLE_IO_READ_ID_CMD              0xAF
+#define READ_SERIAL_FLASH_DISCO_PARAM_CMD    0x5A
+
+/* Read Operations */
+#define READ_CMD                             0x03
+#define READ_4_BYTE_ADDR_CMD                 0x13
+
+#define FAST_READ_CMD                        0x0B
+#define FAST_READ_DTR_CMD                    0x0D
+#define FAST_READ_4_BYTE_ADDR_CMD            0x0C
+
+#define DUAL_OUT_FAST_READ_CMD               0x3B
+#define DUAL_OUT_FAST_READ_DTR_CMD           0x3D
+#define DUAL_OUT_FAST_READ_4_BYTE_ADDR_CMD   0x3C
+
+#define DUAL_INOUT_FAST_READ_CMD             0xBB
+#define DUAL_INOUT_FAST_READ_DTR_CMD         0xBD
+#define DUAL_INOUT_FAST_READ_4_BYTE_ADDR_CMD 0xBC
+
+#define QUAD_OUT_FAST_READ_CMD               0x6B
+#define QUAD_OUT_FAST_READ_DTR_CMD           0x6D
+#define QUAD_OUT_FAST_READ_4_BYTE_ADDR_CMD   0x6C
+
+#define QUAD_INOUT_FAST_READ_CMD             0xEB
+#define QUAD_INOUT_FAST_READ_DTR_CMD         0xED
+#define QUAD_INOUT_FAST_READ_4_BYTE_ADDR_CMD 0xEC
+
+/* Write Operations */
+#define WRITE_ENABLE_CMD                     0x06
+#define WRITE_DISABLE_CMD                    0x04
+
+/* Register Operations */
+#define READ_STATUS_REG_CMD                  0x05
+#define WRITE_STATUS_REG_CMD                 0x01
+
+#define READ_LOCK_REG_CMD                    0xE8
+#define WRITE_LOCK_REG_CMD                   0xE5
+
+#define READ_FLAG_STATUS_REG_CMD             0x70
+#define CLEAR_FLAG_STATUS_REG_CMD            0x50
+
+#define READ_NONVOL_CFG_REG_CMD              0xB5
+#define WRITE_NONVOL_CFG_REG_CMD             0xB1
+
+#define READ_VOL_CFG_REG_CMD                 0x85
+#define WRITE_VOL_CFG_REG_CMD                0x81
+
+#define READ_ENHANCED_VOL_CFG_REG_CMD        0x65
+#define WRITE_ENHANCED_VOL_CFG_REG_CMD       0x61
+
+#define READ_EXT_ADDR_REG_CMD                0xC8
+#define WRITE_EXT_ADDR_REG_CMD               0xC5
+
+/* Program Operations */
+#define PAGE_PROG_CMD                        0x02
+#define PAGE_PROG_4_BYTE_ADDR_CMD            0x12
+
+#define DUAL_IN_FAST_PROG_CMD                0xA2
+#define EXT_DUAL_IN_FAST_PROG_CMD            0xD2
+
+#define QUAD_IN_FAST_PROG_CMD                0x32
+#define EXT_QUAD_IN_FAST_PROG_CMD            0x12 /*0x38*/
+#define QUAD_IN_FAST_PROG_4_BYTE_ADDR_CMD    0x34
+
+/* Erase Operations */
+#define SUBSECTOR_ERASE_CMD                  0x20
+#define SUBSECTOR_ERASE_4_BYTE_ADDR_CMD      0x21
+
+#define SECTOR_ERASE_CMD                     0xD8
+#define SECTOR_ERASE_4_BYTE_ADDR_CMD         0xDC
+
+#define BULK_ERASE_CMD                       0xC7
+
+#define PROG_ERASE_RESUME_CMD                0x7A
+#define PROG_ERASE_SUSPEND_CMD               0x75
+
+/* One-Time Programmable Operations */
+#define READ_OTP_ARRAY_CMD                   0x4B
+#define PROG_OTP_ARRAY_CMD                   0x42
+
+/* 4-byte Address Mode Operations */
+#define ENTER_4_BYTE_ADDR_MODE_CMD           0xB7
+#define EXIT_4_BYTE_ADDR_MODE_CMD            0xE9
+
+/* Quad Operations */
+#define ENTER_QUAD_CMD                       0x35
+#define EXIT_QUAD_CMD                        0xF5
+   
+/** 
+  * @brief  N25Q256A Registers  
+  */ 
+/* Status Register */
+#define N25Q256A_SR_WIP                      ((uint8_t)0x01)    /*!< Write in progress */
+#define N25Q256A_SR_WREN                     ((uint8_t)0x02)    /*!< Write enable latch */
+#define N25Q256A_SR_BLOCKPR                  ((uint8_t)0x5C)    /*!< Block protected against program and erase operations */
+#define N25Q256A_SR_PRBOTTOM                 ((uint8_t)0x20)    /*!< Protected memory area defined by BLOCKPR starts from top or bottom */
+#define N25Q256A_SR_SRWREN                   ((uint8_t)0x80)    /*!< Status register write enable/disable */
+
+/* Nonvolatile Configuration Register */
+#define N25Q256A_NVCR_NBADDR                 ((uint16_t)0x0001) /*!< 3-bytes or 4-bytes addressing */
+#define N25Q256A_NVCR_SEGMENT                ((uint16_t)0x0002) /*!< Upper or lower 128Mb segment selected by default */
+#define N25Q256A_NVCR_DUAL                   ((uint16_t)0x0004) /*!< Dual I/O protocol */
+#define N25Q256A_NVCR_QUAB                   ((uint16_t)0x0008) /*!< Quad I/O protocol */
+#define N25Q256A_NVCR_RH                     ((uint16_t)0x0010) /*!< Reset/hold */
+#define N25Q256A_NVCR_ODS                    ((uint16_t)0x01C0) /*!< Output driver strength */
+#define N25Q256A_NVCR_XIP                    ((uint16_t)0x0E00) /*!< XIP mode at power-on reset */
+#define N25Q256A_NVCR_NB_DUMMY               ((uint16_t)0xF000) /*!< Number of dummy clock cycles */
+
+/* Volatile Configuration Register */
+#define N25Q256A_VCR_WRAP                    ((uint8_t)0x03)    /*!< Wrap */
+#define N25Q256A_VCR_XIP                     ((uint8_t)0x08)    /*!< XIP */
+#define N25Q256A_VCR_NB_DUMMY                ((uint8_t)0xF0)    /*!< Number of dummy clock cycles */
+
+/* Extended Address Register */
+#define N25Q256A_EAR_A24                     ((uint8_t)0x01)    /*!< Select the lower or upper 128Mb segment */
+
+/* Enhanced Volatile Configuration Register */
+#define N25Q256A_EVCR_ODS                    ((uint8_t)0x07)    /*!< Output driver strength */
+#define N25Q256A_EVCR_VPPA                   ((uint8_t)0x08)    /*!< Vpp accelerator */
+#define N25Q256A_EVCR_RH                     ((uint8_t)0x10)    /*!< Reset/hold */
+#define N25Q256A_EVCR_DUAL                   ((uint8_t)0x40)    /*!< Dual I/O protocol */
+#define N25Q256A_EVCR_QUAD                   ((uint8_t)0x80)    /*!< Quad I/O protocol */
+
+/* Flag Status Register */
+#define N25Q256A_FSR_NBADDR                  ((uint8_t)0x01)    /*!< 3-bytes or 4-bytes addressing */
+#define N25Q256A_FSR_PRERR                   ((uint8_t)0x02)    /*!< Protection error */
+#define N25Q256A_FSR_PGSUS                   ((uint8_t)0x04)    /*!< Program operation suspended */
+#define N25Q256A_FSR_VPPERR                  ((uint8_t)0x08)    /*!< Invalid voltage during program or erase */
+#define N25Q256A_FSR_PGERR                   ((uint8_t)0x10)    /*!< Program error */
+#define N25Q256A_FSR_ERERR                   ((uint8_t)0x20)    /*!< Erase error */
+#define N25Q256A_FSR_ERSUS                   ((uint8_t)0x40)    /*!< Erase operation suspended */
+#define N25Q256A_FSR_READY                   ((uint8_t)0x80)    /*!< Ready or command in progress */
+
+/**
+  * @}
+  */
+  
+/** @defgroup N25Q256A_Exported_Functions
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+      
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __N25Q256A_H */
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+  
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/st7735/st7735.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,472 @@
+/**
+  ******************************************************************************
+  * @file    st7735.c
+  * @author  MCD Application Team
+  * @version V1.1.1
+  * @date    24-November-2014
+  * @brief   This file includes the driver for ST7735 LCD mounted on the Adafruit
+  *          1.8" TFT LCD shield (reference ID 802).
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "st7735.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup Components
+  * @{
+  */ 
+
+/** @addtogroup ST7735
+  * @brief      This file provides a set of functions needed to drive the
+  *             ST7735 LCD.
+  * @{
+  */
+
+/** @defgroup ST7735_Private_TypesDefinitions
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+/** @defgroup ST7735_Private_Defines
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+
+/** @defgroup ST7735_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */  
+
+/** @defgroup ST7735_Private_Variables
+  * @{
+  */ 
+
+
+LCD_DrvTypeDef   st7735_drv = 
+{
+  st7735_Init,
+  0,
+  st7735_DisplayOn,
+  st7735_DisplayOff,
+  st7735_SetCursor,
+  st7735_WritePixel,
+  0,
+  st7735_SetDisplayWindow,
+  st7735_DrawHLine,
+  st7735_DrawVLine,
+  st7735_GetLcdPixelWidth,
+  st7735_GetLcdPixelHeight,
+  st7735_DrawBitmap,
+};
+
+static uint16_t ArrayRGB[320] = {0};
+
+/**
+* @}
+*/ 
+
+/** @defgroup ST7735_Private_FunctionPrototypes
+  * @{
+  */
+
+/**
+* @}
+*/ 
+
+/** @defgroup ST7735_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Initialize the ST7735 LCD Component.
+  * @param  None
+  * @retval None
+  */
+void st7735_Init(void)
+{    
+  uint8_t data = 0;
+  
+  /* Initialize ST7735 low level bus layer -----------------------------------*/
+  LCD_IO_Init();
+  /* Out of sleep mode, 0 args, no delay */
+  st7735_WriteReg(LCD_REG_17, 0x00); 
+  /* Frame rate ctrl - normal mode, 3 args:Rate = fosc/(1x2+40) * (LINE+2C+2D)*/
+  LCD_IO_WriteReg(LCD_REG_177);
+  data = 0x01;
+  LCD_IO_WriteMultipleData(&data, 1);
+  data = 0x2C;
+  LCD_IO_WriteMultipleData(&data, 1);
+  data = 0x2D;
+  LCD_IO_WriteMultipleData(&data, 1);
+  /* Frame rate control - idle mode, 3 args:Rate = fosc/(1x2+40) * (LINE+2C+2D) */    
+  st7735_WriteReg(LCD_REG_178, 0x01);
+  st7735_WriteReg(LCD_REG_178, 0x2C);
+  st7735_WriteReg(LCD_REG_178, 0x2D);
+  /* Frame rate ctrl - partial mode, 6 args: Dot inversion mode, Line inversion mode */ 
+  st7735_WriteReg(LCD_REG_179, 0x01);
+  st7735_WriteReg(LCD_REG_179, 0x2C);
+  st7735_WriteReg(LCD_REG_179, 0x2D);
+  st7735_WriteReg(LCD_REG_179, 0x01);
+  st7735_WriteReg(LCD_REG_179, 0x2C);
+  st7735_WriteReg(LCD_REG_179, 0x2D);
+  /* Display inversion ctrl, 1 arg, no delay: No inversion */
+  st7735_WriteReg(LCD_REG_180, 0x07);
+  /* Power control, 3 args, no delay: -4.6V , AUTO mode */
+  st7735_WriteReg(LCD_REG_192, 0xA2);
+  st7735_WriteReg(LCD_REG_192, 0x02);
+  st7735_WriteReg(LCD_REG_192, 0x84);
+  /* Power control, 1 arg, no delay: VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD */
+  st7735_WriteReg(LCD_REG_193, 0xC5);
+  /* Power control, 2 args, no delay: Opamp current small, Boost frequency */ 
+  st7735_WriteReg(LCD_REG_194, 0x0A);
+  st7735_WriteReg(LCD_REG_194, 0x00);
+  /* Power control, 2 args, no delay: BCLK/2, Opamp current small & Medium low */  
+  st7735_WriteReg(LCD_REG_195, 0x8A);
+  st7735_WriteReg(LCD_REG_195, 0x2A);
+  /* Power control, 2 args, no delay */
+  st7735_WriteReg(LCD_REG_196, 0x8A);
+  st7735_WriteReg(LCD_REG_196, 0xEE);
+  /* Power control, 1 arg, no delay */
+  st7735_WriteReg(LCD_REG_197, 0x0E);
+  /* Don't invert display, no args, no delay */
+  LCD_IO_WriteReg(LCD_REG_32);
+  /* Set color mode, 1 arg, no delay: 16-bit color */
+  st7735_WriteReg(LCD_REG_58, 0x05);
+  /* Column addr set, 4 args, no delay: XSTART = 0, XEND = 127 */
+  LCD_IO_WriteReg(LCD_REG_42);
+  data = 0x00;
+  LCD_IO_WriteMultipleData(&data, 1);
+  LCD_IO_WriteMultipleData(&data, 1);
+  LCD_IO_WriteMultipleData(&data, 1);
+  data = 0x7F;
+  LCD_IO_WriteMultipleData(&data, 1);
+  /* Row addr set, 4 args, no delay: YSTART = 0, YEND = 159 */
+  LCD_IO_WriteReg(LCD_REG_43);
+  data = 0x00;
+  LCD_IO_WriteMultipleData(&data, 1);
+  LCD_IO_WriteMultipleData(&data, 1);
+  LCD_IO_WriteMultipleData(&data, 1);
+  data = 0x9F;
+  LCD_IO_WriteMultipleData(&data, 1);
+  /* Magical unicorn dust, 16 args, no delay */
+  st7735_WriteReg(LCD_REG_224, 0x02); 
+  st7735_WriteReg(LCD_REG_224, 0x1c);  
+  st7735_WriteReg(LCD_REG_224, 0x07); 
+  st7735_WriteReg(LCD_REG_224, 0x12);
+  st7735_WriteReg(LCD_REG_224, 0x37);  
+  st7735_WriteReg(LCD_REG_224, 0x32);  
+  st7735_WriteReg(LCD_REG_224, 0x29);  
+  st7735_WriteReg(LCD_REG_224, 0x2d);
+  st7735_WriteReg(LCD_REG_224, 0x29);  
+  st7735_WriteReg(LCD_REG_224, 0x25);  
+  st7735_WriteReg(LCD_REG_224, 0x2B);  
+  st7735_WriteReg(LCD_REG_224, 0x39);  
+  st7735_WriteReg(LCD_REG_224, 0x00);  
+  st7735_WriteReg(LCD_REG_224, 0x01);  
+  st7735_WriteReg(LCD_REG_224, 0x03);  
+  st7735_WriteReg(LCD_REG_224, 0x10);
+  /* Sparkles and rainbows, 16 args, no delay */
+  st7735_WriteReg(LCD_REG_225, 0x03);
+  st7735_WriteReg(LCD_REG_225, 0x1d);  
+  st7735_WriteReg(LCD_REG_225, 0x07);  
+  st7735_WriteReg(LCD_REG_225, 0x06);
+  st7735_WriteReg(LCD_REG_225, 0x2E);  
+  st7735_WriteReg(LCD_REG_225, 0x2C);  
+  st7735_WriteReg(LCD_REG_225, 0x29);  
+  st7735_WriteReg(LCD_REG_225, 0x2D);
+  st7735_WriteReg(LCD_REG_225, 0x2E);  
+  st7735_WriteReg(LCD_REG_225, 0x2E);  
+  st7735_WriteReg(LCD_REG_225, 0x37);  
+  st7735_WriteReg(LCD_REG_225, 0x3F);  
+  st7735_WriteReg(LCD_REG_225, 0x00);  
+  st7735_WriteReg(LCD_REG_225, 0x00);  
+  st7735_WriteReg(LCD_REG_225, 0x02);  
+  st7735_WriteReg(LCD_REG_225, 0x10);
+  /* Normal display on, no args, no delay */
+  st7735_WriteReg(LCD_REG_19, 0x00);
+  /* Main screen turn on, no delay */
+  st7735_WriteReg(LCD_REG_41, 0x00);
+  /* Memory access control: MY = 1, MX = 1, MV = 0, ML = 0 */
+  st7735_WriteReg(LCD_REG_54, 0xC0);
+}
+
+/**
+  * @brief  Enables the Display.
+  * @param  None
+  * @retval None
+  */
+void st7735_DisplayOn(void)
+{
+  uint8_t data = 0;
+  LCD_IO_WriteReg(LCD_REG_19);
+  LCD_Delay(10);
+  LCD_IO_WriteReg(LCD_REG_41);
+  LCD_Delay(10);
+  LCD_IO_WriteReg(LCD_REG_54);
+  data = 0xC0;
+  LCD_IO_WriteMultipleData(&data, 1);
+}
+
+/**
+  * @brief  Disables the Display.
+  * @param  None
+  * @retval None
+  */
+void st7735_DisplayOff(void)
+{
+  uint8_t data = 0;
+  LCD_IO_WriteReg(LCD_REG_19);
+  LCD_Delay(10);
+  LCD_IO_WriteReg(LCD_REG_40);
+  LCD_Delay(10);
+  LCD_IO_WriteReg(LCD_REG_54);
+  data = 0xC0;
+  LCD_IO_WriteMultipleData(&data, 1);
+}
+
+/**
+  * @brief  Sets Cursor position.
+  * @param  Xpos: specifies the X position.
+  * @param  Ypos: specifies the Y position.
+  * @retval None
+  */
+void st7735_SetCursor(uint16_t Xpos, uint16_t Ypos)
+{
+  uint8_t data = 0;
+  LCD_IO_WriteReg(LCD_REG_42);
+  data = (Xpos) >> 8;
+  LCD_IO_WriteMultipleData(&data, 1);
+  data = (Xpos) & 0xFF;
+  LCD_IO_WriteMultipleData(&data, 1);
+  LCD_IO_WriteReg(LCD_REG_43); 
+  data = (Ypos) >> 8;
+  LCD_IO_WriteMultipleData(&data, 1);
+  data = (Ypos) & 0xFF;
+  LCD_IO_WriteMultipleData(&data, 1);
+  LCD_IO_WriteReg(LCD_REG_44);
+}
+
+/**
+  * @brief  Writes pixel.   
+  * @param  Xpos: specifies the X position.
+  * @param  Ypos: specifies the Y position.
+  * @param  RGBCode: the RGB pixel color
+  * @retval None
+  */
+void st7735_WritePixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGBCode)
+{
+  uint8_t data = 0;
+  if((Xpos >= ST7735_LCD_PIXEL_WIDTH) || (Ypos >= ST7735_LCD_PIXEL_HEIGHT)) 
+  {
+    return;
+  }
+  
+  /* Set Cursor */
+  st7735_SetCursor(Xpos, Ypos);
+  
+  data = RGBCode >> 8;
+  LCD_IO_WriteMultipleData(&data, 1);
+  data = RGBCode;
+  LCD_IO_WriteMultipleData(&data, 1);
+}  
+
+
+/**
+  * @brief  Writes to the selected LCD register.
+  * @param  LCDReg: Address of the selected register.
+  * @param  LCDRegValue: value to write to the selected register.
+  * @retval None
+  */
+void st7735_WriteReg(uint8_t LCDReg, uint8_t LCDRegValue)
+{
+  LCD_IO_WriteReg(LCDReg);
+  LCD_IO_WriteMultipleData(&LCDRegValue, 1);
+}
+
+/**
+  * @brief  Sets a display window
+  * @param  Xpos:   specifies the X bottom left position.
+  * @param  Ypos:   specifies the Y bottom left position.
+  * @param  Height: display window height.
+  * @param  Width:  display window width.
+  * @retval None
+  */
+void st7735_SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
+{
+  uint8_t data = 0;
+  /* Column addr set, 4 args, no delay: XSTART = Xpos, XEND = (Xpos + Width - 1) */
+  LCD_IO_WriteReg(LCD_REG_42);
+  data = (Xpos) >> 8;
+  LCD_IO_WriteMultipleData(&data, 1);
+  data = (Xpos) & 0xFF;
+  LCD_IO_WriteMultipleData(&data, 1);
+  data = (Xpos + Width - 1) >> 8;
+  LCD_IO_WriteMultipleData(&data, 1);
+  data = (Xpos + Width - 1) & 0xFF;
+  LCD_IO_WriteMultipleData(&data, 1);
+  /* Row addr set, 4 args, no delay: YSTART = Ypos, YEND = (Ypos + Height - 1) */
+  LCD_IO_WriteReg(LCD_REG_43);
+  data = (Ypos) >> 8;
+  LCD_IO_WriteMultipleData(&data, 1);
+  data = (Ypos) & 0xFF;
+  LCD_IO_WriteMultipleData(&data, 1);
+  data = (Ypos + Height - 1) >> 8;
+  LCD_IO_WriteMultipleData(&data, 1);
+  data = (Ypos + Height - 1) & 0xFF;
+  LCD_IO_WriteMultipleData(&data, 1);
+}
+
+/**
+  * @brief  Draws horizontal line.
+  * @param  RGBCode: Specifies the RGB color   
+  * @param  Xpos: specifies the X position.
+  * @param  Ypos: specifies the Y position.
+  * @param  Length: specifies the line length.  
+  * @retval None
+  */
+void st7735_DrawHLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length)
+{
+  uint8_t counter = 0;
+  
+  if(Xpos + Length > ST7735_LCD_PIXEL_WIDTH) return;
+  
+  /* Set Cursor */
+  st7735_SetCursor(Xpos, Ypos);
+  
+  for(counter = 0; counter < Length; counter++)
+  {
+    ArrayRGB[counter] = RGBCode;
+  }
+  LCD_IO_WriteMultipleData((uint8_t*)&ArrayRGB[0], Length * 2);
+}
+
+/**
+  * @brief  Draws vertical line.
+  * @param  RGBCode: Specifies the RGB color   
+  * @param  Xpos: specifies the X position.
+  * @param  Ypos: specifies the Y position.
+  * @param  Length: specifies the line length.  
+  * @retval None
+  */
+void st7735_DrawVLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length)
+{
+  uint8_t counter = 0;
+  
+  if(Ypos + Length > ST7735_LCD_PIXEL_HEIGHT) return;
+  for(counter = 0; counter < Length; counter++)
+  {
+    st7735_WritePixel(Xpos, Ypos + counter, RGBCode);
+  }   
+}
+
+/**
+  * @brief  Gets the LCD pixel Width.
+  * @param  None
+  * @retval The Lcd Pixel Width
+  */
+uint16_t st7735_GetLcdPixelWidth(void)
+{
+  return ST7735_LCD_PIXEL_WIDTH;
+}
+
+/**
+  * @brief  Gets the LCD pixel Height.
+  * @param  None
+  * @retval The Lcd Pixel Height
+  */
+uint16_t st7735_GetLcdPixelHeight(void)
+{                          
+  return ST7735_LCD_PIXEL_HEIGHT;
+}
+
+/**
+  * @brief  Displays a bitmap picture loaded in the internal Flash.
+  * @param  BmpAddress: Bmp picture address in the internal Flash.
+  * @retval None
+  */
+void st7735_DrawBitmap(uint16_t Xpos, uint16_t Ypos, uint8_t *pbmp)
+{
+  uint32_t index = 0, size = 0;
+  
+  /* Read bitmap size */
+  size = *(volatile uint16_t *) (pbmp + 2);
+  size |= (*(volatile uint16_t *) (pbmp + 4)) << 16;
+  /* Get bitmap data address offset */
+  index = *(volatile uint16_t *) (pbmp + 10);
+  index |= (*(volatile uint16_t *) (pbmp + 12)) << 16;
+  size = (size - index)/2;
+  pbmp += index;
+  
+  /* Set GRAM write direction and BGR = 0 */
+  /* Memory access control: MY = 0, MX = 1, MV = 0, ML = 0 */
+  st7735_WriteReg(LCD_REG_54, 0x40);
+
+  /* Set Cursor */
+  st7735_SetCursor(Xpos, Ypos);  
+ 
+  LCD_IO_WriteMultipleData((uint8_t*)pbmp, size*2);
+ 
+  /* Set GRAM write direction and BGR = 0 */
+  /* Memory access control: MY = 1, MX = 1, MV = 0, ML = 0 */
+  st7735_WriteReg(LCD_REG_54, 0xC0);
+}
+
+/**
+* @}
+*/ 
+
+/**
+* @}
+*/ 
+
+/**
+* @}
+*/ 
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/st7735/st7735.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,215 @@
+/**
+  ******************************************************************************
+  * @file    st7735.h
+  * @author  MCD Application Team
+  * @version V1.1.1
+  * @date    24-November-2014
+  * @brief   This file contains all the functions prototypes for the st7735.c
+  *          driver.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __ST7735_H
+#define __ST7735_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+/* Includes ------------------------------------------------------------------*/
+#include "../Common/lcd.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup Components
+  * @{
+  */ 
+  
+/** @addtogroup ST7735
+  * @{
+  */
+
+/** @defgroup ST7735_Exported_Types
+  * @{
+  */
+   
+/**
+  * @}
+  */ 
+
+/** @defgroup ST7735_Exported_Constants
+  * @{
+  */
+      
+/** 
+  * @brief  ST7735 Size  
+  */  
+#define  ST7735_LCD_PIXEL_WIDTH    ((uint16_t)128)
+#define  ST7735_LCD_PIXEL_HEIGHT   ((uint16_t)160)
+
+/** 
+  * @brief  ST7735 Registers  
+  */ 
+#define  LCD_REG_0               0x00 /* No Operation: NOP */
+#define  LCD_REG_1               0x01 /* Software reset: SWRESET */
+#define  LCD_REG_4               0x04 /* Read Display ID: RDDID */
+#define  LCD_REG_9               0x09 /* Read Display Statu: RDDST */
+#define  LCD_REG_10              0x0A /* Read Display Power: RDDPM */
+#define  LCD_REG_11              0x0B /* Read Display: RDDMADCTL */
+#define  LCD_REG_12              0x0C /* Read Display Pixel: RDDCOLMOD */  
+#define  LCD_REG_13              0x0D /* Read Display Image: RDDIM */
+#define  LCD_REG_14              0x0E /* Read Display Signal: RDDSM */                           
+#define  LCD_REG_16              0x10 /* Sleep in & booster off: SLPIN */ 
+#define  LCD_REG_17              0x11 /* Sleep out & booster on: SLPOUT */
+#define  LCD_REG_18              0x12 /* Partial mode on: PTLON */ 
+#define  LCD_REG_19              0x13 /* Partial off (Normal): NORON */
+#define  LCD_REG_32              0x20 /* Display inversion off: INVOFF */
+#define  LCD_REG_33              0x21 /* Display inversion on: INVON */
+#define  LCD_REG_38              0x26 /* Gamma curve select: GAMSET */
+#define  LCD_REG_40              0x28 /* Display off: DISPOFF */
+#define  LCD_REG_41              0x29 /* Display on: DISPON */
+#define  LCD_REG_42              0x2A /* Column address set: CASET */ 
+#define  LCD_REG_43              0x2B /* Row address set: RASET */
+#define  LCD_REG_44              0x2C /* Memory write: RAMWR */  
+#define  LCD_REG_45              0x2D /* LUT for 4k,65k,262k color: RGBSET */
+#define  LCD_REG_46              0x2E /* Memory read: RAMRD*/
+#define  LCD_REG_48              0x30 /* Partial start/end address set: PTLAR */ 
+#define  LCD_REG_52              0x34 /* Tearing effect line off: TEOFF */ 
+#define  LCD_REG_53              0x35 /* Tearing effect mode set & on: TEON */ 
+#define  LCD_REG_54              0x36 /* Memory data access control: MADCTL */ 
+#define  LCD_REG_56              0x38 /* Idle mode off: IDMOFF */ 
+#define  LCD_REG_57              0x39 /* Idle mode on: IDMON */ 
+#define  LCD_REG_58              0x3A /* Interface pixel format: COLMOD */
+#define  LCD_REG_177             0xB1 /* In normal mode (Full colors): FRMCTR1 */
+#define  LCD_REG_178             0xB2 /* In Idle mode (8-colors): FRMCTR2 */   
+#define  LCD_REG_179             0xB3 /* In partial mode + Full colors: FRMCTR3 */ 
+#define  LCD_REG_180             0xB4 /* Display inversion control: INVCTR */
+#define  LCD_REG_192             0xC0 /* Power control setting: PWCTR1 */ 
+#define  LCD_REG_193             0xC1 /* Power control setting: PWCTR2 */ 
+#define  LCD_REG_194             0xC2 /* In normal mode (Full colors): PWCTR3 */
+#define  LCD_REG_195             0xC3 /* In Idle mode (8-colors): PWCTR4 */ 
+#define  LCD_REG_196             0xC4 /* In partial mode + Full colors: PWCTR5 */ 
+#define  LCD_REG_197             0xC5 /* VCOM control 1: VMCTR1 */ 
+#define  LCD_REG_199             0xC7 /* Set VCOM offset control: VMOFCTR */ 
+#define  LCD_REG_209             0xD1 /* Set LCM version code: WRID2 */ 
+#define  LCD_REG_210             0xD2 /* Customer Project code: WRID3 */ 
+#define  LCD_REG_217             0xD9 /* NVM control status: NVCTR1 */
+#define  LCD_REG_218             0xDA /* Read ID1: RDID1 */ 
+#define  LCD_REG_219             0xDB /* Read ID2: RDID2 */ 
+#define  LCD_REG_220             0xDC /* Read ID3: RDID3 */ 
+#define  LCD_REG_222             0xDE /* NVM Read Command: NVCTR2 */ 
+#define  LCD_REG_223             0xDF /* NVM Write Command: NVCTR3 */
+#define  LCD_REG_224             0xE0 /* Set Gamma adjustment (+ polarity): GAMCTRP1 */                          
+#define  LCD_REG_225             0xE1 /* Set Gamma adjustment (- polarity): GAMCTRN1 */ 
+
+/** 
+  * @brief  LCD Lines depending on the chosen fonts.  
+  */
+#define LCD_LINE_0               LINE(0)
+#define LCD_LINE_1               LINE(1)
+#define LCD_LINE_2               LINE(2)
+#define LCD_LINE_3               LINE(3)
+#define LCD_LINE_4               LINE(4)
+#define LCD_LINE_5               LINE(5)
+#define LCD_LINE_6               LINE(6)
+#define LCD_LINE_7               LINE(7)
+#define LCD_LINE_8               LINE(8)
+#define LCD_LINE_9               LINE(9)
+#define LCD_LINE_10              LINE(10)
+#define LCD_LINE_11              LINE(11)
+#define LCD_LINE_12              LINE(12)
+#define LCD_LINE_13              LINE(13)
+#define LCD_LINE_14              LINE(14)
+#define LCD_LINE_15              LINE(15)
+#define LCD_LINE_16              LINE(16)
+#define LCD_LINE_17              LINE(17)
+#define LCD_LINE_18              LINE(18)
+#define LCD_LINE_19              LINE(19) 
+   
+/**
+  * @}
+  */
+
+/** @defgroup ADAFRUIT_SPI_LCD_Exported_Functions
+  * @{
+  */ 
+void     st7735_Init(void);
+uint16_t st7735_ReadID(void);
+
+void     st7735_DisplayOn(void);
+void     st7735_DisplayOff(void);
+void     st7735_SetCursor(uint16_t Xpos, uint16_t Ypos);
+void     st7735_WritePixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGBCode);
+void     st7735_WriteReg(uint8_t LCDReg, uint8_t LCDRegValue);
+uint8_t  st7735_ReadReg(uint8_t LCDReg);
+
+void     st7735_SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+void     st7735_DrawHLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length);
+void     st7735_DrawVLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length);
+
+uint16_t st7735_GetLcdPixelWidth(void);
+uint16_t st7735_GetLcdPixelHeight(void);
+void     st7735_DrawBitmap(uint16_t Xpos, uint16_t Ypos, uint8_t *pbmp);
+
+/* LCD driver structure */
+extern LCD_DrvTypeDef   st7735_drv;
+
+/* LCD IO functions */
+void     LCD_IO_Init(void);
+void     LCD_IO_WriteMultipleData(uint8_t *pData, uint32_t Size);
+void     LCD_IO_WriteReg(uint8_t Reg);
+void     LCD_Delay(uint32_t delay);
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ST7735_H */
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */ 
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/stmpe1600/stmpe1600.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,605 @@
+/**
+  ******************************************************************************
+  * @file    stmpe1600.c
+  * @author  MCD Application Team
+  * @version V1.1.0
+  * @date    10-February-2015
+  * @brief   This file provides a set of functions needed to manage the STMPE1600
+  *          IO Expander devices.
+  ******************************************************************************
+  * @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 "stmpe1600.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Components
+  * @{
+  */ 
+  
+/** @defgroup STMPE1600
+  * @{
+  */   
+  
+/* Private typedef -----------------------------------------------------------*/
+
+/** @defgroup STMPE1600_Private_Types_Definitions
+  * @{
+  */ 
+  
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup STMPE1600_Private_Defines
+  * @{
+  */ 
+#define STMPE1600_MAX_INSTANCE        2
+
+/* Private macro -------------------------------------------------------------*/
+
+/** @defgroup STMPE1600_Private_Macros
+  * @{
+  */ 
+  
+/* Private variables ---------------------------------------------------------*/
+static uint16_t tmp = 0;
+
+/** @defgroup STMPE1600_Private_Variables
+  * @{
+  */ 
+/* IO driver structure initialization */  
+IO_DrvTypeDef stmpe1600_io_drv = 
+{
+  stmpe1600_Init,
+  stmpe1600_ReadID,
+  stmpe1600_Reset,
+  stmpe1600_Start,
+  stmpe1600_IO_Config,
+  stmpe1600_IO_WritePin,
+  stmpe1600_IO_ReadPin,
+  0,
+  0,
+  stmpe1600_IO_ITStatus,
+  stmpe1600_IO_ClearIT,
+};
+
+uint8_t stmpe1600[STMPE1600_MAX_INSTANCE] = {0};
+/**
+  * @}
+  */ 
+    
+/* Private function prototypes -----------------------------------------------*/
+
+/** @defgroup STMPE1600_Private_Function_Prototypes
+  * @{
+  */
+static uint8_t stmpe1600_GetInstance(uint16_t DeviceAddr);
+
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup STMPE1600_Private_Functions
+  * @{
+  */ 
+
+/**
+  * @brief  Initialize the stmpe1600 and configure the needed hardware resources
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @retval None
+  */
+void stmpe1600_Init(uint16_t DeviceAddr)
+{
+  uint8_t instance;
+  uint8_t empty;
+  
+  /* Check if device instance already exists */
+  instance = stmpe1600_GetInstance(DeviceAddr);
+  
+  if(instance == 0xFF)
+  {
+    /* Look for empty instance */
+    empty = stmpe1600_GetInstance(0);
+    
+    if(empty < STMPE1600_MAX_INSTANCE)
+    {
+      /* Register the current device instance */
+      stmpe1600[empty] = DeviceAddr;
+      
+      /* Initialize IO BUS layer */
+      IOE_Init(); 
+      
+      /* Generate stmpe1600 Software reset */
+      stmpe1600_Reset(DeviceAddr);
+    }
+  } 
+}
+
+/**
+  * @brief  Configures the touch Screen Controller (Single point detection)
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval None.
+  */
+void stmpe1600_Start(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  /*Configuration already done during the initialization */ 
+}
+
+/**
+  * @brief  Reset the stmpe1600 by Software.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @retval None
+  */
+void stmpe1600_Reset(uint16_t DeviceAddr)
+{
+  /* Power Down the stmpe1600 */
+  IOE_Write(DeviceAddr, STMPE1600_REG_SYS_CTRL, (uint16_t)0x80);
+
+  /* Wait for a delay to ensure registers erasing */
+  IOE_Delay(2); 
+  
+  /* Power On the Codec after the power off: all registers are reinitialized */
+  IOE_Write(DeviceAddr, STMPE1600_REG_SYS_CTRL, (uint16_t)0x00); 
+  
+  /* Wait for a delay to ensure registers erasing */
+  IOE_Delay(2); 
+}
+
+/**
+  * @brief  Read the stmpe1600 device ID.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @retval The Device ID (two bytes).
+  */
+uint16_t stmpe1600_ReadID(uint16_t DeviceAddr)
+{
+  uint8_t tmpData[2] = {0 , 0};
+
+  /* Initialize IO BUS layer */
+  IOE_Init(); 
+  
+  /* Read the stmpe1600 device ID */
+  IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_CHP_ID, tmpData, 2);
+  
+  /* Return the device ID value */
+  return((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8));
+}
+
+/**
+  * @brief  Set the global interrupt Polarity.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  Polarity: could be one of these values; 
+  *   @arg  STMPE1600_POLARITY_LOW: Interrupt line is active Low/Falling edge      
+  *   @arg  STMPE1600_POLARITY_HIGH: Interrupt line is active High/Rising edge               
+  * @retval None
+  */
+void stmpe1600_SetITPolarity(uint16_t DeviceAddr, uint8_t Polarity)
+{
+  uint8_t tmp = 0;
+  
+  /* Get the current register value */ 
+  tmp = IOE_Read(DeviceAddr, STMPE1600_REG_SYS_CTRL);
+  
+  /* Mask the polarity bit */
+  tmp &= ~(uint16_t)0x01;
+    
+  /* Set the Interrupt Output line polarity */
+  tmp |= (uint8_t)Polarity;
+  
+  /* Set the new register value */
+  IOE_Write(DeviceAddr, STMPE1600_REG_SYS_CTRL, tmp);
+}
+
+/**
+  * @brief  Enable the Global interrupt.
+  * @param  DeviceAddr: Device address on communication Bus.        
+  * @retval None
+  */
+void stmpe1600_EnableGlobalIT(uint16_t DeviceAddr)
+{
+  uint8_t tmpData[2] = {0 , 0};
+
+  /* Configure NVIC IT for IOE */
+  IOE_ITConfig();
+  
+  /* Get the current register value */
+  IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_SYS_CTRL, tmpData, 2);
+  
+  tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8));
+  
+  /* Set the global interrupts to be Enabled */    
+  tmp |= (uint16_t)STMPE1600_IT_ENABLE;
+  
+  /* Write Back the Interrupt Control register */
+  IOE_WriteMultiple(DeviceAddr, STMPE1600_REG_SYS_CTRL, (uint8_t *)&tmp, 2); 
+}
+
+/**
+  * @brief  Disable the Global interrupt.
+  * @param  DeviceAddr: Device address on communication Bus.        
+  * @retval None
+  */
+void stmpe1600_DisableGlobalIT(uint16_t DeviceAddr)
+{ 
+  uint8_t tmpData[2] = {0 , 0};
+
+  /* Get the current register value */
+  IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_SYS_CTRL, tmpData, 2);
+  
+  tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8));
+  
+  /* Set the global interrupts to be Enabled */    
+  tmp &= ~(uint16_t)STMPE1600_IT_ENABLE;
+  
+  /* Write Back the Interrupt Control register */
+  IOE_WriteMultiple(DeviceAddr, STMPE1600_REG_SYS_CTRL, (uint8_t *)&tmp, 2); 
+}
+
+/**
+  * @brief  Initialize the selected pin(s) direction.
+  * @param  DeviceAddr: Device address on communication Bus.   
+  * @param  IO_Pin: IO pin(s) to be configured. 
+  *         This parameter could be any combination of the following values:
+  *   @arg  STMPE1600_PIN_x: where x can be from 0 to 15.  
+  * @param  Direction: could be STMPE1600_DIRECTION_IN or STMPE1600_DIRECTION_OUT.      
+  * @retval None
+  */
+void stmpe1600_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction)
+{
+  uint8_t tmpData[2] = {0 , 0};
+  
+  /* Get the current register value */
+  IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_GPDR, tmpData, 2);
+
+  tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8));
+  
+  /* Set the Pin direction */
+  if (Direction != STMPE1600_DIRECTION_IN)
+  {
+    tmp |= (uint16_t)IO_Pin;
+  }  
+  else 
+  {
+    tmp &= ~(uint16_t)IO_Pin;
+  }
+    
+  /* Set the new register value */
+  IOE_WriteMultiple(DeviceAddr, STMPE1600_REG_GPDR, (uint8_t *)&tmp, 2);      
+}
+
+/**
+  * @brief  Configure the IO pin(s) according to IO mode structure value.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  IO_Pin: The output pin to be set or reset. This parameter can be one 
+  *         of the following values:   
+  *   @arg  STMPE1600_PIN_x: where x can be from 0 to 7.
+  * @param  IO_Mode: The IO pin mode to configure, could be one of the following values:
+  *   @arg  IO_MODE_INPUT
+  *   @arg  IO_MODE_OUTPUT
+  *   @arg  IO_MODE_IT_RISING_EDGE
+  *   @arg  IO_MODE_IT_FALLING_EDGE         
+  * @retval 0 if no error, IO_Mode if error
+  */
+uint8_t stmpe1600_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode)
+{
+  uint8_t error_code = 0;
+    uint8_t buffer[2] = {0,0};  
+    
+  /* Configure IO pin according to selected IO mode */
+  switch(IO_Mode)
+  {
+  case IO_MODE_INPUT: /* Input mode */
+    stmpe1600_IO_DisablePinIT(DeviceAddr, IO_Pin);
+    stmpe1600_IO_InitPin(DeviceAddr, IO_Pin, STMPE1600_DIRECTION_IN);
+    break;
+    
+  case IO_MODE_OUTPUT: /* Output mode */
+    stmpe1600_IO_DisablePinIT(DeviceAddr, IO_Pin);
+    stmpe1600_IO_InitPin(DeviceAddr, IO_Pin, STMPE1600_DIRECTION_OUT);
+    break;
+  
+  case IO_MODE_IT_RISING_EDGE: /* Interrupt rising edge mode */
+    stmpe1600_SetITPolarity(DeviceAddr, STMPE1600_POLARITY_HIGH);
+    stmpe1600_IO_EnablePinIT(DeviceAddr, IO_Pin);
+    stmpe1600_IO_InitPin(DeviceAddr, IO_Pin, STMPE1600_DIRECTION_IN); 
+    /* Clear all IO IT pending bits if any */
+    stmpe1600_IO_ClearIT(DeviceAddr, IO_Pin);
+    
+    /* Read GMPR to enable interrupt */
+    IOE_ReadMultiple(DeviceAddr , STMPE1600_REG_GPMR, buffer, 2);
+    break; 
+    
+  case IO_MODE_IT_FALLING_EDGE: /* Interrupt falling edge mode */
+    stmpe1600_SetITPolarity(DeviceAddr, STMPE1600_POLARITY_LOW);
+    stmpe1600_IO_EnablePinIT(DeviceAddr, IO_Pin);
+    stmpe1600_IO_InitPin(DeviceAddr, IO_Pin, STMPE1600_DIRECTION_IN); 
+    
+    /* Clear all IO IT pending bits if any */
+    stmpe1600_IO_ClearIT(DeviceAddr, IO_Pin);
+    
+    /* Read GMPR to enable interrupt */
+    IOE_ReadMultiple(DeviceAddr , STMPE1600_REG_GPMR, buffer, 2);    
+    break;
+
+  default:
+    error_code = (uint8_t) IO_Mode;
+	break;
+  } 
+  return error_code;
+}
+
+/**
+  * @brief  Enable polarity inversion of the selected IO pin(s).
+  * @param  DeviceAddr: Device address on communication Bus.    
+  * @param  IO_Pin: IO pin(s) to be configured.  
+  *         This parameter could be any combination of the following values:
+  *   @arg  STMPE1600_PIN_x: where x can be from 0 to 15. 
+  * @retval None
+  */ 
+void stmpe1600_IO_PolarityInv_Enable(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  uint8_t tmpData[2] = {0 , 0};
+  
+  /* Get the current register value */
+  IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_GPPIR, tmpData, 2);
+  
+  tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8));  
+
+  /* Enable pin polarity inversion */
+  tmp |= (uint16_t)IO_Pin;
+    
+  /* Set the new register value */  
+  IOE_WriteMultiple(DeviceAddr, STMPE1600_REG_GPPIR, (uint8_t *)&tmp, 2);
+}
+
+/**
+  * @brief  Disable polarity inversion of the selected IO pins.
+  * @param  DeviceAddr: Device address on communication Bus.    
+  * @param  IO_Pin: IO pin(s) to be configured. 
+  *         This parameter could be any combination of the following values:
+  *   @arg  STMPE1600_PIN_x: where x can be from 0 to 15.
+  * @retval None
+  */ 
+void stmpe1600_IO_PolarityInv_Disable(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  uint8_t tmpData[2] = {0 , 0};
+  
+  /* Get the current register value */
+  IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_GPPIR, tmpData, 2);
+  
+  tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8));  
+
+  /* Disable pin polarity inversion */
+   tmp &= ~ (uint16_t)IO_Pin;
+    
+  /* Set the new register value */  
+  IOE_WriteMultiple(DeviceAddr, STMPE1600_REG_GPPIR, (uint8_t *)&tmp, 2);  
+}
+
+/**
+  * @brief  Set the value of the selected IO pins.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  IO_Pin: IO pin(s) to be set.
+  *         This parameter could be any combination of the following values:
+  *   @arg  STMPE1600_PIN_x: where x can be from 0 to 15.
+  * @param  PinState: The value to be set. 
+  * @retval None
+  */
+void stmpe1600_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState)
+{
+  uint8_t tmpData[2] = {0 , 0};
+  
+  /* Get the current register value */
+  IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_GPMR, tmpData, 2);
+  
+  tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8));  
+  
+  /* Set the pin state */
+  if(PinState != 0)
+  {
+    tmp |= (uint16_t)IO_Pin;
+  }  
+  else 
+  {
+    tmp &= ~(uint16_t)IO_Pin;
+  }
+    
+  /* Set the new register value */  
+  IOE_WriteMultiple(DeviceAddr, STMPE1600_REG_GPSR, (uint8_t *)&tmp, 2);
+}
+
+/**
+  * @brief  Read the state of the selected IO pin(s).
+  * @param  DeviceAddr: Device address on communication Bus. 
+  * @param  IO_Pin: IO pin(s) to be read.  
+  *         This parameter could be any combination of the following values:
+  *   @arg  STMPE1600_PIN_x: where x can be from 0 to 15.
+  * @retval State of the selected IO pin(s).
+  */
+uint32_t stmpe1600_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  uint8_t tmpData[2] = {0 , 0};
+  
+  /* Get the register value */
+  IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_GPMR, tmpData, 2);
+  
+  tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8));
+  
+  /* Return the pin(s) state */
+  return(tmp & IO_Pin);  
+}
+
+/**
+  * @brief  Enable the interrupt mode for the selected IO pin(s).
+  * @param  DeviceAddr: Device address on communication Bus.     
+  * @param  IO_Pin: IO pin(s) to be configured.  
+  *         This parameter could be any combination of the following values:
+  *   @arg  STMPE1600_PIN_x: where x can be from 0 to 15. 
+  * @retval None
+  */
+void stmpe1600_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  uint8_t tmpData[2] = {0 , 0};
+    
+  /* Enable global interrupt */
+  stmpe1600_EnableGlobalIT(DeviceAddr);
+
+  /* Get the current register value */
+  IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_IEGPIOR, tmpData, 2);
+  
+  tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8));  
+  
+  /* Put pin in IT mode */
+  tmp |= (uint16_t)IO_Pin;
+    
+  /* Write the new register value */
+  IOE_WriteMultiple(DeviceAddr, STMPE1600_REG_IEGPIOR, (uint8_t *)&tmp, 2);
+}
+
+/**
+  * @brief  Disable the interrupt mode for the selected IO pin(s).
+  * @param  DeviceAddr: Device address on communication Bus.    
+  * @param  IO_Pin: IO pin(s) to be configured.  
+  *         This parameter could be any combination of the following values:
+  *   @arg  STMPE1600_PIN_x: where x can be from 0 to 15. 
+  * @retval None
+  */
+void stmpe1600_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  uint8_t tmpData[2] = {0 , 0};
+  
+  /* Get the current register value */
+  IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_IEGPIOR, tmpData, 2);
+  
+  tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8));  
+  
+  /* Disable the IT pin mode */
+  tmp &= ~(uint16_t)IO_Pin;
+    
+  /* Set the new register value */
+  IOE_WriteMultiple(DeviceAddr, STMPE1600_REG_IEGPIOR, (uint8_t *)&tmp, 2); 
+}
+
+/**
+  * @brief  Read the IT status of the selected IO pin(s)
+  *         (clears all the pending bits if any). 
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  IO_Pin: IO pin(s) to be checked.  
+  *         This parameter could be any combination of the following values:
+  *   @arg  STMPE1600_PIN_x: where x can be from 0 to 15.           
+  * @retval IT Status of the selected IO pin(s).
+  */
+uint32_t stmpe1600_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  uint8_t tmpData[2] = {0 , 0};
+  
+  /* Get the register value */
+  IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_ISGPIOR, tmpData, 2);
+  
+  tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8));
+  
+  /* Return the pin IT status */
+  return((tmp & IO_Pin) == IO_Pin);  
+}
+
+/**
+  * @brief  Detect an IT pending bit from the selected IO pin(s).
+  *         (clears all the pending bits if any).
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  IO_Pin: IO pin(s) to be checked.  
+  *         This parameter could be any combination of the following values:
+  *   @arg  STMPE1600_PIN_x: where x can be from 0 to 15.           
+  * @retval IT pending bit detection status.
+  */
+uint8_t stmpe1600_IO_ReadIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  uint8_t tmpData[2] = {0 , 0};
+  
+  /* Get the register value */
+  IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_ISGPIOR, tmpData, 2);
+  
+  tmp = ((uint16_t)tmpData[0] | (((uint16_t)tmpData[1]) << 8));
+  
+  /* Return if there is an IT pending bit or not */
+  return(tmp & IO_Pin);
+}
+
+/**
+  * @brief  Clear all the IT pending bits if any. 
+  * @param  DeviceAddr: Device address on communication Bus.            
+  * @retval None
+  */
+void stmpe1600_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  uint8_t tmpData[2] = {0 , 0};
+    
+  /* Get the register value to clear all pending bits */
+  IOE_ReadMultiple(DeviceAddr, STMPE1600_REG_ISGPIOR, tmpData, 2);
+}
+
+/**
+  * @brief  Check if the device instance of the selected address is already registered
+  *         and return its index 
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval Index of the device instance if registered, 0xFF if not.
+  */
+static uint8_t stmpe1600_GetInstance(uint16_t DeviceAddr)
+{
+  uint8_t idx = 0;
+  
+  /* Check all the registered instances */
+  for(idx = 0; idx < STMPE1600_MAX_INSTANCE ; idx ++)
+  {
+    /* Return index if there is address match */
+    if(stmpe1600[idx] == DeviceAddr)
+    {
+      return idx; 
+    }
+  }
+  
+  return 0xFF;
+}
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */      
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/stmpe1600/stmpe1600.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,214 @@
+/**
+  ******************************************************************************
+  * @file    stmpe1600.h
+  * @author  MCD Application Team
+  * @version V1.1.0
+  * @date    10-February-2015
+  * @brief   This file contains all the functions prototypes for the
+  *          stmpe1600.c IO expander driver.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STMPE1600_H
+#define __STMPE1600_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif   
+   
+/* Includes ------------------------------------------------------------------*/
+#include "../Common/io.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup Component
+  * @{
+  */
+    
+/** @defgroup STMPE1600
+  * @{
+  */    
+
+/* Exported types ------------------------------------------------------------*/
+
+/** @defgroup STMPE1600_Exported_Types
+  * @{
+  */ 
+
+/* Exported constants --------------------------------------------------------*/
+  
+/** @defgroup STMPE1600_Exported_Constants
+  * @{
+  */ 
+
+/** 
+  * @brief STMPE1600 chip IDs  
+  */ 
+#define STMPE1600_ID                     0x1600
+
+/** 
+  * @brief  Interrupt enable  
+  */ 
+#define STMPE1600_IT_ENABLE              0x04
+
+/** 
+  * @brief  Identification registers & System Control  
+  */ 
+#define STMPE1600_REG_CHP_ID             0x00
+#define STMPE1600_REG_ID_VERSION         0x02
+#define STMPE1600_REG_SYS_CTRL           0x03
+
+/** 
+  * @brief  IO Registers  
+  */ 
+
+#define STMPE1600_REG_GPMR               0x10
+#define STMPE1600_REG_GPSR               0x12
+#define STMPE1600_REG_GPDR               0x14
+#define STMPE1600_REG_GPPIR              0x16
+   
+/** 
+  * @brief  Interrupt Control registers  
+  */ 
+#define STMPE1600_REG_IEGPIOR            0x08
+#define STMPE1600_REG_ISGPIOR            0x0A
+
+/** 
+  * @brief  IO Pins direction  
+  */
+#define STMPE1600_DIRECTION_IN           0x00
+#define STMPE1600_DIRECTION_OUT          0x01
+
+/** 
+  * @brief  IO IT polarity  
+  */
+#define STMPE1600_POLARITY_LOW           0x00
+#define STMPE1600_POLARITY_HIGH          0x01
+
+/** 
+  * @brief  IO Pins  
+  */     
+#define STMPE1600_PIN_0                  0x0001
+#define STMPE1600_PIN_1                  0x0002
+#define STMPE1600_PIN_2                  0x0004
+#define STMPE1600_PIN_3                  0x0008
+#define STMPE1600_PIN_4                  0x0010
+#define STMPE1600_PIN_5                  0x0020
+#define STMPE1600_PIN_6                  0x0040
+#define STMPE1600_PIN_7                  0x0080
+#define STMPE1600_PIN_8                  0x0100
+#define STMPE1600_PIN_9                  0x0200
+#define STMPE1600_PIN_10                 0x0400
+#define STMPE1600_PIN_11                 0x0800
+#define STMPE1600_PIN_12                 0x1000
+#define STMPE1600_PIN_13                 0x2000
+#define STMPE1600_PIN_14                 0x4000
+#define STMPE1600_PIN_15                 0x8000
+#define STMPE1600_PIN_ALL                0xFFFF    
+
+/**
+  * @}
+  */ 
+  
+/* Exported macro ------------------------------------------------------------*/
+  
+/** @defgroup STMPE1600_Exported_Macros
+  * @{
+  */ 
+
+/* Exported functions --------------------------------------------------------*/
+  
+/** @defgroup STMPE1600_Exported_Functions
+  * @{
+  */
+  
+/** 
+  * @brief STMPE1600 Control functions
+  */
+void     stmpe1600_Init(uint16_t DeviceAddr);
+void     stmpe1600_Reset(uint16_t DeviceAddr);
+uint16_t stmpe1600_ReadID(uint16_t DeviceAddr);
+void     stmpe1600_SetITPolarity(uint16_t DeviceAddr, uint8_t Polarity);
+void     stmpe1600_EnableGlobalIT(uint16_t DeviceAddr);
+void     stmpe1600_DisableGlobalIT(uint16_t DeviceAddr);
+
+/** 
+  * @brief STMPE1600 IO functionalities functions
+  */
+void     stmpe1600_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction);
+uint8_t  stmpe1600_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode);
+void     stmpe1600_IO_PolarityInv_Enable(uint16_t DeviceAddr, uint32_t IO_Pin);
+void     stmpe1600_IO_PolarityInv_Disable(uint16_t DeviceAddr, uint32_t IO_Pin);
+void     stmpe1600_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState);
+uint32_t stmpe1600_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin);
+void     stmpe1600_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin);
+void     stmpe1600_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin);
+uint32_t stmpe1600_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin);
+uint8_t  stmpe1600_IO_ReadIT(uint16_t DeviceAddr, uint32_t IO_Pin);
+void     stmpe1600_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin);
+void     stmpe1600_Start(uint16_t DeviceAddr, uint32_t IO_Pin);
+
+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);
+void     IOE_WriteMultiple(uint8_t addr, uint8_t reg, uint8_t *buffer, uint16_t length);
+
+/* STMPE1600 driver structure */
+extern IO_DrvTypeDef stmpe1600_io_drv;
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __STMPE1600_H */
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */       
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/stmpe811/stmpe811.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,978 @@
+/**
+  ******************************************************************************
+  * @file    stmpe811.c
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    15-December-2014
+  * @brief   This file provides a set of functions needed to manage the STMPE811
+  *          IO Expander devices.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */  
+
+/* Includes ------------------------------------------------------------------*/
+#include "stmpe811.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Components
+  * @{
+  */ 
+  
+/** @defgroup STMPE811
+  * @{
+  */   
+
+/** @defgroup STMPE811_Private_Types_Definitions
+  * @{
+  */ 
+
+/** @defgroup STMPE811_Private_Defines
+  * @{
+  */ 
+#define STMPE811_MAX_INSTANCE         2 
+/**
+  * @}
+  */
+
+/** @defgroup STMPE811_Private_Macros
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+/** @defgroup STMPE811_Private_Variables
+  * @{
+  */ 
+
+/* Touch screen driver structure initialization */  
+TS_DrvTypeDef stmpe811_ts_drv = 
+{
+  stmpe811_Init,
+  stmpe811_ReadID,
+  stmpe811_Reset,
+  stmpe811_TS_Start,
+  stmpe811_TS_DetectTouch,
+  stmpe811_TS_GetXY,
+  stmpe811_TS_EnableIT,
+  stmpe811_TS_ClearIT,
+  stmpe811_TS_ITStatus,
+  stmpe811_TS_DisableIT,
+};
+
+/* IO driver structure initialization */ 
+IO_DrvTypeDef stmpe811_io_drv = 
+{
+  stmpe811_Init,
+  stmpe811_ReadID,
+  stmpe811_Reset,
+  stmpe811_IO_Start,
+  stmpe811_IO_Config,
+  stmpe811_IO_WritePin,
+  stmpe811_IO_ReadPin,
+  stmpe811_IO_EnableIT,
+  stmpe811_IO_DisableIT,
+  stmpe811_IO_ITStatus,
+  stmpe811_IO_ClearIT,
+};
+
+/* stmpe811 instances by address */
+uint8_t stmpe811[STMPE811_MAX_INSTANCE] = {0};
+/**
+  * @}
+  */ 
+
+/** @defgroup STMPE811_Private_Function_Prototypes
+  * @{
+  */
+static uint8_t stmpe811_GetInstance(uint16_t DeviceAddr); 
+/**
+  * @}
+  */ 
+
+/** @defgroup STMPE811_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Initialize the stmpe811 and configure the needed hardware resources
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval None
+  */
+void stmpe811_Init(uint16_t DeviceAddr)
+{
+  uint8_t instance;
+  uint8_t empty;
+  
+  /* Check if device instance already exists */
+  instance = stmpe811_GetInstance(DeviceAddr);
+  
+  /* To prevent double initialization */
+  if(instance == 0xFF)
+  {
+    /* Look for empty instance */
+    empty = stmpe811_GetInstance(0);
+    
+    if(empty < STMPE811_MAX_INSTANCE)
+    {
+      /* Register the current device instance */
+      stmpe811[empty] = DeviceAddr;
+      
+      /* Initialize IO BUS layer */
+      IOE_Init(); 
+      
+      /* Generate stmpe811 Software reset */
+      stmpe811_Reset(DeviceAddr);
+    }
+  }
+}
+ 
+/**
+  * @brief  Reset the stmpe811 by Software.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @retval None
+  */
+void stmpe811_Reset(uint16_t DeviceAddr)
+{
+  /* Power Down the stmpe811 */  
+  IOE_Write(DeviceAddr, STMPE811_REG_SYS_CTRL1, 2);
+
+  /* Wait for a delay to ensure registers erasing */
+  IOE_Delay(10); 
+  
+  /* Power On the Codec after the power off => all registers are reinitialized */
+  IOE_Write(DeviceAddr, STMPE811_REG_SYS_CTRL1, 0);
+  
+  /* Wait for a delay to ensure registers erasing */
+  IOE_Delay(2); 
+}
+
+/**
+  * @brief  Read the stmpe811 IO Expander device ID.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @retval The Device ID (two bytes).
+  */
+uint16_t stmpe811_ReadID(uint16_t DeviceAddr)
+{
+  /* Initialize IO BUS layer */
+  IOE_Init(); 
+  
+  /* Return the device ID value */
+  return ((IOE_Read(DeviceAddr, STMPE811_REG_CHP_ID_LSB) << 8) |\
+          (IOE_Read(DeviceAddr, STMPE811_REG_CHP_ID_MSB)));
+}
+
+/**
+  * @brief  Enable the Global interrupt.
+  * @param  DeviceAddr: Device address on communication Bus.       
+  * @retval None
+  */
+void stmpe811_EnableGlobalIT(uint16_t DeviceAddr)
+{
+  uint8_t tmp = 0;
+  
+  /* Read the Interrupt Control register  */
+  tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_CTRL);
+  
+  /* Set the global interrupts to be Enabled */    
+  tmp |= (uint8_t)STMPE811_GIT_EN;
+  
+  /* Write Back the Interrupt Control register */
+  IOE_Write(DeviceAddr, STMPE811_REG_INT_CTRL, tmp); 
+}
+
+/**
+  * @brief  Disable the Global interrupt.
+  * @param  DeviceAddr: Device address on communication Bus.      
+  * @retval None
+  */
+void stmpe811_DisableGlobalIT(uint16_t DeviceAddr)
+{
+  uint8_t tmp = 0;
+  
+  /* Read the Interrupt Control register  */
+  tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_CTRL);
+
+  /* Set the global interrupts to be Disabled */    
+  tmp &= ~(uint8_t)STMPE811_GIT_EN;
+ 
+  /* Write Back the Interrupt Control register */
+  IOE_Write(DeviceAddr, STMPE811_REG_INT_CTRL, tmp);
+    
+}
+
+/**
+  * @brief  Enable the interrupt mode for the selected IT source
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param Source: The interrupt source to be configured, could be:
+  *   @arg  STMPE811_GIT_IO: IO interrupt 
+  *   @arg  STMPE811_GIT_ADC : ADC interrupt    
+  *   @arg  STMPE811_GIT_FE : Touch Screen Controller FIFO Error interrupt
+  *   @arg  STMPE811_GIT_FF : Touch Screen Controller FIFO Full interrupt      
+  *   @arg  STMPE811_GIT_FOV : Touch Screen Controller FIFO Overrun interrupt     
+  *   @arg  STMPE811_GIT_FTH : Touch Screen Controller FIFO Threshold interrupt   
+  *   @arg  STMPE811_GIT_TOUCH : Touch Screen Controller Touch Detected interrupt  
+  * @retval None
+  */
+void stmpe811_EnableITSource(uint16_t DeviceAddr, uint8_t Source)
+{
+  uint8_t tmp = 0;
+  
+  /* Get the current value of the INT_EN register */
+  tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_EN);
+
+  /* Set the interrupts to be Enabled */    
+  tmp |= Source; 
+  
+  /* Set the register */
+  IOE_Write(DeviceAddr, STMPE811_REG_INT_EN, tmp);   
+}
+
+/**
+  * @brief  Disable the interrupt mode for the selected IT source
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  Source: The interrupt source to be configured, could be:
+  *   @arg  STMPE811_GIT_IO: IO interrupt 
+  *   @arg  STMPE811_GIT_ADC : ADC interrupt    
+  *   @arg  STMPE811_GIT_FE : Touch Screen Controller FIFO Error interrupt
+  *   @arg  STMPE811_GIT_FF : Touch Screen Controller FIFO Full interrupt      
+  *   @arg  STMPE811_GIT_FOV : Touch Screen Controller FIFO Overrun interrupt     
+  *   @arg  STMPE811_GIT_FTH : Touch Screen Controller FIFO Threshold interrupt   
+  *   @arg  STMPE811_GIT_TOUCH : Touch Screen Controller Touch Detected interrupt  
+  * @retval None
+  */
+void stmpe811_DisableITSource(uint16_t DeviceAddr, uint8_t Source)
+{
+  uint8_t tmp = 0;
+  
+  /* Get the current value of the INT_EN register */
+  tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_EN);
+
+  /* Set the interrupts to be Enabled */    
+  tmp &= ~Source; 
+  
+  /* Set the register */
+  IOE_Write(DeviceAddr, STMPE811_REG_INT_EN, tmp);   
+}
+
+/**
+  * @brief  Set the global interrupt Polarity.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  Polarity: the IT mode polarity, could be one of the following values:
+  *   @arg  STMPE811_POLARITY_LOW: Interrupt line is active Low/Falling edge      
+  *   @arg  STMPE811_POLARITY_HIGH: Interrupt line is active High/Rising edge              
+  * @retval None
+  */
+void stmpe811_SetITPolarity(uint16_t DeviceAddr, uint8_t Polarity)
+{
+  uint8_t tmp = 0;
+  
+  /* Get the current register value */ 
+  tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_CTRL);
+  
+  /* Mask the polarity bits */
+  tmp &= ~(uint8_t)0x04;
+    
+  /* Modify the Interrupt Output line configuration */
+  tmp |= Polarity;
+  
+  /* Set the new register value */
+  IOE_Write(DeviceAddr, STMPE811_REG_INT_CTRL, tmp);
+ 
+}
+
+/**
+  * @brief  Set the global interrupt Type. 
+  * @param  DeviceAddr: Device address on communication Bus.      
+  * @param  Type: Interrupt line activity type, could be one of the following values:
+  *   @arg  STMPE811_TYPE_LEVEL: Interrupt line is active in level model         
+  *   @arg  STMPE811_TYPE_EDGE: Interrupt line is active in edge model           
+  * @retval None
+  */
+void stmpe811_SetITType(uint16_t DeviceAddr, uint8_t Type)
+{
+  uint8_t tmp = 0;
+  
+  /* Get the current register value */ 
+  tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_CTRL);
+  
+  /* Mask the type bits */
+  tmp &= ~(uint8_t)0x02;
+    
+  /* Modify the Interrupt Output line configuration */
+  tmp |= Type;
+  
+  /* Set the new register value */
+  IOE_Write(DeviceAddr, STMPE811_REG_INT_CTRL, tmp);
+ 
+}
+
+/**
+  * @brief  Check the selected Global interrupt source pending bit
+  * @param  DeviceAddr: Device address on communication Bus. 
+  * @param  Source: the Global interrupt source to be checked, could be:
+  *   @arg  STMPE811_GIT_IO: IO interrupt 
+  *   @arg  STMPE811_GIT_ADC : ADC interrupt    
+  *   @arg  STMPE811_GIT_FE : Touch Screen Controller FIFO Error interrupt
+  *   @arg  STMPE811_GIT_FF : Touch Screen Controller FIFO Full interrupt      
+  *   @arg  STMPE811_GIT_FOV : Touch Screen Controller FIFO Overrun interrupt     
+  *   @arg  STMPE811_GIT_FTH : Touch Screen Controller FIFO Threshold interrupt   
+  *   @arg  STMPE811_GIT_TOUCH : Touch Screen Controller Touch Detected interrupt      
+  * @retval The checked Global interrupt source status.
+  */
+uint8_t stmpe811_GlobalITStatus(uint16_t DeviceAddr, uint8_t Source)
+{
+  /* Return the global IT source status */
+  return((IOE_Read(DeviceAddr, STMPE811_REG_INT_STA) & Source) == Source);
+}
+
+/**
+  * @brief  Return the Global interrupts status
+  * @param  DeviceAddr: Device address on communication Bus. 
+  * @param  Source: the Global interrupt source to be checked, could be:
+  *   @arg  STMPE811_GIT_IO: IO interrupt 
+  *   @arg  STMPE811_GIT_ADC : ADC interrupt    
+  *   @arg  STMPE811_GIT_FE : Touch Screen Controller FIFO Error interrupt
+  *   @arg  STMPE811_GIT_FF : Touch Screen Controller FIFO Full interrupt      
+  *   @arg  STMPE811_GIT_FOV : Touch Screen Controller FIFO Overrun interrupt     
+  *   @arg  STMPE811_GIT_FTH : Touch Screen Controller FIFO Threshold interrupt   
+  *   @arg  STMPE811_GIT_TOUCH : Touch Screen Controller Touch Detected interrupt      
+  * @retval The checked Global interrupt source status.
+  */
+uint8_t stmpe811_ReadGITStatus(uint16_t DeviceAddr, uint8_t Source)
+{
+  /* Return the global IT source status */
+  return((IOE_Read(DeviceAddr, STMPE811_REG_INT_STA) & Source));
+}
+
+/**
+  * @brief  Clear the selected Global interrupt pending bit(s)
+  * @param  DeviceAddr: Device address on communication Bus. 
+  * @param  Source: the Global interrupt source to be cleared, could be any combination
+  *         of the following values:        
+  *   @arg  STMPE811_GIT_IO: IO interrupt 
+  *   @arg  STMPE811_GIT_ADC : ADC interrupt    
+  *   @arg  STMPE811_GIT_FE : Touch Screen Controller FIFO Error interrupt
+  *   @arg  STMPE811_GIT_FF : Touch Screen Controller FIFO Full interrupt      
+  *   @arg  STMPE811_GIT_FOV : Touch Screen Controller FIFO Overrun interrupt     
+  *   @arg  STMPE811_GIT_FTH : Touch Screen Controller FIFO Threshold interrupt   
+  *   @arg  STMPE811_GIT_TOUCH : Touch Screen Controller Touch Detected interrupt 
+  * @retval None
+  */
+void stmpe811_ClearGlobalIT(uint16_t DeviceAddr, uint8_t Source)
+{
+  /* Write 1 to the bits that have to be cleared */
+  IOE_Write(DeviceAddr, STMPE811_REG_INT_STA, Source);
+}
+
+/**
+  * @brief  Start the IO functionality use and disable the AF for selected IO pin(s).
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  IO_Pin: The IO pin(s) to put in AF. This parameter can be one 
+  *         of the following values:
+  *   @arg  STMPE811_PIN_x: where x can be from 0 to 7.
+  * @retval None
+  */
+void stmpe811_IO_Start(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  uint8_t mode;
+  
+  /* Get the current register value */
+  mode = IOE_Read(DeviceAddr, STMPE811_REG_SYS_CTRL2);
+  
+  /* Set the Functionalities to be Disabled */    
+  mode &= ~(STMPE811_IO_FCT | STMPE811_ADC_FCT);  
+  
+  /* Write the new register value */  
+  IOE_Write(DeviceAddr, STMPE811_REG_SYS_CTRL2, mode); 
+
+  /* Disable AF for the selected IO pin(s) */
+  stmpe811_IO_DisableAF(DeviceAddr, (uint8_t)IO_Pin);
+}
+
+/**
+  * @brief  Configures the IO pin(s) according to IO mode structure value.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  IO_Pin: The output pin to be set or reset. This parameter can be one 
+  *         of the following values:   
+  *   @arg  STMPE811_PIN_x: where x can be from 0 to 7.
+  * @param  IO_Mode: The IO pin mode to configure, could be one of the following values:
+  *   @arg  IO_MODE_INPUT
+  *   @arg  IO_MODE_OUTPUT
+  *   @arg  IO_MODE_IT_RISING_EDGE
+  *   @arg  IO_MODE_IT_FALLING_EDGE
+  *   @arg  IO_MODE_IT_LOW_LEVEL
+  *   @arg  IO_MODE_IT_HIGH_LEVEL            
+  * @retval 0 if no error, IO_Mode if error
+  */
+uint8_t stmpe811_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode)
+{
+  uint8_t error_code = 0;
+
+  /* Configure IO pin according to selected IO mode */
+  switch(IO_Mode)
+  {
+  case IO_MODE_INPUT: /* Input mode */
+    stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_IN);
+    break;
+    
+  case IO_MODE_OUTPUT: /* Output mode */
+    stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_OUT);
+    break;
+  
+  case IO_MODE_IT_RISING_EDGE: /* Interrupt rising edge mode */
+    stmpe811_IO_EnableIT(DeviceAddr);
+    stmpe811_IO_EnablePinIT(DeviceAddr, IO_Pin);
+    stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_IN); 
+    stmpe811_SetITType(DeviceAddr, STMPE811_TYPE_EDGE);      
+    stmpe811_IO_SetEdgeMode(DeviceAddr, IO_Pin, STMPE811_EDGE_RISING); 
+    break;
+  
+  case IO_MODE_IT_FALLING_EDGE: /* Interrupt falling edge mode */
+    stmpe811_IO_EnableIT(DeviceAddr);
+    stmpe811_IO_EnablePinIT(DeviceAddr, IO_Pin);
+    stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_IN); 
+    stmpe811_SetITType(DeviceAddr, STMPE811_TYPE_EDGE);    
+    stmpe811_IO_SetEdgeMode(DeviceAddr, IO_Pin, STMPE811_EDGE_FALLING); 
+    break;
+  
+  case IO_MODE_IT_LOW_LEVEL: /* Low level interrupt mode */
+    stmpe811_IO_EnableIT(DeviceAddr);
+    stmpe811_IO_EnablePinIT(DeviceAddr, IO_Pin);
+    stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_IN); 
+    stmpe811_SetITType(DeviceAddr, STMPE811_TYPE_LEVEL);
+    stmpe811_SetITPolarity(DeviceAddr, STMPE811_POLARITY_LOW);      
+    break;
+    
+  case IO_MODE_IT_HIGH_LEVEL: /* High level interrupt mode */
+    stmpe811_IO_EnableIT(DeviceAddr);
+    stmpe811_IO_EnablePinIT(DeviceAddr, IO_Pin);
+    stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_IN); 
+    stmpe811_SetITType(DeviceAddr, STMPE811_TYPE_LEVEL);
+    stmpe811_SetITPolarity(DeviceAddr, STMPE811_POLARITY_HIGH);  
+    break;    
+
+  default:
+    error_code = (uint8_t) IO_Mode;
+    break;
+  } 
+  return error_code;
+}
+
+/**
+  * @brief  Initialize the selected IO pin direction.
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  IO_Pin: The IO pin to be configured. This parameter could be any 
+  *         combination of the following values:
+  *   @arg  STMPE811_PIN_x: Where x can be from 0 to 7.   
+  * @param  Direction: could be STMPE811_DIRECTION_IN or STMPE811_DIRECTION_OUT.      
+  * @retval None
+  */
+void stmpe811_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction)
+{
+  uint8_t tmp = 0;   
+  
+  /* Get all the Pins direction */
+  tmp = IOE_Read(DeviceAddr, STMPE811_REG_IO_DIR);
+  
+  /* Set the selected pin direction */
+  if (Direction != STMPE811_DIRECTION_IN)
+  {
+    tmp |= (uint8_t)IO_Pin;
+  }  
+  else 
+  {
+    tmp &= ~(uint8_t)IO_Pin;
+  }
+  
+  /* Write the register new value */
+  IOE_Write(DeviceAddr, STMPE811_REG_IO_DIR, tmp);   
+}
+
+/**
+  * @brief  Disable the AF for the selected IO pin(s).
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  IO_Pin: The IO pin to be configured. This parameter could be any 
+  *         combination of the following values:
+  *   @arg  STMPE811_PIN_x: Where x can be from 0 to 7.        
+  * @retval None
+  */
+void stmpe811_IO_DisableAF(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  uint8_t tmp = 0;
+  
+  /* Get the current state of the IO_AF register */
+  tmp = IOE_Read(DeviceAddr, STMPE811_REG_IO_AF);
+
+  /* Enable the selected pins alternate function */
+  tmp |= (uint8_t)IO_Pin;
+
+  /* Write back the new value in IO AF register */
+  IOE_Write(DeviceAddr, STMPE811_REG_IO_AF, tmp);
+  
+}
+
+/**
+  * @brief  Enable the AF for the selected IO pin(s).
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param  IO_Pin: The IO pin to be configured. This parameter could be any 
+  *         combination of the following values:
+  *   @arg  STMPE811_PIN_x: Where x can be from 0 to 7.       
+  * @retval None
+  */
+void stmpe811_IO_EnableAF(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  uint8_t tmp = 0;
+  
+  /* Get the current register value */
+  tmp = IOE_Read(DeviceAddr, STMPE811_REG_IO_AF);
+
+  /* Enable the selected pins alternate function */   
+  tmp &= ~(uint8_t)IO_Pin;   
+  
+  /* Write back the new register value */
+  IOE_Write(DeviceAddr, STMPE811_REG_IO_AF, tmp); 
+}
+
+/**
+  * @brief  Configure the Edge for which a transition is detectable for the
+  *         selected pin.
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  IO_Pin: The IO pin to be configured. This parameter could be any 
+  *         combination of the following values:
+  *   @arg  STMPE811_PIN_x: Where x can be from 0 to 7.  
+  * @param  Edge: The edge which will be detected. This parameter can be one or
+  *         a combination of following values: STMPE811_EDGE_FALLING and STMPE811_EDGE_RISING .
+  * @retval None
+  */
+void stmpe811_IO_SetEdgeMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Edge)
+{
+  uint8_t tmp1 = 0, tmp2 = 0;   
+  
+  /* Get the current registers values */
+  tmp1 = IOE_Read(DeviceAddr, STMPE811_REG_IO_FE);
+  tmp2 = IOE_Read(DeviceAddr, STMPE811_REG_IO_RE);
+
+  /* Disable the Falling Edge */
+  tmp1 &= ~(uint8_t)IO_Pin;
+  
+  /* Disable the Falling Edge */
+  tmp2 &= ~(uint8_t)IO_Pin;
+
+  /* Enable the Falling edge if selected */
+  if (Edge & STMPE811_EDGE_FALLING)
+  {
+    tmp1 |= (uint8_t)IO_Pin;
+  }
+
+  /* Enable the Rising edge if selected */
+  if (Edge & STMPE811_EDGE_RISING)
+  {
+    tmp2 |= (uint8_t)IO_Pin;
+  }
+
+  /* Write back the new registers values */
+  IOE_Write(DeviceAddr, STMPE811_REG_IO_FE, tmp1);
+  IOE_Write(DeviceAddr, STMPE811_REG_IO_RE, tmp2);
+}
+
+/**
+  * @brief  Write a new IO pin state.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param IO_Pin: The output pin to be set or reset. This parameter can be one 
+  *        of the following values:
+  *   @arg  STMPE811_PIN_x: where x can be from 0 to 7. 
+  * @param PinState: The new IO pin state.
+  * @retval None
+  */
+void stmpe811_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState)
+{
+  /* Apply the bit value to the selected pin */
+  if (PinState != 0)
+  {
+    /* Set the register */
+    IOE_Write(DeviceAddr, STMPE811_REG_IO_SET_PIN, (uint8_t)IO_Pin);
+  }
+  else
+  {
+    /* Set the register */
+    IOE_Write(DeviceAddr, STMPE811_REG_IO_CLR_PIN, (uint8_t)IO_Pin);
+  } 
+}
+
+/**
+  * @brief  Return the state of the selected IO pin(s).
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @param IO_Pin: The output pin to be set or reset. This parameter can be one 
+  *        of the following values:
+  *   @arg  STMPE811_PIN_x: where x can be from 0 to 7. 
+  * @retval IO pin(s) state.
+  */
+uint32_t stmpe811_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  return((uint32_t)(IOE_Read(DeviceAddr, STMPE811_REG_IO_MP_STA) & (uint8_t)IO_Pin));
+}
+
+/**
+  * @brief  Enable the global IO interrupt source.
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @retval None
+  */
+void stmpe811_IO_EnableIT(uint16_t DeviceAddr)
+{ 
+  IOE_ITConfig();
+  
+  /* Enable global IO IT source */
+  stmpe811_EnableITSource(DeviceAddr, STMPE811_GIT_IO);
+  
+  /* Enable global interrupt */
+  stmpe811_EnableGlobalIT(DeviceAddr); 
+}
+
+/**
+  * @brief  Disable the global IO interrupt source.
+  * @param  DeviceAddr: Device address on communication Bus.   
+  * @retval None
+  */
+void stmpe811_IO_DisableIT(uint16_t DeviceAddr)
+{
+  /* Disable the global interrupt */
+  stmpe811_DisableGlobalIT(DeviceAddr);
+  
+  /* Disable global IO IT source */
+  stmpe811_DisableITSource(DeviceAddr, STMPE811_GIT_IO);    
+}
+
+/**
+  * @brief  Enable interrupt mode for the selected IO pin(s).
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  IO_Pin: The IO interrupt to be enabled. This parameter could be any 
+  *         combination of the following values:
+  *   @arg  STMPE811_PIN_x: where x can be from 0 to 7.
+  * @retval None
+  */
+void stmpe811_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  uint8_t tmp = 0;
+  
+  /* Get the IO interrupt state */
+  tmp = IOE_Read(DeviceAddr, STMPE811_REG_IO_INT_EN);
+  
+  /* Set the interrupts to be enabled */    
+  tmp |= (uint8_t)IO_Pin;
+  
+  /* Write the register new value */
+  IOE_Write(DeviceAddr, STMPE811_REG_IO_INT_EN, tmp);  
+}
+
+/**
+  * @brief  Disable interrupt mode for the selected IO pin(s).
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  IO_Pin: The IO interrupt to be disabled. This parameter could be any 
+  *         combination of the following values:
+  *   @arg  STMPE811_PIN_x: where x can be from 0 to 7.
+  * @retval None
+  */
+void stmpe811_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  uint8_t tmp = 0;
+  
+  /* Get the IO interrupt state */
+  tmp = IOE_Read(DeviceAddr, STMPE811_REG_IO_INT_EN);
+  
+  /* Set the interrupts to be Disabled */    
+  tmp &= ~(uint8_t)IO_Pin;
+  
+  /* Write the register new value */
+  IOE_Write(DeviceAddr, STMPE811_REG_IO_INT_EN, tmp);   
+}
+
+/**
+  * @brief  Check the status of the selected IO interrupt pending bit
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  IO_Pin: The IO interrupt to be checked could be:
+  *   @arg  STMPE811_PIN_x Where x can be from 0 to 7.             
+  * @retval Status of the checked IO pin(s).
+  */
+uint32_t stmpe811_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  /* Get the Interrupt status */
+  return(IOE_Read(DeviceAddr, STMPE811_REG_IO_INT_STA) & (uint8_t)IO_Pin); 
+}
+
+/**
+  * @brief  Clear the selected IO interrupt pending bit(s).
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  IO_Pin: the IO interrupt to be cleared, could be:
+  *   @arg  STMPE811_PIN_x: Where x can be from 0 to 7.            
+  * @retval None
+  */
+void stmpe811_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+  /* Clear the global IO IT pending bit */
+  stmpe811_ClearGlobalIT(DeviceAddr, STMPE811_GIT_IO);
+  
+  /* Clear the IO IT pending bit(s) */
+  IOE_Write(DeviceAddr, STMPE811_REG_IO_INT_STA, (uint8_t)IO_Pin);  
+  
+  /* Clear the Edge detection pending bit*/
+  IOE_Write(DeviceAddr, STMPE811_REG_IO_ED, (uint8_t)IO_Pin);
+  
+  /* Clear the Rising edge pending bit */
+  IOE_Write(DeviceAddr, STMPE811_REG_IO_RE, (uint8_t)IO_Pin);
+  
+  /* Clear the Falling edge pending bit */
+  IOE_Write(DeviceAddr, STMPE811_REG_IO_FE, (uint8_t)IO_Pin); 
+}
+
+/**
+  * @brief  Configures the touch Screen Controller (Single point detection)
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval None.
+  */
+void stmpe811_TS_Start(uint16_t DeviceAddr)
+{
+  uint8_t mode;
+  
+  /* Get the current register value */
+  mode = IOE_Read(DeviceAddr, STMPE811_REG_SYS_CTRL2);
+  
+  /* Set the Functionalities to be Enabled */    
+  mode &= ~(STMPE811_IO_FCT);  
+  
+  /* Write the new register value */  
+  IOE_Write(DeviceAddr, STMPE811_REG_SYS_CTRL2, mode); 
+
+  /* Select TSC pins in TSC alternate mode */  
+  stmpe811_IO_EnableAF(DeviceAddr, STMPE811_TOUCH_IO_ALL);
+  
+  /* Set the Functionalities to be Enabled */    
+  mode &= ~(STMPE811_TS_FCT | STMPE811_ADC_FCT);  
+  
+  /* Set the new register value */  
+  IOE_Write(DeviceAddr, STMPE811_REG_SYS_CTRL2, mode); 
+  
+  /* Select Sample Time, bit number and ADC Reference */
+  IOE_Write(DeviceAddr, STMPE811_REG_ADC_CTRL1, 0x49);
+  
+  /* Wait for 2 ms */
+  IOE_Delay(2); 
+  
+  /* Select the ADC clock speed: 3.25 MHz */
+  IOE_Write(DeviceAddr, STMPE811_REG_ADC_CTRL2, 0x01);
+  
+  /* Select 2 nF filter capacitor */
+  /* Configuration: 
+     - Touch average control    : 4 samples
+     - Touch delay time         : 500 uS
+     - Panel driver setting time: 500 uS 
+  */
+  IOE_Write(DeviceAddr, STMPE811_REG_TSC_CFG, 0x9A); 
+  
+  /* Configure the Touch FIFO threshold: single point reading */
+  IOE_Write(DeviceAddr, STMPE811_REG_FIFO_TH, 0x01);
+  
+  /* Clear the FIFO memory content. */
+  IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x01);
+  
+  /* Put the FIFO back into operation mode  */
+  IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x00);
+  
+  /* Set the range and accuracy pf the pressure measurement (Z) : 
+     - Fractional part :7 
+     - Whole part      :1 
+  */
+  IOE_Write(DeviceAddr, STMPE811_REG_TSC_FRACT_XYZ, 0x01);
+  
+  /* Set the driving capability (limit) of the device for TSC pins: 50mA */
+  IOE_Write(DeviceAddr, STMPE811_REG_TSC_I_DRIVE, 0x01);
+  
+  /* Touch screen control configuration (enable TSC):
+     - No window tracking index
+     - XYZ acquisition mode
+   */
+  IOE_Write(DeviceAddr, STMPE811_REG_TSC_CTRL, 0x01);
+  
+  /*  Clear all the status pending bits if any */
+  IOE_Write(DeviceAddr, STMPE811_REG_INT_STA, 0xFF);
+
+  /* Wait for 2 ms delay */
+  IOE_Delay(2); 
+}
+
+/**
+  * @brief  Return if there is touch detected or not.
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval Touch detected state.
+  */
+uint8_t stmpe811_TS_DetectTouch(uint16_t DeviceAddr)
+{
+  uint8_t state;
+  uint8_t ret = 0;
+  
+  state = ((IOE_Read(DeviceAddr, STMPE811_REG_TSC_CTRL) & (uint8_t)STMPE811_TS_CTRL_STATUS) == (uint8_t)0x80);
+  
+  if(state > 0)
+  {
+    if(IOE_Read(DeviceAddr, STMPE811_REG_FIFO_SIZE) > 0)
+    {
+      ret = 1;
+    }
+  }
+  else
+  {
+    /* Reset FIFO */
+    IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x01);
+    /* Enable the FIFO again */
+    IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x00);
+  }
+  
+  return ret;
+}
+
+/**
+  * @brief  Get the touch screen X and Y positions values
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @param  X: Pointer to X position value
+  * @param  Y: Pointer to Y position value   
+  * @retval None.
+  */
+void stmpe811_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y)
+{
+  uint8_t  dataXYZ[4];
+  uint32_t uldataXYZ;
+  
+  IOE_ReadMultiple(DeviceAddr, STMPE811_REG_TSC_DATA_NON_INC, dataXYZ, sizeof(dataXYZ)) ;
+  
+  /* Calculate positions values */
+  uldataXYZ = (dataXYZ[0] << 24)|(dataXYZ[1] << 16)|(dataXYZ[2] << 8)|(dataXYZ[3] << 0);     
+  *X = (uldataXYZ >> 20) & 0x00000FFF;     
+  *Y = (uldataXYZ >>  8) & 0x00000FFF;     
+  
+  /* Reset FIFO */
+  IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x01);
+  /* Enable the FIFO again */
+  IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x00);
+}
+
+/**
+  * @brief  Configure the selected source to generate a global interrupt or not
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @retval None
+  */
+void stmpe811_TS_EnableIT(uint16_t DeviceAddr)
+{
+  IOE_ITConfig();
+  
+  /* Enable global TS IT source */
+  stmpe811_EnableITSource(DeviceAddr, STMPE811_TS_IT); 
+  
+  /* Enable global interrupt */
+  stmpe811_EnableGlobalIT(DeviceAddr);
+}
+
+/**
+  * @brief  Configure the selected source to generate a global interrupt or not
+  * @param  DeviceAddr: Device address on communication Bus.    
+  * @retval None
+  */
+void stmpe811_TS_DisableIT(uint16_t DeviceAddr)
+{
+  /* Disable global interrupt */
+  stmpe811_DisableGlobalIT(DeviceAddr);
+  
+  /* Disable global TS IT source */
+  stmpe811_DisableITSource(DeviceAddr, STMPE811_TS_IT); 
+}
+
+/**
+  * @brief  Configure the selected source to generate a global interrupt or not
+  * @param  DeviceAddr: Device address on communication Bus.    
+  * @retval TS interrupts status
+  */
+uint8_t stmpe811_TS_ITStatus(uint16_t DeviceAddr)
+{
+  /* Return TS interrupts status */
+  return(stmpe811_ReadGITStatus(DeviceAddr, STMPE811_TS_IT));
+}
+
+/**
+  * @brief  Configure the selected source to generate a global interrupt or not
+  * @param  DeviceAddr: Device address on communication Bus.  
+  * @retval None
+  */
+void stmpe811_TS_ClearIT(uint16_t DeviceAddr)
+{
+  /* Clear the global TS IT source */
+  stmpe811_ClearGlobalIT(DeviceAddr, STMPE811_TS_IT);
+}
+
+/**
+  * @brief  Check if the device instance of the selected address is already registered
+  *         and return its index  
+  * @param  DeviceAddr: Device address on communication Bus.
+  * @retval Index of the device instance if registered, 0xFF if not.
+  */
+static uint8_t stmpe811_GetInstance(uint16_t DeviceAddr)
+{
+  uint8_t idx = 0;
+  
+  /* Check all the registered instances */
+  for(idx = 0; idx < STMPE811_MAX_INSTANCE ; idx ++)
+  {
+    if(stmpe811[idx] == DeviceAddr)
+    {
+      return idx; 
+    }
+  }
+  
+  return 0xFF;
+}
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/stmpe811/stmpe811.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,292 @@
+/**
+  ******************************************************************************
+  * @file    stmpe811.h
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    15-December-2014
+  * @brief   This file contains all the functions prototypes for the
+  *          stmpe811.c IO expander driver.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STMPE811_H
+#define __STMPE811_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif   
+   
+/* Includes ------------------------------------------------------------------*/
+#include "../Common/ts.h"
+#include "../Common/io.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup Components
+  * @{
+  */
+    
+/** @defgroup STMPE811
+  * @{
+  */    
+
+/** @defgroup STMPE811_Exported_Types
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+   
+/** @defgroup STMPE811_Exported_Constants
+  * @{
+  */ 
+
+/* Chip IDs */   
+#define STMPE811_ID                     0x0811
+    
+/* Identification registers & System Control */ 
+#define STMPE811_REG_CHP_ID_LSB         0x00
+#define STMPE811_REG_CHP_ID_MSB         0x01
+#define STMPE811_REG_ID_VER             0x02
+
+/* Global interrupt Enable bit */ 
+#define STMPE811_GIT_EN                 0x01   
+
+/* IO expander functionalities */        
+#define STMPE811_ADC_FCT                0x01
+#define STMPE811_TS_FCT                 0x02
+#define STMPE811_IO_FCT                 0x04
+#define STMPE811_TEMPSENS_FCT           0x08
+
+/* Global Interrupts definitions */ 
+#define STMPE811_GIT_IO                 0x80  /* IO interrupt                   */
+#define STMPE811_GIT_ADC                0x40  /* ADC interrupt                  */
+#define STMPE811_GIT_TEMP               0x20  /* Not implemented                */
+#define STMPE811_GIT_FE                 0x10  /* FIFO empty interrupt           */
+#define STMPE811_GIT_FF                 0x08  /* FIFO full interrupt            */
+#define STMPE811_GIT_FOV                0x04  /* FIFO overflowed interrupt      */
+#define STMPE811_GIT_FTH                0x02  /* FIFO above threshold interrupt */
+#define STMPE811_GIT_TOUCH              0x01  /* Touch is detected interrupt    */      
+#define STMPE811_ALL_GIT                0x1F  /* All global interrupts          */
+#define STMPE811_TS_IT                  (STMPE811_GIT_TOUCH | STMPE811_GIT_FTH |  STMPE811_GIT_FOV | STMPE811_GIT_FF | STMPE811_GIT_FE) /* Touch screen interrupts */
+    
+/* General Control Registers */ 
+#define STMPE811_REG_SYS_CTRL1          0x03
+#define STMPE811_REG_SYS_CTRL2          0x04
+#define STMPE811_REG_SPI_CFG            0x08 
+
+/* Interrupt system Registers */ 
+#define STMPE811_REG_INT_CTRL           0x09
+#define STMPE811_REG_INT_EN             0x0A
+#define STMPE811_REG_INT_STA            0x0B
+#define STMPE811_REG_IO_INT_EN          0x0C
+#define STMPE811_REG_IO_INT_STA         0x0D
+
+/* IO Registers */ 
+#define STMPE811_REG_IO_SET_PIN         0x10
+#define STMPE811_REG_IO_CLR_PIN         0x11
+#define STMPE811_REG_IO_MP_STA          0x12
+#define STMPE811_REG_IO_DIR             0x13
+#define STMPE811_REG_IO_ED              0x14
+#define STMPE811_REG_IO_RE              0x15
+#define STMPE811_REG_IO_FE              0x16
+#define STMPE811_REG_IO_AF              0x17
+
+/* ADC Registers */ 
+#define STMPE811_REG_ADC_INT_EN         0x0E
+#define STMPE811_REG_ADC_INT_STA        0x0F
+#define STMPE811_REG_ADC_CTRL1          0x20
+#define STMPE811_REG_ADC_CTRL2          0x21
+#define STMPE811_REG_ADC_CAPT           0x22
+#define STMPE811_REG_ADC_DATA_CH0       0x30 
+#define STMPE811_REG_ADC_DATA_CH1       0x32 
+#define STMPE811_REG_ADC_DATA_CH2       0x34 
+#define STMPE811_REG_ADC_DATA_CH3       0x36 
+#define STMPE811_REG_ADC_DATA_CH4       0x38 
+#define STMPE811_REG_ADC_DATA_CH5       0x3A 
+#define STMPE811_REG_ADC_DATA_CH6       0x3B 
+#define STMPE811_REG_ADC_DATA_CH7       0x3C 
+
+/* Touch Screen Registers */ 
+#define STMPE811_REG_TSC_CTRL           0x40
+#define STMPE811_REG_TSC_CFG            0x41
+#define STMPE811_REG_WDM_TR_X           0x42 
+#define STMPE811_REG_WDM_TR_Y           0x44
+#define STMPE811_REG_WDM_BL_X           0x46
+#define STMPE811_REG_WDM_BL_Y           0x48
+#define STMPE811_REG_FIFO_TH            0x4A
+#define STMPE811_REG_FIFO_STA           0x4B
+#define STMPE811_REG_FIFO_SIZE          0x4C
+#define STMPE811_REG_TSC_DATA_X         0x4D 
+#define STMPE811_REG_TSC_DATA_Y         0x4F
+#define STMPE811_REG_TSC_DATA_Z         0x51
+#define STMPE811_REG_TSC_DATA_XYZ       0x52 
+#define STMPE811_REG_TSC_FRACT_XYZ      0x56
+#define STMPE811_REG_TSC_DATA_INC       0x57
+#define STMPE811_REG_TSC_DATA_NON_INC   0xD7
+#define STMPE811_REG_TSC_I_DRIVE        0x58
+#define STMPE811_REG_TSC_SHIELD         0x59
+
+/* Touch Screen Pins definition */ 
+#define STMPE811_TOUCH_YD               STMPE811_PIN_7 
+#define STMPE811_TOUCH_XD               STMPE811_PIN_6
+#define STMPE811_TOUCH_YU               STMPE811_PIN_5
+#define STMPE811_TOUCH_XU               STMPE811_PIN_4
+#define STMPE811_TOUCH_IO_ALL           (uint32_t)(STMPE811_TOUCH_YD | STMPE811_TOUCH_XD | STMPE811_TOUCH_YU | STMPE811_TOUCH_XU)
+
+/* IO Pins definition */ 
+#define STMPE811_PIN_0                  0x01
+#define STMPE811_PIN_1                  0x02
+#define STMPE811_PIN_2                  0x04
+#define STMPE811_PIN_3                  0x08
+#define STMPE811_PIN_4                  0x10
+#define STMPE811_PIN_5                  0x20
+#define STMPE811_PIN_6                  0x40
+#define STMPE811_PIN_7                  0x80
+#define STMPE811_PIN_ALL                0xFF
+
+/* IO Pins directions */ 
+#define STMPE811_DIRECTION_IN           0x00
+#define STMPE811_DIRECTION_OUT          0x01
+
+/* IO IT types */   
+#define STMPE811_TYPE_LEVEL             0x00
+#define STMPE811_TYPE_EDGE              0x02
+
+/* IO IT polarity */   
+#define STMPE811_POLARITY_LOW           0x00
+#define STMPE811_POLARITY_HIGH          0x04
+
+/* IO Pin IT edge modes */
+#define STMPE811_EDGE_FALLING           0x01
+#define STMPE811_EDGE_RISING            0x02
+
+/* TS registers masks */
+#define STMPE811_TS_CTRL_ENABLE         0x01  
+#define STMPE811_TS_CTRL_STATUS         0x80
+/**
+  * @}
+  */ 
+   
+/** @defgroup STMPE811_Exported_Macros
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+   
+/** @defgroup STMPE811_Exported_Functions
+  * @{
+  */
+
+/** 
+  * @brief STMPE811 Control functions
+  */
+void     stmpe811_Init(uint16_t DeviceAddr);
+void     stmpe811_Reset(uint16_t DeviceAddr);
+uint16_t stmpe811_ReadID(uint16_t DeviceAddr);
+void     stmpe811_EnableGlobalIT(uint16_t DeviceAddr);
+void     stmpe811_DisableGlobalIT(uint16_t DeviceAddr);
+void     stmpe811_EnableITSource(uint16_t DeviceAddr, uint8_t Source);
+void     stmpe811_DisableITSource(uint16_t DeviceAddr, uint8_t Source);
+void     stmpe811_SetITPolarity(uint16_t DeviceAddr, uint8_t Polarity);
+void     stmpe811_SetITType(uint16_t DeviceAddr, uint8_t Type);
+uint8_t  stmpe811_GlobalITStatus(uint16_t DeviceAddr, uint8_t Source);
+uint8_t  stmpe811_ReadGITStatus(uint16_t DeviceAddr, uint8_t Source);
+void     stmpe811_ClearGlobalIT(uint16_t DeviceAddr, uint8_t Source);
+
+/** 
+  * @brief STMPE811 IO functionalities functions
+  */
+void     stmpe811_IO_Start(uint16_t DeviceAddr, uint32_t IO_Pin);
+uint8_t  stmpe811_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode);
+void     stmpe811_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction);
+void     stmpe811_IO_EnableAF(uint16_t DeviceAddr, uint32_t IO_Pin);
+void     stmpe811_IO_DisableAF(uint16_t DeviceAddr, uint32_t IO_Pin);
+void     stmpe811_IO_SetEdgeMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Edge);
+void     stmpe811_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState);
+uint32_t stmpe811_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin);
+void     stmpe811_IO_EnableIT(uint16_t DeviceAddr);
+void     stmpe811_IO_DisableIT(uint16_t DeviceAddr);
+void     stmpe811_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin);
+void     stmpe811_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin);
+uint32_t stmpe811_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin);
+void     stmpe811_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin);
+
+/** 
+  * @brief STMPE811 Touch screen functionalities functions
+  */
+void     stmpe811_TS_Start(uint16_t DeviceAddr);
+uint8_t  stmpe811_TS_DetectTouch(uint16_t DeviceAddr);
+void     stmpe811_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y);
+void     stmpe811_TS_EnableIT(uint16_t DeviceAddr);
+void     stmpe811_TS_DisableIT(uint16_t DeviceAddr);
+uint8_t  stmpe811_TS_ITStatus (uint16_t DeviceAddr);
+void     stmpe811_TS_ClearIT (uint16_t DeviceAddr);
+
+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);
+
+/* Touch screen driver structure */
+extern TS_DrvTypeDef stmpe811_ts_drv;
+
+/* IO driver structure */
+extern IO_DrvTypeDef stmpe811_io_drv;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __STMPE811_H */
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/wm8994/wm8994.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,925 @@
+/**
+  ******************************************************************************
+  * @file    wm8994.c
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    24-June-2015
+  * @brief   This file provides the WM8994 Audio Codec 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.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "wm8994.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+  
+/** @addtogroup Components
+  * @{
+  */ 
+
+/** @addtogroup wm8994
+  * @brief     This file provides a set of functions needed to drive the 
+  *            WM8994 audio codec.
+  * @{
+  */
+
+/** @defgroup WM8994_Private_Types
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+  
+/** @defgroup WM8994_Private_Defines
+  * @{
+  */
+/* Uncomment this line to enable verifying data sent to codec after each write 
+   operation (for debug purpose) */
+#if !defined (VERIFY_WRITTENDATA)  
+/* #define VERIFY_WRITTENDATA */
+#endif /* VERIFY_WRITTENDATA */
+/**
+  * @}
+  */ 
+
+/** @defgroup WM8994_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+  
+/** @defgroup WM8994_Private_Variables
+  * @{
+  */
+
+/* Audio codec driver structure initialization */  
+AUDIO_DrvTypeDef wm8994_drv = 
+{
+  wm8994_Init,
+  wm8994_DeInit,
+  wm8994_ReadID,
+
+  wm8994_Play,
+  wm8994_Pause,
+  wm8994_Resume,
+  wm8994_Stop,  
+
+  wm8994_SetFrequency,
+  wm8994_SetVolume,
+  wm8994_SetMute,  
+  wm8994_SetOutputMode,
+
+  wm8994_Reset
+};
+
+static uint32_t outputEnabled = 0;
+static uint32_t inputEnabled = 0;
+/**
+  * @}
+  */ 
+
+/** @defgroup WM8994_Function_Prototypes
+  * @{
+  */
+static uint8_t CODEC_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value);
+/**
+  * @}
+  */ 
+
+/** @defgroup WM8994_Private_Functions
+  * @{
+  */ 
+
+/**
+  * @brief Initializes the audio codec and the control interface.
+  * @param DeviceAddr: Device address on communication Bus.   
+  * @param OutputInputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
+  *  OUTPUT_DEVICE_BOTH, OUTPUT_DEVICE_AUTO, INPUT_DEVICE_DIGITAL_MICROPHONE_1,
+  *  INPUT_DEVICE_DIGITAL_MICROPHONE_2, INPUT_DEVICE_INPUT_LINE_1 or INPUT_DEVICE_INPUT_LINE_2.
+  * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
+  * @param AudioFreq: Audio Frequency 
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t wm8994_Init(uint16_t DeviceAddr, uint16_t OutputInputDevice, uint8_t Volume, uint32_t AudioFreq)
+{
+  uint32_t counter = 0;
+  uint16_t output_device = OutputInputDevice & 0xFF;
+  uint16_t input_device = OutputInputDevice & 0xFF00;
+  uint16_t power_mgnt_reg_1 = 0;
+  
+  /* Initialize the Control interface of the Audio Codec */
+  AUDIO_IO_Init();
+  /* wm8994 Errata Work-Arounds */
+  counter += CODEC_IO_Write(DeviceAddr, 0x102, 0x0003);
+  counter += CODEC_IO_Write(DeviceAddr, 0x817, 0x0000);
+  counter += CODEC_IO_Write(DeviceAddr, 0x102, 0x0000);
+  
+  /* Enable VMID soft start (fast), Start-up Bias Current Enabled */
+  counter += CODEC_IO_Write(DeviceAddr, 0x39, 0x006C);
+  
+  /* Enable bias generator, Enable VMID */
+  counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x0003);
+  
+  /* Add Delay */
+  AUDIO_IO_Delay(50);
+
+  /* Path Configurations for output */
+  if (output_device > 0)
+  {
+    outputEnabled = 1;
+    switch (output_device)
+    {
+    case OUTPUT_DEVICE_SPEAKER:
+      /* Enable DAC1 (Left), Enable DAC1 (Right),
+      Disable DAC2 (Left), Disable DAC2 (Right)*/
+      counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0C0C);
+
+      /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0000);
+
+      /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0000);
+
+      /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
+
+      /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
+      break;
+
+    case OUTPUT_DEVICE_HEADPHONE:
+      /* Disable DAC1 (Left), Disable DAC1 (Right),
+      Enable DAC2 (Left), Enable DAC2 (Right)*/
+      counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
+
+      /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
+
+      /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
+
+      /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
+
+      /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
+      break;
+
+    case OUTPUT_DEVICE_BOTH:
+      /* Enable DAC1 (Left), Enable DAC1 (Right),
+      also Enable DAC2 (Left), Enable DAC2 (Right)*/
+      counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C);
+
+      /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
+
+      /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
+
+      /* Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
+
+      /* Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
+      break;
+
+    case OUTPUT_DEVICE_AUTO :
+    default:
+      /* Disable DAC1 (Left), Disable DAC1 (Right),
+      Enable DAC2 (Left), Enable DAC2 (Right)*/
+      counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
+
+      /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
+
+      /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
+
+      /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
+
+      /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
+      break;
+    }
+  }
+  else
+  {
+    outputEnabled = 0;
+  }
+
+  /* Path Configurations for input */
+  if (input_device > 0)
+  {
+    inputEnabled = 1;
+    switch (input_device)
+    {
+    case INPUT_DEVICE_DIGITAL_MICROPHONE_2 :
+      /* Enable AIF1ADC2 (Left), Enable AIF1ADC2 (Right)
+       * Enable DMICDAT2 (Left), Enable DMICDAT2 (Right)
+       * Enable Left ADC, Enable Right ADC */
+      counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0C30);
+
+      /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
+      counter += CODEC_IO_Write(DeviceAddr, 0x450, 0x00DB);
+
+      /* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
+      counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6000);
+
+      /* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x608, 0x0002);
+
+      /* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x609, 0x0002);
+
+      /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC2 signal detect */
+      counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000E);
+      break;
+
+    case INPUT_DEVICE_INPUT_LINE_1 :
+      /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
+       * Enable Left ADC, Enable Right ADC */
+      counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0303);
+
+      /* Enable AIF1 DRC1 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
+      counter += CODEC_IO_Write(DeviceAddr, 0x440, 0x00DB);
+
+      /* Enable IN1L and IN1R, Disable IN2L and IN2R, Enable Thermal sensor & shutdown */
+      counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6350);
+
+      /* Enable the ADCL(Left) to AIF1 Timeslot 0 (Left) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x606, 0x0002);
+
+      /* Enable the ADCR(Right) to AIF1 Timeslot 0 (Right) mixer path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x607, 0x0002);
+
+      /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
+      counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000D);
+      break;
+
+    case INPUT_DEVICE_DIGITAL_MICROPHONE_1 :
+    case INPUT_DEVICE_INPUT_LINE_2 :
+    default:
+      /* Actually, no other input devices supported */
+      counter++;
+      break;
+    }
+  }
+  else
+  {
+    inputEnabled = 0;
+  }
+  
+  /*  Clock Configurations */
+  switch (AudioFreq)
+  {
+  case  AUDIO_FREQUENCY_8K:
+    /* AIF1 Sample Rate = 8 (KHz), ratio=256 */ 
+    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0003);
+    break;
+    
+  case  AUDIO_FREQUENCY_16K:
+    /* AIF1 Sample Rate = 16 (KHz), ratio=256 */ 
+    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0033);
+    break;
+    
+  case  AUDIO_FREQUENCY_48K:
+    /* AIF1 Sample Rate = 48 (KHz), ratio=256 */ 
+    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
+    break;
+    
+  case  AUDIO_FREQUENCY_96K:
+    /* AIF1 Sample Rate = 96 (KHz), ratio=256 */ 
+    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x00A3);
+    break;
+    
+  case  AUDIO_FREQUENCY_11K:
+    /* AIF1 Sample Rate = 11.025 (KHz), ratio=256 */ 
+    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0013);
+    break;
+    
+  case  AUDIO_FREQUENCY_22K:
+    /* AIF1 Sample Rate = 22.050 (KHz), ratio=256 */ 
+    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0043);
+    break;
+    
+  case  AUDIO_FREQUENCY_44K:
+    /* AIF1 Sample Rate = 44.1 (KHz), ratio=256 */ 
+    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0073);
+    break; 
+    
+  default:
+    /* AIF1 Sample Rate = 48 (KHz), ratio=256 */ 
+    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
+    break; 
+  }
+  /* AIF1 Word Length = 16-bits, AIF1 Format = I2S (Default Register Value) */
+  counter += CODEC_IO_Write(DeviceAddr, 0x300, 0x4010);
+  
+  /* slave mode */
+  counter += CODEC_IO_Write(DeviceAddr, 0x302, 0x0000);
+  
+  /* Enable the DSP processing clock for AIF1, Enable the core clock */
+  counter += CODEC_IO_Write(DeviceAddr, 0x208, 0x000A);
+  
+  /* Enable AIF1 Clock, AIF1 Clock Source = MCLK1 pin */
+  counter += CODEC_IO_Write(DeviceAddr, 0x200, 0x0001);
+
+  if (output_device > 0)  /* Audio output selected */
+  {
+    /* Analog Output Configuration */
+
+    /* Enable SPKRVOL PGA, Enable SPKMIXR, Enable SPKLVOL PGA, Enable SPKMIXL */
+    counter += CODEC_IO_Write(DeviceAddr, 0x03, 0x0300);
+
+    /* Left Speaker Mixer Volume = 0dB */
+    counter += CODEC_IO_Write(DeviceAddr, 0x22, 0x0000);
+
+    /* Speaker output mode = Class D, Right Speaker Mixer Volume = 0dB ((0x23, 0x0100) = class AB)*/
+    counter += CODEC_IO_Write(DeviceAddr, 0x23, 0x0000);
+
+    /* Unmute DAC2 (Left) to Left Speaker Mixer (SPKMIXL) path,
+    Unmute DAC2 (Right) to Right Speaker Mixer (SPKMIXR) path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x36, 0x0300);
+
+    /* Enable bias generator, Enable VMID, Enable SPKOUTL, Enable SPKOUTR */
+    counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x3003);
+
+    /* Headphone/Speaker Enable */
+
+    /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslot 0 */
+    counter += CODEC_IO_Write(DeviceAddr, 0x51, 0x0005);
+
+    /* Enable bias generator, Enable VMID, Enable HPOUT1 (Left) and Enable HPOUT1 (Right) input stages */
+    /* idem for Speaker */
+    power_mgnt_reg_1 |= 0x0303 | 0x3003;
+    counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);
+
+    /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate stages */
+    counter += CODEC_IO_Write(DeviceAddr, 0x60, 0x0022);
+
+    /* Enable Charge Pump */
+    counter += CODEC_IO_Write(DeviceAddr, 0x4C, 0x9F25);
+
+    /* Add Delay */
+    AUDIO_IO_Delay(15);
+
+    /* Select DAC1 (Left) to Left Headphone Output PGA (HPOUT1LVOL) path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x2D, 0x0001);
+
+    /* Select DAC1 (Right) to Right Headphone Output PGA (HPOUT1RVOL) path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x2E, 0x0001);
+
+    /* Enable Left Output Mixer (MIXOUTL), Enable Right Output Mixer (MIXOUTR) */
+    /* idem for SPKOUTL and SPKOUTR */
+    counter += CODEC_IO_Write(DeviceAddr, 0x03, 0x0030 | 0x0300);
+
+    /* Enable DC Servo and trigger start-up mode on left and right channels */
+    counter += CODEC_IO_Write(DeviceAddr, 0x54, 0x0033);
+
+    /* Add Delay */
+    AUDIO_IO_Delay(250);
+
+    /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate and output stages. Remove clamps */
+    counter += CODEC_IO_Write(DeviceAddr, 0x60, 0x00EE);
+
+    /* Unmutes */
+
+    /* Unmute DAC 1 (Left) */
+    counter += CODEC_IO_Write(DeviceAddr, 0x610, 0x00C0);
+
+    /* Unmute DAC 1 (Right) */
+    counter += CODEC_IO_Write(DeviceAddr, 0x611, 0x00C0);
+
+    /* Unmute the AIF1 Timeslot 0 DAC path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0000);
+
+    /* Unmute DAC 2 (Left) */
+    counter += CODEC_IO_Write(DeviceAddr, 0x612, 0x00C0);
+
+    /* Unmute DAC 2 (Right) */
+    counter += CODEC_IO_Write(DeviceAddr, 0x613, 0x00C0);
+
+    /* Unmute the AIF1 Timeslot 1 DAC2 path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0000);
+    
+    /* Volume Control */
+    wm8994_SetVolume(DeviceAddr, Volume);
+  }
+
+  if (input_device > 0) /* Audio input selected */
+  {
+    if ((input_device == INPUT_DEVICE_DIGITAL_MICROPHONE_1) || (input_device == INPUT_DEVICE_DIGITAL_MICROPHONE_2))
+    {
+      /* Enable Microphone bias 1 generator, Enable VMID */
+      power_mgnt_reg_1 |= 0x0013;
+      counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);
+
+      /* ADC oversample enable */
+      counter += CODEC_IO_Write(DeviceAddr, 0x620, 0x0002);
+
+      /* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
+      counter += CODEC_IO_Write(DeviceAddr, 0x411, 0x3800);
+    }
+    else if ((input_device == INPUT_DEVICE_INPUT_LINE_1) || (input_device == INPUT_DEVICE_INPUT_LINE_2))
+    {
+      /* Enable normal bias generator, Enable VMID */
+      power_mgnt_reg_1 |= 0x0003;
+      counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);
+
+      /* Disable mute on IN1L, IN1L Volume = +0dB */
+      counter += CODEC_IO_Write(DeviceAddr, 0x18, 0x000B);
+
+      /* Disable mute on IN1R, IN1R Volume = +0dB */
+      counter += CODEC_IO_Write(DeviceAddr, 0x1A, 0x000B);
+
+      /* Disable mute on IN1L_TO_MIXINL, Gain = +0dB */
+      counter += CODEC_IO_Write(DeviceAddr, 0x29, 0x0025);
+
+      /* Disable mute on IN1R_TO_MIXINL, Gain = +0dB */
+      counter += CODEC_IO_Write(DeviceAddr, 0x2A, 0x0025);
+
+      /* IN1LN_TO_IN1L, IN1LP_TO_VMID, IN1RN_TO_IN1R, IN1RP_TO_VMID */
+      counter += CODEC_IO_Write(DeviceAddr, 0x28, 0x0011);
+
+      /* AIF ADC1 HPF enable, HPF cut = hifi mode fc=4Hz at fs=48kHz */
+      counter += CODEC_IO_Write(DeviceAddr, 0x410, 0x1800);
+    }
+    /* Volume Control */
+    wm8994_SetVolume(DeviceAddr, Volume);
+  }
+  /* Return communication control value */
+  return counter;  
+}
+
+/**
+  * @brief  Deinitializes the audio codec.
+  * @param  None
+  * @retval  None
+  */
+void wm8994_DeInit(void)
+{
+  /* Deinitialize Audio Codec interface */
+  AUDIO_IO_DeInit();
+}
+
+/**
+  * @brief  Get the WM8994 ID.
+  * @param DeviceAddr: Device address on communication Bus.
+  * @retval The WM8994 ID 
+  */
+uint32_t wm8994_ReadID(uint16_t DeviceAddr)
+{
+  /* Initialize the Control interface of the Audio Codec */
+  AUDIO_IO_Init();
+
+  return ((uint32_t)AUDIO_IO_Read(DeviceAddr, WM8994_CHIPID_ADDR));
+}
+
+/**
+  * @brief Start the audio Codec play feature.
+  * @note For this codec no Play options are required.
+  * @param DeviceAddr: Device address on communication Bus.   
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t wm8994_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size)
+{
+  uint32_t counter = 0;
+ 
+  /* Resumes the audio file playing */  
+  /* Unmute the output first */
+  counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
+  
+  return counter;
+}
+
+/**
+  * @brief Pauses playing on the audio codec.
+  * @param DeviceAddr: Device address on communication Bus. 
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t wm8994_Pause(uint16_t DeviceAddr)
+{  
+  uint32_t counter = 0;
+ 
+  /* Pause the audio file playing */
+  /* Mute the output first */
+  counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON);
+  
+  /* Put the Codec in Power save mode */
+  counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x01);
+ 
+  return counter;
+}
+
+/**
+  * @brief Resumes playing on the audio codec.
+  * @param DeviceAddr: Device address on communication Bus. 
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t wm8994_Resume(uint16_t DeviceAddr)
+{
+  uint32_t counter = 0;
+ 
+  /* Resumes the audio file playing */  
+  /* Unmute the output first */
+  counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
+  
+  return counter;
+}
+
+/**
+  * @brief Stops audio Codec playing. It powers down the codec.
+  * @param DeviceAddr: Device address on communication Bus. 
+  * @param CodecPdwnMode: selects the  power down mode.
+  *          - CODEC_PDWN_SW: only mutes the audio codec. When resuming from this 
+  *                           mode the codec keeps the previous initialization
+  *                           (no need to re-Initialize the codec registers).
+  *          - CODEC_PDWN_HW: Physically power down the codec. When resuming from this
+  *                           mode, the codec is set to default configuration 
+  *                           (user should re-Initialize the codec in order to 
+  *                            play again the audio stream).
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t wm8994_Stop(uint16_t DeviceAddr, uint32_t CodecPdwnMode)
+{
+  uint32_t counter = 0;
+
+  if (outputEnabled != 0)
+  {
+    /* Mute the output first */
+    counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON);
+
+    if (CodecPdwnMode == CODEC_PDWN_SW)
+    {
+       /* Only output mute required*/
+    }
+    else /* CODEC_PDWN_HW */
+    {
+      /* Mute the AIF1 Timeslot 0 DAC1 path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0200);
+
+      /* Mute the AIF1 Timeslot 1 DAC2 path */
+      counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0200);
+
+      /* Disable DAC1L_TO_HPOUT1L */
+      counter += CODEC_IO_Write(DeviceAddr, 0x2D, 0x0000);
+
+      /* Disable DAC1R_TO_HPOUT1R */
+      counter += CODEC_IO_Write(DeviceAddr, 0x2E, 0x0000);
+
+      /* Disable DAC1 and DAC2 */
+      counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0000);
+
+      /* Reset Codec by writing in 0x0000 address register */
+      counter += CODEC_IO_Write(DeviceAddr, 0x0000, 0x0000);
+
+      outputEnabled = 0;
+    }
+  }
+  return counter;
+}
+
+/**
+  * @brief Sets higher or lower the codec volume level.
+  * @param DeviceAddr: Device address on communication Bus.
+  * @param Volume: a byte value from 0 to 255 (refer to codec registers 
+  *         description for more details).
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t wm8994_SetVolume(uint16_t DeviceAddr, uint8_t Volume)
+{
+  uint32_t counter = 0;
+  uint8_t convertedvol = VOLUME_CONVERT(Volume);
+
+  /* Output volume */
+  if (outputEnabled != 0)
+  {
+    if(convertedvol > 0x3E)
+    {
+      /* Unmute audio codec */
+      counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
+
+      /* Left Headphone Volume */
+      counter += CODEC_IO_Write(DeviceAddr, 0x1C, 0x3F | 0x140);
+
+      /* Right Headphone Volume */
+      counter += CODEC_IO_Write(DeviceAddr, 0x1D, 0x3F | 0x140);
+
+      /* Left Speaker Volume */
+      counter += CODEC_IO_Write(DeviceAddr, 0x26, 0x3F | 0x140);
+
+      /* Right Speaker Volume */
+      counter += CODEC_IO_Write(DeviceAddr, 0x27, 0x3F | 0x140);
+    }
+    else if (Volume == 0)
+    {
+      /* Mute audio codec */
+      counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON);
+    }
+    else
+    {
+      /* Unmute audio codec */
+      counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
+
+      /* Left Headphone Volume */
+      counter += CODEC_IO_Write(DeviceAddr, 0x1C, convertedvol | 0x140);
+
+      /* Right Headphone Volume */
+      counter += CODEC_IO_Write(DeviceAddr, 0x1D, convertedvol | 0x140);
+
+      /* Left Speaker Volume */
+      counter += CODEC_IO_Write(DeviceAddr, 0x26, convertedvol | 0x140);
+
+      /* Right Speaker Volume */
+      counter += CODEC_IO_Write(DeviceAddr, 0x27, convertedvol | 0x140);
+    }
+  }
+
+  /* Input volume */
+  if (inputEnabled != 0)
+  {
+    convertedvol = VOLUME_IN_CONVERT(Volume);
+
+    /* Left AIF1 ADC1 volume */
+    counter += CODEC_IO_Write(DeviceAddr, 0x400, convertedvol | 0x100);
+
+    /* Right AIF1 ADC1 volume */
+    counter += CODEC_IO_Write(DeviceAddr, 0x401, convertedvol | 0x100);
+
+    /* Left AIF1 ADC2 volume */
+    counter += CODEC_IO_Write(DeviceAddr, 0x404, convertedvol | 0x100);
+
+    /* Right AIF1 ADC2 volume */
+    counter += CODEC_IO_Write(DeviceAddr, 0x405, convertedvol | 0x100);
+  }
+  return counter;
+}
+
+/**
+  * @brief Enables or disables the mute feature on the audio codec.
+  * @param DeviceAddr: Device address on communication Bus.   
+  * @param Cmd: AUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the
+  *             mute mode.
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t wm8994_SetMute(uint16_t DeviceAddr, uint32_t Cmd)
+{
+  uint32_t counter = 0;
+  
+  if (outputEnabled != 0)
+  {
+    /* Set the Mute mode */
+    if(Cmd == AUDIO_MUTE_ON)
+    {
+      /* Soft Mute the AIF1 Timeslot 0 DAC1 path L&R */
+      counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0200);
+
+      /* Soft Mute the AIF1 Timeslot 1 DAC2 path L&R */
+      counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0200);
+    }
+    else /* AUDIO_MUTE_OFF Disable the Mute */
+    {
+      /* Unmute the AIF1 Timeslot 0 DAC1 path L&R */
+      counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0000);
+
+      /* Unmute the AIF1 Timeslot 1 DAC2 path L&R */
+      counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0000);
+    }
+  }
+  return counter;
+}
+
+/**
+  * @brief Switch dynamically (while audio file is played) the output target 
+  *         (speaker or headphone).
+  * @param DeviceAddr: Device address on communication Bus.
+  * @param Output: specifies the audio output target: OUTPUT_DEVICE_SPEAKER,
+  *         OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO 
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t wm8994_SetOutputMode(uint16_t DeviceAddr, uint8_t Output)
+{
+  uint32_t counter = 0; 
+  
+  switch (Output) 
+  {
+  case OUTPUT_DEVICE_SPEAKER:
+    /* Enable DAC1 (Left), Enable DAC1 (Right), 
+    Disable DAC2 (Left), Disable DAC2 (Right)*/
+    counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0C0C);
+    
+    /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0000);
+    
+    /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0000);
+    
+    /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
+    
+    /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
+    break;
+    
+  case OUTPUT_DEVICE_HEADPHONE:
+    /* Disable DAC1 (Left), Disable DAC1 (Right), 
+    Enable DAC2 (Left), Enable DAC2 (Right)*/
+    counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
+    
+    /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
+    
+    /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
+    
+    /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
+    
+    /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
+    break;
+    
+  case OUTPUT_DEVICE_BOTH:
+    /* Enable DAC1 (Left), Enable DAC1 (Right), 
+    also Enable DAC2 (Left), Enable DAC2 (Right)*/
+    counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C);
+    
+    /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
+    
+    /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
+    
+    /* Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
+    
+    /* Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
+    break;
+    
+  default:
+    /* Disable DAC1 (Left), Disable DAC1 (Right), 
+    Enable DAC2 (Left), Enable DAC2 (Right)*/
+    counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
+    
+    /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
+    
+    /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
+    
+    /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
+    
+    /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+    counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
+    break;    
+  }  
+  return counter;
+}
+
+/**
+  * @brief Sets new frequency.
+  * @param DeviceAddr: Device address on communication Bus.
+  * @param AudioFreq: Audio frequency used to play the audio stream.
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t wm8994_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq)
+{
+  uint32_t counter = 0;
+ 
+  /*  Clock Configurations */
+  switch (AudioFreq)
+  {
+  case  AUDIO_FREQUENCY_8K:
+    /* AIF1 Sample Rate = 8 (KHz), ratio=256 */ 
+    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0003);
+    break;
+    
+  case  AUDIO_FREQUENCY_16K:
+    /* AIF1 Sample Rate = 16 (KHz), ratio=256 */ 
+    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0033);
+    break;
+    
+  case  AUDIO_FREQUENCY_48K:
+    /* AIF1 Sample Rate = 48 (KHz), ratio=256 */ 
+    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
+    break;
+    
+  case  AUDIO_FREQUENCY_96K:
+    /* AIF1 Sample Rate = 96 (KHz), ratio=256 */ 
+    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x00A3);
+    break;
+    
+  case  AUDIO_FREQUENCY_11K:
+    /* AIF1 Sample Rate = 11.025 (KHz), ratio=256 */ 
+    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0013);
+    break;
+    
+  case  AUDIO_FREQUENCY_22K:
+    /* AIF1 Sample Rate = 22.050 (KHz), ratio=256 */ 
+    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0043);
+    break;
+    
+  case  AUDIO_FREQUENCY_44K:
+    /* AIF1 Sample Rate = 44.1 (KHz), ratio=256 */ 
+    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0073);
+    break; 
+    
+  default:
+    /* AIF1 Sample Rate = 48 (KHz), ratio=256 */ 
+    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
+    break; 
+  }
+  return counter;
+}
+
+/**
+  * @brief Resets wm8994 registers.
+  * @param DeviceAddr: Device address on communication Bus. 
+  * @retval 0 if correct communication, else wrong communication
+  */
+uint32_t wm8994_Reset(uint16_t DeviceAddr)
+{
+  uint32_t counter = 0;
+  
+  /* Reset Codec by writing in 0x0000 address register */
+  counter = CODEC_IO_Write(DeviceAddr, 0x0000, 0x0000);
+  outputEnabled = 0;
+  inputEnabled=0;
+
+  return counter;
+}
+
+/**
+  * @brief  Writes/Read a single data.
+  * @param  Addr: I2C address
+  * @param  Reg: Reg address 
+  * @param  Value: Data to be written
+  * @retval None
+  */
+static uint8_t CODEC_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value)
+{
+  uint32_t result = 0;
+  
+ AUDIO_IO_Write(Addr, Reg, Value);
+  
+#ifdef VERIFY_WRITTENDATA
+  /* Verify that the data has been correctly written */
+  result = (AUDIO_IO_Read(Addr, Reg) == Value)? 0:1;
+#endif /* VERIFY_WRITTENDATA */
+  
+  return result;
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/wm8994/wm8994.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,188 @@
+/**
+  ******************************************************************************
+  * @file    wm8994.h
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    24-June-2015
+  * @brief   This file contains all the functions prototypes for the 
+  *          wm8994.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 __WM8994_H
+#define __WM8994_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "../Common/audio.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup Component
+  * @{
+  */ 
+  
+/** @addtogroup WM8994
+  * @{
+  */
+
+/** @defgroup WM8994_Exported_Types
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup WM8994_Exported_Constants
+  * @{
+  */ 
+
+/******************************************************************************/
+/***************************  Codec User defines ******************************/
+/******************************************************************************/
+/* Codec output DEVICE */
+#define OUTPUT_DEVICE_SPEAKER                 ((uint16_t)0x0001)
+#define OUTPUT_DEVICE_HEADPHONE               ((uint16_t)0x0002)
+#define OUTPUT_DEVICE_BOTH                    ((uint16_t)0x0003)
+#define OUTPUT_DEVICE_AUTO                    ((uint16_t)0x0004)
+#define INPUT_DEVICE_DIGITAL_MICROPHONE_1     ((uint16_t)0x0100)
+#define INPUT_DEVICE_DIGITAL_MICROPHONE_2     ((uint16_t)0x0200)
+#define INPUT_DEVICE_INPUT_LINE_1             ((uint16_t)0x0300)
+#define INPUT_DEVICE_INPUT_LINE_2             ((uint16_t)0x0400)
+
+/* Volume Levels values */
+#define DEFAULT_VOLMIN                0x00
+#define DEFAULT_VOLMAX                0xFF
+#define DEFAULT_VOLSTEP               0x04
+
+#define AUDIO_PAUSE                   0
+#define AUDIO_RESUME                  1
+
+/* Codec POWER DOWN modes */
+#define CODEC_PDWN_HW                 1
+#define CODEC_PDWN_SW                 2
+
+/* MUTE commands */
+#define AUDIO_MUTE_ON                 1
+#define AUDIO_MUTE_OFF                0
+
+/* 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)  
+
+#define VOLUME_CONVERT(Volume)        (((Volume) > 100)? 100:((uint8_t)(((Volume) * 63) / 100)))
+#define VOLUME_IN_CONVERT(Volume)     (((Volume) >= 100)? 239:((uint8_t)(((Volume) * 240) / 100)))
+
+/******************************************************************************/
+/****************************** REGISTER MAPPING ******************************/
+/******************************************************************************/
+/** 
+  * @brief  WM8994 ID  
+  */  
+#define  WM8994_ID    0x8994
+
+/**
+  * @brief Device ID Register: Reading from this register will indicate device 
+  *                            family ID 8994h
+  */
+#define WM8994_CHIPID_ADDR                  0x00
+
+/**
+  * @}
+  */ 
+
+/** @defgroup WM8994_Exported_Macros
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+/** @defgroup WM8994_Exported_Functions
+  * @{
+  */
+    
+/*------------------------------------------------------------------------------
+                           Audio Codec functions 
+------------------------------------------------------------------------------*/
+/* High Layer codec functions */
+uint32_t wm8994_Init(uint16_t DeviceAddr, uint16_t OutputInputDevice, uint8_t Volume, uint32_t AudioFreq);
+void     wm8994_DeInit(void);
+uint32_t wm8994_ReadID(uint16_t DeviceAddr);
+uint32_t wm8994_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size);
+uint32_t wm8994_Pause(uint16_t DeviceAddr);
+uint32_t wm8994_Resume(uint16_t DeviceAddr);
+uint32_t wm8994_Stop(uint16_t DeviceAddr, uint32_t Cmd);
+uint32_t wm8994_SetVolume(uint16_t DeviceAddr, uint8_t Volume);
+uint32_t wm8994_SetMute(uint16_t DeviceAddr, uint32_t Cmd);
+uint32_t wm8994_SetOutputMode(uint16_t DeviceAddr, uint8_t Output);
+uint32_t wm8994_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq);
+uint32_t wm8994_Reset(uint16_t DeviceAddr);
+
+/* AUDIO IO functions */
+void    AUDIO_IO_Init(void);
+void    AUDIO_IO_DeInit(void);
+void    AUDIO_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value);
+uint8_t AUDIO_IO_Read(uint8_t Addr, uint16_t Reg);
+void    AUDIO_IO_Delay(uint32_t Delay);
+
+/* Audio driver structure */
+extern AUDIO_DrvTypeDef   wm8994_drv;
+
+#endif /* __WM8994_H */
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */ 
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Disco/stm32l476g_discovery.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,1771 @@
+/**
+  ******************************************************************************
+  * @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****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Disco/stm32l476g_discovery.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,566 @@
+/**
+  ******************************************************************************
+  * @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****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Disco/stm32l476g_discovery_audio.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,1422 @@
+/**
+  ******************************************************************************
+  * @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_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_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.
+  */
+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_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
+  */
+static void AUDIO_CODEC_Reset(void)
+{
+  /* Initialize the audio driver structure */
+  hAudioOut.AudioDrv = &cs43l22_drv; 
+  
+  hAudioOut.AudioDrv->Reset(AUDIO_I2C_ADDRESS);
+}
+
+/**
+  * @}
+  */
+
+/** @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****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Disco/stm32l476g_discovery_audio.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,268 @@
+/**
+  ******************************************************************************
+  * @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 "../Components/cs43l22/cs43l22.h"
+#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
+/**
+  * @}
+  */
+/*------------------------------------------------------------------------------
+                          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****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Disco/stm32l476g_discovery_compass.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,270 @@
+/**
+  ******************************************************************************
+  * @file    stm32l476g_discovery_compass.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 E-Compass
+  *          (ACCELEROMETER + MAGNETOMETER) MEMS LSM303C available on 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.h"
+#include "stm32l476g_discovery_compass.h"
+#include "../Components/lsm303c/lsm303c.h"
+#include <math.h>
+    
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup STM32L476G_DISCOVERY
+  * @{
+  */
+
+/** @defgroup STM32L476G_DISCOVERY_COMPASS STM32L476G-DISCOVERY COMPASS
+  * @{
+  */
+
+/* Private typedef -----------------------------------------------------------*/
+/** @defgroup STM32L476G_DISCOVERY_COMPASS_Private_Types Private Types
+  * @{
+  */
+/**
+  * @}
+  */
+
+/* Private defines ------------------------------------------------------------*/
+/** @defgroup STM32L476G_DISCOVERY_COMPASS_Private_Constants Private Constants
+  * @{
+  */
+/**
+  * @}
+  */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup STM32L476G_DISCOVERY_COMPASS_Private_Macros Private Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+/* Private variables ---------------------------------------------------------*/
+/** @defgroup STM32L476G_DISCOVERY_COMPASS_Private_Variables Private Variables
+  * @{
+  */
+static ACCELERO_DrvTypeDef *AccelerometerDrv;
+static MAGNETO_DrvTypeDef  *MagnetoDrv;
+
+/**
+  * @}
+  */
+
+/* Private function prototypes -----------------------------------------------*/
+/** @addtogroup STM32L476G_DISCOVERY_COMPASS_Private_FunctionPrototypes Private Functions
+  * @{
+  */
+/**
+  * @}
+  */
+
+/* Exported functions ---------------------------------------------------------*/
+/** @addtogroup STM32L476G_DISCOVERY_COMPASS_Exported_Functions
+  * @{
+  */
+extern void  ACCELERO_IO_DeInit(void);
+extern void  MAGNETO_IO_DeInit(void);
+
+/**
+  * @brief  Initialize the COMPASS.
+  * @retval COMPASS_OK or COMPASS_ERROR
+  */
+COMPASS_StatusTypeDef BSP_COMPASS_Init(void)
+{  
+  COMPASS_StatusTypeDef ret = COMPASS_OK;
+  uint16_t ctrl = 0x0000;
+  ACCELERO_InitTypeDef LSM303C_InitStructure;
+  ACCELERO_FilterConfigTypeDef LSM303C_FilterStructure;
+  MAGNETO_InitTypeDef LSM303C_InitStructureMag;
+ 
+  if(Lsm303cDrv_accelero.ReadID() != LMS303C_ACC_ID)
+  {
+    ret = COMPASS_ERROR;
+  }
+  else
+  {
+    /* Initialize the COMPASS accelerometer driver structure */
+    AccelerometerDrv = &Lsm303cDrv_accelero;
+  
+    /* MEMS configuration ------------------------------------------------------*/
+    /* Fill the COMPASS accelerometer structure */
+    LSM303C_InitStructure.AccOutput_DataRate = LSM303C_ACC_ODR_50_HZ;
+    LSM303C_InitStructure.Axes_Enable= LSM303C_ACC_AXES_ENABLE;
+    LSM303C_InitStructure.AccFull_Scale = LSM303C_ACC_FULLSCALE_2G;
+    LSM303C_InitStructure.BlockData_Update = LSM303C_ACC_BDU_CONTINUOUS;
+    LSM303C_InitStructure.High_Resolution = LSM303C_ACC_HR_DISABLE;
+    LSM303C_InitStructure.Communication_Mode = LSM303C_ACC_SPI_MODE;
+        
+    /* Configure MEMS: data rate, power mode, full scale and axes */
+    ctrl =  (LSM303C_InitStructure.High_Resolution | LSM303C_InitStructure.AccOutput_DataRate | \
+                       LSM303C_InitStructure.Axes_Enable | LSM303C_InitStructure.BlockData_Update);
+    
+    ctrl |= (LSM303C_InitStructure.AccFull_Scale | LSM303C_InitStructure.Communication_Mode) << 8;
+    
+    /* Configure the COMPASS accelerometer main parameters */
+    AccelerometerDrv->Init(ctrl);
+  
+    /* Fill the COMPASS accelerometer HPF structure */
+    LSM303C_FilterStructure.HighPassFilter_Mode_Selection = LSM303C_ACC_HPM_NORMAL_MODE;
+    LSM303C_FilterStructure.HighPassFilter_CutOff_Frequency = LSM303C_ACC_DFC1_ODRDIV50;
+    LSM303C_FilterStructure.HighPassFilter_Stat = LSM303C_ACC_HPI2S_INT1_DISABLE | LSM303C_ACC_HPI2S_INT2_DISABLE;
+    
+    /* Configure MEMS: mode, cutoff frequency, Filter status, Click, AOI1 and AOI2 */
+    ctrl = (uint8_t) (LSM303C_FilterStructure.HighPassFilter_Mode_Selection |\
+                      LSM303C_FilterStructure.HighPassFilter_CutOff_Frequency|\
+                      LSM303C_FilterStructure.HighPassFilter_Stat);
+
+    /* Configure the COMPASS accelerometer LPF main parameters */
+    AccelerometerDrv->FilterConfig(ctrl);
+  }  
+
+  if(Lsm303cDrv_magneto.ReadID() != LMS303C_MAG_ID)
+  {
+    ret = COMPASS_ERROR;
+  }
+  else
+  {
+    /* Initialize the COMPASS magnetometer driver structure */
+    MagnetoDrv = &Lsm303cDrv_magneto;
+    
+    /* MEMS configuration ------------------------------------------------------*/
+    /* Fill the COMPASS magnetometer structure */
+    LSM303C_InitStructureMag.Register1 = LSM303C_MAG_TEMPSENSOR_DISABLE | LSM303C_MAG_OM_XY_ULTRAHIGH | LSM303C_MAG_ODR_40_HZ;
+    LSM303C_InitStructureMag.Register2 = LSM303C_MAG_FS_16_GA | LSM303C_MAG_REBOOT_DEFAULT | LSM303C_MAG_SOFT_RESET_DEFAULT;
+    LSM303C_InitStructureMag.Register3 = LSM303C_MAG_SPI_MODE | LSM303C_MAG_CONFIG_NORMAL_MODE | LSM303C_MAG_CONTINUOUS_MODE;
+    LSM303C_InitStructureMag.Register4 = LSM303C_MAG_OM_Z_ULTRAHIGH | LSM303C_MAG_BLE_LSB;
+    LSM303C_InitStructureMag.Register5 = LSM303C_MAG_BDU_CONTINUOUS;
+    /* Configure the COMPASS magnetometer main parameters */
+    MagnetoDrv->Init(LSM303C_InitStructureMag);
+  } 
+
+  return ret;
+}
+
+/**
+  * @brief  DeInitialize the COMPASS.
+  * @retval None.
+  */
+void BSP_COMPASS_DeInit(void)
+{
+  /* DeInitialize the COMPASS accelerometer & magnetometer IO interfaces */
+  ACCELERO_IO_DeInit();
+  MAGNETO_IO_DeInit();
+}
+
+/**
+  * @brief  Put the COMPASS in low power mode.
+  * @retval None
+  */
+void BSP_COMPASS_LowPower(void)
+{
+  /* Put the COMPASS accelerometer in low power mode */
+  if(AccelerometerDrv != NULL)
+  {
+    if(AccelerometerDrv->LowPower != NULL)
+    {
+      AccelerometerDrv->LowPower();
+    }
+  }
+  /* Put the COMPASS magnetometer in low power mode */
+  if(MagnetoDrv != NULL)
+  {
+    if(MagnetoDrv->LowPower != NULL)
+    {
+      MagnetoDrv->LowPower();
+    }
+  }
+}
+
+/**
+  * @brief  Get XYZ acceleration values.
+  * @param  pDataXYZ Pointer on 3 angular accelerations table with  
+  *                  pDataXYZ[0] = X axis, pDataXYZ[1] = Y axis, pDataXYZ[2] = Z axis
+  * @retval None
+  */
+void BSP_COMPASS_AccGetXYZ(int16_t *pDataXYZ)
+{
+  if(AccelerometerDrv != NULL)
+  {
+    if(AccelerometerDrv->GetXYZ != NULL)
+    {   
+      AccelerometerDrv->GetXYZ(pDataXYZ);
+    }
+  }
+}
+
+/**
+  * @brief  Get XYZ magnetometer values.
+  * @param  pDataXYZ Pointer on 3 magnetometer values table with
+  *                  pDataXYZ[0] = X axis, pDataXYZ[1] = Y axis, pDataXYZ[2] = Z axis 
+  * @retval None
+  */
+void BSP_COMPASS_MagGetXYZ(int16_t *pDataXYZ)
+{
+  if(MagnetoDrv != NULL)
+  {
+    if(MagnetoDrv->GetXYZ != NULL)
+    {   
+      MagnetoDrv->GetXYZ(pDataXYZ);
+    }
+  }
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Disco/stm32l476g_discovery_compass.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,127 @@
+/**
+  ******************************************************************************
+  * @file    stm32l476g_discovery_compass.h
+  * @author  MCD Application Team
+  * @version V1.0.1
+  * @date    16-September-2015
+  * @brief   This file contains definitions for stm32l476g_discovery_compass.c 
+  *          firmware 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_COMPASS_H
+#define __STM32L476G_DISCOVERY_COMPASS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32l476g_discovery.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup STM32L476G_DISCOVERY
+  * @{
+  */
+
+/** @addtogroup STM32L476G_DISCOVERY_COMPASS
+  * @{
+  */
+
+/** @defgroup STM32L476G_DISCOVERY_COMPASS_Exported_Types Exported Types
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup STM32L476G_DISCOVERY_COMPASS_Exported_Constants Exported Constants
+  * @{
+  */
+typedef enum 
+{
+  COMPASS_OK = 0,
+  COMPASS_ERROR = 1,
+  COMPASS_TIMEOUT = 2
+} 
+COMPASS_StatusTypeDef;
+
+/**
+  * @}
+  */
+
+/** @defgroup STM32L476G_DISCOVERY_COMPASS_Exported_Macros Exported Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup STM32L476G_DISCOVERY_COMPASS_Exported_Functions Exported Functions
+  * @{
+  */
+/* COMPASS functions */
+COMPASS_StatusTypeDef   BSP_COMPASS_Init(void);
+void                    BSP_COMPASS_DeInit(void);
+void                    BSP_COMPASS_LowPower(void);
+void                    BSP_COMPASS_MagGetXYZ(int16_t *pDataXYZ);
+void                    BSP_COMPASS_AccGetXYZ(int16_t *pDataXYZ);
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32L476G_DISCOVERY_COMPASS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Disco/stm32l476g_discovery_glass_lcd.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,989 @@
+/**
+  ******************************************************************************
+  * @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****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Disco/stm32l476g_discovery_glass_lcd.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,547 @@
+ /**
+  ******************************************************************************
+  * @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****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Disco/stm32l476g_discovery_gyroscope.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,300 @@
+/**
+  ******************************************************************************
+  * @file    stm32l476g_discovery_gyroscope.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 L3GD20
+  *          MEMS accelerometer available on 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_gyroscope.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup STM32L476G_DISCOVERY
+  * @{
+  */
+
+/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE STM32L476G-DISCOVERY GYROSCOPE
+  * @{
+  */
+
+/* Private typedef -----------------------------------------------------------*/
+/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Private_Types Private Types
+  * @{
+  */
+/**
+  * @}
+  */
+
+/* Private defines ------------------------------------------------------------*/
+/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Private_Constants Private Constants
+  * @{
+  */
+/**
+  * @}
+  */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Private_Macros Private Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+/* Private variables ---------------------------------------------------------*/
+/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Private_Variables Private Variables
+  * @{
+  */
+static GYRO_DrvTypeDef *GyroscopeDrv;
+
+/**
+  * @}
+  */
+
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Private_FunctionPrototypes Private Functions
+  * @{
+  */
+/**
+  * @}
+  */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup STM32L476G_DISCOVERY_GYROSCOPE_Exported_Functions
+  * @{
+  */
+
+/**
+  * @brief  Initialize Gyroscope.
+  * @retval GYRO_OK or GYRO_ERROR
+  */
+uint8_t BSP_GYRO_Init(void)
+{  
+  uint8_t ret = GYRO_ERROR;
+  uint16_t ctrl = 0x0000;
+  GYRO_InitTypeDef L3GD20_InitStructure;
+  GYRO_FilterConfigTypeDef L3GD20_FilterStructure={0,0};
+
+  if((L3gd20Drv.ReadID() == I_AM_L3GD20) || (L3gd20Drv.ReadID() == I_AM_L3GD20_TR))
+  {
+    /* Initialize the gyroscope driver structure */
+    GyroscopeDrv = &L3gd20Drv;
+
+    /* Configure Mems : data rate, power mode, full scale and axes */
+    L3GD20_InitStructure.Power_Mode = L3GD20_MODE_ACTIVE;
+    L3GD20_InitStructure.Output_DataRate = L3GD20_OUTPUT_DATARATE_1;
+    L3GD20_InitStructure.Axes_Enable = L3GD20_AXES_ENABLE;
+    L3GD20_InitStructure.Band_Width = L3GD20_BANDWIDTH_4;
+    L3GD20_InitStructure.BlockData_Update = L3GD20_BlockDataUpdate_Continous;
+    L3GD20_InitStructure.Endianness = L3GD20_BLE_LSB;
+    L3GD20_InitStructure.Full_Scale = L3GD20_FULLSCALE_500; 
+
+    /* Configure MEMS: data rate, power mode, full scale and axes */
+    ctrl = (uint16_t) (L3GD20_InitStructure.Power_Mode | L3GD20_InitStructure.Output_DataRate | \
+                       L3GD20_InitStructure.Axes_Enable | L3GD20_InitStructure.Band_Width);
+
+    ctrl |= (uint16_t) ((L3GD20_InitStructure.BlockData_Update | L3GD20_InitStructure.Endianness | \
+                        L3GD20_InitStructure.Full_Scale) << 8);
+
+    /* Initialize component */
+    GyroscopeDrv->Init(ctrl);
+  
+    L3GD20_FilterStructure.HighPassFilter_Mode_Selection =L3GD20_HPM_NORMAL_MODE_RES;
+    L3GD20_FilterStructure.HighPassFilter_CutOff_Frequency = L3GD20_HPFCF_0;
+
+    ctrl = (uint8_t) ((L3GD20_FilterStructure.HighPassFilter_Mode_Selection |\
+                       L3GD20_FilterStructure.HighPassFilter_CutOff_Frequency));
+
+    /* Configure component filter */
+    GyroscopeDrv->FilterConfig(ctrl) ;
+  
+    /* Enable component filter */
+    GyroscopeDrv->FilterCmd(L3GD20_HIGHPASSFILTER_ENABLE);
+    
+    ret = GYRO_OK;
+  }
+  else
+  {
+    ret = GYRO_ERROR;
+  }
+  
+  return ret;
+}
+
+
+/**
+  * @brief  DeInitialize Gyroscope.
+  * @retval None
+  */
+void BSP_GYRO_DeInit(void)
+{
+  GYRO_IO_DeInit();  
+}
+
+
+/**
+  * @brief  Put Gyroscope in low power mode.
+  * @retval None
+  */
+void BSP_GYRO_LowPower(void)
+{
+  uint16_t ctrl = 0x0000;
+  GYRO_InitTypeDef L3GD20_InitStructure;
+  
+  /* configure only Power_Mode field */ 
+  L3GD20_InitStructure.Power_Mode = L3GD20_MODE_POWERDOWN;
+  
+  ctrl = (uint16_t) (L3GD20_InitStructure.Power_Mode);
+  
+  /* Set component in low-power mode */
+  GyroscopeDrv->LowPower(ctrl);
+
+
+}
+
+/**
+  * @brief  Read ID of Gyroscope component.
+  * @retval ID
+  */
+uint8_t BSP_GYRO_ReadID(void)
+{
+  uint8_t id = 0x00;
+
+  if(GyroscopeDrv->ReadID != NULL)
+  {
+    id = GyroscopeDrv->ReadID();
+  }  
+  return id;
+}
+
+/**
+  * @brief  Reboot memory content of Gyroscope.
+  * @retval None
+  */
+void BSP_GYRO_Reset(void)
+{
+  if(GyroscopeDrv->Reset != NULL)
+  {
+    GyroscopeDrv->Reset();
+  }  
+}
+
+/**
+  * @brief  Configure Gyroscope interrupts (INT1 or INT2).
+  * @param  pIntConfig: pointer to a GYRO_InterruptConfigTypeDef 
+  *         structure that contains the configuration setting for the L3GD20 Interrupt.
+  * @retval None
+  */
+void BSP_GYRO_ITConfig(GYRO_InterruptConfigTypeDef *pIntConfig)
+{  
+  uint16_t interruptconfig = 0x0000;
+
+  if(GyroscopeDrv->ConfigIT != NULL)
+  {
+    /* Configure latch Interrupt request and axe interrupts */                   
+    interruptconfig |= ((uint8_t)(pIntConfig->Latch_Request| \
+                                  pIntConfig->Interrupt_Axes) << 8);
+
+    interruptconfig |= (uint8_t)(pIntConfig->Interrupt_ActiveEdge);
+
+    GyroscopeDrv->ConfigIT(interruptconfig);
+  }
+}
+
+/**
+  * @brief  Enable Gyroscope interrupts (INT1 or INT2).
+  * @param  IntPin: Interrupt pin 
+  *      This parameter can be: 
+  *        @arg L3GD20_INT1
+  *        @arg L3GD20_INT2
+  * @retval None
+  */
+void BSP_GYRO_EnableIT(uint8_t IntPin)
+{
+  if(GyroscopeDrv->EnableIT != NULL)
+  {
+    GyroscopeDrv->EnableIT(IntPin);
+  }
+}
+
+/**
+  * @brief  Disable Gyroscope interrupts (INT1 or INT2).
+  * @param  IntPin: Interrupt pin 
+  *      This parameter can be: 
+  *        @arg L3GD20_INT1
+  *        @arg L3GD20_INT2
+  * @retval None
+  */
+void BSP_GYRO_DisableIT(uint8_t IntPin)
+{
+  if(GyroscopeDrv->DisableIT != NULL)
+  {
+    GyroscopeDrv->DisableIT(IntPin);
+  }
+}
+
+/**
+  * @brief  Get XYZ angular acceleration from the Gyroscope.
+  * @param  pfData: pointer on floating array         
+  * @retval None
+  */
+void BSP_GYRO_GetXYZ(float* pfData)
+{
+  if(GyroscopeDrv->GetXYZ!= NULL)
+  {
+    GyroscopeDrv->GetXYZ(pfData);
+  }
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Disco/stm32l476g_discovery_gyroscope.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,132 @@
+/**
+  ******************************************************************************
+  * @file    stm32l476g_discovery_gyroscope.h
+  * @author  MCD Application Team
+  * @version V1.0.1
+  * @date    16-September-2015
+  * @brief   This file contains definitions for stm32l476g_discovery_gyroscope.c 
+  *          firmware 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_GYROSCOPE_H
+#define __STM32L476G_DISCOVERY_GYROSCOPE_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32l476g_discovery.h"
+/* Include Gyroscope component driver */
+#include "../Components/l3gd20/l3gd20.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup STM32L476G_DISCOVERY
+  * @{
+  */
+
+/** @addtogroup STM32L476G_DISCOVERY_GYROSCOPE
+  * @{
+  */
+
+/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Exported_Types Exported Types
+  * @{
+  */
+typedef enum 
+{
+  GYRO_OK = 0,
+  GYRO_ERROR = 1,
+  GYRO_TIMEOUT = 2
+} 
+GYRO_StatusTypeDef;
+
+/**
+  * @}
+  */
+
+/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Exported_Constants Exported Constants
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Exported_Macros Exported Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup STM32L476G_DISCOVERY_GYROSCOPE_Exported_Functions  Exported Functions
+  * @{
+  */
+/* Sensor Configuration Functions */ 
+uint8_t BSP_GYRO_Init(void);
+void    BSP_GYRO_DeInit(void);
+void    BSP_GYRO_LowPower(void);
+void    BSP_GYRO_Reset(void);
+uint8_t BSP_GYRO_ReadID(void);
+void    BSP_GYRO_ITConfig(GYRO_InterruptConfigTypeDef *pIntConfigStruct);
+void    BSP_GYRO_EnableIT(uint8_t IntPin);
+void    BSP_GYRO_DisableIT(uint8_t IntPin);
+void    BSP_GYRO_GetXYZ(float* pfData);
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32L476G_DISCOVERY_GYROSCOPE_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Disco/stm32l476g_discovery_idd.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,388 @@
+/**
+  ******************************************************************************
+  * @file    stm32l476g_discovery_idd.c
+  * @author  MCD Application Team
+  * @version V1.0.1
+  * @date    16-September-2015
+  * @brief   This file provides a set of firmware functions to manage the 
+  *          Idd measurement driver for 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_idd.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup STM32L476G_DISCOVERY
+  * @{
+  */
+  
+/** @defgroup STM32L476G_DISCOVERY_IDD STM32L476G-DISCOVERY IDD
+  * @brief This file includes the Idd driver for STM32L476G-DISCOVERY board.
+  *        It allows user to measure MCU Idd current on board, especially in 
+  *        different low power modes.
+  * @{
+  */
+
+/** @defgroup STM32L476G_DISCOVERY_IDD_Private_Defines Private Defines
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+
+/** @defgroup STM32L476G_DISCOVERY_IDD_Private_Variables Private Variables
+  * @{
+  */
+static IDD_DrvTypeDef *IddDrv;
+
+/**
+  * @}
+  */
+
+/** @defgroup STM32L476G_DISCOVERY_IDD_Private_Functions Private Functions
+  * @{
+  */
+
+/**
+  * @}
+  */ 
+
+/** @defgroup STM32L476G_DISCOVERY_IDD_Exported_Functions Exported Functions
+  * @{
+  */ 
+
+/**
+  * @brief  Configures IDD measurement component.
+  * @retval IDD_OK if no problem during initialization
+  */
+uint8_t BSP_IDD_Init(void)
+{
+  IDD_ConfigTypeDef iddconfig = {0};
+  uint8_t mfxstm32l152_id = 0;
+  uint8_t ret = 0;
+
+  /* wake up mfx component in case it went to standby mode */
+  mfxstm32l152_idd_drv.WakeUp(IDD_I2C_ADDRESS);
+  HAL_Delay(5);
+  
+  /* Read ID and verify if the MFX is ready */
+  mfxstm32l152_id = mfxstm32l152_idd_drv.ReadID(IDD_I2C_ADDRESS);
+  
+  if((mfxstm32l152_id == MFXSTM32L152_ID_1) || (mfxstm32l152_id == MFXSTM32L152_ID_2))
+  {
+    /* Initialize the Idd driver structure */
+    IddDrv = &mfxstm32l152_idd_drv;
+    
+    /* Initialize the Idd driver */
+    if(IddDrv->Init != NULL)
+    {
+      IddDrv->Init(IDD_I2C_ADDRESS);
+    }
+
+    /* Configure Idd component with default values */
+    iddconfig.AmpliGain = DISCOVERY_IDD_AMPLI_GAIN;
+    iddconfig.VddMin = DISCOVERY_IDD_VDD_MIN;
+    iddconfig.Shunt0Value = DISCOVERY_IDD_SHUNT0_VALUE;
+    iddconfig.Shunt1Value = DISCOVERY_IDD_SHUNT1_VALUE;
+    iddconfig.Shunt2Value = DISCOVERY_IDD_SHUNT2_VALUE;
+    iddconfig.Shunt3Value = 0;
+    iddconfig.Shunt4Value = DISCOVERY_IDD_SHUNT4_VALUE;
+    iddconfig.Shunt0StabDelay = DISCOVERY_IDD_SHUNT0_STABDELAY;
+    iddconfig.Shunt1StabDelay = DISCOVERY_IDD_SHUNT1_STABDELAY;
+    iddconfig.Shunt2StabDelay = DISCOVERY_IDD_SHUNT2_STABDELAY;
+    iddconfig.Shunt3StabDelay = 0;
+    iddconfig.Shunt4StabDelay = DISCOVERY_IDD_SHUNT4_STABDELAY;
+    iddconfig.ShuntNbOnBoard = MFXSTM32L152_IDD_SHUNT_NB_4;
+    iddconfig.ShuntNbUsed = MFXSTM32L152_IDD_SHUNT_NB_4;
+    iddconfig.VrefMeasurement = MFXSTM32L152_IDD_VREF_AUTO_MEASUREMENT_ENABLE;
+    iddconfig.Calibration = MFXSTM32L152_IDD_AUTO_CALIBRATION_ENABLE;
+    iddconfig.PreDelayUnit = MFXSTM32L152_IDD_PREDELAY_20_MS;
+    iddconfig.PreDelayValue = 0x7F;
+    iddconfig.MeasureNb = 100;
+    iddconfig.DeltaDelayUnit= MFXSTM32L152_IDD_DELTADELAY_0_5_MS;
+    iddconfig.DeltaDelayValue = 10;
+    BSP_IDD_Config(iddconfig);
+
+    ret = IDD_OK;
+  }
+  else
+  {
+    ret = IDD_ERROR;
+  }
+  
+  return ret;
+}
+
+/**
+  * @brief  Unconfigures IDD measurement component.
+  * @retval IDD_OK if no problem during deinitialization
+  */
+void BSP_IDD_DeInit(void)
+{
+  if(IddDrv->DeInit!= NULL)
+  {
+    IddDrv->DeInit(IDD_I2C_ADDRESS);
+  }
+}
+
+/**
+  * @brief  Reset Idd measurement component.
+  * @retval None
+  */
+void BSP_IDD_Reset(void)
+{
+  if(IddDrv->Reset != NULL)
+  {
+    IddDrv->Reset(IDD_I2C_ADDRESS);
+  }
+}
+
+/**
+  * @brief  Turn Idd measurement component in low power (standby/sleep) mode
+  * @retval None
+  */
+void BSP_IDD_LowPower(void)
+{
+  if(IddDrv->LowPower != NULL)
+  {
+    IddDrv->LowPower(IDD_I2C_ADDRESS);
+  }
+}
+
+/**
+  * @brief  Start Measurement campaign 
+  * @retval None
+  */
+void BSP_IDD_StartMeasure(void)
+{
+  if(IddDrv->Start != NULL)
+  {
+    IddDrv->Start(IDD_I2C_ADDRESS);
+  }
+}
+
+/**
+  * @brief  Configure Idd component
+  * @param  IddConfig: structure of idd parameters
+  * @retval None
+  */
+void BSP_IDD_Config(IDD_ConfigTypeDef IddConfig)
+{  
+  if(IddDrv->Config != NULL)
+  {
+    IddDrv->Config(IDD_I2C_ADDRESS, IddConfig);
+  }
+}
+
+/**
+  * @brief  Get Idd current value.
+  * @param  IddValue: Pointer on u32 to store Idd. Value unit is 10 nA.
+  * @retval None
+  */
+void BSP_IDD_GetValue(uint32_t *IddValue)
+{
+  if(IddDrv->GetValue != NULL)
+  {
+    IddDrv->GetValue(IDD_I2C_ADDRESS, IddValue);
+  }
+}
+
+/**
+  * @brief  Enable Idd interrupt that warn end of measurement
+  * @retval None
+  */
+void BSP_IDD_EnableIT(void)
+{
+  if(IddDrv->EnableIT != NULL)
+  {
+    IddDrv->EnableIT(IDD_I2C_ADDRESS);
+  }
+}
+
+/**
+  * @brief  Clear Idd interrupt that warn end of measurement
+  * @retval None
+  */
+void BSP_IDD_ClearIT(void)
+{
+  if(IddDrv->ClearIT != NULL)
+  {
+    IddDrv->ClearIT(IDD_I2C_ADDRESS);
+  }
+}
+
+/**
+  * @brief  Get Idd interrupt status
+  * @retval status
+  */
+uint8_t BSP_IDD_GetITStatus(void)
+{
+  if(IddDrv->GetITStatus != NULL)
+  {
+    return (IddDrv->GetITStatus(IDD_I2C_ADDRESS));
+  }
+  else
+  {
+    return IDD_ERROR;
+  }
+}
+
+/**
+  * @brief  Disable Idd interrupt that warn end of measurement
+  * @retval None
+  */
+void BSP_IDD_DisableIT(void)
+{
+  if(IddDrv->DisableIT != NULL)
+  {
+    IddDrv->DisableIT(IDD_I2C_ADDRESS);
+  }
+}
+
+/**
+  * @brief  Get Error Code .
+  * @retval Error code or error status
+  */
+uint8_t BSP_IDD_ErrorGetCode(void)
+{
+  if(IddDrv->ErrorGetSrc != NULL)
+  {
+    if((IddDrv->ErrorGetSrc(IDD_I2C_ADDRESS) & MFXSTM32L152_IDD_ERROR_SRC) != RESET)
+    {
+      if(IddDrv->ErrorGetCode != NULL)
+      {
+       return IddDrv->ErrorGetCode(IDD_I2C_ADDRESS);
+      }
+      else
+      {
+        return IDD_ERROR;
+      }
+    }
+    else
+    {
+      return IDD_ERROR;
+    }
+  }
+  else
+  {
+    return IDD_ERROR;
+  }
+}
+
+
+/**
+  * @brief  Enable error interrupt that warn end of measurement
+  * @retval None
+  */
+void BSP_IDD_ErrorEnableIT(void)
+{
+  if(IddDrv->ErrorEnableIT != NULL)
+  {
+    IddDrv->ErrorEnableIT(IDD_I2C_ADDRESS);
+  }
+}
+
+/**
+  * @brief  Clear Error interrupt that warn end of measurement
+  * @retval None
+  */
+void BSP_IDD_ErrorClearIT(void)
+{
+  if(IddDrv->ErrorClearIT != NULL)
+  {
+    IddDrv->ErrorClearIT(IDD_I2C_ADDRESS);
+  }
+}
+
+/**
+  * @brief  Get Error interrupt status
+  * @retval Status
+  */
+uint8_t BSP_IDD_ErrorGetITStatus(void)
+{
+  if(IddDrv->ErrorGetITStatus != NULL)
+  {
+    return (IddDrv->ErrorGetITStatus(IDD_I2C_ADDRESS));
+  }
+  else
+  {
+    return 0;
+  }
+}
+
+/**
+  * @brief  Disable Error interrupt 
+  * @retval None
+  */
+void BSP_IDD_ErrorDisableIT(void)
+{
+  if(IddDrv->ErrorDisableIT != NULL)
+  {
+    IddDrv->ErrorDisableIT(IDD_I2C_ADDRESS);
+  }
+}
+
+/**
+  * @brief  Wake up Idd measurement component.
+  * @retval None
+  */
+void BSP_IDD_WakeUp(void)
+{
+  if(IddDrv->WakeUp != NULL)
+  {
+    IddDrv->WakeUp(IDD_I2C_ADDRESS);
+  }
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Disco/stm32l476g_discovery_idd.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,168 @@
+ /**
+  ******************************************************************************
+  * @file    stm32l476g_discovery_idd.h
+  * @author  MCD Application Team
+  * @version V1.0.1
+  * @date    16-September-2015
+  * @brief   Header file for stm32l476g_discovery_idd.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_IDD_H
+#define __STM32L476G_DISCOVERY_IDD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32l476g_discovery.h"
+/* Include Idd measurement component driver */
+#include "../Components/mfxstm32l152/mfxstm32l152.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup STM32L476G_DISCOVERY
+  * @{
+  */
+
+/** @addtogroup STM32L476G_DISCOVERY_IDD
+  * @{
+  */
+
+/** @defgroup STM32L476G_DISCOVERY_IDD_Exported_Types  Exported Types
+  * @{
+  */
+
+/** @defgroup IDD_Config  IDD Config
+  * @{
+  */
+typedef enum 
+{
+  IDD_OK = 0,
+  IDD_TIMEOUT = 1,
+  IDD_ZERO_VALUE = 2,
+  IDD_ERROR = 0xFF
+} 
+IDD_StatusTypeDef;
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup STM32L476G_DISCOVERY_IDD_Exported_Defines  Exported Defines
+  * @{
+  */
+/**
+  * @brief  Shunt values on discovery in milli ohms
+  */
+#define DISCOVERY_IDD_SHUNT0_VALUE                  ((uint16_t) 1000)     /*!< value in milliohm */
+#define DISCOVERY_IDD_SHUNT1_VALUE                  ((uint16_t) 24)       /*!< value in ohm */
+#define DISCOVERY_IDD_SHUNT2_VALUE                  ((uint16_t) 620)      /*!< value in ohm */
+#define DISCOVERY_IDD_SHUNT4_VALUE                  ((uint16_t) 10000)    /*!< value in ohm */
+
+/**
+  * @brief  Shunt stabilization delay on discovery in milli ohms
+  */
+#define DISCOVERY_IDD_SHUNT0_STABDELAY              ((uint8_t) 149)       /*!< value in millisec */
+#define DISCOVERY_IDD_SHUNT1_STABDELAY              ((uint8_t) 149)       /*!< value in millisec */
+#define DISCOVERY_IDD_SHUNT2_STABDELAY              ((uint8_t) 149)       /*!< value in millisec */
+#define DISCOVERY_IDD_SHUNT4_STABDELAY              ((uint8_t) 255)       /*!< value in millisec */
+
+/**
+  * @brief  IDD Ampli Gain on discovery 
+  */
+#if defined(USE_STM32L476G_DISCO_REVC)
+#define DISCOVERY_IDD_AMPLI_GAIN                    ((uint16_t) 4967)     /*!< value is gain * 100 */
+#else
+#define DISCOVERY_IDD_AMPLI_GAIN                    ((uint16_t) 4990)     /*!< value is gain * 100 */
+#endif
+
+/**
+  * @brief  IDD Vdd Min on discovery 
+  */
+#define DISCOVERY_IDD_VDD_MIN                       ((uint16_t) 2000)     /*!< value in millivolt */
+
+/**
+  * @}
+  */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup STM32L476G_DISCOVERY_IDD_Exported_Functions  Exported Functions
+  * @{
+  */
+uint8_t   BSP_IDD_Init(void);
+void      BSP_IDD_DeInit(void);
+void      BSP_IDD_Reset(void);
+void      BSP_IDD_LowPower(void);
+void      BSP_IDD_WakeUp(void);
+void      BSP_IDD_StartMeasure(void);
+void      BSP_IDD_Config(IDD_ConfigTypeDef IddConfig);
+void      BSP_IDD_GetValue(uint32_t *IddValue);
+void      BSP_IDD_EnableIT(void);
+void      BSP_IDD_ClearIT(void);
+uint8_t   BSP_IDD_GetITStatus(void);
+void      BSP_IDD_DisableIT(void);
+uint8_t   BSP_IDD_ErrorGetCode(void);
+void      BSP_IDD_ErrorEnableIT(void);
+void      BSP_IDD_ErrorClearIT(void);
+uint8_t   BSP_IDD_ErrorGetITStatus(void);
+void      BSP_IDD_ErrorDisableIT(void);
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32L476G_DISCOVERY_IDD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Disco/stm32l476g_discovery_qspi.c	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,908 @@
+/**
+  ******************************************************************************
+  * @file    stm32l476g_discovery_qspi.c
+  * @author  MCD Application Team
+  * @version V1.0.1
+  * @date    16-September-2015
+  * @brief   This file includes a standard driver for the N25Q128A QSPI 
+  *          memory mounted on STM32L476G-Discovery board.
+  @verbatim
+  ==============================================================================
+                     ##### How to use this driver #####
+  ==============================================================================  
+  [..] 
+   (#) This driver is used to drive the N25Q128A QSPI external 
+       memory mounted on STM32L476G-DISCO evaluation board.
+       
+   (#) This driver need a specific component driver (N25Q128A) to be included with.
+
+   (#) Initialization steps:
+       (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This 
+            function includes the MSP layer hardware resources initialization and the
+            QSPI interface with the external memory.
+  
+   (#) QSPI memory operations
+       (++) QSPI memory can be accessed with read/write operations once it is
+            initialized.
+            Read/write operation can be performed with AHB access using the functions
+            BSP_QSPI_Read()/BSP_QSPI_Write(). 
+       (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory. 
+            (see the QSPI memory data sheet)
+       (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by
+            specifying the block address. You can perform an erase operation of the whole 
+            chip by calling the function BSP_QSPI_Erase_Chip(). 
+       (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory. 
+            (see the QSPI memory data sheet)
+  @endverbatim
+  ******************************************************************************
+  * @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_qspi.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup STM32L476G_DISCOVERY
+  * @{
+  */
+
+/** @defgroup STM32L476G_DISCOVERY_QSPI STM32L476G-DISCOVERY QSPI
+  * @{
+  */
+
+/* Private variables ---------------------------------------------------------*/
+
+/** @defgroup STM32L476G_DISCOVERY_QSPI_Private_Variables Private Variables
+  * @{
+  */
+QSPI_HandleTypeDef QSPIHandle;
+
+/**
+  * @}
+  */
+
+
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup STM32L476G_DISCOVERY_QSPI_Private_Functions Private Functions
+  * @{
+  */
+static void    QSPI_MspInit            (void);
+static void    QSPI_MspDeInit          (void);
+static uint8_t QSPI_ResetMemory        (QSPI_HandleTypeDef *hqspi);
+static uint8_t QSPI_DummyCyclesCfg     (QSPI_HandleTypeDef *hqspi);
+static uint8_t QSPI_WriteEnable        (QSPI_HandleTypeDef *hqspi);
+static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout);
+
+/**
+  * @}
+  */
+
+/* Exported functions ---------------------------------------------------------*/
+
+/** @addtogroup STM32L476G_DISCOVERY_QSPI_Exported_Functions
+  * @{
+  */
+
+/**
+  * @brief  Initializes the QSPI interface.
+  * @retval QSPI memory status
+  */
+uint8_t BSP_QSPI_Init(void)
+{ 
+  QSPIHandle.Instance = QUADSPI;
+
+  /* Call the DeInit function to reset the driver */
+  if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+        
+  /* System level initialization */
+  QSPI_MspInit();
+  
+  /* QSPI initialization */
+  QSPIHandle.Init.ClockPrescaler     = 1; /* QSPI clock = 80MHz / (ClockPrescaler+1) = 40MHz */
+  QSPIHandle.Init.FifoThreshold      = 4;
+  QSPIHandle.Init.SampleShifting     = QSPI_SAMPLE_SHIFTING_NONE;
+  QSPIHandle.Init.FlashSize          = POSITION_VAL(N25Q128A_FLASH_SIZE) - 1;
+  QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE;
+  QSPIHandle.Init.ClockMode          = QSPI_CLOCK_MODE_0;
+
+  if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  /* QSPI memory reset */
+  if (QSPI_ResetMemory(&QSPIHandle) != QSPI_OK)
+  {
+    return QSPI_NOT_SUPPORTED;
+  }
+ 
+  /* Configuration of the dummy cucles on QSPI memory side */
+  if (QSPI_DummyCyclesCfg(&QSPIHandle) != QSPI_OK)
+  {
+    return QSPI_NOT_SUPPORTED;
+  }
+  
+  return QSPI_OK;
+}
+
+/**
+  * @brief  De-Initializes the QSPI interface.
+  * @retval QSPI memory status
+  */
+uint8_t BSP_QSPI_DeInit(void)
+{ 
+  QSPIHandle.Instance = QUADSPI;
+  
+  /* Call the DeInit function to reset the driver */
+  if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  /* System level De-initialization */
+  QSPI_MspDeInit();
+
+    return QSPI_OK;
+}
+
+/**
+  * @brief  Reads an amount of data from the QSPI memory.
+  * @param  pData: Pointer to data to be read
+  * @param  ReadAddr: Read start address
+  * @param  Size: Size of data to read    
+  * @retval QSPI memory status
+  */
+uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
+{
+  QSPI_CommandTypeDef sCommand;
+
+  /* Initialize the read command */
+  sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
+  sCommand.Instruction       = QUAD_INOUT_FAST_READ_CMD;
+  sCommand.AddressMode       = QSPI_ADDRESS_4_LINES;
+  sCommand.AddressSize       = QSPI_ADDRESS_24_BITS;
+  sCommand.Address           = ReadAddr;
+  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+  sCommand.DataMode          = QSPI_DATA_4_LINES;
+  sCommand.DummyCycles       = N25Q128A_DUMMY_CYCLES_READ_QUAD;
+  sCommand.NbData            = Size;
+  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
+  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
+  sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
+  
+  /* Configure the command */
+  if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+  
+  /* Reception of the data */
+  if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  return QSPI_OK;
+}
+
+/**
+  * @brief  Writes an amount of data to the QSPI memory.
+  * @param  pData: Pointer to data to be written
+  * @param  WriteAddr: Write start address
+  * @param  Size: Size of data to write    
+  * @retval QSPI memory status
+  */
+uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
+{
+  QSPI_CommandTypeDef sCommand;
+  uint32_t end_addr, current_size, current_addr;
+
+  /* Calculation of the size between the write address and the end of the page */
+  current_addr = 0;
+
+  while (current_addr <= WriteAddr)
+  {
+    current_addr += N25Q128A_PAGE_SIZE;
+  }
+  current_size = current_addr - WriteAddr;
+
+  /* Check if the size of the data is less than the remaining place in the page */
+  if (current_size > Size)
+  {
+    current_size = Size;
+  }
+
+  /* Initialize the adress variables */
+  current_addr = WriteAddr;
+  end_addr = WriteAddr + Size;
+
+  /* Initialize the program command */
+  sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
+  sCommand.Instruction       = EXT_QUAD_IN_FAST_PROG_CMD;
+  sCommand.AddressMode       = QSPI_ADDRESS_4_LINES;
+  sCommand.AddressSize       = QSPI_ADDRESS_24_BITS;
+  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+  sCommand.DataMode          = QSPI_DATA_4_LINES;
+  sCommand.DummyCycles       = 0;
+  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
+  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
+  sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
+  
+  /* Perform the write page by page */
+  do
+  {
+    sCommand.Address = current_addr;
+    sCommand.NbData  = current_size;
+
+    /* Enable write operations */
+    if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
+    {
+      return QSPI_ERROR;
+    }
+    
+    /* Configure the command */
+    if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+    {
+      return QSPI_ERROR;
+    }
+    
+    /* Transmission of the data */
+    if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+    {
+      return QSPI_ERROR;
+    }
+    
+    /* Configure automatic polling mode to wait for end of program */  
+    if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
+    {
+      return QSPI_ERROR;
+    }
+    
+    /* Update the address and size variables for next page programming */
+    current_addr += current_size;
+    pData += current_size;
+    current_size = ((current_addr + N25Q128A_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : N25Q128A_PAGE_SIZE;
+  } while (current_addr < end_addr);
+  
+  return QSPI_OK;
+}
+
+/**
+  * @brief  Erases the specified block of the QSPI memory. 
+  * @param  BlockAddress: Block address to erase  
+  * @retval QSPI memory status
+  */
+uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress)
+{
+  QSPI_CommandTypeDef sCommand;
+
+  /* Initialize the erase command */
+  sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
+  sCommand.Instruction       = SUBSECTOR_ERASE_CMD;
+  sCommand.AddressMode       = QSPI_ADDRESS_1_LINE;
+  sCommand.AddressSize       = QSPI_ADDRESS_24_BITS;
+  sCommand.Address           = BlockAddress;
+  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+  sCommand.DataMode          = QSPI_DATA_NONE;
+  sCommand.DummyCycles       = 0;
+  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
+  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
+  sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
+
+  /* Enable write operations */
+  if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  /* Send the command */
+  if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+  
+  /* Configure automatic polling mode to wait for end of erase */  
+  if (QSPI_AutoPollingMemReady(&QSPIHandle, N25Q128A_SUBSECTOR_ERASE_MAX_TIME) != QSPI_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  return QSPI_OK;
+}
+
+/**
+  * @brief  Erases the specified sector of the QSPI memory. 
+  * @param  Sector: Sector address to erase (0 to 255) 
+  * @retval QSPI memory status
+  * @note This function is non blocking meaning that sector erase
+  *       operation is started but not completed when the function 
+  *       returns. Application has to call BSP_QSPI_GetStatus()
+  *       to know when the device is available again (i.e. erase operation
+  *       completed).
+  */
+uint8_t BSP_QSPI_Erase_Sector(uint32_t Sector)
+{
+  QSPI_CommandTypeDef sCommand;
+  
+  if (Sector >= (uint32_t)(N25Q128A_FLASH_SIZE/N25Q128A_SECTOR_SIZE))
+  {
+    return QSPI_ERROR;
+  }
+  
+  /* Initialize the erase command */
+  sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
+  sCommand.Instruction       = SECTOR_ERASE_CMD;
+  sCommand.AddressMode       = QSPI_ADDRESS_1_LINE;
+  sCommand.AddressSize       = QSPI_ADDRESS_24_BITS;
+  sCommand.Address           = (Sector * N25Q128A_SECTOR_SIZE);
+  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+  sCommand.DataMode          = QSPI_DATA_NONE;
+  sCommand.DummyCycles       = 0;
+  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
+  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
+  sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
+  
+  /* Enable write operations */
+  if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
+  {
+    return QSPI_ERROR;
+  }
+  
+  /* Send the command */
+  if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+  
+  return QSPI_OK;
+}
+
+/**
+  * @brief  Erases the entire QSPI memory.
+  * @retval QSPI memory status
+  */
+uint8_t BSP_QSPI_Erase_Chip(void)
+{
+  QSPI_CommandTypeDef sCommand;
+
+  /* Initialize the erase command */
+  sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
+  sCommand.Instruction       = BULK_ERASE_CMD;
+  sCommand.AddressMode       = QSPI_ADDRESS_NONE;
+  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+  sCommand.DataMode          = QSPI_DATA_NONE;
+  sCommand.DummyCycles       = 0;
+  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
+  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
+  sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
+
+  /* Enable write operations */
+  if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  /* Send the command */
+  if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+  
+  /* Configure automatic polling mode to wait for end of erase */  
+  if (QSPI_AutoPollingMemReady(&QSPIHandle, N25Q128A_BULK_ERASE_MAX_TIME) != QSPI_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  return QSPI_OK;
+}
+
+/**
+  * @brief  Reads current status of the QSPI memory.
+  * @retval QSPI memory status
+  */
+uint8_t BSP_QSPI_GetStatus(void)
+{
+  QSPI_CommandTypeDef sCommand;
+  uint8_t reg;
+
+  /* Initialize the read flag status register command */
+  sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
+  sCommand.Instruction       = READ_FLAG_STATUS_REG_CMD;
+  sCommand.AddressMode       = QSPI_ADDRESS_NONE;
+  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+  sCommand.DataMode          = QSPI_DATA_1_LINE;
+  sCommand.DummyCycles       = 0;
+  sCommand.NbData            = 1;
+  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
+  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
+  sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
+
+  /* Configure the command */
+  if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  /* Reception of the data */
+  if (HAL_QSPI_Receive(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+  
+  /* Check the value of the register */
+  if ((reg & (N25Q128A_FSR_PRERR | N25Q128A_FSR_VPPERR | N25Q128A_FSR_PGERR | N25Q128A_FSR_ERERR)) != 0)
+  {
+    return QSPI_ERROR;
+  }
+  else if ((reg & (N25Q128A_FSR_PGSUS | N25Q128A_FSR_ERSUS)) != 0)
+  {
+    return QSPI_SUSPENDED;
+  }
+  else if ((reg & N25Q128A_FSR_READY) != 0)
+  {
+    return QSPI_OK;
+  }
+  else
+  {
+    return QSPI_BUSY;
+  }
+}
+
+/**
+  * @brief  Return the configuration of the QSPI memory.
+  * @param  pInfo: pointer on the configuration structure  
+  * @retval QSPI memory status
+  */
+uint8_t BSP_QSPI_GetInfo(QSPI_Info* pInfo)
+{
+  /* Configure the structure with the memory configuration */
+  pInfo->FlashSize          = N25Q128A_FLASH_SIZE;
+  pInfo->EraseSectorSize    = N25Q128A_SUBSECTOR_SIZE;
+  pInfo->EraseSectorsNumber = (N25Q128A_FLASH_SIZE/N25Q128A_SUBSECTOR_SIZE);
+  pInfo->ProgPageSize       = N25Q128A_PAGE_SIZE;
+  pInfo->ProgPagesNumber    = (N25Q128A_FLASH_SIZE/N25Q128A_PAGE_SIZE);
+  
+  return QSPI_OK;
+}
+
+/**
+  * @brief  Configure the QSPI in memory-mapped mode
+  * @retval QSPI memory status
+  */
+uint8_t BSP_QSPI_EnableMemoryMappedMode(void)
+{
+  QSPI_CommandTypeDef      sCommand;
+  QSPI_MemoryMappedTypeDef sMemMappedCfg;
+
+  /* Configure the command for the read instruction */
+  sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
+  sCommand.Instruction       = QUAD_INOUT_FAST_READ_CMD;
+  sCommand.AddressMode       = QSPI_ADDRESS_4_LINES;
+  sCommand.AddressSize       = QSPI_ADDRESS_24_BITS;
+  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+  sCommand.DataMode          = QSPI_DATA_4_LINES;
+  sCommand.DummyCycles       = N25Q128A_DUMMY_CYCLES_READ_QUAD;
+  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
+  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
+  sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
+  
+  /* Configure the memory mapped mode */
+  sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_ENABLE;
+  sMemMappedCfg.TimeOutPeriod     = 4; /* 50 ns (4 periods of a 80 MHz clock) */
+  
+  if (HAL_QSPI_MemoryMapped(&QSPIHandle, &sCommand, &sMemMappedCfg) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  return QSPI_OK;
+}
+
+/**
+  * @brief  This function suspends an ongoing erase command.
+  * @retval QSPI memory status
+  */
+uint8_t BSP_QSPI_SuspendErase(void)
+{
+  QSPI_CommandTypeDef sCommand;
+  
+  /* Check whether the device is busy (erase operation is 
+  in progress).
+  */
+  if (BSP_QSPI_GetStatus() == QSPI_BUSY)
+  {
+    /* Initialize the erase command */
+    sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
+    sCommand.Instruction       = PROG_ERASE_SUSPEND_CMD;
+    sCommand.AddressMode       = QSPI_ADDRESS_NONE;
+    sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+    sCommand.DataMode          = QSPI_DATA_NONE;
+    sCommand.DummyCycles       = 0;
+    sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
+    sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
+    sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
+    
+    /* Enable write operations */
+    if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
+    {
+      return QSPI_ERROR;
+    }
+    
+    /* Send the command */
+    if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+    {
+      return QSPI_ERROR;
+    }
+    
+    if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED)
+    {
+      return QSPI_OK;
+    }
+    
+    return QSPI_ERROR;
+  }
+  
+  return QSPI_OK;
+}
+
+/**
+  * @brief  This function resumes a paused erase command.
+  * @retval QSPI memory status
+  */
+uint8_t BSP_QSPI_ResumeErase(void)
+{
+  QSPI_CommandTypeDef sCommand;
+  
+  /* Check whether the device is in suspended state */
+  if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED)
+  {
+    /* Initialize the erase command */
+    sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
+    sCommand.Instruction       = PROG_ERASE_RESUME_CMD;
+    sCommand.AddressMode       = QSPI_ADDRESS_NONE;
+    sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+    sCommand.DataMode          = QSPI_DATA_NONE;
+    sCommand.DummyCycles       = 0;
+    sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
+    sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
+    sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
+    
+    /* Enable write operations */
+    if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
+    {
+      return QSPI_ERROR;
+    }
+    
+    /* Send the command */
+    if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+    {
+      return QSPI_ERROR;
+    }
+    
+    /*
+    When this command is executed, the status register write in progress bit is set to 1, and
+    the flag status register program erase controller bit is set to 0. This command is ignored
+    if the device is not in a suspended state.
+    */
+    
+    if (BSP_QSPI_GetStatus() == QSPI_BUSY)
+    {
+      return QSPI_OK;
+    }
+    
+    return QSPI_ERROR;
+  }
+
+  return QSPI_OK;
+}
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32L476G_DISCOVERY_QSPI_Private_Functions 
+  * @{
+  */
+
+/**
+  * @brief  Initializes the QSPI MSP.
+  * @retval None
+  */
+static void QSPI_MspInit(void)
+{
+  GPIO_InitTypeDef GPIO_InitStruct;
+
+  /* Enable the QuadSPI memory interface clock */
+  __HAL_RCC_QSPI_CLK_ENABLE();
+
+  /* Reset the QuadSPI memory interface */
+  __HAL_RCC_QSPI_FORCE_RESET();
+  __HAL_RCC_QSPI_RELEASE_RESET();
+
+  /* Enable GPIO clocks */
+  __HAL_RCC_GPIOE_CLK_ENABLE();
+
+  /* QSPI CS GPIO pin configuration  */
+  GPIO_InitStruct.Pin       = GPIO_PIN_11;
+  GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
+  GPIO_InitStruct.Pull      = GPIO_PULLUP;
+  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
+  GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
+  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+  /* QSPI CLK, D0, D1, D2 and D3 GPIO pins configuration  */
+  GPIO_InitStruct.Pin       = (GPIO_PIN_10 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
+  GPIO_InitStruct.Pull      = GPIO_NOPULL;
+  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+}
+
+/**
+  * @brief  De-Initializes the QSPI MSP.
+  * @retval None
+  */
+static void QSPI_MspDeInit(void)
+{
+  GPIO_InitTypeDef GPIO_InitStruct;
+
+  /* QSPI CLK, CS, PE10 - PE15 GPIO pins de-configuration  */
+
+   __HAL_RCC_GPIOE_CLK_ENABLE();
+      HAL_GPIO_DeInit(GPIOE, (GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15));
+  /* Set GPIOE pin 11 in pull up mode (optimum default setting) */
+  GPIO_InitStruct.Mode      = GPIO_MODE_INPUT;
+  GPIO_InitStruct.Pin       = GPIO_PIN_11;
+  GPIO_InitStruct.Pull      = GPIO_NOPULL;
+  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_LOW;
+  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); 
+  
+  /* Set GPIOE pin 10 in no pull, low state (optimum default setting) */
+  GPIO_InitStruct.Mode      = GPIO_MODE_OUTPUT_PP  ;
+  GPIO_InitStruct.Pull      = GPIO_NOPULL;
+  GPIO_InitStruct.Pin       = (GPIO_PIN_10);
+  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_10, GPIO_PIN_RESET);
+   
+  /* Reset the QuadSPI memory interface */
+  __HAL_RCC_QSPI_FORCE_RESET();
+  __HAL_RCC_QSPI_RELEASE_RESET();
+
+  /* Disable the QuadSPI memory interface clock */
+  __HAL_RCC_QSPI_CLK_DISABLE();
+}
+
+/**
+  * @brief  This function reset the QSPI memory.
+  * @param  hqspi: QSPI handle
+  * @retval None
+  */
+static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi)
+{
+  QSPI_CommandTypeDef sCommand;
+
+  /* Initialize the reset enable command */
+  sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
+  sCommand.Instruction       = RESET_ENABLE_CMD;
+  sCommand.AddressMode       = QSPI_ADDRESS_NONE;
+  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+  sCommand.DataMode          = QSPI_DATA_NONE;
+  sCommand.DummyCycles       = 0;
+  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
+  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
+  sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
+
+  /* Send the command */
+  if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  /* Send the reset memory command */
+  sCommand.Instruction = RESET_MEMORY_CMD;
+  if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  /* Configure automatic polling mode to wait the memory is ready */  
+  if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  return QSPI_OK;
+}
+
+/**
+  * @brief  This function configure the dummy cycles on memory side.
+  * @param  hqspi: QSPI handle
+  * @retval None
+  */
+static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi)
+{
+  QSPI_CommandTypeDef sCommand;
+  uint8_t reg;
+
+  /* Initialize the read volatile configuration register command */
+  sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
+  sCommand.Instruction       = READ_VOL_CFG_REG_CMD;
+  sCommand.AddressMode       = QSPI_ADDRESS_NONE;
+  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+  sCommand.DataMode          = QSPI_DATA_1_LINE;
+  sCommand.DummyCycles       = 0;
+  sCommand.NbData            = 1;
+  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
+  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
+  sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
+
+  /* Configure the command */
+  if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  /* Reception of the data */
+  if (HAL_QSPI_Receive(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  /* Enable write operations */
+  if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  /* Update volatile configuration register (with new dummy cycles) */  
+  sCommand.Instruction = WRITE_VOL_CFG_REG_CMD;
+  MODIFY_REG(reg, N25Q128A_VCR_NB_DUMMY, (N25Q128A_DUMMY_CYCLES_READ_QUAD << POSITION_VAL(N25Q128A_VCR_NB_DUMMY)));
+      
+  /* Configure the write volatile configuration register command */
+  if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  /* Transmission of the data */
+  if (HAL_QSPI_Transmit(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+  
+  return QSPI_OK;
+}
+
+/**
+  * @brief  This function send a Write Enable and wait it is effective.
+  * @param  hqspi: QSPI handle
+  * @retval None
+  */
+static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
+{
+  QSPI_CommandTypeDef     sCommand;
+  QSPI_AutoPollingTypeDef sConfig;
+
+  /* Enable write operations */
+  sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
+  sCommand.Instruction       = WRITE_ENABLE_CMD;
+  sCommand.AddressMode       = QSPI_ADDRESS_NONE;
+  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+  sCommand.DataMode          = QSPI_DATA_NONE;
+  sCommand.DummyCycles       = 0;
+  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
+  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
+  sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
+
+  if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+  
+  /* Configure automatic polling mode to wait for write enabling */  
+  sConfig.Match           = N25Q128A_SR_WREN;
+  sConfig.Mask            = N25Q128A_SR_WREN;
+  sConfig.MatchMode       = QSPI_MATCH_MODE_AND;
+  sConfig.StatusBytesSize = 1;
+  sConfig.Interval        = 0x10;
+  sConfig.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
+
+  sCommand.Instruction    = READ_STATUS_REG_CMD;
+  sCommand.DataMode       = QSPI_DATA_1_LINE;
+
+  if (HAL_QSPI_AutoPolling(&QSPIHandle, &sCommand, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  return QSPI_OK;
+}
+
+/**
+  * @brief  This function read the SR of the memory and wait the EOP.
+  * @param  hqspi: QSPI handle
+  * @param  Timeout: Timeout for auto-polling
+  * @retval None
+  */
+static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
+{
+  QSPI_CommandTypeDef     sCommand;
+  QSPI_AutoPollingTypeDef sConfig;
+
+  /* Configure automatic polling mode to wait for memory ready */  
+  sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
+  sCommand.Instruction       = READ_STATUS_REG_CMD;
+  sCommand.AddressMode       = QSPI_ADDRESS_NONE;
+  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+  sCommand.DataMode          = QSPI_DATA_1_LINE;
+  sCommand.DummyCycles       = 0;
+  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
+  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
+  sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
+
+  sConfig.Match           = 0;
+  sConfig.Mask            = N25Q128A_SR_WIP;
+  sConfig.MatchMode       = QSPI_MATCH_MODE_AND;
+  sConfig.StatusBytesSize = 1;
+  sConfig.Interval        = 0x10;
+  sConfig.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
+
+  if (HAL_QSPI_AutoPolling(&QSPIHandle, &sCommand, &sConfig, Timeout) != HAL_OK)
+  {
+    return QSPI_ERROR;
+  }
+
+  return QSPI_OK;
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Disco/stm32l476g_discovery_qspi.h	Mon Nov 02 19:38:36 2015 +0000
@@ -0,0 +1,135 @@
+/**
+  ******************************************************************************
+  * @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 "../Components/n25q128a/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****/
+