ISSDK  1.8
IoT Sensing Software Development Kit
main_freertos_two_tasks.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 /*! \file main_freertos_two_tasks.c
10  \brief FreeRTOS (two task) implementation of sensor fusion on FRDM-K64F.
11 
12  This file shows one recommended way to incorporate sensor fusion capabilities
13  into a FreeRTOS project.
14 */
15 
16 /* FreeRTOS kernel includes. */
17 #include "FreeRTOS.h"
18 #include "task.h"
19 #include "queue.h"
20 #include "timers.h"
21 #include "event_groups.h"
22 
23 // KSDK and ISSDK Headers
24 #include "fsl_debug_console.h" // KSDK header file for the debug interface
25 #include "board.h" // KSDK header file to define board configuration
26 #include "pin_mux.h" // KSDK header file for pin mux initialization functions
27 #include "clock_config.h" // KSDK header file for clock configuration
28 #include "fsl_port.h" // KSDK header file for Port I/O control
29 #include "fsl_i2c.h" // KSDK header file for I2C interfaces
30 #include "fxas21002.h" // register address and bit field definitions
31 #include "mpl3115.h" // register address and bit field definitions
32 #include "fxos8700.h" // register address and bit field definitions
33 #include "fsl_i2c_cmsis.h"
34 #include "register_io_i2c.h"
35 #include "fsl_smc.h"
36 
37 // Sensor Fusion Headers
38 #include "sensor_fusion.h" // top level magCal and sensor fusion interfaces
39 #include "control.h" // Command/Streaming interface - application specific
40 #include "status.h" // Sta:tus indicator interface - application specific
41 #include "drivers.h" // NXP sensor drivers OR customer-supplied drivers
42 
43 // Global data structures
44 SensorFusionGlobals sfg; ///< This is the primary sensor fusion data structure
45 ControlSubsystem controlSubsystem; ///< used for serial communications
46 StatusSubsystem statusSubsystem; ///< provides visual (usually LED) status indicator
47 struct PhysicalSensor sensors[3]; ///< This implementation uses three physical sensors
48 EventGroupHandle_t event_group = NULL;
49 /*
50 registerDeviceInfo_t i2cBusInfo = {
51  .deviceInstance = I2C_S_DEVICE_INDEX,
52  .functionParam = SMC,
53  .idleFunction = (registeridlefunction_t) SMC_SetPowerModeWait
54 };
55 */
58  .functionParam = NULL,
59  .idleFunction = NULL
60 };
61 
62 static void read_task(void *pvParameters); // FreeRTOS Task definition
63 static void fusion_task(void *pvParameters); // FreeRTOS Task definition
64 
65 /// This is a FreeRTOS (dual task) implementation of the NXP sensor fusion demo build.
66 int main(void)
67 {
68 
69  BOARD_InitPins(); // defined in pin_mux.c, initializes pkg pins
70  BOARD_BootClockRUN(); // defined in clock_config.c, initializes clocks
71  BOARD_InitDebugConsole(); // defined in board.c, initializes the OpenSDA port
72 
73  ARM_DRIVER_I2C* I2Cdrv = &I2C_S_DRIVER; // defined in the <shield>.h file
74 
75  //I2Cdrv->Initialize(I2C_S_SIGNAL_EVENT); // Initialize the KSDK driver for the I2C port
76 
77  I2Cdrv->Initialize(I2C_S_SIGNAL_EVENT); // Initialize the KSDK driver for the I2C port
78 
79  I2Cdrv->PowerControl(ARM_POWER_FULL); // Set the I2C Power mode.
80  I2Cdrv->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST); // Configure the I2C bus speed
81 
82  initializeControlPort(&controlSubsystem); // configure pins and ports for the control sub-system
83  initializeStatusSubsystem(&statusSubsystem); // configure pins and ports for the status sub-system
84  initSensorFusionGlobals(&sfg, &statusSubsystem, &controlSubsystem); // Initialize sensor fusion structures
85  // "install" the sensors we will be using
86  sfg.installSensor(&sfg, &sensors[0], FXOS8700_I2C_ADDR, 1, (void*) I2Cdrv, &i2cBusInfo, FXOS8700_Init, FXOS8700_Read);
87  sfg.installSensor(&sfg, &sensors[1], FXAS21002_I2C_ADDR, 1, (void*) I2Cdrv, &i2cBusInfo, FXAS21002_Init, FXAS21002_Read);
88  sfg.installSensor(&sfg, &sensors[2], MPL3115_I2C_ADDR, 2, (void*) I2Cdrv, &i2cBusInfo, MPL3115_Init, MPL3115_Read);
89  sfg.initializeFusionEngine(&sfg); // This will initialize sensors and magnetic calibration
90 
91  event_group = xEventGroupCreate();
92  xTaskCreate(read_task, "READ", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL);
93  xTaskCreate(fusion_task, "FUSION", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
94 
95  sfg.setStatus(&sfg, NORMAL); // If we got this far, let's set status state to NORMAL
96  vTaskStartScheduler(); // Start the RTOS scheduler
97  sfg.setStatus(&sfg, HARD_FAULT); // If we got this far, FreeRTOS does not have enough memory allocated
98  for (;;) ;
99 }
100 
101 static void read_task(void *pvParameters)
102 {
103  uint16_t i=0; // general counter variable
104  portTickType lastWakeTime;
105  const portTickType frequency = 1; // tick counter runs at the read rate
106  lastWakeTime = xTaskGetTickCount();
107  while (1)
108  {
109  for (i=1; i<=OVERSAMPLE_RATE; i++) {
110  vTaskDelayUntil(&lastWakeTime, frequency);
111  sfg.readSensors(&sfg, i); // Reads sensors, applies HAL and does averaging (if applicable)
112  }
113  xEventGroupSetBits(event_group, B0);
114  }
115 }
116 
117 static void fusion_task(void *pvParameters)
118 {
119  uint16_t i=0; // general counter variable
120  while (1)
121  {
122  xEventGroupWaitBits(event_group, /* The event group handle. */
123  B0, /* The bit pattern the event group is waiting for. */
124  pdTRUE, /* BIT_0 and BIT_4 will be cleared automatically. */
125  pdFALSE, /* Don't wait for both bits, either bit unblock task. */
126  portMAX_DELAY); /* Block indefinitely to wait for the condition to be met. */
127 
128  sfg.conditionSensorReadings(&sfg); // magCal is run as part of this
129  sfg.runFusion(&sfg); // Run the actual fusion algorithms
130  sfg.applyPerturbation(&sfg); // apply debug perturbation (testing only)
131 
132  sfg.loopcounter++; // The loop counter is used to "serialize" mag cal operations
133  i=i+1;
134  if (i>=4) { // Some status codes include a "blink" feature. This loop
135  i=0; // should cycle at least four times for that to operate correctly.
136  sfg.updateStatus(&sfg); // This is where pending status updates are made visible
137  }
138  sfg.queueStatus(&sfg, NORMAL); // assume NORMAL status for next pass through the loop
139  sfg.pControlSubsystem->stream(&sfg, sUARTOutputBuffer); // Send stream data to the Sensor Fusion Toolbox
140  }
141 }
142 
143 /// \endcode
#define B0
Definition: sensor_fusion.h:72
readSensors_t * readSensors
read all physical sensors
This structure defines the device specific info required by register I/O.
Definition: sensor_drv.h:102
initializeFusionEngine_t * initializeFusionEngine
set sensor fusion structures to initial values
int8_t MPL3115_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
int8_t FXOS8700_Init(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
#define OVERSAMPLE_RATE
Provides function prototypes for driver level interfaces.
StatusSubsystem statusSubsystem
provides visual (usually LED) status indicator
Operation is Nominal.
An instance of PhysicalSensor structure type should be allocated for each physical sensors (combo dev...
setStatus_t * queueStatus
queue status change for next regular interval
registerDeviceInfo_t i2cBusInfo
Application-specific status subsystem.
conditionSensorReadings_t * conditionSensorReadings
preprocessing step for sensor fusion
Defines control sub-system.
The top level fusion structure.
int main(void)
This is a FreeRTOS (dual task) implementation of the NXP sensor fusion demo build.
void initSensorFusionGlobals(SensorFusionGlobals *sfg, StatusSubsystem *pStatusSubsystem, ControlSubsystem *pControlSubsystem)
utility function to insert default values in the top level structure
Definition: sensor_fusion.c:51
int8_t FXAS21002_Init(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
#define I2C_S_SIGNAL_EVENT
Definition: issdk_hal.h:34
The register_io_i2c.h file declares low-level interface functions for reading and writing sensor regi...
#define I2C_S_DRIVER
Definition: issdk_hal.h:33
ControlSubsystem controlSubsystem
used for serial communications
struct PhysicalSensor sensors[3]
This implementation uses three physical sensors.
he ControlSubsystem encapsulates command and data streaming functions.
Definition: control.h:42
#define BOARD_BootClockRUN
Definition: clock_config.h:19
int8_t MPL3115_Init(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
runFusion_t * runFusion
run the fusion routines
The fxas21002.h contains the fxas21002 sensor register definitions and its bit mask.
#define FXAS21002_I2C_ADDR
Non-recoverable FAULT = something went very wrong.
The sensor_fusion.h file implements the top level programming interface.
setStatus_t * setStatus
change status indicator immediately
SensorFusionGlobals sfg
This is the primary sensor fusion data structure.
ARM_DRIVER_I2C * I2Cdrv
uint8_t sUARTOutputBuffer[256]
main output buffer defined in control.c
Definition: control.c:37
updateStatus_t * updateStatus
status=next status
installSensor_t * installSensor
function for installing a new sensor into t
struct ControlSubsystem * pControlSubsystem
int8_t initializeControlPort(ControlSubsystem *pComm)
Initialize the control subsystem and all related hardware.
Definition: control.c:160
EventGroupHandle_t event_group
int8_t FXOS8700_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
#define I2C_S_DEVICE_INDEX
Definition: issdk_hal.h:35
#define MPL3115_I2C_ADDR
int8_t FXAS21002_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
The fxos8700.h file contains the register definitions for FXOS8700 sensor driver. ...
void BOARD_InitDebugConsole(void)
Definition: board.c:15
void initializeStatusSubsystem(StatusSubsystem *pStatus)
Definition: status.c:165
#define FXOS8700_I2C_ADDR
void BOARD_InitPins(void)
Configures pin routing and optionally pin electrical features.
Definition: pin_mux.c:47
streamData_t * stream
function to create packets for serial stream
Definition: control.h:51
applyPerturbation_t * applyPerturbation
apply step function for testing purposes
StatusSubsystem() provides an object-like interface for communicating status to the user...
Definition: status.h:22
int32_t loopcounter
counter incrementing each iteration of sensor fusion (typically 25Hz)