Contiki 2.5
mems.c
1 /** @file mems.c
2  * @brief MB851 MEMS drivers
3  *
4  *
5  * <!--(C) COPYRIGHT 2010 STMicroelectronics. All rights reserved. -->
6  */
7 #include PLATFORM_HEADER
8 #include "hal/hal.h"
9 #include "hal/error.h"
10 #include "hal/micro/mems.h"
11 
12 #define TIMEOUT 20000
13 
14 #define SUCCESS 1
15 
16 #define SEND_BYTE(data) do{ SC2_DATA=(data); SC2_TWICTRL1 |= SC_TWISEND; }while(0)
17 
18 #define WAIT_CMD_FIN() do{}while((SC2_TWISTAT&SC_TWICMDFIN)!=SC_TWICMDFIN)
19 #define WAIT_TX_FIN() do{}while((SC2_TWISTAT&SC_TWITXFIN)!=SC_TWITXFIN)
20 #define WAIT_RX_FIN() do{}while((SC2_TWISTAT&SC_TWIRXFIN)!=SC_TWIRXFIN)
21 
22 static int8u i2c_MEMS_Init (void);
23 static int8u i2c_MEMS_Read (t_mems_data *mems_data);
24 //extern void halInternalResetWatchDog(void);
25 static int8u i2c_Send_Frame (int8u DeviceAddress, int8u *pBuffer, int8u NoOfBytes);
26 static int8u i2c_Send_Frame (int8u DeviceAddress, int8u *pBuffer, int8u NoOfBytes);
27 int8u i2c_write_reg (int8u slave_addr, int8u reg_addr, int8u reg_value);
28 static int8u i2c_MEMS_Init (void);
29 static int8u i2c_MEMS_Read (t_mems_data *mems_data);
30 
31 /* Functions -----------------------------------------------------------------*/
32 int8u mems_Init(void)
33 {
34  int8u ret = 0;
35 
36  // GPIO assignments
37  // PA1: SC2SDA (Serial Data)
38  // PA2: SC2SCL (Serial Clock)
39 
40  //-----SC2 I2C Master GPIO configuration
41 
42  TIM2_CCER &= 0xFFFFEEEE;
43  SC2_MODE = SC2_MODE_I2C;
44  GPIO_PACFGL &= 0xFFFFF00F;
45  GPIO_PACFGL |= 0x00000DD0;
46 
47  SC2_RATELIN = 14; // generates standard 100kbps or 400kbps
48  SC2_RATEEXP = 1; // 3 yields 100kbps; 1 yields 400kbps
49  SC2_TWICTRL1 = 0; // start from a clean state
50  SC2_TWICTRL2 = 0; // start from a clean state
51 
52  ret = i2c_MEMS_Init();
53 
54 //Add later if really needed
55 #ifdef ST_DBG
56  if (!ret)
57  i2c_DeInit(MEMS_I2C);
58 #endif
59 
60  return ret;
61 }/* end mems_Init */
62 
63 int8u mems_GetValue(t_mems_data *mems_data)
64 {
65  int8u i;
66  i = i2c_MEMS_Read(mems_data);
67  return i;
68 }/* end mems_GetValue() */
69 
70 
71 /* Private Functions ---------------------------------------------------------*/
72 
73 /*******************************************************************************
74 * Function Name : i2c_Send_Frame
75 * Description : It sends I2C frame
76 * Input : DeviceAddress is the destination device address
77 * pBUffer is the buffer data
78 * NoOfBytes is the number of bytes
79 * Output : None
80 * Return : status
81 *******************************************************************************/
82 static int8u i2c_Send_Frame (int8u DeviceAddress, int8u *pBuffer, int8u NoOfBytes)
83 {
84  int8u i, data;
85 
86  SC2_TWICTRL1 |= SC_TWISTART; // send start
87  WAIT_CMD_FIN();
88 
89  SEND_BYTE(DeviceAddress); // send the address low byte
90  WAIT_TX_FIN();
91 
92  // loop sending the data
93  for (i=0; i<NoOfBytes; i++) {
95 
96  data = *(pBuffer+i);
97 
98  SEND_BYTE(data);
99 
100  WAIT_TX_FIN();
101  }
102 
103  SC2_TWICTRL1 |= SC_TWISTOP;
104  WAIT_CMD_FIN();
105 
106  return SUCCESS;
107 }/* end i2c_Send_Frame() */
108 
109 /*******************************************************************************
110 * Function Name : i2c_Receive_Frame
111 * Description : It receives an I2C frame and stores it in pBUffer parameter
112 * Input : slave_addr is the slave address
113 * reg_addr is the register address
114 * NoOfBytes is the numenr of bytes to read starting from reg_addr
115 * Output : buffer
116 * Return : status
117 *******************************************************************************/
118 static int8u i2c_Receive_Frame (int8u slave_addr, int8u reg_addr, int8u *pBuffer, int8u NoOfBytes)
119 {
120  int8u i, addr = reg_addr;
121 
122  if (NoOfBytes > 1)
123  addr += REPETIR;
124 
125  SC2_TWICTRL1 |= SC_TWISTART; // send start
126  WAIT_CMD_FIN();
127 
128  SEND_BYTE(slave_addr | 0x00); // send the address low byte
129  WAIT_TX_FIN();
130 
131  SEND_BYTE(addr);
132  WAIT_TX_FIN();
133 
134  SC2_TWICTRL1 |= SC_TWISTART; // send start
135  WAIT_CMD_FIN();
136 
137  SEND_BYTE(slave_addr | 0x01); // send the address low byte
138  WAIT_TX_FIN();
139 
140  // loop receiving the data
141  for (i=0;i<NoOfBytes;i++){
143 
144  if (i < (NoOfBytes - 1))
145  SC2_TWICTRL2 |= SC_TWIACK; // ack on receipt of data
146  else
147  SC2_TWICTRL2 &= ~SC_TWIACK; // don't ack if last one
148 
149  SC2_TWICTRL1 |= SC_TWIRECV; // set to receive
150  WAIT_RX_FIN();
151  *(pBuffer+i) = SC2_DATA; // receive data
152  }
153 
154  SC2_TWICTRL1 |= SC_TWISTOP; // send STOP
155  WAIT_CMD_FIN();
156 
157  return SUCCESS;
158 }/* end i2c_Receive_Frame() */
159 
160 
161 /*******************************************************************************
162 * Function Name : i2c_write_reg
163 * Description : It writes a register on the I2C target
164 * Input : slave addr is the I2C target device
165 * reg_addr is the address of the register to be written
166 * reg_value is the value of the register to be written
167 * NoOfBytes is the numenr of bytes to read starting from reg_addr
168 * Output : None
169 * Return : I2C frame
170 *******************************************************************************/
171 int8u i2c_write_reg (int8u slave_addr, int8u reg_addr, int8u reg_value)
172 {
173  int8u i2c_buffer[2];
174 
175  i2c_buffer[0] = reg_addr;
176  i2c_buffer[1] = reg_value;
177 
178  return i2c_Send_Frame (slave_addr, i2c_buffer, 2);
179 }/* end i2c_write_reg() */
180 
181 /*******************************************************************************
182 * Function Name : i2c_read_reg
183 * Description : It reads a register on the I2C target
184 * Input : slave addr is the I2C target device
185 * reg_addr is the address of the register to be read
186 * pBuffer is the storage destination for the read data
187 * NoOfBytes is the amount of data to read
188 * Output : None
189 * Return : I2C frame
190 *******************************************************************************/
191 int8u i2c_read_reg (int8u slave_addr, int8u reg_addr, int8u *pBuffer, int8u NoOfBytes)
192 {
193  return i2c_Receive_Frame (slave_addr, reg_addr, pBuffer, NoOfBytes);
194 }/* end i2c_read_reg() */
195 
196 /*******************************************************************************
197 * Function Name : i2c_MEMS_Init
198 * Description : It performs basic MEMS register writes for initialization
199 * purposes
200 * Input : None
201 * Output : None
202 * Return : status
203 *******************************************************************************/
204 static int8u i2c_MEMS_Init (void)
205 {
206  int8u i = 0;
207 
208  i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, STATUS_REG, 0x00); //no flag
209  i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, FF_WU_CFG, 0x00); // all off
210  i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, DD_CFG, 0x00); // all off
211  i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, (0<<4) | (0<<1) | (0 << 0));
212  i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0x47);
213 
214  if (i != 5)
215  return 0;
216 
217  return 1;
218 }/* end i2c_MEMS_Init() */
219 
220 /*******************************************************************************
221 * Function Name : i2c_MEMS_Read
222 * Description : It reads 3 axes acceleration data from mems
223 * Input : None
224 * Output : mems_data
225 * Return : I2C frame
226 *******************************************************************************/
227 static int8u i2c_MEMS_Read (t_mems_data *mems_data)
228 {
229  int8u i, i2c_buffer[8];
230 
231  /* Wait for new set of data to be available */
232  while (1) {
233  i = i2c_read_reg (kLIS3L02DQ_SLAVE_ADDR, STATUS_REG, i2c_buffer, 1);
234  if (i2c_buffer[0] & (1 << 3))
235  break;
236  }
237  i = i2c_read_reg (kLIS3L02DQ_SLAVE_ADDR, OUTX_L, i2c_buffer, 8);
238 
239  mems_data->outx_h = i2c_buffer[0];
240  mems_data->outx_l = i2c_buffer[1];
241  mems_data->outy_h = i2c_buffer[2];
242  mems_data->outy_l = i2c_buffer[3];
243  mems_data->outz_h = i2c_buffer[4];
244  mems_data->outz_l = i2c_buffer[5];
245 
246  return i;
247 }/* end i2c_MEMS_Read() */