1 /*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2017 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 /**
10 * @file fxlc95000_accel_i2c.c
11 * @brief The fxlc95000_accel_i2c.c file implements the ISSDK FXLC95000 sensor driver
12 * example demonstration as for I2C Mode.
13 */
14
15 /* SDK Includes */
16 #include "pin_mux.h"
17 #include "clock_config.h"
18 #include "board.h"
19 #include "fsl_lptmr.h"
20 #include "fsl_debug_console.h"
21
22 /* CMSIS Includes */
23 #include "Driver_I2C.h"
24
25 /* ISSDK Includes */
26 #include "issdk_hal.h"
27 #include "fxlc95000_drv.h"
28 #include "systick_utils.h"
29
30 /*******************************************************************************
31 * Macros
32 ******************************************************************************/
33 #define SAMPLING_RATE_us (100000) /* Timeout for the ODR Timer. */
34 #define FXLC95000_SAMPLE_SIZE (10) /* 4-Byte timestamp and 2-Byte X,Y,Z Data each. */
35 #define fxlc95000_odr_callback LPTMR0_IRQHandler /* Timer timeout Callback. */
36
37 /*******************************************************************************
38 * Constants
39 ******************************************************************************/
40 /*! Create commands for setting FXLC95000L desired configuration. */
41 const uint8_t cFxlc95000_SetODR_Cmd[] = {FXLC95000_SET_ODR_CMD_HDR, /* ODR equal to Sampling Rate. */
42 FXLC95000_SST_ODR_PAYLOAD(SAMPLING_RATE_us)};
43 const uint8_t cFxlc95000_SetResolution_Cmd[] = {FXLC95000_SET_RESOLUTION_CMD_HDR, /* Resolution 14-bits. */
44 FXLC95000_ACCEL_RESOLUTION_14_BIT};
45 const uint8_t cFxlc95000_SetRange_Cmd[] = {FXLC95000_SET_RANGE_CMD_HDR, /* FS Range 2G. */
46 FXLC95000_ACCEL_RANGE_2G};
47
48 /*! Prepare the register write list to initialize FXLC95000L with desired MBox Settings. */
49 const registercommandlist_t cFxlc95000ConfigMBox[] = {
50 {QuickReadInterruptDisable, 0, sizeof(QuickReadInterruptDisable)}, /* Disable QR INT. */
51 {ConfigureMBoxCmd, 0, sizeof(ConfigureMBoxCmd)}, /* Configure MBox 16 to 25 with 10 byte Sample. */
52 __END_WRITE_CMD__ /* Ref. Table 3-7 of ISF1P195K_SW_REFERENCE_RM. */
53 };
54
55 /*! Prepare the register write list to configure FXLC95000L with desired Sampling Settings. */
56 const registercommandlist_t cFxlc95000ConfigSensor[] = {
57 {StopDataCmd, 0, sizeof(StopDataCmd)}, /* Stop Data before (re)configuration. */
58 {cFxlc95000_SetODR_Cmd, 0, sizeof(cFxlc95000_SetODR_Cmd)}, /* Set Sensor Sampling Rate. */
59 {cFxlc95000_SetRange_Cmd, 0, sizeof(cFxlc95000_SetRange_Cmd)}, /* Set FS Range. */
60 {cFxlc95000_SetResolution_Cmd, 0, sizeof(cFxlc95000_SetResolution_Cmd)}, /* Set Resolution */
61 {StartDataCmd, 0, sizeof(StartDataCmd)}, /* Start Data after (re)configuration. */
62 __END_WRITE_CMD__};
63
64 /*! Prepare the register read list to read the Timestamp and Accel data from FXLC95000. */
65 const registerreadlist_t cFxlc95000ReadSample[] = {
66 {.readFrom = FXLC95000_SAMPLE_OFFSET, .numBytes = FXLC95000_SAMPLE_SIZE}, __END_READ_DATA__};
67
68 /*******************************************************************************
69 * Globals
70 ******************************************************************************/
71 volatile bool gFxlc95000DataRead;
72
73 /*******************************************************************************
74 * Code
75 ******************************************************************************/
76 /* LPTMR based ODR Callback function. */
fxlc95000_odr_callback(void)77 void fxlc95000_odr_callback(void)
78 {
79 LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag);
80 gFxlc95000DataRead = true;
81 }
82
83 /*!
84 * @brief Main function
85 */
main(void)86 int main(void)
87 {
88 int32_t status;
89 lptmr_config_t lptmrConfig;
90 fxlc95000_acceldata_t rawData;
91 uint8_t data[FXLC95000_SAMPLE_SIZE];
92
93 ARM_DRIVER_I2C *I2Cdrv = &I2C_S_DRIVER; // Now using the shield.h value!!!
94 fxlc95000_i2c_sensorhandle_t fxlc95000Driver;
95
96 /*! Initialize the MCU hardware */
97 BOARD_InitPins();
98 BOARD_BootClockRUN();
99 BOARD_SystickEnable();
100 BOARD_InitDebugConsole();
101
102 /* Initialize ODR Timer. */
103 LPTMR_GetDefaultConfig(&lptmrConfig);
104 LPTMR_Init(LPTMR0, &lptmrConfig);
105 LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);
106 LPTMR_SetTimerPeriod(LPTMR0, USEC_TO_COUNT(SAMPLING_RATE_us, CLOCK_GetFreq(kCLOCK_LpoClk)));
107 EnableIRQ(LPTMR0_IRQn);
108
109 PRINTF("\r\n ISSDK FXLC95000 sensor driver example for Normal Mode. \r\n");
110
111 /*! Initialize the I2C driver. */
112 status = I2Cdrv->Initialize(I2C_S_SIGNAL_EVENT);
113 if (ARM_DRIVER_OK != status)
114 {
115 PRINTF("\r\n I2C Initialization Failed\r\n");
116 return -1;
117 }
118
119 /*! Set the I2C Power mode. */
120 status = I2Cdrv->PowerControl(ARM_POWER_FULL);
121 if (ARM_DRIVER_OK != status)
122 {
123 PRINTF("\r\n I2C Power Mode setting Failed\r\n");
124 return -1;
125 }
126
127 /*! Set the I2C bus speed. */
128 status = I2Cdrv->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
129 if (ARM_DRIVER_OK != status)
130 {
131 PRINTF("\r\n I2C Control Mode setting Failed\r\n");
132 return -1;
133 }
134
135 /*! Initialize the FXLC95000 sensor driver. */
136 status = FXLC95000_I2C_Initialize(&fxlc95000Driver, &I2C_S_DRIVER, I2C_S_DEVICE_INDEX, FXLC95000_I2C_ADDR,
137 FXLC95000_BUILD_ID);
138 if (SENSOR_ERROR_NONE != status)
139 {
140 PRINTF("\r\n Sensor Initialization Failed\r\n");
141 return -1;
142 }
143 PRINTF("\r\n Successfully Initiliazed Sensor\r\n");
144
145 /*! Set the task to be executed while waiting for I2C transactions to complete. */
146 FXLC95000_I2C_SetIdleTask(&fxlc95000Driver, (registeridlefunction_t)SMC_SetPowerModeVlpr, SMC);
147
148 gFxlc95000DataRead = false; /* Do not read data, data will be read after ODR Timer expires. */
149
150 /*! Configure the FXLC95000 with MBox settings. */
151 status = FXLC95000_I2C_CommandResponse(&fxlc95000Driver, cFxlc95000ConfigMBox, NULL, NULL);
152 if (SENSOR_ERROR_NONE != status)
153 {
154 PRINTF("\r\n FXLC95000 MBox Configuration Failed, Err = %d \r\n", status);
155 return -1;
156 }
157 /*! Configure the FXLC95000 with Sampling settings. */
158 status = FXLC95000_I2C_CommandResponse(&fxlc95000Driver, cFxlc95000ConfigSensor, NULL, NULL);
159 if (SENSOR_ERROR_NONE != status)
160 {
161 PRINTF("\r\n FXLC95000 Sensor Configuration Failed, Err = %d \r\n", status);
162 return -1;
163 }
164 PRINTF("\r\n Successfully Applied FXLC95000 Sensor Configuration\r\n");
165
166 LPTMR_StartTimer(LPTMR0);
167 for (;;) /* Forever loop */
168 {
169 if (gFxlc95000DataRead == false)
170 {
171 __NOP();
172 continue;
173 }
174 else
175 {
176 gFxlc95000DataRead = false;
177 }
178
179 /*! Read the raw sensor data from the FXLC95000. */
180 status = FXLC95000_I2C_CommandResponse(&fxlc95000Driver, NULL, cFxlc95000ReadSample, data);
181 if (ARM_DRIVER_OK != status)
182 {
183 PRINTF("\r\n Read Failed. \r\n");
184 return -1;
185 }
186
187 /*! Convert the raw bytes to sensor data with correct endianness. */
188 rawData.timestamp = ((uint32_t)data[3] << 24) | ((uint32_t)data[2] << 16) | ((uint16_t)data[1] << 8) | data[0];
189 rawData.accel[0] = ((int16_t)data[5] << 8) | data[4];
190 rawData.accel[1] = ((int16_t)data[7] << 8) | data[6];
191 rawData.accel[2] = ((int16_t)data[9] << 8) | data[8];
192
193 PRINTF("\r\n Timestamp = 0x%X \r\n Accel X = %d Y = %d Z = %d \r\n", rawData.timestamp, rawData.accel[0],
194 rawData.accel[1], rawData.accel[2]);
195 ASK_USER_TO_RESUME(100); /* Ask for user input after processing 100 samples. */
196 }
197 }
198