90 sfg->Accel.iWhoAmI = 0;
96 sfg->Gyro.iWhoAmI = 0;
99 sfg->Pressure.iWhoAmI = 0;
115 if (sfg && pSensor && bus_driver && initialize && read)
124 pSensor->
read = read;
126 pSensor->
addr = addr;
150 for (pSensor = sfg->
pSensors; pSensor != NULL; pSensor = pSensor->
next)
153 if (status == 0) status = s;
165 if (sfg->Accel.iFIFOExceeded > 0) {
172 for (j =
CHX; j <=
CHZ; j++) iSum[j] = 0;
173 for (i = 0; i < sfg->Accel.iFIFOCount; i++)
174 for (j =
CHX; j <=
CHZ; j++) iSum[j] += sfg->Accel.iGsFIFO[i][j];
175 if (sfg->Accel.iFIFOCount > 0)
177 for (j =
CHX; j <=
CHZ; j++)
179 sfg->Accel.iGs[j] = (
int16)(iSum[j] / (
int32) sfg->Accel.iFIFOCount);
180 sfg->Accel.fGs[j] = (float)sfg->Accel.iGs[j] * sfg->Accel.fgPerCount;
210 for (j =
CHX; j <=
CHZ; j++) iSum[j] = 0;
215 for (j =
CHX; j <=
CHZ; j++)
239 if (sfg->Gyro.iFIFOExceeded > 0) {
249 for (j =
CHX; j <=
CHZ; j++) iSum[j] = 0;
250 for (i = 0; i < sfg->Gyro.iFIFOCount; i++)
251 for (j =
CHX; j <=
CHZ; j++)
252 iSum[j] += sfg->Gyro.iYsFIFO[i][j];
253 if (sfg->Gyro.iFIFOCount > 0)
255 for (j =
CHX; j <=
CHZ; j++)
257 sfg->Gyro.iYs[j] = (
int16)(iSum[j] / (
int32) sfg->Gyro.iFIFOCount);
258 sfg->Gyro.fYs[j] = (float)sfg->Gyro.iYs[j] * sfg->Gyro.fDegPerSecPerCount;
269 uint16_t read_loop_counter
279 for (pSensor = sfg->
pSensors; pSensor != NULL; pSensor = pSensor->
next)
281 remainder = fmod(read_loop_counter, pSensor->
schedule);
283 s = pSensor->
read(pSensor, sfg);
284 if (status == 0) status = s;
298 if (sfg->Accel.isEnabled) processAccelData(sfg);
306 if (sfg->Gyro.isEnabled) processGyroData(sfg);
319 for (i=0; i<numElements; i++) d8[i]=0;
323 for (i=0; i<numElements; i++) d16[i]=0;
327 for (i=0; i<numElements; i++) d32[i]=0;
336 for (i=0; i<numElements; i++)
341 for (i=0; i<numElements; i++)
346 for (i=0; i<numElements; i++)
359 sfg->Accel.iFIFOCount=0;
360 sfg->Accel.iFIFOExceeded =
false;
367 sfg->Gyro.iFIFOCount=0;
368 sfg->Gyro.iFIFOExceeded =
false;
392 pSV_1DOF_P_BASIC = &(sfg->SV_1DOF_P_BASIC);
394 pSV_1DOF_P_BASIC = NULL;
397 pSV_3DOF_G_BASIC = &(sfg->SV_3DOF_G_BASIC) ;
399 pSV_3DOF_G_BASIC = NULL;
402 pSV_3DOF_B_BASIC = &(sfg->SV_3DOF_B_BASIC);
404 pSV_3DOF_B_BASIC = NULL;
407 pSV_3DOF_Y_BASIC = &(sfg->SV_3DOF_Y_BASIC);
409 pSV_3DOF_Y_BASIC = NULL;
412 pSV_6DOF_GB_BASIC = &(sfg->SV_6DOF_GB_BASIC);
414 pSV_6DOF_GB_BASIC = NULL;
417 pSV_6DOF_GY_KALMAN = &(sfg->SV_6DOF_GY_KALMAN);
419 pSV_6DOF_GY_KALMAN = NULL;
421 #if F_9DOF_GBY_KALMAN 422 pSV_9DOF_GBY_KALMAN = &(sfg->SV_9DOF_GBY_KALMAN);
424 pSV_9DOF_GBY_KALMAN = NULL;
427 pAccel = &(sfg->Accel);
439 pGyro = &(sfg->Gyro);
444 pPressure = &(sfg->Pressure);
452 pSV_3DOF_B_BASIC, pSV_3DOF_Y_BASIC,
453 pSV_6DOF_GB_BASIC, pSV_6DOF_GY_KALMAN,
454 pSV_9DOF_GBY_KALMAN, pAccel, pMag, pGyro,
518 if (sample[
CHX] == -32768) sample[
CHX]++;
519 if (sample[
CHY] == -32768) sample[
CHY]++;
520 if (sample[
CHZ] == -32768) sample[
CHZ]++;
530 if (fifoCount < maxFifoSize) {
void updateStatus(SensorFusionGlobals *sfg)
quaternion_type DefaultQuaternionPacketType
default quaternion transmitted at power on
#define F_USING_GYRO
nominally 0x0004 if a gyro is to be used, 0x0000 otherwise
void setStatus(SensorFusionGlobals *sfg, fusion_status_t status)
readSensors_t * readSensors
read all physical sensors
#define F_3DOF_Y_BASIC
3DOF gyro integration algorithm selector - 0x0800 to include, 0x0000 otherwise
This structure defines the device specific info required by register I/O.
volatile uint8_t iPerturbation
test perturbation to be applied
initializeFusionEngine_t * initializeFusionEngine
set sensor fusion structures to initial values
This is the 3DOF basic accelerometer state vector structure.
void * bus_driver
should be of type (ARM_DRIVER_I2C* for I2C-based sensors, ARM_DRIVER_SPI* for SPI) ...
readSensor_t * read
pointer to function to read sensor using the supplied drivers
The GyroSensor structure stores raw and processed measurements for a 3-axis gyroscope.
#define F_3DOF_G_BASIC
3DOF accel tilt (accel) algorithm selector - 0x0200 to include, 0x0000 otherwise
ssUpdateStatus_t * test
unit test which simply increments to next state
int32_t systick_I2C
systick counter to benchmark I2C reads
void iUpdateMagBuffer(struct MagBuffer *pthisMagBuffer, struct MagSensor *pthisMag, int32 loopcounter)
#define F_USING_ACCEL
nominally 0x0001 if an accelerometer is to be used, 0x0000 otherwise
int32_t systick_Spare
systick counter for counts spare waiting for timing interrupt
Recoverable FAULT = something went wrong, but we can keep going.
#define F_6DOF_GY_KALMAN
6DOF accel and gyro (Kalman) algorithm selector - 0x2000 to include, 0x0000 otherwise ...
Provides function prototypes for driver level interfaces.
int16_t iBsFIFO[MAG_FIFO_SIZE][3]
FIFO measurements (counts)
SV_9DOF_GBY_KALMAN is the 9DOF Kalman filter accelerometer, magnetometer and gyroscope state vector s...
void fFuseSensors(struct SV_1DOF_P_BASIC *pthisSV_1DOF_P_BASIC, struct SV_3DOF_G_BASIC *pthisSV_3DOF_G_BASIC, struct SV_3DOF_B_BASIC *pthisSV_3DOF_B_BASIC, struct SV_3DOF_Y_BASIC *pthisSV_3DOF_Y_BASIC, struct SV_6DOF_GB_BASIC *pthisSV_6DOF_GB_BASIC, struct SV_6DOF_GY_KALMAN *pthisSV_6DOF_GY_KALMAN, struct SV_9DOF_GBY_KALMAN *pthisSV_9DOF_GBY_KALMAN, struct AccelSensor *pthisAccel, struct MagSensor *pthisMag, struct GyroSensor *pthisGyro, struct PressureSensor *pthisPressure, struct MagCalibration *pthisMagCal)
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
SV_3DOF_Y_BASIC structure is the 3DOF basic gyroscope state vector structure.
void ApplyAccelHAL(struct AccelSensor *Accel)
Apply the accelerometer Hardware Abstraction Layer.
spiSlaveSpecificParams_t slaveParams
SPI specific parameters. Not used for I2C.
void conditionSample(int16_t sample[3])
conditionSample ensures that we never encounter the maximum negative two's complement value for a 16-...
The SV_1DOF_P_BASIC structure contains state information for a pressure sensor/altimeter.
#define CHZ
Used to access Z-channel entries in various data data structures.
void addToFifo(union FifoSensor *sensor, uint16_t maxFifoSize, int16_t sample[3])
addToFifo is called from within sensor driver read functions
The MagSensor structure stores raw and processed measurements for a 3-axis magnetic sensor...
uint8_t iFIFOCount
number of measurements read from FIFO
ssUpdateStatus_t * update
make pending status active/visible
Quaternion derived from 3-axis accel + 3 axis mag (eCompass)
Application-specific status subsystem.
conditionSensorReadings_t * conditionSensorReadings
preprocessing step for sensor fusion
#define F_9DOF_GBY_KALMAN
9DOF accel, mag and gyro algorithm selector - 0x4000 to include, 0x0000 otherwise ...
struct MagSensor Mag
magnetometer storage
int8_t readSensors(SensorFusionGlobals *sfg, uint16_t read_loop_counter)
The sensor_drv.h file contains sensor state and error definitions.
updateStatus_t * testStatus
increment to next enumerated status value (test only)
initializeSensor_t * initialize
pointer to function to initialize sensor using the supplied drivers
uint16_t schedule
Parameter to control sensor sampling rate.
Defines control sub-system.
The top level fusion structure.
void fInitializeAccelCalibration(struct AccelCalibration *pthisAccelCal, struct AccelBuffer *pthisAccelBuffer, volatile int8 *AccelCalPacketOn)
Initialize the accelerometer calibration functions.
#define CHY
Used to access Y-channel entries in various data data structures.
void initSensorFusionGlobals(SensorFusionGlobals *sfg, StatusSubsystem *pStatusSubsystem, ControlSubsystem *pControlSubsystem)
utility function to insert default values in the top level structure
SV_6DOF_GY_KALMAN is the 6DOF Kalman filter accelerometer and gyroscope state vector structure...
void clearFIFOs(SensorFusionGlobals *sfg)
Function to clear FIFO at the end of each fusion computation.
This is the 3DOF basic magnetometer state vector structure/.
Quaternion derived from 3-axis accel (tilt)
#define F_USING_PRESSURE
nominally 0x0008 if altimeter is to be used, 0x0000 otherwise
Quaternion derived from 3-axis mag only (auto compass algorithm)
bool isEnabled
true if the device is sampling
#define F_USING_TEMPERATURE
nominally 0x0010 if temp sensor is to be used, 0x0000 otherwise
void initializeFusionEngine(SensorFusionGlobals *sfg)
volatile quaternion_type QuaternionPacketType
quaternion type transmitted over UART
he ControlSubsystem encapsulates command and data streaming functions.
struct MagCalibration MagCal
mag cal storage
registerDeviceInfo_t deviceInfo
I2C device context.
int16_t iBs[3]
averaged uncalibrated measurement (counts)
uint32_t iFlags
a bit-field of sensors and algorithms used
struct MagBuffer MagBuffer
mag cal constellation points
Quaternion derived from full 9-axis sensor fusion.
void fRunMagCalibration(struct MagCalibration *pthisMagCal, struct MagBuffer *pthisMagBuffer, struct MagSensor *pthisMag, int32 loopcounter)
runFusion_t * runFusion
run the fusion routines
fpSpiReadPreprocessFn_t pReadPreprocessFN
int16_t iGsFIFO[ACCEL_FIFO_SIZE][3]
FIFO measurements (counts)
The AccelSensor structure stores raw and processed measurements for a 3-axis accelerometer.
Non-recoverable FAULT = something went very wrong.
void ApplyGyroHAL(struct GyroSensor *Gyro)
Apply the gyroscope Hardware Abstraction Layer.
int8_t() initializeSensor_t(struct PhysicalSensor *sensor, struct SensorFusionGlobals *sfg)
The sensor_fusion.h file implements the top level programming interface.
uint8_t data[FXLS8962_DATA_SIZE]
Magnetic Calibration Structure.
void ApplyMagHAL(struct MagSensor *Mag)
Apply the magnetometer Hardware Abstraction Layer.
uint8_t iFIFOCount
number of measurements read from FIFO
struct PhysicalSensor * pSensors
a linked list of physical sensors
int8_t() readSensor_t(struct PhysicalSensor *sensor, struct SensorFusionGlobals *sfg)
#define F_3DOF_B_BASIC
3DOF mag eCompass (vehicle/mag) algorithm selector - 0x0400 to include, 0x0000 otherwise ...
setStatus_t * setStatus
change status indicator immediately
void queueStatus(SensorFusionGlobals *sfg, fusion_status_t status)
ssSetStatus_t * queue
queue status change for next regular interval
Initializing sensors and algorithms.
The PressureSensor structure stores raw and processed measurements for an altimeter.
#define F_6DOF_GB_BASIC
6DOF accel and mag eCompass algorithm selector - 0x1000 to include, 0x0000 otherwise ...
ssSetStatus_t * set
change status immediately - no delay
struct PhysicalSensor * next
pointer to next sensor in this linked list
void fInitializeMagCalibration(struct MagCalibration *pthisMagCal, struct MagBuffer *pthisMagBuffer)
#define CORE_SYSTICK_HZ
core and systick clock rate (Hz)
updateStatus_t * updateStatus
status=next status
float fuTPerCount
uT per count
installSensor_t * installSensor
function for installing a new sensor into t
struct ControlSubsystem * pControlSubsystem
struct StatusSubsystem * pStatusSubsystem
uint16_t iFIFOExceeded
Number of samples received in excess of software FIFO size.
fusion_status_t
Application-specific serial communications system.
uint16_t isInitialized
Bitfields to indicate sensor is active (use SensorBitFields from build.h)
Quaternion derived from 3-axis gyro only (rotation)
Lower level magnetic calibration interface.
void testStatus(SensorFusionGlobals *sfg)
int8_t initializeSensors(SensorFusionGlobals *sfg)
void fUpdateAccelBuffer(struct AccelCalibration *pthisAccelCal, struct AccelBuffer *pthisAccelBuffer, struct AccelSensor *pthisAccel, volatile int8 *AccelCalPacketOn)
Update the buffer used to store samples used for accelerometer calibration.
fpSpiWritePreprocessFn_t pWritePreprocessFN
#define CHX
Used to access X-channel entries in various data data structures.
void runFusion(SensorFusionGlobals *sfg)
float fBs[3]
averaged un-calibrated measurement (uT)
The FifoSensor union allows us to use common pointers for Accel, Mag & Gyro logical sensor structures...
uint16_t iFIFOExceeded
Number of samples received in excess of software FIFO size.
void fInitializeFusion(SensorFusionGlobals *sfg)
uint16_t addr
I2C address if applicable.
Quaternion derived from 3-axis accel + 3-axis gyro (gaming)
int8_t iMagBufferReadOnly
flag to denote that the magnetic measurement buffer is temporarily read only
#define F_1DOF_P_BASIC
1DOF pressure (altitude) and temperature algorithm selector - 0x0100 to include, 0x0000 otherwise ...
clearFIFOs_t * clearFIFOs
clear sensor FIFOs
void zeroArray(StatusSubsystem *pStatus, void *data, uint16_t size, uint16_t numElements, uint8_t check)
SV_6DOF_GB_BASIC is the 6DOF basic accelerometer and magnetometer state vector structure.
void processMagData(SensorFusionGlobals *sfg)
void ARM_systick_delay_ms(uint32 iSystemCoreClock, uint32 delay_ms)
int8_t installSensor(SensorFusionGlobals *sfg, struct PhysicalSensor *pSensor, uint16_t addr, uint16_t schedule, void *bus_driver, registerDeviceInfo_t *busInfo, initializeSensor_t *initialize, readSensor_t *read)
void conditionSensorReadings(SensorFusionGlobals *sfg)
registeridlefunction_t idleFunction
uint8_t iWhoAmI
sensor whoami
void fInvertAccelCal(struct AccelSensor *pthisAccel, struct AccelCalibration *pthisAccelCal)
function maps the accelerometer data fGs (g) onto precision calibrated and de-rotated data fGc (g)...
#define F_ALL_SENSORS
refers to all applicable sensor types for the given physical unit
void fInvertMagCal(struct MagSensor *pthisMag, struct MagCalibration *pthisMagCal)
void ARM_systick_enable(void)
Lower level sensor fusion interface.
volatile int8_t AccelCalPacketOn
variable used to coordinate accelerometer calibration
applyPerturbation_t * applyPerturbation
apply step function for testing purposes
StatusSubsystem() provides an object-like interface for communicating status to the user...
int32_t loopcounter
counter incrementing each iteration of sensor fusion (typically 25Hz)
applyPerturbation_t ApplyPerturbation
ApplyPerturbation is a reverse unit-step test function.