Contiki 2.6

mems.c

00001 /** @file mems.c
00002  * @brief MB851 MEMS drivers
00003  *
00004  *
00005  * <!--(C) COPYRIGHT 2010 STMicroelectronics. All rights reserved.        -->
00006  */
00007 #include PLATFORM_HEADER
00008 #include "hal/hal.h"
00009 #include "hal/error.h"
00010 #include "hal/micro/mems.h"
00011 
00012 #define TIMEOUT 20000
00013 
00014 #define SUCCESS 1
00015 
00016 #define SEND_BYTE(data) do{ SC2_DATA=(data); SC2_TWICTRL1 |= SC_TWISEND; }while(0)
00017 
00018 #define WAIT_CMD_FIN()  do{}while((SC2_TWISTAT&SC_TWICMDFIN)!=SC_TWICMDFIN)
00019 #define WAIT_TX_FIN()   do{}while((SC2_TWISTAT&SC_TWITXFIN)!=SC_TWITXFIN)
00020 #define WAIT_RX_FIN()   do{}while((SC2_TWISTAT&SC_TWIRXFIN)!=SC_TWIRXFIN)
00021 
00022 static int8u i2c_MEMS_Init (void);
00023 static int8u i2c_MEMS_Read (t_mems_data *mems_data);
00024 //extern void halInternalResetWatchDog(void);
00025 static int8u i2c_Send_Frame (int8u DeviceAddress, int8u *pBuffer, int8u NoOfBytes);
00026 static int8u i2c_Send_Frame (int8u DeviceAddress, int8u *pBuffer, int8u NoOfBytes);
00027 int8u i2c_write_reg (int8u slave_addr, int8u reg_addr, int8u reg_value);
00028 static int8u i2c_MEMS_Init (void);
00029 static int8u i2c_MEMS_Read (t_mems_data *mems_data);
00030 
00031 /* Functions -----------------------------------------------------------------*/
00032 int8u mems_Init(void)
00033 {  
00034   int8u ret = 0;
00035   
00036   // GPIO assignments
00037   // PA1: SC2SDA (Serial Data)
00038   // PA2: SC2SCL (Serial Clock)
00039 
00040   //-----SC2 I2C Master GPIO configuration
00041 
00042   TIM2_CCER &= 0xFFFFEEEE;
00043   SC2_MODE =  SC2_MODE_I2C;
00044   GPIO_PACFGL &= 0xFFFFF00F;
00045   GPIO_PACFGL |= 0x00000DD0;
00046   
00047   SC2_RATELIN =  14;   // generates standard 100kbps or 400kbps
00048   SC2_RATEEXP =  1;    // 3 yields 100kbps; 1 yields 400kbps
00049   SC2_TWICTRL1 =  0;   // start from a clean state
00050   SC2_TWICTRL2 =  0;   // start from a clean state  
00051   
00052   ret = i2c_MEMS_Init();
00053 
00054 //Add later if really needed  
00055 #ifdef ST_DBG  
00056   if (!ret)
00057    i2c_DeInit(MEMS_I2C);
00058 #endif
00059   
00060   return ret;
00061 }/* end mems_Init */
00062 
00063 int8u mems_GetValue(t_mems_data *mems_data)
00064 {
00065   int8u i; 
00066   i = i2c_MEMS_Read(mems_data);   
00067   return i;
00068 }/* end mems_GetValue() */
00069 
00070 
00071 /* Private Functions ---------------------------------------------------------*/
00072 
00073 /*******************************************************************************
00074 * Function Name  : i2c_Send_Frame
00075 * Description    : It sends I2C frame 
00076 * Input          : DeviceAddress is the destination device address
00077 *                  pBUffer is the buffer data
00078 *                  NoOfBytes is the number of bytes
00079 * Output         : None
00080 * Return         : status
00081 *******************************************************************************/
00082 static int8u i2c_Send_Frame (int8u DeviceAddress, int8u *pBuffer, int8u NoOfBytes)
00083 {
00084   int8u i, data;
00085 
00086   SC2_TWICTRL1 |= SC_TWISTART;   // send start
00087   WAIT_CMD_FIN();
00088   
00089   SEND_BYTE(DeviceAddress);   // send the address low byte
00090   WAIT_TX_FIN();
00091   
00092    // loop sending the data
00093   for (i=0; i<NoOfBytes; i++) {
00094     halInternalResetWatchDog();
00095     
00096     data = *(pBuffer+i);
00097         
00098     SEND_BYTE(data);
00099     
00100     WAIT_TX_FIN();
00101   }
00102 
00103   SC2_TWICTRL1 |= SC_TWISTOP;
00104   WAIT_CMD_FIN();
00105   
00106   return SUCCESS;
00107 }/* end i2c_Send_Frame() */
00108 
00109 /*******************************************************************************
00110 * Function Name  : i2c_Receive_Frame
00111 * Description    : It receives an I2C frame and stores it in pBUffer parameter
00112 * Input          : slave_addr is the slave address
00113 *                  reg_addr is the register address
00114 *                  NoOfBytes is the numenr of bytes to read starting from reg_addr
00115 * Output         : buffer
00116 * Return         : status
00117 *******************************************************************************/
00118 static int8u i2c_Receive_Frame (int8u slave_addr, int8u reg_addr, int8u *pBuffer, int8u NoOfBytes)
00119 {
00120   int8u i, addr = reg_addr;
00121   
00122   if (NoOfBytes > 1)
00123     addr += REPETIR;
00124   
00125   SC2_TWICTRL1 |= SC_TWISTART;   // send start
00126   WAIT_CMD_FIN();
00127    
00128   SEND_BYTE(slave_addr | 0x00);      // send the address low byte
00129   WAIT_TX_FIN();
00130   
00131   SEND_BYTE(addr);
00132   WAIT_TX_FIN();
00133 
00134   SC2_TWICTRL1 |= SC_TWISTART;     // send start
00135   WAIT_CMD_FIN();
00136   
00137   SEND_BYTE(slave_addr | 0x01);      // send the address low byte
00138   WAIT_TX_FIN();
00139  
00140   // loop receiving the data
00141   for (i=0;i<NoOfBytes;i++){
00142     halInternalResetWatchDog();
00143 
00144     if (i < (NoOfBytes - 1))
00145       SC2_TWICTRL2 |= SC_TWIACK;   // ack on receipt of data
00146     else
00147       SC2_TWICTRL2 &= ~SC_TWIACK;  // don't ack if last one
00148 
00149     SC2_TWICTRL1 |= SC_TWIRECV;    // set to receive
00150     WAIT_RX_FIN();
00151     *(pBuffer+i) = SC2_DATA;       // receive data
00152   }
00153 
00154   SC2_TWICTRL1 |= SC_TWISTOP;      // send STOP
00155   WAIT_CMD_FIN();  
00156 
00157   return SUCCESS;
00158 }/* end i2c_Receive_Frame() */
00159 
00160 
00161 /*******************************************************************************
00162 * Function Name  : i2c_write_reg
00163 * Description    : It writes a register on the I2C target
00164 * Input          : slave addr is the I2C target device
00165 *                  reg_addr is the address of the register to be written
00166 *                  reg_value is the value of the register to be written
00167 *                  NoOfBytes is the numenr of bytes to read starting from reg_addr
00168 * Output         : None
00169 * Return         : I2C frame
00170 *******************************************************************************/
00171 int8u i2c_write_reg (int8u slave_addr, int8u reg_addr, int8u reg_value)
00172 {
00173   int8u i2c_buffer[2];
00174   
00175   i2c_buffer[0] = reg_addr;
00176   i2c_buffer[1] = reg_value;
00177 
00178   return i2c_Send_Frame (slave_addr, i2c_buffer, 2);
00179 }/* end i2c_write_reg() */
00180 
00181 /*******************************************************************************
00182 * Function Name  : i2c_read_reg
00183 * Description    : It reads  a register on the I2C target
00184 * Input          : slave addr is the I2C target device
00185 *                  reg_addr is the address of the register to be read
00186 *                  pBuffer is the storage destination for the read data
00187 *                  NoOfBytes is the amount of data to read
00188 * Output         : None
00189 * Return         : I2C frame
00190 *******************************************************************************/
00191 int8u i2c_read_reg (int8u slave_addr, int8u reg_addr, int8u *pBuffer, int8u NoOfBytes)
00192 {
00193   return i2c_Receive_Frame (slave_addr, reg_addr, pBuffer, NoOfBytes);
00194 }/* end i2c_read_reg() */
00195 
00196 /*******************************************************************************
00197 * Function Name  : i2c_MEMS_Init
00198 * Description    : It performs basic MEMS register writes for initialization 
00199 *                  purposes
00200 * Input          : None
00201 * Output         : None
00202 * Return         : status
00203 *******************************************************************************/
00204 static int8u i2c_MEMS_Init (void)
00205 {
00206   int8u i = 0;
00207 
00208   i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, STATUS_REG, 0x00);    //no flag
00209   i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, FF_WU_CFG, 0x00);     // all off
00210   i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, DD_CFG, 0x00);        // all off
00211   i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, (0<<4) | (0<<1) | (0 << 0));
00212   i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0x47);
00213 
00214   if (i != 5)
00215     return 0;
00216 
00217   return 1;
00218 }/* end i2c_MEMS_Init() */
00219 
00220 /*******************************************************************************
00221 * Function Name  : i2c_MEMS_Read
00222 * Description    : It reads 3 axes acceleration data from mems
00223 * Input          : None
00224 * Output         : mems_data
00225 * Return         : I2C frame
00226 *******************************************************************************/
00227 static int8u i2c_MEMS_Read (t_mems_data *mems_data)
00228 {
00229   int8u i, i2c_buffer[8];
00230 
00231   /* Wait for new set of data to be available */
00232   while (1) {
00233     i = i2c_read_reg (kLIS3L02DQ_SLAVE_ADDR, STATUS_REG, i2c_buffer, 1);
00234     if (i2c_buffer[0] & (1 << 3))
00235       break;
00236   }
00237   i = i2c_read_reg (kLIS3L02DQ_SLAVE_ADDR, OUTX_L, i2c_buffer, 8);  
00238 
00239   mems_data->outx_h = i2c_buffer[0];
00240   mems_data->outx_l = i2c_buffer[1];
00241   mems_data->outy_h = i2c_buffer[2];
00242   mems_data->outy_l = i2c_buffer[3];
00243   mems_data->outz_h = i2c_buffer[4];
00244   mems_data->outz_l = i2c_buffer[5];
00245 
00246   return i;
00247 }/* end i2c_MEMS_Read() */