1 /*
2 * Copyright (c) 2015-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 fxls8962_fifo_spi.c
11 * @brief The fxls8962_fifo_spi.c file implements the ISSDK FXLS8962 SPI sensor driver
12 * example demonstration for FIFO Mode.
13 */
14
15 //-----------------------------------------------------------------------
16 // SDK Includes
17 //-----------------------------------------------------------------------
18 #include "pin_mux.h"
19 #include "clock_config.h"
20 #include "board.h"
21 #include "fsl_debug_console.h"
22
23 //-----------------------------------------------------------------------
24 // ISSDK Includes
25 //-----------------------------------------------------------------------
26 #include "issdk_hal.h"
27 #include "gpio_driver.h"
28 #include "fxls8962_drv.h"
29 #include "systick_utils.h"
30
31 //-----------------------------------------------------------------------
32 // CMSIS Includes
33 //-----------------------------------------------------------------------
34 #include "Driver_SPI.h"
35
36 //-----------------------------------------------------------------------
37 // Macros
38 //-----------------------------------------------------------------------
39 #define FXLS8962_DATA_SIZE (6)
40 #define FXLS8962_FIFO_WMRK_SIZE (16)
41
42 /*******************************************************************************
43 * Constants
44 ******************************************************************************/
45 /*! @brief Register settings for FIFO (buffered) mode. */
46 const registerwritelist_t cFxls8962ConfigFIFO[] = {
47 /* Set Full-scale range as 2G. */
48 {FXLS8962_SENS_CONFIG1, FXLS8962_SENS_CONFIG1_FSR_2G, FXLS8962_SENS_CONFIG1_FSR_MASK},
49 /* Set Wake Mode ODR Rate as 12.5Hz. */
50 {FXLS8962_SENS_CONFIG3, FXLS8962_SENS_CONFIG3_WAKE_ODR_12_5HZ, FXLS8962_SENS_CONFIG3_WAKE_ODR_MASK},
51 /* Set Buffering Mode as Stop-when-Full. */
52 {FXLS8962_BUF_CONFIG1, FXLS8962_BUF_CONFIG1_BUF_MODE_STOP_MODE, FXLS8962_BUF_CONFIG1_BUF_MODE_MASK},
53 /* Set FIFO Water Mark. */
54 {FXLS8962_BUF_CONFIG2, FXLS8962_FIFO_WMRK_SIZE, FXLS8962_BUF_CONFIG2_BUF_WMRK_MASK},
55 /* Enable Interrupts for FIFO Watermark Events. */
56 {FXLS8962_INT_EN, FXLS8962_INT_EN_BUF_EN_EN, FXLS8962_INT_EN_BUF_EN_MASK},
57 __END_WRITE_DATA__};
58
59 /*! @brief Address of Raw Accel Data in FIFO Mode. */
60 const registerreadlist_t cFxls8962OutputFIF0[] = {
61 {.readFrom = FXLS8962_BUF_X_LSB, .numBytes = FXLS8962_DATA_SIZE * FXLS8962_FIFO_WMRK_SIZE}, __END_READ_DATA__};
62
63 /*******************************************************************************
64 * Global Variables
65 ******************************************************************************/
66 volatile bool gFxls8962DataReady = false;
67
68 /*******************************************************************************
69 * Code
70 ******************************************************************************/
71 /*!
72 * @brief The Data ready ISR callback function
73 */
fxls8962_int_data_ready_callback(void * pUserData)74 void fxls8962_int_data_ready_callback(void *pUserData)
75 { /*! @brief Set flag to indicate Sensor has signalled data ready. */
76 gFxls8962DataReady = true;
77 }
78
79 /*!
80 * @brief Main function
81 */
main(void)82 int main(void)
83 {
84 int32_t status;
85 uint8_t i, data[FXLS8962_DATA_SIZE * FXLS8962_FIFO_WMRK_SIZE];
86 fxls8962_acceldata_t rawData;
87
88 GENERIC_DRIVER_GPIO *pGpioDriver = &Driver_GPIO_KSDK;
89 ARM_DRIVER_SPI *pSPIdriver = &SPI_S_DRIVER;
90 fxls8962_spi_sensorhandle_t fxls8962Driver;
91
92 /*! Initialize the MCU hardware. */
93 BOARD_InitPins();
94 BOARD_BootClockRUN();
95 BOARD_SystickEnable();
96 BOARD_InitDebugConsole();
97
98 PRINTF("\r\n ISSDK FXLS8962 sensor driver example demonstration for SPI with FIFO Mode.\r\n");
99
100 /*! Initialize FXLS8962 pin used by FRDM board */
101 pGpioDriver->pin_init(&FXLS8962_INT1, GPIO_DIRECTION_IN, NULL, &fxls8962_int_data_ready_callback, NULL);
102
103 /*! Initialize RGB LED pin used by FRDM board */
104 pGpioDriver->pin_init(&GREEN_LED, GPIO_DIRECTION_OUT, NULL, NULL, NULL);
105
106 /*! Initialize the SPI driver. */
107 status = pSPIdriver->Initialize(SPI_S_SIGNAL_EVENT);
108 if (ARM_DRIVER_OK != status)
109 {
110 PRINTF("\r\n SPI Initialization Failed\r\n");
111 return -1;
112 }
113
114 /*! Set the SPI Power mode. */
115 status = pSPIdriver->PowerControl(ARM_POWER_FULL);
116 if (ARM_DRIVER_OK != status)
117 {
118 PRINTF("\r\n SPI Power Mode setting Failed\r\n");
119 return -1;
120 }
121
122 /*! Set the SPI Slave speed. */
123 status = pSPIdriver->Control(ARM_SPI_MODE_MASTER | ARM_SPI_CPOL0_CPHA0, SPI_S_BAUDRATE);
124 if (ARM_DRIVER_OK != status)
125 {
126 PRINTF("\r\n SPI Control Mode setting Failed\r\n");
127 return -1;
128 }
129
130 /*! Initialize FXLS8962 sensor driver. */
131 status = FXLS8962_SPI_Initialize(&fxls8962Driver, &SPI_S_DRIVER, SPI_S_DEVICE_INDEX, &FXLS8962_CS,
132 FXLS8962_WHOAMI_VALUE);
133 if (SENSOR_ERROR_NONE != status)
134 {
135 PRINTF("\r\n FXLS8962 Sensor Initialization Failed\r\n");
136 return -1;
137 }
138 PRINTF("\r\n Successfully Initiliazed FXLS8962 Sensor\r\n");
139
140 /*! Set the task to be executed while waiting for SPI transactions to complete. */
141 FXLS8962_SPI_SetIdleTask(&fxls8962Driver, (registeridlefunction_t)SMC_SetPowerModeVlpr, SMC);
142
143 /*! Configure the FXLS8962 sensor. */
144 status = FXLS8962_SPI_Configure(&fxls8962Driver, cFxls8962ConfigFIFO);
145 if (SENSOR_ERROR_NONE != status)
146 {
147 PRINTF("\r\n FXLS8962 Sensor Configuration Failed, Err = %d\r\n", status);
148 return -1;
149 }
150 PRINTF("\r\n Successfully Applied FXLS8962 Sensor Configuration\r\n");
151
152 gFxls8962DataReady = false;
153 for (;;) /* Forever loop */
154 { /* In ISR Mode we do not need to check Data Ready Register.
155 * The receipt of interrupt will indicate data is ready. */
156 if (false == gFxls8962DataReady)
157 { /* Loop, if new sample is not available. */
158 SMC_SetPowerModeWait(SMC);
159 continue;
160 }
161 else
162 { /*! Clear the data ready flag, it will be set again by the ISR. */
163 gFxls8962DataReady = false;
164 pGpioDriver->toggle_pin(&GREEN_LED);
165 }
166
167 /*! Read new raw sensor data from the FXLS8962. */
168 status = FXLS8962_SPI_ReadData(&fxls8962Driver, cFxls8962OutputFIF0, data);
169 if (ARM_DRIVER_OK != status)
170 {
171 PRINTF("\r\n Read Failed. \r\n");
172 return -1;
173 }
174
175 for (i = 0; i < FXLS8962_FIFO_WMRK_SIZE; i++)
176 { /*! Convert the raw sensor data to signed 16-bit container for display to the debug port. */
177 rawData.accel[0] = ((int16_t)data[i * FXLS8962_DATA_SIZE + 1] << 8) | data[i * FXLS8962_DATA_SIZE + 0];
178 rawData.accel[1] = ((int16_t)data[i * FXLS8962_DATA_SIZE + 3] << 8) | data[i * FXLS8962_DATA_SIZE + 2];
179 rawData.accel[2] = ((int16_t)data[i * FXLS8962_DATA_SIZE + 5] << 8) | data[i * FXLS8962_DATA_SIZE + 4];
180 }
181
182 /*! Display to the debug port the last sample.
183 * NOTE: PRINTF is relatively expensive in terms of CPU time, specially when used with-in execution loop. */
184 PRINTF("\r\nX=%5d Y=%5d Z=%5d\r\n", rawData.accel[0], rawData.accel[1], rawData.accel[2]);
185 ASK_USER_TO_RESUME(8); /* Ask for user input after processing 8 FIFOs. */
186 }
187 }
188