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