51 #include "clock_config.h"    57 #include "Driver_USART.h"    58 #include "fsl_i2c_cmsis.h"    59 #include "fsl_uart_cmsis.h"    66 #include "gpio_driver.h"    67 #include "auto_detection_service.h"    80 #define TIMESTAMP_DATA_SIZE      (4)                                 81 #define NINEAXISSENSOR_DATA_SIZE (18)                                 82 #define QUATERNION_SIZE          (8)                                 83 #define EULERANGLE_DATA_SIZE     (6)                                 84 #define FITERROR_DATA_SIZE       (2)                                 85 #define COORDINATES_SIZE         (1)                                 86 #define BOARDINFO_SIZE           (1)                                 87 #define BUILDNAME_SIZE           (2)                                 88 #define SYSTICKINFO_SIZE         (2)                                 90 #define APPLICATION_NAME "9 Axis Orientation Sensor Demo"                    92 #define APPLICATION_VERSION "2.5"    95 #define STREAMING_PAYLOAD_LEN \    96     (TIMESTAMP_DATA_SIZE + NINEAXISSENSOR_DATA_SIZE + QUATERNION_SIZE + EULERANGLE_DATA_SIZE + FITERROR_DATA_SIZE + COORDINATES_SIZE + BOARDINFO_SIZE + BUILDNAME_SIZE + SYSTICKINFO_SIZE)   116     .functionParam      = NULL,
   124 static void updateOrientBuf(uint8_t *pDest,
   127                             uint16_t iBytesToCopy);
   146     uint8_t tag, uint8_t *hostCommand, uint8_t *hostResponse, 
size_t *hostMsgSize, 
size_t respBufferSize)
   148     bool success = 
false;
   163         if (respBufferSize >= boardNameLen + shieldNameLen + appNameLen + 3)
   172         hostResponse[*hostMsgSize] = appNameLen;
   175         memcpy(hostResponse + *hostMsgSize, 
embAppName, appNameLen);
   176         *hostMsgSize += appNameLen;
   178         hostResponse[*hostMsgSize] = boardNameLen;
   181         memcpy(hostResponse + *hostMsgSize, 
boardString, boardNameLen);
   182         *hostMsgSize += boardNameLen;
   184         hostResponse[*hostMsgSize] = shieldNameLen;
   187         memcpy(hostResponse + *hostMsgSize, 
shieldString, shieldNameLen);
   188         *hostMsgSize += shieldNameLen;
   198         switch (hostCommand[0]) 
   227 void updateOrientBuf(uint8_t *pDest, uint16_t *pIndex, uint8_t *pSrc, uint16_t iBytesToCopy)
   231     for (counter = 0; counter < iBytesToCopy; counter++)
   233         pDest[(*pIndex)++] = pSrc[counter];
   243     int16_t scratch16 = 0;
   245     for (i=0; i<numZeros; i++) {
   254     SV_ptr data, 
Quaternion *fq, int16_t *iPhi, int16_t *iThe, int16_t *iRho, int16_t iOmega[], uint16_t *isystick)
   260     *iPhi = (int16_t)(10.0F * data->
fPhi);
   261     *iThe = (int16_t)(10.0F * data->
fThe);
   262     *iRho = (int16_t)(10.0F * data->
fRho);
   263     *isystick = (uint16_t)(data->
systick / 20);
   282         pComm->
stream = encodeOrientPacketStream; 
   298     static uint32_t iTimeStamp = 0;                              
   302     int16_t         iPhi, iThe, iRho;                            
   317     updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *)&iTimeStamp, 4);
   324         scratch32 = (sfg->Accel.iGc[
CHX] * 8192) / sfg->Accel.iCountsPerg;
   325         if (scratch32 > 32767) scratch32 = 32767;
   326         if (scratch32 < -32768) scratch32 = -32768;
   327         scratch16 = (int16_t) (scratch32);
   328         updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
   330         scratch32 = (sfg->Accel.iGc[
CHY] * 8192) / sfg->Accel.iCountsPerg;
   331         if (scratch32 > 32767) scratch32 = 32767;
   332         if (scratch32 < -32768) scratch32 = -32768;
   333         scratch16 = (int16_t) (scratch32);
   334         updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
   336         scratch32 = (sfg->Accel.iGc[
CHZ] * 8192) / sfg->Accel.iCountsPerg;
   337         if (scratch32 > 32767) scratch32 = 32767;
   338         if (scratch32 < -32768) scratch32 = -32768;
   339         scratch16 = (int16_t) (scratch32);
   340         updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
   354         updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
   356         updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
   358         updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
   371         scratch16 = (int16_t) ((sfg->Gyro.iYs[
CHX] * 20) / sfg->Gyro.iCountsPerDegPerSec);
   372         updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
   373         scratch16 = (int16_t) ((sfg->Gyro.iYs[
CHY] * 20) / sfg->Gyro.iCountsPerDegPerSec);
   374         updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
   375         scratch16 = (int16_t) ((sfg->Gyro.iYs[
CHZ] * 20) / sfg->Gyro.iCountsPerDegPerSec);
   376         updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
   386     fq.
q1 = fq.
q2 = fq.
q3 = 0.0F;
   388     iOmega[
CHX] = iOmega[
CHY] = iOmega[
CHZ] = 0;
   389     iPhi = iThe = iRho = 0;
   401     scratch16 = (int16_t) (fq.
q0 * 30000.0F);
   402     updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
   403     scratch16 = (int16_t) (fq.
q1 * 30000.0F);
   404     updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
   405     scratch16 = (int16_t) (fq.
q2 * 30000.0F);
   406     updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
   407     scratch16 = (int16_t) (fq.
q3 * 30000.0F);
   408     updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
   412     updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &iPhi, 2);
   413     updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &iThe, 2);
   414     updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &iRho, 2);
   423         updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
   427 #if THISCOORDSYSTEM == ANDROID   430 #elif THISCOORDSYSTEM == WIN8   433 #endif // THISCOORDSYSTEM   436     updateOrientBuf(sUARTOutputBuffer, &iIndex, &flags, 1);
   440     updateOrientBuf(sUARTOutputBuffer, &iIndex, &tmpuint8_t, 1);
   444     updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
   447     updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &isystick, 2);
   467     uint8_t secondaryStreamID1;             
   487     I2Cdrv->PowerControl(ARM_POWER_FULL);
   488     I2Cdrv->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
   492     if (ARM_DRIVER_OK != status)
   497     status = pUartDriver->PowerControl(ARM_POWER_FULL);
   498     if (ARM_DRIVER_OK != status)
   504     if (ARM_DRIVER_OK != status)
   510     initOrientaionAppControlPort(&gOrientationControlSubsystem);
   538     if (0 == secondaryStreamID1)
 void initSensorFusionGlobals(SensorFusionGlobals *sfg, StatusSubsystem *pStatusSubsystem, ControlSubsystem *pControlSubsystem)
utility function to insert default values in the top level structure 
 
The register_io_i2c.h file declares low-level interface functions for reading and writing sensor regi...
 
volatile quaternion_type QuaternionPacketType
quaternion type transmitted over UART 
 
#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. 
 
#define HOST_PRO_CMD_W_CFG_TAG
 
int8_t FXAS21002_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
 
#define HOST_S_SIGNAL_EVENT
 
void Host_IO_Receive(host_cmd_proc_fn_t process_host_command, uint8_t encoding)
 
#define BOARD_BootClockRUN
 
int32_t systick
systick timer; 
 
uint8_t data[FXLS8962_DATA_SIZE]
 
void initializeStatusSubsystem(StatusSubsystem *pStatus)
 
float fOmega[3]
average angular velocity (deg/s) 
 
float q1
x vector component 
 
writePort_t * write
low level function to write a char buffer to the serial stream 
 
volatile uint8_t AltPacketOn
flag to enable altitude packet 
 
installSensor_t * installSensor
function for installing a new sensor into t 
 
int16_t iBc[3]
averaged calibrated measurement (counts) 
 
#define ADS_MAX_STRING_LENGTH
 
#define HOST_PRO_INT_DEV_TAG
 
The fxos8700.h file contains the register definitions for FXOS8700 sensor driver. ...
 
updateStatus_t * updateStatus
status=next status 
 
#define HOST_PRO_INT_CMD_TAG
Bit aligned values for Host Protocol Interface IDs (Bits 5-6). 
 
he ControlSubsystem encapsulates command and data streaming functions. 
 
The fxas21002.h contains the fxas21002 sensor register definitions and its bit mask. 
 
int8_t FXOS8700_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
 
volatile uint8_t AngularVelocityPacketOn
flag to enable angular velocity packet 
 
void pit_init(uint32_t microseconds)
 
#define THIS_BOARD
FRDM_K64F. 
 
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 
 
#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 
 
struct MagSensor Mag
magnetometer storage 
 
int8_t FXAS21002_Init(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
 
initializeFusionEngine_t * initializeFusionEngine
set sensor fusion structures to initial values 
 
#define THISBUILD
define build number sent in debug packet for display purposes only 
 
void sBufAppendItem(uint8_t *pDest, uint16_t *pIndex, uint8_t *pSource, uint16_t iBytesToCopy)
Utility function used to place data in output buffer about to be transmitted via UART. 
 
int8_t FXOS8700_Init(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
 
setStatus_t * setStatus
change status indicator immediately 
 
float fFitErrorpc
current fit error % 
 
The sensor_fusion.h file implements the top level programming interface. 
 
volatile uint8_t RPCPacketOn
flag to enable roll, pitch, compass packet 
 
#define CHZ
Used to access Z-channel entries in various data data structures. 
 
void Host_IO_Add_ISO_Header(uint8_t streamID, uint8_t *pStreamingPacket, size_t sizePayload)
 
void Host_IO_Send(uint8_t *pMsg, size_t size, uint8_t encoding)
 
registerDeviceInfo_t deviceInfo
I2C device context. 
 
Provides function prototypes for driver level interfaces. 
 
uint8_t sUARTOutputBuffer[256]
main output buffer defined in control.c 
 
Quaternion fq
orientation quaternion 
 
void BOARD_SystickEnable(void)
Function to enable systicks framework. 
 
#define I2C_S_DEVICE_INDEX
 
#define CHX
Used to access X-channel entries in various data data structures. 
 
uint32_t iFlags
a bit-field of sensors and algorithms used 
 
int16_t iCountsPeruT
counts per uT 
 
#define FXAS21002_I2C_ADDR
 
runFusion_t * runFusion
run the fusion routines 
 
streamData_t * stream
function to create packets for serial stream 
 
Provides a simple abstraction for a periodic interval timer. 
 
float q2
y vector component 
 
Application-specific status subsystem. 
 
#define BOARD_DEBUG_UART_BAUDRATE
 
quaternion structure definition 
 
struct MagCalibration MagCal
mag cal storage 
 
Quaternion derived from 3-axis accel (tilt) 
 
readSensors_t * readSensors
read all physical sensors 
 
#define FUSION_HZ
(int) actual rate of fusion algorithm execution and sensor FIFO reads 
 
void BOARD_RunADS(const char *appName, char *boardString, char *shieldString, size_t bufferLength)
The function to register Application Name and initialte ADS. 
 
conditionSensorReadings_t * conditionSensorReadings
preprocessing step for sensor fusion 
 
Defines control sub-system. 
 
struct ControlSubsystem * pControlSubsystem
 
uint8_t Host_IO_Init(ARM_DRIVER_USART *pDrv, void *pBus, void *pDevInfo, void *spiSlaveParams, uint16_t slaveAddress)
 
#define F_USING_ACCEL
nominally 0x0001 if an accelerometer is to be used, 0x0000 otherwise 
 
The host_io_uart.h file contains the Host Protocol interface definitions and configuration. 
 
float q3
z vector component 
 
#define STREAMING_HEADER_LEN
 
status_t SMC_SetPowerModeWait(void *arg)
Configures the system to WAIT power mode. API name used from Kinetis family to maintain compatibility...
 
This structure defines the device specific info required by register I/O. 
 
setStatus_t * queueStatus
queue status change for next regular interval 
 
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) 
 
volatile int8_t AccelCalPacketOn
variable used to coordinate accelerometer calibration 
 
#define I2C_S_SIGNAL_EVENT
 
volatile uint8_t DebugPacketOn
flag to enable debug packet