1 /*
2  * Copyright 2023 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 /**
9  * @file  fxls8961af_spi.c
10  *  @brief The fxls8961af_spi.c file implements the ISSDK FXLS8961AF 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 "fxls8961_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 FXLS8961_DATA_SIZE (6)
39 
40 //-----------------------------------------------------------------------
41 // Constants
42 //-----------------------------------------------------------------------
43 /*! @brief Register settings for Normal (non buffered) mode. */
44 const registerwritelist_t cFxls8961ConfigNormal[] = {
45     /* Set Full-scale range as 2G. */
46     {FXLS8961_SENS_CONFIG1, FXLS8961_SENS_CONFIG1_FSR_2G, FXLS8961_SENS_CONFIG1_FSR_MASK},
47     /* Set Wake Mode ODR Rate as 6.25Hz. */
48     {FXLS8961_SENS_CONFIG3, FXLS8961_SENS_CONFIG3_WAKE_ODR_6_25HZ, FXLS8961_SENS_CONFIG3_WAKE_ODR_MASK},
49     __END_WRITE_DATA__};
50 
51 /*! @brief Address of DATA Ready Status Register. */
52 const registerreadlist_t cFxls8961DRDYEvent[] = {{.readFrom = FXLS8961_INT_STATUS, .numBytes = 1}, __END_READ_DATA__};
53 
54 /*! @brief Address of Raw Accel Data in Normal Mode. */
55 const registerreadlist_t cFxls8961OutputNormal[] = {{.readFrom = FXLS8961_OUT_X_LSB, .numBytes = FXLS8961_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 gFxls8961DataReady;
75     uint8_t data[FXLS8961_DATA_SIZE];
76     fxls8961_acceldata_t rawData;
77 
78     ARM_DRIVER_SPI *pSPIdriver = &SPI_S_DRIVER;
79     fxls8961_spi_sensorhandle_t fxls8961Driver;
80 
81     /*! Initialize the MCU hardware. */
82     BOARD_InitPins();
83     BOARD_BootClockRUN();
84     BOARD_SystickEnable();
85     BOARD_InitDebugConsole();
86 
87     PRINTF("\r\n ISSDK FXLS8961 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 fxls8961 sensor driver. */
114     status = FXLS8961_SPI_Initialize(&fxls8961Driver, &SPI_S_DRIVER, SPI_S_DEVICE_INDEX, &FXLS8961_CS,
115     		&whoami);
116     if (SENSOR_ERROR_NONE != status)
117     {
118         PRINTF("\r\n FXLS8961 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 ((FXLS8971_WHOAMI_VALUE == whoami) || (FXLS8961_WHOAMI_VALUE == whoami))
130     {
131     	PRINTF("\r\n Successfully Initialized Chiron with WHO_AM_I = 0x%X\r\n", whoami);
132     }
133     else if (FXLS8962_WHOAMI_VALUE == whoami)
134     {
135     	PRINTF("\r\n Successfully Initialized Newstein with WHO_AM_I = 0x%X\r\n", whoami);
136     }
137     else
138     {
139     	PRINTF("\r\n Bad WHO_AM_I = 0x%X\r\n", whoami);
140     }
141 
142     /*!  Set the task to be executed while waiting for SPI transactions to complete. */
143     FXLS8961_SPI_SetIdleTask(&fxls8961Driver, (registeridlefunction_t)SMC_SetPowerModeVlpr, SMC);
144 
145     /*! Configure the FXLS8961 sensor driver. */
146     status = FXLS8961_SPI_Configure(&fxls8961Driver, cFxls8961ConfigNormal);
147     if (SENSOR_ERROR_NONE != status)
148     {
149         PRINTF("\r\n FXLS8961 Sensor Configuration Failed, Err = %d\r\n", status);
150         return -1;
151     }
152     PRINTF("\r\n Successfully Applied FXLS8961 Sensor Configuration\r\n");
153 
154     for (;;) /* Forever loop */
155     {
156         /*! Wait for data ready from the FXLS8961. */
157         status = FXLS8961_SPI_ReadData(&fxls8961Driver, cFxls8961DRDYEvent, &gFxls8961DataReady);
158         if (0 == (gFxls8961DataReady & FXLS8961_INT_STATUS_SRC_DRDY_MASK))
159         { /* Loop, if new sample is not available. */
160             continue;
161         }
162 
163         /*! Read the raw sensor data from the FXLS8961. */
164         status = FXLS8961_SPI_ReadData(&fxls8961Driver, cFxls8961OutputNormal, data);
165         if (ARM_DRIVER_OK != status)
166         {
167             PRINTF("\r\nRead Failed.\r\n");
168             return -1;
169         }
170 
171         /*! Convert the raw sensor data for display to the debug port. */
172         rawData.accel[0] = ((int16_t)data[1] << 8) | data[0];
173         rawData.accel[1] = ((int16_t)data[3] << 8) | data[2];
174         rawData.accel[2] = ((int16_t)data[5] << 8) | data[4];
175 
176         /* NOTE: PRINTF is relatively expensive in terms of CPU time, specially when used with-in execution loop. */
177         PRINTF("\r\n X=%5d Y=%5d Z=%5d\r\n", rawData.accel[0], rawData.accel[1], rawData.accel[2]);
178     }
179 }
180