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