53 #include "clock_config.h" 59 #include "Driver_USART.h" 60 #include "fsl_i2c_cmsis.h" 61 #include "fsl_uart_cmsis.h" 65 #include "gpio_driver.h" 66 #include "auto_detection_service.h" 79 #define TIMESTAMP_DATA_SIZE (4) 80 #define NINEAXISSENSOR_DATA_SIZE (18) 81 #define QUATERNION_SIZE (8) 82 #define EULERANGLE_DATA_SIZE (6) 83 #define FITERROR_DATA_SIZE (2) 84 #define COORDINATES_SIZE (1) 85 #define BOARDINFO_SIZE (1) 86 #define BUILDNAME_SIZE (2) 87 #define SYSTICKINFO_SIZE (2) 89 #define APPLICATION_NAME "9 Axis Orientation Sensor Demo" 91 #define APPLICATION_VERSION "2.5" 94 #define STREAMING_PAYLOAD_LEN \ 95 (TIMESTAMP_DATA_SIZE + NINEAXISSENSOR_DATA_SIZE + QUATERNION_SIZE + EULERANGLE_DATA_SIZE + FITERROR_DATA_SIZE + COORDINATES_SIZE + BOARDINFO_SIZE + BUILDNAME_SIZE + SYSTICKINFO_SIZE) 114 .functionParam = NULL,
122 static void updateOrientBuf(uint8_t *pDest,
125 uint16_t iBytesToCopy);
144 uint8_t tag, uint8_t *hostCommand, uint8_t *hostResponse,
size_t *hostMsgSize,
size_t respBufferSize)
146 bool success =
false;
161 if (respBufferSize >= boardNameLen + shieldNameLen + appNameLen + 3)
170 hostResponse[*hostMsgSize] = appNameLen;
173 memcpy(hostResponse + *hostMsgSize,
embAppName, appNameLen);
174 *hostMsgSize += appNameLen;
176 hostResponse[*hostMsgSize] = boardNameLen;
179 memcpy(hostResponse + *hostMsgSize,
boardString, boardNameLen);
180 *hostMsgSize += boardNameLen;
182 hostResponse[*hostMsgSize] = shieldNameLen;
185 memcpy(hostResponse + *hostMsgSize,
shieldString, shieldNameLen);
186 *hostMsgSize += shieldNameLen;
196 switch (hostCommand[0])
225 void updateOrientBuf(uint8_t *pDest, uint16_t *pIndex, uint8_t *pSrc, uint16_t iBytesToCopy)
229 for (counter = 0; counter < iBytesToCopy; counter++)
231 pDest[(*pIndex)++] = pSrc[counter];
241 int16_t scratch16 = 0;
243 for (i=0; i<numZeros; i++) {
252 SV_ptr data,
Quaternion *fq, int16_t *iPhi, int16_t *iThe, int16_t *iRho, int16_t iOmega[], uint16_t *isystick)
258 *iPhi = (int16_t)(10.0F * data->
fPhi);
259 *iThe = (int16_t)(10.0F * data->
fThe);
260 *iRho = (int16_t)(10.0F * data->
fRho);
261 *isystick = (uint16_t)(data->
systick / 20);
280 pComm->
stream = encodeOrientPacketStream;
296 static uint32_t iTimeStamp = 0;
300 int16_t iPhi, iThe, iRho;
315 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *)&iTimeStamp, 4);
322 scratch32 = (sfg->Accel.iGc[
CHX] * 8192) / sfg->Accel.iCountsPerg;
323 if (scratch32 > 32767) scratch32 = 32767;
324 if (scratch32 < -32768) scratch32 = -32768;
325 scratch16 = (int16_t) (scratch32);
326 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
328 scratch32 = (sfg->Accel.iGc[
CHY] * 8192) / sfg->Accel.iCountsPerg;
329 if (scratch32 > 32767) scratch32 = 32767;
330 if (scratch32 < -32768) scratch32 = -32768;
331 scratch16 = (int16_t) (scratch32);
332 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
334 scratch32 = (sfg->Accel.iGc[
CHZ] * 8192) / sfg->Accel.iCountsPerg;
335 if (scratch32 > 32767) scratch32 = 32767;
336 if (scratch32 < -32768) scratch32 = -32768;
337 scratch16 = (int16_t) (scratch32);
338 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
352 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
354 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
356 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
369 scratch16 = (int16_t) ((sfg->Gyro.iYs[
CHX] * 20) / sfg->Gyro.iCountsPerDegPerSec);
370 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
371 scratch16 = (int16_t) ((sfg->Gyro.iYs[
CHY] * 20) / sfg->Gyro.iCountsPerDegPerSec);
372 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
373 scratch16 = (int16_t) ((sfg->Gyro.iYs[
CHZ] * 20) / sfg->Gyro.iCountsPerDegPerSec);
374 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
384 fq.
q1 = fq.
q2 = fq.
q3 = 0.0F;
386 iOmega[
CHX] = iOmega[
CHY] = iOmega[
CHZ] = 0;
387 iPhi = iThe = iRho = 0;
399 scratch16 = (int16_t) (fq.
q0 * 30000.0F);
400 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
401 scratch16 = (int16_t) (fq.
q1 * 30000.0F);
402 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
403 scratch16 = (int16_t) (fq.
q2 * 30000.0F);
404 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
405 scratch16 = (int16_t) (fq.
q3 * 30000.0F);
406 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
410 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &iPhi, 2);
411 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &iThe, 2);
412 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &iRho, 2);
421 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
425 #if THISCOORDSYSTEM == ANDROID 428 #elif THISCOORDSYSTEM == WIN8 431 #endif // THISCOORDSYSTEM 434 updateOrientBuf(sUARTOutputBuffer, &iIndex, &flags, 1);
438 updateOrientBuf(sUARTOutputBuffer, &iIndex, &tmpuint8_t, 1);
442 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
445 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &isystick, 2);
466 uint8_t secondaryStreamID1,secondaryStreamID2,secondaryStreamID3;
485 I2Cdrv->PowerControl(ARM_POWER_FULL);
486 I2Cdrv->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
490 if (ARM_DRIVER_OK != status)
495 status = pUartDriver->PowerControl(ARM_POWER_FULL);
496 if (ARM_DRIVER_OK != status)
502 if (ARM_DRIVER_OK != status)
508 initOrientaionAppControlPort(&gOrientationControlSubsystem);
538 if (0 == secondaryStreamID1)
547 if (0 == secondaryStreamID2)
556 if (0 == secondaryStreamID3)
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
int8_t MPL3115_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
int16_t iBc[3]
averaged calibrated measurement (counts)
#define ADS_MAX_STRING_LENGTH
#define HOST_PRO_INT_DEV_TAG
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.
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
int8_t MAG3110_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
#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
#define FXLS8962_I2C_ADDR
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)
#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.
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
int8_t FXLS8962_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
#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.
int8_t FXLS8962_Init(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
setStatus_t * queueStatus
queue status change for next regular interval
int8_t MAG3110_Init(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
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
#define I2C_S_SIGNAL_EVENT
volatile uint8_t DebugPacketOn
flag to enable debug packet