stm3210c_eval_ioe.c

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