CircleOS  1
mems_spe.c
Go to the documentation of this file.
1 /****************** COPYRIGHT (C) 2007-2013 KEOLABS S.A.S. ********************/
19 /******************************************************************************/
20 
21 /* Includes ------------------------------------------------------------------*/
22 #include "circle.h"
23 
25 
26 /* Private define ------------------------------------------------------------*/
27 #define RDOUTXL 0xE8
28 #define WRCTRL_REG1 0x20
29 #define RDCTRL_REG1 0xA0
30 #define RDID 0x8F
31 #define DUMMY_BYTE 0xA5
32 #define HIGH 0x01
33 #define LOW 0x00
34 #define ACTIVE 0x00
35 #define STDBY 0x01
38 /* Private variables ---------------------------------------------------------*/
39 
40 
41 /* Private function prototypes -----------------------------------------------*/
42 
43 
44 /* Private functions ---------------------------------------------------------*/
45 
46 /*******************************************************************************
47 *
48 * MEMS_WakeUp
49 *
50 *******************************************************************************/
55 /******************************************************************************/
56 void MEMS_WakeUp( void )
57 {
58  u8 reg_val;
59 
60  /* read RDCTRL_REG1 */
61 
62  /* Chip Select low */
63  MEMS_ChipSelect( ACTIVE );
64 
65  /* Send "RDCTRL_REG1" instruction */
66  MEMS_SendByte( RDCTRL_REG1 );
67 
68  reg_val = MEMS_SendByte( DUMMY_BYTE );
69 
70  /* Chip Select high */
71  MEMS_ChipSelect( STDBY );
72 
73  /* SET P0:P1 to '11' */
74  /* 0xC0 to wake up and 0x30 for full speed frequency (640 Hz). */
75  reg_val = reg_val | 0xC0 | 0x30;
76 
77  /* Chip Select low */
78  MEMS_ChipSelect( ACTIVE );
79 
80  /* Send "WRCTRL_REG1" instruction */
81  MEMS_SendByte( WRCTRL_REG1 );
82  MEMS_SendByte( reg_val );
83 
84  /* Chip Select high */
85  MEMS_ChipSelect( STDBY );
86 }
87 
88 /*******************************************************************************
89 *
90 * MEMS_ReadOutXY
91 *
92 *******************************************************************************/
100 /******************************************************************************/
101 u32 MEMS_ReadOutXY( void )
102 {
103 
104  u8 OutXL;
105  u8 OutXH;
106  u8 OutYL;
107  u8 OutYH;
108  u8 OutZL;
109  u8 OutZH;
110 
111  /* Chip Select low */
112  MEMS_ChipSelect( ACTIVE );
113 
114  /* Send "RDOUTXL" instruction */
115  MEMS_SendByte( RDOUTXL );
116 
117  /* Read a byte */
118  OutXL = MEMS_SendByte( DUMMY_BYTE );
119 
120  /* Read a byte */
121  OutXH = MEMS_SendByte( DUMMY_BYTE );
122 
123  /* Read a byte */
124  OutYL = MEMS_SendByte( DUMMY_BYTE );
125 
126  /* Read a byte */
127  OutYH = MEMS_SendByte( DUMMY_BYTE );
128 
129  /* Read a byte */
130  OutZL = MEMS_SendByte( DUMMY_BYTE );
131 
132  /* Read a byte */
133  OutZH = MEMS_SendByte( DUMMY_BYTE );
134 
135  MEMS_Info.OutX = OutXL + ( OutXH << 8 );
136  MEMS_Info.OutY = OutYL + ( OutYH << 8 );
137  MEMS_Info.OutZ = OutZL + ( OutZH << 8 );
138 
139  /* Chip Select high */
140  MEMS_ChipSelect( STDBY );
141 
142  MEMS_Info.OutX_F4 += ( MEMS_Info.OutX - ( MEMS_Info.OutX_F4 >> 2 ) ); // Filter on 4 values.
143  MEMS_Info.OutY_F4 += ( MEMS_Info.OutY - ( MEMS_Info.OutY_F4 >> 2 ) ); // Filter on 4 values.
144  MEMS_Info.OutZ_F4 += ( MEMS_Info.OutZ - ( MEMS_Info.OutZ_F4 >> 2 ) ); // Filter on 4 values.
145 
146  MEMS_Info.OutX_F16 += ( MEMS_Info.OutX - ( MEMS_Info.OutX_F16 >> 4 ) ); // Filter on 16 values.
147  MEMS_Info.OutY_F16 += ( MEMS_Info.OutY - ( MEMS_Info.OutY_F16 >> 4 ) ); // Filter on 16 values.
148  MEMS_Info.OutZ_F16 += ( MEMS_Info.OutZ - ( MEMS_Info.OutZ_F16 >> 4 ) ); // Filter on 16 values.
149 
150  MEMS_Info.OutX_F64 += ( MEMS_Info.OutX - ( MEMS_Info.OutX_F64 >> 6 ) ); // Filter on 64 values.
151  MEMS_Info.OutY_F64 += ( MEMS_Info.OutY - ( MEMS_Info.OutY_F64 >> 6 ) ); // Filter on 64 values.
152  MEMS_Info.OutZ_F64 += ( MEMS_Info.OutZ - ( MEMS_Info.OutZ_F64 >> 6 ) ); // Filter on 64 values.
153 
154  MEMS_Info.OutX_F256 += ( MEMS_Info.OutX - ( MEMS_Info.OutX_F256 >> 8 ) ); // Filter on 256 values.
155  MEMS_Info.OutY_F256 += ( MEMS_Info.OutY - ( MEMS_Info.OutY_F256 >> 8 ) ); // Filter on 256 values.
156  MEMS_Info.OutZ_F256 += ( MEMS_Info.OutZ - ( MEMS_Info.OutZ_F256 >> 8 ) ); // Filter on 256 values.
157 
158  return ( MEMS_Info.OutX + ( MEMS_Info.OutY << 16 ) );
159 }
160 
161 /*******************************************************************************
162 *
163 * MEMS_ChipSelect
164 *
165 *******************************************************************************/
172 /******************************************************************************/
173 void MEMS_ChipSelect( u8 State )
174 {
175  /* Set High or low the chip select line */
176  GPIO_WriteBit( GPIOX_MEMS_CS, GPIO_PIN_MEMS_CS, ( BitAction )State );
177 }
178 
179 /*******************************************************************************
180 *
181 * MEMS_SendByte
182 *
183 *******************************************************************************/
193 /******************************************************************************/
194 u8 MEMS_SendByte( u8 byte )
195 {
196  /* Loop while DR register in not empty */
197  while ( SPI_I2S_GetFlagStatus( SPIX_MEMS, SPI_I2S_FLAG_TXE ) == RESET );
198 
199  /* Send byte through the SPIx peripheral */
200  SPI_I2S_SendData( SPIX_MEMS, byte );
201 
202  /* Wait to receive a byte */
203  while ( SPI_I2S_GetFlagStatus( SPIX_MEMS, SPI_I2S_FLAG_RXNE ) == RESET );
204 
205  /* Return the byte read from the SPI bus */
206  return SPI_I2S_ReceiveData( SPIX_MEMS );
207 }
208 
209 /* Public functions for CircleOS ---------------------------------------------*/
210 
211 /*******************************************************************************
212 *
213 * MEMS_Init
214 *
215 *******************************************************************************/
223 /******************************************************************************/
224 NODEBUG2 void MEMS_Init( void )
225 {
226  SPI_InitTypeDef SPI_InitStructure;
227  GPIO_InitTypeDef GPIO_InitStructure;
228 
229  /* Enable SPIx, GPIOX_MEMS_CTRL and GPIOX_MEMS_CS clocks */
230  RCC_APBxPERIPH_MEMS_CLOCK_CMD( RCC_APBxPERIPH_SPIX_MEMS, ENABLE );
231  RCC_PERIPH_GPIO_CLOCK_CMD( RCC_APBxPERIPH_GPIOX_MEMS_CTRL, ENABLE );
232  RCC_PERIPH_GPIO_CLOCK_CMD( RCC_APBxPERIPH_GPIOX_MEMS_CS, ENABLE );
233 
234 #ifdef STM32L1XX_MD
235 
236  /* Configure MSD_SPI pins: SCK, MISO and MOSI */
237  GPIO_InitStructure.GPIO_Pin = GPIO_PIN_MEMS_SCK | GPIO_PIN_MEMS_MISO | GPIO_PIN_MEMS_MOSI;
238  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
239  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
240  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
241  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
242  GPIO_Init( GPIOX_MEMS_CTRL, &GPIO_InitStructure );
243 
244  /* Connect PXx to SD_SPI_SCK, SD_SPI_MISO and SD_SPI_MOSI*/
245  GPIO_PinAFConfig(GPIOX_MEMS_CTRL, MEMS_SPI_SCK_SOURCE, MEMS_SPI_SCK_AF);
246  GPIO_PinAFConfig(GPIOX_MEMS_CTRL, MEMS_SPI_MISO_SOURCE, MEMS_SPI_MISO_AF);
247  GPIO_PinAFConfig(GPIOX_MEMS_CTRL, MEMS_SPI_MOSI_SOURCE, MEMS_SPI_MOSI_AF);
248 
249 #else
250 
251 #ifdef STM32F429X
252 
253  /* Configure MSD_SPI pins: SCK, MISO and MOSI */
254  GPIO_InitStructure.GPIO_Pin = GPIO_PIN_MEMS_SCK | GPIO_PIN_MEMS_MISO | GPIO_PIN_MEMS_MOSI;
255  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
256  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
257  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
258  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
259  GPIO_Init( GPIOX_MEMS_CTRL, &GPIO_InitStructure );
260 
261  /* Connect PXx to SD_SPI_SCK, SD_SPI_MISO and SD_SPI_MOSI*/
262  GPIO_PinAFConfig(GPIOX_MEMS_CTRL, MEMS_SPI_SCK_SOURCE, MEMS_SPI_SCK_AF);
263  GPIO_PinAFConfig(GPIOX_MEMS_CTRL, MEMS_SPI_MISO_SOURCE, MEMS_SPI_MISO_AF);
264  GPIO_PinAFConfig(GPIOX_MEMS_CTRL, MEMS_SPI_MOSI_SOURCE, MEMS_SPI_MOSI_AF);
265 
266 #else
267 
268  /* Configure SPI pins: SCK and MOSI */
269  GPIO_InitStructure.GPIO_Pin = GPIO_PIN_MEMS_SCK | GPIO_PIN_MEMS_MOSI;
270  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
271  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
272  GPIO_Init( GPIOX_MEMS_CTRL, &GPIO_InitStructure );
273 
274  /* Configure SPI pins: MISO */
275  GPIO_InitStructure.GPIO_Pin = GPIO_PIN_MEMS_MISO;
276  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
277  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
278  GPIO_Init( GPIOX_MEMS_CTRL, &GPIO_InitStructure );
279 
280 #endif
281 #endif
282 
283  /* Configure Pxx as Output push-pull, used as MEMS Chip select */
284  GPIO_InitStructure.GPIO_Pin = GPIO_PIN_MEMS_CS;
285 #ifdef STM32L1XX_MD
286  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
287  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
288  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
289  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
290 #else
291 #ifdef STM32F429X
292  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
293  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
294  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
295  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
296 #else
297  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
298  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
299 #endif
300 #endif
301  GPIO_Init( GPIOX_MEMS_CS, &GPIO_InitStructure );
302 
303  /* SPI configuration */
304  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
305  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
306  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
307  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
308  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
309  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
310  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
311  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
312  SPI_InitStructure.SPI_CRCPolynomial = 7;
313 
314  SPI_Init( SPIX_MEMS, &SPI_InitStructure );
315 
316  /* Enable SPI */
317  SPI_Cmd( SPIX_MEMS, ENABLE );
318 
319  if ( MEMS_ReadID() != 0x3A )
320  {
321  s32 i;
322 
323  // Try to resynchronize
324  for ( i = 0 ; i < 17 ; i++ )
325  {
326  /* Configure SPI2 pins: SCK, MISO and MOSI */
327  GPIO_InitStructure.GPIO_Pin = GPIO_PIN_MEMS_SCK | GPIO_PIN_MEMS_MOSI;
328  #ifdef STM32L1XX_MD
329  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
330  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
331  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
332  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
333  #else
334  #ifdef STM32F429X
335  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
336  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
337  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
338  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
339  #else
340  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
341  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
342  GPIO_Init( GPIOX_MEMS_CTRL, &GPIO_InitStructure );
343  #endif
344  #endif
345  GPIO_WriteBit( GPIOX_MEMS_CTRL, GPIO_PIN_MEMS_MOSI, HIGH );
346  MEMS_ChipSelect( ACTIVE );
347 
348  GPIO_WriteBit( GPIOX_MEMS_CTRL, GPIO_PIN_MEMS_SCK, LOW );
349  GPIO_WriteBit( GPIOX_MEMS_CTRL, GPIO_PIN_MEMS_SCK, HIGH );
350  MEMS_ChipSelect( HIGH );
351 
352  /* Configure again PB. SCK as SPI2 pin */
353  GPIO_InitStructure.GPIO_Pin = GPIO_PIN_MEMS_SCK | GPIO_PIN_MEMS_MOSI;
354  #ifdef STM32L1XX_MD
355  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
356  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
357  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
358  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
359  #else
360  #ifdef STM32F429X
361  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
362  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
363  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
364  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
365  #else
366  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
367  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
368  GPIO_Init( GPIOX_MEMS_CTRL, &GPIO_InitStructure );
369  #endif
370  #endif
371  if ( MEMS_ReadID() == 0x3A )
372  {
373  break;
374  }
375  }
376 
377  if ( i == 17 )
378  {
379  DRAW_DisplayString( 1, 50, "Test MEM ID Failed", 18 );
380  fIsStandAlone = 1;
381  }
382  }
383 
384  MEMS_ReadOutXY();
385 
386  MEMS_Info.OutX_F4 = MEMS_Info.OutX_F16 = MEMS_Info.OutX_F64 = MEMS_Info.OutX_F256 = MEMS_Info.OutX;
387  MEMS_Info.OutY_F4 = MEMS_Info.OutY_F16 = MEMS_Info.OutY_F64 = MEMS_Info.OutY_F256 = MEMS_Info.OutY;
388  MEMS_Info.OutZ_F4 = MEMS_Info.OutZ_F16 = MEMS_Info.OutZ_F64 = MEMS_Info.OutZ_F256 = MEMS_Info.OutZ;
389 
390  /* Init X and Y*/
391  MEMS_GetPosition( &XInit, &YInit );
392 
393  /* Wake Up Mems*/
394  MEMS_WakeUp();
395 }
396 
397 
398 /*******************************************************************************
399 *
400 * MEMS_ReadID
401 *
402 *******************************************************************************/
409 /******************************************************************************/
410 u8 MEMS_ReadID( void )
411 {
412  u8 Temp = 0;
413 
414  /* Chip Select low */
415  MEMS_ChipSelect( ACTIVE );
416 
417  /* Send "RDID" instruction */
418  MEMS_SendByte( RDID );
419 
420  /* Read a byte from the MEMS */
421  Temp = MEMS_SendByte( DUMMY_BYTE );
422 
423  /* Chip Select low */
424  MEMS_ChipSelect( STDBY );
425 
426  return Temp;
427 }
428 
430 
431 /* Public functions ----------------------------------------------------------*/
432 
433