diff libs/STM32F10x_StdPeriph_Lib_V3.5.0/Utilities/STM32_EVAL/STM32100E_EVAL/stm32100e_eval_ioe.c @ 0:c59513fd84fb

Initial commit of STM32 test code.
author Daniel O'Connor <darius@dons.net.au>
date Mon, 03 Oct 2011 21:19:15 +1030
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libs/STM32F10x_StdPeriph_Lib_V3.5.0/Utilities/STM32_EVAL/STM32100E_EVAL/stm32100e_eval_ioe.c	Mon Oct 03 21:19:15 2011 +1030
@@ -0,0 +1,1405 @@
+/**
+  ******************************************************************************
+  * @file    stm32100e_eval_ioe.c
+  * @author  MCD Application Team
+  * @version V4.5.0
+  * @date    07-March-2011
+  * @brief   This file includes the IO Expander driver for STMPE811 IO Expander 
+  *          devices.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************  
+  */ 
+
+  /* File Info : ---------------------------------------------------------------
+  
+    Note:
+    -----
+    - This driver uses the DMA method for sending and receiving data on I2C bus
+      which allow higher efficiency and reliability of the communication.
+    
+    SUPPORTED FEATURES:
+      - Touch Screen Features: Single point mode (Polling/Interrupt).     
+      - TempSensor Feature: accuracy not determined (Polling).
+      - IO Read/write : Set/Reset and Read (Polling/Interrupt).
+      
+    UNSUPPORTED FEATURES:
+      - Row ADC Feature is not supported (not implemented on STM32100E-EVAL board)
+      - Joystick: config and Read (Polling/Interrupt)     
+  ----------------------------------------------------------------------------*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32100e_eval_ioe.h"
+
+/** @addtogroup Utilities
+  * @{
+  */
+
+/** @addtogroup STM32_EVAL
+  * @{
+  */ 
+
+/** @addtogroup STM32100E_EVAL
+  * @{
+  */
+    
+/** @defgroup STM32100E_EVAL_IOE 
+  * @brief  This file includes the IO Expander driver for STMPE811 IO Expander 
+  *         devices.
+  * @{
+  */   
+
+/** @defgroup STM32100E_EVAL_IOE_Private_TypesDefinitions
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup STM32100E_EVAL_IOE_Private_Defines
+  * @{
+  */ 
+#define TIMEOUT_MAX    0x1000 /*<! The value of the maximal timeout for I2C waiting loops */
+/**
+  * @}
+  */ 
+
+
+/** @defgroup STM32100E_EVAL_IOE_Private_Macros
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup STM32100E_EVAL_IOE_Private_Variables
+  * @{
+  */ 
+TS_STATE TS_State;              /*<! The global structure holding the TS state */
+
+uint32_t IOE_TimeOut = TIMEOUT_MAX; /*<! Value of Timeout when I2C communication fails */
+/**
+  * @}
+  */ 
+
+
+/** @defgroup STM32100E_EVAL_IOE_Private_FunctionPrototypes
+  * @{
+  */ 
+static uint16_t IOE_TS_Read_X(void);
+static uint16_t IOE_TS_Read_Y(void);
+static uint16_t IOE_TS_Read_Z(void);
+
+static void IOE_GPIO_Config(void);
+static void IOE_I2C_Config(void);
+static void IOE_DMA_Config(IOE_DMADirection_TypeDef Direction, uint8_t* buffer);
+static void IOE_EXTI_Config(void);
+
+#ifndef USE_Delay
+static void delay(__IO uint32_t nCount);
+#endif /* USE_Delay*/
+/**
+  * @}
+  */ 
+
+
+/** @defgroup STM32100E_EVAL_IOE_Private_Functions
+  * @{
+  */ 
+
+
+/**
+  * @brief  Initializes and Configures the IO_Expanders Functionalities 
+  *         (Touch Screen ..) and configures all STM32100E-EVAL necessary
+  *         hardware (GPIOs, APB clocks ..).
+  * @param  None
+  * @retval IOE_OK if all initializations done correctly. Other value if error.
+  */
+uint8_t IOE_Config(void)
+{
+  /* Configure the needed pins */
+  IOE_GPIO_Config();
+  
+  /* Configure I2C peripheral */
+  IOE_I2C_Config();
+  
+  /* Read IO Expander 1 ID  */
+  if(IOE_IsOperational(IOE_1_ADDR))
+  {
+    return IOE1_NOT_OPERATIONAL;
+  } 
+  
+  /* Generate IOExpander Software reset */
+  IOE_Reset(IOE_1_ADDR); 
+  
+  /* ---------------------- IO Expander configuration --------------------- */
+  /* Enable the GPIO, Touch Screen and ADC functionalities */
+  IOE_FnctCmd(IOE_1_ADDR, IOE_TS_FCT | IOE_ADC_FCT | IOE_IO_FCT | IOE_TEMPSENS_FCT  , ENABLE);
+   
+  /* Touch Screen controller configuration */
+  IOE_TS_Config();
+  
+  /* Temperature Sensor configuration */
+  IOE_TempSens_Config();
+ 
+  /* ------------------------------------------------------------------------ */
+  
+  /* Configuration is OK */
+  return IOE_OK; 
+}
+
+/**
+  * @brief  Configures The selected interrupts on the IO Expanders.
+  * @param  IOE_ITSRC_Source: the source of the interrupts. Could be one or a 
+  *         combination of the following parameters:
+  *   @arg  IOE_ITSRC_TSC: Touch Screen interrupts.
+  * @retval IOE_OK: if all initializations are OK. Other value if error.
+  */
+uint8_t IOE_ITConfig(uint32_t IOE_ITSRC_Source)
+{   
+  /* Configure the Interrupt output pin to generate low level (INT_CTRL) */
+  IOE_ITOutConfig(Polarity_Low, Type_Level);    
+  
+  /* Manage the Touch Screen Interrupts */  
+  if (IOE_ITSRC_Source & IOE_ITSRC_TSC)
+  {   
+    /* Enable the Global interrupt */  
+    IOE_GITCmd(IOE_1_ADDR, ENABLE);     
+           
+    /* Enable the Global GPIO Interrupt */
+    IOE_GITConfig(IOE_1_ADDR, (uint8_t)(IOE_GIT_TOUCH | IOE_GIT_FTH | IOE_GIT_FOV), ENABLE);    
+    
+    /* Read the GPIO_IT_STA to clear all pending bits if any */
+    I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_GPIO_INT_STA); 
+  }
+  
+  /* Configure the Interrupt line as EXTI source */
+  IOE_EXTI_Config();    
+  
+  /* If all OK return IOE_OK */
+  return IOE_OK;
+}
+
+/**
+  * @brief  Writes a bit value to an output IO pin.
+  * @param IO_Pin: The output pin to be set or reset. 
+  *                IO_Pin_x: Where x can be from 0 to 7. 
+  * @param BitVal: The value to be set. This parameter can be one of the
+  *        following values: BitSet or BitReset. See IOE_BitVal_TypeDef.
+  * @retval IOE_OK or PARAM_ERROR
+  */
+uint8_t IOE_WriteIOPin(uint8_t IO_Pin, IOE_BitValue_TypeDef BitVal)
+{
+  uint8_t DeviceAddr = 0;
+  
+  /* Get the IO expander Address according to which pin is to be controlled */
+  if (IO_Pin & IO1_OUT_ALL_PINS)
+  {
+    DeviceAddr = IOE_1_ADDR;
+  }
+  else
+  {
+    return PARAM_ERROR;
+  }
+  
+  /* Apply the bit value to the selected pin */
+  if (BitVal == BitReset)
+  {
+    /* Set the register */
+    I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_CLR_PIN, IO_Pin);
+  }
+  else
+  {
+    /* Set the register */
+    I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_SET_PIN, IO_Pin);
+  }
+  
+  return IOE_OK;
+}
+
+
+/**
+  * @brief  Returns the status of the selected input IO pin.
+  * @param IO_Pin: The input pin to be read. 
+  *                IO_Pin_x: Where x can be from 0 to 7.
+  *   @arg  JOY_IO_PINS: Joystick IO pins (use IOE_JoyStickGetState for these pins)  
+  * @retval None
+  */
+uint8_t IOE_ReadIOPin(uint32_t IO_Pin)
+{
+  uint8_t DeviceAddr = 0;
+  uint8_t tmp = 0;  
+  if (IO_Pin & IO1_IN_ALL_PINS)
+  {
+    DeviceAddr = IOE_1_ADDR;
+  }
+   else 
+  {
+    return PARAM_ERROR;
+  }
+  
+  /* Get all the Pins status */
+  tmp = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_GPIO_MP_STA);
+  if ((tmp & (uint8_t)IO_Pin) != 0)
+  {
+    return BitSet;
+  }  
+  else 
+  {
+    return BitReset;
+  }
+}
+
+
+/**
+  * @brief  Returns Status and positions of the Touch screen.
+  * @param  None
+  * @retval Pointer to TS_STATE structure holding Touch Screen information.
+  */
+TS_STATE* IOE_TS_GetState(void)
+{
+  uint32_t xDiff, yDiff , x , y;
+  static uint32_t _x = 0, _y = 0;
+  
+  /* Check if the Touch detect event happenned */
+  TS_State.TouchDetected = (I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_TSC_CTRL) & 0x80);
+  if(TS_State.TouchDetected) 
+  {
+    x = IOE_TS_Read_X();
+    y = IOE_TS_Read_Y();
+    xDiff = x > _x? (x - _x): (_x - x);
+    yDiff = y > _y? (y - _y): (_y - y);       
+    if (xDiff + yDiff > 5)
+    {
+      _x = x;
+      _y = y;       
+    }
+  }  
+  /* Update the X position */
+  TS_State.X = _x;
+    
+  /* Update the Y position */  
+  TS_State.Y = _y;
+  /* Update the Z Pression index */  
+  TS_State.Z = IOE_TS_Read_Z();  
+  
+  /* Clear the interrupt pending bit and enable the FIFO again */
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_FIFO_STA, 0x01);
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_FIFO_STA, 0x00);
+  
+  /* Return pointer to the updated structure */
+  return &TS_State; 
+}
+
+/**
+  * @brief  Returns the temperature row value (in 16 bit format).
+  * @param  None
+  * @retval The temperature row value.
+  */
+uint32_t IOE_TempSens_GetData(void)
+{  
+  static __IO uint32_t tmp = 0;  
+    
+  /* Aquire data enable */
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_TEMP_CTRL, 0x03);
+  
+  /* Enable the TEMPSENS module */
+  tmp = (uint32_t)((I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_TEMP_DATA) & 0x03) << 8); 
+  tmp |= (uint32_t)I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_TEMP_DATA + 1); 
+  
+  tmp = (uint32_t)((33 * tmp * 100) / 751);
+  tmp = (uint32_t)((tmp + 5) / 10);
+  
+  /* return the temprature row value */
+  return tmp;
+}
+
+/**
+  * @brief  Checks the selected Global interrupt source pending bit
+  * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
+  * @param  Global_IT: the Global interrupt source to be checked, could be:
+  *   @arg  Global_IT_GPIO : All IOs interrupt
+  *   @arg  Global_IT_ADC : ADC interrupt
+  *   @arg  Global_IT_TEMP : Temperature Sensor interrupts      
+  *   @arg  Global_IT_FE : Touch Screen Controller FIFO Error interrupt
+  *   @arg  Global_IT_FF : Touch Screen Controller FIFO Full interrupt      
+  *   @arg  Global_IT_FOV : Touch Screen Controller FIFO Overrun interrupt     
+  *   @arg  Global_IT_FTH : Touch Screen Controller FIFO Threshold interrupt   
+  *   @arg  Global_IT_TOUCH : Touch Screen Controller Touch Detected interrupt      
+  * @retval Status of the checked flag. Could be SET or RESET.
+  */
+FlagStatus IOE_GetGITStatus(uint8_t DeviceAddr, uint8_t Global_IT)
+{
+  __IO uint8_t tmp = 0;
+ 
+  /* get the Interrupt status */
+  tmp = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_INT_STA);
+  
+  if ((tmp & (uint8_t)Global_IT) != 0)
+  {
+    return SET;
+  }
+  else
+  {
+    return RESET;
+  }
+}
+
+/**
+  * @brief  Clears the selected Global interrupt pending bit(s)
+  * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
+  * @param  Global_IT: the Global interrupt to be cleared, could be any combination
+  *         of the following values:   
+  *   @arg  Global_IT_GPIO : All IOs interrupt
+  *   @arg  Global_IT_ADC : ADC interrupt
+  *   @arg  Global_IT_TEMP : Temperature Sensor interrupts      
+  *   @arg  Global_IT_FE : Touch Screen Controller FIFO Error interrupt
+  *   @arg  Global_IT_FF : Touch Screen Controller FIFO Full interrupt      
+  *   @arg  Global_IT_FOV : Touch Screen Controller FIFO Overrun interrupt     
+  *   @arg  Global_IT_FTH : Touch Screen Controller FIFO Threshold interrupt   
+  *   @arg  Global_IT_TOUCH : Touch Screen Controller Touch Detected interrupt 
+  * @retval IOE_OK: if all initializations are OK. Other value if error.
+  */
+uint8_t IOE_ClearGITPending(uint8_t DeviceAddr, uint8_t Global_IT)
+{
+  /* Write 1 to the bits that have to be cleared */
+  I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_INT_STA, Global_IT); 
+
+  /* If all OK return IOE_OK */
+  return IOE_OK;
+}
+
+/**
+  * @brief  Checks the status of the selected IO interrupt pending bit
+  * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
+  * @param  IO_IT: the IO interrupt to be checked could be IO_ITx Where x can be 
+  *         from 0 to 7.             
+  * @retval Status of the checked flag. Could be SET or RESET.
+  */
+FlagStatus IOE_GetIOITStatus(uint8_t DeviceAddr, uint8_t IO_IT)
+{
+  uint8_t tmp = 0;
+ 
+  /* get the Interrupt status */
+  tmp = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_GPIO_INT_STA);
+  
+  if ((tmp & (uint8_t)IO_IT) != 0)
+  {
+    return SET;
+  }
+  else
+  {
+    return RESET;
+  }
+}
+
+/**
+  * @brief  Clears the selected IO interrupt pending bit(s).
+  * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
+  * @param  IO_IT: the IO interrupt to be checked could be IO_ITx Where x can be 
+  *         from 0 to 7.              
+  * @retval IOE_OK: if all initializations are OK. Other value if error.
+  */
+uint8_t IOE_ClearIOITPending(uint8_t DeviceAddr, uint8_t IO_IT)
+{
+  /* Write 1 to the bits that have to be cleared */
+  I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_INT_STA, IO_IT);  
+  
+  /* Clear the Edge detection pending bit*/
+  I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_ED, IO_IT);
+
+  /* Clear the Rising edge pending bit */
+  I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_RE, IO_IT);
+
+  /* Clear the Falling edge pending bit */
+  I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_FE, IO_IT); 
+
+  return IOE_OK;
+  
+}
+/**
+  * @brief  Checks if the selected device is correctly configured and 
+  *         communicates correctly ont the I2C bus.
+  * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
+  * @retval IOE_OK if IOE is operational. Other value if failure.
+  */
+uint8_t IOE_IsOperational(uint8_t DeviceAddr)
+{
+  /* Return Error if the ID is not correct */
+  if( IOE_ReadID(DeviceAddr) != (uint16_t)STMPE811_ID )
+  {
+    /* Check if a Timeout occured */
+    if (IOE_TimeOut == 0)
+    {
+      return(IOE_TimeoutUserCallback());
+    }
+    else
+    {
+      return IOE_FAILURE; /* ID is not Correct */
+    }
+  } 
+  else 
+  {
+    return IOE_OK; /* ID is correct */
+  }
+}
+
+/**
+  * @brief  Resets the IO Expander by Software (SYS_CTRL1, RESET bit).
+  * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
+  * @retval IOE_OK: if all initializations are OK. Other value if error.
+  */
+uint8_t IOE_Reset(uint8_t DeviceAddr)
+{
+  /* Power Down the IO_Expander */
+  I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_SYS_CTRL1, 0x02);
+
+  /* wait for a delay to insure registers erasing */
+  _delay_(2); 
+  
+  /* Power On the Codec after the power off => all registers are reinitialized*/
+  I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_SYS_CTRL1, 0x00);
+  
+  /* If all OK return IOE_OK */
+  return IOE_OK;    
+}
+
+/**
+  * @brief  Reads the selected device's ID.
+  * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
+  * @retval The Device ID (two bytes).
+  */
+uint16_t IOE_ReadID(uint8_t DeviceAddr)
+{
+  uint16_t tmp = 0;
+
+  /* Read device ID  */
+  tmp = I2C_ReadDeviceRegister(DeviceAddr, 0);
+  tmp = (uint32_t)(tmp << 8);
+  tmp |= (uint32_t)I2C_ReadDeviceRegister(DeviceAddr, 1);
+  
+  /* Return the ID */
+  return (uint16_t)tmp;
+}
+
+/**
+  * @brief  Configures the selcted IO Expander functionalities.
+  * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
+  * @param  Fct: the functions to be configured. could be any 
+  *         combination of the following values:
+  *   @arg  IOE_IO_FCT : IO function
+  *   @arg  IOE_TS_FCT : Touch Screen function
+  *   @arg  IOE_ADC_FCT : ADC function
+  *   @arg  IOE_TEMPSENS_FCT : Tempreature Sensor function
+  * @retval IOE_OK: if all initializations are OK. Other value if error.
+  */
+uint8_t IOE_FnctCmd(uint8_t DeviceAddr, uint8_t Fct, FunctionalState NewState)
+{
+  uint8_t tmp = 0;
+  
+  /* Get the register value */
+  tmp = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_SYS_CTRL2);
+  
+  if (NewState != DISABLE)
+  {
+    /* Set the Functionalities to be Enabled */    
+    tmp &= ~(uint8_t)Fct;
+  }
+  else
+  {
+    /* Set the Functionalities to be Disabled */    
+    tmp |= (uint8_t)Fct;  
+  }
+  
+  /* Set the register value */
+  I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_SYS_CTRL2, tmp);
+  
+  /* If all OK return IOE_OK */
+  return IOE_OK;    
+}
+
+/**
+  * @brief  Configures the selected pin direction (to be an input or an output)
+  * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
+  * @param  IO_Pin: IO_Pin_x: Where x can be from 0 to 7.   
+  * @param  Direction: could be Direction_IN or Direction_OUT.      
+  * @retval IOE_OK: if all initializations are OK. Other value if error.
+  */
+uint8_t IOE_IOPinConfig(uint8_t DeviceAddr, uint8_t IO_Pin, uint8_t Direction)
+{
+  uint8_t tmp = 0;   
+  
+  /* Get all the Pins direction */
+  tmp = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_GPIO_DIR);
+  
+  if (Direction != Direction_IN)
+  {
+    tmp |= (uint8_t)IO_Pin;
+  }  
+  else 
+  {
+    tmp &= ~(uint8_t)IO_Pin;
+  }
+  
+  /* Write the register new value */
+  I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_DIR, tmp);
+  
+  /* If all OK return IOE_OK */
+  return IOE_OK;      
+}
+
+/**
+  * @brief  Enables or disables the Global interrupt.
+  * @param  DeviceAddr: The address of the IOExpander, could be :I OE_1_ADDR.
+  * @param  NewState: could be ENABLE or DISABLE.        
+  * @retval IOE_OK: if all initializations are OK. Other value if error.
+  */
+uint8_t IOE_GITCmd(uint8_t DeviceAddr, FunctionalState NewState)
+{
+  uint8_t tmp = 0;
+  
+  /* Read the Interrupt Control register  */
+  I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_INT_CTRL);
+  
+  if (NewState != DISABLE)
+  {
+    /* Set the global interrupts to be Enabled */    
+    tmp |= (uint8_t)IOE_GIT_EN;
+  }
+  else
+  {
+    /* Set the global interrupts to be Disabled */    
+    tmp &= ~(uint8_t)IOE_GIT_EN;
+  }  
+  
+  /* Write Back the Interrupt Control register */
+  I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_INT_CTRL, tmp);
+
+  /* If all OK return IOE_OK */
+  return IOE_OK;     
+}
+
+/**
+  * @brief  Configures the selected source to generate or not a global interrupt
+  * @param DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR
+  * @param Global_IT: the interrupt source to be configured, could be:
+  *   @arg  Global_IT_GPIO : All IOs interrupt
+  *   @arg  Global_IT_ADC : ADC interrupt
+  *   @arg  Global_IT_TEMP : Temperature Sensor interrupts  
+  *   @arg  Global_IT_FE : Touch Screen Controller FIFO Error interrupt
+  *   @arg  Global_IT_FF : Touch Screen Controller FIFO Full interrupt      
+  *   @arg  Global_IT_FOV : Touch Screen Controller FIFO Overrun interrupt     
+  *   @arg  Global_IT_FTH : Touch Screen Controller FIFO Threshold interrupt   
+  *   @arg  Global_IT_TOUCH : Touch Screen Controller Touch Detected interrupt 
+  * @retval IOE_OK: if all initializations are OK. Other value if error.
+  */
+uint8_t IOE_GITConfig(uint8_t DeviceAddr, uint8_t Global_IT, FunctionalState NewState)
+{
+  uint8_t tmp = 0;
+  
+  /* Get the current value of the INT_EN register */
+  tmp = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_INT_EN);
+  
+  if (NewState != DISABLE)
+  {
+    /* Set the interrupts to be Enabled */    
+    tmp |= (uint8_t)Global_IT;  
+  }
+  else
+  {
+    /* Set the interrupts to be Disabled */    
+    tmp &= ~(uint8_t)Global_IT;
+  }
+  /* Set the register */
+  I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_INT_EN, tmp);
+  
+  /* If all OK return IOE_OK */
+  return IOE_OK;  
+}
+
+/**
+  * @brief  Configures the selected pins to generate an interrupt or not.
+  * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
+  * @param  IO_IT: The IO interrupt to be configured. This parameter could be any
+  *         combination of the following values:
+  *   @arg  IO_IT_x: where x can be from 0 to 7.
+  * @param  NewState: could be ENABLE or DISABLE.  
+  * @retval IOE_OK: if all initializations are OK. Other value if error.
+  */
+uint8_t IOE_IOITConfig(uint8_t DeviceAddr, uint8_t IO_IT, FunctionalState NewState)
+{
+  uint8_t tmp = 0;
+ 
+  tmp = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_GPIO_INT_EN);
+  
+  if (NewState != DISABLE)
+  {
+    /* Set the interrupts to be Enabled */    
+    tmp |= (uint8_t)IO_IT;
+  }
+  else
+  {
+    /* Set the interrupts to be Disabled */    
+    tmp &= ~(uint8_t)IO_IT;
+  }
+  
+  /* Set the register */
+  I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_INT_EN, tmp);
+  
+  /* If all OK return IOE_OK */
+  return IOE_OK;   
+}
+
+/**
+  * @brief  Configures the touch Screen Controller (Single point detection)
+  * @param  None
+  * @retval IOE_OK if all initializations are OK. Other value if error.
+  */
+uint8_t IOE_TS_Config(void)
+{
+  uint8_t tmp = 0;  
+  
+  /* Enable TSC Fct: already done in IOE_Config */
+  tmp = I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_SYS_CTRL2);
+  tmp &= ~(uint32_t)(IOE_TS_FCT | IOE_ADC_FCT);
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_SYS_CTRL2, tmp); 
+  
+  /* Enable the TSC gloabl interrupts */
+  tmp = I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_INT_EN);
+  tmp |= (uint32_t)(IOE_GIT_TOUCH | IOE_GIT_FTH | IOE_GIT_FOV);
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_INT_EN, tmp); 
+  
+  /* Select Sample Time, bit number and ADC Reference */
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_ADC_CTRL1, 0x49);
+  
+  /* Wait for ~20 ms */
+  _delay_(2);  
+  
+  /* Select the ADC clock speed: 3.25 MHz */
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_ADC_CTRL2, 0x01);
+  
+  /* Select TSC pins in non default mode */  
+  tmp = I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_GPIO_AF);
+  tmp &= ~(uint8_t)TOUCH_IO_ALL;
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_GPIO_AF, tmp); 
+  
+  /* Select 2 nF filter capacitor */
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_TSC_CFG, 0x9A);   
+  
+  /* Select single point reading  */
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_FIFO_TH, 0x01);
+  
+  /* Write 0x01 to clear the FIFO memory content. */
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_FIFO_STA, 0x01);
+  
+  /* Write 0x00 to put the FIFO back into operation mode  */
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_FIFO_STA, 0x00);
+  
+  /* set the data format for Z value: 7 fractional part and 1 whole part */
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_TSC_FRACT_XYZ, 0x01);
+  
+  /* set the driving capability of the device for TSC pins: 50mA */
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_TSC_I_DRIVE, 0x01);
+  
+  /* Use no tracking index, touchscreen controller operation mode (XYZ) and 
+     enable the TSC */
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_TSC_CTRL, 0x01);
+  
+  /*  Clear all the status pending bits */
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_INT_STA, 0xFF); 
+  
+  /* Initialize the TS structure to their default values */ 
+  TS_State.TouchDetected = TS_State.X = TS_State.Y = TS_State.Z = 0;
+  
+  /* All configuration done */
+  return IOE_OK;  
+}
+
+/**
+  * @brief  Configures and enables the Temperature sensor module.
+  * @param  None
+  * @retval IOE_OK if all initializations are OK. Other value if error.
+  */
+uint8_t IOE_TempSens_Config(void)
+{
+  __IO uint8_t tmp = 0;
+  
+  /* Enable Temperature Sensor Fct: already done in IOE_Config */
+  tmp = I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_SYS_CTRL2);
+  tmp &= ~(uint32_t)(IOE_TEMPSENS_FCT | IOE_ADC_FCT);
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_SYS_CTRL2, tmp);  
+  
+  /* Enable the TEMPSENS module */
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_TEMP_CTRL, 0x01);
+  
+  /* Aquire data enable */
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_TEMP_CTRL, 0x3);
+  
+  /* All configuration done */
+  return IOE_OK;
+}
+
+/**
+  * @brief  Configures the selected pin to be in Alternate function or not
+  * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
+  * @param  IO_Pin: IO_Pin_x, Where x can be from 0 to 7.   
+  * @param  NewState: State of the AF for the selected pin, could be 
+  *         ENABLE or DISABLE.       
+  * @retval IOE_OK: if all initializations are OK. Other value if error.
+  */
+uint8_t IOE_IOAFConfig(uint8_t DeviceAddr, uint8_t IO_Pin, FunctionalState NewState)
+{
+  uint8_t tmp = 0;
+  
+  /* Get the current state of the GPIO_AF register */
+  tmp = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_GPIO_AF);
+  
+  if (NewState != DISABLE)
+  {
+    /* Enable the selected pins alternate function */
+    tmp |= (uint8_t)IO_Pin;
+  }
+  else
+  {
+    /* Disable the selected pins alternate function */   
+    tmp &= ~(uint8_t)IO_Pin;   
+  }
+  
+  /* Write back the new valu in GPIO_AF register */  
+  I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_AF, tmp);  
+
+  /* If all OK return IOE_OK */
+  return IOE_OK;
+}
+
+/**
+  * @brief  Configures the Edge for which a transition is detectable for the
+  *         the selected pin.
+  * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
+  * @param  IO_Pin: IO_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
+  *         a combination of follwing values: EDGE_FALLING and EDGE_RISING .
+  * @retval IOE_OK: if all initializations are OK. Other value if error.
+  */
+uint8_t IOE_IOEdgeConfig(uint8_t DeviceAddr, uint8_t IO_Pin, uint8_t Edge)
+{
+  uint8_t tmp1 = 0, tmp2 = 0;   
+  
+  /* Get the registers values */
+  tmp1 = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_GPIO_FE);
+  tmp2 = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_GPIO_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 & EDGE_FALLING)
+  {
+    tmp1 |= (uint8_t)IO_Pin;
+  }
+
+  /* Enable the Rising edge if selected */
+  if (Edge & EDGE_RISING)
+  {
+    tmp2 |= (uint8_t)IO_Pin;
+  }
+
+  /* Write back the registers values */
+  I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_FE, tmp1);
+  I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_RE, tmp2);
+  
+  /* if OK return 0 */
+  return IOE_OK;
+}
+
+/**
+  * @brief  Configures the Interrupt line active state and format (level/edge)
+  * @param  Polarity: could be
+  *   @arg  Polarity_Low: Interrupt line is active Low/Falling edge      
+  *   @arg  Polarity_High: Interrupt line is active High/Rising edge      
+  * @param  Type: Interrupt line activity type, could be one of the following values
+  *   @arg  Type_Level: Interrupt line is active in level model         
+  *   @arg  Type_Edge: Interrupt line is active in edge model           
+  * @retval IOE_OK: if all initializations are OK. Other value if error.
+  */
+uint8_t IOE_ITOutConfig(uint8_t Polarity, uint8_t Type)
+{
+  uint8_t tmp = 0;
+  
+  /*  Get the register IOE_REG_INT_CTRL value */ 
+  tmp = I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_INT_CTRL);
+  
+  /* Mask the polarity and type bits */
+  tmp &= ~(uint8_t)0x06;
+    
+  /* Modify the Interrupt Output line configuration */
+  tmp |= (uint8_t)(Polarity | Type);
+  
+  /* Set the register */
+  I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_INT_CTRL, tmp);
+    
+  /* If all OK return IOE_OK */
+  return IOE_OK;  
+}
+
+/**
+  * @brief  Writes a value in a register of the device through I2C.
+  * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR. 
+  * @param  RegisterAddr: The target register adress
+  * @param  RegisterValue: The target register value to be written 
+  * @retval IOE_OK: if all operations are OK. Other value if error.
+  */
+uint8_t I2C_WriteDeviceRegister(uint8_t DeviceAddr, uint8_t RegisterAddr, uint8_t RegisterValue)
+{
+  uint32_t read_verif = 0;  
+  uint8_t IOE_BufferTX = 0;
+  
+  /* Get Value to be written */
+  IOE_BufferTX = RegisterValue;
+  
+  /* Configure DMA Peripheral */
+  IOE_DMA_Config(IOE_DMA_TX, (uint8_t*)(&IOE_BufferTX));
+  
+  /* Enable the I2C peripheral */
+  I2C_GenerateSTART(IOE_I2C, ENABLE);
+  
+  /* Test on SB Flag */
+  IOE_TimeOut = TIMEOUT_MAX;
+  while (I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB) == RESET) 
+  {
+    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
+  }
+  
+  /* Transmit the slave address and enable writing operation */
+  I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Transmitter);
+  
+  /* Test on ADDR Flag */
+  IOE_TimeOut = TIMEOUT_MAX;
+  while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
+  {
+    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
+  }
+   
+  /* Transmit the first address for r/w operations */
+  I2C_SendData(IOE_I2C, RegisterAddr);
+  
+  /* Test on TXE FLag (data dent) */
+  IOE_TimeOut = TIMEOUT_MAX;
+  while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF)))  
+  {
+    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
+  }
+  
+  /* Enable I2C DMA request */
+  I2C_DMACmd(IOE_I2C,ENABLE);
+  
+  /* Enable DMA TX Channel */
+  DMA_Cmd(IOE_DMA_TX_CHANNEL, ENABLE);
+  
+  /* Wait until DMA Transfer Complete */
+  IOE_TimeOut = TIMEOUT_MAX;
+  while (!DMA_GetFlagStatus(IOE_DMA_TX_TCFLAG))
+  {
+    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
+  }  
+  
+  /* Wait until BTF Flag is set before generating STOP */
+  IOE_TimeOut = 2 * TIMEOUT_MAX;
+  while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF)))  
+  {
+  }
+  
+  /* Send STOP Condition */
+  I2C_GenerateSTOP(IOE_I2C, ENABLE);
+  
+  /* Disable DMA TX Channel */
+  DMA_Cmd(IOE_DMA_TX_CHANNEL, DISABLE);
+  
+  /* Disable I2C DMA request */  
+  I2C_DMACmd(IOE_I2C,DISABLE);
+  
+  /* Clear DMA TX Transfer Complete Flag */
+  DMA_ClearFlag(IOE_DMA_TX_TCFLAG);
+  
+#ifdef VERIFY_WRITTENDATA
+  /* Verify (if needed) that the loaded data is correct  */
+  
+  /* Read the just written register*/
+  read_verif = I2C_ReadDeviceRegister(DeviceAddr, RegisterAddr);
+  /* Load the register and verify its value  */
+  if (read_verif != RegisterValue)
+  {
+    /* Control data wrongly tranfered */
+    read_verif = IOE_FAILURE;
+  }
+  else
+  {
+    /* Control data correctly transfered */
+    read_verif = 0;
+  }
+#endif
+  
+  /* Return the verifying value: 0 (Passed) or 1 (Failed) */
+  return read_verif;
+}
+
+/**
+  * @brief  Reads a register of the device through I2C.
+  * @param  DeviceAddr: The address of the device, could be : IOE_1_ADDR.
+  * @param  RegisterAddr: The target register adress (between 00x and 0x24)
+  * @retval The value of the read register (0xAA if Timout occured)   
+  */
+uint8_t I2C_ReadDeviceRegister(uint8_t DeviceAddr, uint8_t RegisterAddr)
+{
+  uint8_t IOE_BufferRX[2] = {0x00, 0x00};  
+    
+  /* Configure DMA Peripheral */
+  IOE_DMA_Config(IOE_DMA_RX, (uint8_t*)IOE_BufferRX);
+  
+  /* Enable DMA NACK automatic generation */
+  I2C_DMALastTransferCmd(IOE_I2C, ENABLE);
+  
+  /* Enable the I2C peripheral */
+  I2C_GenerateSTART(IOE_I2C, ENABLE);
+  
+  /* Test on SB Flag */
+  IOE_TimeOut = TIMEOUT_MAX;
+  while (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB)) 
+  {
+    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
+  }
+  
+  /* Send device address for write */
+  I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Transmitter);
+  
+  /* Test on ADDR Flag */
+  IOE_TimeOut = TIMEOUT_MAX;
+  while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) 
+  {
+    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
+  }
+  
+  /* Send the device's internal address to write to */
+  I2C_SendData(IOE_I2C, RegisterAddr);  
+  
+  /* Test on TXE FLag (data dent) */
+  IOE_TimeOut = TIMEOUT_MAX;
+  while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF)))  
+  {
+    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
+  }
+  
+  /* Send START condition a second time */  
+  I2C_GenerateSTART(IOE_I2C, ENABLE);
+  
+  /* Test on SB Flag */
+  IOE_TimeOut = TIMEOUT_MAX;
+  while (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB)) 
+  {
+    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
+  }
+  
+  /* Send IOExpander address for read */
+  I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Receiver);
+  
+  /* Test on ADDR Flag */
+  IOE_TimeOut = TIMEOUT_MAX;
+  while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))   
+  {
+    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
+  }
+    
+  /* Enable I2C DMA request */
+  I2C_DMACmd(IOE_I2C,ENABLE);
+  
+  /* Enable DMA RX Channel */
+  DMA_Cmd(IOE_DMA_RX_CHANNEL, ENABLE);
+  
+  /* Wait until DMA Transfer Complete */
+  IOE_TimeOut = 2 * TIMEOUT_MAX;
+  while (!DMA_GetFlagStatus(IOE_DMA_RX_TCFLAG))
+  {
+    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
+  }        
+  
+  /* Send STOP Condition */
+  I2C_GenerateSTOP(IOE_I2C, ENABLE);
+  
+  /* Disable DMA RX Channel */
+  DMA_Cmd(IOE_DMA_RX_CHANNEL, DISABLE);
+  
+  /* Disable I2C DMA request */  
+  I2C_DMACmd(IOE_I2C,DISABLE);
+  
+  /* Clear DMA RX Transfer Complete Flag */
+  DMA_ClearFlag(IOE_DMA_RX_TCFLAG);
+  
+  /* return a pointer to the IOE_Buffer */
+  return (uint8_t)IOE_BufferRX[0];  
+}
+
+
+/**
+  * @brief  Reads a buffer of 2 bytes from the device registers.
+  * @param  DeviceAddr: The address of the device, could be : IOE_1_ADDR.
+  * @param  RegisterAddr: The target register adress (between 00x and 0x24)
+  * @retval A pointer to the buffer containing the two returned bytes (in halfword).  
+  */
+uint16_t I2C_ReadDataBuffer(uint8_t DeviceAddr, uint32_t RegisterAddr)
+{  
+  uint8_t tmp= 0;
+  uint8_t IOE_BufferRX[2] = {0x00, 0x00};  
+   
+  /* Configure DMA Peripheral */
+  IOE_DMA_Config(IOE_DMA_RX, (uint8_t*)IOE_BufferRX);
+  
+  /* Enable DMA NACK automatic generation */
+  I2C_DMALastTransferCmd(IOE_I2C, ENABLE);
+  
+  /* Enable the I2C peripheral */
+  I2C_GenerateSTART(IOE_I2C, ENABLE);
+  
+  /* Test on SB Flag */
+  IOE_TimeOut = TIMEOUT_MAX;
+  while (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB)) 
+  {
+    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
+  }
+  
+  /* Send device address for write */
+  I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Transmitter);
+  
+  /* Test on ADDR Flag */
+  IOE_TimeOut = TIMEOUT_MAX;
+  while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
+  {
+    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
+  }
+  
+  /* Send the device's internal address to write to */
+  I2C_SendData(IOE_I2C, RegisterAddr);  
+  
+  /* Test on TXE FLag (data dent) */
+  IOE_TimeOut = TIMEOUT_MAX;
+  while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF)))  
+  {
+    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
+  }
+  
+  /* Send START condition a second time */  
+  I2C_GenerateSTART(IOE_I2C, ENABLE);
+  
+  /* Test on SB Flag */
+  IOE_TimeOut = TIMEOUT_MAX;
+  while (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB)) 
+  {
+    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
+  }
+  
+  /* Send IOExpander address for read */
+  I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Receiver);
+  
+  /* Test on ADDR Flag */
+  IOE_TimeOut = TIMEOUT_MAX;
+  while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))   
+  {
+    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
+  }
+  
+  /* Enable I2C DMA request */
+  I2C_DMACmd(IOE_I2C,ENABLE);
+  
+  /* Enable DMA RX Channel */
+  DMA_Cmd(IOE_DMA_RX_CHANNEL, ENABLE);
+  
+  /* Wait until DMA Transfer Complete */
+  IOE_TimeOut = 2 * TIMEOUT_MAX;
+  while (!DMA_GetFlagStatus(IOE_DMA_RX_TCFLAG))
+  {
+    if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
+  }        
+  
+  /* Send STOP Condition */
+  I2C_GenerateSTOP(IOE_I2C, ENABLE);
+  
+  /* Disable DMA RX Channel */
+  DMA_Cmd(IOE_DMA_RX_CHANNEL, DISABLE);
+  
+  /* Disable I2C DMA request */  
+  I2C_DMACmd(IOE_I2C,DISABLE);
+  
+  /* Clear DMA RX Transfer Complete Flag */
+  DMA_ClearFlag(IOE_DMA_RX_TCFLAG);
+  
+  /* Reorganize received data */  
+  tmp = IOE_BufferRX[0];
+  IOE_BufferRX[0] = IOE_BufferRX[1];
+  IOE_BufferRX[1] = tmp;
+  
+  /* return a pointer to the IOE_Buffer */
+  return *(uint16_t *)IOE_BufferRX;  
+}
+
+/**
+  * @brief  Return Touch Screen X position value
+  * @param  None
+  * @retval X position.
+  */
+static uint16_t IOE_TS_Read_X(void)
+{
+  int32_t x, xr;
+ 
+  x = I2C_ReadDataBuffer(IOE_1_ADDR, IOE_REG_TSC_DATA_Y);
+  
+  /* first correction */
+  xr =  (x * 320) >> 12;
+  /* second correction */
+  xr = ((xr * 32)/29) - 17;
+  
+  if(xr <= 0)
+    xr = 0;
+  
+  return (uint16_t)(xr); 
+}
+
+/**
+  * @brief  Return Touch Screen Y position value
+  * @param  None
+  * @retval Y position.
+  */
+static uint16_t IOE_TS_Read_Y(void)
+{
+  int32_t y, yr;
+  y= I2C_ReadDataBuffer(IOE_1_ADDR, IOE_REG_TSC_DATA_X);
+  
+  yr= (y * 240) >> 12;
+  yr = ((yr * 240) / 217) - 12;
+  
+  if(yr <= 0)
+    yr = 0;
+  
+  return (uint16_t)(yr); 
+}
+
+/**
+  * @brief  Return Touch Screen Z position value
+  * @param  None
+  * @retval Z position.
+  */
+static uint16_t IOE_TS_Read_Z(void)
+{
+  uint32_t z;
+  z = I2C_ReadDataBuffer(IOE_1_ADDR, IOE_REG_TSC_DATA_Z);
+  
+  
+  if(z <= 0)
+    z = 0;
+  
+  return (uint16_t)(z); 
+}
+
+/**
+  * @brief  Initializes the GPIO pins used by the IO expander.
+  * @param  None
+  * @retval None
+  */
+static void IOE_GPIO_Config(void)
+{
+  GPIO_InitTypeDef GPIO_InitStructure;
+  
+  /* Enable IOE_I2C and IOE_I2C_PORT & Alternate Function clocks */
+  RCC_APB1PeriphClockCmd(IOE_I2C_CLK, ENABLE);
+  RCC_APB2PeriphClockCmd(IOE_I2C_SCL_GPIO_CLK | IOE_I2C_SDA_GPIO_CLK | IOE_IT_GPIO_CLK
+                         | RCC_APB2Periph_AFIO, ENABLE);
+  
+  /* Reset IOE_I2C IP */
+  RCC_APB1PeriphResetCmd(IOE_I2C_CLK, ENABLE);
+  
+  /* Release reset signal of IOE_I2C IP */
+  RCC_APB1PeriphResetCmd(IOE_I2C_CLK, DISABLE);
+  
+  /* IOE_I2C SCL and SDA pins configuration */
+  GPIO_InitStructure.GPIO_Pin = IOE_I2C_SCL_PIN;
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
+  GPIO_Init(IOE_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
+
+  /* IOE_I2C SCL and SDA pins configuration */
+  GPIO_InitStructure.GPIO_Pin = IOE_I2C_SDA_PIN;
+  GPIO_Init(IOE_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);  
+  
+  /* Set EXTI pin as Input PullUp - IO_Expander_INT */
+  GPIO_InitStructure.GPIO_Pin = IOE_IT_PIN;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+  GPIO_Init(IOE_IT_GPIO_PORT, &GPIO_InitStructure);
+  
+  /* Connect IO Expander IT line to EXTI line */
+  GPIO_EXTILineConfig(IOE_IT_EXTI_PORT_SOURCE, IOE_IT_EXTI_PIN_SOURCE);
+}
+
+
+/**
+  * @brief  Configure the I2C Peripheral used to communicate with IO_Expanders.
+  * @param  None
+  * @retval None
+  */
+static void IOE_I2C_Config(void)
+{
+  I2C_InitTypeDef I2C_InitStructure;
+  
+  /* IOE_I2C configuration */
+  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
+  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
+  I2C_InitStructure.I2C_OwnAddress1 = 0x00;
+  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
+  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
+  I2C_InitStructure.I2C_ClockSpeed = IOE_I2C_SPEED;
+  
+  I2C_Init(IOE_I2C, &I2C_InitStructure);
+}
+
+
+/**
+  * @brief  Configure the DMA Peripheral used to handle communication via I2C.
+  * @param  None
+  * @retval None
+  */
+
+static void IOE_DMA_Config(IOE_DMADirection_TypeDef Direction, uint8_t* buffer)
+{
+  DMA_InitTypeDef DMA_InitStructure;
+  
+  RCC_AHBPeriphClockCmd(IOE_DMA_CLK, ENABLE);
+  
+  /* Initialize the DMA_PeripheralBaseAddr member */
+  DMA_InitStructure.DMA_PeripheralBaseAddr = IOE_I2C_DR;
+  /* Initialize the DMA_MemoryBaseAddr member */
+  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)buffer;
+   /* Initialize the DMA_PeripheralInc member */
+  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+  /* Initialize the DMA_MemoryInc member */
+  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
+  /* Initialize the DMA_PeripheralDataSize member */
+  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
+  /* Initialize the DMA_MemoryDataSize member */
+  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
+  /* Initialize the DMA_Mode member */
+  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
+  /* Initialize the DMA_Priority member */
+  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
+  /* Initialize the DMA_M2M member */
+  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
+  
+  /* If using DMA for Reception */
+  if (Direction == IOE_DMA_RX)
+  {
+    /* Initialize the DMA_DIR member */
+    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
+    
+    /* Initialize the DMA_BufferSize member */
+    DMA_InitStructure.DMA_BufferSize = 2;
+    
+    DMA_DeInit(IOE_DMA_RX_CHANNEL);
+    
+    DMA_Init(IOE_DMA_RX_CHANNEL, &DMA_InitStructure);
+  }
+   /* If using DMA for Transmission */
+  else if (Direction == IOE_DMA_TX)
+  { 
+    /* Initialize the DMA_DIR member */
+    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
+    
+    /* Initialize the DMA_BufferSize member */
+    DMA_InitStructure.DMA_BufferSize = 1;
+    
+    DMA_DeInit(IOE_DMA_TX_CHANNEL);
+    
+    DMA_Init(IOE_DMA_TX_CHANNEL, &DMA_InitStructure);
+  }
+}
+
+/**
+  * @brief  Configures the IO expander Interrupt line and GPIO in EXTI mode.
+  * @param  None        
+  * @retval None
+  */
+static void IOE_EXTI_Config(void)
+{
+  GPIO_InitTypeDef GPIO_InitStructure;
+  NVIC_InitTypeDef NVIC_InitStructure;
+  EXTI_InitTypeDef EXTI_InitStructure;
+ 
+  /* Enable Button GPIO clock */
+  RCC_APB2PeriphClockCmd(IOE_IT_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE);
+  
+  /* Configure Button pin as input floating */
+  GPIO_InitStructure.GPIO_Pin = IOE_IT_PIN;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
+  GPIO_Init(IOE_IT_GPIO_PORT, &GPIO_InitStructure);  
+  
+  /* Connect Button EXTI Line to Button GPIO Pin */
+  GPIO_EXTILineConfig(IOE_IT_EXTI_PORT_SOURCE, IOE_IT_EXTI_PIN_SOURCE);  
+  
+  /* Configure Button EXTI line */
+  EXTI_InitStructure.EXTI_Line = IOE_IT_EXTI_LINE;
+  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;  
+  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+  EXTI_Init(&EXTI_InitStructure);
+  
+  /* Enable and set Button EXTI Interrupt to the lowest priority */
+  NVIC_InitStructure.NVIC_IRQChannel = IOE_IT_EXTI_IRQn;
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+  NVIC_Init(&NVIC_InitStructure);
+}
+
+#ifndef USE_Delay
+/**
+  * @brief  Inserts a delay time.
+  * @param  nCount: specifies the delay time length.
+  * @retval None
+  */
+static void delay(__IO uint32_t nCount)
+{
+  __IO uint32_t index = 0; 
+  for(index = (100000 * nCount); index != 0; index--)
+  {
+  }
+}
+#endif /* USE_Delay*/
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */  
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+   
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/