1 /*
2  * Copyright 2019-2021 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 /**
9  * @file fxos8700_freemaster_demo.c
10  * @brief The fxos8700_freemaster.c file implements FreeMASTER demo using the ISSDK
11  *        FXOS8700 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 "fxos8700_drv.h"
32 
33 /*******************************************************************************
34  * Macro Definitions
35  ******************************************************************************/
36 
37 #define FXOS8700_NUM_REGISTERS (FXOS8700_A_FFMT_THS_Z_LSB + 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.000244)   /* Sensitivity factor for 2G FS */
43 #define ACCEL_4G_SENS          (0.000488)   /* Sensitivity factor for 4G FS */
44 #define ACCEL_8G_SENS          (0.000976)   /* Sensitivity factor for 8G FS */
45 #define N                      (500U)       /* Number of samples used to measure offset/noise */
46 #define RAW_ACCELMAG_DATA_SIZE (12U)        /* Accel + Mag Data Size */
47 #define MAX8BITSTORAGE         (255U)
48 
49 /*******************************************************************************
50  * Constants
51  ******************************************************************************/
52 /*!
53  * @brief Defines the register write list to configure FXOS8700 in Hybrid mode.
54  */
55 const registerwritelist_t fxos8700_Config_Hybrid[] = {
56         /*! Clear F_SETUP. */
57 		{FXOS8700_F_SETUP, 0x00, 0x00},
58         /*! Set FS 2G Mode. */
59 		{FXOS8700_XYZ_DATA_CFG, FXOS8700_XYZ_DATA_CFG_FS_2G_0P244, FXOS8700_XYZ_DATA_CFG_FS_MASK},
60         /*! Configure the FXOS8700 to 100Hz sampling rate. */
61         {FXOS8700_CTRL_REG1, FXOS8700_CTRL_REG1_DR_HYBRID_100_HZ, FXOS8700_CTRL_REG1_DR_MASK},
62         /*! Configure the FXOS8700 to Set High Resolution Mode. */
63         {FXOS8700_CTRL_REG2, FXOS8700_CTRL_REG2_MODS_HIGH_RES, FXOS8700_CTRL_REG2_MODS_MASK},
64         {FXOS8700_CTRL_REG3, FXOS8700_CTRL_REG3_IPOL_ACTIVE_HIGH | FXOS8700_CTRL_REG3_PP_OD_PUSH_PULL,
65 		                     FXOS8700_CTRL_REG3_IPOL_MASK | FXOS8700_CTRL_REG3_PP_OD_MASK}, /*! Active High, Push-Pull */
66         {FXOS8700_CTRL_REG4, FXOS8700_CTRL_REG4_INT_EN_DRDY_EN,FXOS8700_CTRL_REG4_INT_EN_DRDY_MASK}, /*! Data Ready Event. */
67         {FXOS8700_CTRL_REG5, FXOS8700_CTRL_REG5_INT_CFG_DRDY_INT2, FXOS8700_CTRL_REG5_INT_CFG_DRDY_MASK}, /*! INT2 Pin  */
68         {FXOS8700_M_CTRL_REG1, FXOS8700_M_CTRL_REG1_M_ACAL_DISABLE | FXOS8700_M_CTRL_REG1_M_HMS_HYBRID_MODE | FXOS8700_M_CTRL_REG1_M_OS_OSR0,
69                                FXOS8700_M_CTRL_REG1_M_ACAL_MASK | FXOS8700_M_CTRL_REG1_M_HMS_MASK | FXOS8700_M_CTRL_REG1_M_OS_MASK}, /*! Enable the Hybrid Mode. */
70         {FXOS8700_M_CTRL_REG2, FXOS8700_M_CTRL_REG2_M_AUTOINC_HYBRID_MODE, FXOS8700_M_CTRL_REG2_M_AUTOINC_MASK}, /*! Enable the Data read with Hybrid Mode. */
71         {FXOS8700_CTRL_REG5,0x7E,0x00},
72         {FXOS8700_CTRL_REG4,255,0x00},
73 
74 		/*! Landscape-Portrait registers configurations */
75         {FXOS8700_PL_CFG,FXOS8700_PL_CFG_DBCNTM_CLEAR_MODE  ,FXOS8700_PL_CFG_DBCNTM_MASK},
76         {FXOS8700_PL_CFG,FXOS8700_PL_CFG_PL_EN_ENABLE   ,FXOS8700_PL_CFG_PL_EN_MASK },
77 		/*! PL count set to (64 * 2.5ms) = 160ms */
78         {FXOS8700_PL_COUNT, 0x40, 0x00},
79 		/*! Z-lock angle threshold set to ~28deg */
80         {FXOS8700_PL_BF_ZCOMP,4 ,FXOS8700_PL_BF_ZCOMP_ZLOCK_MASK},
81 		/*! Back/front trip angle threshold set to ~44deg */
82         {FXOS8700_PL_BF_ZCOMP,2 ,FXOS8700_PL_BF_ZCOMP_BKFR_MASK},
83 		/*! PL_THS set to 0x10=> 45deg threshold angle, HYS set to 0b100=> LtoP trip angle 59deg and PtoL trip angle 31deg*/
84         {FXOS8700_PL_THS_REG,132,0x00},
85 
86         /*! Freefall detection registers configurations */
87 		/*! Configure FreeFall debounce counter to 60msec */
88 	    {FXOS8700_A_FFMT_COUNT, A_FFMT_COUNT, 0}, /* Debounce Counter */
89 		/*! Configure FreeFall detection threshold to 0.5g */
90 	    {FXOS8700_A_FFMT_THS, FF_A_FFMT_THS | FXOS8700_A_FFMT_THS_DBCNTM_MASK,
91 	     FXOS8700_A_FFMT_THS_THS_MASK | FXOS8700_A_FFMT_THS_DBCNTM_MASK}, /* Threshold */
92 		 /*! Configure sensor to detect freefall, raise event on X, Y, Z axes */
93 	    {FXOS8700_A_FFMT_CFG,
94 	     FXOS8700_A_FFMT_CFG_OAE_FREEFALL | FXOS8700_A_FFMT_CFG_ZEFE_RAISE_EVENT |
95 	         FXOS8700_A_FFMT_CFG_YEFE_RAISE_EVENT | FXOS8700_A_FFMT_CFG_XEFE_RAISE_EVENT,
96 	     FXOS8700_A_FFMT_CFG_OAE_MASK | FXOS8700_A_FFMT_CFG_ZEFE_MASK |
97 	         FXOS8700_A_FFMT_CFG_YEFE_MASK | FXOS8700_A_FFMT_CFG_XEFE_MASK},
98 	    {FXOS8700_CTRL_REG4, FXOS8700_CTRL_REG4_INT_EN_FFMT_EN, FXOS8700_CTRL_REG4_INT_EN_FFMT_MASK},
99 
100         /*! Pulse detection registers configurations */
101 		/*! Configure to raise event flag on detection of single-pulse event (spefe) on X, Y & Z axes*/
102         {FXOS8700_PULSE_CFG,21,0x00},
103 		/*! Configure Pulse Time Limit to 50msec */
104         {FXOS8700_PULSE_TMLT,80,0x00},
105 		/*! Configure pulse latency to 300msec */
106         {FXOS8700_PULSE_LTCY,240,0x00},
107 		/*! Configure Pulse detection threshold for X, Y, Z axes */
108         {FXOS8700_PULSE_THSX,55,0x00},
109         {FXOS8700_PULSE_THSY,55,0x00},
110         {FXOS8700_PULSE_THSZ,82,0x00},
111 
112         /*! VECM change detection configurations */
113         { FXOS8700_A_VECM_CNT,15,0x00},
114 		/*! Configure VECM to enable VECM ELE (0x40) and VECM EN (0x08)*/
115         { FXOS8700_A_VECM_CFG,72,0x00},
116 		/*! Set VECM THS to ~0.5g; THS = 0x788=>1928 (=0.47g in 2g mode) */
117         { FXOS8700_A_VECM_THS_LSB,88,0x00},
118         { FXOS8700_A_VECM_THS_MSB,1, FXOS8700_A_VECM_THS_MSB_A_VBECM_DBCNTM_MASK  },
119         { FXOS8700_A_VECM_THS_MSB,27, FXOS8700_A_VECM_THS_MSB_A_VBECM_THS_MASK  },
120 
121         __END_WRITE_DATA__};
122 
123 /*!
124  * @brief Defines the register read list to read the Data Ready Status.
125  */
126 const registerreadlist_t cFXOS8700_whoami[] = {
127         {.readFrom = FXOS8700_WHO_AM_I, .numBytes = 1}, __END_READ_DATA__};
128 /*!
129  * @brief Defines the register read list to read the Interrupt Source.
130  */
131 const registerreadlist_t cFXOS8700_int_src[] = {
132         {.readFrom = FXOS8700_INT_SOURCE, .numBytes = 1}, __END_READ_DATA__};
133 /*!
134  * @brief Defines the register read list to read the FullScale range.
135  */
136 const registerreadlist_t cFXOS8700_fs_src[] = {
137         {.readFrom = FXOS8700_XYZ_DATA_CFG, .numBytes = 1}, __END_READ_DATA__};
138 
139 /*!
140  * @brief Defines the register read list to read all-registers.
141  */
142 const registerreadlist_t FXOS8700_ALL_REG_READ[] = {{.readFrom = FXOS8700_STATUS, .numBytes = FXOS8700_NUM_REGISTERS},
143                                                       __END_READ_DATA__};
144 /*!
145  * @brief Defines the register read list to read FFMT Source.
146  */
147 const registerreadlist_t cFXOS8700_ffmt_src[] = {
148         {.readFrom = FXOS8700_A_FFMT_SRC , .numBytes = 1}, __END_READ_DATA__};
149 /*!
150  * @brief Defines the register read list to read the PL Status.
151  */
152 const registerreadlist_t cFXOS8700_pl_status[] = {
153         {.readFrom = FXOS8700_PL_STATUS, .numBytes = 1}, __END_READ_DATA__};
154 
155 /*!
156  * @brief This structure defines the fxos8700 all registers metadata.
157  */
158 typedef struct
159 {
160     uint8_t offset;
161     uint8_t value;
162     uint8_t trigger;
163     uint8_t read_offset;
164     uint8_t read_value;
165     uint8_t read_trigger;
166     uint8_t readall_value[FXOS8700_NUM_REGISTERS];
167     uint8_t readall_size;
168     uint8_t readall_trigger;
169     uint8_t toggle;
170     uint8_t trigger_accel_offnoise;
171     uint8_t trigger_mag_offnoise;
172     uint8_t fs_value;
173     uint8_t mods_value;
174     uint16_t freefall_cntr;
175     uint16_t tapdetect_cntr;
176     uint16_t orient_cntr;
177     uint16_t vecmchange_cntr;
178     uint8_t reg_addr[FXOS8700_NUM_REGISTERS];
179     uint8_t dataready_cntr;
180     float accel[3];
181     float mag[3];
182 } fxos8700_allregs_t;
183 
184 /*!
185  * @brief This structure defines the fxos8700 offset and noise calculation parameters.
186  */
187 typedef struct
188 {
189   	float offx;
190   	float offy;
191   	float offz;
192   	float rmsx;
193   	float rmsy;
194   	float rmsz;
195   	float mag_off[3];
196   	float mag_rms[3];
197   	uint8_t complete_accel_offnoise;
198   	uint8_t complete_mag_offnoise;
199 } fxos8700_offset_noise_t;
200 
201 /*!
202  * @brief Defines host operation types.
203  */
204 typedef enum fxos8700_operation_type
205 {
206 	FXOS8700_REG_WRITE   = 1U,
207 	FXOS8700_REG_READ    = 2U,
208 	FXOS8700_ALLREG_READ = 3U,
209 	FXOS8700_ACCEL_CONFIG_END
210 
211 } fxos8700_operation_type_t;
212 
213 
214 /*******************************************************************************
215  * Globals
216  ******************************************************************************/
217 
218 fxos8700_accelmagdata_t rawData;
219 fxos8700_allregs_t      registers;
220 fxos8700_offset_noise_t offnoise_data;
221 uint8_t prev_toggle = 1;
222 volatile bool bFxos8700DataReady = false;
223 
224 static FMSTR_U8 recBuffer[1024*10];
225 FMSTR_REC_BUFF  recBuffCfg;
226 FMSTR_REC_VAR   recVar;
227 FMSTR_REC_CFG   recCfg;
228 
229 /*******************************************************************************
230  * Local functions
231  ******************************************************************************/
232 /*! @brief           Function to initialize target communication to FreeMASTER host.
233  *  @details         This function initializes FreeMASTER UART communication.
234  *  @param[in]       void.
235  *  @return          void.
236  */
237 static void init_freemaster_uart(void);
238 /*! @brief           ISR for FXOS8700 data ready event.
239  *  @details         This function implements ISR for FXOS8700 DRDY event.
240  *  @param[in]       void *.
241  *  @return          void.
242  */
243 void fxos8700_isr_callback(void *pUserData);
244 /*! @brief           Function to apply FXOS8700 register write operation.
245  *  @details         This function apply FXOS8700 register write based on write trigger from host.
246  *  @param[in]       fxos8700_i2c_sensorhandle_t FXOS8700drv, FXOS8700 sensor I2C handle.
247  *  @param[in]       uint8_t offset, the address of the register to start writing from.
248  *  @param[in]       uint8_t value, value to write on register offset.
249  *  @return          returns the status of the operation.
250  */
251 int32_t apply_register_write(fxos8700_i2c_sensorhandle_t FXOS8700drv, uint8_t offset, uint8_t value);
252 /*! @brief           Function to apply FXOS8700 register read operation.
253  *  @details         This function apply FXOS8700 register read based on read trigger from host.
254  *  @param[in]       fxos8700_i2c_sensorhandle_t FXOS8700drv, FXOS8700 sensor I2C handle.
255  *  @param[in]       uint8_t offset, the address of the register to read from.
256  *  @param[in/out]   uint8_t *value, pointer to output buffer.
257  *  @return          returns the status of the operation.
258  */
259 int32_t apply_register_read(fxos8700_i2c_sensorhandle_t FXOS8700drv, uint8_t offset, uint8_t *value);
260 /*! @brief           Function to apply FXOS8700 register read-all operation.
261  *  @details         This function apply FXOS8700 all-registers read based on read-all trigger from host.
262  *  @param[in]       fxos8700_i2c_sensorhandle_t FXOS8700drv, FXOS8700 sensor I2C handle.
263  *  @return          returns the status of the operation.
264  */
265 int32_t apply_register_readall(fxos8700_i2c_sensorhandle_t FXOS8700drv);
266 /*! @brief           Function to update dropdown selection.
267  *  @details         This function updates the dropdown selection values in real-time based on read/write/read-all triggers.
268  *  @param[in/out]   fxos8700_allregs_t *registers, pointer to FXOS8700 all-registers metadata.
269  *  @param[in]       uint8_t caller, called from which operation type.
270  *  @return          returns the status of the operation.
271  */
272 int32_t update_dropdown_selection( fxos8700_allregs_t *registers, uint8_t caller);
273 /*! @brief           Function to initialize offset noise measurement.
274  *  @details         This function initializes offset noise measurement metadata.
275  *  @param[in/out]   fxos8700_offset_noise_t *offnoiseptr, pointer to FXOS8700 offset noise metadata.
276  *  @return          void.
277  */
278 void offset_noise_init(fxos8700_offset_noise_t *offnoiseptr);
279 /*! @brief           Function to measure accelerometer offset noise.
280  *  @details         This function measures accelerometer offset noise.
281  *  @param[in]       fxos8700_accelmagdata_t *rawData, pointer to FXOS8700 rawdata metadata.
282  *  @param[in/out]   fxos8700_offset_noise_t *offnoiseptr, pointer to FXOS8700 offset noise metadata.
283  *  @param[in]       float sens, FXOS8700 sensitivity based on FS configuration.
284  *  @return          void.
285  */
286 void accel_off_noise(fxos8700_accelmagdata_t* rawData,fxos8700_offset_noise_t *offnoiseptr, float sens);
287 /*! @brief           Function to measure magnetometer offset noise.
288  *  @details         This function measures magnetometer offset noise.
289  *  @param[in]       fxos8700_accelmagdata_t *rawData, pointer to FXOS8700 rawdata metadata.
290  *  @param[in/out]   fxos8700_offset_noise_t *offnoiseptr, pointer to FXOS8700 offset noise metadata.
291  *  @return          void.
292  */
293 void mag_off_noise(fxos8700_accelmagdata_t* rawData,fxos8700_offset_noise_t *offnoiseptr);
294 void FRM_Recorder_Init();
295 
296 /*******************************************************************************
297  * Code
298  ******************************************************************************/
299 
300 /*! This is the Sensor Data Ready ISR implementation.*/
fxos8700_isr_callback(void * pUserData)301 void fxos8700_isr_callback(void *pUserData)
302 { /*! @brief Set flag to indicate Sensor has signalled data ready. */
303     bFxos8700DataReady = true;
304 }
305 
306 /* Create TSA table and add output variables. */
307 /*!
308  * @brief Target Side Addressable (TSA) table created for this application.
309  */
310 FMSTR_TSA_TABLE_BEGIN(main_table)
FMSTR_TSA_STRUCT(fxos8700_accelmagdata_t)311 	FMSTR_TSA_STRUCT(fxos8700_accelmagdata_t)
312     FMSTR_TSA_MEMBER(fxos8700_accelmagdata_t, mag, FMSTR_TSA_SINT16)
313 
314 	FMSTR_TSA_STRUCT(fxos8700_allregs_t)
315     FMSTR_TSA_MEMBER(fxos8700_allregs_t, offset, FMSTR_TSA_UINT8)
316     FMSTR_TSA_MEMBER(fxos8700_allregs_t, value, FMSTR_TSA_UINT8)
317     FMSTR_TSA_MEMBER(fxos8700_allregs_t, trigger, FMSTR_TSA_UINT8)
318     FMSTR_TSA_MEMBER(fxos8700_allregs_t, read_offset, FMSTR_TSA_UINT8)
319     FMSTR_TSA_MEMBER(fxos8700_allregs_t, read_value, FMSTR_TSA_UINT8)
320     FMSTR_TSA_MEMBER(fxos8700_allregs_t, read_trigger, FMSTR_TSA_UINT8)
321     FMSTR_TSA_MEMBER(fxos8700_allregs_t, readall_value, FMSTR_TSA_UINT8)
322     FMSTR_TSA_MEMBER(fxos8700_allregs_t, readall_size, FMSTR_TSA_UINT8)
323     FMSTR_TSA_MEMBER(fxos8700_allregs_t, readall_trigger, FMSTR_TSA_UINT8)
324 	FMSTR_TSA_MEMBER(fxos8700_allregs_t, trigger_accel_offnoise, FMSTR_TSA_UINT8)
325 	FMSTR_TSA_MEMBER(fxos8700_allregs_t, trigger_mag_offnoise, FMSTR_TSA_UINT8)
326 	FMSTR_TSA_MEMBER(fxos8700_allregs_t, fs_value, FMSTR_TSA_UINT8)
327 	FMSTR_TSA_MEMBER(fxos8700_allregs_t, mods_value, FMSTR_TSA_UINT8)
328 	FMSTR_TSA_MEMBER(fxos8700_allregs_t, toggle, FMSTR_TSA_UINT8)
329     FMSTR_TSA_MEMBER(fxos8700_allregs_t, freefall_cntr, FMSTR_TSA_UINT16)
330     FMSTR_TSA_MEMBER(fxos8700_allregs_t, tapdetect_cntr, FMSTR_TSA_UINT16)
331     FMSTR_TSA_MEMBER(fxos8700_allregs_t, orient_cntr, FMSTR_TSA_UINT16)
332 	FMSTR_TSA_MEMBER(fxos8700_allregs_t, vecmchange_cntr, FMSTR_TSA_UINT16)
333     FMSTR_TSA_MEMBER(fxos8700_allregs_t, reg_addr, FMSTR_TSA_UINT8)
334     FMSTR_TSA_MEMBER(fxos8700_allregs_t, accel, FMSTR_TSA_FLOAT)
335     FMSTR_TSA_MEMBER(fxos8700_allregs_t, dataready_cntr, FMSTR_TSA_UINT8)
336 
337 	FMSTR_TSA_STRUCT(fxos8700_offset_noise_t)
338 	FMSTR_TSA_MEMBER(fxos8700_offset_noise_t, offx, FMSTR_TSA_FLOAT)
339 	FMSTR_TSA_MEMBER(fxos8700_offset_noise_t, offy, FMSTR_TSA_FLOAT)
340 	FMSTR_TSA_MEMBER(fxos8700_offset_noise_t, offz, FMSTR_TSA_FLOAT)
341 	FMSTR_TSA_MEMBER(fxos8700_offset_noise_t, rmsx, FMSTR_TSA_FLOAT)
342 	FMSTR_TSA_MEMBER(fxos8700_offset_noise_t, rmsy, FMSTR_TSA_FLOAT)
343 	FMSTR_TSA_MEMBER(fxos8700_offset_noise_t, rmsz, FMSTR_TSA_FLOAT)
344 	FMSTR_TSA_MEMBER(fxos8700_offset_noise_t, mag_rms, FMSTR_TSA_FLOAT)
345 	FMSTR_TSA_MEMBER(fxos8700_offset_noise_t, mag_off, FMSTR_TSA_FLOAT)
346 	FMSTR_TSA_MEMBER(fxos8700_offset_noise_t, complete_accel_offnoise, FMSTR_TSA_UINT8)
347 	FMSTR_TSA_MEMBER(fxos8700_offset_noise_t, complete_mag_offnoise, FMSTR_TSA_UINT8)
348 
349     FMSTR_TSA_RO_VAR(rawData, FMSTR_TSA_USERTYPE(fxos8700_accelmagdata_t))
350 
351     FMSTR_TSA_RW_VAR(registers, FMSTR_TSA_USERTYPE(fxos8700_allregs_t))
352 
353     FMSTR_TSA_RO_VAR(offnoise_data, FMSTR_TSA_USERTYPE(fxos8700_offset_noise_t))
354 
355 FMSTR_TSA_TABLE_END()
356 
357 FMSTR_TSA_TABLE_LIST_BEGIN()
358     FMSTR_TSA_TABLE(main_table)
359 FMSTR_TSA_TABLE_LIST_END()
360 
361 /*!
362  * @brief FreeMASTER recorder initialization
363  */
364 void FRM_Recorder_Init()
365 {
366     /* Do local configuration of additional recorder */
367 
368     /* Setup the additional recorder raw buffer */
369     recBuffCfg.addr = recBuffer;
370     recBuffCfg.size = sizeof(recBuffer);
371     recBuffCfg.basePeriod_ns = 0;    /* Unknown period */
372     recBuffCfg.name = "FXOS8700 3-Axis Accelerometer Data";
373 
374     FMSTR_RecorderCreate(1, &recBuffCfg);
375 }
376 
377 /*!
378  * @brief Main function
379  */
380 
main(void)381 int main(void)
382 {
383     int32_t status;
384     uint16_t ffmt_incr   = 0;
385     uint16_t pulse_incr  = 0;
386     uint16_t orient_incr = 0;
387     uint16_t vecm_incr   = 0;
388     uint8_t regdata;
389     float sensitivity = ACCEL_2G_SENS;
390 
391     ARM_DRIVER_I2C *I2Cdrv = &I2C_S_DRIVER; // Now using the shield.h value!!!
392     GENERIC_DRIVER_GPIO *pGpioDriver = &Driver_GPIO_KSDK;
393     fxos8700_i2c_sensorhandle_t FXOS8700drv;
394 
395     /*! Initialize the MCU hardware. */
396     BOARD_InitPins();
397     BOARD_BootClockRUN();
398     BOARD_InitDebugConsole();
399 
400     /*! Initialize FXOS8700_INT2 pin used by FRDM board */
401     pGpioDriver->pin_init(&FXOS8700_INT2, GPIO_DIRECTION_IN, NULL, &fxos8700_isr_callback, NULL);
402 
403     /*! Initialize RGB LED pin used by FRDM board */
404     pGpioDriver->pin_init(&GREEN_LED, GPIO_DIRECTION_OUT, NULL, NULL, NULL);
405 
406     /*! FreeMASTER communication layer initialization */
407     init_freemaster_uart();
408 
409     /*! Initialize the I2C driver. */
410     status = I2Cdrv->Initialize(I2C_S_SIGNAL_EVENT);
411     if (ARM_DRIVER_OK != status)
412     {
413         return status;
414     }
415 
416     /*! Set the I2C Power mode. */
417     status = I2Cdrv->PowerControl(ARM_POWER_FULL);
418     if (ARM_DRIVER_OK != status)
419     {
420         return status;
421     }
422 
423     /*! Set the I2C bus speed. */
424     status = I2Cdrv->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
425     if (ARM_DRIVER_OK != status)
426     {
427         return status;
428     }
429 
430     /*! Initialize the FXOS8700 sensor driver. */
431     status = FXOS8700_I2C_Initialize(&FXOS8700drv, &I2C_S_DRIVER, I2C_S_DEVICE_INDEX, FXOS8700_I2C_ADDR,
432                                      FXOS8700_WHO_AM_I_PROD_VALUE);
433     if (SENSOR_ERROR_NONE != status)
434     {
435         return status;
436     }
437 
438     /*!  Set the task to be executed while waiting for I2C transactions to complete. */
439     FXOS8700_I2C_SetIdleTask(&FXOS8700drv, (registeridlefunction_t)SMC_SetPowerModeVlpr, SMC);
440 
441     /*! Configure the fxos8700 sensor driver. */
442     status = FXOS8700_I2C_Configure(&FXOS8700drv, fxos8700_Config_Hybrid);
443     if (SENSOR_ERROR_NONE != status)
444     {
445         return status;
446     }
447 
448     /*! FreeMASTER Driver Initialization */
449     FMSTR_Init();
450 
451     /*! FreeMASTER Recorder Initialization */
452     FRM_Recorder_Init();
453 
454     /*! Initialize trigger flags */
455     registers.toggle = 1;
456     registers.trigger = 0;
457     registers.read_trigger = 0;
458     registers.read_value = 0;
459     registers.readall_trigger = 0;
460     registers.trigger_accel_offnoise=0;
461     registers.trigger_mag_offnoise=0;
462     registers.dataready_cntr = 0;
463 
464     /*! Initialize read all values */
465     for(int i = 0; i < FXOS8700_NUM_REGISTERS; i++)
466     {
467     	registers.readall_value[i] = 0;
468     }
469 
470     for (;;) /* Forever loop */
471     {
472 
473         /*! Call Recorder#0 in execution loop for generic high-speed variables sampling. */
474         FMSTR_Recorder(0);
475 
476     	/*! Call FreeMASTER host in polling mode */
477 		FMSTR_Poll();
478 
479         /*! Check for any write register trigger from Host */
480 		if (registers.trigger == 1)
481 		{
482 		    /*! Apply Register Write */
483 			status = apply_register_write(FXOS8700drv, registers.offset, registers.value);
484 		    if (SENSOR_ERROR_NONE != status)
485 		    {
486                 return status;
487 		    }
488 		    registers.trigger = 0;
489             /*! Update drop down menu selection based on updated register write */
490 		    update_dropdown_selection(&registers, FXOS8700_REG_WRITE);
491 		}
492 
493         /*! Check for any read register trigger from Host */
494 		if (registers.read_trigger == 1)
495 		{
496 		    /*! Apply Register Write */
497 			status = apply_register_read(FXOS8700drv, registers.read_offset, &(registers.read_value));
498 		    if (SENSOR_ERROR_NONE != status)
499 		    {
500                 return status;
501 		    }
502 		    registers.read_trigger = 0;
503             /*! Update drop down menu selection based on updated register read */
504 		    update_dropdown_selection(&registers, FXOS8700_REG_READ);
505 		}
506 
507         /*! Check for any read all register trigger from Host */
508 		if (registers.readall_trigger == 1)
509 		{
510 		    /*! Apply Register Write */
511 			status = apply_register_readall(FXOS8700drv);
512 		    if (SENSOR_ERROR_NONE != status)
513 		    {
514                 return status;
515 		    }
516 		    registers.readall_trigger = 0;
517 		    registers.readall_size = FXOS8700_NUM_REGISTERS;
518             /*! Update drop down menu selection based on updated all-register read */
519 		    update_dropdown_selection(&registers, FXOS8700_ALLREG_READ);
520 		}
521 
522         /*! Wait for data ready interrupt from the FXOS8700. */
523         if (false == bFxos8700DataReady)
524         {
525             SMC_SetPowerModeWait(SMC); /* Power save, wait if nothing to do. */
526             continue;
527         }
528         else
529         { /*! Clear the data ready flag, it will be set again by the ISR. */
530             bFxos8700DataReady = false;
531             //pGpioDriver->toggle_pin(&GREEN_LED);
532         }
533 
534         /*! Calling Recorder#1 for sampling sensor data when we get sensor data ready interrupt based on ODR. */
535         FMSTR_Recorder(1);
536 
537         /*! Read all FXOS8700 registers */
538         status = FXOS8700_I2C_ReadData(&FXOS8700drv, FXOS8700_ALL_REG_READ, registers.reg_addr);
539         if (0 == (registers.reg_addr[0] & FXOS8700_DR_STATUS_ZYXDR_MASK))
540         { /* Loop, if new sample is not available. */
541             continue;
542         }
543 
544         /*! Convert the raw sensor data to signed 16-bit container for display to the debug port. */
545         rawData.accel[0] = ((int16_t)registers.reg_addr[1] << 8) | registers.reg_addr[2];
546         rawData.accel[0] /= 4;
547         rawData.accel[1] = ((int16_t)registers.reg_addr[3] << 8) | registers.reg_addr[4];
548         rawData.accel[1] /= 4;
549         rawData.accel[2] = ((int16_t)registers.reg_addr[5] << 8) | registers.reg_addr[6];
550         rawData.accel[2] /= 4;
551         rawData.mag[0] = ((int16_t)registers.reg_addr[7] << 8) | registers.reg_addr[8];
552         rawData.mag[1] = ((int16_t)registers.reg_addr[9] << 8) | registers.reg_addr[10];
553         rawData.mag[2] = ((int16_t)registers.reg_addr[11] << 8) | registers.reg_addr[12];
554 
555         status = FXOS8700_I2C_ReadData(&FXOS8700drv, cFXOS8700_whoami, (uint8_t *)&registers.reg_addr[13]);
556 
557         /*! Check the FS and apply sensitivity */
558         status = FXOS8700_I2C_ReadData(&FXOS8700drv, cFXOS8700_fs_src, &regdata);
559         if (regdata == 1)
560         {
561             sensitivity = ACCEL_4G_SENS;
562         }
563         else if (regdata == 2)
564         {
565             sensitivity = ACCEL_8G_SENS;
566         }
567         else
568         {
569             sensitivity = ACCEL_2G_SENS;
570         }
571 
572         /*! Convert raw values to Gs */
573         registers.accel[0] = (float) (rawData.accel[0] * sensitivity);
574         registers.accel[1] = (float) (rawData.accel[1] * sensitivity);
575         registers.accel[2] = (float) (rawData.accel[2] * sensitivity);
576 
577         /*! Increment data ready counter and check for rollover */
578         registers.dataready_cntr++;
579         if(MAX8BITSTORAGE == registers.dataready_cntr)
580         {
581         	registers.dataready_cntr = 0;
582         }
583 
584         if (prev_toggle != registers.toggle)
585         {
586         	pGpioDriver->toggle_pin(&GREEN_LED);
587         	prev_toggle = registers.toggle;
588         }
589 
590         /*! Call offset and noise calculation function for FXOS8700 accelerometer */
591         if (registers.trigger_accel_offnoise == 1)
592         {
593         	accel_off_noise(&(rawData), &(offnoise_data), sensitivity);
594             if (offnoise_data.complete_accel_offnoise == 1)
595             {
596             	registers.trigger_accel_offnoise = 0;
597             	//offnoise_data.complete_accel_offnoise = 0;
598             }
599         }
600 
601         /*! Call offset and noise calculation function for FXOS8700 magnetometer */
602 	   if (registers.trigger_mag_offnoise == 1)
603 	   {
604 		   mag_off_noise(&(rawData), &(offnoise_data));
605 		   if (offnoise_data.complete_mag_offnoise == 1)
606 		   {
607 			registers.trigger_mag_offnoise = 0;
608 			PRINTF("\r\n Mag offset X = %f  Y = %f  Z = %f\r\n", offnoise_data.mag_off[0], offnoise_data.mag_off[1], offnoise_data.mag_off[2]);
609 		   }
610 	   }
611 
612        status = FXOS8700_I2C_ReadData(&FXOS8700drv, cFXOS8700_int_src, &regdata);
613 
614         /*! The following condition checks for multiple interrupts occurring at the same time */
615         if((regdata & FXOS8700_INT_SOURCE_SRC_FFMT_MASK) == 0x04)
616         {
617             ffmt_incr++;
618             if (ffmt_incr == 1)
619             {
620                 registers.freefall_cntr++;
621             }
622         }
623         /*! Check for single-tap detection interrupt */
624         else if((regdata & FXOS8700_INT_SOURCE_SRC_PULSE_MASK) == 0x08)
625         {
626             pulse_incr++;
627             if (pulse_incr == 1)
628             {
629                 registers.tapdetect_cntr++;
630             }
631         }
632         /*! Check for Vector Magnitude change interrupt */
633         else if((regdata & FXOS8700_INT_SOURCE_SRC_A_VECM_MASK) == 0x02)
634         {
635             vecm_incr++;
636             if (vecm_incr == 1)
637             {
638                 registers.vecmchange_cntr++;
639             }
640         }
641         /*! Check for Vector Magnitude change interrupt */
642         else if((regdata & FXOS8700_INT_SOURCE_SRC_LNDPRT_MASK) == 0x10)
643         {
644             orient_incr++;
645             if (orient_incr == 1)
646             {
647                 registers.orient_cntr++;
648             }
649         }
650         /* Else send other interrupts, clear counters */
651         else
652         {
653         	/* Reset all event counters */
654             ffmt_incr = 0;
655             pulse_incr = 0;
656             orient_incr = 0;
657             vecm_incr = 0;
658         }
659 
660         /*! Read FFMT interrupt source register to clear flags */
661         status = FXOS8700_I2C_ReadData(&FXOS8700drv, cFXOS8700_int_src, &regdata);
662         status = FXOS8700_I2C_ReadData(&FXOS8700drv, cFXOS8700_ffmt_src, &regdata);
663         status = FXOS8700_I2C_ReadData(&FXOS8700drv, cFXOS8700_pl_status, &regdata);
664 
665     }
666 }
667 
668 
669 /*!
670  * @brief Service register write trigger from Host
671  */
apply_register_write(fxos8700_i2c_sensorhandle_t FXOS8700drv,uint8_t offset,uint8_t value)672 int32_t apply_register_write(fxos8700_i2c_sensorhandle_t FXOS8700drv, uint8_t offset, uint8_t value)
673 {
674     int32_t status;
675 
676 	if (offset > FXOS8700_NUM_REGISTERS)
677 	{
678 		return SENSOR_ERROR_INVALID_PARAM;
679 	}
680 
681 	registerwritelist_t register_write[] = {
682 	     /*! Set register offset with provided value */
683 	     {offset, value, 0},
684 	      __END_WRITE_DATA__};
685 
686     status = FXOS8700_I2C_Configure(&FXOS8700drv, register_write);
687     if (SENSOR_ERROR_NONE != status)
688     {
689         return SENSOR_ERROR_WRITE;
690     }
691 
692     return SENSOR_ERROR_NONE;
693 }
694 
695 /*!
696  * @brief Service register read trigger from Host
697  */
apply_register_read(fxos8700_i2c_sensorhandle_t FXOS8700drv,uint8_t read_offset,uint8_t * read_value)698 int32_t apply_register_read(fxos8700_i2c_sensorhandle_t FXOS8700drv, uint8_t read_offset, uint8_t *read_value)
699 {
700     int32_t status;
701 
702 	if (read_offset > FXOS8700_NUM_REGISTERS)
703 	{
704 		return SENSOR_ERROR_INVALID_PARAM;
705 	}
706 
707 	registerreadlist_t register_read[] = {
708 		     /*! Set register offset with provided value */
709 	        {.readFrom = read_offset, .numBytes = 1}, __END_READ_DATA__};
710 
711     status = FXOS8700_I2C_ReadData(&FXOS8700drv, register_read, read_value);
712     if (SENSOR_ERROR_NONE != status)
713     {
714         return SENSOR_ERROR_WRITE;
715     }
716 
717     return SENSOR_ERROR_NONE;
718 }
719 
720 /*!
721  * @brief Service register read all trigger from Host
722  */
apply_register_readall(fxos8700_i2c_sensorhandle_t FXOS8700drv)723 int32_t apply_register_readall(fxos8700_i2c_sensorhandle_t FXOS8700drv)
724 {
725     int32_t status;
726 
727 	for (int reg_offset = FXOS8700_STATUS; reg_offset <= FXOS8700_A_FFMT_THS_Z_LSB; reg_offset++)
728 	{
729 		registerreadlist_t register_readall[] = {
730 				 /*! Set register offset with provided value */
731 				{.readFrom = reg_offset, .numBytes = 1}, __END_READ_DATA__};
732 
733 		status = FXOS8700_I2C_ReadData(&FXOS8700drv, register_readall, &(registers.readall_value[reg_offset]));
734 		if (SENSOR_ERROR_NONE != status)
735 		{
736 			return SENSOR_ERROR_READ;
737 		}
738 	}
739 
740     return SENSOR_ERROR_NONE;
741 }
742 
743 /*!
744  * @brief Update drop down selection values based on register write, read or readall.
745  */
update_dropdown_selection(fxos8700_allregs_t * registers,uint8_t caller)746 int32_t update_dropdown_selection( fxos8700_allregs_t *registers, uint8_t caller)
747 {
748 
749     int32_t status = SENSOR_ERROR_NONE;
750 
751 	switch (caller)
752 	{
753 		case FXOS8700_REG_WRITE:
754 
755             /*! Update drop down option based on updated read value */
756 		    if(FXOS8700_XYZ_DATA_CFG == registers->offset) //FS Selection
757 		    {
758 			    registers->fs_value = registers->value;
759 		    }
760 		    else if (FXOS8700_CTRL_REG2 == registers->offset)
761 		    {
762 			    registers->mods_value = registers->value;
763 		    }
764 			break;
765 		case FXOS8700_REG_READ: //Called from Register Read
766 
767             /*! Update drop down option based on updated read value */
768 		    if(FXOS8700_XYZ_DATA_CFG == registers->read_offset) //FS Selection
769 		    {
770 			    registers->fs_value = registers->read_value;
771 		    }
772 		    else if (FXOS8700_CTRL_REG2 == registers->offset)
773 		    {
774 			    registers->mods_value = registers->read_value;
775 		    }
776 			break;
777 		case FXOS8700_ALLREG_READ: //Called from Register ReadAll
778 
779             /*! Update drop down option based on updated read values */
780 			registers->fs_value = registers->reg_addr[FXOS8700_XYZ_DATA_CFG];
781 			registers->mods_value = registers->reg_addr[FXOS8700_CTRL_REG2];
782 			break;
783         default:
784             status = SENSOR_ERROR_INVALID_PARAM;
785             break;
786 	}
787 
788     return status;
789 
790 }
791 
792 /*******************************************************************************
793  * OFFSET NOISE CALCULATION
794  ******************************************************************************/
795 
796 /*!
797  * @brief Initialize Offset-Noise Variables
798  */
offset_noise_init(fxos8700_offset_noise_t * offnoiseptr)799 void offset_noise_init(fxos8700_offset_noise_t *offnoiseptr)
800 {
801 	offnoiseptr->offx = 0.0;
802 	offnoiseptr->offy = 0.0;
803 	offnoiseptr->offz = 0.0;
804 	offnoiseptr->rmsx = 0.0;
805 	offnoiseptr->rmsy = 0.0;
806 	offnoiseptr->rmsz = 0.0;
807 	offnoiseptr->mag_off[0] = 0.0;
808 	offnoiseptr->mag_off[1] = 0.0;
809 	offnoiseptr->mag_off[2] = 0.0;
810 	offnoiseptr->mag_rms[0] = 0.0;
811 	offnoiseptr->mag_rms[1] = 0.0;
812 	offnoiseptr->mag_rms[2] = 0.0;
813 	offnoiseptr->complete_accel_offnoise = 0;
814 	offnoiseptr->complete_mag_offnoise = 0;
815 }
816 
817 
818 /* Calculate Offset & Noise for ACCELEROMETER */
accel_off_noise(fxos8700_accelmagdata_t * rawData,fxos8700_offset_noise_t * offnoiseptr,float sens)819 void accel_off_noise(fxos8700_accelmagdata_t* rawData,fxos8700_offset_noise_t *offnoiseptr, float sens)
820 {
821 	uint16_t j;
822 	static uint16_t k=0;
823 	static uint16_t cntr=0;
824 	static float stdx=0;
825 	static float stdy=0;
826 	static float stdz=0;
827 	static float xx[N], yy[N], zz[N];
828 	static float xm[N], ym[N], zm[N];
829 	static float xsq[N], ysq[N], zsq[N];
830 	float am[3];
831 	static float sumx=0.0;
832 	static float sumy=0.0;
833 	static float sumz=0.0;
834 
835     /* Init offset noise variables */
836     offset_noise_init(offnoiseptr);
837 
838 	cntr++;
839 
840 	/* Store Accel samples and calculate sum for configured N */
841 	if(cntr < N)
842 	{
843 		 am[0]=rawData->accel[0]*sens;
844 		 am[1]=rawData->accel[1]*sens;
845 		 am[2]=rawData->accel[2]*sens;
846 		 xx[k]=am[0];
847 		 yy[k]=am[1];
848 		 zz[k]=am[2];
849 		 sumx+=am[0];
850 		 sumy+=am[1];
851 		 sumz+=am[2];
852 		 k+=1;
853 		 offnoiseptr->complete_accel_offnoise = 0;
854 	}
855 
856 	/* Measure offset and RMS */
857 	if(cntr == N)
858 	{
859 		/* Measure average */
860 		sumx=sumx/(N-1);
861 		sumy=sumy/(N-1);
862 		sumz=sumz/(N-1);
863 
864 		/* Measure offset */
865 		offnoiseptr->offx=0-sumx;
866 		offnoiseptr->offy=0-sumy;
867 		offnoiseptr->offz=1-sumz;
868 
869 		/* Measure standard deviation */
870 		for(j=0; j<N-1; j++)
871 		{
872 			xm[j]=xx[j]-sumx;
873 			ym[j]=yy[j]-sumy;
874 			zm[j]=zz[j]-sumz;
875 
876 			xsq[j]=pow(xm[j],2);
877 			ysq[j]=pow(ym[j],2);
878 			zsq[j]=pow(zm[j],2);
879 			stdx+=xsq[j];
880 			stdy+=ysq[j];
881 			stdz+=zsq[j];
882 		}
883 		stdx=stdx/(N-2);
884 		stdy=stdy/(N-2);
885 		stdz=stdz/(N-2);
886 
887         /* Measure RMS */
888 		offnoiseptr->rmsx=pow(stdx,0.5);
889 		offnoiseptr->rmsy=pow(stdy,0.5);
890 		offnoiseptr->rmsz=pow(stdz,0.5);
891 
892 		/* Set the completion flag */
893 		offnoiseptr->complete_accel_offnoise = 1;
894 
895 		/* Reset local storage */
896 		cntr = k = 0;
897 		sumx = sumy = sumz = 0;
898 		stdx = stdy = stdz = 0;
899 	}
900 }
901 
902 /* Calculate Offset & Noise for MAGNETOMETER */
mag_off_noise(fxos8700_accelmagdata_t * rawData,fxos8700_offset_noise_t * offnoiseptr)903 void mag_off_noise(fxos8700_accelmagdata_t* rawData,fxos8700_offset_noise_t *offnoiseptr)
904 {
905 	//local variables
906 
907 	uint16_t j;
908 	static uint16_t k;
909 	static uint16_t cntr=0;
910 	static float stdx=0;
911 	static float stdy=0;
912 	static float stdz=0;
913 	static float xx[N], yy[N], zz[N];
914 	static float xm[N], ym[N], zm[N];
915 	static float xsq[N], ysq[N], zsq[N];
916 	float mm[3];
917 	float Bx[2] = {0,0};
918 	float By[2] = {0,0};
919 	float Bz[2] = {0,0};
920 	float sens=0.1; //uT
921 	static float sumx=0.0;
922 	static float sumy=0.0;
923 	static float sumz=0.0;
924 	//float refx, refy, refz;
925 
926     /* Init offset noise variables */
927     offset_noise_init(offnoiseptr);
928 
929 	cntr++;
930 	 if(cntr < N)
931 	        {
932 		       /* if (cntr == 1)
933 		        {
934 		        	refx = rawData->mag[0]*sens;
935 		        	refy = rawData->mag[1]*sens;
936 		        	refz = rawData->mag[2]*sens;
937 		        }*/
938 		         mm[0]=rawData->mag[0]*sens;
939 		         mm[1]=rawData->mag[1]*sens;
940 		         mm[2]=rawData->mag[2]*sens;
941 	        	 xx[k]=mm[0];
942 	        	 yy[k]=mm[1];
943 	        	 zz[k]=mm[2];
944 	        	 Bx[0]=xx[0];
945 	        	 Bx[1]=xx[0];
946 	        	 By[0]=yy[0];
947 	        	 By[1]=yy[0];
948 	        	 Bz[0]=zz[0];
949 	        	 Bz[1]=zz[0];
950 	        	 sumx+=mm[0];
951 	        	 sumy+=mm[1];
952 	        	 sumz+=mm[2];
953 	        	 //Bx[0]=
954 	        	 k+=1;
955 	        	 offnoiseptr->complete_mag_offnoise = 0;
956 	        }
957 	        if(cntr == N)
958 	        {
959 	        	sumx=sumx/(N-1);
960 	            sumy=sumy/(N-1);
961 	            sumz=sumz/(N-1);
962 	        	for (j=0; j<N; j++)
963 	        	{
964 	        		/*if (!(xx[i]>=Bx[0]))
965 	        		{
966 	        			Bx[0]=xx[i];
967 	        		}
968 	        		if(!(xx[i] <= Bx[1]))
969 	        		{
970 	        			Bx[1]=xx[i];
971 	        		} */
972 	        		if(Bx[0] > xx[j]) Bx[0]=xx[j]; //minimum value
973 	        		if(Bx[1] < xx[j]) Bx[1]=xx[j]; //maximum value
974 	        		if(By[0] > yy[j]) By[0]=yy[j];
975 	        		if(By[1] < yy[j]) By[1]=yy[j];
976 	        		if(Bz[0] > zz[j]) Bz[0]=zz[j];
977 	        		if(Bz[1] < zz[j]) Bz[1]=zz[j];
978 
979 	        	}
980 	            offnoiseptr->mag_off[0]=0.5*(Bx[0]+Bx[1]);
981 	            offnoiseptr->mag_off[1]=0.5*(By[0]+By[1]);
982 	            offnoiseptr->mag_off[2]=0.5*(Bz[0]+Bz[1]);
983 	            for(j=0; j<N-1; j++)
984 	            {
985 	            	xm[j]=xx[j]-sumx;
986 	                ym[j]=yy[j]-sumy;
987 	                zm[j]=zz[j]-sumz;
988 	                 			 //PRINTF("\r\n Before X = %f  Y = %f  Z = %f\r\n", xx[j], yy[j], zz[j]);
989 	                xsq[j]=pow(xm[j],2);
990 	                ysq[j]=pow(ym[j],2);
991 	                zsq[j]=pow(zm[j],2);
992 	                stdx+=xsq[j];
993 	                stdy+=ysq[j];
994 	                stdz+=zsq[j];
995 	            }
996 	                stdx=stdx/(N-2);
997 	                stdy=stdy/(N-2);
998 	                stdz=stdz/(N-2);
999 	                 		 //PRINTF("\r\n Accel StdX = %f  StdY = %f  StdZ = %f\r\n", stdx, stdy, stdz);
1000 	                offnoiseptr->mag_rms[0]=pow(stdx,0.5);
1001 	                offnoiseptr->mag_rms[1]=pow(stdy,0.5);
1002 	                offnoiseptr->mag_rms[2]=pow(stdz,0.5);
1003 
1004 	                offnoiseptr->complete_mag_offnoise = 1;
1005 	                cntr = k = 0;
1006 	                sumx = sumy = sumz = 0;
1007 	                stdx = stdy = stdz = 0;
1008 	                //refx = refy = refz = 0;
1009 	        }
1010 
1011 }
1012 
1013 
1014 /*!
1015  * @brief UART Module initialization (UART is a the standard block included e.g. in K22F)
1016  */
init_freemaster_uart(void)1017 static void init_freemaster_uart(void)
1018 {
1019     uart_config_t config;
1020 
1021     /*
1022      * config.baudRate_Bps = 115200U;
1023      * config.parityMode = kUART_ParityDisabled;
1024      * config.stopBitCount = kUART_OneStopBit;
1025      * config.txFifoWatermark = 0;
1026      * config.rxFifoWatermark = 1;
1027      * config.enableTx = false;
1028      * config.enableRx = false;
1029      */
1030     UART_GetDefaultConfig(&config);
1031     config.baudRate_Bps = 115200U;
1032     config.enableTx = false;
1033     config.enableRx = false;
1034 
1035     UART_Init((UART_Type*)BOARD_DEBUG_UART_BASEADDR, &config, BOARD_DEBUG_UART_CLK_FREQ);
1036 
1037     /* Register communication module used by FreeMASTER driver. */
1038     FMSTR_SerialSetBaseAddress((UART_Type*)BOARD_DEBUG_UART_BASEADDR);
1039 
1040 #if FMSTR_SHORT_INTR || FMSTR_LONG_INTR
1041     /* Enable UART interrupts. */
1042     EnableIRQ(BOARD_UART_IRQ);
1043     EnableGlobalIRQ(0);
1044 #endif
1045 }
1046 
1047 #if FMSTR_SHORT_INTR || FMSTR_LONG_INTR
1048 /*
1049 *   Application interrupt handler of communication peripheral used in interrupt modes
1050 *   of FreeMASTER communication.
1051 *
1052 *   NXP MCUXpresso SDK framework defines interrupt vector table as a part of "startup_XXXXXX.x"
1053 *   assembler/C file. The table points to weakly defined symbols, which may be overwritten by the
1054 *   application specific implementation. FreeMASTER overrides the original weak definition and
1055 *   redirects the call to its own handler.
1056 *
1057 */
1058 
BOARD_UART_IRQ_HANDLER(void)1059 void BOARD_UART_IRQ_HANDLER(void)
1060 {
1061     /* Call FreeMASTER Interrupt routine handler */
1062     FMSTR_SerialIsr();
1063     /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
1064         exception return operation might vector to incorrect interrupt */
1065 #if defined __CORTEX_M && (__CORTEX_M == 4U)
1066     __DSB();
1067 #endif
1068 }
1069 #endif
1070 
1071