Contiki 2.5
mems.c
1 /******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
2 * File Name : hal_led.c
3 * Author : MCD Application Team
4 * Version : V1.0
5 * Date : September 2009
6 * Description : Driver for leds management on STM32W108 MB851 board
7 ********************************************************************************
8 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
9 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
10 * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
11 * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
12 * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
13 * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
14 *******************************************************************************/
15 
16 /* Includes ------------------------------------------------------------------*/
17 
18 #include PLATFORM_HEADER
19 #include "mems.h"
20 #include "timer.h"
21 
22 /* Private define -- ---------------------------------------------------------*/
23 
24 #define TIMEOUT 20000
25 
26 #define SUCCESS 1
27 #define FAIL 0
28 
29 #define SEND_BYTE(data) do{ SC2_DATA=(data); SC2_TWICTRL1 |= SC_TWISEND; }while(0)
30 
31 #define WAIT_CMD_FIN() { \
32  struct timer t; \
33  timer_set(&t, CLOCK_SECOND/100); \
34  while((SC2_TWISTAT&SC_TWICMDFIN)!=SC_TWICMDFIN){ \
35  if(timer_expired(&t)){ \
36  return FAIL; \
37  } \
38  } \
39  }
40 
41 #define WAIT_TX_FIN() { \
42  struct timer t; \
43  timer_set(&t, CLOCK_SECOND/100); \
44  while((SC2_TWISTAT&SC_TWITXFIN)!=SC_TWITXFIN){ \
45  if(timer_expired(&t)){ \
46  return FAIL; \
47  } \
48  } \
49  }
50 #define WAIT_RX_FIN() { \
51  struct timer t; \
52  timer_set(&t, CLOCK_SECOND/100); \
53  while((SC2_TWISTAT&SC_TWIRXFIN)!=SC_TWIRXFIN){ \
54  if(timer_expired(&t)){ \
55  return FAIL; \
56  } \
57  } \
58  }
59 
60 /* Private variables ---------------------------------------------------------*/
61 static boolean fullscale_state;
62 
63 /* Private functions ---------------------------------------------------------*/
64 static int8u I2C_MEMS_Init (void);
65 //extern void halInternalResetWatchDog(void);
66 static int8u I2C_Send_Frame (int8u DeviceAddress, int8u *pBuffer, int8u NoOfBytes);
67 int8u i2c_write_reg (int8u slave_addr, int8u reg_addr, int8u reg_value);
68 //static int8u I2C_MEMS_Read (t_mems_data *mems_data);
69 
70 /* Functions -----------------------------------------------------------------*/
71 
72 /*******************************************************************************
73 * Function Name : Mems_Init
74 * Description : It inits mems
75 * Input : None
76 * Output : status
77 * Return : None
78 *******************************************************************************/
79 int8u Mems_Init(void)
80 {
81  int8u ret = 0;
82 
83  // GPIO assignments
84  // PA1: SC2SDA (Serial Data)
85  // PA2: SC2SCL (Serial Clock)
86 
87  //-----SC2 I2C Master GPIO configuration
88 
89  TIM2_CCER &= 0xFFFFEEEE;
90  SC2_MODE = SC2_MODE_I2C;
91  GPIO_PACFGL &= 0xFFFFF00F;
92  GPIO_PACFGL |= 0x00000DD0;
93 
94  SC2_RATELIN = 14; // generates standard 100kbps or 400kbps
95  SC2_RATEEXP = 1; // 3 yields 100kbps; 1 yields 400kbps
96  SC2_TWICTRL1 = 0; // start from a clean state
97  SC2_TWICTRL2 = 0; // start from a clean state
98 
99  ret = I2C_MEMS_Init();
100 
101  fullscale_state = MEMS_LOW_RANGE;
102 
103 //Add later if really needed
104 #ifdef ST_DBG
105  if (!ret)
106  I2C_DeInit(MEMS_I2C);
107 #endif
108 
109  return ret;
110 }/* end Mems_Init */
111 
112 /*******************************************************************************
113 * Function Name : Mems_GetValue
114 * Description : It returns the 3 mems acceleration values related to x,y,z
115 * axes in mems_data
116 * Input : mems_data
117 * Output : status
118 * Return : None
119 *******************************************************************************/
120 //int8u Mems_GetValue(t_mems_data *mems_data)
121 //{
122 // int8u i;
123 // i = I2C_MEMS_Read(mems_data);
124 // return i;
125 //}
126 
127 
128 /* Private Functions ---------------------------------------------------------*/
129 
130 /*******************************************************************************
131 * Function Name : I2C_Send_Frame
132 * Description : It sends I2C frame
133 * Input : DeviceAddress is the destination device address
134 * pBUffer is the buffer data
135 * NoOfBytes is the number of bytes
136 * Output : None
137 * Return : 1 if the frame has been successfully sent, 0 otherwise.
138 *******************************************************************************/
139 static int8u I2C_Send_Frame (int8u DeviceAddress, int8u *pBuffer, int8u NoOfBytes)
140 {
141  int8u i, data;
142 
143  SC2_TWICTRL1 |= SC_TWISTART; // send start
144  WAIT_CMD_FIN();
145 
146  SEND_BYTE(DeviceAddress); // send the address low byte
147  WAIT_TX_FIN();
148 
149  // loop sending the data
150  for (i=0; i<NoOfBytes; i++) {
152 
153  data = *(pBuffer+i);
154 
155  SEND_BYTE(data);
156 
157  WAIT_TX_FIN();
158  }
159 
160  SC2_TWICTRL1 |= SC_TWISTOP;
161  WAIT_CMD_FIN();
162 
163  return SUCCESS;
164 }/* end I2C_Send_Frame() */
165 
166 /*******************************************************************************
167 * Function Name : I2C_Receive_Frame
168 * Description : It receives an I2C frame and stores it in pBUffer parameter
169 * Input : slave_addr is the slave address
170 * reg_addr is the register address
171 * NoOfBytes is the numenr of bytes to read starting from reg_addr
172 * Output : I2C frame in pBUffer
173 * Return : 1 if the frame has been successfully received, 0 otherwise.
174 *******************************************************************************/
175 static int8u I2C_Receive_Frame (int8u slave_addr, int8u reg_addr, int8u *pBuffer, int8u NoOfBytes)
176 {
177  int8u i, addr = reg_addr;
178 
179  if (NoOfBytes > 1)
180  addr += REPETIR;
181 
182  SC2_TWICTRL1 |= SC_TWISTART; // send start
183  WAIT_CMD_FIN();
184 
185  SEND_BYTE(slave_addr | 0x00); // send the address low byte
186  WAIT_TX_FIN();
187 
188  SEND_BYTE(addr);
189  WAIT_TX_FIN();
190 
191  SC2_TWICTRL1 |= SC_TWISTART; // send start
192  WAIT_CMD_FIN();
193 
194  SEND_BYTE(slave_addr | 0x01); // send the address low byte
195  WAIT_TX_FIN();
196 
197  // loop receiving the data
198  for (i=0;i<NoOfBytes;i++){
200 
201  if (i < (NoOfBytes - 1))
202  SC2_TWICTRL2 |= SC_TWIACK; // ack on receipt of data
203  else
204  SC2_TWICTRL2 &= ~SC_TWIACK; // don't ack if last one
205 
206  SC2_TWICTRL1 |= SC_TWIRECV; // set to receive
207  WAIT_RX_FIN();
208  *(pBuffer+i) = SC2_DATA; // receive data
209  }
210 
211  SC2_TWICTRL1 |= SC_TWISTOP; // send STOP
212  WAIT_CMD_FIN();
213 
214  return SUCCESS;
215 }/* end I2C_Receive_Frame() */
216 
217 
218 /*******************************************************************************
219 * Function Name : i2c_write_reg
220 * Description : It writes a register on the I2C target
221 * Input : slave addr is the I2C target device
222 * reg_addr is the address of the register to be written
223 * reg_value is the value of the register to be written
224 * Output : None
225 * Return : 1 if the register has been successfully written, 0 otherwise.
226 *******************************************************************************/
227 int8u i2c_write_reg (int8u slave_addr, int8u reg_addr, int8u reg_value)
228 {
229  int8u i2c_buffer[2];
230 
231  i2c_buffer[0] = reg_addr;
232  i2c_buffer[1] = reg_value;
233 
234  return I2C_Send_Frame (slave_addr, i2c_buffer, 2);
235 }/* end i2c_write_reg() */
236 
237 /*******************************************************************************
238 * Function Name : i2c_read_reg
239 * Description : It reads a register on the I2C target
240 * Input : slave addr is the I2C target device
241 * reg_addr is the address of the register to be read
242 * pBuffer is the storage destination for the read data
243 * NoOfBytes is the amount of data to read
244 * Output : I2C frame
245 * Return : 1 if the register has been successfully read, 0 otherwise.
246 *******************************************************************************/
247 int8u i2c_read_reg (int8u slave_addr, int8u reg_addr, int8u *pBuffer, int8u NoOfBytes)
248 {
249  return I2C_Receive_Frame (slave_addr, reg_addr, pBuffer, NoOfBytes);
250 }/* end i2c_read_reg() */
251 
252 /*******************************************************************************
253 * Function Name : I2C_MEMS_Init
254 * Description : It performs basic MEMS register writes for initialization
255 * purposes
256 * Input : None
257 * Output : None
258 * Return : 1 if the device has been successfully initialized, 0 otherwise.
259 *******************************************************************************/
260 static int8u I2C_MEMS_Init (void)
261 {
262  int8u i = 0;
263 
264  i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, STATUS_REG, 0x00); //no flag
265  i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, FF_WU_CFG, 0x00); // all off
266  i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, DD_CFG, 0x00); // all off
267  //i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, (1<<4) | (1<<1) | (1 << 0));
268 
269  i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, 0x00);
270  //i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0xC7);
271  i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0x87);
272 
273  if (i != 5)
274  return 0;
275 
276  return 1;
277 }/* end I2C_MEMS_Init() */
278 
279 /*******************************************************************************
280 * Function Name : I2C_MEMS_On
281 * Description : It turn on the device.
282 * Input : None
283 * Output : None
284 * Return : 1 if the device has been successfully set to normal mode, 0 otherwise.
285 *******************************************************************************/
286 int8u MEMS_On (void)
287 {
288  return i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0xC7);
289 }
290 
291 /*******************************************************************************
292 * Function Name : I2C_MEMS_Off
293 * Description : It turn off the device.
294 * Input : None
295 * Output : None
296 * Return : 1 if the device has been successfully set to power-down mode, 0 otherwise.
297 *******************************************************************************/
298 int8u MEMS_Off (void)
299 {
300  return i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0x87);
301 }
302 
303 /*******************************************************************************
304 * Function Name : I2C_MEMS_SetFullScale
305 * Description : It sets the full-scale range of the device.
306 * Input : range HIGH for high scale selection, LOW for low range.
307 * Output : None
308 * Return : 1 if the device has been successfully set to full scale mode, 0 otherwise.
309 *******************************************************************************/
310 int8u MEMS_SetFullScale (boolean range)
311 {
312  int8u i2c_buffer;
313 
314  if(!i2c_read_reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, &i2c_buffer, 1))
315  return 0;
316 
317  if(range==MEMS_HIGH_RANGE){
318  i2c_buffer |= 0x20;
319  }
320  else {
321  i2c_buffer &= ~0x20;
322  }
323 
324  if(!i2c_write_reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, i2c_buffer))
325  return 0;
326 
327  fullscale_state = range;
328 
329  return 1;
330 
331 }
332 
333 /*******************************************************************************
334 * Function Name : I2C_MEMS_GetFullScale
335 * Description : It get the full-scale range of the device.
336 * Input : None
337 * Output : None
338 * Return : range HIGH for high scale selection, LOW for low range.
339 *******************************************************************************/
340 boolean MEMS_GetFullScale (void)
341 {
342  return fullscale_state;
343 }
344 
345 /*******************************************************************************
346 * Function Name : I2C_MEMS_Read
347 * Description : It reads 3 axes acceleration data from mems
348 * Input : None
349 * Output : mems_data
350 * Return : 1 if acceleration data has been successfully read, 0 otherwise
351 *******************************************************************************/
352 //static int8u I2C_MEMS_Read (t_mems_data *mems_data)
353 //{
354 // int8u i, i2c_buffer[8];
355 //
356 // i = i2c_read_reg (kLIS3L02DQ_SLAVE_ADDR, OUTX_L, i2c_buffer, 8);
357 //
358 // mems_data->outx_h = i2c_buffer[0];
359 // mems_data->outx_l = i2c_buffer[1];
360 // mems_data->outy_h = i2c_buffer[2];
361 // mems_data->outy_l = i2c_buffer[3];
362 // mems_data->outz_h = i2c_buffer[4];
363 // mems_data->outz_l = i2c_buffer[5];
364 //
365 // return i;
366 //}/* end I2C_MEMS_Read() */
367 
368 /******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/