1 /*
2 * Copyright 2021 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 /**
9 * @file fxls896xaf_spi.c
10 * @brief The fxls896xaf_spi.c file implements the ISSDK FXLS896xAF SPI sensor driver
11 * example demonstration for SPI Mode with polling.
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
22 //-----------------------------------------------------------------------
23 // ISSDK Includes
24 //-----------------------------------------------------------------------
25 #include "issdk_hal.h"
26 #include "gpio_driver.h"
27 #include "fxls896x_drv.h"
28 #include "systick_utils.h"
29
30 //-----------------------------------------------------------------------
31 // CMSIS Includes
32 //-----------------------------------------------------------------------
33 #include "Driver_SPI.h"
34
35 //-----------------------------------------------------------------------
36 // Macros
37 //-----------------------------------------------------------------------
38 #define FXLS896x_DATA_SIZE (6)
39
40 //-----------------------------------------------------------------------
41 // Constants
42 //-----------------------------------------------------------------------
43 /*! @brief Register settings for Normal (non buffered) mode. */
44 const registerwritelist_t cFxls896xConfigNormal[] = {
45 /* Set Full-scale range as 2G. */
46 {FXLS896x_SENS_CONFIG1, FXLS896x_SENS_CONFIG1_FSR_2G, FXLS896x_SENS_CONFIG1_FSR_MASK},
47 /* Set Wake Mode ODR Rate as 6.25Hz. */
48 {FXLS896x_SENS_CONFIG3, FXLS896x_SENS_CONFIG3_WAKE_ODR_6_25HZ, FXLS896x_SENS_CONFIG3_WAKE_ODR_MASK},
49 __END_WRITE_DATA__};
50
51 /*! @brief Address of DATA Ready Status Register. */
52 const registerreadlist_t cFxls896xDRDYEvent[] = {{.readFrom = FXLS896x_INT_STATUS, .numBytes = 1}, __END_READ_DATA__};
53
54 /*! @brief Address of Raw Accel Data in Normal Mode. */
55 const registerreadlist_t cFxls896xOutputNormal[] = {{.readFrom = FXLS896x_OUT_X_LSB, .numBytes = FXLS896x_DATA_SIZE},
56 __END_READ_DATA__};
57
58 //-----------------------------------------------------------------------
59 // Functions
60 //-----------------------------------------------------------------------
61 /*! -----------------------------------------------------------------------
62 * @brief This is the The main function implementation.
63 * @details This function invokes board initializes routines, then then brings up the sensor and
64 * finally enters an endless loop to continuously read available samples.
65 * @param[in] void This is no input parameter.
66 * @return void There is no return value.
67 * @constraints None
68 * @reeentrant No
69 * -----------------------------------------------------------------------*/
main(void)70 int main(void)
71 {
72 int32_t status;
73 uint8_t whoami;
74 uint8_t gFxls896xDataReady;
75 uint8_t data[FXLS896x_DATA_SIZE];
76 fxls896x_acceldata_t rawData;
77
78 ARM_DRIVER_SPI *pSPIdriver = &SPI_S_DRIVER;
79 fxls896x_spi_sensorhandle_t fxls896xDriver;
80
81 /*! Initialize the MCU hardware. */
82 BOARD_InitPins();
83 BOARD_BootClockRUN();
84 BOARD_SystickEnable();
85 BOARD_InitDebugConsole();
86
87 PRINTF("\r\n ISSDK FXLS896x sensor driver example demonstration for SPI with Poll Mode.\r\n");
88
89 /*! Initialize the SPI driver. */
90 status = pSPIdriver->Initialize(SPI_S_SIGNAL_EVENT);
91 if (ARM_DRIVER_OK != status)
92 {
93 PRINTF("\r\n SPI Initialization Failed\r\n");
94 return -1;
95 }
96
97 /*! Set the SPI Power mode. */
98 status = pSPIdriver->PowerControl(ARM_POWER_FULL);
99 if (ARM_DRIVER_OK != status)
100 {
101 PRINTF("\r\n SPI Power Mode setting Failed\r\n");
102 return -1;
103 }
104
105 /*! Set the SPI Slave speed. */
106 status = pSPIdriver->Control(ARM_SPI_MODE_MASTER | ARM_SPI_CPOL0_CPHA0, SPI_S_BAUDRATE);
107 if (ARM_DRIVER_OK != status)
108 {
109 PRINTF("\r\n SPI Control Mode setting Failed\r\n");
110 return -1;
111 }
112
113 /*! Initialize the fxls896x sensor driver. */
114 status = FXLS896x_SPI_Initialize(&fxls896xDriver, &SPI_S_DRIVER, SPI_S_DEVICE_INDEX, &FXLS896x_CS,
115 &whoami);
116 if (SENSOR_ERROR_NONE != status)
117 {
118 PRINTF("\r\n FXLS896x Sensor Initialization Failed\r\n");
119 return -1;
120 }
121 if ((FXLS8964_WHOAMI_VALUE == whoami) || (FXLS8967_WHOAMI_VALUE == whoami))
122 {
123 PRINTF("\r\n Successfully Initialized Gemini with WHO_AM_I = 0x%X\r\n", whoami);
124 }
125 else if ((FXLS8974_WHOAMI_VALUE == whoami) || (FXLS8968_WHOAMI_VALUE == whoami))
126 {
127 PRINTF("\r\n Successfully Initialized Timandra with WHO_AM_I = 0x%X\r\n", whoami);
128 }
129 else if (FXLS8962_WHOAMI_VALUE == whoami)
130 {
131 PRINTF("\r\n Successfully Initialized Newstein with WHO_AM_I = 0x%X\r\n", whoami);
132 }
133 else
134 {
135 PRINTF("\r\n Bad WHO_AM_I = 0x%X\r\n", whoami);
136 }
137
138 /*! Set the task to be executed while waiting for SPI transactions to complete. */
139 FXLS896x_SPI_SetIdleTask(&fxls896xDriver, (registeridlefunction_t)SMC_SetPowerModeVlpr, SMC);
140
141 /*! Configure the FXLS896x sensor driver. */
142 status = FXLS896x_SPI_Configure(&fxls896xDriver, cFxls896xConfigNormal);
143 if (SENSOR_ERROR_NONE != status)
144 {
145 PRINTF("\r\n FXLS896x Sensor Configuration Failed, Err = %d\r\n", status);
146 return -1;
147 }
148 PRINTF("\r\n Successfully Applied FXLS896x Sensor Configuration\r\n");
149
150 for (;;) /* Forever loop */
151 {
152 /*! Wait for data ready from the FXLS896x. */
153 status = FXLS896x_SPI_ReadData(&fxls896xDriver, cFxls896xDRDYEvent, &gFxls896xDataReady);
154 if (0 == (gFxls896xDataReady & FXLS896x_INT_STATUS_SRC_DRDY_MASK))
155 { /* Loop, if new sample is not available. */
156 continue;
157 }
158
159 /*! Read the raw sensor data from the FXLS896x. */
160 status = FXLS896x_SPI_ReadData(&fxls896xDriver, cFxls896xOutputNormal, data);
161 if (ARM_DRIVER_OK != status)
162 {
163 PRINTF("\r\nRead Failed.\r\n");
164 return -1;
165 }
166
167 /*! Convert the raw sensor data for display to the debug port. */
168 rawData.accel[0] = ((int16_t)data[1] << 8) | data[0];
169 rawData.accel[1] = ((int16_t)data[3] << 8) | data[2];
170 rawData.accel[2] = ((int16_t)data[5] << 8) | data[4];
171
172 /* NOTE: PRINTF is relatively expensive in terms of CPU time, specially when used with-in execution loop. */
173 PRINTF("\r\n X=%5d Y=%5d Z=%5d\r\n", rawData.accel[0], rawData.accel[1], rawData.accel[2]);
174 }
175 }
176