ISSDK  1.8
IoT Sensing Software Development Kit
mma865x_freemaster_demo.c
Go to the documentation of this file.
1 /*
2  * Copyright 2020-2021 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 /**
9  * @file mma865x_freemaster_demo.c
10  * @brief The mma865x_freemaster_demo.c file implements FreeMASTER demo using the ISSDK
11  * MMA865x sensor driver example demonstration with interrupt mode.
12  */
13 
14 /* SDK Includes */
15 #include "pin_mux.h"
16 #include "clock_config.h"
17 #include "board.h"
18 #include "fsl_debug_console.h"
19 #include "math.h"
20 #include "fsl_uart.h"
21 #include "fsl_common.h"
22 #include "freemaster.h"
23 #include "freemaster_serial_uart.h"
24 
25 /* CMSIS Includes */
26 #include "Driver_I2C.h"
27 
28 /* ISSDK Includes */
29 #include "issdk_hal.h"
30 #include "gpio_driver.h"
31 #include "mma865x_drv.h"
32 
33 /*******************************************************************************
34  * Macro Definitions
35  ******************************************************************************/
36 
37 #define MMA865x_NUM_REGISTERS (MMA865x_OFF_Z + 1)
38 #define FF_A_FFMT_THS (0x08) /* FreeFall Threshold Value. */
39 #define A_FFMT_COUNT (0x18) /* Freefall/motion debounce count value. */
40 #define PL_COUNT (0x15) /* Pulse debounce count value. */
41 #define ASLP_COUNTER (0x07) /* Auto Sleep after ~5s. */
42 #define ACCEL_2G_SENS (0.000976) /* Sensitivity factor for 2G FS */
43 #define ACCEL_4G_SENS (0.001953) /* Sensitivity factor for 4G FS */
44 #define ACCEL_8G_SENS (0.003906) /* Sensitivity factor for 8G FS */
45 #define N (500U) /* Number of samples used to measure offset/noise */
46 #define RAW_ACCEL_DATA_SIZE (6U) /* Accel Data Size */
47 #define MAX8BITSTORAGE (255U)
48 
49 /*******************************************************************************
50  * Constants
51  ******************************************************************************/
52 /*! @brief Prepare the register write list to configure MMA865x in non-FIFO and ISR mode. */
54 { /*! Clear F_SETUP. */
55  {MMA865x_F_SETUP, 0x00, 0},
56  /*! Configure the MMA865x to set FS Range as 2g. */
58  /*! Configure the MMA865x to set ODR to 100Hz. */
60  /*! Configure the MMA865x to set High Resolution mode. */
62  /*! Configure the MMA865x to set interrupt polarity as Active High. */
64  /*! Configure the MMA865x to set interrupt polarity as Active High. */
66  /*! Configure the MMA865x to set interrupt polarity as Active High. */
67  {MMA865x_PL_COUNT, 0xFF, 0},
68  /*! Configure the MMA865x to set interrupt polarity as Active High. */
70  /*! Configure the MMA865x to set interrupt polarity as Active High. */
71  {MMA865x_FF_MT_COUNT, 0x01, 0},
72  /*! Configure the MMA865x to set interrupt polarity as Active High. */
74  /*! Configure the MMA865x to set interrupt polarity as Active High. */
77  {MMA865x_TRANSIENT_COUNT, 0x0C, 0},
78  /*! Configure the MMA865x to set interrupt polarity as Active High. */
80  {MMA865x_PULSE_THSX, 0x37, 0},
81  /*! Configure the MMA865x to set interrupt polarity as Active High. */
82  {MMA865x_PULSE_THSY, 0x37, 0},
83  /*! Configure the MMA865x to set interrupt polarity as Active High. */
84  {MMA865x_PULSE_THSZ, 0x52, 0},
85  /*! Configure the MMA865x to set interrupt polarity as Active High. */
86  {MMA865x_PULSE_TMLT, 0x30, 0},
87  /*! Configure the MMA865x to set interrupt polarity as Active High. */
88  {MMA865x_PULSE_LTCY, 0x3C, 0},
89  /*! Configure the MMA865x to enable Interrupts for Data Ready. */
91  /*! Configure the MMA865x to route Data Ready Interrupts to INT1. */
94 
95 /*! @brief Prepare the register read for WHOAMI Register. */
97  {.readFrom = MMA865x_WHO_AM_I, .numBytes = 1}, __END_READ_DATA__};
98 
99 /*! @brief Prepare the register read for INT Status Register. */
101  {.readFrom = MMA865x_INT_SOURCE, .numBytes = 1}, __END_READ_DATA__};
102 
103 /*! @brief Prepare the register read for FullScale range Register. */
105  {.readFrom = MMA865x_XYZ_DATA_CFG, .numBytes = 1}, __END_READ_DATA__};
106 
107 /*! @brief Prepare the register read for FFMT Register. */
109  {.readFrom = MMA865x_FF_MT_SRC , .numBytes = 1}, __END_READ_DATA__};
110 
111 /*! @brief Prepare the register read for PL Status Register. */
113  {.readFrom = MMA865x_PL_STATUS, .numBytes = 1}, __END_READ_DATA__};
114 
115 /*! @brief MMA865x register list to read all registers */
118 
119 /*! @brief This structure defines the mma865x all registers metadata.*/
120 typedef struct
121 {
122  uint8_t offset;
123  uint8_t value;
124  uint8_t trigger;
125  uint8_t read_offset;
126  uint8_t read_value;
127  uint8_t read_trigger;
128  uint8_t readall_value[MMA865x_NUM_REGISTERS];
129  uint8_t readall_size;
131  uint8_t toggle;
133  uint8_t fs_value;
134  uint8_t mods_value;
135  uint16_t freefall_cntr;
136  uint16_t tapdetect_cntr;
137  uint16_t orient_cntr;
138  uint16_t vecmchange_cntr;
139  uint8_t reg_addr[MMA865x_NUM_REGISTERS];
140  uint8_t dataready_cntr;
141  float accel[3];
142  float mag[3];
144 
145 /*! @brief This structure defines offset and noise calculation parameters. */
146 typedef struct
147 {
148  float offx;
149  float offy;
150  float offz;
151  float rmsx;
152  float rmsy;
153  float rmsz;
156 
157 /*! @brief Defines MMA8652 host operation types. */
159 {
164 
166 
167 
168 /*******************************************************************************
169  * Globals
170  ******************************************************************************/
171 
175 uint8_t prev_toggle = 1;
176 volatile bool bMma8652IntFlag = false;
177 
178 static FMSTR_U8 recBuffer[1024*10];
179 FMSTR_REC_BUFF recBuffCfg;
180 FMSTR_REC_VAR recVar;
181 FMSTR_REC_CFG recCfg;
182 
183 /*******************************************************************************
184  * Local functions
185  ******************************************************************************/
186 /*! @brief Function to initialize target communication to FreeMASTER host.
187  * @details This function initializes FreeMASTER UART communication.
188  * @param[in] void.
189  * @return void.
190  */
191 static void init_freemaster_uart(void);
192 /*! @brief ISR for MMA8652 data ready event.
193  * @details This function implements ISR for MMA8652 DRDY event.
194  * @param[in] void *.
195  * @return void.
196  */
197 void mma8652_isr_callback(void *pUserData);
198 /*! @brief Function to apply MMA8652 register write operation.
199  * @details This function apply MMA8652 register write based on write trigger from host.
200  * @param[in] mma865x_i2c_sensorhandle_t MMA8652drv, MMA8652 sensor I2C handle.
201  * @param[in] uint8_t offset, the address of the register to start writing from.
202  * @param[in] uint8_t value, value to write on register offset.
203  * @return returns the status of the operation.
204  */
205 int32_t apply_register_write(mma865x_i2c_sensorhandle_t MMA8652drv, uint8_t offset, uint8_t value);
206 /*! @brief Function to apply MMA8652 register read operation.
207  * @details This function apply MMA8652 register read based on read trigger from host.
208  * @param[in] mma865x_i2c_sensorhandle_t MMA8652drv, MMA8652 sensor I2C handle.
209  * @param[in] uint8_t offset, the address of the register to read from.
210  * @param[in/out] uint8_t *value, pointer to output buffer.
211  * @return returns the status of the operation.
212  */
213 int32_t apply_register_read(mma865x_i2c_sensorhandle_t MMA8652drv, uint8_t offset, uint8_t *value);
214 /*! @brief Function to apply MMA8652 register read-all operation.
215  * @details This function apply MMA8652 all-registers read based on read-all trigger from host.
216  * @param[in] mma865x_i2c_sensorhandle_t MMA8652drv, MMA8652 sensor I2C handle.
217  * @return returns the status of the operation.
218  */
220 /*! @brief Function to update dropdown selection.
221  * @details This function updates the dropdown selection values in real-time based on read/write/read-all triggers.
222  * @param[in/out] mma865x_allregs_t *registers, pointer to MMA8652 all-registers metadata.
223  * @param[in] uint8_t caller, called from which operation type.
224  * @return returns the status of the operation.
225  */
226 int32_t update_dropdown_selection(mma865x_allregs_t *registers, uint8_t caller);
227 /*! @brief Function to initialize offset noise measurement.
228  * @details This function initializes offset noise measurement metadata.
229  * @param[in/out] mma865x_allregs_t *offnoiseptr, pointer to MMA8652 offset noise metadata.
230  * @return void.
231  */
232 void offset_noise_init(mma865x_offset_noise_t *offnoiseptr);
233 /*! @brief Function to measure accelerometer offset noise.
234  * @details This function measures accelerometer offset noise.
235  * @param[in] mma865x_acceldata_t *rawData, pointer to MMA8652 rawdata metadata.
236  * @param[in/out] mma865x_offset_noise_t *offnoiseptr, pointer to MMA8652 offset noise metadata.
237  * @param[in] float sens, MMA8652 sensitivity based on FS configuration.
238  * @return void.
239  */
240 void accel_off_noise(mma865x_acceldata_t* rawData, mma865x_offset_noise_t *offnoiseptr, float sens);
241 void FRM_Recorder_Init();
242 
243 /*******************************************************************************
244  * Code
245  ******************************************************************************/
246 
247 /* This is the Sensor Data Ready ISR implementation.*/
248 void mma8652_isr_callback(void *pUserData)
249 { /*! @brief Set flag to indicate Sensor has signalled data ready. */
250  bMma8652IntFlag = true;
251 }
252 
253 /* Create TSA table and add output variables. */
254 /*!
255  * @brief Target Side Addressable (TSA) table created for this application.
256  */
258  FMSTR_TSA_STRUCT(mma865x_acceldata_t)
259 
260  FMSTR_TSA_STRUCT(mma865x_allregs_t)
261  FMSTR_TSA_MEMBER(mma865x_allregs_t, offset, FMSTR_TSA_UINT8)
262  FMSTR_TSA_MEMBER(mma865x_allregs_t, value, FMSTR_TSA_UINT8)
263  FMSTR_TSA_MEMBER(mma865x_allregs_t, trigger, FMSTR_TSA_UINT8)
264  FMSTR_TSA_MEMBER(mma865x_allregs_t, read_offset, FMSTR_TSA_UINT8)
265  FMSTR_TSA_MEMBER(mma865x_allregs_t, read_value, FMSTR_TSA_UINT8)
266  FMSTR_TSA_MEMBER(mma865x_allregs_t, read_trigger, FMSTR_TSA_UINT8)
267  FMSTR_TSA_MEMBER(mma865x_allregs_t, readall_value, FMSTR_TSA_UINT8)
268  FMSTR_TSA_MEMBER(mma865x_allregs_t, readall_size, FMSTR_TSA_UINT8)
269  FMSTR_TSA_MEMBER(mma865x_allregs_t, readall_trigger, FMSTR_TSA_UINT8)
270  FMSTR_TSA_MEMBER(mma865x_allregs_t, trigger_accel_offnoise, FMSTR_TSA_UINT8)
271  FMSTR_TSA_MEMBER(mma865x_allregs_t, fs_value, FMSTR_TSA_UINT8)
272  FMSTR_TSA_MEMBER(mma865x_allregs_t, mods_value, FMSTR_TSA_UINT8)
273  FMSTR_TSA_MEMBER(mma865x_allregs_t, toggle, FMSTR_TSA_UINT8)
274  FMSTR_TSA_MEMBER(mma865x_allregs_t, freefall_cntr, FMSTR_TSA_UINT16)
275  FMSTR_TSA_MEMBER(mma865x_allregs_t, tapdetect_cntr, FMSTR_TSA_UINT16)
276  FMSTR_TSA_MEMBER(mma865x_allregs_t, orient_cntr, FMSTR_TSA_UINT16)
277  FMSTR_TSA_MEMBER(mma865x_allregs_t, vecmchange_cntr, FMSTR_TSA_UINT16)
278  FMSTR_TSA_MEMBER(mma865x_allregs_t, reg_addr, FMSTR_TSA_UINT8)
279  FMSTR_TSA_MEMBER(mma865x_allregs_t, accel, FMSTR_TSA_FLOAT)
280  FMSTR_TSA_MEMBER(mma865x_allregs_t, dataready_cntr, FMSTR_TSA_UINT8)
281 
282  FMSTR_TSA_STRUCT(mma865x_offset_noise_t)
283  FMSTR_TSA_MEMBER(mma865x_offset_noise_t, offx, FMSTR_TSA_FLOAT)
284  FMSTR_TSA_MEMBER(mma865x_offset_noise_t, offy, FMSTR_TSA_FLOAT)
285  FMSTR_TSA_MEMBER(mma865x_offset_noise_t, offz, FMSTR_TSA_FLOAT)
286  FMSTR_TSA_MEMBER(mma865x_offset_noise_t, rmsx, FMSTR_TSA_FLOAT)
287  FMSTR_TSA_MEMBER(mma865x_offset_noise_t, rmsy, FMSTR_TSA_FLOAT)
288  FMSTR_TSA_MEMBER(mma865x_offset_noise_t, rmsz, FMSTR_TSA_FLOAT)
289  FMSTR_TSA_MEMBER(mma865x_offset_noise_t, complete_accel_offnoise, FMSTR_TSA_UINT8)
290 
291  FMSTR_TSA_RO_VAR(rawData, FMSTR_TSA_USERTYPE(mma865x_accelmagdata_t))
292 
293  FMSTR_TSA_RW_VAR(registers, FMSTR_TSA_USERTYPE(mma865x_allregs_t))
294 
295  FMSTR_TSA_RO_VAR(offnoise_data, FMSTR_TSA_USERTYPE(mma865x_offset_noise_t))
296 
297 FMSTR_TSA_TABLE_END()
298 
299 FMSTR_TSA_TABLE_LIST_BEGIN()
300  FMSTR_TSA_TABLE(main_table)
301 FMSTR_TSA_TABLE_LIST_END()
302 
303 /*!
304  * @brief FreeMASTER recorder initialization
305  */
306 void FRM_Recorder_Init()
307 {
308  /* Do local configuration of additional recorder */
309 
310  /* Setup the additional recorder raw buffer */
311  recBuffCfg.addr = recBuffer;
312  recBuffCfg.size = sizeof(recBuffer);
313  recBuffCfg.basePeriod_ns = 0; /* Unknown period */
314  recBuffCfg.name = "MMA865x 3-Axis Accelerometer Data";
315 
316  FMSTR_RecorderCreate(1, &recBuffCfg);
317 }
318 
319 /*!
320  * @brief Main function
321  */
322 
323 int main(void)
324 {
325  int32_t status;
326  uint16_t ffmt_incr = 0;
327  uint16_t pulse_incr = 0;
328  uint16_t orient_incr = 0;
329  uint16_t vecm_incr = 0;
330  uint8_t regdata;
331  float sensitivity = ACCEL_2G_SENS;
332 
333  ARM_DRIVER_I2C *I2Cdrv = &I2C_S_DRIVER; // Now using the shield.h value!!!
335  mma865x_i2c_sensorhandle_t MMA8652drv;
336 
337  /*! Initialize the MCU hardware. */
338  BOARD_InitPins();
341 
342  /*! Initialize MMA8652_INT1 pin used by FRDM board */
343  pGpioDriver->pin_init(&MMA8652_INT1, GPIO_DIRECTION_IN, NULL, &mma8652_isr_callback, NULL);
344 
345  /*! Initialize RGB LED pin used by FRDM board */
346  pGpioDriver->pin_init(&GREEN_LED, GPIO_DIRECTION_OUT, NULL, NULL, NULL);
347 
348  /*! FreeMASTER communication layer initialization */
349  init_freemaster_uart();
350 
351  /*! Initialize the I2C driver. */
352  status = I2Cdrv->Initialize(I2C_S_SIGNAL_EVENT);
353  if (ARM_DRIVER_OK != status)
354  {
355  return status;
356  }
357 
358  /*! Set the I2C Power mode. */
359  status = I2Cdrv->PowerControl(ARM_POWER_FULL);
360  if (ARM_DRIVER_OK != status)
361  {
362  return status;
363  }
364 
365  /*! Set the I2C bus speed. */
366  status = I2Cdrv->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
367  if (ARM_DRIVER_OK != status)
368  {
369  return status;
370  }
371 
372  /*! Initialize the MMA865x sensor driver. */
374  if (SENSOR_ERROR_NONE != status)
375  {
376  return status;
377  }
378 
379  /*! Set the task to be executed while waiting for I2C transactions to complete. */
381 
382  /*! Configure the mma865x sensor driver. */
383  status = MMA865x_I2C_Configure(&MMA8652drv, Mma865x_Config);
384  if (SENSOR_ERROR_NONE != status)
385  {
386  return status;
387  }
388 
389  /*! FreeMASTER Driver Initialization */
390  FMSTR_Init();
391 
392  /*! FreeMASTER Recorder Initialization */
394 
395  /*! Initialize trigger flags */
396  registers.toggle = 1;
397  registers.trigger = 0;
398  registers.read_trigger = 0;
399  registers.read_value = 0;
400  registers.readall_trigger = 0;
401  registers.trigger_accel_offnoise=0;
402  registers.dataready_cntr = 0;
403 
404  for(int i = 0; i < MMA865x_NUM_REGISTERS; i++)
405  {
406  registers.readall_value[i] = 0;
407  }
408 
409  for (;;) /* Forever loop */
410  {
411 
412  /*! Calling Recorder#0 in execution loop for generic high-speed variables sampling. */
413  FMSTR_Recorder(0);
414 
415  /*! FreeMASTER host communication polling mode */
416  FMSTR_Poll();
417 
418  /*! Check for any write register trigger from Host */
419  if (registers.trigger == 1)
420  {
421  /*! Apply Register Write */
422  status = apply_register_write(MMA8652drv, registers.offset, registers.value);
423  if (SENSOR_ERROR_NONE != status)
424  {
425  return status;
426  }
427  registers.trigger = 0;
428  /*! Update drop down menu selection based on updated register write */
430  }
431 
432  /*! Check for any read register trigger from Host */
433  if (registers.read_trigger == 1)
434  {
435  /*! Apply Register Write */
436  status = apply_register_read(MMA8652drv, registers.read_offset, &(registers.read_value));
437  if (SENSOR_ERROR_NONE != status)
438  {
439  return status;
440  }
441  registers.read_trigger = 0;
442  /*! Update drop down menu selection based on updated register read */
444  }
445 
446  /*! Check for any read all register trigger from Host */
447  if (registers.readall_trigger == 1)
448  {
449  /*! Apply Register Write */
450  status = apply_register_readall(MMA8652drv);
451  if (SENSOR_ERROR_NONE != status)
452  {
453  return status;
454  }
455  registers.readall_trigger = 0;
457  /*! Update drop down menu selection based on updated all register read */
459  }
460 
461  /*! Wait for data ready from the MMA865x. */
462  if (false == bMma8652IntFlag)
463  {
464  SMC_SetPowerModeWait(SMC); /* Power save, wait if nothing to do. */
465  continue;
466  }
467  else
468  { /*! Clear the data ready flag, it will be set again by the ISR. */
469  bMma8652IntFlag = false;
470  //pGpioDriver->toggle_pin(&GREEN_LED);
471  }
472 
473  /*! Calling Recorder#1 for sampling sensor data when we get sensor data ready interrupt based on ODR. */
474  FMSTR_Recorder(1);
475 
476  /*! Read all MMA865x registers */
477  status = MMA865x_I2C_ReadData(&MMA8652drv, MMA865x_ALL_REG_READ, registers.reg_addr);
478  if (0 == (registers.reg_addr[0] & MMA865x_STATUS_ZYXDR_MASK))
479  { /* Loop, if new sample is not available. */
480  continue;
481  }
482 
483  /*! Convert the raw sensor data to signed 16-bit container for display to the debug port. */
484  rawData.accel[0] = ((int16_t)registers.reg_addr[1] << 8) | registers.reg_addr[2];
485  rawData.accel[0] /= 16;
486  rawData.accel[1] = ((int16_t)registers.reg_addr[3] << 8) | registers.reg_addr[4];
487  rawData.accel[1] /= 16;
488  rawData.accel[2] = ((int16_t)registers.reg_addr[5] << 8) | registers.reg_addr[6];
489  rawData.accel[2] /= 16;
490 
491  status = MMA865x_I2C_ReadData(&MMA8652drv, cMMA865x_whoami, (uint8_t *)&registers.reg_addr[13]);
492 
493  /*! Check the FS and apply sensitivity */
494  status = MMA865x_I2C_ReadData(&MMA8652drv, cMMA865x_fs_src, &regdata);
495  if (regdata == 1)
496  {
497  sensitivity = ACCEL_4G_SENS;
498  }
499  else if (regdata == 2)
500  {
501  sensitivity = ACCEL_8G_SENS;
502  }
503  else
504  {
505  sensitivity = ACCEL_2G_SENS;
506  }
507 
508  /*! Convert raw values to Gs */
509  registers.accel[0] = (float) (rawData.accel[0] * sensitivity);
510  registers.accel[1] = (float) (rawData.accel[1] * sensitivity);
511  registers.accel[2] = (float) (rawData.accel[2] * sensitivity);
512 
513  /*! Increment data ready counter and check for rollover */
514  registers.dataready_cntr++;
515  if(MAX8BITSTORAGE == registers.dataready_cntr)
516  {
517  registers.dataready_cntr = 0;
518  }
519 
520  if (prev_toggle != registers.toggle)
521  {
522  pGpioDriver->toggle_pin(&GREEN_LED);
523  prev_toggle = registers.toggle;
524  }
525 
526  /*! Call offset and noise calculation function for MMA8652 */
527  if (registers.trigger_accel_offnoise == 1)
528  {
529  accel_off_noise(&(rawData), &(offnoise_data), sensitivity);
530  if (offnoise_data.complete_accel_offnoise == 1)
531  {
532  registers.trigger_accel_offnoise = 0;
533  //offnoise_data.complete_accel_offnoise = 0;
534  }
535  }
536 
537  status = MMA865x_I2C_ReadData(&MMA8652drv, cMMA865x_int_src, &regdata);
538 
539  /*! The following condition checks for multiple interrupts occurring at the same time */
540  if((regdata & MMA865x_INT_SOURCE_SRC_FF_MT_MASK) == 0x04)
541  {
542  ffmt_incr++;
543  if (ffmt_incr == 1)
544  {
545  registers.freefall_cntr++;
546  }
547  }
548  /*! Check for single-tap detection interrupt */
549  else if((regdata & MMA865x_INT_SOURCE_SRC_PULSE_MASK) == 0x08)
550  {
551  pulse_incr++;
552  if (pulse_incr == 1)
553  {
554  registers.tapdetect_cntr++;
555  }
556  }
557  /*! Check for Vector Magnitude change interrupt */
558  else if((regdata & MMA865x_INT_SOURCE_SRC_FF_MT_MASK) == 0x04)
559  {
560  vecm_incr++;
561  if (vecm_incr == 1)
562  {
563  registers.vecmchange_cntr++;
564  }
565  }
566  /*! Check for Vector Magnitude change interrupt */
567  else if((regdata & MMA865x_INT_SOURCE_SRC_LNDPRT_MASK) == 0x10)
568  {
569  orient_incr++;
570  if (orient_incr == 1)
571  {
572  registers.orient_cntr++;
573  }
574  }
575  /* Else send other interrupts, clear counters */
576  else
577  {
578  /* Reset all event counters */
579  ffmt_incr = 0;
580  pulse_incr = 0;
581  orient_incr = 0;
582  vecm_incr = 0;
583  }
584 
585  /*! Read FFMT interrupt source register to clear flags */
586  status = MMA865x_I2C_ReadData(&MMA8652drv, cMMA865x_int_src, &regdata);
587  status = MMA865x_I2C_ReadData(&MMA8652drv, cMMA865x_ffmt_src, &regdata);
588  status = MMA865x_I2C_ReadData(&MMA8652drv, cMMA865x_pl_status, &regdata);
589 
590  }
591 }
592 
593 
594 /*!
595  * @brief Service register write trigger from Host
596  */
597 int32_t apply_register_write(mma865x_i2c_sensorhandle_t MMA8652drv, uint8_t offset, uint8_t value)
598 {
599  int32_t status;
600 
601  if (offset > MMA865x_NUM_REGISTERS)
602  {
604  }
605 
606  registerwritelist_t mma865x_register_write[] = {
607  /*! Set register offset with provided value */
608  {offset, value, 0},
610 
611  status = MMA865x_I2C_Configure(&MMA8652drv, mma865x_register_write);
612  if (SENSOR_ERROR_NONE != status)
613  {
614  return SENSOR_ERROR_WRITE;
615  }
616 
617  return SENSOR_ERROR_NONE;
618 }
619 
620 /*!
621  * @brief Service register read trigger from Host
622  */
623 int32_t apply_register_read(mma865x_i2c_sensorhandle_t MMA8652drv, uint8_t read_offset, uint8_t *read_value)
624 {
625  int32_t status;
626 
627  if (read_offset > MMA865x_NUM_REGISTERS)
628  {
630  }
631 
632  registerreadlist_t mma865x_register_read[] = {
633  /*! Set register offset with provided value */
634  {.readFrom = read_offset, .numBytes = 1}, __END_READ_DATA__};
635 
636  status = MMA865x_I2C_ReadData(&MMA8652drv, mma865x_register_read, read_value);
637  if (SENSOR_ERROR_NONE != status)
638  {
639  return SENSOR_ERROR_WRITE;
640  }
641 
642  return SENSOR_ERROR_NONE;
643 }
644 
645 /*!
646  * @brief Service register read all trigger from Host
647  */
649 {
650  int32_t status;
651 
652  for (int reg_offset = MMA865x_STATUS; reg_offset <= MMA865x_OFF_Z; reg_offset++)
653  {
654  registerreadlist_t mma865x_register_readall[] = {
655  /*! Set register offset with provided value */
656  {.readFrom = reg_offset, .numBytes = 1}, __END_READ_DATA__};
657 
658  status = MMA865x_I2C_ReadData(&MMA8652drv, mma865x_register_readall, &(registers.readall_value[reg_offset]));
659  if (SENSOR_ERROR_NONE != status)
660  {
661  return SENSOR_ERROR_READ;
662  }
663  }
664 
665  return SENSOR_ERROR_NONE;
666 }
667 
668 /*!
669  * @brief Update drop down selection values based on register write, read or readall.
670  */
672 {
673 
675 
676  switch (caller)
677  {
678  case MMA865x_REG_WRITE:
679 
680  /*! Update drop down option based on updated read value */
681  if(MMA865x_XYZ_DATA_CFG == registers->offset) //FS Selection
682  {
683  registers->fs_value = registers->value;
684  }
685  else if (MMA865x_CTRL_REG2 == registers->offset)
686  {
687  registers->mods_value = registers->value;
688  }
689  break;
690  case MMA865x_REG_READ: //Called from Register Read
691 
692  /*! Update drop down option based on updated read value */
693  if(MMA865x_XYZ_DATA_CFG == registers->read_offset) //FS Selection
694  {
695  registers->fs_value = registers->read_value;
696  }
697  else if (MMA865x_CTRL_REG2 == registers->offset)
698  {
699  registers->mods_value = registers->read_value;
700  }
701  break;
702  case MMA865x_ALLREG_READ: //Called from Register ReadAll
703 
704  /*! Update drop down option based on updated read values */
705  registers->fs_value = registers->reg_addr[MMA865x_XYZ_DATA_CFG];
706  registers->mods_value = registers->reg_addr[MMA865x_CTRL_REG2];
707  break;
708  default:
710  break;
711  }
712 
713  return status;
714 
715 }
716 
717 /*******************************************************************************
718  * OFFSET NOISE CALCULATION
719  ******************************************************************************/
720 
721 /*!
722  * @brief Initialize Offset-Noise Variables
723  */
725 {
726  offnoiseptr->offx = 0.0;
727  offnoiseptr->offy = 0.0;
728  offnoiseptr->offz = 0.0;
729  offnoiseptr->rmsx = 0.0;
730  offnoiseptr->rmsy = 0.0;
731  offnoiseptr->rmsz = 0.0;
732  offnoiseptr->complete_accel_offnoise = 0;
733 }
734 
735 
736 /* Calculate Offset & Noise for ACCELEROMETER */
737 void accel_off_noise(mma865x_acceldata_t* rawData, mma865x_offset_noise_t *offnoiseptr, float sens)
738 {
739  uint16_t j;
740  static uint16_t k=0;
741  static uint16_t cntr=0;
742  static float stdx=0;
743  static float stdy=0;
744  static float stdz=0;
745  static float xx[N], yy[N], zz[N];
746  static float xm[N], ym[N], zm[N];
747  static float xsq[N], ysq[N], zsq[N];
748  float am[3];
749  static float sumx=0.0;
750  static float sumy=0.0;
751  static float sumz=0.0;
752 
753  /* Init offset noise variables */
754  offset_noise_init(offnoiseptr);
755 
756  cntr++;
757 
758  /* Store Accel samples and calculate sum for configured N */
759  if(cntr < N)
760  {
761  am[0]=rawData->accel[0]*sens;
762  am[1]=rawData->accel[1]*sens;
763  am[2]=rawData->accel[2]*sens;
764  xx[k]=am[0];
765  yy[k]=am[1];
766  zz[k]=am[2];
767  sumx+=am[0];
768  sumy+=am[1];
769  sumz+=am[2];
770  k+=1;
771  offnoiseptr->complete_accel_offnoise = 0;
772  }
773 
774  /* Measure offset and RMS */
775  if(cntr == N)
776  {
777  /* Measure average */
778  sumx=sumx/(N-1);
779  sumy=sumy/(N-1);
780  sumz=sumz/(N-1);
781 
782  /* Measure offset */
783  offnoiseptr->offx=0-sumx;
784  offnoiseptr->offy=0-sumy;
785  offnoiseptr->offz=1-sumz;
786 
787  /* Measure standard deviation */
788  for(j=0; j<N-1; j++)
789  {
790  xm[j]=xx[j]-sumx;
791  ym[j]=yy[j]-sumy;
792  zm[j]=zz[j]-sumz;
793 
794  xsq[j]=pow(xm[j],2);
795  ysq[j]=pow(ym[j],2);
796  zsq[j]=pow(zm[j],2);
797  stdx+=xsq[j];
798  stdy+=ysq[j];
799  stdz+=zsq[j];
800  }
801  stdx=stdx/(N-2);
802  stdy=stdy/(N-2);
803  stdz=stdz/(N-2);
804 
805  /* Measure RMS */
806  offnoiseptr->rmsx=pow(stdx,0.5);
807  offnoiseptr->rmsy=pow(stdy,0.5);
808  offnoiseptr->rmsz=pow(stdz,0.5);
809 
810  /* Set the completion flag */
811  offnoiseptr->complete_accel_offnoise = 1;
812 
813  /* Reset local storage */
814  cntr = k = 0;
815  sumx = sumy = sumz = 0;
816  stdx = stdy = stdz = 0;
817  }
818 }
819 
820 /*!
821  * @brief UART Module initialization (UART is a the standard block included e.g. in K22F)
822  */
823 static void init_freemaster_uart(void)
824 {
825  uart_config_t config;
826 
827  /*
828  * config.baudRate_Bps = 115200U;
829  * config.parityMode = kUART_ParityDisabled;
830  * config.stopBitCount = kUART_OneStopBit;
831  * config.txFifoWatermark = 0;
832  * config.rxFifoWatermark = 1;
833  * config.enableTx = false;
834  * config.enableRx = false;
835  */
836  UART_GetDefaultConfig(&config);
837  config.baudRate_Bps = 115200U;
838  config.enableTx = false;
839  config.enableRx = false;
840 
841  UART_Init((UART_Type*)BOARD_DEBUG_UART_BASEADDR, &config, BOARD_DEBUG_UART_CLK_FREQ);
842 
843  /* Register communication module used by FreeMASTER driver. */
844  FMSTR_SerialSetBaseAddress((UART_Type*)BOARD_DEBUG_UART_BASEADDR);
845 
846 #if FMSTR_SHORT_INTR || FMSTR_LONG_INTR
847  /* Enable UART interrupts. */
848  EnableIRQ(BOARD_UART_IRQ);
849  EnableGlobalIRQ(0);
850 #endif
851 }
852 
853 #if FMSTR_SHORT_INTR || FMSTR_LONG_INTR
854 /*
855 * Application interrupt handler of communication peripheral used in interrupt modes
856 * of FreeMASTER communication.
857 *
858 * NXP MCUXpresso SDK framework defines interrupt vector table as a part of "startup_XXXXXX.x"
859 * assembler/C file. The table points to weakly defined symbols, which may be overwritten by the
860 * application specific implementation. FreeMASTER overrides the original weak definition and
861 * redirects the call to its own handler.
862 *
863 */
864 
865 void BOARD_UART_IRQ_HANDLER(void)
866 {
867  /* Call FreeMASTER Interrupt routine handler */
868  FMSTR_SerialIsr();
869  /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
870  exception return operation might vector to incorrect interrupt */
871 #if defined __CORTEX_M && (__CORTEX_M == 4U)
872  __DSB();
873 #endif
874 }
875 #endif
876 
const registerwritelist_t Mma865x_Config[]
Prepare the register write list to configure MMA865x in non-FIFO and ISR mode.
FMSTR_REC_VAR recVar
#define MMA865x_CTRL_REG1_DR_MASK
Definition: mma865x.h:1534
#define BOARD_UART_IRQ
Definition: board.h:27
void FRM_Recorder_Init()
This structure defines the Write command List.
Definition: sensor_drv.h:68
This defines the sensor specific information.
Definition: mma865x_drv.h:29
void offset_noise_init(mma865x_offset_noise_t *offnoiseptr)
Function to initialize offset noise measurement.
#define MMA865x_INT_SOURCE_SRC_LNDPRT_MASK
Definition: mma865x.h:455
int32_t status
#define MMA865x_CTRL_REG4_INT_EN_PULSE_EN
Definition: mma865x.h:1774
#define ACCEL_2G_SENS
#define MMA865x_XYZ_DATA_CFG_FS_MASK
Definition: mma865x.h:530
status_t SMC_SetPowerModeVlpr(void *arg)
Configures the system to VLPR power mode. API name used from Kinetis family to maintain compatibility...
Definition: lpc54114.c:169
#define MMA865x_CTRL_REG5_INT_CFG_DRDY_INT1
Definition: mma865x.h:1853
#define MMA865x_FF_MT_CFG_XEFE_EN
Definition: mma865x.h:881
FMSTR_TSA_TABLE_BEGIN(main_table)
Target Side Addressable (TSA) table created for this application.
#define N
const registerreadlist_t cMMA865x_pl_status[]
Prepare the register read for PL Status Register.
#define BOARD_DEBUG_UART_CLK_FREQ
Definition: board.h:26
#define MMA8652_INT1
int32_t update_dropdown_selection(mma865x_allregs_t *registers, uint8_t caller)
Function to update dropdown selection.
Access structure of the GPIO Driver.
Definition: Driver_GPIO.h:38
#define SMC
Definition: lpc54114.h:118
const registerreadlist_t MMA865x_ALL_REG_READ[]
MMA865x register list to read all registers.
const registerreadlist_t cMMA865x_fs_src[]
Prepare the register read for FullScale range Register.
#define MMA865x_STATUS_ZYXDR_MASK
Definition: mma865x.h:111
#define MMA865x_NUM_REGISTERS
#define __END_WRITE_DATA__
Definition: sensor_drv.h:45
This structure defines offset and noise calculation parameters.
#define MMA865x_CTRL_REG3_IPOL_MASK
Definition: mma865x.h:1664
typedef int32_t(DATA_FORMAT_Append_t))(void *pData
The interface function to append the data on the formated stream.
#define MMA865x_INT_SOURCE_SRC_PULSE_MASK
Definition: mma865x.h:452
#define ACCEL_8G_SENS
#define MMA865x_FF_MT_THS_DBCNTM_INC_CLR
Definition: mma865x.h:994
int32_t MMA865x_I2C_ReadData(mma865x_i2c_sensorhandle_t *pSensorHandle, const registerreadlist_t *pReadList, uint8_t *pBuffer)
The interface function to read the sensor data.
Definition: mma865x_drv.c:106
#define MMA865x_CTRL_REG3_IPOL_ACTIVE_HIGH
Definition: mma865x.h:1701
mma865x_offset_noise_t offnoise_data
#define I2C_S_SIGNAL_EVENT
Definition: issdk_hal.h:34
#define MMA865x_FF_MT_CFG_ZEFE_EN
Definition: mma865x.h:875
#define I2C_S_DRIVER
Definition: issdk_hal.h:33
FMSTR_REC_BUFF recBuffCfg
#define MMA865x_CTRL_REG4_INT_EN_FF_MT_EN
Definition: mma865x.h:1776
#define MMA865x_CTRL_REG2_MODS_MASK
Definition: mma865x.h:1592
#define BOARD_BootClockRUN
Definition: clock_config.h:19
int32_t apply_register_read(mma865x_i2c_sensorhandle_t MMA8652drv, uint8_t offset, uint8_t *value)
Function to apply MMA8652 register read operation.
void(* registeridlefunction_t)(void *userParam)
This is the register idle function type.
Definition: sensor_drv.h:97
#define MAX8BITSTORAGE
#define MMA865x_PULSE_CFG_XSPEFE_EN
Definition: mma865x.h:1290
int16_t accel[3]
Definition: mma865x_drv.h:41
GENERIC_DRIVER_GPIO Driver_GPIO_KSDK
Definition: gpio_driver.c:177
GENERIC_DRIVER_GPIO * pGpioDriver
#define MMA865x_PULSE_CFG_ZSPEFE_EN
Definition: mma865x.h:1282
#define MMA865x_TRANSIENT_CFG_ZTEFE_EN
Definition: mma865x.h:1062
#define BOARD_UART_IRQ_HANDLER
Definition: board.h:28
int32_t MMA865x_I2C_Configure(mma865x_i2c_sensorhandle_t *pSensorHandle, const registerwritelist_t *pRegWriteList)
The interface function to configure he sensor.
Definition: mma865x_drv.c:61
#define MMA865x_TRANSIENT_THS_DBCNTM_INC_CLR
Definition: mma865x.h:1191
#define __END_READ_DATA__
Definition: sensor_drv.h:51
const registerreadlist_t cMMA865x_whoami[]
Prepare the register read for WHOAMI Register.
const registerreadlist_t cMMA865x_ffmt_src[]
Prepare the register read for FFMT Register.
uint8_t prev_toggle
The mma865x_drv.h file describes the MMA865x driver interface and structures.
void mma8652_isr_callback(void *pUserData)
ISR for MMA8652 data ready event.
#define MMA865x_CTRL_REG4_INT_EN_LNDPRT_EN
Definition: mma865x.h:1772
#define MMA865x_CTRL_REG4_INT_EN_DRDY_EN
Definition: mma865x.h:1778
#define MMA865x_TRANSIENT_CFG_XTEFE_EN
Definition: mma865x.h:1070
mma865x_allregs_t registers
#define BOARD_DEBUG_UART_BASEADDR
Definition: board.h:24
const registerreadlist_t cMMA865x_int_src[]
Prepare the register read for INT Status Register.
ARM_DRIVER_I2C * I2Cdrv
#define ACCEL_4G_SENS
mma865x_acceldata_t rawData
uint16_t readFrom
Definition: sensor_drv.h:80
void accel_off_noise(mma865x_acceldata_t *rawData, mma865x_offset_noise_t *offnoiseptr, float sens)
Function to measure accelerometer offset noise.
int32_t apply_register_write(mma865x_i2c_sensorhandle_t MMA8652drv, uint8_t offset, uint8_t value)
Function to apply MMA8652 register write operation.
void(* toggle_pin)(pinID_t aPinId)
Definition: Driver_GPIO.h:48
#define MMA865x_PL_CFG_PL_EN_EN
Definition: mma865x.h:700
#define MMA865x_CTRL_REG2_MODS_HR
Definition: mma865x.h:1623
uint8_t reg_addr[MMA865x_NUM_REGISTERS]
#define MMA865x_CTRL_REG4_INT_EN_TRANS_EN
Definition: mma865x.h:1770
status_t SMC_SetPowerModeWait(void *arg)
Configures the system to WAIT power mode. API name used from Kinetis family to maintain compatibility...
Definition: lpc54114.c:155
#define MMA865x_TRANSIENT_CFG_YTEFE_EN
Definition: mma865x.h:1066
#define MMA865x_XYZ_DATA_CFG_FS_2G
Definition: mma865x.h:542
void(* pin_init)(pinID_t aPinId, gpio_direction_t dir, void *apPinConfig, gpio_isr_handler_t aIsrHandler, void *apUserData)
Definition: Driver_GPIO.h:41
This structure defines the Read command List.
Definition: sensor_drv.h:78
#define MMA8652_I2C_ADDR
This structure defines the mma865x raw data buffer.
Definition: mma865x_drv.h:38
#define MMA865x_PL_CFG_DBCNTM_CLEAR
Definition: mma865x.h:697
#define MMA865x_INT_SOURCE_SRC_FF_MT_MASK
Definition: mma865x.h:449
gpioHandleKSDK_t GREEN_LED
Definition: frdm_k64f.c:188
#define I2C_S_DEVICE_INDEX
Definition: issdk_hal.h:35
int32_t apply_register_readall(mma865x_i2c_sensorhandle_t MMA8652drv)
Function to apply MMA8652 register read-all operation.
void MMA865x_I2C_SetIdleTask(mma865x_i2c_sensorhandle_t *pSensorHandle, registeridlefunction_t idleTask, void *userParam)
: The interface function to set the I2C Idle Task.
Definition: mma865x_drv.c:53
enum mma8652_operation_type mma865x_operation_type_t
Defines MMA8652 host operation types.
volatile bool bMma8652IntFlag
uint8_t readall_value[MMA865x_NUM_REGISTERS]
This structure defines the mma865x all registers metadata.
mma8652_operation_type
Defines MMA8652 host operation types.
void BOARD_InitDebugConsole(void)
Definition: board.c:15
#define MMA8652_WHOAMI_VALUE
Definition: mma865x.h:65
int32_t MMA865x_I2C_Initialize(mma865x_i2c_sensorhandle_t *pSensorHandle, ARM_DRIVER_I2C *pBus, uint8_t index, uint16_t sAddress, uint8_t whoAmi)
The interface function to initialize the sensor.
Definition: mma865x_drv.c:22
void BOARD_InitPins(void)
Configures pin routing and optionally pin electrical features.
Definition: pin_mux.c:47
#define MMA865x_FF_MT_CFG_OAE_FREEFALL
Definition: mma865x.h:872
int main(void)
Main function.
FMSTR_REC_CFG recCfg
#define MMA865x_PULSE_CFG_YSPEFE_EN
Definition: mma865x.h:1286
#define MMA865x_CTRL_REG1_DR_100HZ
Definition: mma865x.h:1551
#define MMA865x_FF_MT_CFG_YEFE_EN
Definition: mma865x.h:878