27 #include "clock_config.h" 33 #include "Driver_USART.h" 34 #include "fsl_i2c_cmsis.h" 35 #include "fsl_uart_cmsis.h" 39 #include "gpio_driver.h" 40 #include "auto_detection_service.h" 53 #define TIMESTAMP_DATA_SIZE (4) 54 #define NINEAXISSENSOR_DATA_SIZE (18) 55 #define QUATERNION_SIZE (8) 56 #define EULERANGLE_DATA_SIZE (6) 57 #define FITERROR_DATA_SIZE (2) 58 #define COORDINATES_SIZE (1) 59 #define BOARDINFO_SIZE (1) 60 #define BUILDNAME_SIZE (2) 61 #define SYSTICKINFO_SIZE (2) 63 #define APPLICATION_NAME "9 Axis Orientation Sensor Demo" 65 #define APPLICATION_VERSION "2.5" 68 #define STREAMING_PAYLOAD_LEN \ 69 (TIMESTAMP_DATA_SIZE + NINEAXISSENSOR_DATA_SIZE + QUATERNION_SIZE + EULERANGLE_DATA_SIZE + FITERROR_DATA_SIZE + COORDINATES_SIZE + BOARDINFO_SIZE + BUILDNAME_SIZE + SYSTICKINFO_SIZE) 88 .functionParam = NULL,
96 static void updateOrientBuf(uint8_t *pDest,
99 uint16_t iBytesToCopy);
118 uint8_t tag, uint8_t *hostCommand, uint8_t *hostResponse,
size_t *hostMsgSize,
size_t respBufferSize)
120 bool success =
false;
135 if (respBufferSize >= boardNameLen + shieldNameLen + appNameLen + 3)
144 hostResponse[*hostMsgSize] = appNameLen;
147 memcpy(hostResponse + *hostMsgSize,
embAppName, appNameLen);
148 *hostMsgSize += appNameLen;
150 hostResponse[*hostMsgSize] = boardNameLen;
153 memcpy(hostResponse + *hostMsgSize,
boardString, boardNameLen);
154 *hostMsgSize += boardNameLen;
156 hostResponse[*hostMsgSize] = shieldNameLen;
159 memcpy(hostResponse + *hostMsgSize,
shieldString, shieldNameLen);
160 *hostMsgSize += shieldNameLen;
170 switch (hostCommand[0])
199 void updateOrientBuf(uint8_t *pDest, uint16_t *pIndex, uint8_t *pSrc, uint16_t iBytesToCopy)
203 for (counter = 0; counter < iBytesToCopy; counter++)
205 pDest[(*pIndex)++] = pSrc[counter];
215 int16_t scratch16 = 0;
217 for (i=0; i<numZeros; i++) {
226 SV_ptr data,
Quaternion *fq, int16_t *iPhi, int16_t *iThe, int16_t *iRho, int16_t iOmega[], uint16_t *isystick)
232 *iPhi = (int16_t)(10.0F * data->
fPhi);
233 *iThe = (int16_t)(10.0F * data->
fThe);
234 *iRho = (int16_t)(10.0F * data->
fRho);
235 *isystick = (uint16_t)(data->
systick / 20);
254 pComm->
stream = encodeOrientPacketStream;
270 static uint32_t iTimeStamp = 0;
274 int16_t iPhi, iThe, iRho;
289 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *)&iTimeStamp, 4);
296 scratch32 = (sfg->Accel.iGc[
CHX] * 8192) / sfg->Accel.iCountsPerg;
297 if (scratch32 > 32767) scratch32 = 32767;
298 if (scratch32 < -32768) scratch32 = -32768;
299 scratch16 = (int16_t) (scratch32);
300 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
302 scratch32 = (sfg->Accel.iGc[
CHY] * 8192) / sfg->Accel.iCountsPerg;
303 if (scratch32 > 32767) scratch32 = 32767;
304 if (scratch32 < -32768) scratch32 = -32768;
305 scratch16 = (int16_t) (scratch32);
306 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
308 scratch32 = (sfg->Accel.iGc[
CHZ] * 8192) / sfg->Accel.iCountsPerg;
309 if (scratch32 > 32767) scratch32 = 32767;
310 if (scratch32 < -32768) scratch32 = -32768;
311 scratch16 = (int16_t) (scratch32);
312 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
326 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
328 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
330 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
343 scratch16 = (int16_t) ((sfg->Gyro.iYs[
CHX] * 20) / sfg->Gyro.iCountsPerDegPerSec);
344 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
345 scratch16 = (int16_t) ((sfg->Gyro.iYs[
CHY] * 20) / sfg->Gyro.iCountsPerDegPerSec);
346 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
347 scratch16 = (int16_t) ((sfg->Gyro.iYs[
CHZ] * 20) / sfg->Gyro.iCountsPerDegPerSec);
348 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
358 fq.
q1 = fq.
q2 = fq.
q3 = 0.0F;
360 iOmega[
CHX] = iOmega[
CHY] = iOmega[
CHZ] = 0;
361 iPhi = iThe = iRho = 0;
373 scratch16 = (int16_t) (fq.
q0 * 30000.0F);
374 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
375 scratch16 = (int16_t) (fq.
q1 * 30000.0F);
376 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
377 scratch16 = (int16_t) (fq.
q2 * 30000.0F);
378 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
379 scratch16 = (int16_t) (fq.
q3 * 30000.0F);
380 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
384 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &iPhi, 2);
385 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &iThe, 2);
386 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &iRho, 2);
395 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
399 #if THISCOORDSYSTEM == ANDROID 402 #elif THISCOORDSYSTEM == WIN8 405 #endif // THISCOORDSYSTEM 408 updateOrientBuf(sUARTOutputBuffer, &iIndex, &flags, 1);
412 updateOrientBuf(sUARTOutputBuffer, &iIndex, &tmpuint8_t, 1);
416 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
419 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &isystick, 2);
440 uint8_t secondaryStreamID1,secondaryStreamID2,secondaryStreamID3;
459 I2Cdrv->PowerControl(ARM_POWER_FULL);
460 I2Cdrv->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
464 if (ARM_DRIVER_OK != status)
469 status = pUartDriver->PowerControl(ARM_POWER_FULL);
470 if (ARM_DRIVER_OK != status)
476 if (ARM_DRIVER_OK != status)
482 initOrientaionAppControlPort(&gOrientationControlSubsystem);
512 if (0 == secondaryStreamID1)
521 if (0 == secondaryStreamID2)
530 if (0 == secondaryStreamID3)
#define APPLICATION_VERSION
Version to distinguish between instances the same application based on target Shield and updates...
quaternion_type DefaultQuaternionPacketType
default quaternion transmitted at power on
float q2
y vector component
#define F_USING_GYRO
nominally 0x0004 if a gyro is to be used, 0x0000 otherwise
readSensors_t * readSensors
read all physical sensors
volatile uint8_t RPCPacketOn
flag to enable roll, pitch, compass packet
This structure defines the device specific info required by register I/O.
uint8_t Host_IO_Init(ARM_DRIVER_USART *pDrv, void *pBus, void *pDevInfo, void *spiSlaveParams, uint16_t slaveAddress)
float fFitErrorpc
current fit error %
initializeFusionEngine_t * initializeFusionEngine
set sensor fusion structures to initial values
void Host_IO_Receive(host_cmd_proc_fn_t process_host_command, uint8_t encoding)
void * bus_driver
should be of type (ARM_DRIVER_I2C* for I2C-based sensors, ARM_DRIVER_SPI* for SPI) ...
#define F_USING_ACCEL
nominally 0x0001 if an accelerometer is to be used, 0x0000 otherwise
int8_t MPL3115_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
ControlSubsystem gOrientationControlSubsystem
Provides function prototypes for driver level interfaces.
uint8_t orientOutputBuffer[STREAMING_HEADER_LEN+STREAMING_PAYLOAD_LEN]
The host_io_uart.h file contains the Host Protocol interface definitions and configuration.
volatile uint8_t AngularVelocityPacketOn
flag to enable angular velocity packet
#define APPLICATION_NAME
Unique Name for this application which should match the target GUI pkg name.
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
int8_t MAG3110_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
#define CHZ
Used to access Z-channel entries in various data data structures.
int8_t MAG3110_Init(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
#define HOST_PRO_CMD_W_CFG_TAG
writePort_t * write
low level function to write a char buffer to the serial stream
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
Defines control sub-system.
#define THIS_BOARD
FRDM_K64F.
The top level fusion structure.
volatile uint8_t DebugPacketOn
flag to enable debug packet
#define CHY
Used to access Y-channel entries in various data data structures.
typedef int32_t(DATA_FORMAT_Append_t))(void *pData
The interface function to append the data on the formated stream.
#define HOST_S_SIGNAL_EVENT
void initSensorFusionGlobals(SensorFusionGlobals *sfg, StatusSubsystem *pStatusSubsystem, ControlSubsystem *pControlSubsystem)
utility function to insert default values in the top level structure
int8_t FXAS21002_Init(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
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.
Quaternion derived from 3-axis accel (tilt)
#define I2C_S_SIGNAL_EVENT
The register_io_i2c.h file declares low-level interface functions for reading and writing sensor regi...
quaternion structure definition
float q3
z vector component
void Host_IO_Add_ISO_Header(uint8_t streamID, uint8_t *pStreamingPacket, size_t sizePayload)
volatile quaternion_type QuaternionPacketType
quaternion type transmitted over UART
he ControlSubsystem encapsulates command and data streaming functions.
#define BOARD_DEBUG_UART_BAUDRATE
struct MagCalibration MagCal
mag cal storage
StatusSubsystem statusSubsystem
registerDeviceInfo_t deviceInfo
I2C device context.
uint32_t iFlags
a bit-field of sensors and algorithms used
bool process_host_command(uint8_t tag, uint8_t *hostCommand, uint8_t *hostResponse, size_t *hostMsgSize, size_t respBufferSize)
#define BOARD_BootClockRUN
int8_t MPL3115_Init(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
runFusion_t * runFusion
run the fusion routines
#define FXAS21002_I2C_ADDR
void Host_IO_Send(uint8_t *pMsg, size_t size, uint8_t encoding)
struct PhysicalSensor sensors[4]
This implementation uses up to 4 sensors.
float fOmega[3]
average angular velocity (deg/s)
registerDeviceInfo_t i2cBusInfo
volatile bool gStreamingEnabled
The sensor_fusion.h file implements the top level programming interface.
uint8_t data[FXLS8962_DATA_SIZE]
void pit_init(uint32_t microseconds)
#define HOST_PRO_INT_DEV_TAG
void BOARD_RunADS(const char *appName, char *boardString, char *shieldString, size_t bufferLength)
The function to register Application Name and initialte ADS.
int8_t FXLS8962_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
setStatus_t * setStatus
change status indicator immediately
volatile uint8_t AltPacketOn
flag to enable altitude packet
int8_t FXLS8962_Init(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
int main(void)
Main function.
Quaternion fq
orientation quaternion
#define STREAMING_PAYLOAD_LEN
uint8_t sUARTOutputBuffer[256]
main output buffer defined in control.c
updateStatus_t * updateStatus
status=next status
#define FUSION_HZ
(int) actual rate of fusion algorithm execution and sensor FIFO reads
installSensor_t * installSensor
function for installing a new sensor into t
struct ControlSubsystem * pControlSubsystem
#define ADS_MAX_STRING_LENGTH
char boardString[ADS_MAX_STRING_LENGTH]
void BOARD_SystickEnable(void)
Function to enable systicks framework.
#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...
float q1
x vector component
char embAppName[ADS_MAX_STRING_LENGTH]
#define CHX
Used to access X-channel entries in various data data structures.
void appendZerosOrientBuf(uint8_t *pDest, uint16_t *pIndex, uint16_t numZeros)
appendZerosOrientBuf utility function
#define I2C_S_DEVICE_INDEX
char shieldString[ADS_MAX_STRING_LENGTH]
int32_t systick
systick timer;
int16_t iBc[3]
averaged calibrated measurement (counts)
int8_t FXAS21002_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
#define FXLS8962_I2C_ADDR
void readAlgoParams(SV_ptr data, Quaternion *fq, int16_t *iPhi, int16_t *iThe, int16_t *iRho, int16_t iOmega[], uint16_t *isystick)
Utility function for reading common algorithm parameters.
#define HOST_PRO_INT_CMD_TAG
Bit aligned values for Host Protocol Interface IDs (Bits 5-6).
void initializeStatusSubsystem(StatusSubsystem *pStatus)
#define THISBUILD
define build number sent in debug packet for display purposes only
int16_t iCountsPeruT
counts per uT
streamData_t * stream
function to create packets for serial stream
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)
Provides a simple abstraction for a periodic interval timer.