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