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****/