ISF  2.1
Intelligent Sensing Framework for Kinetis with Processor Expert
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
fsl_fxls8471_i2cspi_3D_accel.c
Go to the documentation of this file.
1 /**
2  ** @file fsl_fxls8471_i2cspi_3D_accel.c
3  ** @version 01.00
4  ** @brief
5  **
6  */
7 /**
8  ** @addtogroup fsl_fxls8471_i2cspi_3D_accel_module fsl_fxls8471_i2cspi_3D_accel module documentation
9  ** @{
10  */
11 
12 /* MODULE fsl_fxls8471_i2cspi_3D_accel. */
13 
14 #include <isf.h>
15 #include <isf_types.h>
16 #include <lwmem.h>
17 #include <lwsem.h>
18 #include <lwevent.h>
19 #include <isf_sm_api.h>
20 #include <isf_dsa_adapter.h>
21 #include <isf_bm.h>
22 #include <isf_sensor_types.h>
23 #include <isf_fifo.h>
25 #include <isf_comm.h>
26 #include <isf_util.h>
27 #include <isf_sensors.h>
28 #include "fxls8471.h"
29 #include "fsl_i2c_master_driver.h"
31 #include "isf_spi_master_types.h"
32 
33 
34 /*! @brief User specified settings that may change */
35 static fxls8471_Specific_Settings_t fxls8471_settings;
36 
37 
38 /*! @brief The constant array, fsl_fxls8471_period, maps the available sample rates into the compatible sampling periods. */
39 static const isf_duration_t fsl_fxls8471_period[] =
40 {
41  1250, // 800 Hz
42  2500, // 400 Hz
43  5000, // 200 Hz
44  10000, // 100 Hz
45  20000, // 50 Hz
46  80000, // 12.5 Hz
47  160000, // 6.25 Hz
48  640000 // 1.56 Hz
49 };
50 
51 /*
52  * @brief This table contains the Accel conversion factors based on the full-scale range selected.
53  */
54 const struct
55 {
56  float floatFactor;
57  float floatOffset;
61 {
62  { 0.000061, 0.0, 8, 0},
63  { 0.000122, 0.0, 16, 0},
64  { 0.000244, 0.0, 32, 0}
65 };
68 
69 // Define the FXLS8471 functional interface status return type.
71 
72 /*
73  * Local function prototypes.
74  */
75 void fxls8471_Reset(int32_t *status, void* pSensorHandle);
76 void fxls8471_CheckId(int32_t *status, void* pSensorHandle);
77 void fxls8471_SetMode(int32_t *status, void* pSensorHandle, int32_t Mode);
78 void fxls8471_ValidateConfig(int32_t *status, void* pSensorHandle, void* pSettings);
81 isf_dsa_status_t fxls8471_GetData(isf_SensorHandle_t *pSensorHandle, void* pBuffer);
82 
83 // Converter routines for the supported data types
84 static isf_dsa_status_t float_accel3d_converter(fxls8471_Sensor_Specific_Settings_t *pSensorSpecificConfig, fxls8471_DataBuffer_t *nativeSample, void *vpConvertedSample );
85 static isf_dsa_status_t fixed_accel3d_converter(fxls8471_Sensor_Specific_Settings_t *pSensorSpecificConfig, fxls8471_DataBuffer_t *nativeSample, void *vpConvertedSample );
86 
87 /*
88  ** ===================================================================
89  ** Method : fsl_fxls8471_i2cspi_3D_accel_Initialize (component ISFDSA)
90  ** @brief
91  **
92  ** Parameters :
93  ** NAME - DESCRIPTION
94  ** @param
95  ** isf_SensorHandle_t *pSensorHandle
96  ** @return
97  ** isf_dsa_status_t -
98  ** ===================================================================
99  */
101 {
102  if ( NULL == pSensorHandle){
103  return DSA_ERR_PARAM;
104  }
105 
106  int32_t status;
107 
108 
109  // Create a pointer to the slave specific comm info
111  spi_master_slaveInfo_t *pSlave = pCommInfo->pSlaveInfo;
112  spi_master_busConfig_t *pBusConfig = &pCommInfo->busConfig;
113 
114  // Check if the sensor is available, and that it has already been initialized.
115  if (pSensorHandle->adapterStatus > DSA_STATE_NOT_INITIALIZED) {
116  return DSA_ERR_INITIALIZE;
117  }
118 
119  // Allocate the adapter specific memory for the descriptor
120  pSensorHandle->pDeviceDescriptor = (DeviceDescriptor_t *)_lwmem_alloc_system_zero(sizeof(DeviceDescriptor_t));
121 
122  // Create and validate helper reference pointers.
123  DeviceDescriptor_t *pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHandle->pDeviceDescriptor;
124 
125  if (NULL == pDeviceDescriptor) {
126  return DSA_ERR_INITIALIZE;
127  }
128 
129  // Allocate the current sample data buffer and initialize it.
130  pDeviceDescriptor->pCurrentSample = _lwmem_alloc_system_zero(sizeof(fxls8471_DataBuffer_t));
131  fxls8471_DataBuffer_t *pCurrentSampleBuffer = (fxls8471_DataBuffer_t *)pDeviceDescriptor->pCurrentSample;
132  pCurrentSampleBuffer->timeStamp = 0;
133  pCurrentSampleBuffer->accel[0] = 0;
134  pCurrentSampleBuffer->accel[1] = 0;
135  pCurrentSampleBuffer->accel[2] = 0;
136 
137  dm_ChannelDescriptor_t *pChannelDescriptor = &pDeviceDescriptor->cDescriptor;
138 
139  // Initialize the channel
140  if(ISF_SUCCESS != dm_channel_init(pSensorHandle->pSensorStaticConfig->channelId, pChannelDescriptor)){
141  return DSA_ERR_INITIALIZE;
142  }
143 
144  // Check the channel state. Must be COMM_STATE_INIT to configure.
145  if(COMM_STATE_INIT != dm_channel_get_state(pChannelDescriptor)){
146  return DSA_ERR_INITIALIZE;
147  }
148 
149  // Initialize the channel/bus configuration according to the comm specific info.
150  if(ISF_SUCCESS != dm_channel_configure(pChannelDescriptor, pBusConfig)){
151  return DSA_ERR_INITIALIZE;
152  }
153 
154  // Start the Bus
155  if(ISF_SUCCESS != dm_channel_start(pChannelDescriptor)){
156  return DSA_ERR_INITIALIZE;
157  }
158 
159  // Get the Channel state to check if it is ready to use
160  if (COMM_STATE_OK != dm_channel_get_state(pChannelDescriptor)) {
161  return DSA_ERR_INITIALIZE;
162  }
163 
164  // Open the device and get the device handler
165  if(ISF_SUCCESS != dm_device_open(pChannelDescriptor, (void *)pSlave, &pDeviceDescriptor->deviceHandle)){
166  return DSA_ERR_INITIALIZE;
167  }
168 
169  // A very short delay is needed for device startup.
170  _time_delay_ticks(1);
171 
172  // Query the sensor to validate Device Messaging initialization and the sensor identity.
173  fxls8471_CheckId(&status,pSensorHandle);
174  if (ISF_SUCCESS != status)
175  {
176  return DSA_ERR_INITIALIZE;
177  }
178 
179  // Set the adapter state to be initialized.
180  pSensorHandle->adapterStatus = DSA_STATE_INITIALIZED;
181 
182  // Create a semaphore to synchronize the device descriptor across tasks
183  if (MQX_OK != _lwsem_create(&pDeviceDescriptor->deviceSemaphore, 1)){
184  return DSA_ERR_INITIALIZE;
185  }
186 
187  pDeviceDescriptor->skipFramecnt = 0;
188 
189  return ISF_SUCCESS;
190 }
191 
192 /*
193  ** ===================================================================
194  ** Method : fsl_fxls8471_i2cspi_3D_accel_ValidateSettings (component ISFDSA)
195  ** @brief
196  **
197  ** Parameters :
198  ** NAME - DESCRIPTION
199  ** @param
200  ** isf_SensorHandle_t *pSensorHandle
201  ** @param
202  ** isf_SubscriptionSettings_t *pSettings
203  ** @return
204  ** isf_dsa_status_t -
205  ** ===================================================================
206  */
208 {
209  // Check the input arguments.
210  if ((NULL == pSensorHandle) || (NULL == pSensorSettings)) {
211  return DSA_ERR_PARAM;
212  }
213 
214  int32_t status;
215 
216  fxls8471_ValidateConfig(&status,pSensorHandle,pSensorSettings);
217 
218  return status;
219 }
220 
221 /*
222  ** ===================================================================
223  ** Method : fsl_fxls8471_i2cspi_3D_accel_Configure (component ISFDSA)
224  ** @brief
225  **
226  ** Parameters :
227  ** NAME - DESCRIPTION
228  ** @param
229  ** isf_SensorHandle_t *pSensorHandle
230  ** @param
231  ** isf_SubscriptionSettings_t *pConfigSettings
232  ** @return
233  ** isf_dsa_status_t -
234  ** ===================================================================
235  */
237 {
238  // Check pointers.
239  if((NULL == pSensorHandle) || (NULL == pSensorSettings) ){
240  return DSA_ERR_PARAM;
241  }
242 
243  int32_t status;
244 
245  int32_t retStat = DSA_ERR_CONFIGURE; // Return Status
246 
247  // Create helper reference pointers.
248  DeviceDescriptor_t *pDeviceDescriptor = (DeviceDescriptor_t*) pSensorHandle->pDeviceDescriptor;
249 
250  // Check the device descriptor pointer.
251  if (NULL == pDeviceDescriptor)
252  {
253  return retStat;
254  }
255 
256  // Lock the device descriptor.
257  _lwsem_wait_ticks(&pDeviceDescriptor->deviceSemaphore, 0);
258 
259  // Check the driver state.
260  if (DSA_STATE_INITIALIZED > pSensorHandle->adapterStatus){
261  goto unlockdescriptor;
262  }
263 
264  // User Notice: This is a required function call. If it is not here, there may be conflicts, data loss,
265  // or any number of undesirable things may occur.
266  if (ISF_SUCCESS != dm_channel_acquire_lock(&pDeviceDescriptor->cDescriptor, 0)) {
267  goto unlockdescriptor;
268  }
269 
270  // Set the sensor into STANDBY mode for configuration.
271  fxls8471_SetMode(&status, pSensorHandle, SENSOR_STANDBY);
272  if (ISF_SUCCESS != status) {
273  goto unlockchannel;
274  }
275 
276  // Configure the sensor.
277  retStat = fxls8471_SetConfig(pSensorHandle, pSensorSettings);
278  if (ISF_SUCCESS != retStat) {
279  goto unlockchannel;
280  }
281 
282  // Register the periodic callback function with the Bus Manager.
283  pDeviceDescriptor->token = bm_register_periodic_callback( pSensorSettings->nSamplePeriod, fsl_fxls8471_i2cspi_3D_accel_PeriodicCallback , pSensorHandle);
284  if(BM_ERROR & pDeviceDescriptor->token){
285  goto unlockchannel;
286  }
287 
288  //Store the configured settings
289  pSensorHandle->controlData.sensorSettings = *pSensorSettings;
290 
292  retStat = ISF_SUCCESS;
293 
294 unlockchannel:
295  // Unlock the channel.
296  // The explicit lock must be released when the configuration is done allowing the bus to be used by others.
297  // User Notice: This is a required function call.
298  status = dm_channel_release_lock(&pDeviceDescriptor->cDescriptor);
299  if (ISF_SUCCESS != status)
300  {
301  retStat = status;
302  }
303 
304 unlockdescriptor:
305 
306  // Unlock the device descriptor.
307  _lwsem_post(&pDeviceDescriptor->deviceSemaphore);
308 
309  return retStat;
310 }
311 
312 /*
313  ** ===================================================================
314  ** Method : fsl_fxls8471_i2cspi_3D_accel_StartData (component ISFDSA)
315  ** @brief
316  **
317  ** Parameters :
318  ** NAME - DESCRIPTION
319  ** @param
320  ** isf_SensorHandle_t *pSensorHandle
321  ** @return
322  ** isf_dsa_status_t -
323  ** ===================================================================
324  */
326 {
327  // Check pointers.
328  if(NULL == pSensorHandle){
329  return DSA_ERR_PARAM;
330  }
331 
332  int32_t status;
333  int32_t retStat = DSA_ERR_START_DATA;
334 
335  // Create helper reference pointers.
336  DeviceDescriptor_t* pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHandle->pDeviceDescriptor;
337 
338  // Check the device descriptor.
339  if (NULL == pDeviceDescriptor)
340  return DSA_ERR_PARAM;
341 
342  // Lock the device descriptor.
343  _lwsem_wait_ticks(&pDeviceDescriptor->deviceSemaphore, 0);
344 
345  // Check the driver state.
346  if (DSA_STATE_CONFIGURED_STOPPED > pSensorHandle->adapterStatus)
347  {
348  goto unlockdescriptor;
349  }
350 
351  // Set the sensor into ACTIVE mode for operation.
352  fxls8471_SetMode(&status, pSensorHandle, SENSOR_ACTIVE);
353  if (ISF_SUCCESS != status) {
354  goto unlockdescriptor;
355  }
356 
357  // Start the Bus Manager sampling timer.
358  if (BM_ERROR & bm_start(FALSE, pDeviceDescriptor->token)) // Check for Bus Manager error and return on failure.
359  goto unlockdescriptor;
360 
361  // Set device to active state.
363  retStat = ISF_SUCCESS;
364 
365 unlockdescriptor:
366  // Unlock the device descriptor.
367  _lwsem_post(&pDeviceDescriptor->deviceSemaphore);
368 
369  return retStat;
370 }
371 
372 /*
373  ** ===================================================================
374  ** Method : fsl_fxls8471_i2cspi_3D_accel_EndData (component ISFDSA)
375  ** @brief
376  **
377  ** Parameters :
378  ** NAME - DESCRIPTION
379  ** @param
380  ** isf_SensorHandle_t *pSensorHandle
381  ** @return
382  ** isf_dsa_status_t -
383  ** ===================================================================
384  */
386 {
387  // Check pointers.
388  if(NULL == pSensorHandle){
389  return DSA_ERR_PARAM;
390  }
391 
392  int32_t status;
393 
394  // Create helper reference pointers.
395  DeviceDescriptor_t* pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHandle->pDeviceDescriptor;
396 
397  // Set the default return status.
398  int32_t retStat = DSA_ERR_END_DATA;
399 
400  // Check the device descriptor.
401  if (NULL == pDeviceDescriptor)
402  return retStat;
403 
404  // Lock the device descriptor.
405  _lwsem_wait_ticks(&pDeviceDescriptor->deviceSemaphore, 0);
406 
407  // Check the driver state.
408  if (DSA_STATE_CONFIGURED_STOPPED >= pSensorHandle->adapterStatus)
409  goto unlockdescriptor;
410 
411  // Check that the adapter is not already started.
412  if (DSA_STATE_CONFIGURED_STARTED == pSensorHandle->adapterStatus) {
413  // If it is, then stop the Bus Manager (BM) sample timer.
414  isf_status_t bmStopStatus = bm_stop(pDeviceDescriptor->token);
415  if (BM_ERROR & bmStopStatus)
416  goto unlockdescriptor;
417  }
418 
419  // Set the sensor into STANDBY mode for configuration.
420  fxls8471_SetMode(&status, pSensorHandle, SENSOR_STANDBY);
421  if (ISF_SUCCESS != status) {
422  goto unlockdescriptor;
423  }
424 
426  retStat = ISF_SUCCESS;
427 
428 
429 unlockdescriptor:
430  // Unlock the device descriptor.
431  _lwsem_post(&pDeviceDescriptor->deviceSemaphore);
432 
433  return retStat;
434 }
435 
436 /*
437  ** ===================================================================
438  ** Method : fsl_fxls8471_i2cspi_3D_accel_Calibrate (component ISFDSA)
439  ** @brief
440  **
441  ** Parameters :
442  ** NAME - DESCRIPTION
443  ** @param
444  ** isf_SensorHandle_t *pSensorHandle
445  ** @return
446  ** isf_dsa_status_t -
447  ** ===================================================================
448  */
450 {
451  int32_t retStat = ISF_SUCCESS;
452 
453  return retStat;
454 }
455 
456 /*
457  ** ===================================================================
458  ** Method : fsl_fxls8471_i2cspi_3D_accel_Shutdown (component ISFDSA)
459  ** @brief
460  **
461  ** Parameters :
462  ** NAME - DESCRIPTION
463  ** @param
464  ** isf_SensorHandle_t *pSensorHandle
465  ** @return
466  ** isf_dsa_status_t -
467  ** ===================================================================
468  */
470 {
471  if(NULL == pSensorHandle){
472  return DSA_ERR_PARAM;
473  }
474 
475  // Create helper reference pointers.
476  DeviceDescriptor_t* pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHandle->pDeviceDescriptor;
477 
478  // Remove the sensor adapter from the Bus Manager callbacks.
479  bm_unregister_callback(pDeviceDescriptor->token);
480  pSensorHandle->adapterStatus = DSA_STATE_INITIALIZED;
481  return ISF_SUCCESS;
482 
483 }
484 
485 /*
486  ** ===================================================================
487  ** Method : fsl_fxls8471_i2cspi_3D_accel_PeriodicCallback (component ISFDSA)
488  ** @brief
489  **
490  ** Parameters :
491  ** NAME - DESCRIPTION
492  ** @param
493  ** void* pSensorHandle -
494  ** @return
495  ** void -
496  ** ===================================================================
497  */
499 {
500  // Check pointers.
501  if(NULL == pSensorHandle){
502  return;
503  }
504 
505  // Create helper reference pointers.
506  volatile isf_SensorHandle_t *pSensorHdl = (isf_SensorHandle_t *)pSensorHandle;
508  DeviceDescriptor_t *pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHdl->pDeviceDescriptor;
509  isf_status_t st;
510  int32 numBytes;
511 
512  // Check the device descriptor
513  if (NULL == pDeviceDescriptor){
514  return;
515  }
516 
517  // Create a helper pointer to the current sample buffer.
518  fxls8471_DataBuffer_t *pCurrentSampleBuffer = (fxls8471_DataBuffer_t *)pDeviceDescriptor->pCurrentSample;
519 
520  // Apply sample skip if necessary.
521  if (pDeviceDescriptor->skipFramecnt) {
522  // Not done skipping samples.
523  --pDeviceDescriptor->skipFramecnt;
524  return;
525  }
526 
527  // Get the time stamp
528  pCurrentSampleBuffer->timeStamp = isf_time_util_get_usec();
529 
530  // Lock the device descriptor.
531  if (MQX_OK !=_lwsem_wait_ticks(&pDeviceDescriptor->deviceSemaphore, 0))
532  {
533  goto unlockdescriptor;
534  }
535 
536 
537  // Check the driver state.
538  if (DSA_STATE_CONFIGURED_STARTED != pSensorHdl->adapterStatus)
539  {
540  goto unlockdescriptor;
541  }
542 
543  // Get sensor data.
544  fxls8471_GetData(pSensorHandle, ((uint8*)&pCurrentSampleBuffer->accel[0])); // Returns samples in big endian.
545 
546  // Lock the fifo for update.
547  if(MQX_OK != isf_fifo_lock(pFifo)){
548  return;
549  }
550 
552 
553 
554  // write the new data
556  {
557  *pFifoEntry = *pCurrentSampleBuffer;
558  }
559  else
560  {
562  pSensorHdl,
565  pCurrentSampleBuffer,
566  pFifoEntry,
567  &numBytes);
568  }
569 
570  // Increment the fifo to the next sample entry.
571  st = isf_fifo_el_increment(pFifo);
572 
573  // Unlock the fifo.
574  isf_fifo_unlock(pFifo);
575 
576  if (st == ISF_FIFO_FULL)
577  {
578  // Notify the user using their registered event information
579  _lwevent_set(pSensorHdl->controlData.pEventGroup,(_mqx_uint)pSensorHdl->controlData.nEventFieldIndex);
580  }
581 
582 unlockdescriptor:
583  // Unlock the device descriptor.
584  _lwsem_post(&pDeviceDescriptor->deviceSemaphore);
585 
586 }
587 
588 /*!
589  * @brief This function coverts the raw sample data to the desired output type.
590  */
592  (
593  volatile isf_SensorHandle_t *pSensorHandle,
594  isf_SensorDataTypes_t convertToType, isf_dsa_result_types_t resultType,
595  void *pNativeSample,
596  void *pConvertedSample,
597  int32 *numBytes
598  )
599 {
602 
603  pConverter = NULL;
604 
605  switch (convertToType)
606  {
608  if (resultType == DSA_RESULT_TYPE_ENG_FLOAT)
609  pConverter = float_accel3d_converter;
610  else if (resultType == DSA_RESULT_TYPE_ENG_FIXED)
611  pConverter = fixed_accel3d_converter;
612  break;
613 
614  default:
616  }
617  if (pConverter == NULL)
619 
620  retStat = pConverter(
622  (fxls8471_DataBuffer_t *)pNativeSample,
623  pConvertedSample
624  );
625 
626  return retStat;
627 }
628 
629 static isf_dsa_status_t float_accel3d_converter(fxls8471_Sensor_Specific_Settings_t *pSensorSpecificConfig, fxls8471_DataBuffer_t *nativeSample, void *vpConvertedSample )
630 {
631  isf_Acceleration3D_Float_t *convertedSample = (isf_Acceleration3D_Float_t *)vpConvertedSample;
632  convertedSample->timestamp = nativeSample->timeStamp;
633  // These factors and offsets really depends on the configured sensor Range in pSensorSpecificConfig
634  //convertedSample->accel[0] = nativeSample->accel[0] * FXLS8471_ACCEL_FLOAT_CONVERSION_FACTOR + FXLS8471_ACCEL_FLOAT_CONVERSION_OFFSET;
635  //convertedSample->accel[1] = nativeSample->accel[1] * FXLS8471_ACCEL_FLOAT_CONVERSION_FACTOR + FXLS8471_ACCEL_FLOAT_CONVERSION_OFFSET;
636  //convertedSample->accel[2] = nativeSample->accel[2] * FXLS8471_ACCEL_FLOAT_CONVERSION_FACTOR + FXLS8471_ACCEL_FLOAT_CONVERSION_OFFSET;
637 
638  // Convert the sample based on the full-scale range.
639  convertedSample->accel[0] = nativeSample->accel[0] * fxls8471AccelConvTable[pSensorSpecificConfig->accelFullScaleRange].floatFactor + fxls8471AccelConvTable[pSensorSpecificConfig->accelFullScaleRange].floatOffset;
640  convertedSample->accel[1] = nativeSample->accel[1] * fxls8471AccelConvTable[pSensorSpecificConfig->accelFullScaleRange].floatFactor + fxls8471AccelConvTable[pSensorSpecificConfig->accelFullScaleRange].floatOffset;
641  convertedSample->accel[2] = nativeSample->accel[2] * fxls8471AccelConvTable[pSensorSpecificConfig->accelFullScaleRange].floatFactor + fxls8471AccelConvTable[pSensorSpecificConfig->accelFullScaleRange].floatOffset;
642  return ISF_SUCCESS;
643 }
644 
645 static isf_dsa_status_t fixed_accel3d_converter(fxls8471_Sensor_Specific_Settings_t *pSensorSpecificConfig, fxls8471_DataBuffer_t *nativeSample, void *vpConvertedSample )
646 {
647  isf_Acceleration3D_EngFixed_t *convertedSample = (isf_Acceleration3D_EngFixed_t *)vpConvertedSample;
648  convertedSample->timestamp = nativeSample->timeStamp;
649  // These factors and offsets really depend on the configured sensor Range in pSensorSpecificConfig
650  //convertedSample->accel[0] = nativeSample->accel[0] * FXLS8471_ACCEL_FIXED_CONVERSION_FACTOR + FXLS8471_ACCEL_FIXED_CONVERSION_OFFSET;
651  //convertedSample->accel[1] = nativeSample->accel[1] * FXLS8471_ACCEL_FIXED_CONVERSION_FACTOR + FXLS8471_ACCEL_FIXED_CONVERSION_OFFSET;
652  //convertedSample->accel[2] = nativeSample->accel[2] * FXLS8471_ACCEL_FIXED_CONVERSION_FACTOR + FXLS8471_ACCEL_FIXED_CONVERSION_OFFSET;
653 
654  // Convert the sample based on the full-scale range.
655  convertedSample->accel[0] = (nativeSample->accel[0] * fxls8471AccelConvTable[pSensorSpecificConfig->accelFullScaleRange].fixedFactor + fxls8471AccelConvTable[pSensorSpecificConfig->accelFullScaleRange].fixedOffset)/4;
656  convertedSample->accel[1] = (nativeSample->accel[1] * fxls8471AccelConvTable[pSensorSpecificConfig->accelFullScaleRange].fixedFactor + fxls8471AccelConvTable[pSensorSpecificConfig->accelFullScaleRange].fixedOffset)/4;
657  convertedSample->accel[2] = (nativeSample->accel[2] * fxls8471AccelConvTable[pSensorSpecificConfig->accelFullScaleRange].fixedFactor + fxls8471AccelConvTable[pSensorSpecificConfig->accelFullScaleRange].fixedOffset)/4;
658  return ISF_SUCCESS;
659 }
660 
661 /*!
662  * @brief This function resets the FXLS8471 sensor resulting in a default configuration for
663  * all registers.
664  */
665 void fxls8471_Reset(int32_t* status, void* pSensorHandle)
666 {
667  uint8 buffer[1] = {0};
668 
669  // Create and validate helper reference pointers.
670  isf_SensorHandle_t* pSensorHdl = (isf_SensorHandle_t *)pSensorHandle;
671  DeviceDescriptor_t* pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHdl->pDeviceDescriptor;
672  dm_DeviceDescriptor_t* pDeviceHandle = &pDeviceDescriptor->deviceHandle;
673 
674  // Reset the device.
675  // Put the device the STANDBY state which is required before any configuration registers are set.
676  buffer[0]= FXLS8471_RST_MASK; // no shift
677  if (ISF_SUCCESS != dm_device_write(pDeviceHandle, FXLS8471_CTRL_REG2, buffer, 1, 1)){
678  *status = DSA_ERR_INITIALIZE;
679  return;
680  }
681 
682  // Burn a write and ignore the return.
683  buffer[0] = 0;
684  ( void ) dm_device_write(pDeviceHandle, FXLS8471_ASLP_COUNT, buffer, 1, 1);
685 
686  // Turn-on time = 1 second (FXLS8471 Data Sheet) for OSR = 2^7 (128).
687  _time_delay_ticks(1000/5);
688 
689  *status = ISF_SUCCESS;
690 }
691 
692 /*!
693  * @brief This function validates the FXLS8471 sensor is connected via the I2C bus.
694  */
695 void fxls8471_CheckId(int32_t *status, void* pSensorHandle)
696 {
697  uint8 buffer[1] = {0};
698  int32 retStat = SENSOR_ERROR_CHECKID;
699 
700  // Create and validate helper reference pointers.
701  isf_SensorHandle_t* pSensorHdl = (isf_SensorHandle_t *)pSensorHandle;
702  DeviceDescriptor_t* pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHdl->pDeviceDescriptor;
703  dm_DeviceDescriptor_t* pDeviceHandle = &pDeviceDescriptor->deviceHandle;
704 
705  if (ISF_SUCCESS != dm_device_read(pDeviceHandle, FXLS8471_WHO_AM_I, &buffer[0], 1, 1)){
706  *status = retStat;
707  }
708  if (FXLS8471_WHOAMI_VALUE != buffer[0]) {
709  *status = retStat;
710  }
711 
712  *status = ISF_SUCCESS;
713 }
714 
715 /*!
716  * @brief This function validates the configuration for the FXLS8471 sensor.
717  */
718 void fxls8471_ValidateConfig(int32_t* status, void* pSensorHandle, void* pSettings)
719 {
720  isf_dsa_status_t st; // The status variable.
721  isf_SensorHandle_t *pSensorHdl = (isf_SensorHandle_t *)pSensorHandle;
722  DeviceDescriptor_t *pDeviceDescriptor = (DeviceDescriptor_t*) pSensorHdl->pDeviceDescriptor;
723  isf_dsa_SensorSettings_t *pConfig = (isf_dsa_SensorSettings_t*)pSettings;
724 
725  // Validate the configuration data using the global data
726  st = fxls8471_GetConfig( pConfig, pDeviceDescriptor );
727 
728  // If the configuration data has been modified. convey this information to user Application.
729  if (st) {
730  *status = DSA_RET_SETTINGS_CHANGED;
731  return;
732  }
733 
734  *status = ISF_SUCCESS;
735 }
736 
737 /*!
738  * @brief This function sets the FXLS8471 part to the requested mode.
739  */
740 void fxls8471_SetMode(int32_t* status, void* pSensorHandle, int32_t Mode)
741 {
742  isf_SensorHandle_t* pSensorHdl = (isf_SensorHandle_t *)pSensorHandle;
743  DeviceDescriptor_t* pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHdl->pDeviceDescriptor;
744  dm_DeviceDescriptor_t* pDeviceHandle = &pDeviceDescriptor->deviceHandle;
745 
746  uint8 buffer[1] = {0x00};
747 
748  switch(Mode)
749  {
750  // This will put the sensor into the standby mode
751  case SENSOR_STANDBY:
752  case SENSOR_BOOT:
753  case SENSOR_READY:
754  {
755  // this sensor requires read-modify-write
756  if (ISF_SUCCESS != dm_device_read(pDeviceHandle, FXLS8471_CTRL_REG1, buffer, 1, 1) ){
757  *status = SENSOR_ERROR_SETMODE;
758  return;
759  }
760  buffer[0] = (buffer[0] & ~FXLS8471_ACTIVE_MASK);
761  if (ISF_SUCCESS != dm_device_write(pDeviceHandle, FXLS8471_CTRL_REG1, buffer, 1, 1) ){
762  *status = SENSOR_ERROR_SETMODE;
763  return;
764  }
765  }
766  break;
767 
768  // This will put the sensor into the active state
769  case SENSOR_ACTIVE:
770  {
771  // this sensor requires read-modify-write
772  if (ISF_SUCCESS != dm_device_read(pDeviceHandle, FXLS8471_CTRL_REG1, buffer, 1, 1) ){
773  *status = SENSOR_ERROR_SETMODE;
774  return;
775  }
776  buffer[0] = (buffer[0] | FXLS8471_ACTIVE_MASK);
777  if (ISF_SUCCESS != dm_device_write(pDeviceHandle, FXLS8471_CTRL_REG1, buffer, 1, 1) ){
778  *status = SENSOR_ERROR_SETMODE;
779  return;
780  }
781  // Read the value of the status register to wait for valid data
782  buffer[0] = 0;
783  do {
784  if (ISF_SUCCESS != dm_device_read(pDeviceHandle, FXLS8471_STATUS, buffer, 1, 1) ){
785  *status = SENSOR_ERROR_SETMODE;
786  return;
787  }
788  _time_delay_ticks(1); // short delay to yield CPU/RTOS.
789  } while (0 == FXLS8471_GET_FIELD(ZYXDR,buffer[0]) ); // Wait for Data Ready.
790  }
791  break;
792 
793  default:
794  *status = SENSOR_ERROR_SETMODE;
795  return;
796  }
797  // return success
798  *status = ISF_SUCCESS;
799 }
800 
801 /*!
802  * @brief This function retrieves the raw data from the FXLS8471 sensor.
803  */
804 #define BYTES_FOR_FULL_READ 7
805 
807 {
809 
810  DeviceDescriptor_t* pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHandle->pDeviceDescriptor;
811  dm_DeviceDescriptor_t* pDeviceHandle = &pDeviceDescriptor->deviceHandle;
812 
813  uint16* pSensorData = (uint16*)pBuffer;
814  uint8 registerData[BYTES_FOR_FULL_READ];
815 
816  // read the full width of the data for both full or short reads
817  if (ISF_SUCCESS != dm_device_read(pDeviceHandle, FXLS8471_STATUS, registerData, BYTES_FOR_FULL_READ, BYTES_FOR_FULL_READ) )
818  { // return error SENSOR_ERROR_GETDATA
819  return retStat;
820  }
821 
822  // If there is any data, then format and copy it to the output buffer.
823  if ( FXLS8471_GET_FIELD(ZYXDR, registerData[0] ) > 0 )
824  {
825  // collect the full 16-bit data for each of x,y,z
826  pSensorData[0] = ((int16)registerData[1])<<8 | registerData[2];
827  pSensorData[1] = ((int16)registerData[3])<<8 | registerData[4];
828  pSensorData[2] = ((int16)registerData[5])<<8 | registerData[6];
829  }
830  // return success
831  return ISF_SUCCESS;
832 }
833 
834 
835 /*!
836  * @brief This function sets the FXLS8471 sensor configuration.
837  */
839 {
840  int32_t retStat = DSA_ERR_CONFIGURE; // Return Status
841  uint8 address, value;
842 
843  // Create helper reference pointers.
844  DeviceDescriptor_t *pDeviceDescriptor = (DeviceDescriptor_t*) pSensorHandle->pDeviceDescriptor;
846  dm_DeviceDescriptor_t *pDeviceHandle = &pDeviceDescriptor->deviceHandle;
847 
848  /* Write the sensor specific data based on the pre-computed register level pairs (Addr, Value) */
849  uint8 buffer[1];
850  for (uint32 reg=0; reg < pConfigSpecific->regCount; reg++)
851  {
852  address = pConfigSpecific->regPairs[reg].regAddr;
853  value = pConfigSpecific->regPairs[reg].regValue;
854  buffer[0] = pConfigSpecific->regPairs[reg].regValue;
855  if (ISF_SUCCESS != dm_device_write(pDeviceHandle, pConfigSpecific->regPairs[reg].regAddr,&buffer[0],1,1))
856  {
857  return retStat;
858  }
859  }
860 
861  // Set up the Control register #1 functions: ODR override for SLEEP mode and the WAKE mode ODR.
862  buffer[0] = FXLS8471_SET_FIELD(DR,fxls8471_settings.sampleRateIndex);
863  if (ISF_SUCCESS != dm_device_write(&pDeviceDescriptor->deviceHandle, FXLS8471_CTRL_REG1, buffer, 1, 1) ) return FXLS8471_ERROR;
864 
865  return ISF_SUCCESS;
866 }
867 
868 /*
869  * Local Subroutines
870  */
871 
872 /*! @brief This function obtains the configuration register values for a given user configuration of the FXLS8471.
873  * If the configuration has changed then it returns true and saves the new configuration.
874  *
875  * @param[out] pRequiredSettings update the data period in settings
876  * @param[out] pDeviceDes update the data rate in the generic sensor structure for this device
877  * @return ::fxls8471_GetConfig() returns a value of type ::isf_dsa_status_t indicating the success or failure of the function
878  * call.
879  * @retval 0 is returned when the configuration is valid.
880  * @retval 1 is returned when the configuration is modified.
881  *
882  * @Constraints None
883  *
884  * @Reentrant Yes
885  * @Libs lib_fsl_fxls8471_i2cspi_3D_accel.lib
886  */
888 {
889  // Validate the reporting rate.
890  uint8 retStat = 0; // no changes
891  uint8 periodFound = FALSE; // not found
892  uint8 dataRate;
893 
894  // get the number of array entries, which is not the max data rate by rather the size
895  // of the array (number or elements in the array), max index = size - 1
896  uint8 maxDataRateIndex = sizeof fsl_fxls8471_period / sizeof fsl_fxls8471_period[0];
897 
898  for (dataRate = 0; dataRate < maxDataRateIndex; dataRate++)
899  {
900  if (fsl_fxls8471_period[dataRate] == pRequiredSettings->nSamplePeriod)
901  {
902  periodFound = TRUE;
903  break;
904  }
905  }
906 
907  // If a valid reporting rate has not been set, then default to the FXLS8471 hardware default of 800Hz.
908  if ( !periodFound )
909  {
911  pRequiredSettings->nSamplePeriod = FSL_FXLS8471_ACCEL_800HZ;
912  fxls8471_settings.sampleRateIndex = maxDataRateIndex - 1; // max range index
913  }
914  else
915  { // copy the rate index to local storage as needed
916  fxls8471_settings.sampleRateIndex = dataRate;
917  }
918 
919  return retStat;
920 }
921 
922 /*!
923 ** @}
924 */
925 /* END fsl_fxls8471_i2cspi_3D_accel.c */
926 
927 
isf_status_t dm_channel_start(dm_ChannelDescriptor_t *apChannelDescriptor)
This function starts a channel.
#define FXLS8471_RST_MASK
Definition: fxls8471.h:369
void * pSensorSpecificSettings
unsigned char uint8
This defines uint8 as unsigned char.
Definition: isf_types.h:18
#define TRUE
Definition: isf_types.h:52
fsl_i2c_master_driver.h defines structures and types for the i2c master driver.
Standard fixed type for three axis accelerometers.
This structure defines important settings.
uint32 isf_time_util_get_usec(void)
This API returns the time in microseconds.
Definition: isf_util.c:52
isf_status_t dm_device_open(dm_ChannelDescriptor_t *apChannelDescriptor, void *apDevice, dm_DeviceDescriptor_t *apDeviceDescriptor)
This function creates a device handle for a device at a specified channel address.
const void * commInfo
isf_dsa_ControlData_t controlData
isf_fifo_status_t isf_fifo_lock(isf_fifo_t *pFifo)
Lock a sample buffer for exclusive access.
Definition: isf_fifo.c:171
comm_State_t dm_channel_get_state(dm_ChannelDescriptor_t *apChannelDescriptor)
This function returns the channel state.
isf_fifo_status_t isf_fifo_unlock(isf_fifo_t *pFifo)
Release the exclusive access lock on a sample buffer.
Definition: isf_fifo.c:202
isf_fifo_status_t isf_fifo_el_increment(isf_fifo_t *pFifo)
Routine increments the insert pointer after direct access.
Definition: isf_fifo.c:240
isf_dsa_status_t fsl_fxls8471_i2cspi_3D_accel_EndData(isf_SensorHandle_t *pSensorHandle)
isf_dsa_status_t fsl_fxls8471_i2cspi_3D_accel_Shutdown(isf_SensorHandle_t *pSensorHandle)
isf_sensors.h contains the ISF Generic Sensor definitions and data structures required when a client ...
#define FALSE
Definition: isf_types.h:56
API definitions, types, and macros for the Intelligent Sensing Framework (ISF) Bus Manager (BM)...
dm_DeviceDescriptor_t deviceHandle
Definition: isf_sensors.h:52
This defines the DSA sensor device handle structure used to invoke the adapter access functions...
#define BYTES_FOR_FULL_READ
This function retrieves the raw data from the FXLS8471 sensor.
This structure defines the slave specific spi information.
Define the sensor device descriptor.
Definition: isf_sensors.h:49
isf_dsa_status_t fxls8471_GetData(isf_SensorHandle_t *pSensorHandle, void *pBuffer)
LWSEM_STRUCT deviceSemaphore
Definition: isf_sensors.h:54
uint8 sampleRateIndex
Holds the ODR index into the rate array fsl_fxls8471_period */.
unsigned long uint32
This defines uint32 as unsigned long.
Definition: isf_types.h:36
isf_dsa_status_t fxls8471_GetConfig(isf_dsa_SensorSettings_t *pRequiredSettings, DeviceDescriptor_t *pDeviceDes)
This function obtains the configuration register values for a given user configuration of the FXLS847...
spi_master_busConfig_t busConfig
isf_SensorTypes_t
dm_ChannelDescriptor_t cDescriptor
Definition: isf_sensors.h:51
const struct @17 fxls8471AccelConvTable[]
isf_status_t dm_device_write(dm_DeviceDescriptor_t *apDeviceDescriptor, int32 aOffset, uint8 *apWriteBuffer, uint32 aBuffsize, uint32 aNbyteWrite)
This function writes to a device.
isf_status_t bm_unregister_callback(bm_callback_token_t aToken)
This API unregisters one or more callbacks.
int32 fxls8471_status_t
The fxls8471.h contains the FXLS8471 Accelerometer register definitions, access macros, and device access functions.
#define FXLS8471_SET_FIELD(name, val)
Definition: fxls8471.h:96
The fsl_fxls8471_i2cspi_3D_accel.h file contains the definitions and functions supporting the MMA8652...
The isf_types.h file contains the ISF data type definitions and some of the globally used macros...
void fxls8471_ValidateConfig(int32_t *status, void *pSensorHandle, void *pSettings)
This function validates the configuration for the FXLS8471 sensor.
isf_dsa_status_t fsl_fxls8471_i2cspi_3D_accel_Convert(volatile isf_SensorHandle_t *pSensorHandle, isf_SensorDataTypes_t convertToType, isf_dsa_result_types_t resultType, void *pNativeSample, void *pConvertedSample, int32 *numBytes)
This function coverts the raw sample data to the desired output type.
isf_acceleration_g_fixed_32s1i16_t accel[3]
isf_dsa_status_t fsl_fxls8471_i2cspi_3D_accel_Configure(isf_SensorHandle_t *pSensorHandle, isf_dsa_SensorSettings_t *pSensorSettings)
int32 isf_dsa_status_t
This is the Sensor Manager API return type definition.
isf_acceleration_g_float_t accel[3]
void fxls8471_SetMode(int32_t *status, void *pSensorHandle, int32_t Mode)
This function sets the FXLS8471 part to the requested mode.
isf_SensorTypes_t fxls8471_SupportedSensorTypes[]
Supported sensor and data types for FXLS8471.
#define FXLS8471_GET_FIELD(name, val)
Definition: fxls8471.h:97
isf_status_t dm_channel_acquire_lock(dm_ChannelDescriptor_t *apChannelDescriptor, isf_duration_t aTimeout)
This function locks the channel for exclusive access.
The isf_sensor_types.h contains the enumerated list of sensor types used by ISF.
The isf_util.h file contains the utility method declarations and macros.
enum isf_dsa_result_enums isf_dsa_result_types_t
isf_dsa_status_t fsl_fxls8471_i2cspi_3D_accel_Calibrate(isf_SensorHandle_t *pSensorHandle, void *pCalData)
bm_callback_token_t bm_register_periodic_callback(isf_duration_t aPeriod, bm_callback_t *pCallback, void *pCbData)
This API schedules a callback at the specified period.
#define FXLS8471_ACTIVE_MASK
Definition: fxls8471.h:358
#define FXLS8471_WHOAMI_VALUE
Definition: fxls8471.h:88
spi_master_slaveInfo_t * pSlaveInfo
isf_dsa_result_types_t resultFormat
isf_dsa_status_t fxls8471_SetConfig(isf_SensorHandle_t *pSensorHandle, isf_dsa_SensorSettings_t *pConfigSettings)
This function sets the FXLS8471 sensor configuration.
void fxls8471_Reset(int32_t *status, void *pSensorHandle)
This function resets the FXLS8471 sensor resulting in a default configuration for all registers...
isf_SensorDataTypes_t fxls8471_SupportedDataTypes[]
isf_SensorDataTypes_t
isf_status_t dm_channel_init(dm_ChannelId_t aChannelId, dm_ChannelDescriptor_t *apChannelDescriptor)
This function initializes a channel.
isf_status_t bm_stop(bm_callback_token_t aTokens)
This API stops one or more callback(s) by setting them to the inactive state.
const isf_SensorConfig_t * pSensorStaticConfig
isf_status_t bm_start(boolean aSync, bm_callback_token_t aTokens)
This API sets one or more callback(s) to the active state.
uint32 isf_duration_t
ISF time duration in microseconds.
Definition: isf.h:59
long int32
This defines int32 as long.
Definition: isf_types.h:32
isf_SensorDataTypes_t resultType
Main ISF header file. Contains code common to all ISF components.
LWEVENT_STRUCT * pEventGroup
short int16
This defines int16 as short.
Definition: isf_types.h:23
The isf_sm_api.h contains the collection of APIs for the Sensor Manager as well as related defines an...
isf_dsa_AdapterStatus_t adapterStatus
sys_channelId_t channelId
isf_dsa_status_t fsl_fxls8471_i2cspi_3D_accel_ValidateSettings(isf_SensorHandle_t *pSensorHandle, isf_dsa_SensorSettings_t *pSensorSettings)
Standard float type for three axis accelerometers.
isf_status_t dm_device_read(dm_DeviceDescriptor_t *apDeviceDescriptor, int32 aOffset, uint8 *apReadBuffer, uint32 aBuffsize, uint32 aNbyteRead)
This function reads from a device.
unsigned short uint16
This defines uint16 as unsigned short.
Definition: isf_types.h:27
#define BM_ERROR
This value specifies a general Bus Manager error. If an error occurs in registering a callback...
Definition: isf_bm.h:57
isf_dsa_status_t fsl_fxls8471_i2cspi_3D_accel_StartData(isf_SensorHandle_t *pSensorHandle)
int32 isf_status_t
ISF return status type.
Definition: isf.h:51
This structure defines the dummy DSA data buffer format.
This defines the DSA sensor configuration parameter structure configuring the sensor settings by a su...
isf_spi_master_types.h defines the spi protocol adapter structure and types.
isf_comm.h defines the common types for the Communications Service Family of the Intelligent Sensing ...
isf_status_t dm_channel_configure(dm_ChannelDescriptor_t *apChannelDescriptor, dm_ChannelConfig_ptr apChannelConfig)
This function reconfigures an already initialized channel.
isf_dsa_SensorSettings_t sensorSettings
void * isf_fifo_el_get_insert_pointer(isf_fifo_t *pFifo)
Routine returns the insert pointer for direct access.
Definition: isf_fifo.c:232
isf_status_t dm_channel_release_lock(dm_ChannelDescriptor_t *apChannelDescriptor)
This function releases exclusive channel access.
This structure defines a handle for the device.
Definition: isf_devmsg.h:61
void fsl_fxls8471_i2cspi_3D_accel_PeriodicCallback(void *pSensorHandle)
The isf_accelerometer_types.h file contains the ISF data type definitions for use with the ISF generi...
void fxls8471_CheckId(int32_t *status, void *pSensorHandle)
This function validates the FXLS8471 sensor is connected via the I2C bus.
This structure is a declaration of a channel descriptor type.
Definition: isf_devmsg.h:50
#define ISF_FIFO_FULL
Definition: isf_fifo.h:32
bm_callback_token_t token
Definition: isf_sensors.h:53
isf_dsa_status_t fsl_fxls8471_i2cspi_3D_accel_Initialize(isf_SensorHandle_t *pSensorHandle)