1 /*
2  * Copyright 2020-2021 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 /**
9  * @file fxls8962_freemaster_demo.c
10  * @brief The fxls8962_freemaster_demo.c file implements FreeMASTER demo using the ISSDK
11  *        FXLS896x sensor driver example demonstration with interrupt mode.
12  */
13 
14 //-----------------------------------------------------------------------
15 // SDK Includes
16 //-----------------------------------------------------------------------
17 #include "pin_mux.h"
18 #include "clock_config.h"
19 #include "board.h"
20 #include "fsl_debug_console.h"
21 #include "math.h"
22 #include "fsl_uart.h"
23 #include "fsl_common.h"
24 #include "freemaster.h"
25 #include "freemaster_serial_uart.h"
26 //-----------------------------------------------------------------------
27 // CMSIS Includes
28 //-----------------------------------------------------------------------
29 #include "Driver_I2C.h"
30 
31 //-----------------------------------------------------------------------
32 // ISSDK Includes
33 //-----------------------------------------------------------------------
34 #include "issdk_hal.h"
35 #include "gpio_driver.h"
36 #include "fxls8962_drv.h"
37 #include "systick_utils.h"
38 
39 //-----------------------------------------------------------------------
40 // Macros
41 //-----------------------------------------------------------------------
42 #define FXLS896x_NUM_REGISTERS (FXLS8962_SELF_TEST_CONFIG2 + 1)
43 #define FF_A_FFMT_THS          (0x08)       /* FreeFall Threshold Value. */
44 #define A_FFMT_COUNT           (0x18)       /* Freefall/motion debounce count value. */
45 #define PL_COUNT               (0x15)       /* Pulse debounce count value. */
46 #define ASLP_COUNTER           (0x07)       /* Auto Sleep after ~5s. */
47 #define ACCEL_2G_SENS          (0.000976)   /* Sensitivity factor for 2G FS */
48 #define ACCEL_4G_SENS          (0.001953)   /* Sensitivity factor for 4G FS */
49 #define ACCEL_8G_SENS          (0.003906)   /* Sensitivity factor for 8G FS */
50 #define ACCEL_16G_SENS         (0.007813)   /* Sensitivity factor for 16G FS */
51 #define N                      (100U)       /* Number of samples used to measure offset/noise */
52 #define RAW_ACCEL_DATA_SIZE    (6U)         /* Accel Data Size */
53 #define MAX8BITSTORAGE         (255U)
54 #define FXLS8962_DATA_SIZE 6
55 //-----------------------------------------------------------------------
56 // Constants
57 //-----------------------------------------------------------------------
58 /*! @brief Defines the register write list to configure FXLS896x in Interrupt mode. */
59 const registerwritelist_t cFxls8962ConfigNormal[] = {
60     /*! Set Full-scale range as 4G. */
61     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_FSR_4G, FXLS8962_SENS_CONFIG1_FSR_MASK},
62     /*! Clear SENS_CONFIG2 */
63     {FXLS8962_SENS_CONFIG2, 0x00, 0x00},
64     /*! Disable Self-Test. */
65     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_ST_AXIS_SEL_DISABLED, FXLS8962_SENS_CONFIG1_ST_AXIS_SEL_MASK},
66     /*! Set Wake Mode ODR Rate as 12.5Hz. */
67     {FXLS8962_SENS_CONFIG3, FXLS8962_SENS_CONFIG3_WAKE_ODR_12_5HZ, FXLS8962_SENS_CONFIG3_WAKE_ODR_MASK},
68     /*! Enable Interrupts for Data Ready Events. */
69     {FXLS8962_INT_EN, FXLS8962_INT_EN_DRDY_EN_EN, FXLS8962_INT_EN_DRDY_EN_MASK},
70     /*! Enable Temperature sensor. */
71     {FXLS8962_SENS_CONFIG2,FXLS8962_SENS_CONFIG2_ANIC_TEMP_EN,FXLS8962_SENS_CONFIG2_ANIC_TEMP_MASK},
72     /*! Set Self-Test ODR to 100 Hz. */
73     {0x38,0x05,0x00},
74     {0x2F,0x38,0x00},
75     {0x30,0xD8,0x00},
76     {0x33,0xC0,0x00},
77     {0x34,0xFF,0x00},
78     {0x35,0x40,0x00},
79     __END_WRITE_DATA__};
80 
81 /*! @brief Register settings for Self-Test in X Axis (Positive polarity). */
82 const registerwritelist_t cFxls8962STXP[] = {
83     /* Set Self Test Axis. */
84     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_FSR_16G, FXLS8962_SENS_CONFIG1_FSR_MASK},
85     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_ST_AXIS_SEL_EN_X, FXLS8962_SENS_CONFIG1_ST_AXIS_SEL_MASK},
86     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_ST_POL_POSITIVE,  FXLS8962_SENS_CONFIG1_ST_POL_MASK},
87     __END_WRITE_DATA__};
88 
89 /*! @brief Register settings for Self-Test in X Axis (Negative polarity). */
90 const registerwritelist_t cFxls8962STXN[] = {
91     /* Set Self Test Axis. */
92     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_FSR_16G, FXLS8962_SENS_CONFIG1_FSR_MASK},
93     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_ST_AXIS_SEL_EN_X, FXLS8962_SENS_CONFIG1_ST_AXIS_SEL_MASK},
94     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_ST_POL_NEGATIVE, FXLS8962_SENS_CONFIG1_ST_POL_MASK},
95     __END_WRITE_DATA__};
96 
97 /*! @brief Register settings for Self-Test in Y Axis (Positive polarity). */
98 const registerwritelist_t cFxls8962STYP[] = {
99     /* Set Self Test Axis. */
100     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_FSR_16G, FXLS8962_SENS_CONFIG1_FSR_MASK},
101     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_ST_AXIS_SEL_EN_Y, FXLS8962_SENS_CONFIG1_ST_AXIS_SEL_MASK},
102     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_ST_POL_POSITIVE,FXLS8962_SENS_CONFIG1_ST_POL_MASK},
103     __END_WRITE_DATA__};
104 
105 /*! @brief Register settings for Self-Test in Y Axis (Negative polarity). */
106 const registerwritelist_t cFxls8962STYN[] = {
107     /* Set Self Test Axis. */
108     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_FSR_16G, FXLS8962_SENS_CONFIG1_FSR_MASK},
109     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_ST_AXIS_SEL_EN_Y, FXLS8962_SENS_CONFIG1_ST_AXIS_SEL_MASK},
110     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_ST_POL_NEGATIVE, FXLS8962_SENS_CONFIG1_ST_POL_MASK},
111     __END_WRITE_DATA__};
112 
113 /*! @brief Register settings for Self-Test in Z Axis (Positive polarity). */
114 const registerwritelist_t cFxls8962STZP[] = {
115     /* Set Self Test Axis. */
116     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_FSR_16G, FXLS8962_SENS_CONFIG1_FSR_MASK},
117     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_ST_AXIS_SEL_EN_Z, FXLS8962_SENS_CONFIG1_ST_AXIS_SEL_MASK},
118     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_ST_POL_POSITIVE, FXLS8962_SENS_CONFIG1_ST_POL_MASK},
119     __END_WRITE_DATA__};
120 
121 /*! @brief Register settings for Self-Test in Z Axis (Negative polarity). */
122 const registerwritelist_t cFxls8962STZN[] = {
123     /* Set Self Test Axis. */
124     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_FSR_16G, FXLS8962_SENS_CONFIG1_FSR_MASK},
125     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_ST_AXIS_SEL_EN_Z, FXLS8962_SENS_CONFIG1_ST_AXIS_SEL_MASK},
126     {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_ST_POL_NEGATIVE,  FXLS8962_SENS_CONFIG1_ST_POL_MASK},
127     __END_WRITE_DATA__};
128 
129 /*! @brief Address of Raw Accel Data in Normal Mode. */
130 const registerreadlist_t cFxls8962OutputNormal[] = {{.readFrom = FXLS8962_OUT_X_LSB, .numBytes = FXLS8962_DATA_SIZE},
131     __END_READ_DATA__};
132 
133 const registerreadlist_t cFXLS896x_whoami[] = {
134         {.readFrom = FXLS8962_WHO_AM_I, .numBytes = 1}, __END_READ_DATA__};
135 
136 /*! @brief Prepare the register read for INT Status Register. */
137 const registerreadlist_t cFXLS896x_int_src[] = {
138         {.readFrom = FXLS8962_INT_STATUS, .numBytes = 1}, __END_READ_DATA__};
139 
140 /*! @brief Prepare the register read for FullScale range Register. */
141 const registerreadlist_t cFXLS896x_fs_src[] = {
142         {.readFrom = FXLS8962_SENS_CONFIG1, .numBytes = 1}, __END_READ_DATA__};
143 
144 /*! @brief FXLS896x register list to read all registers */
145 const registerreadlist_t FXLS896x_ALL_REG_READ[] = {{.readFrom = FXLS8962_INT_STATUS, .numBytes = FXLS896x_NUM_REGISTERS},
146                                                       __END_READ_DATA__};
147 
148 //-----------------------------------------------------------------------
149 // Global Variables
150 //-----------------------------------------------------------------------
151 /*! @brief This structure defines the fxls896x all registers metadata.*/
152 typedef struct
153 {
154     uint8_t offset;
155     uint8_t value;
156     uint8_t trigger;
157     uint8_t read_offset;
158     uint8_t read_value;
159     uint8_t read_trigger;
160     uint8_t readall_value[FXLS896x_NUM_REGISTERS];
161     uint8_t readall_size;
162     uint8_t readall_trigger;
163     uint8_t toggle;
164     uint8_t trigger_accel_offnoise;
165     uint8_t trigger_selftest;
166     uint8_t fs_value;
167     uint8_t mods_value;
168     uint8_t odr_value;
169     uint16_t freefall_cntr;
170     uint16_t tapdetect_cntr;
171     uint16_t orient_cntr;
172     uint16_t vecmchange_cntr;
173     uint8_t reg_addr[FXLS896x_NUM_REGISTERS];
174     uint8_t dataready_cntr;
175     float accel[3];
176     uint8_t sdcd;
177     int8_t temp;
178     int16_t selftest[3];
179 } fxls896x_allregs_t;
180 //-----------------------------------------------------------------------
181 /*! @brief This structure defines the fxls896x offset and noise calculation parameters. */
182 typedef struct
183 {
184   	float offx;
185   	float offy;
186   	float offz;
187   	float rmsx;
188   	float rmsy;
189   	float rmsz;
190   	uint8_t complete_accel_offnoise;
191 } fxls896x_offset_noise_t;
192 
193 /*! @brief This structure defines variables to compute self-test output change (STOC) and self-test offset (STOF). */
194 typedef struct
195 {
196 	int16_t x_stoc;
197 	int16_t y_stoc;
198 	int16_t z_stoc;
199 	int16_t x_stof;
200 	int16_t y_stof;
201 	int16_t z_stof;
202   	uint8_t complete_selftest;
203 } fxls896x_selftest_t;
204 
205 /*! @brief This structure defines the fxls8962 raw data buffer.*/
206 typedef struct
207 {
208     int16_t xdata; /*!< The x accel data */
209     int16_t ydata; /*!< The y accel data */
210     int16_t zdata; /*!< The z accel data */
211 } sensor_data;
212 
213 
214 typedef union rawdata
215 {
216 	uint8_t byte_data[sizeof(sensor_data)];
217 	sensor_data dat;
218 }RAW_DATA;
219 
220 /*! @brief This structure defines the fxls8962 host operation type.*/
221 typedef enum fxls896x_operation_type
222 {
223 	FXLS896x_REG_WRITE   = 1U,
224 	FXLS896x_REG_READ    = 2U,
225     FXLS896x_ALLREG_READ = 3U,
226 	FXLS896x_ACCEL_CONFIG_END
227 
228 } fxls896x_operation_type_t;
229 
230 /*******************************************************************************
231  * Globals
232  ******************************************************************************/
233 
234 fxls8962_acceldata_t rawData;
235 fxls896x_allregs_t      registers;
236 fxls896x_offset_noise_t offnoise_data;
237 fxls896x_selftest_t selftest;
238 uint8_t prev_toggle = 1;
239 volatile bool bFxls896xIntFlag = false;
240 
241 static FMSTR_U8 recBuffer[1024*10];
242 FMSTR_REC_BUFF  recBuffCfg;
243 FMSTR_REC_VAR   recVar;
244 FMSTR_REC_CFG   recCfg;
245 
246 uint8_t axis=0;
247 /* variables to store self-test values (Positive(P) + / Negative(N) -) */
248 int16_t XSTP[2]={0,0},YSTP[2]={0,0},ZSTP[2]={0,0},XSTN[2]={0,0},YSTN[2]={0,0},ZSTN[2]={0,0};
249 
250 
251 /*******************************************************************************
252  * Local functions
253  ******************************************************************************/
254  /*! @brief           Function to initialize target communication to FreeMASTER host.
255  *  @details         This function initializes FreeMASTER UART communication.
256  *  @param[in]       void.
257  *  @return          void.
258  */
259 static void init_freemaster_uart(void);
260 /*! @brief           ISR for FXLS896x interrupt source event.
261  *  @details         This function implements ISR for FXLS896x INT source.
262  *  @param[in]       void *.
263  *  @return          void.
264  */
265 void fxls896x_isr_callback(void *pUserData);
266 /*! @brief           Function to apply FXLS896x register write operation.
267  *  @details         This function apply FXLS896x register write based on write trigger from host.
268  *  @param[in]       fxls8962_i2c_sensorhandle_t fxls8962Driver, FXLS896x sensor I2C handle.
269  *  @param[in]       uint8_t offset, the address of the register to start writing from.
270  *  @param[in]       uint8_t value, value to write on register offset.
271  *  @return          returns the status of the operation.
272  */
273 int32_t apply_register_write(fxls8962_i2c_sensorhandle_t fxls8962Driver, uint8_t offset, uint8_t value);
274 /*! @brief           Function to apply FXLS896x register read operation.
275  *  @details         This function apply FXLS896x register read based on read trigger from host.
276  *  @param[in]       fxls8962_i2c_sensorhandle_t fxls8962Driver, FXLS896x sensor I2C handle.
277  *  @param[in]       uint8_t offset, the address of the register to read from.
278  *  @param[in/out]   uint8_t *value, pointer to output buffer.
279  *  @return          returns the status of the operation.
280  */
281 int32_t apply_register_read(fxls8962_i2c_sensorhandle_t fxls8962Driver, uint8_t offset, uint8_t *value);
282 /*! @brief           Function to apply FXLS896x register read-all operation.
283  *  @details         This function apply FXLS896x all-registers read based on read-all trigger from host.
284  *  @param[in]       fxls8962_i2c_sensorhandle_t fxls8962Driver, FXLS896x sensor I2C handle.
285  *  @return          returns the status of the operation.
286  */
287 int32_t apply_register_readall(fxls8962_i2c_sensorhandle_t fxls8962Driver);
288 /*! @brief           Function to update dropdown selection.
289  *  @details         This function updates the dropdown selection values in real-time based on read/write/read-all triggers.
290  *  @param[in/out]   fxls896x_allregs_t *registers, pointer to FXLS896x all-registers metadata.
291  *  @param[in]       uint8_t caller, called from which operation type.
292  *  @return          returns the status of the operation.
293  */
294 int32_t update_dropdown_selection(fxls896x_allregs_t *registers, uint8_t caller);
295 /*! @brief           Function to initialize offset noise measurement.
296  *  @details         This function initializes offset noise measurement metadata.
297  *  @param[in/out]   fxls896x_offset_noise_t *offnoiseptr, pointer to FXLS896x offset noise metadata.
298  *  @return          void.
299  */
300 void offset_noise_init(fxls896x_offset_noise_t *offnoiseptr);
301 /*! @brief           Function to measure accelerometer offset noise.
302  *  @details         This function measures accelerometer offset noise.
303  *  @param[in]       fxls8962_acceldata_t *rawData, pointer to FXLS896x rawdata metadata.
304  *  @param[in/out]   fxls896x_offset_noise_t *offnoiseptr, pointer to FXLS896x offset noise metadata.
305  *  @param[in]       float sens, FXLS896x sensitivity based on FS configuration.
306  *  @return          void.
307  */
308 void accel_off_noise(fxls8962_acceldata_t* rawData, fxls896x_offset_noise_t *offnoiseptr, float sens);
309 /*! @brief           Function to initialize FXLS896x self test metadata.
310  *  @details         This function initializes FXLS896x self test metadata.
311  *  @param[in/out]   fxls896x_selftest_t *selftest, pointer to FXLS896x selftest metadata.
312  *  @return          void.
313  */
314 void selftest_init(fxls896x_selftest_t *selftest);
315 /*! @brief           Function to perform FXLS896x self test.
316  *  @details         This function performs FXLS896x self test.
317  *  @param[in]       fxls8962_i2c_sensorhandle_t fxls8962Driver, FXLS896x sensor I2C handle.
318  *  @param[in/out]   fxls896x_selftest_t *selftest, pointer to FXLS896x selftest metadata.
319  *  @return          returns the status of the operation..
320  */
321 int32_t perform_selftest(fxls8962_i2c_sensorhandle_t fxls8962Driver, fxls896x_selftest_t *selftest);
322 void FRM_Recorder_Init();
323 
324 /*******************************************************************************
325  * Code
326  ******************************************************************************/
fxls896x_isr_callback(void * pUserData)327 void fxls896x_isr_callback(void *pUserData)
328 { /*! @brief Set flag to indicate Sensor has signalled data ready. */
329     bFxls896xIntFlag = true;
330 }
331 
332 /* Create TSA table and add output variables. */
333 /*!
334  * @brief Target Side Addressable (TSA) table created for this application.
335  */
336 FMSTR_TSA_TABLE_BEGIN(main_table)
FMSTR_TSA_STRUCT(fxls8962_acceldata_t)337 	FMSTR_TSA_STRUCT(fxls8962_acceldata_t)
338 
339 	FMSTR_TSA_STRUCT(fxls896x_allregs_t)
340     FMSTR_TSA_MEMBER(fxls896x_allregs_t, offset, FMSTR_TSA_UINT8)
341     FMSTR_TSA_MEMBER(fxls896x_allregs_t, value, FMSTR_TSA_UINT8)
342     FMSTR_TSA_MEMBER(fxls896x_allregs_t, trigger, FMSTR_TSA_UINT8)
343     FMSTR_TSA_MEMBER(fxls896x_allregs_t, read_offset, FMSTR_TSA_UINT8)
344     FMSTR_TSA_MEMBER(fxls896x_allregs_t, read_value, FMSTR_TSA_UINT8)
345     FMSTR_TSA_MEMBER(fxls896x_allregs_t, read_trigger, FMSTR_TSA_UINT8)
346     FMSTR_TSA_MEMBER(fxls896x_allregs_t, readall_value, FMSTR_TSA_UINT8)
347     FMSTR_TSA_MEMBER(fxls896x_allregs_t, readall_size, FMSTR_TSA_UINT8)
348     FMSTR_TSA_MEMBER(fxls896x_allregs_t, readall_trigger, FMSTR_TSA_UINT8)
349 	FMSTR_TSA_MEMBER(fxls896x_allregs_t, trigger_accel_offnoise, FMSTR_TSA_UINT8)
350 	FMSTR_TSA_MEMBER(fxls896x_allregs_t, trigger_selftest, FMSTR_TSA_UINT8)
351 	FMSTR_TSA_MEMBER(fxls896x_allregs_t, fs_value, FMSTR_TSA_UINT8)
352 	FMSTR_TSA_MEMBER(fxls896x_allregs_t, mods_value, FMSTR_TSA_UINT8)
353 	FMSTR_TSA_MEMBER(fxls896x_allregs_t, odr_value, FMSTR_TSA_UINT8)
354 	FMSTR_TSA_MEMBER(fxls896x_allregs_t, toggle, FMSTR_TSA_UINT8)
355     FMSTR_TSA_MEMBER(fxls896x_allregs_t, freefall_cntr, FMSTR_TSA_UINT16)
356     FMSTR_TSA_MEMBER(fxls896x_allregs_t, tapdetect_cntr, FMSTR_TSA_UINT16)
357     FMSTR_TSA_MEMBER(fxls896x_allregs_t, orient_cntr, FMSTR_TSA_UINT16)
358 	FMSTR_TSA_MEMBER(fxls896x_allregs_t, vecmchange_cntr, FMSTR_TSA_UINT16)
359     FMSTR_TSA_MEMBER(fxls896x_allregs_t, reg_addr, FMSTR_TSA_UINT8)
360     FMSTR_TSA_MEMBER(fxls896x_allregs_t, accel, FMSTR_TSA_FLOAT)
361     FMSTR_TSA_MEMBER(fxls896x_allregs_t, sdcd, FMSTR_TSA_UINT8)
362     FMSTR_TSA_MEMBER(fxls896x_allregs_t, temp, FMSTR_TSA_SINT8)
363     FMSTR_TSA_MEMBER(fxls896x_allregs_t, selftest, FMSTR_TSA_SINT16)
364     FMSTR_TSA_MEMBER(fxls896x_allregs_t, dataready_cntr, FMSTR_TSA_UINT8)
365 
366 	FMSTR_TSA_STRUCT(fxls896x_offset_noise_t)
367 	FMSTR_TSA_MEMBER(fxls896x_offset_noise_t, offx, FMSTR_TSA_FLOAT)
368 	FMSTR_TSA_MEMBER(fxls896x_offset_noise_t, offy, FMSTR_TSA_FLOAT)
369 	FMSTR_TSA_MEMBER(fxls896x_offset_noise_t, offz, FMSTR_TSA_FLOAT)
370 	FMSTR_TSA_MEMBER(fxls896x_offset_noise_t, rmsx, FMSTR_TSA_FLOAT)
371 	FMSTR_TSA_MEMBER(fxls896x_offset_noise_t, rmsy, FMSTR_TSA_FLOAT)
372 	FMSTR_TSA_MEMBER(fxls896x_offset_noise_t, rmsz, FMSTR_TSA_FLOAT)
373 	FMSTR_TSA_MEMBER(fxls896x_offset_noise_t, complete_accel_offnoise, FMSTR_TSA_UINT8)
374 
375 
376 	FMSTR_TSA_STRUCT(fxls896x_selftest_t)
377     FMSTR_TSA_MEMBER(fxls896x_selftest_t, x_stoc, FMSTR_TSA_SINT16)
378     FMSTR_TSA_MEMBER(fxls896x_selftest_t, y_stoc, FMSTR_TSA_SINT16)
379     FMSTR_TSA_MEMBER(fxls896x_selftest_t, z_stoc, FMSTR_TSA_SINT16)
380     FMSTR_TSA_MEMBER(fxls896x_selftest_t, x_stof, FMSTR_TSA_SINT16)
381     FMSTR_TSA_MEMBER(fxls896x_selftest_t, y_stof, FMSTR_TSA_SINT16)
382     FMSTR_TSA_MEMBER(fxls896x_selftest_t, z_stof, FMSTR_TSA_SINT16)
383 	FMSTR_TSA_MEMBER(fxls896x_selftest_t, complete_selftest, FMSTR_TSA_UINT8)
384 
385     FMSTR_TSA_RO_VAR(rawData, FMSTR_TSA_USERTYPE(fxls8962_acceldata_t))
386 
387     FMSTR_TSA_RW_VAR(registers, FMSTR_TSA_USERTYPE(fxls896x_allregs_t))
388 
389     FMSTR_TSA_RO_VAR(offnoise_data, FMSTR_TSA_USERTYPE(fxls896x_offset_noise_t))
390 
391     FMSTR_TSA_RO_VAR(selftest, FMSTR_TSA_USERTYPE(fxls896x_selftest_t))
392 
393 FMSTR_TSA_TABLE_END()
394 
395 FMSTR_TSA_TABLE_LIST_BEGIN()
396     FMSTR_TSA_TABLE(main_table)
397 FMSTR_TSA_TABLE_LIST_END()
398 
399 /*!
400  * @brief FreeMASTER recorder initialization
401  */
402 void FRM_Recorder_Init()
403 {
404     /* Do local configuration of additional recorder */
405 
406     /* Setup the additional recorder raw buffer */
407     recBuffCfg.addr = recBuffer;
408     recBuffCfg.size = sizeof(recBuffer);
409     recBuffCfg.basePeriod_ns = 0;    /* Unknown period */
410     recBuffCfg.name = "FXLS896x 3-Axis Accelerometer Data";
411 
412     FMSTR_RecorderCreate(1, &recBuffCfg);
413 }
414 
415 /*!
416  * @brief Main function
417  */
418 
main(void)419 int main(void)
420 {
421     int32_t status;
422     uint8_t whoami = 0;
423     uint8_t regdata;
424     float sensitivity = ACCEL_4G_SENS;
425 
426     ARM_DRIVER_I2C *I2Cdrv = &I2C_S_DRIVER; // Now using the shield.h value!!!
427     GENERIC_DRIVER_GPIO *pGpioDriver = &Driver_GPIO_KSDK;
428     fxls8962_i2c_sensorhandle_t fxls8962Driver;
429 
430     /*! Initialize the MCU hardware. */
431     BOARD_InitPins();
432     BOARD_BootClockRUN();
433     BOARD_SystickEnable();
434     BOARD_InitDebugConsole();
435 
436     /*! Initialize FXLS8962_INT1 pin used by FRDM board */
437     pGpioDriver->pin_init(&FXLS8962_INT1, GPIO_DIRECTION_IN, NULL, &fxls896x_isr_callback, NULL);
438 
439     /*! Initialize RGB LED pin used by FRDM board */
440     pGpioDriver->pin_init(&GREEN_LED, GPIO_DIRECTION_OUT, NULL, NULL, NULL);
441 
442     /*! FreeMASTER communication layer initialization */
443     init_freemaster_uart();
444 
445     /*! Initialize the I2C driver. */
446     status = I2Cdrv->Initialize(I2C_S_SIGNAL_EVENT);
447     if (ARM_DRIVER_OK != status)
448     {
449         return -1;
450     }
451 
452     /*! Set the I2C Power mode. */
453     status = I2Cdrv->PowerControl(ARM_POWER_FULL);
454     if (ARM_DRIVER_OK != status)
455     {
456         return -1;
457     }
458 
459     /*! Set the I2C bus speed. */
460     status = I2Cdrv->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
461     if (ARM_DRIVER_OK != status)
462     {
463         return -1;
464     }
465 
466     /*! Initialize FXLS8962 sensor driver. */
467     status = FXLS8962_I2C_Initialize(&fxls8962Driver, &I2C_S_DRIVER, I2C_S_DEVICE_INDEX, FXLS8962_I2C_ADDR,
468                                      &whoami);
469     if (SENSOR_ERROR_NONE != status)
470     {
471         return status;
472     }
473 
474     /*!  Set the task to be executed while waiting for I2C transactions to complete. */
475     FXLS8962_I2C_SetIdleTask(&fxls8962Driver, (registeridlefunction_t)SMC_SetPowerModeVlpr, SMC);
476 
477     /*! Configure the FXLS8962 sensor. */
478     status = FXLS8962_I2C_Configure(&fxls8962Driver, cFxls8962ConfigNormal);
479     if (SENSOR_ERROR_NONE != status)
480     {
481         return status;
482     }
483 
484     /*! FreeMASTER Driver Initialization */
485     FMSTR_Init();
486 
487     /*! FreeMASTER Recorder Initialization */
488     FRM_Recorder_Init();
489 
490     /*! Initialize trigger flags */
491     registers.toggle = 1;
492     registers.trigger = 0;
493     registers.read_trigger = 0;
494     registers.read_value = 0;
495     registers.readall_trigger = 0;
496     registers.trigger_accel_offnoise=0;
497     registers.trigger_selftest=0;
498     registers.dataready_cntr = 0;
499     registers.selftest[0]=0;
500     registers.selftest[1]=0;
501     registers.selftest[2]=0;
502 
503     for(int i = 0; i < FXLS896x_NUM_REGISTERS; i++)
504     {
505     	registers.readall_value[i] = 0;
506     }
507 
508     for (;;) /* Forever loop */
509     {
510 
511         /*! Calling Recorder#0 in execution loop for generic high-speed variables sampling. */
512         FMSTR_Recorder(0);
513 
514     	/*! FreeMASTER host communication polling mode */
515 		FMSTR_Poll();
516 
517         /*! Check for any write register trigger from Host */
518 		if (registers.trigger == 1)
519 		{
520 		    /*! Apply Register Write */
521 			status = apply_register_write(fxls8962Driver, registers.offset, registers.value);
522 		    if (SENSOR_ERROR_NONE != status)
523 		    {
524                 return status;
525 		    }
526 		    registers.trigger = 0;
527             /*! Update drop down menu selection based on updated register write */
528 		    update_dropdown_selection(&registers, FXLS896x_REG_WRITE);
529 		}
530 
531         /*! Check for any read register trigger from Host */
532 		if (registers.read_trigger == 1)
533 		{
534 		    /*! Apply Register Write */
535 			status = apply_register_read(fxls8962Driver, registers.read_offset, &(registers.read_value));
536 		    if (SENSOR_ERROR_NONE != status)
537 		    {
538                 return status;
539 		    }
540 		    registers.read_trigger = 0;
541             /*! Update drop down menu selection based on updated register read */
542 		    update_dropdown_selection(&registers, FXLS896x_REG_READ);
543 		}
544 
545         /*! Check for any read all register trigger from Host */
546 		if (registers.readall_trigger == 1)
547 		{
548 		    /*! Apply Register Write */
549 			status = apply_register_readall(fxls8962Driver);
550 		    if (SENSOR_ERROR_NONE != status)
551 		    {
552                 return status;
553 		    }
554 		    registers.readall_trigger = 0;
555 		    registers.readall_size = FXLS896x_NUM_REGISTERS;
556             /*! Update drop down menu selection based on updated all register read */
557 		    update_dropdown_selection(&registers, FXLS896x_ALLREG_READ);
558 		}
559 
560         /*! Wait for data ready interrupt from the FXLS8962. */
561         if (false == bFxls896xIntFlag)
562         { /* Loop, if new sample is not available. */
563             SMC_SetPowerModeWait(SMC);
564             continue;
565         }
566         else
567         { /*! Clear the data ready flag, it will be set again by the ISR. */
568             bFxls896xIntFlag = false;
569             pGpioDriver->toggle_pin(&GREEN_LED);
570         }
571 
572         /*! Calling Recorder#1 for sampling sensor data when we get sensor data ready interrupt based on ODR. */
573         FMSTR_Recorder(1);
574 
575 
576         /*! Read new raw sensor data from the FXLS8962. */
577         status = FXLS8962_I2C_ReadData(&fxls8962Driver, FXLS896x_ALL_REG_READ, registers.reg_addr);
578         if (ARM_DRIVER_OK != status)
579         {
580             return -1;
581         }
582 
583         registers.temp = registers.reg_addr[1]+25;
584         registers.sdcd = (registers.reg_addr[0] & 0x10)>>4;
585 
586         /*! Convert the raw sensor data to signed 16-bit container for display to the debug port. */
587         rawData.accel[0] = (int16_t)(((int16_t)(((int16_t)registers.reg_addr[3] << 8) | registers.reg_addr[2])));
588         rawData.accel[1] = (int16_t)(((int16_t)(((int16_t)registers.reg_addr[5] << 8) | registers.reg_addr[4])));
589         rawData.accel[2] = (int16_t)(((int16_t)(((int16_t)registers.reg_addr[7] << 8) | registers.reg_addr[6])));
590 
591         status = FXLS8962_I2C_ReadData(&fxls8962Driver, cFXLS896x_whoami, (uint8_t *)&registers.reg_addr[13]);
592 
593         /*! Check the FS and apply sensitivity */
594         status = FXLS8962_I2C_ReadData(&fxls8962Driver, cFXLS896x_fs_src, &regdata);
595         if ((regdata & FXLS8962_SENS_CONFIG1_FSR_MASK) == 2)
596         {
597             sensitivity = ACCEL_4G_SENS;
598         }
599         else if ((regdata & FXLS8962_SENS_CONFIG1_FSR_MASK) == 4)
600         {
601             sensitivity = ACCEL_8G_SENS;
602         }
603         else if ((regdata & FXLS8962_SENS_CONFIG1_FSR_MASK) == 6)
604         {
605             sensitivity = ACCEL_16G_SENS;
606         }
607         else
608         {
609             sensitivity = ACCEL_2G_SENS;
610         }
611 
612         /*! Convert raw values to Gs */
613         registers.accel[0] = (float) (rawData.accel[0] * sensitivity);
614         registers.accel[1] = (float) (rawData.accel[1] * sensitivity);
615         registers.accel[2] = (float) (rawData.accel[2] * sensitivity);
616 
617         /*! Increment data ready counter and check for rollover */
618         registers.dataready_cntr++;
619         if(MAX8BITSTORAGE == registers.dataready_cntr)
620         {
621         	registers.dataready_cntr = 0;
622         }
623 
624         if (prev_toggle != registers.toggle)
625         {
626         	pGpioDriver->toggle_pin(&GREEN_LED);
627         	prev_toggle = registers.toggle;
628         }
629 
630         /*! Call offset and noise calculation function for FXLS896x */
631         if (registers.trigger_accel_offnoise == 1)
632         {
633         	accel_off_noise(&(rawData), &(offnoise_data), sensitivity);
634             if (offnoise_data.complete_accel_offnoise == 1)
635             {
636             	registers.trigger_accel_offnoise = 0;
637             }
638         }
639 
640         /*! Call self-test function */
641         if (registers.trigger_selftest == 1)
642         {
643         	perform_selftest(fxls8962Driver, &selftest);
644             if (selftest.complete_selftest == 1)
645             {
646             	registers.trigger_selftest = 0;
647 
648                 /*! Re-Configure the FXLS8962 sensor to default configuration */
649                 status = FXLS8962_I2C_Configure(&fxls8962Driver, cFxls8962ConfigNormal);
650                 if (SENSOR_ERROR_NONE != status)
651                 {
652                     return status;
653                 }
654             }
655         }
656 
657     }
658 }
659 
660 
661 /*!
662  * @brief Service register write trigger from Host
663  */
apply_register_write(fxls8962_i2c_sensorhandle_t fxls8962Driver,uint8_t offset,uint8_t value)664 int32_t apply_register_write(fxls8962_i2c_sensorhandle_t fxls8962Driver, uint8_t offset, uint8_t value)
665 {
666     int32_t status;
667 
668 	if (offset > FXLS896x_NUM_REGISTERS)
669 	{
670 		return SENSOR_ERROR_INVALID_PARAM;
671 	}
672 
673 	registerwritelist_t fxls896x_register_write[] = {
674 	     /*! Set register offset with provided value */
675 	     {offset, value, 0},
676 	      __END_WRITE_DATA__};
677 
678     status = FXLS8962_I2C_Configure(&fxls8962Driver, fxls896x_register_write);
679     if (SENSOR_ERROR_NONE != status)
680     {
681         return SENSOR_ERROR_WRITE;
682     }
683 
684     return SENSOR_ERROR_NONE;
685 }
686 
687 /*!
688  * @brief Service register read trigger from Host
689  */
apply_register_read(fxls8962_i2c_sensorhandle_t fxls8962Driver,uint8_t read_offset,uint8_t * read_value)690 int32_t apply_register_read(fxls8962_i2c_sensorhandle_t fxls8962Driver, uint8_t read_offset, uint8_t *read_value)
691 {
692     int32_t status;
693 
694 	if (read_offset > FXLS896x_NUM_REGISTERS)
695 	{
696 		return SENSOR_ERROR_INVALID_PARAM;
697 	}
698 
699 	registerreadlist_t fxls896x_register_read[] = {
700 		     /*! Set register offset with provided value */
701 	        {.readFrom = read_offset, .numBytes = 1}, __END_READ_DATA__};
702 
703     status = FXLS8962_I2C_ReadData(&fxls8962Driver, fxls896x_register_read, read_value);
704     if (SENSOR_ERROR_NONE != status)
705     {
706         return SENSOR_ERROR_WRITE;
707     }
708 
709     return SENSOR_ERROR_NONE;
710 }
711 
712 /*!
713  * @brief Service register read all trigger from Host
714  */
apply_register_readall(fxls8962_i2c_sensorhandle_t fxls8962Driver)715 int32_t apply_register_readall(fxls8962_i2c_sensorhandle_t fxls8962Driver)
716 {
717     int32_t status;
718 
719 	for (int reg_offset = FXLS8962_INT_STATUS; reg_offset <= FXLS8962_SELF_TEST_CONFIG2; reg_offset++)
720 	{
721 		registerreadlist_t fxls896x_register_readall[] = {
722 				 /*! Set register offset with provided value */
723 				{.readFrom = reg_offset, .numBytes = 1}, __END_READ_DATA__};
724 
725 		status = FXLS8962_I2C_ReadData(&fxls8962Driver, fxls896x_register_readall, &(registers.readall_value[reg_offset]));
726 		if (SENSOR_ERROR_NONE != status)
727 		{
728 			return SENSOR_ERROR_READ;
729 		}
730 	}
731 
732     return SENSOR_ERROR_NONE;
733 }
734 
735 /*!
736  * @brief Update drop down selection values based on register write, read or readall.
737  */
update_dropdown_selection(fxls896x_allregs_t * registers,uint8_t caller)738 int32_t update_dropdown_selection(fxls896x_allregs_t *registers, uint8_t caller)
739 {
740 
741     int32_t status = SENSOR_ERROR_NONE;
742 
743 	switch (caller)
744 	{
745 		case FXLS896x_REG_WRITE:
746 
747             /*! Update drop down option based on updated read value */
748 		    if(FXLS8962_SENS_CONFIG1 == registers->offset) //FS Selection
749 		    {
750 			    registers->fs_value = registers->value;
751 		    }
752 		    else if (FXLS8962_SENS_CONFIG2 == registers->offset)
753 		    {
754 			    registers->mods_value = registers->value;
755 		    }
756 		    else if (FXLS8962_SENS_CONFIG3 == registers->offset)
757 		    {
758 			    registers->odr_value = registers->value;
759 		    }
760 			break;
761 		case FXLS896x_REG_READ: //Called from Register Read
762 
763             /*! Update drop down option based on updated read value */
764 		    if(FXLS8962_SENS_CONFIG1 == registers->read_offset) //FS Selection
765 		    {
766 			    registers->fs_value = registers->read_value;
767 		    }
768 		    else if (FXLS8962_SENS_CONFIG2 == registers->read_offset)
769 		    {
770 			    registers->mods_value = registers->read_value;
771 		    }
772 		    else if (FXLS8962_SENS_CONFIG3 == registers->read_offset)
773 		    {
774 			    registers->odr_value = registers->read_value;
775 		    }
776 			break;
777 		case FXLS896x_ALLREG_READ: //Called from Register ReadAll
778 
779             /*! Update drop down option based on updated read values */
780 			registers->fs_value   = registers->reg_addr[FXLS8962_SENS_CONFIG1];
781 			registers->mods_value = registers->reg_addr[FXLS8962_SENS_CONFIG2];
782 			registers->odr_value = registers->reg_addr[FXLS8962_SENS_CONFIG3];
783 			break;
784         default:
785             status = SENSOR_ERROR_INVALID_PARAM;
786             break;
787 	}
788 
789     return status;
790 
791 }
792 
793 /*******************************************************************************
794  * OFFSET NOISE CALCULATION
795  ******************************************************************************/
796 
797 /*!
798  * @brief Initialize Offset-Noise Variables
799  */
offset_noise_init(fxls896x_offset_noise_t * offnoiseptr)800 void offset_noise_init(fxls896x_offset_noise_t *offnoiseptr)
801 {
802 	offnoiseptr->offx = 0.0;
803 	offnoiseptr->offy = 0.0;
804 	offnoiseptr->offz = 0.0;
805 	offnoiseptr->rmsx = 0.0;
806 	offnoiseptr->rmsy = 0.0;
807 	offnoiseptr->rmsz = 0.0;
808 	offnoiseptr->complete_accel_offnoise = 0;
809 }
810 
811 
812 /* Calculate Offset & Noise for FXLS896x */
accel_off_noise(fxls8962_acceldata_t * rawData,fxls896x_offset_noise_t * offnoiseptr,float sens)813 void accel_off_noise(fxls8962_acceldata_t* rawData, fxls896x_offset_noise_t *offnoiseptr, float sens)
814 {
815 	uint16_t j;
816 	static uint16_t k=0;
817 	static uint16_t cntr=0;
818 	static float stdx=0;
819 	static float stdy=0;
820 	static float stdz=0;
821 	static float xx[N], yy[N], zz[N];
822 	static float xm[N], ym[N], zm[N];
823 	static float xsq[N], ysq[N], zsq[N];
824 	float am[3];
825 	static float sumx=0.0;
826 	static float sumy=0.0;
827 	static float sumz=0.0;
828 
829     /* Init offset noise variables */
830     offset_noise_init(offnoiseptr);
831 
832 	cntr++;
833 
834 	/* Store Accel samples and calculate sum for configured N */
835 	if(cntr < N)
836 	{
837 		 am[0]=rawData->accel[0]*sens;
838 		 am[1]=rawData->accel[1]*sens;
839 		 am[2]=rawData->accel[2]*sens;
840 		 xx[k]=am[0];
841 		 yy[k]=am[1];
842 		 zz[k]=am[2];
843 		 sumx+=am[0];
844 		 sumy+=am[1];
845 		 sumz+=am[2];
846 		 k+=1;
847 		 offnoiseptr->complete_accel_offnoise = 0;
848 	}
849 
850 	/* Measure offset and RMS */
851 	if(cntr == N)
852 	{
853 		/* Measure average */
854 		sumx=sumx/(N-1);
855 		sumy=sumy/(N-1);
856 		sumz=sumz/(N-1);
857 
858 		/* Measure offset */
859 		offnoiseptr->offx=0-sumx;
860 		offnoiseptr->offy=0-sumy;
861 		offnoiseptr->offz=1-sumz;
862 
863 		/* Measure standard deviation */
864 		for(j=0; j<N-1; j++)
865 		{
866 			xm[j]=xx[j]-sumx;
867 			ym[j]=yy[j]-sumy;
868 			zm[j]=zz[j]-sumz;
869 
870 			xsq[j]=pow(xm[j],2);
871 			ysq[j]=pow(ym[j],2);
872 			zsq[j]=pow(zm[j],2);
873 			stdx+=xsq[j];
874 			stdy+=ysq[j];
875 			stdz+=zsq[j];
876 		}
877 		stdx=stdx/(N-2);
878 		stdy=stdy/(N-2);
879 		stdz=stdz/(N-2);
880 
881         /* Measure RMS */
882 		offnoiseptr->rmsx=pow(stdx,0.5);
883 		offnoiseptr->rmsy=pow(stdy,0.5);
884 		offnoiseptr->rmsz=pow(stdz,0.5);
885 
886 		/* Set the completion flag */
887 		offnoiseptr->complete_accel_offnoise = 1;
888 
889 		/* Reset local storage */
890 		cntr = k = 0;
891 		sumx = sumy = sumz = 0;
892 		stdx = stdy = stdz = 0;
893 	}
894 }
895 
896 /*!
897  * @brief Initialize Offset-Noise Variables
898  */
selftest_init(fxls896x_selftest_t * selftest)899 void selftest_init(fxls896x_selftest_t *selftest)
900 {
901 	selftest->x_stoc = 0;
902 	selftest->y_stoc = 0;
903 	selftest->z_stoc = 0;
904 	selftest->x_stof = 0;
905 	selftest->y_stof = 0;
906 	selftest->z_stof = 0;
907 	selftest->complete_selftest = 0;
908 }
909 
910 
perform_selftest(fxls8962_i2c_sensorhandle_t fxls8962Driver,fxls896x_selftest_t * selftest)911 int32_t perform_selftest(fxls8962_i2c_sensorhandle_t fxls8962Driver, fxls896x_selftest_t *selftest)
912 {
913 	int32_t status;
914 
915 	axis=0;
916 
917     /* Initialize self-test parameters */
918 	selftest_init(selftest);
919 
920 	while (axis<6)
921 	{
922 
923 		switch(axis)
924 		{
925 			case 0:status = FXLS8962_I2C_Configure(&fxls8962Driver, cFxls8962STXP);break;
926 			case 1:status = FXLS8962_I2C_Configure(&fxls8962Driver, cFxls8962STXN);break;
927 			case 2:status = FXLS8962_I2C_Configure(&fxls8962Driver, cFxls8962STYP);break;
928 			case 3:status = FXLS8962_I2C_Configure(&fxls8962Driver, cFxls8962STYN);break;
929 			case 4:status = FXLS8962_I2C_Configure(&fxls8962Driver, cFxls8962STZP);break;
930 			case 5:status = FXLS8962_I2C_Configure(&fxls8962Driver, cFxls8962STZN);break;
931 			default:break;
932 		}
933 
934 		if (ARM_DRIVER_OK != status)
935 		{
936 			return status;
937 		}
938 
939 		int counter =0;
940 		for(counter=0;counter<1;counter++)
941 		{
942 
943 			// In ISR Mode we do not need to check Data Ready Register.
944 			// The receipt of interrupt will indicate data is ready.
945 			RAW_DATA data_ = {0x00};
946 			while(false == bFxls896xIntFlag)
947 			{
948 
949 			}
950 
951 			/*! Set device to Standby mode. */
952 			Register_I2C_Write(&I2C_S_DRIVER,&(fxls8962Driver.deviceInfo),FXLS8962_I2C_ADDR, FXLS8962_SENS_CONFIG1,0x00,0x00,0x00);
953 			if (ARM_DRIVER_OK != status)
954 			{
955 				return SENSOR_ERROR_WRITE;
956 			}
957 
958 
959 			bFxls896xIntFlag = false;
960 			//pGpioDriver->toggle_pin(&RED_LED);
961 
962 			/*! Read new raw sensor data from the FXLS8962. */
963 			status = FXLS8962_I2C_ReadData(&fxls8962Driver, cFxls8962OutputNormal, &data_.byte_data[0]);
964 			if (ARM_DRIVER_OK != status)
965 			{ /* Read did not work, so loop. */
966 				continue;
967 			}
968 
969 			/* store the self-test values for each axis & for each polarity*/
970 			switch(axis)
971 			{
972 			case 0: XSTP[counter]= data_.dat.xdata;break;
973 			case 1: XSTN[counter]= data_.dat.xdata;break;
974 			case 2: YSTP[counter]= data_.dat.ydata;break;
975 			case 3: YSTN[counter]= data_.dat.ydata;break;
976 			case 4: ZSTP[counter]= data_.dat.zdata;break;
977 			case 5: ZSTN[counter]= data_.dat.zdata;break;
978 			default:break;
979 			}
980 
981 		}
982 
983 		BOARD_DELAY_ms(1000);
984 		axis++;
985 	}
986 
987 		/* compute self-test output change*/
988 	    selftest->x_stoc=(XSTP[0]-XSTN[0])/2;
989 	    selftest->y_stoc=(YSTP[0]-YSTN[0])/2;
990 	    selftest->z_stoc=(ZSTP[0]-ZSTN[0])/2;
991 
992 		/* compute self-test offset*/
993 	    selftest->x_stof=(XSTP[0]+XSTN[0])/2;
994 	    selftest->y_stof=(YSTP[0]+YSTN[0])/2;
995 	    selftest->z_stof=(ZSTP[0]+ZSTN[0])/2;
996 
997 	    selftest->complete_selftest = 1;
998 	    return SENSOR_ERROR_NONE;
999 }
1000 
1001 /*!
1002  * @brief UART Module initialization (UART is a the standard block included e.g. in K22F)
1003  */
init_freemaster_uart(void)1004 static void init_freemaster_uart(void)
1005 {
1006     uart_config_t config;
1007 
1008     /*
1009      * config.baudRate_Bps = 115200U;
1010      * config.parityMode = kUART_ParityDisabled;
1011      * config.stopBitCount = kUART_OneStopBit;
1012      * config.txFifoWatermark = 0;
1013      * config.rxFifoWatermark = 1;
1014      * config.enableTx = false;
1015      * config.enableRx = false;
1016      */
1017     UART_GetDefaultConfig(&config);
1018     config.baudRate_Bps = 115200U;
1019     config.enableTx = false;
1020     config.enableRx = false;
1021 
1022     UART_Init((UART_Type*)BOARD_DEBUG_UART_BASEADDR, &config, BOARD_DEBUG_UART_CLK_FREQ);
1023 
1024     /* Register communication module used by FreeMASTER driver. */
1025     FMSTR_SerialSetBaseAddress((UART_Type*)BOARD_DEBUG_UART_BASEADDR);
1026 
1027 #if FMSTR_SHORT_INTR || FMSTR_LONG_INTR
1028     /* Enable UART interrupts. */
1029     EnableIRQ(BOARD_UART_IRQ);
1030     EnableGlobalIRQ(0);
1031 #endif
1032 }
1033 
1034 #if FMSTR_SHORT_INTR || FMSTR_LONG_INTR
1035 /*
1036 *   Application interrupt handler of communication peripheral used in interrupt modes
1037 *   of FreeMASTER communication.
1038 *
1039 *   NXP MCUXpresso SDK framework defines interrupt vector table as a part of "startup_XXXXXX.x"
1040 *   assembler/C file. The table points to weakly defined symbols, which may be overwritten by the
1041 *   application specific implementation. FreeMASTER overrides the original weak definition and
1042 *   redirects the call to its own handler.
1043 *
1044 */
1045 
BOARD_UART_IRQ_HANDLER(void)1046 void BOARD_UART_IRQ_HANDLER(void)
1047 {
1048     /* Call FreeMASTER Interrupt routine handler */
1049     FMSTR_SerialIsr();
1050     /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
1051         exception return operation might vector to incorrect interrupt */
1052 #if defined __CORTEX_M && (__CORTEX_M == 4U)
1053     __DSB();
1054 #endif
1055 }
1056 #endif
1057 
1058