ISSDK  1.8
IoT Sensing Software Development Kit
mma8491q_demo.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 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 mma8491q_demo.c
11  * @brief The mma8491q_demo.c file implements the ISSDK MMA8491Q sensor driver
12  * demo demonstration with polling mode.
13  */
14 
15 //-----------------------------------------------------------------------
16 // SDK Includes
17 //-----------------------------------------------------------------------
18 #include "board.h"
19 #include "pin_mux.h"
20 #include "fsl_lptmr.h"
21 #include "clock_config.h"
22 
23 //-----------------------------------------------------------------------
24 // CMSIS Includes
25 //-----------------------------------------------------------------------
26 #include "Driver_I2C.h"
27 #include "Driver_USART.h"
28 
29 //-----------------------------------------------------------------------
30 // ISSDK Includes
31 //-----------------------------------------------------------------------
32 #include "issdk_hal.h"
33 #include "gpio_driver.h"
34 #include "mma8491q_drv.h"
35 #include "host_io_uart.h"
36 #include "systick_utils.h"
37 #include "auto_detection_service.h"
38 
39 //-----------------------------------------------------------------------
40 // Macros
41 //-----------------------------------------------------------------------
42 /* Timer timeout Callback. */
43 #define mma8491q_en_callback LPTMR0_IRQHandler
44 /* Desired ODR rate in milli seconds (since the example uses LPTMR, this should be >= 10ms for reliable timing). */
45 #define MMA8491Q_T_ODR_ms 100U
46 #define MMA8491Q_STREAM_DATA_SIZE 13 /* The size of Streaming Data in Host Message. */
47 /*! @brief Unique Name for this application which should match the target GUI pkg name. */
48 #define APPLICATION_NAME "MMA8491 Accelerometer Demo"
49 /*! @brief Version to distinguish between instances the same application based on target Shield and updates. */
50 #define APPLICATION_VERSION "2.5"
51 /* The LPTMR Timeout Correction in milliseconds. */
52 #define LPTMR_T_CORRECTION_ms 2
53 
54 //-----------------------------------------------------------------------
55 // Constants
56 //-----------------------------------------------------------------------
57 /*! @brief Address of Status Register. */
59 
60 /*! @brief Address and size of Raw Acceleration Data. */
63 
64 //-----------------------------------------------------------------------
65 // Global Variables
66 //-----------------------------------------------------------------------
69 volatile bool bStreamingEnabled = false, bMma8491qReady = false, bMma849qDataReady = false;
70 gpioConfigKSDK_t gGpioConfigInPins = /* SDK GPIO Config for Tilt Pins. */
71  {
72  .pinConfig = {kGPIO_DigitalInput, 0},
73  .interruptMode = kPORT_InterruptOrDMADisabled,
74  .portPinConfig = {0},
75  .portPinConfig.mux = kPORT_MuxAsGpio,
76 };
77 uint8_t gStreamID; /* The auto assigned Stream ID. */
80 
81 //-----------------------------------------------------------------------
82 // Functions
83 //-----------------------------------------------------------------------
84 /* @brief Block for adding EN delay. */
86 {
87  uint32_t delay, count, systemCoreClock;
88 
89  systemCoreClock = CLOCK_GetCoreSysClkFreq();
90  delay = (int)(0.16*MSEC_TO_COUNT(MMA8491Q_T_ON_TYPICAL, systemCoreClock));
91  for(count=0;count<delay;count++)
92  {
93  __NOP();
94  }
95 }
96 
97 /* LPTMR based EN control Timer Callback function. */
99 {
100  LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag);
101  bMma849qDataReady = true;
102 }
103 
104 /* Function for MMA8491Q specific initialization tasks. */
105 void mma8491q_timer_fwk_init(uint32_t samplingInterval)
106 {
107  lptmr_config_t lptmrConfig;
108  /* Initialize ODR Timer. */
109  LPTMR_GetDefaultConfig(&lptmrConfig);
110  LPTMR_Init(LPTMR0, &lptmrConfig);
111  LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);
112  EnableIRQ(LPTMR0_IRQn);
113 
114  /* Put the Sensor into Active Mode to enable I2C communication. */
115  LPTMR_SetTimerPeriod(LPTMR0, MSEC_TO_COUNT((samplingInterval-LPTMR_T_CORRECTION_ms), CLOCK_GetFreq(kCLOCK_LpoClk)));
116 }
117 
118 /* Handler for Device Info and Streaming Control Commands. */
120  uint8_t tag, uint8_t *hostCommand, uint8_t *hostResponse, size_t *hostMsgSize, size_t respBufferSize)
121 {
122  bool success = false;
123 
124  /* If it is Host requesting Device Info, send Board Name and Shield Name. */
125  if (tag == HOST_PRO_INT_DEV_TAG)
126  { /* Byte 1 : Payload - Length of APPLICATION_NAME (b)
127  * Bytes=b : Payload Application Name
128  * Byte b+1 : Payload - Length of BOARD_NAME (s)
129  * Bytes=s : Payload Board Name
130  * Byte b+s+2 : Payload - Length of SHIELD_NAME (v)
131  * Bytes=v : Payload Shield Name */
132 
133  size_t appNameLen = strlen(embAppName);
134  size_t boardNameLen = strlen(boardString);
135  size_t shieldNameLen = strlen(shieldString);
136 
137  if (respBufferSize >= boardNameLen + shieldNameLen + appNameLen + 3)
138  { /* We have sufficient buffer. */
139  *hostMsgSize = 0;
140  }
141  else
142  {
143  return false;
144  }
145 
146  hostResponse[*hostMsgSize] = appNameLen;
147  *hostMsgSize += 1;
148 
149  memcpy(hostResponse + *hostMsgSize, embAppName, appNameLen);
150  *hostMsgSize += appNameLen;
151 
152  hostResponse[*hostMsgSize] = boardNameLen;
153  *hostMsgSize += 1;
154 
155  memcpy(hostResponse + *hostMsgSize, boardString, boardNameLen);
156  *hostMsgSize += boardNameLen;
157 
158  hostResponse[*hostMsgSize] = shieldNameLen;
159  *hostMsgSize += 1;
160 
161  memcpy(hostResponse + *hostMsgSize, shieldString, shieldNameLen);
162  *hostMsgSize += shieldNameLen;
163 
164  return true;
165  }
166 
167  /* If it is Host sending Streaming Commands, take necessary actions. */
168  if ((tag == (HOST_PRO_INT_CMD_TAG | HOST_PRO_CMD_W_CFG_TAG)) &&
170  { /* Byte 1 : Payload - Operation Code (Start/Stop Operation Code)
171  * Byte 2 : Payload - Stream ID (Target Stream for carrying out operation) */
172  switch (hostCommand[0]) /* Execute desired operation (Start/Stop) on the requested Stream. */
173  {
174  case HOST_CMD_START:
175  if (hostCommand[1] == gStreamID && bMma8491qReady && bStreamingEnabled == false)
176  {
177  LPTMR_StartTimer(LPTMR0);
179  bStreamingEnabled = true;
180  success = true;
181  }
182  break;
183  case HOST_CMD_STOP:
184  if (hostCommand[1] == gStreamID && bMma8491qReady && bStreamingEnabled == true)
185  {
186  LPTMR_StopTimer(LPTMR0);
187  pGpioDriver->clr_pin(&GREEN_LED);
188  bStreamingEnabled = false;
189  success = true;
190  }
191  break;
192  default:
193  break;
194  }
195  *hostMsgSize = 0; /* Zero payload in response. */
196  }
197 
198  return success;
199 }
200 
201 /*!
202  * @brief Main function
203  */
204 int main(void)
205 {
206  int32_t status;
208 
209  mma8491q_i2c_sensorhandle_t mma8491qDriver;
211 
212  ARM_DRIVER_I2C *pI2cDriver = &I2C_S_DRIVER;
213  ARM_DRIVER_USART *pUartDriver = &HOST_S_DRIVER;
214 
215  /*! Initialize the MCU hardware. */
218 
219  /* Create the Short Application Name String for ADS. */
220  sprintf(embAppName, "%s:%s", APPLICATION_NAME, APPLICATION_VERSION);
221 
222  /* Run ADS. */
224 
225  /* Create the Full Application Name String for Device Info Response. */
227 
228  /* Initialize Tilt Pin IDs. */
229  pGpioDriver->pin_init(&MMA8491_EN, GPIO_DIRECTION_OUT, NULL, NULL, NULL);
230  pGpioDriver->pin_init(&MMA8491_XOUT, GPIO_DIRECTION_IN, &gGpioConfigInPins, NULL, NULL);
231  pGpioDriver->pin_init(&MMA8491_YOUT, GPIO_DIRECTION_IN, &gGpioConfigInPins, NULL, NULL);
232  pGpioDriver->pin_init(&MMA8491_ZOUT, GPIO_DIRECTION_IN, &gGpioConfigInPins, NULL, NULL);
233 
234  /*! Initialize GREEN LED pin used by FRDM board */
235  pGpioDriver->pin_init(&GREEN_LED, GPIO_DIRECTION_OUT, NULL, NULL, NULL);
236 
237  /*! Initialize the I2C driver. */
238  status = pI2cDriver->Initialize(I2C_S_SIGNAL_EVENT);
239  if (ARM_DRIVER_OK != status)
240  {
241  return -1;
242  }
243 
244  /*! Set the I2C Power mode. */
245  status = pI2cDriver->PowerControl(ARM_POWER_FULL);
246  if (ARM_DRIVER_OK != status)
247  {
248  return -1;
249  }
250 
251  /*! Set the I2C bus speed. */
252  status = pI2cDriver->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
253  if (ARM_DRIVER_OK != status)
254  {
255  return -1;
256  }
257 
258  /*! Initialize the UART driver. */
259  status = pUartDriver->Initialize(HOST_S_SIGNAL_EVENT);
260  if (ARM_DRIVER_OK != status)
261  {
262  return -1;
263  }
264 
265  /*! Set the UART Power mode. */
266  status = pUartDriver->PowerControl(ARM_POWER_FULL);
267  if (ARM_DRIVER_OK != status)
268  {
269  return -1;
270  }
271 
272  /*! Set UART Baud Rate. */
273  status = pUartDriver->Control(ARM_USART_MODE_ASYNCHRONOUS, BOARD_DEBUG_UART_BAUDRATE);
274  if (ARM_DRIVER_OK != status)
275  {
276  return -1;
277  }
278 
279  /* Set EN = 1 to enable I2C communication. */
280  pGpioDriver->set_pin(&MMA8491_EN);
282 
283  /* Initialize the Sensor Driver. */
285  if (SENSOR_ERROR_NONE == status)
286  {
287  /*! Set the task to be executed while waiting for I2C transactions to complete. */
289  bMma8491qReady = true;
290  }
291 
292  /*! Initialize streaming and assign a Stream ID. */
293  gStreamID =
294  Host_IO_Init(pUartDriver, (void *)mma8491qDriver.pCommDrv, &mma8491qDriver.deviceInfo, NULL, MMA8491_I2C_ADDR);
295  /* Confirm if a valid Stream ID has been allocated for this stream. */
296  if (0 == gStreamID)
297  {
298  bMma8491qReady = false;
299  }
300  else
301  { /*! Populate streaming header. */
303  pGpioDriver->clr_pin(&GREEN_LED); /* Set LED to indicate application is ready. */
304  }
305 
306  /*! Initialize MMA8491_ODR Timer framework. */
308  for (;;) /* Forever loop */
309  { /* Call UART Non-Blocking Receive. */
311 
312  /*! Process packets only if streaming has been enabled by Host */
313  if (false == bStreamingEnabled || false == bMma849qDataReady)
314  {
315  SMC_SetPowerModeWait(SMC); /* Power save, wait if nothing to do. */
316  continue;
317  }
318  else
319  {
320  pGpioDriver->toggle_pin(&GREEN_LED);
321  bMma849qDataReady = false;
322  }
323 
324  /* Set EN = 1 to put the Sensor into Active Mode. */
325  pGpioDriver->set_pin(&MMA8491_EN);
327  do
328  { /*! Process packets only when data ready is indicated by the MMA8491Q. */
329  MMA8491Q_I2C_ReadData(&mma8491qDriver, cMma8491qStatus, &dataReady);
330  } while (0 == (dataReady & MMA8491Q_STATUS_ZYXDR_MASK));
331 
332  /*! Read the raw sensor data from the MMA8491Q. */
333  status = MMA8491Q_I2C_ReadData(&mma8491qDriver, cMma8491qOutput, data);
334  if (ARM_DRIVER_OK != status)
335  { /* Loop, if sample read failed. */
336  continue;
337  }
338  /* Set EN = 0 to put the Sensor into Shutdown Mode. */
339  pGpioDriver->clr_pin(&MMA8491_EN);
340 
341  /* Update timestamp from Systick framework. */
343 
344  /* Read Tilt Output */
345  rawData.tilt[0] = pGpioDriver->read_pin(&MMA8491_XOUT);
346  rawData.tilt[1] = pGpioDriver->read_pin(&MMA8491_YOUT);
347  rawData.tilt[2] = pGpioDriver->read_pin(&MMA8491_ZOUT);
348 
349  /*! Process the sample and convert the raw sensor data. */
350  rawData.accel[0] = ((int16_t)data[0] << 8) | (data[1]);
351  rawData.accel[0] /= 4;
352  rawData.accel[1] = ((int16_t)data[2] << 8) | (data[3]);
353  rawData.accel[1] /= 4;
354  rawData.accel[2] = ((int16_t)data[4] << 8) | (data[5]);
355  rawData.accel[2] /= 4;
356 
357  /* Copy Raw samples to Streaming Buffer. */
358  memcpy(streamingPacket + STREAMING_HEADER_LEN, &rawData, MMA8491Q_STREAM_DATA_SIZE);
359  /* Send streaming packet to Host. */
360  Host_IO_Send(streamingPacket, sizeof(streamingPacket), HOST_FORMAT_HDLC);
361  }
362 }
void(* set_pin)(pinID_t aPinId)
Definition: Driver_GPIO.h:46
int32_t gSystick
Definition: mma8491q_demo.c:78
char embAppName[ADS_MAX_STRING_LENGTH]
Definition: mma8491q_demo.c:68
uint8_t Host_IO_Init(ARM_DRIVER_USART *pDrv, void *pBus, void *pDevInfo, void *spiSlaveParams, uint16_t slaveAddress)
Definition: host_io_uart.c:100
This defines the function pointers and sensor specific information.
Definition: mma8491q_drv.h:29
The GPIO Configuration KSDK.
Definition: gpio_driver.h:39
void Host_IO_Receive(host_cmd_proc_fn_t process_host_command, uint8_t encoding)
Definition: host_io_uart.c:207
volatile bool bMma849qDataReady
Definition: mma8491q_demo.c:69
int32_t status
#define APPLICATION_NAME
Unique Name for this application which should match the target GUI pkg name.
Definition: mma8491q_demo.c:48
#define MMA8491_YOUT
status_t SMC_SetPowerModeVlpr(void *arg)
Configures the system to VLPR power mode. API name used from Kinetis family to maintain compatibility...
Definition: lpc54114.c:169
The host_io_uart.h file contains the Host Protocol interface definitions and configuration.
uint32_t(* read_pin)(pinID_t aPinId)
Definition: Driver_GPIO.h:50
#define MMA8491_XOUT
volatile bool bStreamingEnabled
Definition: mma8491q_demo.c:69
#define MMA8491_EN
ARM_DRIVER_I2C * pCommDrv
Definition: mma8491q_drv.h:32
#define HOST_PRO_CMD_W_CFG_TAG
Definition: host_io_uart.h:63
Access structure of the GPIO Driver.
Definition: Driver_GPIO.h:38
#define SMC
Definition: lpc54114.h:118
#define MMA8491_I2C_ADDR
#define APPLICATION_VERSION
Version to distinguish between instances the same application based on target Shield and updates...
Definition: mma8491q_demo.c:50
gpioConfigKSDK_t gGpioConfigInPins
Definition: mma8491q_demo.c:70
void(* clr_pin)(pinID_t aPinId)
Definition: Driver_GPIO.h:47
typedef int32_t(DATA_FORMAT_Append_t))(void *pData
The interface function to append the data on the formated stream.
#define HOST_S_SIGNAL_EVENT
Definition: frdm_k64f.h:94
void MMA8491Q_I2C_SetIdleTask(mma8491q_i2c_sensorhandle_t *pSensorHandle, registeridlefunction_t idleTask, void *userParam)
: The interface function to set the I2C Idle Task.
Definition: mma8491q_drv.c:56
gpio_pin_config_t pinConfig
Definition: gpio_driver.h:41
#define I2C_S_SIGNAL_EVENT
Definition: issdk_hal.h:34
const registerreadlist_t cMma8491qStatus[]
Address of Status Register.
Definition: mma8491q_demo.c:58
#define I2C_S_DRIVER
Definition: issdk_hal.h:33
char boardString[ADS_MAX_STRING_LENGTH]
Definition: mma8491q_demo.c:67
void Host_IO_Add_ISO_Header(uint8_t streamID, uint8_t *pStreamingPacket, size_t sizePayload)
Definition: host_io_uart.c:86
#define BOARD_DEBUG_UART_BAUDRATE
Definition: board.h:31
#define MMA8491Q_STREAM_DATA_SIZE
Definition: mma8491q_demo.c:46
#define BOARD_BootClockRUN
Definition: clock_config.h:19
void(* registeridlefunction_t)(void *userParam)
This is the register idle function type.
Definition: sensor_drv.h:97
int main(void)
Main function.
registerDeviceInfo_t deviceInfo
Definition: mma8491q_drv.h:31
uint8_t streamingPacket[STREAMING_HEADER_LEN+FXLS8962_STREAM_DATA_SIZE]
GENERIC_DRIVER_GPIO Driver_GPIO_KSDK
Definition: gpio_driver.c:177
const registerreadlist_t cMma8491qOutput[]
Address and size of Raw Acceleration Data.
Definition: mma8491q_demo.c:61
void Host_IO_Send(uint8_t *pMsg, size_t size, uint8_t encoding)
Definition: host_io_uart.c:136
void BOARD_SystickStart(int32_t *pStart)
Function to Record the Start systick.
Definition: systick_utils.c:44
#define MMA8491Q_T_ON_TYPICAL
Definition: mma8491q.h:29
uint32_t BOARD_SystickElapsedTime_us(int32_t *pStart)
Function to compute the Elapsed Time.
Definition: systick_utils.c:64
This structure defines the mma8491q data buffer.
Definition: mma8491q_drv.h:38
uint8_t data[FXLS8962_DATA_SIZE]
#define __END_READ_DATA__
Definition: sensor_drv.h:51
#define HOST_PRO_INT_DEV_TAG
Definition: host_io_uart.h:59
void BOARD_RunADS(const char *appName, char *boardString, char *shieldString, size_t bufferLength)
The function to register Application Name and initialte ADS.
int32_t MMA8491Q_I2C_ReadData(mma8491q_i2c_sensorhandle_t *pSensorHandle, const registerreadlist_t *pReadList, uint8_t *pBuffer)
The interface function to read the sensor data.
Definition: mma8491q_drv.c:64
#define MMA8491Q_STATUS_ZYXDR_MASK
Definition: mma8491q.h:67
fxos8700_accelmagdata_t rawData
uint8_t gStreamID
Definition: mma8491q_demo.c:77
#define MMA8491Q_DATA_SIZE
Definition: mma8491q_drv.h:63
The mma8491q_drv.h file describes the MMA8491Q driver interface and structures.
char shieldString[ADS_MAX_STRING_LENGTH]
Definition: mma8491q_demo.c:67
uint16_t readFrom
Definition: sensor_drv.h:80
int32_t MMA8491Q_I2C_Initialize(mma8491q_i2c_sensorhandle_t *pSensorHandle, ARM_DRIVER_I2C *pBus, uint8_t index, uint16_t sAddress)
The interface function to initialize the sensor.
Definition: mma8491q_drv.c:22
#define MMA8491Q_T_ODR_ms
Definition: mma8491q_demo.c:45
void(* toggle_pin)(pinID_t aPinId)
Definition: Driver_GPIO.h:48
#define ADS_MAX_STRING_LENGTH
void BOARD_SystickEnable(void)
Function to enable systicks framework.
Definition: systick_utils.c:35
#define STREAMING_HEADER_LEN
Definition: host_io_uart.h:25
volatile bool bMma8491qReady
Definition: mma8491q_demo.c:69
status_t SMC_SetPowerModeWait(void *arg)
Configures the system to WAIT power mode. API name used from Kinetis family to maintain compatibility...
Definition: lpc54114.c:155
void(* pin_init)(pinID_t aPinId, gpio_direction_t dir, void *apPinConfig, gpio_isr_handler_t aIsrHandler, void *apUserData)
Definition: Driver_GPIO.h:41
bool process_host_command(uint8_t tag, uint8_t *hostCommand, uint8_t *hostResponse, size_t *hostMsgSize, size_t respBufferSize)
This structure defines the Read command List.
Definition: sensor_drv.h:78
ARM Systick Utilities.
gpioHandleKSDK_t GREEN_LED
Definition: frdm_k64f.c:188
#define I2C_S_DEVICE_INDEX
Definition: issdk_hal.h:35
void mma8491q_timer_fwk_init(uint32_t samplingInterval)
void mma8491q_en_delay()
Definition: mma8491q_demo.c:85
#define MMA8491_ZOUT
#define LPTMR_T_CORRECTION_ms
Definition: mma8491q_demo.c:52
#define HOST_PRO_INT_CMD_TAG
Bit aligned values for Host Protocol Interface IDs (Bits 5-6).
Definition: host_io_uart.h:57
#define SHIELD_NAME
GENERIC_DRIVER_GPIO * pGpioDriver
Definition: mma8491q_demo.c:79
#define mma8491q_en_callback
Definition: mma8491q_demo.c:43
#define HOST_S_DRIVER
Definition: frdm_k64f.h:93