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) 89 .functionParam = NULL,
97 static void updateOrientBuf(uint8_t *pDest,
100 uint16_t iBytesToCopy);
119 uint8_t tag, uint8_t *hostCommand, uint8_t *hostResponse,
size_t *hostMsgSize,
size_t respBufferSize)
121 bool success =
false;
136 if (respBufferSize >= boardNameLen + shieldNameLen + appNameLen + 3)
145 hostResponse[*hostMsgSize] = appNameLen;
148 memcpy(hostResponse + *hostMsgSize,
embAppName, appNameLen);
149 *hostMsgSize += appNameLen;
151 hostResponse[*hostMsgSize] = boardNameLen;
154 memcpy(hostResponse + *hostMsgSize,
boardString, boardNameLen);
155 *hostMsgSize += boardNameLen;
157 hostResponse[*hostMsgSize] = shieldNameLen;
160 memcpy(hostResponse + *hostMsgSize,
shieldString, shieldNameLen);
161 *hostMsgSize += shieldNameLen;
171 switch (hostCommand[0])
200 void updateOrientBuf(uint8_t *pDest, uint16_t *pIndex, uint8_t *pSrc, uint16_t iBytesToCopy)
204 for (counter = 0; counter < iBytesToCopy; counter++)
206 pDest[(*pIndex)++] = pSrc[counter];
216 int16_t scratch16 = 0;
218 for (i=0; i<numZeros; i++) {
227 SV_ptr data,
Quaternion *fq, int16_t *iPhi, int16_t *iThe, int16_t *iRho, int16_t iOmega[], uint16_t *isystick)
233 *iPhi = (int16_t)(10.0F * data->
fPhi);
234 *iThe = (int16_t)(10.0F * data->
fThe);
235 *iRho = (int16_t)(10.0F * data->
fRho);
236 *isystick = (uint16_t)(data->
systick / 20);
255 pComm->
stream = encodeOrientPacketStream;
271 static uint32_t iTimeStamp = 0;
275 int16_t iPhi, iThe, iRho;
290 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *)&iTimeStamp, 4);
297 scratch32 = (sfg->Accel.iGc[
CHX] * 8192) / sfg->Accel.iCountsPerg;
298 if (scratch32 > 32767) scratch32 = 32767;
299 if (scratch32 < -32768) scratch32 = -32768;
300 scratch16 = (int16_t) (scratch32);
301 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
303 scratch32 = (sfg->Accel.iGc[
CHY] * 8192) / sfg->Accel.iCountsPerg;
304 if (scratch32 > 32767) scratch32 = 32767;
305 if (scratch32 < -32768) scratch32 = -32768;
306 scratch16 = (int16_t) (scratch32);
307 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
309 scratch32 = (sfg->Accel.iGc[
CHZ] * 8192) / sfg->Accel.iCountsPerg;
310 if (scratch32 > 32767) scratch32 = 32767;
311 if (scratch32 < -32768) scratch32 = -32768;
312 scratch16 = (int16_t) (scratch32);
313 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
327 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
329 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
331 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
344 scratch16 = (int16_t) ((sfg->Gyro.iYs[
CHX] * 20) / sfg->Gyro.iCountsPerDegPerSec);
345 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
346 scratch16 = (int16_t) ((sfg->Gyro.iYs[
CHY] * 20) / sfg->Gyro.iCountsPerDegPerSec);
347 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
348 scratch16 = (int16_t) ((sfg->Gyro.iYs[
CHZ] * 20) / sfg->Gyro.iCountsPerDegPerSec);
349 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
359 fq.
q1 = fq.
q2 = fq.
q3 = 0.0F;
361 iOmega[
CHX] = iOmega[
CHY] = iOmega[
CHZ] = 0;
362 iPhi = iThe = iRho = 0;
374 scratch16 = (int16_t) (fq.
q0 * 30000.0F);
375 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
376 scratch16 = (int16_t) (fq.
q1 * 30000.0F);
377 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
378 scratch16 = (int16_t) (fq.
q2 * 30000.0F);
379 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
380 scratch16 = (int16_t) (fq.
q3 * 30000.0F);
381 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
385 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &iPhi, 2);
386 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &iThe, 2);
387 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &iRho, 2);
396 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
400 #if THISCOORDSYSTEM == ANDROID 403 #elif THISCOORDSYSTEM == WIN8 406 #endif // THISCOORDSYSTEM 409 updateOrientBuf(sUARTOutputBuffer, &iIndex, &flags, 1);
413 updateOrientBuf(sUARTOutputBuffer, &iIndex, &tmpuint8_t, 1);
417 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &scratch16, 2);
420 updateOrientBuf(sUARTOutputBuffer, &iIndex, (uint8_t *) &isystick, 2);
441 uint8_t secondaryStreamID1,secondaryStreamID2;
460 I2Cdrv->PowerControl(ARM_POWER_FULL);
461 I2Cdrv->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
465 if (ARM_DRIVER_OK != status)
470 status = pUartDriver->PowerControl(ARM_POWER_FULL);
471 if (ARM_DRIVER_OK != status)
477 if (ARM_DRIVER_OK != status)
483 initOrientaionAppControlPort(&gOrientationControlSubsystem);
512 if (0 == secondaryStreamID1)
521 if (0 == secondaryStreamID2)
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
#define STREAMING_PAYLOAD_LEN
registerDeviceInfo_t i2cBusInfo
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
char boardString[ADS_MAX_STRING_LENGTH]
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
int8_t MAG3110_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
int8_t MMA8652_Init(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
int main(void)
Main function.
#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.
char shieldString[ADS_MAX_STRING_LENGTH]
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
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.
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
struct PhysicalSensor sensors[3]
he ControlSubsystem encapsulates command and data streaming functions.
#define BOARD_DEBUG_UART_BAUDRATE
char embAppName[ADS_MAX_STRING_LENGTH]
struct MagCalibration MagCal
mag cal storage
void appendZerosOrientBuf(uint8_t *pDest, uint16_t *pIndex, uint16_t numZeros)
appendZerosOrientBuf utility function
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
#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)
int8_t MMA8652_Read(struct PhysicalSensor *sensor, SensorFusionGlobals *sfg)
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.
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]
#define APPLICATION_VERSION
Version to distinguish between instances the same application based on target Shield and updates...
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
ControlSubsystem gOrientationControlSubsystem
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...
#define APPLICATION_NAME
Unique Name for this application which should match the target GUI pkg name.
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)
volatile bool gStreamingEnabled
#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
StatusSubsystem statusSubsystem
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)
bool process_host_command(uint8_t tag, uint8_t *hostCommand, uint8_t *hostResponse, size_t *hostMsgSize, size_t respBufferSize)
Provides a simple abstraction for a periodic interval timer.