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 mma845x_interrupt.c
11 * @brief The mma845x_interrupt.c file implements the ISSDK MMA845x sensor driver
12 * example demonstration with Interrupt 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 // CMSIS Includes
25 //-----------------------------------------------------------------------
26 #include "Driver_I2C.h"
27
28 //-----------------------------------------------------------------------
29 // ISSDK Includes
30 //-----------------------------------------------------------------------
31 #include "issdk_hal.h"
32 #include "gpio_driver.h"
33 #include "mma845x_drv.h"
34
35 //-----------------------------------------------------------------------
36 // Constants
37 //-----------------------------------------------------------------------
38 /*! Prepare the register write list to configure MMA845x in non-FIFO and ISR mode. */
39 const registerwritelist_t mma845x_Config_Isr[] = {
40 /*! Configure the MMA845x CTRL_REG1 to set mode to STANDBY and odr to 12.5Hz. */
41 {MMA845x_CTRL_REG1, MMA845x_CTRL_REG1_MODE_STANDBY | MMA845x_CTRL_REG1_DR_12DOT5HZ, 0},
42 /*! Configure the MMA845x to disable FIFO */
43 {MMA845x_F_SETUP, MMA845x_F_SETUP_F_MODE_FIFODISABLED, 0},
44 /*! Configure the MMA845x CTRL_REG2 to set the Oversampling mode to High Resolution. */
45 {MMA845x_CTRL_REG2, MMA845x_CTRL_REG2_MODS_HIGHRES, 0},
46 /*! Configure the MMA845x CTRL_REG3 to set the Interrupt polarity to ACTIVE high. */
47 {MMA845x_CTRL_REG3, MMA845x_CTRL_REG3_IPOL_HIGH, 0},
48 /*! Configure the MMA845x CTRL_REG4 to enable the data ready interrupt. */
49 {MMA845x_CTRL_REG4, MMA845x_CTRL_REG4_INT_EN_DRDY_ENABLED, 0},
50 /*! Configure the MMA845x CTRL_REG5 to route Interrupt to INT1 pin. */
51 {MMA845x_CTRL_REG5, MMA845x_CTRL_REG5_INT_CFG_DRDY_INT1, 0},
52 __END_WRITE_DATA__};
53
54 /*! Prepare the register read list to read the Data Ready Status from MMA845x. */
55 const registerreadlist_t MMA845x_Data_Ready[] = {{.readFrom = MMA845x_STATUS, .numBytes = 1}, __END_READ_DATA__};
56
57 /*! Prepare the register read list to read the raw Accel data from MMA845x. */
58 const registerreadlist_t mma845x_Output_Values[] = {
59 {.readFrom = MMA845x_OUT_X_MSB, .numBytes = MMA845x_ACCEL_DATA_SIZE}, __END_READ_DATA__};
60
61 //-----------------------------------------------------------------------
62 // Global Variables
63 //-----------------------------------------------------------------------
64 volatile bool mma845xInterrupt = false;
65
66 //-----------------------------------------------------------------------
67 // Functions
68 //-----------------------------------------------------------------------
69 /*! -----------------------------------------------------------------------
70 * @brief This is the Sensor Data Ready ISR implementation.
71 * @details This function sets the flag which indicates if a new sample(s) is available for reading.
72 * @param[in] pUserData This is a void pointer to the instance of the user specific data structure for the ISR.
73 * @return void There is no return value.
74 * @constraints None
75 * @reeentrant Yes
76 * -----------------------------------------------------------------------*/
mma845x_isr(void * pUserData)77 void mma845x_isr(void *pUserData)
78 { /*! @brief Set flag to indicate Sensor has signalled data ready. */
79 mma845xInterrupt = true;
80 }
81
82 /*! -----------------------------------------------------------------------
83 * @brief This is the The main function implementation.
84 * @details This function invokes board initializes routines, then then brings up the sensor and
85 * finally enters an endless loop to continuously read available samples.
86 * @param[in] void This is no input parameter.
87 * @return void There is no return value.
88 * @constraints None
89 * @reeentrant No
90 * -----------------------------------------------------------------------*/
main(void)91 int main(void)
92 {
93 int32_t status;
94 uint8_t data[MMA845x_ACCEL_DATA_SIZE];
95 mma845x_acceldata_t rawData;
96
97 ARM_DRIVER_I2C *I2Cdrv = &I2C_S_DRIVER; // Now using the shield.h value!!!
98 mma845x_i2c_sensorhandle_t MMA845xdrv;
99 GENERIC_DRIVER_GPIO *gpioDriver = &Driver_GPIO_KSDK;
100
101 /*! Initialize the MCU hardware. */
102 BOARD_InitPins();
103 BOARD_BootClockRUN();
104 BOARD_InitDebugConsole();
105
106 PRINTF("\r\n ISSDK MMA845x sensor driver example for interrupt mode.\r\n");
107
108 /*! Initialize INT1 pin used by FRDM board */
109 gpioDriver->pin_init(&MMA845x_INT1, GPIO_DIRECTION_IN, NULL, &mma845x_isr, NULL);
110 /*! Initialize RGB LED pin used by FRDM board */
111 gpioDriver->pin_init(&GREEN_LED, GPIO_DIRECTION_OUT, NULL, NULL, NULL);
112
113 /*! Initialize the I2C driver. */
114 status = I2Cdrv->Initialize(I2C_S_SIGNAL_EVENT);
115 if (ARM_DRIVER_OK != status)
116 {
117 PRINTF("\r\n I2C Initialization Failed\r\n");
118 return -1;
119 }
120
121 /*! Set the I2C Power mode. */
122 status = I2Cdrv->PowerControl(ARM_POWER_FULL);
123 if (ARM_DRIVER_OK != status)
124 {
125 PRINTF("\r\n I2C Power Mode setting Failed\r\n");
126 return -1;
127 }
128
129 /*! Set the I2C bus speed. */
130 status = I2Cdrv->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
131 if (ARM_DRIVER_OK != status)
132 {
133 PRINTF("\r\n I2C Control Mode setting Failed\r\n");
134 return -1;
135 }
136
137 /*! Initialize the MMA845x sensor driver. */
138 status = MMA845x_I2C_Initialize(&MMA845xdrv, &I2C_S_DRIVER, I2C_S_DEVICE_INDEX, MMA845x_I2C_ADDR,
139 MMA8451_WHO_AM_I_WHOAMI_VALUE);
140 if (SENSOR_ERROR_NONE != status)
141 {
142 PRINTF("\r\n Sensor Initialization Failed\r\n");
143 return -1;
144 }
145 PRINTF("\r\n Successfully Initiliazed Sensor\r\n");
146
147 /*! Set the task to be executed while waiting for I2C transactions to complete. */
148 MMA845x_I2C_SetIdleTask(&MMA845xdrv, (registeridlefunction_t)SMC_SetPowerModeVlpr, SMC);
149
150 /*! Configure the MMA845x sensor driver with No FIFO mode. */
151 status = MMA845x_I2C_Configure(&MMA845xdrv, mma845x_Config_Isr);
152 if (SENSOR_ERROR_NONE != status)
153 {
154 PRINTF("\r\n MMA845x Sensor Configuration Failed, Err = %d\r\n", status);
155 return -1;
156 }
157 PRINTF("\r\n Successfully Applied MMA845x Sensor Configuration\r\n");
158
159 for (;;) /* Forever loop */
160 { /* In ISR Mode we do not need to check Data Ready Register.
161 * The receipt of interrupt will indicate data is ready. */
162 if (false == mma845xInterrupt)
163 { /* Loop, if new sample is not available. */
164 SMC_SetPowerModeWait(SMC);
165 continue;
166 }
167 else
168 { /*! Clear the data ready flag, it will be set again by the ISR. */
169 mma845xInterrupt = false;
170 gpioDriver->toggle_pin(&GREEN_LED);
171 }
172
173 /*! Read the raw sensor data from the MMA845x. */
174 status = MMA845x_I2C_ReadData(&MMA845xdrv, mma845x_Output_Values, data);
175 if (ARM_DRIVER_OK != status)
176 {
177 PRINTF("\r\n Read Failed. \r\n");
178 return -1;
179 }
180
181 /*! Convert the raw sensor data to signed 16-bit container for display to the debug port. */
182 rawData.accel[0] = ((int16_t)data[0] << 8) | data[1];
183 rawData.accel[0] /= 4;
184 rawData.accel[1] = ((int16_t)data[2] << 8) | data[3];
185 rawData.accel[1] /= 4;
186 rawData.accel[2] = ((int16_t)data[4] << 8) | data[5];
187 rawData.accel[2] /= 4;
188
189 /* NOTE: PRINTF is relatively expensive in terms of CPU time, specially when used with-in execution loop. */
190 PRINTF("\r\n Accel X = %d Y = %d Z = %d\r\n", rawData.accel[0], rawData.accel[1], rawData.accel[2]);
191 ASK_USER_TO_RESUME(100); /* Ask for user input after processing 100 samples. */
192 }
193 }
194