116 sfg->Accel.iWhoAmI = 0;
122 sfg->Gyro.iWhoAmI = 0;
125 sfg->Pressure.iWhoAmI = 0;
141 if (sfg && pSensor && bus_driver && initialize && read)
150 pSensor->
read = read;
152 pSensor->
addr = addr;
176 for (pSensor = sfg->
pSensors; pSensor != NULL; pSensor = pSensor->
next)
179 if (status == 0) status = s;
191 if (sfg->Accel.iFIFOExceeded > 0) {
198 for (j =
CHX; j <=
CHZ; j++) iSum[j] = 0;
199 for (i = 0; i < sfg->Accel.iFIFOCount; i++)
200 for (j =
CHX; j <=
CHZ; j++) iSum[j] += sfg->Accel.iGsFIFO[i][j];
201 if (sfg->Accel.iFIFOCount > 0)
203 for (j =
CHX; j <=
CHZ; j++)
205 sfg->Accel.iGs[j] = (
int16)(iSum[j] / (
int32) sfg->Accel.iFIFOCount);
206 sfg->Accel.fGs[j] = (float)sfg->Accel.iGs[j] * sfg->Accel.fgPerCount;
236 for (j =
CHX; j <=
CHZ; j++) iSum[j] = 0;
241 for (j =
CHX; j <=
CHZ; j++)
265 if (sfg->Gyro.iFIFOExceeded > 0) {
275 for (j =
CHX; j <=
CHZ; j++) iSum[j] = 0;
276 for (i = 0; i < sfg->Gyro.iFIFOCount; i++)
277 for (j =
CHX; j <=
CHZ; j++)
278 iSum[j] += sfg->Gyro.iYsFIFO[i][j];
279 if (sfg->Gyro.iFIFOCount > 0)
281 for (j =
CHX; j <=
CHZ; j++)
283 sfg->Gyro.iYs[j] = (
int16)(iSum[j] / (
int32) sfg->Gyro.iFIFOCount);
284 sfg->Gyro.fYs[j] = (float)sfg->Gyro.iYs[j] * sfg->Gyro.fDegPerSecPerCount;
295 uint16_t read_loop_counter
305 for (pSensor = sfg->
pSensors; pSensor != NULL; pSensor = pSensor->
next)
307 remainder = fmod(read_loop_counter, pSensor->
schedule);
309 s = pSensor->
read(pSensor, sfg);
310 if (status == 0) status = s;
324 if (sfg->Accel.isEnabled) processAccelData(sfg);
332 if (sfg->Gyro.isEnabled) processGyroData(sfg);
345 for (i=0; i<numElements; i++) d8[i]=0;
349 for (i=0; i<numElements; i++) d16[i]=0;
353 for (i=0; i<numElements; i++) d32[i]=0;
362 for (i=0; i<numElements; i++)
367 for (i=0; i<numElements; i++)
372 for (i=0; i<numElements; i++)
385 sfg->Accel.iFIFOCount=0;
386 sfg->Accel.iFIFOExceeded =
false;
393 sfg->Gyro.iFIFOCount=0;
394 sfg->Gyro.iFIFOExceeded =
false;
418 pSV_1DOF_P_BASIC = &(sfg->SV_1DOF_P_BASIC);
420 pSV_1DOF_P_BASIC = NULL;
423 pSV_3DOF_G_BASIC = &(sfg->SV_3DOF_G_BASIC) ;
425 pSV_3DOF_G_BASIC = NULL;
428 pSV_3DOF_B_BASIC = &(sfg->SV_3DOF_B_BASIC);
430 pSV_3DOF_B_BASIC = NULL;
433 pSV_3DOF_Y_BASIC = &(sfg->SV_3DOF_Y_BASIC);
435 pSV_3DOF_Y_BASIC = NULL;
438 pSV_6DOF_GB_BASIC = &(sfg->SV_6DOF_GB_BASIC);
440 pSV_6DOF_GB_BASIC = NULL;
443 pSV_6DOF_GY_KALMAN = &(sfg->SV_6DOF_GY_KALMAN);
445 pSV_6DOF_GY_KALMAN = NULL;
447 #if F_9DOF_GBY_KALMAN 448 pSV_9DOF_GBY_KALMAN = &(sfg->SV_9DOF_GBY_KALMAN);
450 pSV_9DOF_GBY_KALMAN = NULL;
453 pAccel = &(sfg->Accel);
465 pGyro = &(sfg->Gyro);
470 pPressure = &(sfg->Pressure);
478 pSV_3DOF_B_BASIC, pSV_3DOF_Y_BASIC,
479 pSV_6DOF_GB_BASIC, pSV_6DOF_GY_KALMAN,
480 pSV_9DOF_GBY_KALMAN, pAccel, pMag, pGyro,
544 if (sample[
CHX] == -32768) sample[
CHX]++;
545 if (sample[
CHY] == -32768) sample[
CHY]++;
546 if (sample[
CHZ] == -32768) sample[
CHZ]++;
556 if (fifoCount < maxFifoSize) {
void initSensorFusionGlobals(SensorFusionGlobals *sfg, StatusSubsystem *pStatusSubsystem, ControlSubsystem *pControlSubsystem)
utility function to insert default values in the top level structure
The sensor_drv.h file contains sensor state and error definitions.
void ARM_systick_enable(void)
Initializing sensors and algorithms.
int8_t iMagBufferReadOnly
flag to denote that the magnetic measurement buffer is temporarily read only
Quaternion derived from full 9-axis sensor fusion.
volatile quaternion_type QuaternionPacketType
quaternion type transmitted over UART
uint16_t iFIFOExceeded
Number of samples received in excess of software FIFO size.
void fInitializeFusion(SensorFusionGlobals *sfg)
int8_t() readSensor_t(struct PhysicalSensor *sensor, struct SensorFusionGlobals *sfg)
fpSpiWritePreprocessFn_t pWritePreprocessFN
#define F_USING_GYRO
nominally 0x0004 if a gyro is to be used, 0x0000 otherwise
void * bus_driver
should be of type (ARM_DRIVER_I2C* for I2C-based sensors, ARM_DRIVER_SPI* for SPI) ...
#define CHY
Used to access Y-channel entries in various data data structures.
registeridlefunction_t idleFunction
updateStatus_t * testStatus
increment to next enumerated status value (test only)
#define F_ALL_SENSORS
refers to all applicable sensor types for the given physical unit
ssSetStatus_t * set
change status immediately - no delay
void iUpdateMagBuffer(struct MagBuffer *pthisMagBuffer, struct MagSensor *pthisMag, int32 loopcounter)
struct PhysicalSensor * next
pointer to next sensor in this linked list
int16_t iBs[3]
averaged uncalibrated measurement (counts)
void setStatus(SensorFusionGlobals *sfg, fusion_status_t status)
void fInitializeAccelCalibration(struct AccelCalibration *pthisAccelCal, struct AccelBuffer *pthisAccelBuffer, volatile int8 *AccelCalPacketOn)
Initialize the accelerometer calibration functions.
volatile uint8_t iPerturbation
test perturbation to be applied
Lower level sensor fusion interface.
struct MagBuffer MagBuffer
mag cal constellation points
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.
int32_t systick_Spare
systick counter for counts spare waiting for timing interrupt
Quaternion derived from 3-axis mag only (auto compass algorithm)
uint8_t data[FXLS8962_DATA_SIZE]
void ApplyGyroHAL(struct GyroSensor *Gyro)
Apply the gyroscope Hardware Abstraction Layer.
#define F_USING_PRESSURE
nominally 0x0008 if altimeter is to be used, 0x0000 otherwise
uint16_t schedule
Parameter to control sensor sampling rate.
uint16_t iFIFOExceeded
Number of samples received in excess of software FIFO size.
void fInvertAccelCal(struct AccelSensor *pthisAccel, struct AccelCalibration *pthisAccelCal)
function maps the accelerometer data fGs (g) onto precision calibrated and de-rotated data fGc (g)...
installSensor_t * installSensor
function for installing a new sensor into t
void zeroArray(StatusSubsystem *pStatus, void *data, uint16_t size, uint16_t numElements, uint8_t check)
float fuTPerCount
uT per count
This is the 3DOF basic magnetometer state vector structure/.
void processMagData(SensorFusionGlobals *sfg)
void fRunMagCalibration(struct MagCalibration *pthisMagCal, struct MagBuffer *pthisMagBuffer, struct MagSensor *pthisMag, int32 loopcounter)
Quaternion derived from 3-axis gyro only (rotation)
uint8_t iWhoAmI
sensor whoami
updateStatus_t * updateStatus
status=next status
void testStatus(SensorFusionGlobals *sfg)
Quaternion derived from 3-axis accel + 3 axis mag (eCompass)
The AccelSensor structure stores raw and processed measurements for a 3-axis accelerometer.
void initializeFusionEngine(SensorFusionGlobals *sfg)
he ControlSubsystem encapsulates command and data streaming functions.
Quaternion derived from 3-axis accel + 3-axis gyro (gaming)
SV_9DOF_GBY_KALMAN is the 9DOF Kalman filter accelerometer, magnetometer and gyroscope state vector s...
void clearFIFOs(SensorFusionGlobals *sfg)
Function to clear FIFO at the end of each fusion computation.
The MagSensor structure stores raw and processed measurements for a 3-axis magnetic sensor...
bool isEnabled
true if the device is sampling
StatusSubsystem() provides an object-like interface for communicating status to the user...
The top level fusion structure.
quaternion_type DefaultQuaternionPacketType
default quaternion transmitted at power on
struct PhysicalSensor * pSensors
a linked list of physical sensors
int8_t() initializeSensor_t(struct PhysicalSensor *sensor, struct SensorFusionGlobals *sfg)
void fInitializeMagCalibration(struct MagCalibration *pthisMagCal, struct MagBuffer *pthisMagBuffer)
The SV_1DOF_P_BASIC structure contains state information for a pressure sensor/altimeter.
Recoverable FAULT = something went wrong, but we can keep going.
#define F_1DOF_P_BASIC
1DOF pressure (altitude) and temperature algorithm selector - 0x0100 to include, 0x0000 otherwise ...
initializeSensor_t * initialize
pointer to function to initialize sensor using the supplied drivers
float fBs[3]
averaged un-calibrated measurement (uT)
ssUpdateStatus_t * update
make pending status active/visible
#define F_9DOF_GBY_KALMAN
9DOF accel, mag and gyro algorithm selector - 0x4000 to include, 0x0000 otherwise ...
applyPerturbation_t * applyPerturbation
apply step function for testing purposes
SV_6DOF_GY_KALMAN is the 6DOF Kalman filter accelerometer and gyroscope state vector structure...
int8_t readSensors(SensorFusionGlobals *sfg, uint16_t read_loop_counter)
struct MagSensor Mag
magnetometer storage
initializeFusionEngine_t * initializeFusionEngine
set sensor fusion structures to initial values
int16_t iBsFIFO[MAG_FIFO_SIZE][3]
FIFO measurements (counts)
uint16_t addr
I2C address if applicable.
void addToFifo(union FifoSensor *sensor, uint16_t maxFifoSize, int16_t sample[3])
addToFifo is called from within sensor driver read functions
#define F_6DOF_GY_KALMAN
6DOF accel and gyro (Kalman) algorithm selector - 0x2000 to include, 0x0000 otherwise ...
uint8_t iFIFOCount
number of measurements read from FIFO
setStatus_t * setStatus
change status indicator immediately
The sensor_fusion.h file implements the top level programming interface.
void runFusion(SensorFusionGlobals *sfg)
The FifoSensor union allows us to use common pointers for Accel, Mag & Gyro logical sensor structures...
SV_3DOF_Y_BASIC structure is the 3DOF basic gyroscope state vector structure.
#define F_3DOF_G_BASIC
3DOF accel tilt (accel) algorithm selector - 0x0200 to include, 0x0000 otherwise
#define CHZ
Used to access Z-channel entries in various data data structures.
void queueStatus(SensorFusionGlobals *sfg, fusion_status_t status)
uint16_t isInitialized
Bitfields to indicate sensor is active (use SensorBitFields from build.h)
spiSlaveSpecificParams_t slaveParams
SPI specific parameters. Not used for I2C.
int16_t iGsFIFO[ACCEL_FIFO_SIZE][3]
FIFO measurements (counts)
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)
Lower level magnetic calibration interface.
registerDeviceInfo_t deviceInfo
I2C device context.
Provides function prototypes for driver level interfaces.
ssSetStatus_t * queue
queue status change for next regular interval
#define F_USING_TEMPERATURE
nominally 0x0010 if temp sensor is to be used, 0x0000 otherwise
clearFIFOs_t * clearFIFOs
clear sensor FIFOs
struct StatusSubsystem * pStatusSubsystem
ssUpdateStatus_t * test
unit test which simply increments to next state
uint8_t iFIFOCount
number of measurements read from FIFO
#define CHX
Used to access X-channel entries in various data data structures.
uint32_t iFlags
a bit-field of sensors and algorithms used
void ApplyMagHAL(struct MagSensor *Mag)
Apply the magnetometer Hardware Abstraction Layer.
runFusion_t * runFusion
run the fusion routines
void conditionSample(int16_t sample[3])
conditionSample ensures that we never encounter the maximum negative two's complement value for a 16-...
Non-recoverable FAULT = something went very wrong.
Application-specific status subsystem.
Magnetic Calibration Structure.
void fInvertMagCal(struct MagSensor *pthisMag, struct MagCalibration *pthisMagCal)
void conditionSensorReadings(SensorFusionGlobals *sfg)
struct MagCalibration MagCal
mag cal storage
void updateStatus(SensorFusionGlobals *sfg)
int32_t systick_I2C
systick counter to benchmark I2C reads
Quaternion derived from 3-axis accel (tilt)
#define F_3DOF_Y_BASIC
3DOF gyro integration algorithm selector - 0x0800 to include, 0x0000 otherwise
#define F_6DOF_GB_BASIC
6DOF accel and mag eCompass algorithm selector - 0x1000 to include, 0x0000 otherwise ...
readSensors_t * readSensors
read all physical sensors
conditionSensorReadings_t * conditionSensorReadings
preprocessing step for sensor fusion
Defines control sub-system.
struct ControlSubsystem * pControlSubsystem
void ApplyAccelHAL(struct AccelSensor *Accel)
Apply the accelerometer Hardware Abstraction Layer.
readSensor_t * read
pointer to function to read sensor using the supplied drivers
#define F_USING_ACCEL
nominally 0x0001 if an accelerometer is to be used, 0x0000 otherwise
fusion_status_t
Application-specific serial communications system.
void ARM_systick_delay_ms(uint32 iSystemCoreClock, uint32 delay_ms)
SV_6DOF_GB_BASIC is the 6DOF basic accelerometer and magnetometer state vector structure.
This structure defines the device specific info required by register I/O.
#define F_3DOF_B_BASIC
3DOF mag eCompass (vehicle/mag) algorithm selector - 0x0400 to include, 0x0000 otherwise ...
setStatus_t * queueStatus
queue status change for next regular interval
This is the 3DOF basic accelerometer state vector structure.
#define CORE_SYSTICK_HZ
core and systick clock rate (Hz)
An instance of PhysicalSensor structure type should be allocated for each physical sensors (combo dev...
int32_t loopcounter
counter incrementing each iteration of sensor fusion (typically 25Hz)
volatile int8_t AccelCalPacketOn
variable used to coordinate accelerometer calibration
The GyroSensor structure stores raw and processed measurements for a 3-axis gyroscope.
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)
applyPerturbation_t ApplyPerturbation
ApplyPerturbation is a reverse unit-step test function.
fpSpiReadPreprocessFn_t pReadPreprocessFN
int8_t initializeSensors(SensorFusionGlobals *sfg)
The PressureSensor structure stores raw and processed measurements for an altimeter.