ISSDK  1.7
IoT Sensing Software Development Kit
main_freertos_two_tasks.c
Go to the documentation of this file.
1 /*
2  * The Clear BSD License
3  * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
4  * Copyright 2016-2017 NXP
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without modification,
8  * are permitted (subject to the limitations in the disclaimer below) provided
9  * that the following conditions are met:
10  *
11  * o Redistributions of source code must retain the above copyright notice, this list
12  * of conditions and the following disclaimer.
13  *
14  * o Redistributions in binary form must reproduce the above copyright notice, this
15  * list of conditions and the following disclaimer in the documentation and/or
16  * other materials provided with the distribution.
17  *
18  * o Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from this
20  * software without specific prior written permission.
21  *
22  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
27  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 /*! \file main_freertos_two_tasks.c
36  \brief FreeRTOS (two task) implementation of sensor fusion on FRDM-K64F.
37 
38  This file shows one recommended way to incorporate sensor fusion capabilities
39  into a FreeRTOS project.
40 */
41 
42 /* FreeRTOS kernel includes. */
43 #include "FreeRTOS.h"
44 #include "task.h"
45 #include "queue.h"
46 #include "timers.h"
47 #include "event_groups.h"
48 
49 // KSDK and ISSDK Headers
50 #include "fsl_debug_console.h" // KSDK header file for the debug interface
51 #include "board.h" // KSDK header file to define board configuration
52 #include "pin_mux.h" // KSDK header file for pin mux initialization functions
53 #include "clock_config.h" // KSDK header file for clock configuration
54 #include "fsl_port.h" // KSDK header file for Port I/O control
55 #include "fsl_i2c.h" // KSDK header file for I2C interfaces
56 #include "fxas21002.h" // register address and bit field definitions
57 #include "mpl3115.h" // register address and bit field definitions
58 #include "fxos8700.h" // register address and bit field definitions
59 #include "fsl_i2c_cmsis.h"
60 #include "register_io_i2c.h"
61 #include "fsl_smc.h"
62 
63 // Sensor Fusion Headers
64 #include "sensor_fusion.h" // top level magCal and sensor fusion interfaces
65 #include "control.h" // Command/Streaming interface - application specific
66 #include "status.h" // Sta:tus indicator interface - application specific
67 #include "drivers.h" // NXP sensor drivers OR customer-supplied drivers
68 
69 // Global data structures
70 SensorFusionGlobals sfg; ///< This is the primary sensor fusion data structure
71 ControlSubsystem controlSubsystem; ///< used for serial communications
72 StatusSubsystem statusSubsystem; ///< provides visual (usually LED) status indicator
73 struct PhysicalSensor sensors[3]; ///< This implementation uses three physical sensors
74 EventGroupHandle_t event_group = NULL;
75 /*
76 registerDeviceInfo_t i2cBusInfo = {
77  .deviceInstance = I2C_S_DEVICE_INDEX,
78  .functionParam = SMC,
79  .idleFunction = (registeridlefunction_t) SMC_SetPowerModeWait
80 };
81 */
84  .functionParam = NULL,
85  .idleFunction = NULL
86 };
87 
88 static void read_task(void *pvParameters); // FreeRTOS Task definition
89 static void fusion_task(void *pvParameters); // FreeRTOS Task definition
90 
91 /// This is a FreeRTOS (dual task) implementation of the NXP sensor fusion demo build.
92 int main(void)
93 {
94 
95  BOARD_InitPins(); // defined in pin_mux.c, initializes pkg pins
96  BOARD_BootClockRUN(); // defined in clock_config.c, initializes clocks
97  BOARD_InitDebugConsole(); // defined in board.c, initializes the OpenSDA port
98 
99  ARM_DRIVER_I2C* I2Cdrv = &I2C_S_DRIVER; // defined in the <shield>.h file
100 
101  //I2Cdrv->Initialize(I2C_S_SIGNAL_EVENT); // Initialize the KSDK driver for the I2C port
102 
103  I2Cdrv->Initialize(I2C_S_SIGNAL_EVENT); // Initialize the KSDK driver for the I2C port
104 
105  I2Cdrv->PowerControl(ARM_POWER_FULL); // Set the I2C Power mode.
106  I2Cdrv->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST); // Configure the I2C bus speed
107 
108  initializeControlPort(&controlSubsystem); // configure pins and ports for the control sub-system
109  initializeStatusSubsystem(&statusSubsystem); // configure pins and ports for the status sub-system
110  initSensorFusionGlobals(&sfg, &statusSubsystem, &controlSubsystem); // Initialize sensor fusion structures
111  // "install" the sensors we will be using
112  sfg.installSensor(&sfg, &sensors[0], FXOS8700_I2C_ADDR, 1, (void*) I2Cdrv, &i2cBusInfo, FXOS8700_Init, FXOS8700_Read);
113  sfg.installSensor(&sfg, &sensors[1], FXAS21002_I2C_ADDR, 1, (void*) I2Cdrv, &i2cBusInfo, FXAS21002_Init, FXAS21002_Read);
114  sfg.installSensor(&sfg, &sensors[2], MPL3115_I2C_ADDR, 2, (void*) I2Cdrv, &i2cBusInfo, MPL3115_Init, MPL3115_Read);
115  sfg.initializeFusionEngine(&sfg); // This will initialize sensors and magnetic calibration
116 
117  event_group = xEventGroupCreate();
118  xTaskCreate(read_task, "READ", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL);
119  xTaskCreate(fusion_task, "FUSION", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
120 
121  sfg.setStatus(&sfg, NORMAL); // If we got this far, let's set status state to NORMAL
122  vTaskStartScheduler(); // Start the RTOS scheduler
123  sfg.setStatus(&sfg, HARD_FAULT); // If we got this far, FreeRTOS does not have enough memory allocated
124  for (;;) ;
125 }
126 
127 static void read_task(void *pvParameters)
128 {
129  uint16_t i=0; // general counter variable
130  portTickType lastWakeTime;
131  const portTickType frequency = 1; // tick counter runs at the read rate
132  lastWakeTime = xTaskGetTickCount();
133  while (1)
134  {
135  for (i=1; i<=OVERSAMPLE_RATE; i++) {
136  vTaskDelayUntil(&lastWakeTime, frequency);
137  sfg.readSensors(&sfg, i); // Reads sensors, applies HAL and does averaging (if applicable)
138  }
139  xEventGroupSetBits(event_group, B0);
140  }
141 }
142 
143 static void fusion_task(void *pvParameters)
144 {
145  uint16_t i=0; // general counter variable
146  while (1)
147  {
148  xEventGroupWaitBits(event_group, /* The event group handle. */
149  B0, /* The bit pattern the event group is waiting for. */
150  pdTRUE, /* BIT_0 and BIT_4 will be cleared automatically. */
151  pdFALSE, /* Don't wait for both bits, either bit unblock task. */
152  portMAX_DELAY); /* Block indefinitely to wait for the condition to be met. */
153 
154  sfg.conditionSensorReadings(&sfg); // magCal is run as part of this
155  sfg.runFusion(&sfg); // Run the actual fusion algorithms
156  sfg.applyPerturbation(&sfg); // apply debug perturbation (testing only)
157 
158  sfg.loopcounter++; // The loop counter is used to "serialize" mag cal operations
159  i=i+1;
160  if (i>=4) { // Some status codes include a "blink" feature. This loop
161  i=0; // should cycle at least four times for that to operate correctly.
162  sfg.updateStatus(&sfg); // This is where pending status updates are made visible
163  }
164  sfg.queueStatus(&sfg, NORMAL); // assume NORMAL status for next pass through the loop
165  sfg.pControlSubsystem->stream(&sfg, sUARTOutputBuffer); // Send stream data to the Sensor Fusion Toolbox
166  }
167 }
168 
169 /// \endcode
void initSensorFusionGlobals(SensorFusionGlobals *sfg, StatusSubsystem *pStatusSubsystem, ControlSubsystem *pControlSubsystem)
utility function to insert default values in the top level structure
Definition: sensor_fusion.c:77
#define OVERSAMPLE_RATE
The register_io_i2c.h file declares low-level interface functions for reading and writing sensor regi...
registerDeviceInfo_t i2cBusInfo
int8_t FXAS21002_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
ControlSubsystem controlSubsystem
used for serial communications
#define BOARD_BootClockRUN
Definition: clock_config.h:45
void initializeStatusSubsystem(StatusSubsystem *pStatus)
Definition: status.c:191
EventGroupHandle_t event_group
installSensor_t * installSensor
function for installing a new sensor into t
int8_t MPL3115_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
void BOARD_InitDebugConsole(void)
Definition: board.c:41
The fxos8700.h file contains the register definitions for FXOS8700 sensor driver. ...
updateStatus_t * updateStatus
status=next status
he ControlSubsystem encapsulates command and data streaming functions.
Definition: control.h:68
The fxas21002.h contains the fxas21002 sensor register definitions and its bit mask.
int8_t FXOS8700_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
StatusSubsystem() provides an object-like interface for communicating status to the user...
Definition: status.h:48
The top level fusion structure.
#define B0
Definition: sensor_fusion.h:98
StatusSubsystem statusSubsystem
provides visual (usually LED) status indicator
applyPerturbation_t * applyPerturbation
apply step function for testing purposes
int8_t FXAS21002_Init(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
initializeFusionEngine_t * initializeFusionEngine
set sensor fusion structures to initial values
int8_t MPL3115_Init(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
int main(void)
This is a FreeRTOS (dual task) implementation of the NXP sensor fusion demo build.
int8_t FXOS8700_Init(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
setStatus_t * setStatus
change status indicator immediately
The sensor_fusion.h file implements the top level programming interface.
struct PhysicalSensor sensors[3]
This implementation uses three physical sensors.
Provides function prototypes for driver level interfaces.
The mpl3115.h contains the MPL3115 Pressure sensor register definitions, access macros, and device access functions.
uint8_t sUARTOutputBuffer[256]
main output buffer defined in control.c
Definition: control.c:63
#define I2C_S_DEVICE_INDEX
Definition: issdk_hal.h:61
#define FXAS21002_I2C_ADDR
runFusion_t * runFusion
run the fusion routines
#define I2C_S_DRIVER
Definition: issdk_hal.h:59
int8_t initializeControlPort(ControlSubsystem *pComm)
Initialize the control subsystem and all related hardware.
Definition: control.c:186
streamData_t * stream
function to create packets for serial stream
Definition: control.h:77
Non-recoverable FAULT = something went very wrong.
Application-specific status subsystem.
#define MPL3115_I2C_ADDR
readSensors_t * readSensors
read all physical sensors
conditionSensorReadings_t * conditionSensorReadings
preprocessing step for sensor fusion
Defines control sub-system.
struct ControlSubsystem * pControlSubsystem
This structure defines the device specific info required by register I/O.
Definition: sensor_drv.h:128
Operation is Nominal.
void BOARD_InitPins(void)
Configures pin routing and optionally pin electrical features.
Definition: pin_mux.c:73
setStatus_t * queueStatus
queue status change for next regular interval
SensorFusionGlobals sfg
This is the primary sensor fusion data structure.
An instance of PhysicalSensor structure type should be allocated for each physical sensors (combo dev...
#define FXOS8700_I2C_ADDR
int32_t loopcounter
counter incrementing each iteration of sensor fusion (typically 25Hz)
#define I2C_S_SIGNAL_EVENT
Definition: issdk_hal.h:60