ISF  2.2 rev 5
Intelligent Sensing Framework for Kinetis with Processor Expert
fsl_mag3110_i2c_3D_mag.c
Go to the documentation of this file.
1 /**
2  ** @file fsl_mag3110_i2c_3D_mag.c
3  ** @brief MAG3110 Sensor Adapter header file
4  ** @copyright Copyright (c) 2015, Freescale Semiconductor, Inc.
5  ** @version 01.00
6  ** @brief
7  **
8  */
9 
10 #include <isf.h>
11 #include <isf_types.h>
12 #include <isf_sm_api.h>
13 #include <isf_dsa_adapter.h>
14 #include <isf_bm.h>
15 #include <isf_sensor_types.h>
16 #include <isf_fifo.h>
17 #include <isf_magnetometer_types.h>
18 #include <isf_comm.h>
19 #include <isf_util.h>
20 #include <isf_sensors.h>
21 #include "fsl_os_abstraction.h"
22 #include "mag3110.h"
23 #include "fsl_i2c_master_driver.h"
24 #include "fsl_mag3110_i2c_3D_mag.h"
25 
26 
27 /* MAG3110 Sensor Output conversion factors */
28 #define MAG3110_MAG_FLOAT_CONVERSION_FACTOR (0.1)
29 #define MAG3110_MAG_FLOAT_CONVERSION_OFFSET (0.0)
30 #define MAG3110_MAG_FIXED_CONVERSION_FACTOR (6554)
31 #define MAG3110_MAG_FIXED_CONVERSION_OFFSET (0)
32 
33 /* Declare the local helper functions for MAG3110 */
34 void mag3110_Reset(int32_t *status, isf_SensorHandle_t* pSensorHandle);
35 void mag3110_CheckId(int32_t *status, isf_SensorHandle_t* pSensorHandle);
36 void mag3110_ValidateConfig(int32_t *status, isf_SensorHandle_t* pSensorHandle, isf_dsa_SensorSettings_t *pSubSettings);
37 void mag3110_SetMode(int32_t *status, isf_SensorHandle_t* pSensorHandle, int32_t Mode);
38 void mag3110_GetData(int32_t *status, isf_SensorHandle_t* pSensorHandle, void* pBuffer);
39 void mag3110_SetConfig(int32_t *status, isf_SensorHandle_t* pSensorHandle, isf_dsa_SensorSettings_t *pSubSettings);
40 uint8 get_config_bits(mag_config_t *cfg, uint8 *ratebits, uint8 *osbits);
41 
42 static isf_dsa_status_t float_magfs3d_converter(mag3110_Sensor_Specific_Settings_t *pSensorSpecificConfig, mag3110_DataBuffer_t *nativeSample, void *vpConvertedSample );
43 static isf_dsa_status_t fixed_magfs3d_converter(mag3110_Sensor_Specific_Settings_t *pSensorSpecificConfig, mag3110_DataBuffer_t *nativeSample, void *vpConvertedSample );
44 static isf_dsa_status_t count_magfs3d_converter(mag3110_Sensor_Specific_Settings_t *pSensorSpecificConfig, mag3110_DataBuffer_t *nativeSample, void *vpConvertedSample );
45 /*! @brief Supported sensor and data types for MMA8652 */
48 
49 /*
50  ** ===================================================================
51  ** Method : fsl_mag3110_i2c_3D_mag_Initialize (component ISFDSA)
52  ** @brief
53  **
54  ** Parameters :
55  ** NAME - DESCRIPTION
56  ** @param
57  ** void* pSensorHandle -
58  ** @return
59  ** int32_t -
60  ** ===================================================================
61  */
63 {
64  if ( NULL == pSensorHandle){
65  return DSA_ERR_PARAM;
66  }
67 
68  int32_t status;
69 
70  // Check if the sensor is available, and that it has already been initialized.
71  if (pSensorHandle->adapterStatus > DSA_STATE_NOT_INITIALIZED) {
72  return DSA_ERR_INITIALIZE;
73  }
74 
75  // Allocate the adapter specific memory for the descriptor
76  //pSensorHandle->pDeviceDescriptor = (DeviceDescriptor_t *)_lwmem_alloc_system_zero(sizeof(DeviceDescriptor_t));
77  pSensorHandle->pDeviceDescriptor = (DeviceDescriptor_t *)OSA_MemAllocZero(sizeof(DeviceDescriptor_t));
78 
79  // Create and validate helper reference pointers.
80  DeviceDescriptor_t *pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHandle->pDeviceDescriptor;
81 
82  if (NULL == pDeviceDescriptor) {
83  return DSA_ERR_INITIALIZE;
84  }
85 
86  // Allocate the current sample data buffer and initialize it.
87  //pDeviceDescriptor->pCurrentSample = _lwmem_alloc_system_zero(sizeof(mag3110_DataBuffer_t));
88  pDeviceDescriptor->pCurrentSample = OSA_MemAllocZero(sizeof(mag3110_DataBuffer_t));
89  mag3110_DataBuffer_t *pCurrentSampleBuffer = (mag3110_DataBuffer_t *)pDeviceDescriptor->pCurrentSample;
90  pCurrentSampleBuffer->timeStamp = 0;
91  pCurrentSampleBuffer->mag[0] = 0;
92  pCurrentSampleBuffer->mag[1] = 0;
93  pCurrentSampleBuffer->mag[2] = 0;
94  pCurrentSampleBuffer->addr = ((i2c_device_t *)pSensorHandle->pSensorStaticConfig->commInfo)->address;
95 
96  dm_ChannelDescriptor_t *pChannelDescriptor = &pDeviceDescriptor->cDescriptor;
97 
98  // Initialize the channel
99  if(ISF_SUCCESS != dm_channel_init(pSensorHandle->pSensorStaticConfig->channelId, pChannelDescriptor)){
100  return DSA_ERR_INITIALIZE;
101  }
102  // Start the Bus
103  if(ISF_SUCCESS != dm_channel_start(pChannelDescriptor)){
104  return DSA_ERR_INITIALIZE;
105  }
106 
107  // Get the Channel state to check if it is ready to use
108  if (COMM_STATE_OK != dm_channel_get_state(pChannelDescriptor)) {
109  return DSA_ERR_INITIALIZE;
110  }
111 
112  // Open the device and get the device handler
113  if(ISF_SUCCESS != dm_device_open(pChannelDescriptor, (void *)pSensorHandle->pSensorStaticConfig->commInfo, &pDeviceDescriptor->deviceHandle)){
114  return DSA_ERR_INITIALIZE;
115  }
116 
117  // A very short delay is needed for device startup.
118  OSA_TimeDelay(1);
119 
120  // Query the sensor to validate Device Messaging initialization and the sensor identity.
121  mag3110_CheckId(&status,pSensorHandle);
122  if (ISF_SUCCESS != status)
123  {
124  return DSA_ERR_INITIALIZE;
125  }
126 
127  // Set the adapter state to be initialized.
128  pSensorHandle->adapterStatus = DSA_STATE_INITIALIZED;
129 
130  // Create a semaphore to synchronize the device descriptor across tasks
131  //if (MQX_OK != _lwsem_create(&pDeviceDescriptor->deviceSemaphore, 1)){
132  if (kStatus_OSA_Success != OSA_SemaCreate(&pDeviceDescriptor->deviceSemaphore, 1)){
133  return DSA_ERR_INITIALIZE;
134  }
135 
136  pDeviceDescriptor->skipFramecnt = 0;
137 
138  return ISF_SUCCESS;
139 }
140 
141 /*
142  ** ===================================================================
143  ** Method : fsl_mag3110_i2c_3D_mag_ValidateSettings (component ISFDSA)
144  ** @brief
145  **
146  ** Parameters :
147  ** NAME - DESCRIPTION
148  ** @param
149  ** void* pSensorHandle -
150  ** @param
151  ** void* pSettings -
152  ** @return
153  ** int32_t -
154  ** ===================================================================
155  */
157 {
158  // Check the input arguments.
159  if ((NULL == pSensorHandle) || (NULL == pSubSettings)) {
160  return DSA_ERR_PARAM;
161  }
162 
163  int32_t status;
164 
165  mag3110_ValidateConfig(&status,pSensorHandle,pSubSettings);
166 
167  return status;
168 }
169 
170 /*
171  ** ===================================================================
172  ** Method : fsl_mag3110_i2c_3D_mag_Configure (component ISFDSA)
173  ** @brief
174  **
175  ** Parameters :
176  ** NAME - DESCRIPTION
177  ** @param
178  ** void* pSensorHandle -
179  ** @param
180  ** void* pConfigSettings -
181  ** @return
182  ** int32_t -
183  ** ===================================================================
184  */
185 //#define DEBUG_READ_ALL_REGS
186 #ifdef DEBUG_READ_ALL_REGS
187 static uint8 debugRegs[18];
188 #endif
190 {
191  // Check pointers.
192  if((NULL == pSensorHandle) || (NULL == pSensorSettings) ){
193  return DSA_ERR_PARAM;
194  }
195 
196  int32_t status;
197 
198  int32_t retStat = DSA_ERR_CONFIGURE; // Return Status
199 
200  // Create helper reference pointers.
201  DeviceDescriptor_t *pDeviceDescriptor = (DeviceDescriptor_t*) pSensorHandle->pDeviceDescriptor;
202 
203  // Check the device descriptor pointer.
204  if (NULL == pDeviceDescriptor)
205  {
206  return retStat;
207  }
208 
209  // Lock the device descriptor.
210  //_lwsem_wait_ticks(&pDeviceDescriptor->deviceSemaphore, 0);
211  OSA_SemaWait(&pDeviceDescriptor->deviceSemaphore, OSA_WAIT_FOREVER);
212 
213  // Check the driver state.
214  if (DSA_STATE_INITIALIZED > pSensorHandle->adapterStatus){
215  goto unlockdescriptor;
216  }
217 
218  // User Notice: This is a required function call. If it is not here, there may be conflicts, data loss,
219  // or any number of undesirable things may occur.
220  if (ISF_SUCCESS != dm_channel_acquire_lock(&pDeviceDescriptor->cDescriptor, 0)) {
221  goto unlockdescriptor;
222  }
223 
224  // Set the sensor into STANDBY mode for configuration.
225  mag3110_SetMode(&status, pSensorHandle, SENSOR_STANDBY);
226  if (ISF_SUCCESS != status) {
227  goto unlockchannel;
228  }
229 
230  // Configure the sensor.
231  mag3110_SetConfig(&status, pSensorHandle, pSensorSettings);
232  if (ISF_SUCCESS != status) {
233  goto unlockchannel;
234  }
235 
236 #ifdef DEBUG_READ_ALL_REGS
237  for (int i=0; i<sizeof(debugRegs); i++)
238  {
239  dm_device_read(&pDeviceDescriptor->deviceHandle,i, &debugRegs[i], 1, 1);
240  }
241 #endif
242  // Register the periodic callback function with the Bus Manager.
243  pDeviceDescriptor->token = bm_register_periodic_callback( pSensorSettings->nSamplePeriod, fsl_mag3110_i2c_3D_mag_PeriodicCallback , (void *)pSensorHandle);
244  if(BM_ERROR & pDeviceDescriptor->token){
245  goto unlockchannel;
246  }
247 
248  //Store the configured settings
249  pSensorHandle->controlData.sensorSettings = *pSensorSettings;
250 
252  retStat = ISF_SUCCESS;
253 
254 unlockchannel:
255  // Unlock the channel.
256  // The explicit lock must be released when the configuration is done allowing the bus to be used by others.
257  // User Notice: This is a required function call.
258  status = dm_channel_release_lock(&pDeviceDescriptor->cDescriptor);
259  if (ISF_SUCCESS != status)
260  {
261  retStat = status;
262  }
263 
264 unlockdescriptor:
265 
266  // Unlock the device descriptor.
267  //_lwsem_post(&pDeviceDescriptor->deviceSemaphore);
268  OSA_SemaPost(&pDeviceDescriptor->deviceSemaphore);
269 
270  return retStat;
271 }
272 
273 /*
274  ** ===================================================================
275  ** Method : fsl_mag3110_i2c_3D_mag_StartData (component ISFDSA)
276  ** @brief
277  **
278  ** Parameters :
279  ** NAME - DESCRIPTION
280  ** @param
281  ** void* pSensorHandle -
282  ** @return
283  ** int32_t -
284  ** ===================================================================
285  */
287 {
288  // Check pointers.
289  if(NULL == pSensorHandle){
290  return DSA_ERR_PARAM;
291  }
292 
293  int32_t status;
294  int32_t retStat = DSA_ERR_START_DATA;
295 
296  // Create helper reference pointers.
297  DeviceDescriptor_t* pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHandle->pDeviceDescriptor;
298 
299  // Check the device descriptor.
300  if (NULL == pDeviceDescriptor)
301  return DSA_ERR_PARAM;
302 
303  // Lock the device descriptor.
304  //_lwsem_wait_ticks(&pDeviceDescriptor->deviceSemaphore, 0);
305  OSA_SemaWait(&pDeviceDescriptor->deviceSemaphore, OSA_WAIT_FOREVER);
306 
307  // Check the driver state.
308  if (DSA_STATE_CONFIGURED_STOPPED > pSensorHandle->adapterStatus)
309  {
310  goto unlockdescriptor;
311  }
312 
313  // Set the sensor into ACTIVE mode for operation.
314  mag3110_SetMode(&status, pSensorHandle, SENSOR_ACTIVE);
315  if (ISF_SUCCESS != status) {
316  goto unlockdescriptor;
317  }
318 
319  // Start the Bus Manager sampling timer.
320  if (BM_ERROR & bm_start(FALSE, pDeviceDescriptor->token)) // Check for Bus Manager error and return on failure.
321  goto unlockdescriptor;
322 
323  // Set device to active state.
325  retStat = ISF_SUCCESS;
326 
327 unlockdescriptor:
328  // Unlock the device descriptor.
329  //_lwsem_post(&pDeviceDescriptor->deviceSemaphore);
330  OSA_SemaPost(&pDeviceDescriptor->deviceSemaphore);
331 
332 
333  return retStat;
334 }
335 
336 /*
337  ** ===================================================================
338  ** Method : fsl_mag3110_i2c_3D_mag_EndData (component ISFDSA)
339  ** @brief
340  **
341  ** Parameters :
342  ** NAME - DESCRIPTION
343  ** @param
344  ** void* pSensorHandle -
345  ** @return
346  ** int32_t -
347  ** ===================================================================
348  */
350 {
351  // Check pointers.
352  if(NULL == pSensorHandle){
353  return DSA_ERR_PARAM;
354  }
355 
356  int32_t status;
357 
358  // Create helper reference pointers.
359  DeviceDescriptor_t* pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHandle->pDeviceDescriptor;
360 
361  // Set the default return status.
362  int32_t retStat = DSA_ERR_END_DATA;
363 
364  // Check the device descriptor.
365  if (NULL == pDeviceDescriptor)
366  return retStat;
367 
368  // Lock the device descriptor.
369  //_lwsem_wait_ticks(&pDeviceDescriptor->deviceSemaphore, 0);
370  OSA_SemaWait(&pDeviceDescriptor->deviceSemaphore, OSA_WAIT_FOREVER);
371 
372  // Check the driver state.
373  if (DSA_STATE_CONFIGURED_STOPPED >= pSensorHandle->adapterStatus)
374  goto unlockdescriptor;
375 
376  // Check that the adapter is not already started.
377  if (DSA_STATE_CONFIGURED_STARTED == pSensorHandle->adapterStatus) {
378  // If it is, then stop the Bus Manager (BM) sample timer.
379  isf_status_t bmStopStatus = bm_stop(pDeviceDescriptor->token);
380  if (BM_ERROR & bmStopStatus)
381  goto unlockdescriptor;
382  }
383 #if 0
384  // Set the sensor into STANDBY mode for configuration.
385  mag3110_SetMode(&status, pSensorHandle, SENSOR_STANDBY);
386 #endif
387  if (ISF_SUCCESS != status) {
388  goto unlockdescriptor;
389  }
390 
392  retStat = ISF_SUCCESS;
393 
394 
395 unlockdescriptor:
396  // Unlock the device descriptor.
397  //_lwsem_post(&pDeviceDescriptor->deviceSemaphore);
398  OSA_SemaPost(&pDeviceDescriptor->deviceSemaphore);
399 
400  return retStat;
401 }
402 
403 /*
404  ** ===================================================================
405  ** Method : fsl_mag3110_i2c_3D_mag_Calibrate (component ISFDSA)
406  ** @brief
407  **
408  ** Parameters :
409  ** NAME - DESCRIPTION
410  ** @param
411  ** void* pSensorHandle -
412  ** @return
413  ** int32_t -
414  ** ===================================================================
415  */
417 {
418  int32_t retStat = ISF_SUCCESS;
419 
420  return retStat;
421 }
422 
423 /*
424  ** ===================================================================
425  ** Method : fsl_mag3110_i2c_3D_mag_Shutdown (component ISFDSA)
426  ** @brief
427  **
428  ** Parameters :
429  ** NAME - DESCRIPTION
430  ** @param
431  ** void* pSensorHandle -
432  ** @return
433  ** int32_t -
434  ** ===================================================================
435  */
437 {
438  if(NULL == pSensorHandle){
439  return DSA_ERR_PARAM;
440  }
441 
442  // Create helper reference pointers.
443  DeviceDescriptor_t* pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHandle->pDeviceDescriptor;
444 
445  // Remove the sensor adapter from the Bus Manager callbacks.
446  bm_unregister_callback(pDeviceDescriptor->token);
447  pSensorHandle->adapterStatus = DSA_STATE_INITIALIZED;
448  return ISF_SUCCESS;
449 }
450 
451 /*
452  ** ===================================================================
453  ** Method : fsl_mag3110_i2c_3D_mag_PeriodicCallback (component ISFDSA)
454  ** @brief
455  **
456  ** Parameters :
457  ** NAME - DESCRIPTION
458  ** @param
459  ** void* pSensorHandle -
460  ** @return
461  ** void -
462  ** ===================================================================
463  */
465 {
466  // Check pointers.
467  if(NULL == pSensorHandle){
468  return;
469  }
470 
471  int32_t status;
472  int32 numBytes;
473 
474  // Create helper reference pointers.
475  volatile isf_SensorHandle_t *pSensorHdl = (isf_SensorHandle_t *)pSensorHandle;
477  DeviceDescriptor_t *pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHdl->pDeviceDescriptor;
478  isf_status_t st;
479 
480  // Check the device descriptor
481  if (NULL == pDeviceDescriptor){
482  return;
483  }
484 
485  // Create a helper pointer to the current sample buffer.
486  mag3110_DataBuffer_t *pCurrentSampleBuffer = (mag3110_DataBuffer_t *)pDeviceDescriptor->pCurrentSample;
487 
488  // Apply sample skip if necessary.
489  if (pDeviceDescriptor->skipFramecnt) {
490  // Not done skipping samples.
491  --pDeviceDescriptor->skipFramecnt;
492  return;
493  }
494 
495  // Get the time stamp
496  pCurrentSampleBuffer->timeStamp = isf_time_util_get_usec();
497 
498  // Lock the device descriptor.
499  //if (MQX_OK !=_lwsem_wait_ticks(&pDeviceDescriptor->deviceSemaphore, 0))
500  if (kStatus_OSA_Success !=OSA_SemaWait(&pDeviceDescriptor->deviceSemaphore, OSA_WAIT_FOREVER))
501  {
502  goto unlockdescriptor;
503  }
504 
505 
506  // Check the driver state.
507  if (DSA_STATE_CONFIGURED_STARTED != pSensorHdl->adapterStatus)
508  {
509  goto unlockdescriptor;
510  }
511 
512  // Get sensor data.
513  mag3110_GetData(&status, pSensorHandle, ((uint8*)&pCurrentSampleBuffer->mag[0]));
514 
515  // Convert the samples to big endian.
516  pCurrentSampleBuffer->mag[0] = isf_swap2byte(pCurrentSampleBuffer->mag[0]);
517  pCurrentSampleBuffer->mag[1] = isf_swap2byte(pCurrentSampleBuffer->mag[1]);
518  pCurrentSampleBuffer->mag[2] = isf_swap2byte(pCurrentSampleBuffer->mag[2]);
519 
520 #ifdef DEBUG_READ_ALL_REGS
521  for (int i=0; i<sizeof(debugRegs); i++)
522  {
523  dm_device_read(&pDeviceDescriptor->deviceHandle,i, &debugRegs[i], 1, 1);
524  }
525 #endif
526  // Lock the fifo for update.
527  if(kStatus_OSA_Success != isf_fifo_lock(pFifo)){
528  return;
529  }
530 
532 
533 
534  // write the new data
536  {
537  *pFifoEntry = *pCurrentSampleBuffer;
538  }
539  else
540  {
542  pSensorHdl,
545  pCurrentSampleBuffer,
546  pFifoEntry,
547  &numBytes);
548  }
549 
550  // Increment the fifo to the next sample entry.
551  st = isf_fifo_el_increment(pFifo);
552 
553  // Unlock the fifo.
554  isf_fifo_unlock(pFifo);
555 
556  if (st == ISF_FIFO_FULL)
557  {
558  // Notify the user using their registered event information
559  //_lwevent_set(pSensorHdl->controlData.pEventGroup,(uint32_t)pSensorHdl->controlData.nEventFieldIndex);
560  OSA_EventSet(pSensorHdl->controlData.pEventGroup,(uint32_t)pSensorHdl->controlData.nEventFieldIndex);
561  }
562 
563 unlockdescriptor:
564  // Unlock the device descriptor.
565  //_lwsem_post(&pDeviceDescriptor->deviceSemaphore);
566  OSA_SemaPost(&pDeviceDescriptor->deviceSemaphore);
567 
568 }
569 
570 /*!
571  * @brief This function coverts the raw sample data to the desired output type.
572  */
574  (
575  volatile isf_SensorHandle_t *pSensorHandle,
576  isf_SensorDataTypes_t convertToType, isf_dsa_result_types_t resultType,
577  void *pNativeSample,
578  void *pConvertedSample,
579  int32 *numBytes
580  )
581 {
584 
585  pConverter = NULL;
586 
587  switch (convertToType)
588  {
590  if (resultType == DSA_RESULT_TYPE_ENG_FLOAT)
591  pConverter = float_magfs3d_converter;
592  else if (resultType == DSA_RESULT_TYPE_ENG_FIXED)
593  pConverter = fixed_magfs3d_converter;
594  else if(resultType == DSA_RESULT_TYPE_RAW_COUNTS)
595  pConverter = count_magfs3d_converter;
596  break;
597 
598  default:
600  }
601  if (pConverter == NULL)
603 
604  retStat = pConverter(
606  (mag3110_DataBuffer_t *)pNativeSample,
607  pConvertedSample
608  );
609 
610  return retStat;
611 }
612 
613 static isf_dsa_status_t float_magfs3d_converter(mag3110_Sensor_Specific_Settings_t *pSensorSpecificConfig, mag3110_DataBuffer_t *nativeSample, void *vpConvertedSample )
614 {
615  isf_MagneticFieldStrength3D_float_t *convertedSample = (isf_MagneticFieldStrength3D_float_t *)vpConvertedSample;
616  convertedSample->timestamp = nativeSample->timeStamp;
617  // These factors and offsets really depend on the configured sensor Range in pSensorSpecificConfig
621 
622  return ISF_SUCCESS;
623 }
624 
625 static isf_dsa_status_t fixed_magfs3d_converter(mag3110_Sensor_Specific_Settings_t *pSensorSpecificConfig, mag3110_DataBuffer_t *nativeSample, void *vpConvertedSample )
626 {
628  convertedSample->timestamp = nativeSample->timeStamp;
629  // These factors and offsets really depend on the configured sensor Range in pSensorSpecificConfig
633 
634  return ISF_SUCCESS;
635 }
636 static isf_dsa_status_t count_magfs3d_converter(mag3110_Sensor_Specific_Settings_t *pSensorSpecificConfig, mag3110_DataBuffer_t *nativeSample, void *vpConvertedSample )
637 {
639  convertedSample->timestamp = nativeSample->timeStamp;
640  // FXOS8700 has a fixed range, so use the fixed conversion constants.
641  convertedSample->fieldStrength[0] = nativeSample->mag[0] ;
642  convertedSample->fieldStrength[1] = nativeSample->mag[1] ;
643  convertedSample->fieldStrength[2] = nativeSample->mag[2] ;
644 
645  return ISF_SUCCESS;
646 }
647 /*!
648  * @brief This function resets the MAG3110 sensor resulting in a default configuration for
649  * all registers.
650  */
651 void mag3110_Reset(int32_t *status, isf_SensorHandle_t* pSensorHandle)
652 {
653  *status = ISF_SUCCESS;
654 }
655 
656 /*!
657  * @brief This function validates the MAG3110 sensor is connected via the I2C bus.
658  */
659 void mag3110_CheckId(int32_t *status, isf_SensorHandle_t* pSensorHandle)
660 {
661  uint8 buffer[1];
663 
664  // Create and validate helper reference pointers.
665  DeviceDescriptor_t *pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHandle->pDeviceDescriptor;
666  dm_DeviceDescriptor_t* pDeviceHandle = &pDeviceDescriptor->deviceHandle;
667 
668  if (ISF_SUCCESS != dm_device_read(pDeviceHandle, MAG3110_WHO_AM_I, &buffer[0], 1, 1)){
669  *status = retStat;
670  }
671  if (MAG3110_WHOAMI_VALUE != buffer[0]) {
672  *status = retStat;
673  }
674 
675 
676  *status = ISF_SUCCESS;
677 }
678 
679 /*!
680  * @brief This function validates the configuration for the MAG3110 sensor.
681  */
682 void mag3110_ValidateConfig(int32_t *status, isf_SensorHandle_t* pSensorHandle, isf_dsa_SensorSettings_t *pSubSettings)
683 {
684  int32_t st; // The status variable.
685  mag_config_t cfg; // The configuration variable.
686  uint8 rateBits; // The MAG3110 rate bits, i.e. DR2,DR1,DR0.
687  uint8 osBits; // The MA3110 over sample bits, i.e.OS1, OS0.
688 
690 
691  cfg.period = pSubSettings->nSamplePeriod;
692  cfg.overSampleRate = pConfigSpecific->overSamplingRatio;
693 
694  // Validate the configuration data.
695  st = get_config_bits( &cfg, &rateBits, &osBits);
696 
697  // If the sample rate has been modified. convey this information to user Application.
698  if (st && (pSubSettings->nSamplePeriod != cfg.period)) {
699  pSubSettings->nSamplePeriod = cfg.period;
700  *status = DSA_RET_SETTINGS_CHANGED;
701  }
702  else {
703  *status = ISF_SUCCESS;
704  }
705 }
706 
707 /*!
708  * @brief This function sets the MAG3110 part to the requested mode.
709  */
710 void mag3110_SetMode(int32_t *status, isf_SensorHandle_t* pSensorHandle, int32_t Mode)
711 {
712  DeviceDescriptor_t *pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHandle->pDeviceDescriptor;
713  dm_DeviceDescriptor_t* pDeviceHandle = &pDeviceDescriptor->deviceHandle;
714 
715  uint8 buffer[1] = {0x00};
716 
717  switch(Mode)
718  {
719  case SENSOR_STANDBY:
720  {
721  if (ISF_SUCCESS != dm_device_read(pDeviceHandle,MAG3110_CTRL_REG1, buffer, 1, 1))
722  {
723  *status = SENSOR_ERROR_SETMODE;
724  return;
725  }
726  buffer[0] &= ~MAG3110_AC_MASK; // AC = 0: STANDBY Mode.
727  if (ISF_SUCCESS != dm_device_write(pDeviceHandle, MAG3110_CTRL_REG1, &buffer[0], 1, 1)){
728  *status = SENSOR_ERROR_SETMODE;
729  return;
730  }
731  }
732  break;
733  case SENSOR_ACTIVE:
734  {
735  if (ISF_SUCCESS != dm_device_read(pDeviceHandle,MAG3110_CTRL_REG1, buffer, 1, 1))
736  {
737  *status = SENSOR_ERROR_SETMODE;
738  return;
739  }
740  buffer[0] |= MAG3110_AC_MASK; // AC = 1: ACTIVE Mode.
741  if (ISF_SUCCESS != dm_device_write(pDeviceHandle, MAG3110_CTRL_REG1, &buffer[0], 1, 1)){
742  *status = SENSOR_ERROR_SETMODE;
743  return;
744  }
745  }
746  break;
747  case SENSOR_BOOT:
748  case SENSOR_READY:
749  default:
750  *status = SENSOR_ERROR_SETMODE;
751  return;
752  }
753 
754  *status = ISF_SUCCESS;
755 }
756 
757 /*!
758  * @brief This function retrieves the raw data from the MAG3110 sensor.
759  */
760 void mag3110_GetData(int32_t *status, isf_SensorHandle_t* pSensorHandle, void* pBuffer)
761 {
763  DeviceDescriptor_t *pDeviceDescriptor = (DeviceDescriptor_t*)pSensorHandle->pDeviceDescriptor;
764  dm_DeviceDescriptor_t* pDeviceHandle = &pDeviceDescriptor->deviceHandle;
765 
766  // Get fsl_mag3110_i2c_3D_mag data.
767  {
768 
770  *status = retStat;
771  }
772 
773  }
774 
775 }
776 
777 /*!
778  * @brief This function sets the MAG3110 sensor configuration.
779  */
780 void mag3110_SetConfig(int32_t *status, isf_SensorHandle_t* pSensorHandle, isf_dsa_SensorSettings_t *pSubSettings)
781 {
782  int32_t st; // The status variable from get_config_bits().
783  int32_t retStat = DSA_ERR_CONFIGURE; // Return Status
784  mag_config_t cfg; // Temporary variable to hold the configuration settings.
785  uint8 rateBits; // MAG3110 rate bits variable, i.e.DR2,DR1,DR0.
786  uint8 osBits; // MAG3110 over sample bits, i.e.OS1, OS0.
787 
788  // Create helper reference pointers.
789  DeviceDescriptor_t *pDeviceDescriptor = (DeviceDescriptor_t*) pSensorHandle->pDeviceDescriptor;
791  dm_DeviceDescriptor_t *pDeviceHandle = &pDeviceDescriptor->deviceHandle;
792 
793  /* Write the sensor specific data based on the pre-computed register level pairs (Addr, Value) */
794  uint8 buffer[1];
795  for (uint32 reg=0; reg < pConfigSpecific->regCount; reg++)
796  {
797  buffer[0] = pConfigSpecific->regPairs[reg].regValue;
798  if (ISF_SUCCESS != dm_device_write(pDeviceHandle, pConfigSpecific->regPairs[reg].regAddr,&buffer[0],1,1))
799  {
800  *status = retStat;
801  return;
802  }
803  }
804 
805 
806  {
807 #if 0 // Mode is no longer set through subscription
808  uint8 buffer[1] = {0x00};
809  if((FSL_MAG3110_MODE_NON_RAW_FAST == pSubSettings->nMode) || (FSL_MAG3110_MODE_RAW_FAST == pSubSettings->nMode)){
810  pDeviceDescriptor->dataBlockSize = MAG3110_NUMBER_AXIS;
811  buffer[0] = MAG3110_SET_FIELD(FR,1);
812  }
813  else
814  {
816  }
817 #endif
818 
819  // Compute the rate and over sample bit settings
820  cfg.period = pSubSettings->nSamplePeriod;
821  cfg.overSampleRate = pConfigSpecific->overSamplingRatio;
822 
823  st = get_config_bits( &cfg, &rateBits, &osBits);
824 
825  // Send the command to the device.
826  if (ISF_SUCCESS != dm_device_read(pDeviceHandle, MAG3110_CTRL_REG1, &buffer[0], 1, 1)){
827  *status = retStat;
828  return;
829  }
830  // Set the control register for output and over-sampling rates.
831  buffer[0] |= MAG3110_SET_FIELD(DR,rateBits) | MAG3110_SET_FIELD(OS,osBits);
832 
833  // Send the command to the device.
834  if (ISF_SUCCESS != dm_device_write(pDeviceHandle, MAG3110_CTRL_REG1, &buffer[0], 1, 1)){
835  *status = retStat;
836  return;
837  }
838  }
839 
840  // If the sample period had to be modified, tell the user what the new value is
841  if (st && (pSubSettings->nSamplePeriod != cfg.period))
842  {
843  pSubSettings->nSamplePeriod = cfg.period;
844  *status = DSA_RET_SETTINGS_CHANGED;
845  }
846  else
847  {
848  *status = ISF_SUCCESS;
849  }
850 }
851 
852 /*! @brief This function obtains the configuration register values for a given user configuration of the MAG3110.
853  *
854  * @details This function computes the rate bits (DR2, DR1, DR0) and oversample bits (OS1, OS0) corresponding
855  * to the requested configuration provided by the configuration. If the requested configuration
856  * is not supported, the configuration is adjusted to the closest supported rate and the adjusted values
857  * are returned. ::get_config_bits() uses binary bit operations to move between the MAG3110's rate and
858  * the oversample bit configuration patterns. The sample period is in usecs.
859  *
860  * For example, when the rateBits are all zeros, the sample period is 12500 usecs. As the rateBits are
861  * provided as a 3 digit binary number, each increment of rateBits doubles the period. In general:
862  * Rate = 12500 << rateBits.
863  *
864  * The oversample bits determine how many samples are taken internally for each output sample.
865  * With the OsBits viewed as a 2 digit binary number, an OsBits value of 0 means an
866  * over sample rate of 16 and each increment of the OsBits doubles the over sample rate.
867  * In general:
868  * Over sample Rate = 1 <<(OsBits + 4)
869  * The internal ADC sample period is then:
870  * ADC period = 12500 << ( rateBits + OsBits )
871  *
872  * Given an arbitrary period in usecs and a desired over sample rate, the closest supported adc rate is
873  * computed by performing the following:
874  * The requested period is right shifted by the OsBits value + 2.
875  * This produces a normalized value of 3125 decimal for the the smallest supported rate (12500 usecs at
876  * 16x over sampling). 3125 decimal is 0b110000110101 and a findFirstOne (ff1) on this returns 20.
877  *
878  * Since all supported rates are powers of 2 larger than this base number, a findFirstOne(ff1) is
879  * performed on this normalized rate and subtracting it from 20 is the number of rateBits that must
880  * be set to get the desired rate. If this is too large, the number can be limited to the maximum
881  * rateBits allowed (7) and/or the over sampling rate can be reduced to lower the internal ADC rate
882  * to an acceptable rate.
883  *
884  * @param[in] cfg Magnetometer configuration information. ::mag_config_t is the structure type.
885  * @param[out] ratebits The data rate configuration bits.
886  * @param[out] osbits The over sample configuration bits.
887  *
888  * @return ::get_config_bits() returns a value of type ::uint8 indicating the success or failure of the function
889  * call.
890  * @retval 0 is returned when the configuration is valid.
891  * @retval 1 is returned when the configuration is modified.
892  *
893  * @Constraints None
894  *
895  * @Reentrant Yes
896  * @Libs lib_fsl_mag3110_i2c_3D_mag.lib
897  */
898 uint8 get_config_bits(mag_config_t *cfg, uint8 *ratebits, uint8 *osbits)
899 {
900  uint8 op;
901  uint8 opl;
902  uint32 shiftedPeriod;
903  mag_config_t oldCfg = *cfg;
904 
905  /* Save requested configuration for later comparison. */
906  *osbits = cfg->overSampleRate;
907 
908  /* Compute normalized period. */
909  shiftedPeriod = (cfg->period)>>(*osbits+2);
910 
911  /* Quick way to see how much bigger the requested period is compared to the
912  * fastest supported rate.
913  */
914  op = ff1(shiftedPeriod);
915 
916  /* Copy the value before trimming, when required. */
917  opl = op;
918 
919  /* Lower the over sampling rate until the internal rate is acceptable
920  * or the over sampling rate is as low as it can go.
921  */
922  while ( opl > 20 && *osbits ) {
923  opl--;
924  (*osbits)--;
925  }
926 
927  /* If the internal ADC rate is too low, increase the over sampling rate
928  * until the rate is acceptable or the over sampling rate is as high as
929  * it can go.
930  */
931  while ( opl < 13 && (*osbits < 3) ) {
932  opl++;
933  (*osbits)++;
934  }
935 
936  /* If the ADC rate is still not in the acceptable range, apply hard limits
937  * (which will change the rate seen by the user).
938  */
939  if ( op > 20) opl = 20;
940  if ( op < 13) opl = 13;
941 
942  /* Get the new rateBits after adjustments. */
943  *ratebits = 20 - opl;
944 
945  /* Put the adjusted values back in the input structure to return to the user. */
946  cfg->period = 12500<<(*ratebits + *osbits);
947  cfg->overSampleRate = *osbits;
948 
949  /* Set the return status to indicate whether any changes to the requested configuration were made. */
950  return ( cfg->period != oldCfg.period || cfg->overSampleRate != oldCfg.overSampleRate );
951 
952 }
953 
954 /*!
955 ** @}
956 */
957 
958 /* END fsl_mag3110_i2c_3D_mag. */
isf_status_t dm_channel_start(dm_ChannelDescriptor_t *apChannelDescriptor)
This function starts a channel.
void * pSensorSpecificSettings
unsigned char uint8
Definition: isf_types.h:76
This structure defines the dummy DSA data buffer format.
isf_dsa_status_t fsl_mag3110_i2c_3D_mag_Calibrate(isf_SensorHandle_t *pSensorHandle, void *pCalData)
isf_dsa_status_t fsl_mag3110_i2c_3D_mag_Shutdown(isf_SensorHandle_t *pSensorHandle)
void fsl_mag3110_i2c_3D_mag_PeriodicCallback(void *pSensorHandle)
Standard fixed type for three axis accelerometers.
The isf_magnetometer_types.h file contains the ISF data type definitions for use with the ISF generic...
uint32 isf_time_util_get_usec(void)
This API returns the time in microseconds.
Definition: isf_util.c:55
uint8 overSampleRate
Definition: mag3110.h:121
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.
#define MAG3110_MAG_FIXED_CONVERSION_OFFSET
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:170
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:199
isf_microTeslas_raw_16count_t fieldStrength[3]
isf_fifo_status_t isf_fifo_el_increment(isf_fifo_t *pFifo)
Routine increments the insert pointer after direct access.
Definition: isf_fifo.c:237
isf_sensors.h contains the ISF Generic Sensor definitions and data structures required when a client ...
#define MAG3110_MAG_FLOAT_CONVERSION_OFFSET
void mag3110_Reset(int32_t *status, isf_SensorHandle_t *pSensorHandle)
This function resets the MAG3110 sensor resulting in a default configuration for all registers...
#define FALSE
Definition: isf_types.h:86
isf_fieldStrength_uT_float_t fieldStrength[3]
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...
isf_SensorDataTypes_t TYPE_MAGNETIC_FIELD_STRENGTH_3D
The fsl_mag3110_i2c_3D_mag.h file contains the definitions and functions supporting the MAG3110 Senso...
Define the sensor device descriptor.
Definition: isf_sensors.h:49
#define MAG3110_AC_MASK
Definition: mag3110.h:94
isf_microTeslas_fixed_32s1i16_t fieldStrength[3]
isf_dsa_status_t fsl_mag3110_i2c_3D_mag_EndData(isf_SensorHandle_t *pSensorHandle)
uint8 get_config_bits(mag_config_t *cfg, uint8 *ratebits, uint8 *osbits)
This function obtains the configuration register values for a given user configuration of the MAG3110...
isf_SensorTypes_t
dm_ChannelDescriptor_t cDescriptor
Definition: isf_sensors.h:51
isf_dsa_status_t fsl_mag3110_i2c_3D_mag_Initialize(isf_SensorHandle_t *pSensorHandle)
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.
isf_dsa_status_t fsl_mag3110_i2c_3D_mag_ValidateSettings(isf_SensorHandle_t *pSensorHandle, isf_dsa_SensorSettings_t *pSubSettings)
uint32 period
Definition: mag3110.h:120
The isf_types.h file contains the ISF data type definitions and some of the globally used macros...
isf_dsa_status_t fsl_mag3110_i2c_3D_mag_Configure(isf_SensorHandle_t *pSensorHandle, isf_dsa_SensorSettings_t *pSensorSettings)
isf_SensorDataTypes_t mag3110_SupportedDataTypes[]
The mag3110.h contains the MAG3110 Magnetometer register definitions, access macros, and device access functions.
int32 isf_dsa_status_t
This is the Sensor Manager API return type definition.
uint16 isf_swap2byte(uint16 n)
2 byte swapping method
Definition: isf_util.c:156
isf_SensorTypes_t mag3110_SupportedSensorTypes[]
Supported sensor and data types for MMA8652.
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
uint32 ff1(uint32 doubleword)
find first-in.
Definition: isf_util.c:28
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.
void mag3110_CheckId(int32_t *status, isf_SensorHandle_t *pSensorHandle)
This function validates the MAG3110 sensor is connected via the I2C bus.
#define MAG3110_MAG_FIXED_CONVERSION_FACTOR
isf_dsa_result_types_t resultFormat
isf_SensorDataTypes_t
isf_status_t dm_channel_init(dm_ChannelId_t aChannelId, dm_ChannelDescriptor_t *apChannelDescriptor)
This function initializes a channel.
void mag3110_SetMode(int32_t *status, isf_SensorHandle_t *pSensorHandle, int32_t Mode)
This function sets the MAG3110 part to the requested mode.
#define MAG3110_SET_FIELD(name, val)
Definition: mag3110.h:52
void mag3110_GetData(int32_t *status, isf_SensorHandle_t *pSensorHandle, void *pBuffer)
This function retrieves the raw data from the MAG3110 sensor.
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.
isf_SensorDataTypes_t resultType
Main ISF header file. Contains code common to all ISF components.
The isf_sm_api.h contains the collection of APIs for the Sensor Manager as well as related defines an...
The structure defines the MAG3110 configuration.
Definition: mag3110.h:119
isf_dsa_AdapterStatus_t adapterStatus
signed long int int32
Definition: isf_types.h:74
sys_channelId_t channelId
isf_dsa_status_t fsl_mag3110_i2c_3D_mag_StartData(isf_SensorHandle_t *pSensorHandle)
#define MAG3110_NUMBER_BYTES_AXIS
Definition: mag3110.h:18
#define MAG3100_READ_BUF_SIZE
Definition: fxas21002.h:186
isf_status_t dm_device_read(dm_DeviceDescriptor_t *apDeviceDescriptor, int32 aOffset, uint8 *apReadBuffer, uint32 aBuffsize, uint32 aNbyteRead)
This function reads from a device.
#define BM_ERROR
This value specifies a general Bus Manager error. If an error occurs in registering a callback...
Definition: isf_bm.h:57
int32 isf_status_t
ISF return status type.
Definition: isf.h:76
This defines the DSA sensor configuration parameter structure configuring the sensor settings by a su...
isf_comm.h defines the common types for the Communications Service Family of the Intelligent Sensing ...
isf_dsa_SensorSettings_t sensorSettings
#define MAG3110_WHOAMI_VALUE
Definition: mag3110.h:109
void * isf_fifo_el_get_insert_pointer(isf_fifo_t *pFifo)
Routine returns the insert pointer for direct access.
Definition: isf_fifo.c:229
isf_status_t dm_channel_release_lock(dm_ChannelDescriptor_t *apChannelDescriptor)
This function releases exclusive channel access.
unsigned long int uint32
Definition: isf_types.h:78
This structure defines a handle for the device.
Definition: isf_devmsg.h:61
void mag3110_ValidateConfig(int32_t *status, isf_SensorHandle_t *pSensorHandle, isf_dsa_SensorSettings_t *pSubSettings)
This function validates the configuration for the MAG3110 sensor.
isf_SensorDataTypes_t TYPE_MAGNETIC_FIELD_STRENGTH_3D
isf_dsa_status_t fsl_mag3110_i2c_3D_mag_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.
#define MAG3110_MAG_FLOAT_CONVERSION_FACTOR
int32 mag3110_status_t
Definition: mag3110.h:116
semaphore_t deviceSemaphore
Definition: isf_sensors.h:54
This structure is a declaration of a channel descriptor type.
Definition: isf_devmsg.h:50
#define ISF_FIFO_FULL
Definition: isf_fifo.h:33
bm_callback_token_t token
Definition: isf_sensors.h:53
void mag3110_SetConfig(int32_t *status, isf_SensorHandle_t *pSensorHandle, isf_dsa_SensorSettings_t *pSubSettings)
This function sets the MAG3110 sensor configuration.
#define MAG3110_NUMBER_AXIS
The MAG3110 registers, masks, and constants.
Definition: mag3110.h:17