mems.c

00001 /******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
00002 * File Name          : hal_led.c
00003 * Author             : MCD Application Team
00004 * Version            : V1.0
00005 * Date               : September 2009
00006 * Description        : Driver for leds management on STM32W108 MB851 board
00007 ********************************************************************************
00008 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
00009 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
00010 * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
00011 * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
00012 * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
00013 * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
00014 *******************************************************************************/
00015 
00016 /* Includes ------------------------------------------------------------------*/
00017 
00018 #include PLATFORM_HEADER
00019 #include "mems.h"
00020 #include "timer.h"
00021 
00022 /* Private define -- ---------------------------------------------------------*/
00023 
00024 #define TIMEOUT 20000
00025 
00026 #define SUCCESS 1
00027 #define FAIL    0  
00028 
00029 #define SEND_BYTE(data) do{ SC2_DATA=(data); SC2_TWICTRL1 |= SC_TWISEND; }while(0)
00030 
00031 #define WAIT_CMD_FIN()  {                                                       \
00032                           struct timer t;                                       \
00033                           timer_set(&t, CLOCK_SECOND/100);                      \
00034                           while((SC2_TWISTAT&SC_TWICMDFIN)!=SC_TWICMDFIN){      \
00035                             if(timer_expired(&t)){                              \
00036                             return FAIL;                                        \
00037                            }                                                    \
00038                           }                                                     \
00039                         }
00040 
00041 #define WAIT_TX_FIN()   {                                                       \
00042                           struct timer t;                                       \
00043                           timer_set(&t, CLOCK_SECOND/100);                      \
00044                           while((SC2_TWISTAT&SC_TWITXFIN)!=SC_TWITXFIN){        \
00045                             if(timer_expired(&t)){                              \
00046                             return FAIL;                                        \
00047                            }                                                    \
00048                           }                                                     \
00049                         }
00050 #define WAIT_RX_FIN()    {                                                      \
00051                           struct timer t;                                       \
00052                           timer_set(&t, CLOCK_SECOND/100);                      \
00053                           while((SC2_TWISTAT&SC_TWIRXFIN)!=SC_TWIRXFIN){        \
00054                             if(timer_expired(&t)){                              \
00055                             return FAIL;                                        \
00056                            }                                                    \
00057                           }                                                     \
00058                         }
00059 
00060 /* Private variables ---------------------------------------------------------*/
00061 static boolean fullscale_state;
00062 
00063 /* Private functions ---------------------------------------------------------*/
00064 static int8u I2C_MEMS_Init (void);
00065 //extern void halInternalResetWatchDog(void);
00066 static int8u I2C_Send_Frame (int8u DeviceAddress, int8u *pBuffer, int8u NoOfBytes);
00067 int8u i2c_write_reg (int8u slave_addr, int8u reg_addr, int8u reg_value);
00068 //static int8u I2C_MEMS_Read (t_mems_data *mems_data);
00069 
00070 /* Functions -----------------------------------------------------------------*/
00071 
00072 /*******************************************************************************
00073 * Function Name  : Mems_Init
00074 * Description    : It inits mems 
00075 * Input          : None
00076 * Output         : status
00077 * Return         : None
00078 *******************************************************************************/
00079 int8u Mems_Init(void)
00080 {  
00081   int8u ret = 0;
00082   
00083   // GPIO assignments
00084   // PA1: SC2SDA (Serial Data)
00085   // PA2: SC2SCL (Serial Clock)
00086 
00087   //-----SC2 I2C Master GPIO configuration
00088 
00089   TIM2_CCER &= 0xFFFFEEEE;
00090   SC2_MODE =  SC2_MODE_I2C;
00091   GPIO_PACFGL &= 0xFFFFF00F;
00092   GPIO_PACFGL |= 0x00000DD0;
00093   
00094   SC2_RATELIN =  14;   // generates standard 100kbps or 400kbps
00095   SC2_RATEEXP =  1;    // 3 yields 100kbps; 1 yields 400kbps
00096   SC2_TWICTRL1 =  0;   // start from a clean state
00097   SC2_TWICTRL2 =  0;   // start from a clean state  
00098   
00099   ret = I2C_MEMS_Init();
00100   
00101   fullscale_state = MEMS_LOW_RANGE;
00102 
00103 //Add later if really needed  
00104 #ifdef ST_DBG  
00105   if (!ret)
00106    I2C_DeInit(MEMS_I2C);
00107 #endif
00108   
00109   return ret;
00110 }/* end Mems_Init */
00111 
00112 /*******************************************************************************
00113 * Function Name  : Mems_GetValue
00114 * Description    : It returns the 3 mems acceleration values related to x,y,z 
00115 *                  axes in mems_data
00116 * Input          : mems_data
00117 * Output         : status
00118 * Return         : None
00119 *******************************************************************************/
00120 //int8u Mems_GetValue(t_mems_data *mems_data)
00121 //{
00122 //  int8u i; 
00123 //  i = I2C_MEMS_Read(mems_data);   
00124 //  return i;
00125 //}
00126 
00127 
00128 /* Private Functions ---------------------------------------------------------*/
00129 
00130 /*******************************************************************************
00131 * Function Name  : I2C_Send_Frame
00132 * Description    : It sends I2C frame 
00133 * Input          : DeviceAddress is the destination device address
00134 *                  pBUffer is the buffer data
00135 *                  NoOfBytes is the number of bytes
00136 * Output         : None
00137 * Return         : 1 if the frame has been successfully sent, 0 otherwise.
00138 *******************************************************************************/
00139 static int8u I2C_Send_Frame (int8u DeviceAddress, int8u *pBuffer, int8u NoOfBytes)
00140 {
00141   int8u i, data;
00142 
00143   SC2_TWICTRL1 |= SC_TWISTART;   // send start
00144   WAIT_CMD_FIN();
00145   
00146   SEND_BYTE(DeviceAddress);   // send the address low byte
00147   WAIT_TX_FIN();
00148   
00149    // loop sending the data
00150   for (i=0; i<NoOfBytes; i++) {
00151     halInternalResetWatchDog();
00152     
00153     data = *(pBuffer+i);
00154         
00155     SEND_BYTE(data);
00156     
00157     WAIT_TX_FIN();
00158   }
00159 
00160   SC2_TWICTRL1 |= SC_TWISTOP;
00161   WAIT_CMD_FIN();
00162   
00163   return SUCCESS;
00164 }/* end I2C_Send_Frame() */
00165 
00166 /*******************************************************************************
00167 * Function Name  : I2C_Receive_Frame
00168 * Description    : It receives an I2C frame and stores it in pBUffer parameter
00169 * Input          : slave_addr is the slave address
00170 *                  reg_addr is the register address
00171 *                  NoOfBytes is the numenr of bytes to read starting from reg_addr
00172 * Output         : I2C frame in pBUffer
00173 * Return         : 1 if the frame has been successfully received, 0 otherwise.
00174 *******************************************************************************/
00175 static int8u I2C_Receive_Frame (int8u slave_addr, int8u reg_addr, int8u *pBuffer, int8u NoOfBytes)
00176 {
00177   int8u i, addr = reg_addr;
00178   
00179   if (NoOfBytes > 1)
00180     addr += REPETIR;
00181   
00182   SC2_TWICTRL1 |= SC_TWISTART;   // send start
00183   WAIT_CMD_FIN();
00184    
00185   SEND_BYTE(slave_addr | 0x00);      // send the address low byte
00186   WAIT_TX_FIN();
00187   
00188   SEND_BYTE(addr);
00189   WAIT_TX_FIN();
00190 
00191   SC2_TWICTRL1 |= SC_TWISTART;     // send start
00192   WAIT_CMD_FIN();
00193   
00194   SEND_BYTE(slave_addr | 0x01);      // send the address low byte
00195   WAIT_TX_FIN();
00196  
00197   // loop receiving the data
00198   for (i=0;i<NoOfBytes;i++){
00199     halInternalResetWatchDog();
00200 
00201     if (i < (NoOfBytes - 1))
00202       SC2_TWICTRL2 |= SC_TWIACK;   // ack on receipt of data
00203     else
00204       SC2_TWICTRL2 &= ~SC_TWIACK;  // don't ack if last one
00205 
00206     SC2_TWICTRL1 |= SC_TWIRECV;    // set to receive
00207     WAIT_RX_FIN();
00208     *(pBuffer+i) = SC2_DATA;       // receive data
00209   }
00210 
00211   SC2_TWICTRL1 |= SC_TWISTOP;      // send STOP
00212   WAIT_CMD_FIN();  
00213 
00214   return SUCCESS;
00215 }/* end I2C_Receive_Frame() */
00216 
00217 
00218 /*******************************************************************************
00219 * Function Name  : i2c_write_reg
00220 * Description    : It writes a register on the I2C target
00221 * Input          : slave addr is the I2C target device
00222 *                  reg_addr is the address of the register to be written
00223 *                  reg_value is the value of the register to be written
00224 * Output         : None
00225 * Return         : 1 if the register has been successfully written, 0 otherwise.
00226 *******************************************************************************/
00227 int8u i2c_write_reg (int8u slave_addr, int8u reg_addr, int8u reg_value)
00228 {
00229   int8u i2c_buffer[2];
00230   
00231   i2c_buffer[0] = reg_addr;
00232   i2c_buffer[1] = reg_value;
00233 
00234   return I2C_Send_Frame (slave_addr, i2c_buffer, 2);
00235 }/* end i2c_write_reg() */
00236 
00237 /*******************************************************************************
00238 * Function Name  : i2c_read_reg
00239 * Description    : It reads  a register on the I2C target
00240 * Input          : slave addr is the I2C target device
00241 *                  reg_addr is the address of the register to be read
00242 *                  pBuffer is the storage destination for the read data
00243 *                  NoOfBytes is the amount of data to read
00244 * Output         : I2C frame
00245 * Return         : 1 if the register has been successfully read, 0 otherwise.
00246 *******************************************************************************/
00247 int8u i2c_read_reg (int8u slave_addr, int8u reg_addr, int8u *pBuffer, int8u NoOfBytes)
00248 {
00249   return I2C_Receive_Frame (slave_addr, reg_addr, pBuffer, NoOfBytes);
00250 }/* end i2c_read_reg() */
00251 
00252 /*******************************************************************************
00253 * Function Name  : I2C_MEMS_Init
00254 * Description    : It performs basic MEMS register writes for initialization 
00255 *                  purposes
00256 * Input          : None
00257 * Output         : None
00258 * Return         : 1 if the device has been successfully initialized, 0 otherwise.
00259 *******************************************************************************/
00260 static int8u I2C_MEMS_Init (void)
00261 {
00262   int8u i = 0;
00263 
00264   i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, STATUS_REG, 0x00);    //no flag
00265   i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, FF_WU_CFG, 0x00);     // all off
00266   i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, DD_CFG, 0x00);        // all off
00267   //i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, (1<<4) | (1<<1) | (1 << 0));
00268   
00269   i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, 0x00);
00270   //i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0xC7);
00271   i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0x87);  
00272 
00273   if (i != 5)
00274     return 0;
00275 
00276   return 1;
00277 }/* end I2C_MEMS_Init() */
00278 
00279 /*******************************************************************************
00280 * Function Name  : I2C_MEMS_On
00281 * Description    : It turn on the device. 
00282 * Input          : None
00283 * Output         : None
00284 * Return         : 1 if the device has been successfully set to normal mode, 0 otherwise.
00285 *******************************************************************************/
00286 int8u MEMS_On (void)
00287 {
00288   return i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0xC7);  
00289 }
00290 
00291 /*******************************************************************************
00292 * Function Name  : I2C_MEMS_Off
00293 * Description    : It turn off the device. 
00294 * Input          : None
00295 * Output         : None
00296 * Return         : 1 if the device has been successfully set to power-down mode, 0 otherwise.
00297 *******************************************************************************/
00298 int8u MEMS_Off (void)
00299 {
00300   return i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0x87);  
00301 }
00302 
00303 /*******************************************************************************
00304 * Function Name  : I2C_MEMS_SetFullScale
00305 * Description    : It sets the full-scale range of the device.
00306 * Input          : range  HIGH for high scale selection, LOW for low range.
00307 * Output         : None
00308 * Return         : 1 if the device has been successfully set to full scale mode, 0 otherwise.
00309 *******************************************************************************/
00310 int8u MEMS_SetFullScale (boolean range)
00311 {
00312   int8u i2c_buffer;
00313   
00314   if(!i2c_read_reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, &i2c_buffer, 1))
00315     return 0;
00316   
00317   if(range==MEMS_HIGH_RANGE){
00318     i2c_buffer |= 0x20;
00319   }
00320   else {
00321     i2c_buffer &= ~0x20;
00322   }
00323 
00324   if(!i2c_write_reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, i2c_buffer))
00325     return 0;
00326   
00327   fullscale_state = range;
00328   
00329   return 1;
00330   
00331 }
00332 
00333 /*******************************************************************************
00334 * Function Name  : I2C_MEMS_GetFullScale
00335 * Description    : It get the full-scale range of the device. 
00336 * Input          : None
00337 * Output         : None
00338 * Return         : range  HIGH for high scale selection, LOW for low range.
00339 *******************************************************************************/
00340 boolean MEMS_GetFullScale (void)
00341 {  
00342   return fullscale_state;  
00343 }
00344 
00345 /*******************************************************************************
00346 * Function Name  : I2C_MEMS_Read
00347 * Description    : It reads 3 axes acceleration data from mems
00348 * Input          : None
00349 * Output         : mems_data
00350 * Return         : 1 if acceleration data has been successfully read, 0 otherwise
00351 *******************************************************************************/
00352 //static int8u I2C_MEMS_Read (t_mems_data *mems_data)
00353 //{
00354 //  int8u i, i2c_buffer[8];
00355 //
00356 //  i = i2c_read_reg (kLIS3L02DQ_SLAVE_ADDR, OUTX_L, i2c_buffer, 8);  
00357 //
00358 //  mems_data->outx_h = i2c_buffer[0];
00359 //  mems_data->outx_l = i2c_buffer[1];
00360 //  mems_data->outy_h = i2c_buffer[2];
00361 //  mems_data->outy_l = i2c_buffer[3];
00362 //  mems_data->outz_h = i2c_buffer[4];
00363 //  mems_data->outz_l = i2c_buffer[5];
00364 //
00365 //  return i;
00366 //}/* end I2C_MEMS_Read() */
00367 
00368 /******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

Generated on Mon Apr 11 14:23:40 2011 for Contiki 2.5 by  doxygen 1.6.1