25 #include "clock_config.h" 31 #include "Driver_USART.h" 32 #include "fsl_i2c_cmsis.h" 33 #include "fsl_uart_cmsis.h" 40 #include "gpio_driver.h" 41 #include "auto_detection_service.h" 54 #define TIMESTAMP_DATA_SIZE (4) 55 #define NINEAXISSENSOR_DATA_SIZE (18) 56 #define QUATERNION_SIZE (8) 57 #define EULERANGLE_DATA_SIZE (6) 58 #define FITERROR_DATA_SIZE (2) 59 #define COORDINATES_SIZE (1) 60 #define BOARDINFO_SIZE (1) 61 #define BUILDNAME_SIZE (2) 62 #define SYSTICKINFO_SIZE (2) 64 #define APPLICATION_NAME "9 Axis Orientation Sensor Demo" 66 #define APPLICATION_VERSION "2.5" 69 #define STREAMING_PAYLOAD_LEN \ 70 (TIMESTAMP_DATA_SIZE + NINEAXISSENSOR_DATA_SIZE + QUATERNION_SIZE + EULERANGLE_DATA_SIZE + FITERROR_DATA_SIZE + COORDINATES_SIZE + BOARDINFO_SIZE + BUILDNAME_SIZE + SYSTICKINFO_SIZE) 90 .functionParam = NULL,
98 static void updateOrientBuf(uint8_t *pDest,
101 uint16_t iBytesToCopy);
120 uint8_t tag, uint8_t *hostCommand, uint8_t *hostResponse,
size_t *hostMsgSize,
size_t respBufferSize)
122 bool success =
false;
137 if (respBufferSize >= boardNameLen + shieldNameLen + appNameLen + 3)
146 hostResponse[*hostMsgSize] = appNameLen;
149 memcpy(hostResponse + *hostMsgSize,
embAppName, appNameLen);
150 *hostMsgSize += appNameLen;
152 hostResponse[*hostMsgSize] = boardNameLen;
155 memcpy(hostResponse + *hostMsgSize,
boardString, boardNameLen);
156 *hostMsgSize += boardNameLen;
158 hostResponse[*hostMsgSize] = shieldNameLen;
161 memcpy(hostResponse + *hostMsgSize,
shieldString, shieldNameLen);
162 *hostMsgSize += shieldNameLen;
172 switch (hostCommand[0])
201 void updateOrientBuf(uint8_t *pDest, uint16_t *pIndex, uint8_t *pSrc, uint16_t iBytesToCopy)
205 for (counter = 0; counter < iBytesToCopy; counter++)
207 pDest[(*pIndex)++] = pSrc[counter];
217 int16_t scratch16 = 0;
219 for (i=0; i<numZeros; i++) {
228 SV_ptr data,
Quaternion *fq, int16_t *iPhi, int16_t *iThe, int16_t *iRho, int16_t iOmega[], uint16_t *isystick)
234 *iPhi = (int16_t)(10.0F * data->
fPhi);
235 *iThe = (int16_t)(10.0F * data->
fThe);
236 *iRho = (int16_t)(10.0F * data->
fRho);
237 *isystick = (uint16_t)(data->
systick / 20);
256 pComm->
stream = encodeOrientPacketStream;
272 static uint32_t iTimeStamp = 0;
276 int16_t iPhi, iThe, iRho;
291 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *)&iTimeStamp, 4);
298 scratch32 = (sfg->Accel.iGc[
CHX] * 8192) / sfg->Accel.iCountsPerg;
299 if (scratch32 > 32767) scratch32 = 32767;
300 if (scratch32 < -32768) scratch32 = -32768;
301 scratch16 = (int16_t) (scratch32);
302 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
304 scratch32 = (sfg->Accel.iGc[
CHY] * 8192) / sfg->Accel.iCountsPerg;
305 if (scratch32 > 32767) scratch32 = 32767;
306 if (scratch32 < -32768) scratch32 = -32768;
307 scratch16 = (int16_t) (scratch32);
308 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
310 scratch32 = (sfg->Accel.iGc[
CHZ] * 8192) / sfg->Accel.iCountsPerg;
311 if (scratch32 > 32767) scratch32 = 32767;
312 if (scratch32 < -32768) scratch32 = -32768;
313 scratch16 = (int16_t) (scratch32);
314 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
328 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
330 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
332 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
345 scratch16 = (int16_t) ((sfg->Gyro.iYs[
CHX] * 20) / sfg->Gyro.iCountsPerDegPerSec);
346 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
347 scratch16 = (int16_t) ((sfg->Gyro.iYs[
CHY] * 20) / sfg->Gyro.iCountsPerDegPerSec);
348 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
349 scratch16 = (int16_t) ((sfg->Gyro.iYs[
CHZ] * 20) / sfg->Gyro.iCountsPerDegPerSec);
350 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
360 fq.
q1 = fq.
q2 = fq.
q3 = 0.0F;
362 iOmega[
CHX] = iOmega[
CHY] = iOmega[
CHZ] = 0;
363 iPhi = iThe = iRho = 0;
375 scratch16 = (int16_t) (fq.
q0 * 30000.0F);
376 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
377 scratch16 = (int16_t) (fq.
q1 * 30000.0F);
378 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
379 scratch16 = (int16_t) (fq.
q2 * 30000.0F);
380 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
381 scratch16 = (int16_t) (fq.
q3 * 30000.0F);
382 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
386 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &iPhi, 2);
387 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &iThe, 2);
388 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &iRho, 2);
397 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
401 #if THISCOORDSYSTEM == ANDROID 404 #elif THISCOORDSYSTEM == WIN8 407 #endif // THISCOORDSYSTEM 410 updateOrientBuf(sUARTOutputBuffer, &iIndex, &flags, 1);
414 updateOrientBuf(sUARTOutputBuffer, &iIndex, &tmpuint8_t, 1);
418 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
421 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &isystick, 2);
441 uint8_t secondaryStreamID1;
461 I2Cdrv->PowerControl(ARM_POWER_FULL);
462 I2Cdrv->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
466 if (ARM_DRIVER_OK != status)
471 status = pUartDriver->PowerControl(ARM_POWER_FULL);
472 if (ARM_DRIVER_OK != status)
478 if (ARM_DRIVER_OK != status)
484 initOrientaionAppControlPort(&gOrientationControlSubsystem);
512 if (0 == secondaryStreamID1)
quaternion_type DefaultQuaternionPacketType
default quaternion transmitted at power on
ControlSubsystem gOrientationControlSubsystem
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 FXOS8700_Init(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
Provides function prototypes for driver level interfaces.
The host_io_uart.h file contains the Host Protocol interface definitions and configuration.
volatile uint8_t AngularVelocityPacketOn
flag to enable angular velocity packet
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
#define CHZ
Used to access Z-channel entries in various data data structures.
#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
char boardString[ADS_MAX_STRING_LENGTH]
#define F_9DOF_GBY_KALMAN
9DOF accel, mag and gyro algorithm selector - 0x4000 to include, 0x0000 otherwise ...
struct MagSensor Mag
magnetometer storage
#define APPLICATION_NAME
Unique Name for this application which should match the target GUI pkg name.
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.
StatusSubsystem statusSubsystem
char shieldString[ADS_MAX_STRING_LENGTH]
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)
char embAppName[ADS_MAX_STRING_LENGTH]
#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
registerDeviceInfo_t i2cBusInfo
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
registerDeviceInfo_t deviceInfo
I2C device context.
uint32_t iFlags
a bit-field of sensors and algorithms used
#define BOARD_BootClockRUN
runFusion_t * runFusion
run the fusion routines
The fxas21002.h contains the fxas21002 sensor register definitions and its bit mask.
#define FXAS21002_I2C_ADDR
void Host_IO_Send(uint8_t *pMsg, size_t size, uint8_t encoding)
float fOmega[3]
average angular velocity (deg/s)
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.
#define APPLICATION_VERSION
Version to distinguish between instances the same application based on target Shield and updates...
setStatus_t * setStatus
change status indicator immediately
volatile uint8_t AltPacketOn
flag to enable altitude packet
uint8_t orientOutputBuffer[STREAMING_HEADER_LEN+STREAMING_PAYLOAD_LEN]
Quaternion fq
orientation quaternion
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
int main(void)
Main function.
#define STREAMING_PAYLOAD_LEN
struct PhysicalSensor sensors[2]
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...
int8_t FXOS8700_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
float q1
x vector component
#define CHX
Used to access X-channel entries in various data data structures.
#define I2C_S_DEVICE_INDEX
int32_t systick
systick timer;
int16_t iBc[3]
averaged calibrated measurement (counts)
int8_t FXAS21002_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
The fxos8700.h file contains the register definitions for FXOS8700 sensor driver. ...
void appendZerosOrientBuf(uint8_t *pDest, uint16_t *pIndex, uint16_t numZeros)
appendZerosOrientBuf utility function
#define HOST_PRO_INT_CMD_TAG
Bit aligned values for Host Protocol Interface IDs (Bits 5-6).
void initializeStatusSubsystem(StatusSubsystem *pStatus)
#define FXOS8700_I2C_ADDR
#define THISBUILD
define build number sent in debug packet for display purposes only
volatile bool gStreamingEnabled
bool process_host_command(uint8_t tag, uint8_t *hostCommand, uint8_t *hostResponse, size_t *hostMsgSize, size_t respBufferSize)
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
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.
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.