Contiki 2.6
|
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() */