stm32100e_eval_ioe.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32100e_eval_ioe.c
00004   * @author  MCD Application Team
00005   * @version V4.3.0
00006   * @date    10/15/2010
00007   * @brief   This file includes the IO Expander driver for STMPE811 IO Expander 
00008   *          devices.
00009   ******************************************************************************
00010   * @copy
00011   *
00012   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
00013   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
00014   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
00015   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
00016   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
00017   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
00018   *
00019   * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
00020   */ 
00021 
00022   /* File Info : ---------------------------------------------------------------
00023   
00024     Note:
00025     -----
00026     - This driver uses the DMA method for sending and receiving data on I2C bus
00027       which allow higher efficiency and reliability of the communication.
00028     
00029     SUPPORTED FEATURES:
00030       - Touch Screen Features: Single point mode (Polling/Interrupt).     
00031       - TempSensor Feature: accuracy not determined (Polling).
00032       - IO Read/write : Set/Reset and Read (Polling/Interrupt).
00033       
00034     UNSUPPORTED FEATURES:
00035       - Row ADC Feature is not supported (not implemented on STM32100E-EVAL board)
00036       - Joystick: config and Read (Polling/Interrupt)     
00037   ----------------------------------------------------------------------------*/
00038 
00039 /* Includes ------------------------------------------------------------------*/
00040 #include "stm32100e_eval_ioe.h"
00041 
00042 /** @addtogroup Utilities
00043   * @{
00044   */
00045 
00046 /** @addtogroup STM32_EVAL
00047   * @{
00048   */ 
00049 
00050 /** @addtogroup STM32100E_EVAL
00051   * @{
00052   */
00053     
00054 /** @defgroup STM32100E_EVAL_IOE 
00055   * @brief  This file includes the IO Expander driver for STMPE811 IO Expander 
00056   *         devices.
00057   * @{
00058   */   
00059 
00060 /** @defgroup STM32100E_EVAL_IOE_Private_TypesDefinitions
00061   * @{
00062   */ 
00063 /**
00064   * @}
00065   */ 
00066 
00067 
00068 /** @defgroup STM32100E_EVAL_IOE_Private_Defines
00069   * @{
00070   */ 
00071 #define TIMEOUT_MAX    0x1000; /*<! The value of the maximal timeout for I2C waiting loops */
00072 /**
00073   * @}
00074   */ 
00075 
00076 
00077 /** @defgroup STM32100E_EVAL_IOE_Private_Macros
00078   * @{
00079   */ 
00080 /**
00081   * @}
00082   */ 
00083 
00084 
00085 /** @defgroup STM32100E_EVAL_IOE_Private_Variables
00086   * @{
00087   */ 
00088 TS_STATE TS_State;              /*<! The global structure holding the TS state */
00089 
00090 uint32_t IOE_TimeOut = TIMEOUT_MAX; /*<! Value of Timeout when I2C communication fails */
00091 /**
00092   * @}
00093   */ 
00094 
00095 
00096 /** @defgroup STM32100E_EVAL_IOE_Private_FunctionPrototypes
00097   * @{
00098   */ 
00099 static uint16_t IOE_TS_Read_X(void);
00100 static uint16_t IOE_TS_Read_Y(void);
00101 static uint16_t IOE_TS_Read_Z(void);
00102 
00103 static void IOE_GPIO_Config(void);
00104 static void IOE_I2C_Config(void);
00105 static void IOE_DMA_Config(IOE_DMADirection_TypeDef Direction, uint8_t* buffer);
00106 static void IOE_EXTI_Config(void);
00107 
00108 #ifndef USE_Delay
00109 static void delay(__IO uint32_t nCount);
00110 #endif /* USE_Delay*/
00111 /**
00112   * @}
00113   */ 
00114 
00115 
00116 /** @defgroup STM32100E_EVAL_IOE_Private_Functions
00117   * @{
00118   */ 
00119 
00120 
00121 /**
00122   * @brief  Initializes and Configures the IO_Expanders Functionalities 
00123   *         (Touch Screen ..) and configures all STM32100E-EVAL necessary
00124   *         hardware (GPIOs, APB clocks ..).
00125   * @param  None
00126   * @retval IOE_OK if all initializations done correctly. Other value if error.
00127   */
00128 uint8_t IOE_Config(void)
00129 {
00130   /* Configure the needed pins */
00131   IOE_GPIO_Config();
00132   
00133   /* Configure I2C peripheral */
00134   IOE_I2C_Config();
00135   
00136   /* Read IO Expander 1 ID  */
00137   if(IOE_IsOperational(IOE_1_ADDR))
00138   {
00139     return IOE1_NOT_OPERATIONAL;
00140   } 
00141   
00142   /* Generate IOExpander Software reset */
00143   IOE_Reset(IOE_1_ADDR); 
00144   
00145   /* ---------------------- IO Expander configuration --------------------- */
00146   /* Enable the GPIO, Touch Screen and ADC functionalities */
00147   IOE_FnctCmd(IOE_1_ADDR, IOE_TS_FCT | IOE_ADC_FCT | IOE_IO_FCT | IOE_TEMPSENS_FCT  , ENABLE);
00148    
00149   /* Touch Screen controller configuration */
00150   IOE_TS_Config();
00151   
00152   /* Temperature Sensor configuration */
00153   IOE_TempSens_Config();
00154  
00155   /* ------------------------------------------------------------------------ */
00156   
00157   /* Configuration is OK */
00158   return IOE_OK; 
00159 }
00160 
00161 /**
00162   * @brief  Configures The selected interrupts on the IO Expanders.
00163   * @param  IOE_ITSRC_Source: the source of the interrupts. Could be one or a 
00164   *         combination of the following parameters:
00165   *   @arg  IOE_ITSRC_TSC: Touch Screen interrupts.
00166   * @retval IOE_OK: if all initializations are OK. Other value if error.
00167   */
00168 uint8_t IOE_ITConfig(uint32_t IOE_ITSRC_Source)
00169 {   
00170   /* Configure the Interrupt output pin to generate low level (INT_CTRL) */
00171   IOE_ITOutConfig(Polarity_Low, Type_Level);    
00172   
00173   /* Manage the Touch Screen Interrupts */  
00174   if (IOE_ITSRC_Source & IOE_ITSRC_TSC)
00175   {   
00176     /* Enable the Global interrupt */  
00177     IOE_GITCmd(IOE_1_ADDR, ENABLE);     
00178            
00179     /* Enable the Global GPIO Interrupt */
00180     IOE_GITConfig(IOE_1_ADDR, (uint8_t)(IOE_GIT_TOUCH | IOE_GIT_FTH | IOE_GIT_FOV), ENABLE);    
00181     
00182     /* Read the GPIO_IT_STA to clear all pending bits if any */
00183     I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_GPIO_INT_STA); 
00184   }
00185   
00186   /* Configure the Interrupt line as EXTI source */
00187   IOE_EXTI_Config();    
00188   
00189   /* If all OK return IOE_OK */
00190   return IOE_OK;
00191 }
00192 
00193 /**
00194   * @brief  Writes a bit value to an output IO pin.
00195   * @param IO_Pin: The output pin to be set or reset. 
00196   *                IO_Pin_x: Where x can be from 0 to 7. 
00197   * @param BitVal: The value to be set. This parameter can be one of the
00198   *        following values: BitSet or BitReset. See IOE_BitVal_TypeDef.
00199   * @retval IOE_OK or PARAM_ERROR
00200   */
00201 uint8_t IOE_WriteIOPin(uint8_t IO_Pin, IOE_BitValue_TypeDef BitVal)
00202 {
00203   uint8_t DeviceAddr = 0;
00204   
00205   /* Get the IO expander Address according to which pin is to be controlled */
00206   if (IO_Pin & IO1_OUT_ALL_PINS)
00207   {
00208     DeviceAddr = IOE_1_ADDR;
00209   }
00210   else
00211   {
00212     return PARAM_ERROR;
00213   }
00214   
00215   /* Apply the bit value to the selected pin */
00216   if (BitVal == BitReset)
00217   {
00218     /* Set the register */
00219     I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_CLR_PIN, IO_Pin);
00220   }
00221   else
00222   {
00223     /* Set the register */
00224     I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_SET_PIN, IO_Pin);
00225   }
00226   
00227   return IOE_OK;
00228 }
00229 
00230 
00231 /**
00232   * @brief  Returns the status of the selected input IO pin.
00233   * @param IO_Pin: The input pin to be read. 
00234   *                IO_Pin_x: Where x can be from 0 to 7.
00235   *   @arg  JOY_IO_PINS: Joystick IO pins (use IOE_JoyStickGetState for these pins)  
00236   * @retval None
00237   */
00238 uint8_t IOE_ReadIOPin(uint32_t IO_Pin)
00239 {
00240   uint8_t DeviceAddr = 0;
00241   uint8_t tmp = 0;  
00242   if (IO_Pin & IO1_IN_ALL_PINS)
00243   {
00244     DeviceAddr = IOE_1_ADDR;
00245   }
00246    else 
00247   {
00248     return PARAM_ERROR;
00249   }
00250   
00251   /* Get all the Pins status */
00252   tmp = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_GPIO_MP_STA);
00253   if ((tmp & (uint8_t)IO_Pin) != 0)
00254   {
00255     return BitSet;
00256   }  
00257   else 
00258   {
00259     return BitReset;
00260   }
00261 }
00262 
00263 
00264 /**
00265   * @brief  Returns Status and positions of the Touch screen.
00266   * @param  None
00267   * @retval Pointer to TS_STATE structure holding Touch Screen information.
00268   */
00269 TS_STATE* IOE_TS_GetState(void)
00270 {
00271   uint32_t xDiff, yDiff , x , y;
00272   static uint32_t _x = 0, _y = 0;
00273   
00274   /* Check if the Touch detect event happenned */
00275   TS_State.TouchDetected = (I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_TSC_CTRL) & 0x80);
00276   if(TS_State.TouchDetected) 
00277   {
00278     x = IOE_TS_Read_X();
00279     y = IOE_TS_Read_Y();
00280     xDiff = x > _x? (x - _x): (_x - x);
00281     yDiff = y > _y? (y - _y): (_y - y);       
00282     if (xDiff + yDiff > 5)
00283     {
00284       _x = x;
00285       _y = y;       
00286     }
00287   }  
00288   /* Update the X position */
00289   TS_State.X = _x;
00290     
00291   /* Update the Y position */  
00292   TS_State.Y = _y;
00293   /* Update the Z Pression index */  
00294   TS_State.Z = IOE_TS_Read_Z();  
00295   
00296   /* Clear the interrupt pending bit and enable the FIFO again */
00297   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_FIFO_STA, 0x01);
00298   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_FIFO_STA, 0x00);
00299   
00300   /* Return pointer to the updated structure */
00301   return &TS_State; 
00302 }
00303 
00304 /**
00305   * @brief  Returns the temperature row value (in 16 bit format).
00306   * @param  None
00307   * @retval The temperature row value.
00308   */
00309 uint32_t IOE_TempSens_GetData(void)
00310 {  
00311   static __IO uint32_t tmp = 0;  
00312     
00313   /* Aquire data enable */
00314   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_TEMP_CTRL, 0x03);
00315   
00316   /* Enable the TEMPSENS module */
00317   tmp = (uint32_t)((I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_TEMP_DATA) & 0x03) << 8); 
00318   tmp |= (uint32_t)I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_TEMP_DATA + 1); 
00319   
00320   tmp = (uint32_t)((33 * tmp * 100) / 751);
00321   tmp = (uint32_t)((tmp + 5) / 10);
00322   
00323   /* return the temprature row value */
00324   return tmp;
00325 }
00326 
00327 /**
00328   * @brief  Checks the selected Global interrupt source pending bit
00329   * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
00330   * @param  Global_IT: the Global interrupt source to be checked, could be:
00331   *   @arg  Global_IT_GPIO : All IOs interrupt
00332   *   @arg  Global_IT_ADC : ADC interrupt
00333   *   @arg  Global_IT_TEMP : Temperature Sensor interrupts      
00334   *   @arg  Global_IT_FE : Touch Screen Controller FIFO Error interrupt
00335   *   @arg  Global_IT_FF : Touch Screen Controller FIFO Full interrupt      
00336   *   @arg  Global_IT_FOV : Touch Screen Controller FIFO Overrun interrupt     
00337   *   @arg  Global_IT_FTH : Touch Screen Controller FIFO Threshold interrupt   
00338   *   @arg  Global_IT_TOUCH : Touch Screen Controller Touch Detected interrupt      
00339   * @retval Status of the checked flag. Could be SET or RESET.
00340   */
00341 FlagStatus IOE_GetGITStatus(uint8_t DeviceAddr, uint8_t Global_IT)
00342 {
00343   __IO uint8_t tmp = 0;
00344  
00345   /* get the Interrupt status */
00346   tmp = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_INT_STA);
00347   
00348   if ((tmp & (uint8_t)Global_IT) != 0)
00349   {
00350     return SET;
00351   }
00352   else
00353   {
00354     return RESET;
00355   }
00356 }
00357 
00358 /**
00359   * @brief  Clears the selected Global interrupt pending bit(s)
00360   * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
00361   * @param  Global_IT: the Global interrupt to be cleared, could be any combination
00362   *         of the following values:   
00363   *   @arg  Global_IT_GPIO : All IOs interrupt
00364   *   @arg  Global_IT_ADC : ADC interrupt
00365   *   @arg  Global_IT_TEMP : Temperature Sensor interrupts      
00366   *   @arg  Global_IT_FE : Touch Screen Controller FIFO Error interrupt
00367   *   @arg  Global_IT_FF : Touch Screen Controller FIFO Full interrupt      
00368   *   @arg  Global_IT_FOV : Touch Screen Controller FIFO Overrun interrupt     
00369   *   @arg  Global_IT_FTH : Touch Screen Controller FIFO Threshold interrupt   
00370   *   @arg  Global_IT_TOUCH : Touch Screen Controller Touch Detected interrupt 
00371   * @retval IOE_OK: if all initializations are OK. Other value if error.
00372   */
00373 uint8_t IOE_ClearGITPending(uint8_t DeviceAddr, uint8_t Global_IT)
00374 {
00375   /* Write 1 to the bits that have to be cleared */
00376   I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_INT_STA, Global_IT); 
00377 
00378   /* If all OK return IOE_OK */
00379   return IOE_OK;
00380 }
00381 
00382 /**
00383   * @brief  Checks the status of the selected IO interrupt pending bit
00384   * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
00385   * @param  IO_IT: the IO interrupt to be checked could be IO_ITx Where x can be 
00386   *         from 0 to 7.             
00387   * @retval Status of the checked flag. Could be SET or RESET.
00388   */
00389 FlagStatus IOE_GetIOITStatus(uint8_t DeviceAddr, uint8_t IO_IT)
00390 {
00391   uint8_t tmp = 0;
00392  
00393   /* get the Interrupt status */
00394   tmp = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_GPIO_INT_STA);
00395   
00396   if ((tmp & (uint8_t)IO_IT) != 0)
00397   {
00398     return SET;
00399   }
00400   else
00401   {
00402     return RESET;
00403   }
00404 }
00405 
00406 /**
00407   * @brief  Clears the selected IO interrupt pending bit(s).
00408   * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
00409   * @param  IO_IT: the IO interrupt to be checked could be IO_ITx Where x can be 
00410   *         from 0 to 7.              
00411   * @retval IOE_OK: if all initializations are OK. Other value if error.
00412   */
00413 uint8_t IOE_ClearIOITPending(uint8_t DeviceAddr, uint8_t IO_IT)
00414 {
00415   /* Write 1 to the bits that have to be cleared */
00416   I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_INT_STA, IO_IT);  
00417   
00418   /* Clear the Edge detection pending bit*/
00419   I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_ED, IO_IT);
00420 
00421   /* Clear the Rising edge pending bit */
00422   I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_RE, IO_IT);
00423 
00424   /* Clear the Falling edge pending bit */
00425   I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_FE, IO_IT); 
00426 
00427   return IOE_OK;
00428   
00429 }
00430 /**
00431   * @brief  Checks if the selected device is correctly configured and 
00432   *         communicates correctly ont the I2C bus.
00433   * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
00434   * @retval IOE_OK if IOE is operational. Other value if failure.
00435   */
00436 uint8_t IOE_IsOperational(uint8_t DeviceAddr)
00437 {
00438   /* Return Error if the ID is not correct */
00439   if( IOE_ReadID(DeviceAddr) != (uint16_t)STMPE811_ID )
00440   {
00441     /* Check if a Timeout occured */
00442     if (IOE_TimeOut == 0)
00443     {
00444       return(IOE_TimeoutUserCallback());
00445     }
00446     else
00447     {
00448       return IOE_FAILURE; /* ID is not Correct */
00449     }
00450   } 
00451   else 
00452   {
00453     return IOE_OK; /* ID is correct */
00454   }
00455 }
00456 
00457 /**
00458   * @brief  Resets the IO Expander by Software (SYS_CTRL1, RESET bit).
00459   * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
00460   * @retval IOE_OK: if all initializations are OK. Other value if error.
00461   */
00462 uint8_t IOE_Reset(uint8_t DeviceAddr)
00463 {
00464   /* Power Down the IO_Expander */
00465   I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_SYS_CTRL1, 0x02);
00466 
00467   /* wait for a delay to insure registers erasing */
00468   _delay_(2); 
00469   
00470   /* Power On the Codec after the power off => all registers are reinitialized*/
00471   I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_SYS_CTRL1, 0x00);
00472   
00473   /* If all OK return IOE_OK */
00474   return IOE_OK;    
00475 }
00476 
00477 /**
00478   * @brief  Reads the selected device's ID.
00479   * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
00480   * @retval The Device ID (two bytes).
00481   */
00482 uint16_t IOE_ReadID(uint8_t DeviceAddr)
00483 {
00484   uint16_t tmp = 0;
00485 
00486   /* Read device ID  */
00487   tmp = I2C_ReadDeviceRegister(DeviceAddr, 0);
00488   tmp = (uint32_t)(tmp << 8);
00489   tmp |= (uint32_t)I2C_ReadDeviceRegister(DeviceAddr, 1);
00490   
00491   /* Return the ID */
00492   return (uint16_t)tmp;
00493 }
00494 
00495 /**
00496   * @brief  Configures the selcted IO Expander functionalities.
00497   * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
00498   * @param  Fct: the functions to be configured. could be any 
00499   *         combination of the following values:
00500   *   @arg  IOE_IO_FCT : IO function
00501   *   @arg  IOE_TS_FCT : Touch Screen function
00502   *   @arg  IOE_ADC_FCT : ADC function
00503   *   @arg  IOE_TEMPSENS_FCT : Tempreature Sensor function
00504   * @retval IOE_OK: if all initializations are OK. Other value if error.
00505   */
00506 uint8_t IOE_FnctCmd(uint8_t DeviceAddr, uint8_t Fct, FunctionalState NewState)
00507 {
00508   uint8_t tmp = 0;
00509   
00510   /* Get the register value */
00511   tmp = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_SYS_CTRL2);
00512   
00513   if (NewState != DISABLE)
00514   {
00515     /* Set the Functionalities to be Enabled */    
00516     tmp &= ~(uint8_t)Fct;
00517   }
00518   else
00519   {
00520     /* Set the Functionalities to be Disabled */    
00521     tmp |= (uint8_t)Fct;  
00522   }
00523   
00524   /* Set the register value */
00525   I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_SYS_CTRL2, tmp);
00526   
00527   /* If all OK return IOE_OK */
00528   return IOE_OK;    
00529 }
00530 
00531 /**
00532   * @brief  Configures the selected pin direction (to be an input or an output)
00533   * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
00534   * @param  IO_Pin: IO_Pin_x: Where x can be from 0 to 7.   
00535   * @param  Direction: could be Direction_IN or Direction_OUT.      
00536   * @retval IOE_OK: if all initializations are OK. Other value if error.
00537   */
00538 uint8_t IOE_IOPinConfig(uint8_t DeviceAddr, uint8_t IO_Pin, uint8_t Direction)
00539 {
00540   uint8_t tmp = 0;   
00541   
00542   /* Get all the Pins direction */
00543   tmp = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_GPIO_DIR);
00544   
00545   if (Direction != Direction_IN)
00546   {
00547     tmp |= (uint8_t)IO_Pin;
00548   }  
00549   else 
00550   {
00551     tmp &= ~(uint8_t)IO_Pin;
00552   }
00553   
00554   /* Write the register new value */
00555   I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_DIR, tmp);
00556   
00557   /* If all OK return IOE_OK */
00558   return IOE_OK;      
00559 }
00560 
00561 /**
00562   * @brief  Enables or disables the Global interrupt.
00563   * @param  DeviceAddr: The address of the IOExpander, could be :I OE_1_ADDR.
00564   * @param  NewState: could be ENABLE or DISABLE.        
00565   * @retval IOE_OK: if all initializations are OK. Other value if error.
00566   */
00567 uint8_t IOE_GITCmd(uint8_t DeviceAddr, FunctionalState NewState)
00568 {
00569   uint8_t tmp = 0;
00570   
00571   /* Read the Interrupt Control register  */
00572   I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_INT_CTRL);
00573   
00574   if (NewState != DISABLE)
00575   {
00576     /* Set the global interrupts to be Enabled */    
00577     tmp |= (uint8_t)IOE_GIT_EN;
00578   }
00579   else
00580   {
00581     /* Set the global interrupts to be Disabled */    
00582     tmp &= ~(uint8_t)IOE_GIT_EN;
00583   }  
00584   
00585   /* Write Back the Interrupt Control register */
00586   I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_INT_CTRL, tmp);
00587 
00588   /* If all OK return IOE_OK */
00589   return IOE_OK;     
00590 }
00591 
00592 /**
00593   * @brief  Configures the selected source to generate or not a global interrupt
00594   * @param DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR
00595   * @param Global_IT: the interrupt source to be configured, could be:
00596   *   @arg  Global_IT_GPIO : All IOs interrupt
00597   *   @arg  Global_IT_ADC : ADC interrupt
00598   *   @arg  Global_IT_TEMP : Temperature Sensor interrupts  
00599   *   @arg  Global_IT_FE : Touch Screen Controller FIFO Error interrupt
00600   *   @arg  Global_IT_FF : Touch Screen Controller FIFO Full interrupt      
00601   *   @arg  Global_IT_FOV : Touch Screen Controller FIFO Overrun interrupt     
00602   *   @arg  Global_IT_FTH : Touch Screen Controller FIFO Threshold interrupt   
00603   *   @arg  Global_IT_TOUCH : Touch Screen Controller Touch Detected interrupt 
00604   * @retval IOE_OK: if all initializations are OK. Other value if error.
00605   */
00606 uint8_t IOE_GITConfig(uint8_t DeviceAddr, uint8_t Global_IT, FunctionalState NewState)
00607 {
00608   uint8_t tmp = 0;
00609   
00610   /* Get the current value of the INT_EN register */
00611   tmp = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_INT_EN);
00612   
00613   if (NewState != DISABLE)
00614   {
00615     /* Set the interrupts to be Enabled */    
00616     tmp |= (uint8_t)Global_IT;  
00617   }
00618   else
00619   {
00620     /* Set the interrupts to be Disabled */    
00621     tmp &= ~(uint8_t)Global_IT;
00622   }
00623   /* Set the register */
00624   I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_INT_EN, tmp);
00625   
00626   /* If all OK return IOE_OK */
00627   return IOE_OK;  
00628 }
00629 
00630 /**
00631   * @brief  Configures the selected pins to generate an interrupt or not.
00632   * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
00633   * @param  IO_IT: The IO interrupt to be configured. This parameter could be any
00634   *         combination of the following values:
00635   *   @arg  IO_IT_x: where x can be from 0 to 7.
00636   * @param  NewState: could be ENABLE or DISABLE.  
00637   * @retval IOE_OK: if all initializations are OK. Other value if error.
00638   */
00639 uint8_t IOE_IOITConfig(uint8_t DeviceAddr, uint8_t IO_IT, FunctionalState NewState)
00640 {
00641   uint8_t tmp = 0;
00642  
00643   tmp = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_GPIO_INT_EN);
00644   
00645   if (NewState != DISABLE)
00646   {
00647     /* Set the interrupts to be Enabled */    
00648     tmp |= (uint8_t)IO_IT;
00649   }
00650   else
00651   {
00652     /* Set the interrupts to be Disabled */    
00653     tmp &= ~(uint8_t)IO_IT;
00654   }
00655   
00656   /* Set the register */
00657   I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_INT_EN, tmp);
00658   
00659   /* If all OK return IOE_OK */
00660   return IOE_OK;   
00661 }
00662 
00663 /**
00664   * @brief  Configures the touch Screen Controller (Single point detection)
00665   * @param  None
00666   * @retval IOE_OK if all initializations are OK. Other value if error.
00667   */
00668 uint8_t IOE_TS_Config(void)
00669 {
00670   uint8_t tmp = 0;  
00671   
00672   /* Enable TSC Fct: already done in IOE_Config */
00673   tmp = I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_SYS_CTRL2);
00674   tmp &= ~(uint32_t)(IOE_TS_FCT | IOE_ADC_FCT);
00675   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_SYS_CTRL2, tmp); 
00676   
00677   /* Enable the TSC gloabl interrupts */
00678   tmp = I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_INT_EN);
00679   tmp |= (uint32_t)(IOE_GIT_TOUCH | IOE_GIT_FTH | IOE_GIT_FOV);
00680   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_INT_EN, tmp); 
00681   
00682   /* Select Sample Time, bit number and ADC Reference */
00683   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_ADC_CTRL1, 0x49);
00684   
00685   /* Wait for ~20 ms */
00686   _delay_(2);  
00687   
00688   /* Select the ADC clock speed: 3.25 MHz */
00689   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_ADC_CTRL2, 0x01);
00690   
00691   /* Select TSC pins in non default mode */  
00692   tmp = I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_GPIO_AF);
00693   tmp &= ~(uint8_t)TOUCH_IO_ALL;
00694   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_GPIO_AF, tmp); 
00695   
00696   /* Select 2 nF filter capacitor */
00697   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_TSC_CFG, 0x9A);   
00698   
00699   /* Select single point reading  */
00700   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_FIFO_TH, 0x01);
00701   
00702   /* Write 0x01 to clear the FIFO memory content. */
00703   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_FIFO_STA, 0x01);
00704   
00705   /* Write 0x00 to put the FIFO back into operation mode  */
00706   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_FIFO_STA, 0x00);
00707   
00708   /* set the data format for Z value: 7 fractional part and 1 whole part */
00709   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_TSC_FRACT_XYZ, 0x01);
00710   
00711   /* set the driving capability of the device for TSC pins: 50mA */
00712   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_TSC_I_DRIVE, 0x01);
00713   
00714   /* Use no tracking index, touchscreen controller operation mode (XYZ) and 
00715      enable the TSC */
00716   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_TSC_CTRL, 0x01);
00717   
00718   /*  Clear all the status pending bits */
00719   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_INT_STA, 0xFF); 
00720   
00721   /* Initialize the TS structure to their default values */ 
00722   TS_State.TouchDetected = TS_State.X = TS_State.Y = TS_State.Z = 0;
00723   
00724   /* All configuration done */
00725   return IOE_OK;  
00726 }
00727 
00728 /**
00729   * @brief  Configures and enables the Temperature sensor module.
00730   * @param  None
00731   * @retval IOE_OK if all initializations are OK. Other value if error.
00732   */
00733 uint8_t IOE_TempSens_Config(void)
00734 {
00735   __IO uint8_t tmp = 0;
00736   
00737   /* Enable Temperature Sensor Fct: already done in IOE_Config */
00738   tmp = I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_SYS_CTRL2);
00739   tmp &= ~(uint32_t)(IOE_TEMPSENS_FCT | IOE_ADC_FCT);
00740   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_SYS_CTRL2, tmp);  
00741   
00742   /* Enable the TEMPSENS module */
00743   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_TEMP_CTRL, 0x01);
00744   
00745   /* Aquire data enable */
00746   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_TEMP_CTRL, 0x3);
00747   
00748   /* All configuration done */
00749   return IOE_OK;
00750 }
00751 
00752 /**
00753   * @brief  Configures the selected pin to be in Alternate function or not
00754   * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
00755   * @param  IO_Pin: IO_Pin_x, Where x can be from 0 to 7.   
00756   * @param  NewState: State of the AF for the selected pin, could be 
00757   *         ENABLE or DISABLE.       
00758   * @retval IOE_OK: if all initializations are OK. Other value if error.
00759   */
00760 uint8_t IOE_IOAFConfig(uint8_t DeviceAddr, uint8_t IO_Pin, FunctionalState NewState)
00761 {
00762   uint8_t tmp = 0;
00763   
00764   /* Get the current state of the GPIO_AF register */
00765   tmp = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_GPIO_AF);
00766   
00767   if (NewState != DISABLE)
00768   {
00769     /* Enable the selected pins alternate function */
00770     tmp |= (uint8_t)IO_Pin;
00771   }
00772   else
00773   {
00774     /* Disable the selected pins alternate function */   
00775     tmp &= ~(uint8_t)IO_Pin;   
00776   }
00777   
00778   /* Write back the new valu in GPIO_AF register */  
00779   I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_AF, tmp);  
00780 
00781   /* If all OK return IOE_OK */
00782   return IOE_OK;
00783 }
00784 
00785 /**
00786   * @brief  Configures the Edge for which a transition is detectable for the
00787   *         the selected pin.
00788   * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR.
00789   * @param  IO_Pin: IO_Pin_x, Where x can be from 0 to 7.   
00790   * @param  Edge: The edge which will be detected. This parameter can be one or a
00791   *         a combination of follwing values: EDGE_FALLING and EDGE_RISING .
00792   * @retval IOE_OK: if all initializations are OK. Other value if error.
00793   */
00794 uint8_t IOE_IOEdgeConfig(uint8_t DeviceAddr, uint8_t IO_Pin, uint8_t Edge)
00795 {
00796   uint8_t tmp1 = 0, tmp2 = 0;   
00797   
00798   /* Get the registers values */
00799   tmp1 = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_GPIO_FE);
00800   tmp2 = I2C_ReadDeviceRegister(DeviceAddr, IOE_REG_GPIO_RE);
00801 
00802   /* Disable the Falling Edge */
00803   tmp1 &= ~(uint8_t)IO_Pin;
00804   /* Disable the Falling Edge */
00805   tmp2 &= ~(uint8_t)IO_Pin;
00806 
00807   /* Enable the Falling edge if selected */
00808   if (Edge & EDGE_FALLING)
00809   {
00810     tmp1 |= (uint8_t)IO_Pin;
00811   }
00812 
00813   /* Enable the Rising edge if selected */
00814   if (Edge & EDGE_RISING)
00815   {
00816     tmp2 |= (uint8_t)IO_Pin;
00817   }
00818 
00819   /* Write back the registers values */
00820   I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_FE, tmp1);
00821   I2C_WriteDeviceRegister(DeviceAddr, IOE_REG_GPIO_RE, tmp2);
00822   
00823   /* if OK return 0 */
00824   return IOE_OK;
00825 }
00826 
00827 /**
00828   * @brief  Configures the Interrupt line active state and format (level/edge)
00829   * @param  Polarity: could be
00830   *   @arg  Polarity_Low: Interrupt line is active Low/Falling edge      
00831   *   @arg  Polarity_High: Interrupt line is active High/Rising edge      
00832   * @param  Type: Interrupt line activity type, could be one of the following values
00833   *   @arg  Type_Level: Interrupt line is active in level model         
00834   *   @arg  Type_Edge: Interrupt line is active in edge model           
00835   * @retval IOE_OK: if all initializations are OK. Other value if error.
00836   */
00837 uint8_t IOE_ITOutConfig(uint8_t Polarity, uint8_t Type)
00838 {
00839   uint8_t tmp = 0;
00840   
00841   /*  Get the register IOE_REG_INT_CTRL value */ 
00842   tmp = I2C_ReadDeviceRegister(IOE_1_ADDR, IOE_REG_INT_CTRL);
00843   
00844   /* Mask the polarity and type bits */
00845   tmp &= ~(uint8_t)0x06;
00846     
00847   /* Modify the Interrupt Output line configuration */
00848   tmp |= (uint8_t)(Polarity | Type);
00849   
00850   /* Set the register */
00851   I2C_WriteDeviceRegister(IOE_1_ADDR, IOE_REG_INT_CTRL, tmp);
00852     
00853   /* If all OK return IOE_OK */
00854   return IOE_OK;  
00855 }
00856 
00857 /**
00858   * @brief  Writes a value in a register of the device through I2C.
00859   * @param  DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR. 
00860   * @param  RegisterAddr: The target register adress
00861   * @param  RegisterValue: The target register value to be written 
00862   * @retval IOE_OK: if all operations are OK. Other value if error.
00863   */
00864 uint8_t I2C_WriteDeviceRegister(uint8_t DeviceAddr, uint8_t RegisterAddr, uint8_t RegisterValue)
00865 {
00866   uint32_t read_verif = 0;  
00867   uint8_t IOE_BufferTX = 0;
00868   
00869   /* Get Value to be written */
00870   IOE_BufferTX = RegisterValue;
00871   
00872   /* Configure DMA Peripheral */
00873   IOE_DMA_Config(IOE_DMA_TX, (uint8_t*)(&IOE_BufferTX));
00874   
00875   /* Enable the I2C peripheral */
00876   I2C_GenerateSTART(IOE_I2C, ENABLE);
00877   
00878   /* Test on SB Flag */
00879   IOE_TimeOut = TIMEOUT_MAX;
00880   while (I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB) == RESET) 
00881   {
00882     if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
00883   }
00884   
00885   /* Transmit the slave address and enable writing operation */
00886   I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Transmitter);
00887   
00888   /* Test on ADDR Flag */
00889   IOE_TimeOut = TIMEOUT_MAX;
00890   while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
00891   {
00892     if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
00893   }
00894    
00895   /* Transmit the first address for r/w operations */
00896   I2C_SendData(IOE_I2C, RegisterAddr);
00897   
00898   /* Test on TXE FLag (data dent) */
00899   IOE_TimeOut = TIMEOUT_MAX;
00900   while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF)))  
00901   {
00902     if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
00903   }
00904   
00905   /* Enable I2C DMA request */
00906   I2C_DMACmd(IOE_I2C,ENABLE);
00907   
00908   /* Enable DMA TX Channel */
00909   DMA_Cmd(IOE_DMA_TX_CHANNEL, ENABLE);
00910   
00911   /* Wait until DMA Transfer Complete */
00912   IOE_TimeOut = TIMEOUT_MAX;
00913   while (!DMA_GetFlagStatus(IOE_DMA_TX_TCFLAG))
00914   {
00915     if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
00916   }  
00917   
00918   /* Wait until BTF Flag is set before generating STOP */
00919   IOE_TimeOut = 2 * TIMEOUT_MAX;
00920   while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF)))  
00921   {
00922   }
00923   
00924   /* Send STOP Condition */
00925   I2C_GenerateSTOP(IOE_I2C, ENABLE);
00926   
00927   /* Disable DMA TX Channel */
00928   DMA_Cmd(IOE_DMA_TX_CHANNEL, DISABLE);
00929   
00930   /* Disable I2C DMA request */  
00931   I2C_DMACmd(IOE_I2C,DISABLE);
00932   
00933   /* Clear DMA TX Transfer Complete Flag */
00934   DMA_ClearFlag(IOE_DMA_TX_TCFLAG);
00935   
00936 #ifdef VERIFY_WRITTENDATA
00937   /* Verify (if needed) that the loaded data is correct  */
00938   
00939   /* Read the just written register*/
00940   read_verif = I2C_ReadDeviceRegister(DeviceAddr, RegisterAddr);
00941   /* Load the register and verify its value  */
00942   if (read_verif != RegisterValue)
00943   {
00944     /* Control data wrongly tranfered */
00945     read_verif = IOE_FAILURE;
00946   }
00947   else
00948   {
00949     /* Control data correctly transfered */
00950     read_verif = 0;
00951   }
00952 #endif
00953   
00954   /* Return the verifying value: 0 (Passed) or 1 (Failed) */
00955   return read_verif;
00956 }
00957 
00958 /**
00959   * @brief  Reads a register of the device through I2C.
00960   * @param  DeviceAddr: The address of the device, could be : IOE_1_ADDR.
00961   * @param  RegisterAddr: The target register adress (between 00x and 0x24)
00962   * @retval The value of the read register (0xAA if Timout occured)   
00963   */
00964 uint8_t I2C_ReadDeviceRegister(uint8_t DeviceAddr, uint8_t RegisterAddr)
00965 {
00966   uint8_t IOE_BufferRX[2] = {0x00, 0x00};  
00967     
00968   /* Configure DMA Peripheral */
00969   IOE_DMA_Config(IOE_DMA_RX, (uint8_t*)IOE_BufferRX);
00970   
00971   /* Enable DMA NACK automatic generation */
00972   I2C_DMALastTransferCmd(IOE_I2C, ENABLE);
00973   
00974   /* Enable the I2C peripheral */
00975   I2C_GenerateSTART(IOE_I2C, ENABLE);
00976   
00977   /* Test on SB Flag */
00978   IOE_TimeOut = TIMEOUT_MAX;
00979   while (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB)) 
00980   {
00981     if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
00982   }
00983   
00984   /* Send device address for write */
00985   I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Transmitter);
00986   
00987   /* Test on ADDR Flag */
00988   IOE_TimeOut = TIMEOUT_MAX;
00989   while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) 
00990   {
00991     if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
00992   }
00993   
00994   /* Send the device's internal address to write to */
00995   I2C_SendData(IOE_I2C, RegisterAddr);  
00996   
00997   /* Test on TXE FLag (data dent) */
00998   IOE_TimeOut = TIMEOUT_MAX;
00999   while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF)))  
01000   {
01001     if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
01002   }
01003   
01004   /* Send START condition a second time */  
01005   I2C_GenerateSTART(IOE_I2C, ENABLE);
01006   
01007   /* Test on SB Flag */
01008   IOE_TimeOut = TIMEOUT_MAX;
01009   while (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB)) 
01010   {
01011     if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
01012   }
01013   
01014   /* Send IOExpander address for read */
01015   I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Receiver);
01016   
01017   /* Test on ADDR Flag */
01018   IOE_TimeOut = TIMEOUT_MAX;
01019   while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))   
01020   {
01021     if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
01022   }
01023     
01024   /* Enable I2C DMA request */
01025   I2C_DMACmd(IOE_I2C,ENABLE);
01026   
01027   /* Enable DMA RX Channel */
01028   DMA_Cmd(IOE_DMA_RX_CHANNEL, ENABLE);
01029   
01030   /* Wait until DMA Transfer Complete */
01031   IOE_TimeOut = 2 * TIMEOUT_MAX;
01032   while (!DMA_GetFlagStatus(IOE_DMA_RX_TCFLAG))
01033   {
01034     if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
01035   }        
01036   
01037   /* Send STOP Condition */
01038   I2C_GenerateSTOP(IOE_I2C, ENABLE);
01039   
01040   /* Disable DMA RX Channel */
01041   DMA_Cmd(IOE_DMA_RX_CHANNEL, DISABLE);
01042   
01043   /* Disable I2C DMA request */  
01044   I2C_DMACmd(IOE_I2C,DISABLE);
01045   
01046   /* Clear DMA RX Transfer Complete Flag */
01047   DMA_ClearFlag(IOE_DMA_RX_TCFLAG);
01048   
01049   /* return a pointer to the IOE_Buffer */
01050   return (uint8_t)IOE_BufferRX[0];  
01051 }
01052 
01053 
01054 /**
01055   * @brief  Reads a buffer of 2 bytes from the device registers.
01056   * @param  DeviceAddr: The address of the device, could be : IOE_1_ADDR.
01057   * @param  RegisterAddr: The target register adress (between 00x and 0x24)
01058   * @retval A pointer to the buffer containing the two returned bytes (in halfword).  
01059   */
01060 uint16_t I2C_ReadDataBuffer(uint8_t DeviceAddr, uint32_t RegisterAddr)
01061 {  
01062   uint8_t tmp= 0;
01063   uint8_t IOE_BufferRX[2] = {0x00, 0x00};  
01064    
01065   /* Configure DMA Peripheral */
01066   IOE_DMA_Config(IOE_DMA_RX, (uint8_t*)IOE_BufferRX);
01067   
01068   /* Enable DMA NACK automatic generation */
01069   I2C_DMALastTransferCmd(IOE_I2C, ENABLE);
01070   
01071   /* Enable the I2C peripheral */
01072   I2C_GenerateSTART(IOE_I2C, ENABLE);
01073   
01074   /* Test on SB Flag */
01075   IOE_TimeOut = TIMEOUT_MAX;
01076   while (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB)) 
01077   {
01078     if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
01079   }
01080   
01081   /* Send device address for write */
01082   I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Transmitter);
01083   
01084   /* Test on ADDR Flag */
01085   IOE_TimeOut = TIMEOUT_MAX;
01086   while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
01087   {
01088     if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
01089   }
01090   
01091   /* Send the device's internal address to write to */
01092   I2C_SendData(IOE_I2C, RegisterAddr);  
01093   
01094   /* Test on TXE FLag (data dent) */
01095   IOE_TimeOut = TIMEOUT_MAX;
01096   while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF)))  
01097   {
01098     if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
01099   }
01100   
01101   /* Send START condition a second time */  
01102   I2C_GenerateSTART(IOE_I2C, ENABLE);
01103   
01104   /* Test on SB Flag */
01105   IOE_TimeOut = TIMEOUT_MAX;
01106   while (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB)) 
01107   {
01108     if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
01109   }
01110   
01111   /* Send IOExpander address for read */
01112   I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Receiver);
01113   
01114   /* Test on ADDR Flag */
01115   IOE_TimeOut = TIMEOUT_MAX;
01116   while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))   
01117   {
01118     if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
01119   }
01120   
01121   /* Enable I2C DMA request */
01122   I2C_DMACmd(IOE_I2C,ENABLE);
01123   
01124   /* Enable DMA RX Channel */
01125   DMA_Cmd(IOE_DMA_RX_CHANNEL, ENABLE);
01126   
01127   /* Wait until DMA Transfer Complete */
01128   IOE_TimeOut = 2 * TIMEOUT_MAX;
01129   while (!DMA_GetFlagStatus(IOE_DMA_RX_TCFLAG))
01130   {
01131     if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback());
01132   }        
01133   
01134   /* Send STOP Condition */
01135   I2C_GenerateSTOP(IOE_I2C, ENABLE);
01136   
01137   /* Disable DMA RX Channel */
01138   DMA_Cmd(IOE_DMA_RX_CHANNEL, DISABLE);
01139   
01140   /* Disable I2C DMA request */  
01141   I2C_DMACmd(IOE_I2C,DISABLE);
01142   
01143   /* Clear DMA RX Transfer Complete Flag */
01144   DMA_ClearFlag(IOE_DMA_RX_TCFLAG);
01145   
01146   /* Reorganize received data */  
01147   tmp = IOE_BufferRX[0];
01148   IOE_BufferRX[0] = IOE_BufferRX[1];
01149   IOE_BufferRX[1] = tmp;
01150   
01151   /* return a pointer to the IOE_Buffer */
01152   return *(uint16_t *)IOE_BufferRX;  
01153 }
01154 
01155 /**
01156   * @brief  Return Touch Screen X position value
01157   * @param  None
01158   * @retval X position.
01159   */
01160 static uint16_t IOE_TS_Read_X(void)
01161 {
01162   int32_t x, xr;
01163  
01164   x = I2C_ReadDataBuffer(IOE_1_ADDR, IOE_REG_TSC_DATA_Y);
01165   
01166   /* first correction */
01167   xr =  (x * 320) >> 12;
01168   /* second correction */
01169   xr = ((xr * 32)/29) - 17;
01170   
01171   if(xr <= 0)
01172     xr = 0;
01173   
01174   return (uint16_t)(xr); 
01175 }
01176 
01177 /**
01178   * @brief  Return Touch Screen Y position value
01179   * @param  None
01180   * @retval Y position.
01181   */
01182 static uint16_t IOE_TS_Read_Y(void)
01183 {
01184   int32_t y, yr;
01185   y= I2C_ReadDataBuffer(IOE_1_ADDR, IOE_REG_TSC_DATA_X);
01186   
01187   yr= (y * 240) >> 12;
01188   yr = ((yr * 240) / 217) - 12;
01189   
01190   if(yr <= 0)
01191     yr = 0;
01192   
01193   return (uint16_t)(yr); 
01194 }
01195 
01196 /**
01197   * @brief  Return Touch Screen Z position value
01198   * @param  None
01199   * @retval Z position.
01200   */
01201 static uint16_t IOE_TS_Read_Z(void)
01202 {
01203   uint32_t z;
01204   z = I2C_ReadDataBuffer(IOE_1_ADDR, IOE_REG_TSC_DATA_Z);
01205   
01206   
01207   if(z <= 0)
01208     z = 0;
01209   
01210   return (uint16_t)(z); 
01211 }
01212 
01213 /**
01214   * @brief  Initializes the GPIO pins used by the IO expander.
01215   * @param  None
01216   * @retval None
01217   */
01218 static void IOE_GPIO_Config(void)
01219 {
01220   GPIO_InitTypeDef GPIO_InitStructure;
01221   
01222   /* Enable IOE_I2C and IOE_I2C_PORT & Alternate Function clocks */
01223   RCC_APB1PeriphClockCmd(IOE_I2C_CLK, ENABLE);
01224   RCC_APB2PeriphClockCmd(IOE_I2C_SCL_GPIO_CLK | IOE_I2C_SDA_GPIO_CLK | IOE_IT_GPIO_CLK
01225                          | RCC_APB2Periph_AFIO, ENABLE);
01226   
01227   /* Reset IOE_I2C IP */
01228   RCC_APB1PeriphResetCmd(IOE_I2C_CLK, ENABLE);
01229   
01230   /* Release reset signal of IOE_I2C IP */
01231   RCC_APB1PeriphResetCmd(IOE_I2C_CLK, DISABLE);
01232   
01233   /* IOE_I2C SCL and SDA pins configuration */
01234   GPIO_InitStructure.GPIO_Pin = IOE_I2C_SCL_PIN;
01235   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
01236   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
01237   GPIO_Init(IOE_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
01238 
01239   /* IOE_I2C SCL and SDA pins configuration */
01240   GPIO_InitStructure.GPIO_Pin = IOE_I2C_SDA_PIN;
01241   GPIO_Init(IOE_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);  
01242   
01243   /* Set EXTI pin as Input PullUp - IO_Expander_INT */
01244   GPIO_InitStructure.GPIO_Pin = IOE_IT_PIN;
01245   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
01246   GPIO_Init(IOE_IT_GPIO_PORT, &GPIO_InitStructure);
01247   
01248   /* Connect IO Expander IT line to EXTI line */
01249   GPIO_EXTILineConfig(IOE_IT_EXTI_PORT_SOURCE, IOE_IT_EXTI_PIN_SOURCE);
01250 }
01251 
01252 
01253 /**
01254   * @brief  Configure the I2C Peripheral used to communicate with IO_Expanders.
01255   * @param  None
01256   * @retval None
01257   */
01258 static void IOE_I2C_Config(void)
01259 {
01260   I2C_InitTypeDef I2C_InitStructure;
01261   
01262   /* IOE_I2C configuration */
01263   I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
01264   I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
01265   I2C_InitStructure.I2C_OwnAddress1 = 0x00;
01266   I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
01267   I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
01268   I2C_InitStructure.I2C_ClockSpeed = IOE_I2C_SPEED;
01269   
01270   I2C_Init(IOE_I2C, &I2C_InitStructure);
01271 }
01272 
01273 
01274 /**
01275   * @brief  Configure the DMA Peripheral used to handle communication via I2C.
01276   * @param  None
01277   * @retval None
01278   */
01279 
01280 static void IOE_DMA_Config(IOE_DMADirection_TypeDef Direction, uint8_t* buffer)
01281 {
01282   DMA_InitTypeDef DMA_InitStructure;
01283   
01284   RCC_AHBPeriphClockCmd(IOE_DMA_CLK, ENABLE);
01285   
01286   /* Initialize the DMA_PeripheralBaseAddr member */
01287   DMA_InitStructure.DMA_PeripheralBaseAddr = IOE_I2C_DR;
01288   /* Initialize the DMA_MemoryBaseAddr member */
01289   DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)buffer;
01290    /* Initialize the DMA_PeripheralInc member */
01291   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
01292   /* Initialize the DMA_MemoryInc member */
01293   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
01294   /* Initialize the DMA_PeripheralDataSize member */
01295   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
01296   /* Initialize the DMA_MemoryDataSize member */
01297   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
01298   /* Initialize the DMA_Mode member */
01299   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
01300   /* Initialize the DMA_Priority member */
01301   DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
01302   /* Initialize the DMA_M2M member */
01303   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
01304   
01305   /* If using DMA for Reception */
01306   if (Direction == IOE_DMA_RX)
01307   {
01308     /* Initialize the DMA_DIR member */
01309     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
01310     
01311     /* Initialize the DMA_BufferSize member */
01312     DMA_InitStructure.DMA_BufferSize = 2;
01313     
01314     DMA_DeInit(IOE_DMA_RX_CHANNEL);
01315     
01316     DMA_Init(IOE_DMA_RX_CHANNEL, &DMA_InitStructure);
01317   }
01318    /* If using DMA for Transmission */
01319   else if (Direction == IOE_DMA_TX)
01320   { 
01321     /* Initialize the DMA_DIR member */
01322     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
01323     
01324     /* Initialize the DMA_BufferSize member */
01325     DMA_InitStructure.DMA_BufferSize = 1;
01326     
01327     DMA_DeInit(IOE_DMA_TX_CHANNEL);
01328     
01329     DMA_Init(IOE_DMA_TX_CHANNEL, &DMA_InitStructure);
01330   }
01331 }
01332 
01333 /**
01334   * @brief  Configures the IO expander Interrupt line and GPIO in EXTI mode.
01335   * @param  None        
01336   * @retval None
01337   */
01338 static void IOE_EXTI_Config(void)
01339 {
01340   GPIO_InitTypeDef GPIO_InitStructure;
01341   NVIC_InitTypeDef NVIC_InitStructure;
01342   EXTI_InitTypeDef EXTI_InitStructure;
01343  
01344   /* Enable Button GPIO clock */
01345   RCC_APB2PeriphClockCmd(IOE_IT_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE);
01346   
01347   /* Configure Button pin as input floating */
01348   GPIO_InitStructure.GPIO_Pin = IOE_IT_PIN;
01349   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
01350   GPIO_Init(IOE_IT_GPIO_PORT, &GPIO_InitStructure);  
01351   
01352   /* Connect Button EXTI Line to Button GPIO Pin */
01353   GPIO_EXTILineConfig(IOE_IT_EXTI_PORT_SOURCE, IOE_IT_EXTI_PIN_SOURCE);  
01354   
01355   /* Configure Button EXTI line */
01356   EXTI_InitStructure.EXTI_Line = IOE_IT_EXTI_LINE;
01357   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
01358   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;  
01359   EXTI_InitStructure.EXTI_LineCmd = ENABLE;
01360   EXTI_Init(&EXTI_InitStructure);
01361   
01362   /* Enable and set Button EXTI Interrupt to the lowest priority */
01363   NVIC_InitStructure.NVIC_IRQChannel = IOE_IT_EXTI_IRQn;
01364   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
01365   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
01366   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
01367   NVIC_Init(&NVIC_InitStructure);
01368 }
01369 
01370 #ifndef USE_Delay
01371 /**
01372   * @brief  Inserts a delay time.
01373   * @param  nCount: specifies the delay time length.
01374   * @retval None
01375   */
01376 static void delay(__IO uint32_t nCount)
01377 {
01378   __IO uint32_t index = 0; 
01379   for(index = (100000 * nCount); index != 0; index--)
01380   {
01381   }
01382 }
01383 #endif /* USE_Delay*/
01384 /**
01385   * @}
01386   */ 
01387 
01388 /**
01389   * @}
01390   */ 
01391 
01392 /**
01393   * @}
01394   */  
01395 
01396 /**
01397   * @}
01398   */ 
01399 
01400 /**
01401   * @}
01402   */ 
01403    
01404 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
STM32F10x Standard Peripherals Library: Footer

 

 

 

      For complete documentation on STM32(CORTEX M3) 32-bit Microcontrollers platform visit  www.st.com/STM32