diff options
Diffstat (limited to 'sensorlib')
71 files changed, 28792 insertions, 0 deletions
diff --git a/sensorlib/Makefile b/sensorlib/Makefile new file mode 100644 index 0000000..3b8f43c --- /dev/null +++ b/sensorlib/Makefile @@ -0,0 +1,88 @@ +#******************************************************************************
+#
+# Makefile - Rules for building the sensor library.
+#
+# Copyright (c) 2012-2014 Texas Instruments Incorporated. All rights reserved.
+# Software License Agreement
+#
+# Texas Instruments (TI) is supplying this software for use solely and
+# exclusively on TI's microcontroller products. The software is owned by
+# TI and/or its suppliers, and is protected under applicable copyright
+# laws. You may not combine this software with "viral" open-source
+# software in order to form a larger program.
+#
+# THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+# NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+# NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+# CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+# DAMAGES, FOR ANY REASON WHATSOEVER.
+#
+# This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+#
+#******************************************************************************
+
+#
+# The base directory for TivaWare.
+#
+ROOT=..
+
+#
+# Include the common make definitions.
+#
+include ${ROOT}/makedefs
+
+#
+# Where to find header files that do not live in the source directory.
+#
+IPATH=..
+
+#
+# The default rule, which causes the sensor library to be built.
+#
+all: ${COMPILER}
+all: ${COMPILER}/libsensor.a
+
+#
+# The rule to clean out all the build products.
+#
+clean:
+ @rm -rf ${COMPILER} ${wildcard *~}
+
+#
+# The rule to create the target directory.
+#
+${COMPILER}:
+ @mkdir -p ${COMPILER}
+
+#
+# Rules for building the sensor library.
+#
+${COMPILER}/libsensor.a: ${COMPILER}/ak8963.o
+${COMPILER}/libsensor.a: ${COMPILER}/ak8975.o
+${COMPILER}/libsensor.a: ${COMPILER}/bmp180.o
+${COMPILER}/libsensor.a: ${COMPILER}/bq27510g3.o
+${COMPILER}/libsensor.a: ${COMPILER}/cm3218.o
+${COMPILER}/libsensor.a: ${COMPILER}/comp_dcm.o
+${COMPILER}/libsensor.a: ${COMPILER}/i2cm_drv.o
+${COMPILER}/libsensor.a: ${COMPILER}/isl29023.o
+${COMPILER}/libsensor.a: ${COMPILER}/kxti9.o
+${COMPILER}/libsensor.a: ${COMPILER}/l3gd20h.o
+${COMPILER}/libsensor.a: ${COMPILER}/lsm303d.o
+${COMPILER}/libsensor.a: ${COMPILER}/lsm303dlhc_accel.o
+${COMPILER}/libsensor.a: ${COMPILER}/lsm303dlhc_mag.o
+${COMPILER}/libsensor.a: ${COMPILER}/magneto.o
+${COMPILER}/libsensor.a: ${COMPILER}/mpu6050.o
+${COMPILER}/libsensor.a: ${COMPILER}/mpu9150.o
+${COMPILER}/libsensor.a: ${COMPILER}/quaternion.o
+${COMPILER}/libsensor.a: ${COMPILER}/sht21.o
+${COMPILER}/libsensor.a: ${COMPILER}/tmp006.o
+${COMPILER}/libsensor.a: ${COMPILER}/tmp100.o
+${COMPILER}/libsensor.a: ${COMPILER}/vector.o
+
+#
+# Include the automatically generated dependency files.
+#
+ifneq (${MAKECMDGOALS},clean)
+-include ${wildcard ${COMPILER}/*.d} __dummy__
+endif
diff --git a/sensorlib/ak8963.c b/sensorlib/ak8963.c new file mode 100644 index 0000000..5b605a6 --- /dev/null +++ b/sensorlib/ak8963.c @@ -0,0 +1,666 @@ +//*****************************************************************************
+//
+// ak8963.c - Driver for the AK8963 magnetometer.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <stdint.h>
+#include "sensorlib/hw_ak8963.h"
+#include "sensorlib/i2cm_drv.h"
+#include "sensorlib/ak8963.h"
+
+//*****************************************************************************
+//
+//! \addtogroup ak8963_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The states of the AK8963 state machine.
+//
+//*****************************************************************************
+#define AK8963_STATE_IDLE 0 // State machine is idle
+#define AK8963_STATE_READ 1 // Waiting for read
+#define AK8963_STATE_WRITE 2 // Waiting for write
+#define AK8963_STATE_RMW 3 // Waiting for read-modify-write
+
+//*****************************************************************************
+//
+// The factors used to convert the magnetometer readings from the AK8963 into
+// floating point values in tesla
+//
+//*****************************************************************************
+static const float g_fAK8963Factors[] =
+{
+ 0.0000006, // 14-bit = .6 uT/LSB
+ 0.00000015, // 16-bit = .15 uT/LSB
+};
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transations to/from the
+// AK8963 have completed.
+//
+//*****************************************************************************
+static void
+AK8963Callback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tAK8963 *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tAK8963 structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result in a callback to propagate
+ // the error).
+ //
+ if(ui8Status != I2CM_STATUS_SUCCESS)
+ {
+ psInst->ui8State = AK8963_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the AK8963 state machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // All states that trivially transition to IDLE, and all unknown
+ // states.
+ //
+ case AK8963_STATE_READ:
+ default:
+ {
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = AK8963_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // A write has just completed.
+ //
+ case AK8963_STATE_WRITE:
+ {
+ //
+ // Set the bit width to the new value. If the register was not
+ // modified, the values will be the same so this has no effect.
+ //
+ psInst->ui8BitOutput = psInst->ui8NewBitOutput;
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = AK8963_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // A read-modify-write just completed
+ //
+ case AK8963_STATE_RMW:
+ {
+ //
+ // See if the AK8963_O_CNTL2 register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ AK8963_O_CNTL2)
+ {
+ //
+ // Extract the AK8963_CNTL2_SRST field
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ AK8963_CNTL2_SRST)
+ {
+ //
+ // A soft reset has happened. Reset the bitoutput
+ // tracking variable
+ //
+ psInst->ui8BitOutput = 0;
+ }
+ }
+
+ //
+ // See if the AK8963_O_CNTL register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ AK8963_O_CNTL)
+ {
+ //
+ // Extract the BITM field
+ //
+ psInst->ui8BitOutput =
+ ((psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ AK8963_CNTL_BITM_M) >> AK8963_CNTL_BITM_S);
+ }
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = AK8963_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == AK8963_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the AK8963 driver.
+//!
+//! \param psInst is a pointer to the AK8963 instance data.
+//! \param psI2CInst is a pointer to the I2C master driver instance data.
+//! \param ui8I2CAddr is the I2C address of the AK8963 device.
+//! \param pfnCallback is the function to be called when the initialization has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initializes the AK8963 driver, preparing it for operation.
+//!
+//! \return Returns 1 if the AK8963 driver was successfully initialized and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+AK8963Init(tAK8963 *psInst, tI2CMInstance *psI2CInst, uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Initialize the AK8963 instance structure.
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8I2CAddr;
+ psInst->ui8State = AK8963_STATE_IDLE;
+ psInst->ui8BitOutput = AK8963_CNTL_BITM_14BIT >> AK8963_CNTL_BITM_S;
+ psInst->ui8NewBitOutput = AK8963_CNTL_BITM_14BIT >> AK8963_CNTL_BITM_S;
+
+ //
+ // The default settings are ok. Return success and call the callback.
+ //
+ if(pfnCallback)
+ {
+ pfnCallback(pvCallbackData, 0);
+ }
+
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads data from AK8963 registers.
+//!
+//! \param psInst is a pointer to the AK8963 instance data.
+//! \param ui8Reg is the first register to read.
+//! \param pui8Data is a pointer to the location to store the data that is
+//! read.
+//! \param ui16Count is the number of data bytes to read.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function reads a sequence of data values from consecutive registers in
+//! the AK8963.
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+AK8963Read(tAK8963 *psInst, uint_fast8_t ui8Reg, uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the AK8963 driver is not idle (in other words, there
+ // is already an outstanding request to the AK8963).
+ //
+ if(psInst->ui8State != AK8963_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read state.
+ //
+ psInst->ui8State = AK8963_STATE_READ;
+
+ //
+ // Read the requested registers from the AK8963.
+ //
+ psInst->uCommand.pui8Buffer[0] = ui8Reg;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, pui8Data, ui16Count,
+ AK8963Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = AK8963_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Writes data to AK8963 registers.
+//!
+//! \param psInst is a pointer to the AK8963 instance data.
+//! \param ui8Reg is the first register to write.
+//! \param pui8Data is a pointer to the data to write.
+//! \param ui16Count is the number of data bytes to write.
+//! \param pfnCallback is the function to be called when the data has been
+//! written (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function writes a sequence of data values to consecutive registers in
+//! the AK8963. The first byte of the \e pui8Data buffer contains the value to
+//! be written into the \e ui8Reg register, the second value contains the data
+//! to be written into the next register, and so on.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+AK8963Write(tAK8963 *psInst, uint_fast8_t ui8Reg, const uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the AK8963 driver is not idle (in other words, there
+ // is already an outstanding request to the AK8963).
+ //
+ if(psInst->ui8State != AK8963_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // See if the CNTL2 register is being written.
+ //
+ if((ui8Reg <= AK8963_O_CNTL2) && ((ui8Reg + ui16Count) > AK8963_O_CNTL2))
+ {
+ //
+ // See if a soft reset is being requested.
+ //
+ if(pui8Data[ui8Reg - AK8963_O_CNTL2] & AK8963_CNTL2_SRST)
+ {
+ //
+ // Update the bit width based on the soft reset.
+ //
+ psInst->ui8NewBitOutput = 0;
+ }
+ }
+
+ //
+ // See if the CNTL register is being written.
+ //
+ if((ui8Reg <= AK8963_O_CNTL) && ((ui8Reg + ui16Count) > AK8963_O_CNTL))
+ {
+ //
+ // Extract the new value of the BITM field from the CNTL register
+ // value.
+ //
+ psInst->ui8NewBitOutput = ((pui8Data[ui8Reg - AK8963_O_CNTL] &
+ AK8963_CNTL_BITM_M) >> AK8963_CNTL_BITM_S);
+ }
+
+ //
+ // Move the state machine to the wait for write state.
+ //
+ psInst->ui8State = AK8963_STATE_WRITE;
+
+ //
+ // Write the requested registers to the AK8963.
+ //
+ if(I2CMWrite8(&(psInst->uCommand.sWriteState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui8Data, ui16Count, AK8963Callback,
+ psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = AK8963_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of an AK8963 register.
+//!
+//! \param psInst is a pointer to the AK8963 instance data.
+//! \param ui8Reg is the register to modify.
+//! \param ui8Mask is the bit mask that is ANDed with the current register
+//! value.
+//! \param ui8Value is the bit mask that is ORed with the result of the AND
+//! operation.
+//! \param pfnCallback is the function to be called when the data has been
+//! changed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function changes the value of a register in the AK8963 via a
+//! read-modify-write operation, allowing one of the fields to be changed
+//! without disturbing the other fields. The \e ui8Reg register is read, ANDed
+//! with \e ui8Mask, ORed with \e ui8Value, and then written back to the
+//! AK8963.
+//!
+//! \return Returns 1 if the read-modify-write was successfully started and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+AK8963ReadModifyWrite(tAK8963 *psInst, uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask, uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the AK8963 driver is not idle (in other words, there
+ // is already an outstanding request to the AK8963).
+ //
+ if(psInst->ui8State != AK8963_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read-modify-write state.
+ //
+ psInst->ui8State = AK8963_STATE_RMW;
+
+ //
+ // Submit the read-modify-write request to the AK8963.
+ //
+ if(I2CMReadModifyWrite8(&(psInst->uCommand.sReadModifyWriteState),
+ psInst->psI2CInst, psInst->ui8Addr, ui8Reg,
+ ui8Mask, ui8Value, AK8963Callback, psInst) == 0)
+ {
+ //
+ // The I2C read-modify-write failed, so move to the idle state and
+ // return a failure.
+ //
+ psInst->ui8State = AK8963_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads the magnetometer data from the AK8963.
+//!
+//! \param psInst is a pointer to the AK8963 instance data.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read of the AK8963 data registers. When the
+//! read has completed (as indicated by calling the callback function), the new
+//! readings can be obtained via:
+//!
+//! - AK8963DataMagnetoGetRaw()
+//! - AK8963DataMagnetoGetFloat()
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+AK8963DataRead(tAK8963 *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the AK8963 driver is not idle (in other words, there
+ // is already an outstanding request to the AK8963).
+ //
+ if(psInst->ui8State != AK8963_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for data read state.
+ //
+ psInst->ui8State = AK8963_STATE_READ;
+
+ //
+ // Read the data registers from the AK8963.
+ //
+ // ST1 + (HXL + HXH) + (HYL + HYH) + (HZL + HZH) + ST2 = 8 bytes
+ //
+ psInst->pui8Data[0] = AK8963_O_ST1;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr, psInst->pui8Data, 1,
+ psInst->pui8Data, 8, AK8963Callback, psInst) == 0)
+ {
+ //
+ // The I2C read failed, so move to the idle state and return a failure.
+ //
+ psInst->ui8State = AK8963_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Gets the raw magnetometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the AK8963 instance data.
+//! \param pui16MagnetoX is a pointer to the value into which the raw X-axis
+//! magnetometer data is stored.
+//! \param pui16MagnetoY is a pointer to the value into which the raw Y-axis
+//! magnetometer data is stored.
+//! \param pui16MagnetoZ is a pointer to the value into which the raw Z-axis
+//! magnetometer data is stored.
+//!
+//! This function returns the raw magnetometer data from the most recent data
+//! read. The data is not manipulated in any way by the driver. If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AK8963DataMagnetoGetRaw(tAK8963 *psInst, uint_fast16_t *pui16MagnetoX,
+ uint_fast16_t *pui16MagnetoY,
+ uint_fast16_t *pui16MagnetoZ)
+{
+ //
+ // Return the raw magnetometer values.
+ //
+ if(pui16MagnetoX)
+ {
+ *pui16MagnetoX = (psInst->pui8Data[2] << 8) | psInst->pui8Data[1];
+ }
+ if(pui16MagnetoY)
+ {
+ *pui16MagnetoY = (psInst->pui8Data[4] << 8) | psInst->pui8Data[3];
+ }
+ if(pui16MagnetoZ)
+ {
+ *pui16MagnetoZ = (psInst->pui8Data[6] << 8) | psInst->pui8Data[5];
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the magnetometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the AK8963 instance data.
+//! \param pfMagnetoX is a pointer to the value into which the X-axis
+//! magnetometer data is stored.
+//! \param pfMagnetoY is a pointer to the value into which the Y-axis
+//! magnetometer data is stored.
+//! \param pfMagnetoZ is a pointer to the value into which the Z-axis
+//! magnetometer data is stored.
+//!
+//! This function returns the magnetometer data from the most recent data read,
+//! converted into tesla. If any of the output data pointers are \b NULL, the
+//! corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AK8963DataMagnetoGetFloat(tAK8963 *psInst, float *pfMagnetoX,
+ float *pfMagnetoY, float *pfMagnetoZ)
+{
+ float fFactor;
+
+ //
+ // Get the conversion factor for the current data format.
+ //
+ fFactor = g_fAK8963Factors[psInst->ui8BitOutput];
+
+ //
+ // Convert the magnetometer values into floating-point tesla values.
+ //
+ if(pfMagnetoX)
+ {
+ *pfMagnetoX = ((float)(int16_t)((psInst->pui8Data[2] << 8) |
+ psInst->pui8Data[1]) * fFactor);
+ }
+ if(pfMagnetoY)
+ {
+ *pfMagnetoY = ((float)(int16_t)((psInst->pui8Data[4] << 8) |
+ psInst->pui8Data[3]) * fFactor);
+ }
+ if(pfMagnetoZ)
+ {
+ *pfMagnetoZ = ((float)(int16_t)((psInst->pui8Data[6] << 8) |
+ psInst->pui8Data[5]) * fFactor);
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the status registers from the most recent data read.
+//!
+//! \param psInst is a pointer to the AK8963 instance data.
+//! \param pui8Status1 is a pointer to the value into which the ST1 data is
+//! stored.
+//! \param pui8Status2 is a pointer to the value into which the ST2 data is
+//! stored.
+//!
+//! This function returns the magnetometer status registers from the most
+//! recent data read. If any of the output data pointers are \b NULL, the
+//! corresponding data is not be provided.
+//!
+//! Note that the AKM comp routines require ST1 and ST2, so we read them for
+//! that reason.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AK8963DataGetStatus(tAK8963 *psInst, uint_fast8_t *pui8Status1,
+ uint_fast8_t *pui8Status2)
+{
+ //
+ // Return the status registers
+ //
+ if(pui8Status1)
+ {
+ *pui8Status1 = psInst->pui8Data[0];
+ }
+ if(pui8Status2)
+ {
+ *pui8Status2 = psInst->pui8Data[7];
+ }
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/ak8963.h b/sensorlib/ak8963.h new file mode 100644 index 0000000..4be56dd --- /dev/null +++ b/sensorlib/ak8963.h @@ -0,0 +1,160 @@ +//*****************************************************************************
+//
+// ak8963.h - Prototypes for the AK8963 magnetometer driver.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_AK8963_H__
+#define __SENSORLIB_AK8963_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the AK8963 driver.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The pointer to the I2C master interface instance used to communicate
+ // with the AK8963.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The I2C address of the AK8963.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The state of the state machine used while accessing the AK8963.
+ //
+ uint8_t ui8State;
+
+ //
+ // The data output bit width.
+ //
+ uint8_t ui8BitOutput;
+
+ //
+ // The new data output bit width, which is used when a register write
+ // succeeds.
+ //
+ uint8_t ui8NewBitOutput;
+
+ //
+ // The data buffer used for sending/receiving data to/from the AK8963.
+ //
+ uint8_t pui8Data[8];
+
+ //
+ // The function that is called when the current request has completed
+ // processing.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The callback data provided to the callback function.
+ //
+ void *pvCallbackData;
+
+ //
+ // A union of structures that are used for read, write and
+ // read-modify-write operations. Since only one operation can be active at
+ // a time, it is safe to re-use the memory in this manner.
+ //
+ union
+ {
+ //
+ // A buffer used to store the write portion of a register read.
+ //
+ uint8_t pui8Buffer[2];
+
+ //
+ // The write state used to write register values.
+ //
+ tI2CMWrite8 sWriteState;
+
+ //
+ // The read-modify-write state used to modify register values.
+ //
+ tI2CMReadModifyWrite8 sReadModifyWriteState;
+ }
+ uCommand;
+}
+tAK8963;
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern uint_fast8_t AK8963Init(tAK8963 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t AK8963Read(tAK8963 *psInst, uint_fast8_t ui8Reg,
+ uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t AK8963Write(tAK8963 *psInst, uint_fast8_t ui8Reg,
+ const uint8_t *pui8Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t AK8963ReadModifyWrite(tAK8963 *psInst,
+ uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask,
+ uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t AK8963DataRead(tAK8963 *psInst,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern void AK8963DataMagnetoGetRaw(tAK8963 *psInst,
+ uint_fast16_t *pui16MagnetoX,
+ uint_fast16_t *pui16MagnetoY,
+ uint_fast16_t *pui16MagnetoZ);
+extern void AK8963DataMagnetoGetFloat(tAK8963 *psInst, float *pfMagnetoX,
+ float *pfMagnetoY, float *pfMagnetoZ);
+extern void AK8963DataGetStatus(tAK8963 *psInst, uint_fast8_t *pui8Status1,
+ uint_fast8_t *pui8Status2);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_AK8963_H__
diff --git a/sensorlib/ak8975.c b/sensorlib/ak8975.c new file mode 100644 index 0000000..776229c --- /dev/null +++ b/sensorlib/ak8975.c @@ -0,0 +1,558 @@ +//*****************************************************************************
+//
+// ak8975.c - Driver for the AK8975 magnetometer.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <stdint.h>
+#include "sensorlib/hw_ak8975.h"
+#include "sensorlib/i2cm_drv.h"
+#include "sensorlib/ak8975.h"
+
+//*****************************************************************************
+//
+//! \addtogroup ak8975_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The states of the AK8975 state machine.
+//
+//*****************************************************************************
+#define AK8975_STATE_IDLE 0 // State machine is idle
+#define AK8975_STATE_READ 1 // Waiting for read
+#define AK8975_STATE_WRITE 2 // Waiting for write
+#define AK8975_STATE_RMW 3 // Waiting for read-modify-write
+
+//*****************************************************************************
+//
+// Converting sensor data to tesla (0.3 uT per LSB)
+//
+//*****************************************************************************
+#define CONVERT_TO_TESLA 0.0000003
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transations to/from the
+// AK8975 have completed.
+//
+//*****************************************************************************
+static void
+AK8975Callback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tAK8975 *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tAK8975 structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result in a callback to propagate the
+ // error).
+ //
+ if(ui8Status != I2CM_STATUS_SUCCESS)
+ {
+ psInst->ui8State = AK8975_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the AK8975 state machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // All states that trivially transition to IDLE, and all unknown
+ // states.
+ //
+ case AK8975_STATE_READ:
+ case AK8975_STATE_WRITE:
+ case AK8975_STATE_RMW:
+ default:
+ {
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = AK8975_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == AK8975_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the AK8975 driver.
+//!
+//! \param psInst is a pointer to the AK8975 instance data.
+//! \param psI2CInst is a pointer to the I2C master driver instance data.
+//! \param ui8I2CAddr is the I2C address of the AK8975 device.
+//! \param pfnCallback is the function to be called when the initialization has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initializes the AK8975 driver, preparing it for operation.
+//!
+//! \return Returns 1 if the AK8975 driver was successfully initialized and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+AK8975Init(tAK8975 *psInst, tI2CMInstance *psI2CInst, uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Initialize the AK8975 instance structure.
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8I2CAddr;
+ psInst->ui8State = AK8975_STATE_IDLE;
+
+ //
+ // The default settings are ok. Return success and call the callback.
+ //
+ if(pfnCallback)
+ {
+ pfnCallback(pvCallbackData, 0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads data from AK8975 registers.
+//!
+//! \param psInst is a pointer to the AK8975 instance data.
+//! \param ui8Reg is the first register to read.
+//! \param pui8Data is a pointer to the location to store the data that is
+//! read.
+//! \param ui16Count is the number of data bytes to read.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function reads a sequence of data values from consecutive registers in
+//! the AK8975.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+AK8975Read(tAK8975 *psInst, uint_fast8_t ui8Reg, uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the AK8975 driver is not idle (in other words, there
+ // is already an outstanding request to the AK8975).
+ //
+ if(psInst->ui8State != AK8975_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read state.
+ //
+ psInst->ui8State = AK8975_STATE_READ;
+
+ //
+ // Read the requested registers from the AK8975.
+ //
+ psInst->uCommand.pui8Buffer[0] = ui8Reg;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, pui8Data, ui16Count,
+ AK8975Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = AK8975_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Writes data to AK8975 registers.
+//!
+//! \param psInst is a pointer to the AK8975 instance data.
+//! \param ui8Reg is the first register to write.
+//! \param pui8Data is a pointer to the data to write.
+//! \param ui16Count is the number of data bytes to write.
+//! \param pfnCallback is the function to be called when the data has been
+//! written (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function writes a sequence of data values to consecutive registers in
+//! the AK8975. The first byte of the \e pui8Data buffer contains the value to
+//! be written into the \e ui8Reg register, the second value contains the data
+//! to be written into the next register, and so on.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+AK8975Write(tAK8975 *psInst, uint_fast8_t ui8Reg, uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the AK8975 driver is not idle (in other words, there
+ // is already an outstanding request to the AK8975).
+ //
+ if(psInst->ui8State != AK8975_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for write state.
+ //
+ psInst->ui8State = AK8975_STATE_WRITE;
+
+ //
+ // Write the requested registers to the AK8975.
+ //
+ if(I2CMWrite8(&(psInst->uCommand.sWriteState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui8Data, ui16Count, AK8975Callback,
+ psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = AK8975_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of an AK8975 register.
+//!
+//! \param psInst is a pointer to the AK8975 instance data.
+//! \param ui8Reg is the register to modify.
+//! \param ui8Mask is the bit mask that is ANDed with the current register
+//! value.
+//! \param ui8Value is the bit mask that is ORed with the result of the AND
+//! operation.
+//! \param pfnCallback is the function to be called when the data has been
+//! changed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function changes the value of a register in the AK8975 via a
+//! read-modify-write operation, allowing one of the fields to be changed
+//! without disturbing the other fields. The \e ui8Reg register is read, ANDed
+//! with \e ui8Mask, ORed with \e ui8Value, and then written back to the
+//! AK8975.
+//!
+//! \return Returns 1 if the read-modify-write was successfully started and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+AK8975ReadModifyWrite(tAK8975 *psInst, uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask, uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the AK8975 driver is not idle (in other words, there
+ // is already an outstanding request to the AK8975).
+ //
+ if(psInst->ui8State != AK8975_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read-modify-write state.
+ //
+ psInst->ui8State = AK8975_STATE_RMW;
+
+ //
+ // Submit the read-modify-write request to the AK8975.
+ //
+ if(I2CMReadModifyWrite8(&(psInst->uCommand.sReadModifyWriteState),
+ psInst->psI2CInst, psInst->ui8Addr, ui8Reg,
+ ui8Mask, ui8Value, AK8975Callback, psInst) == 0)
+ {
+ //
+ // The I2C read-modify-write failed, so move to the idle state and
+ // return a failure.
+ //
+ psInst->ui8State = AK8975_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads the magnetometer data from the AK8975.
+//!
+//! \param psInst is a pointer to the AK8975 instance data.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read of the AK8975 data registers. When the
+//! read has completed (as indicated by calling the callback function), the new
+//! readings can be obtained via:
+//!
+//! - AK8975DataMagnetoGetRaw()
+//! - AK8975DataMagnetoGetFloat()
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+AK8975DataRead(tAK8975 *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the AK8975 driver is not idle (in other words, there
+ // is already an outstanding request to the AK8975).
+ //
+ if(psInst->ui8State != AK8975_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for data read state.
+ //
+ psInst->ui8State = AK8975_STATE_READ;
+
+ //
+ // Read the data registers from the AK8975.
+ //
+ // ST1 + (HXL + HXH) + (HYL + HYH) + (HZL + HZH) + ST2 = 8 bytes
+ //
+ psInst->pui8Data[0] = AK8975_O_ST1;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr, psInst->pui8Data, 1,
+ psInst->pui8Data, 8, AK8975Callback, psInst) == 0)
+ {
+ //
+ // The I2C read failed, so move to the idle state and return a failure.
+ //
+ psInst->ui8State = AK8975_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Gets the raw magnetometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the AK8975 instance data.
+//! \param pui16MagnetoX is a pointer to the value into which the raw X-axis
+//! magnetometer data is stored.
+//! \param pui16MagnetoY is a pointer to the value into which the raw Y-axis
+//! magnetometer data is stored.
+//! \param pui16MagnetoZ is a pointer to the value into which the raw Z-axis
+//! magnetometer data is stored.
+//!
+//! This function returns the raw magnetometer data from the most recent data
+//! read. The data is not manipulated in any way by the driver. If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AK8975DataMagnetoGetRaw(tAK8975 *psInst, uint_fast16_t *pui16MagnetoX,
+ uint_fast16_t *pui16MagnetoY,
+ uint_fast16_t *pui16MagnetoZ)
+{
+ //
+ // Return the raw magnetometer values.
+ //
+ if(pui16MagnetoX)
+ {
+ *pui16MagnetoX = (psInst->pui8Data[2] << 8) | psInst->pui8Data[1];
+ }
+ if(pui16MagnetoY)
+ {
+ *pui16MagnetoY = (psInst->pui8Data[4] << 8) | psInst->pui8Data[3];
+ }
+ if(pui16MagnetoZ)
+ {
+ *pui16MagnetoZ = (psInst->pui8Data[6] << 8) | psInst->pui8Data[5];
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the magnetometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the AK8975 instance data.
+//! \param pfMagnetoX is a pointer to the value into which the X-axis
+//! magnetometer data is stored.
+//! \param pfMagnetoY is a pointer to the value into which the Y-axis
+//! magnetometer data is stored.
+//! \param pfMagnetoZ is a pointer to the value into which the Z-axis
+//! magnetometer data is stored.
+//!
+//! This function returns the magnetometer data from the most recent data read,
+//! converted into tesla. If any of the output data pointers are
+//! \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AK8975DataMagnetoGetFloat(tAK8975 *psInst, float *pfMagnetoX,
+ float *pfMagnetoY, float *pfMagnetoZ)
+{
+ //
+ // Convert the magnetometer values into floating-point tesla values.
+ //
+ if(pfMagnetoX)
+ {
+ *pfMagnetoX = ((float)(int16_t)((psInst->pui8Data[2] << 8) |
+ psInst->pui8Data[1]) *
+ CONVERT_TO_TESLA);
+ }
+ if(pfMagnetoY)
+ {
+ *pfMagnetoY = ((float)(int16_t)((psInst->pui8Data[4] << 8) |
+ psInst->pui8Data[3]) *
+ CONVERT_TO_TESLA);
+ }
+ if(pfMagnetoZ)
+ {
+ *pfMagnetoZ = ((float)(int16_t)((psInst->pui8Data[6] << 8) |
+ psInst->pui8Data[5]) *
+ CONVERT_TO_TESLA);
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the status registers from the most recent data read.
+//!
+//! \param psInst is a pointer to the AK8975 instance data.
+//! \param pui8Status1 is a pointer to the value into which the ST1 data is
+//! stored.
+//! \param pui8Status2 is a pointer to the value into which the ST2 data is
+//! stored.
+//!
+//! This function returns the magnetometer status registers from the most
+//! recent data read. If any of the output data pointers are \b NULL, the
+//! corresponding data is not provided.
+//!
+//! Note that the AKM comp routines require ST1 and ST2, so we read
+//! them for that reason.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+AK8975DataGetStatus(tAK8975 *psInst, uint_fast8_t *pui8Status1,
+ uint_fast8_t *pui8Status2)
+{
+ //
+ // Return the status registers
+ //
+ if(pui8Status1)
+ {
+ *pui8Status1 = psInst->pui8Data[0];
+ }
+ if(pui8Status2)
+ {
+ *pui8Status2 = psInst->pui8Data[7];
+ }
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/ak8975.h b/sensorlib/ak8975.h new file mode 100644 index 0000000..97c2893 --- /dev/null +++ b/sensorlib/ak8975.h @@ -0,0 +1,148 @@ +//*****************************************************************************
+//
+// ak8975.h - Prototypes for the AK8975 magnetometer driver.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_AK8975_H__
+#define __SENSORLIB_AK8975_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the AK8975 driver.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The pointer to the I2C master interface instance used to communicate
+ // with the AK8975.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The I2C address of the AK8975.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The state of the state machine used while accessing the AK8975.
+ //
+ uint8_t ui8State;
+
+ //
+ // The data buffer used for sending/receiving data to/from the AK8975.
+ //
+ uint8_t pui8Data[8];
+
+ //
+ // The function that is called when the current request has completed
+ // processing.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The callback data provided to the callback function.
+ //
+ void *pvCallbackData;
+
+ //
+ // A union of structures that are used for read, write and
+ // read-modify-write operations. Since only one operation can be active at
+ // a time, it is safe to re-use the memory in this manner.
+ //
+ union
+ {
+ //
+ // A buffer used to store the write portion of a register read.
+ //
+ uint8_t pui8Buffer[2];
+
+ //
+ // The write state used to write register values.
+ //
+ tI2CMWrite8 sWriteState;
+
+ //
+ // The read-modify-write state used to modify register values.
+ //
+ tI2CMReadModifyWrite8 sReadModifyWriteState;
+ }
+ uCommand;
+}
+tAK8975;
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern uint_fast8_t AK8975Init(tAK8975 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t AK8975Read(tAK8975 *psInst, uint_fast8_t ui8Reg,
+ uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t AK8975Write(tAK8975 *psInst, uint_fast8_t ui8Reg,
+ uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t AK8975ReadModifyWrite(tAK8975 *psInst,
+ uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask,
+ uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t AK8975DataRead(tAK8975 *psInst,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern void AK8975DataMagnetoGetRaw(tAK8975 *psInst,
+ uint_fast16_t *pui16MagnetoX,
+ uint_fast16_t *pui16MagnetoY,
+ uint_fast16_t *pui16MagnetoZ);
+extern void AK8975DataMagnetoGetFloat(tAK8975 *psInst, float *pfMagnetoX,
+ float *pfMagnetoY, float *pfMagnetoZ);
+extern void AK8975DataGetStatus(tAK8975 *psInst, uint_fast8_t *pui8Status1,
+ uint_fast8_t *pui8Status2);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_AK8975_H__
diff --git a/sensorlib/bmp180.c b/sensorlib/bmp180.c new file mode 100644 index 0000000..a25701e --- /dev/null +++ b/sensorlib/bmp180.c @@ -0,0 +1,919 @@ +//*****************************************************************************
+//
+// bmp180.c - Driver for the BMP180 pressure sensor.
+//
+// Copyright (c) 2012-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <math.h>
+#include <stdint.h>
+#include "sensorlib/hw_bmp180.h"
+#include "sensorlib/i2cm_drv.h"
+#include "sensorlib/bmp180.h"
+
+//*****************************************************************************
+//
+//! \addtogroup bmp180_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The states of the BMP180 state machine.
+//
+//*****************************************************************************
+#define BMP180_STATE_IDLE 0 // State machine is idle
+#define BMP180_STATE_INIT1 1 // Waiting for initialization 1
+#define BMP180_STATE_INIT2 2 // Waiting for initialization 2
+#define BMP180_STATE_READ 3 // Waiting for read
+#define BMP180_STATE_WRITE 4 // Waiting for write
+#define BMP180_STATE_RMW 5 // Waiting for read-modify-write
+#define BMP180_STATE_REQ_TEMP 6 // Requested temperature
+#define BMP180_STATE_WAIT_TEMP 7 // Waiting for temperature ready
+#define BMP180_STATE_READ_TEMP 8 // Reading temperature value
+#define BMP180_STATE_REQ_PRES 9 // Requested pressure
+#define BMP180_STATE_WAIT_PRES 10 // Waiting for pressure ready
+#define BMP180_STATE_READ_PRES 11 // Reading pressure value
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transations to/from the
+// BMP180 have completed.
+//
+//*****************************************************************************
+static void
+BMP180Callback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tBMP180 *psInst;
+ uint16_t ui16ReadVerify;
+
+ //
+ // Convert the instance data into a pointer to a tBMP180 structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result in a callback to propagate the
+ // error).
+ //
+ if(ui8Status != I2CM_STATUS_SUCCESS)
+ {
+ psInst->ui8State = BMP180_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the BMP180 state machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // All states that trivially transition to IDLE, and all unknown
+ // states.
+ //
+ case BMP180_STATE_READ:
+ case BMP180_STATE_READ_PRES:
+ default:
+ {
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = BMP180_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // The first step of initialization has just completed.
+ //
+ case BMP180_STATE_INIT1:
+ {
+ //
+ // Read the calibration data from the BMP180.
+ //
+ psInst->pui8Data[0] = BMP180_O_AC1_MSB;
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr, psInst->pui8Data, 1,
+ psInst->uCommand.pui8Buffer, 22, BMP180Callback, psInst);
+
+ //
+ // Move to the wait for initialization step 2 state.
+ //
+ psInst->ui8State = BMP180_STATE_INIT2;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // The second step of initialization has just completed.
+ //
+ case BMP180_STATE_INIT2:
+ {
+ //
+ // Data communication is checked by verifying that the calibration
+ // data is neither 0 nor 0xFFFF. This is used to check that reset
+ // is complete and the part is ready. It also verifies that we
+ // have valid calibration data before proceeding.
+ //
+ ui16ReadVerify = psInst->uCommand.pui8Buffer[0];
+ ui16ReadVerify <<= 8;
+ ui16ReadVerify |= psInst->uCommand.pui8Buffer[1];
+ if((ui16ReadVerify == 0) || (ui16ReadVerify == 0xFFFF))
+ {
+ //
+ // Reread the calibration data from the BMP180.
+ //
+ psInst->pui8Data[0] = BMP180_O_AC1_MSB;
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr, psInst->pui8Data,
+ 1, psInst->uCommand.pui8Buffer, 22, BMP180Callback,
+ psInst);
+ }
+ else
+ {
+ //
+ // Extract the calibration data from the data that was read.
+ //
+ psInst->i16AC1 =
+ (int16_t)((psInst->uCommand.pui8Buffer[0] << 8) |
+ psInst->uCommand.pui8Buffer[1]);
+ psInst->i16AC2 =
+ (int16_t)((psInst->uCommand.pui8Buffer[2] << 8) |
+ psInst->uCommand.pui8Buffer[3]);
+ psInst->i16AC3 =
+ (int16_t)((psInst->uCommand.pui8Buffer[4] << 8) |
+ psInst->uCommand.pui8Buffer[5]);
+ psInst->ui16AC4 =
+ (uint16_t)((psInst->uCommand.pui8Buffer[6] << 8) |
+ psInst->uCommand.pui8Buffer[7]);
+ psInst->ui16AC5 =
+ (uint16_t)((psInst->uCommand.pui8Buffer[8] << 8) |
+ psInst->uCommand.pui8Buffer[9]);
+ psInst->ui16AC6 =
+ (uint16_t)((psInst->uCommand.pui8Buffer[10] << 8) |
+ psInst->uCommand.pui8Buffer[11]);
+ psInst->i16B1 =
+ (int16_t)((psInst->uCommand.pui8Buffer[12] << 8) |
+ psInst->uCommand.pui8Buffer[13]);
+ psInst->i16B2 =
+ (int16_t)((psInst->uCommand.pui8Buffer[14] << 8) |
+ psInst->uCommand.pui8Buffer[15]);
+ psInst->i16MC =
+ (int16_t)((psInst->uCommand.pui8Buffer[18] << 8) |
+ psInst->uCommand.pui8Buffer[19]);
+ psInst->i16MD =
+ (int16_t)((psInst->uCommand.pui8Buffer[20] << 8) |
+ psInst->uCommand.pui8Buffer[21]);
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = BMP180_STATE_IDLE;
+ }
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // A write has just completed.
+ //
+ case BMP180_STATE_WRITE:
+ {
+ //
+ // Set the mode to the new mode. If the register was not modified,
+ // the values will be the same so this has no effect.
+ //
+ psInst->ui8Mode = psInst->ui8NewMode;
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = BMP180_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // A read-modify-write has just completed.
+ //
+ case BMP180_STATE_RMW:
+ {
+ //
+ // See if the CTRL_MEAS register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ BMP180_O_CTRL_MEAS)
+ {
+ //
+ // Extract the measurement mode from the CTRL_MEAS register
+ // value.
+ //
+ psInst->ui8Mode =
+ (psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ BMP180_CTRL_MEAS_OSS_M);
+ }
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = BMP180_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // The temperature has been requested.
+ //
+ case BMP180_STATE_REQ_TEMP:
+ {
+ //
+ // Read the control register to see if the temperature reading is
+ // available.
+ //
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1,
+ psInst->uCommand.pui8Buffer + 1, 1, BMP180Callback,
+ psInst);
+
+ //
+ // Move to the wait for temperature state.
+ //
+ psInst->ui8State = BMP180_STATE_WAIT_TEMP;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // Waiting for the temperature reading to be available.
+ //
+ case BMP180_STATE_WAIT_TEMP:
+ {
+ //
+ // See if the temperature reading is available.
+ //
+ if(psInst->uCommand.pui8Buffer[1] & BMP180_CTRL_MEAS_SCO)
+ {
+ //
+ // The temperature reading is not ready yet, so read the
+ // control register again.
+ //
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1,
+ psInst->uCommand.pui8Buffer + 1, 1, BMP180Callback,
+ psInst);
+ }
+ else
+ {
+ //
+ // The temperature reading is ready, so read it now.
+ //
+ psInst->uCommand.pui8Buffer[0] = BMP180_O_OUT_MSB;
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 2,
+ BMP180Callback, psInst);
+
+ //
+ // Move to the temperature reading state.
+ //
+ psInst->ui8State = BMP180_STATE_READ_TEMP;
+ }
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // The temperature reading has been retrieved.
+ //
+ case BMP180_STATE_READ_TEMP:
+ {
+ //
+ // Request the pressure reading from the BMP180.
+ //
+ psInst->uCommand.pui8Buffer[0] = BMP180_O_CTRL_MEAS;
+ psInst->uCommand.pui8Buffer[1] = (BMP180_CTRL_MEAS_SCO |
+ BMP180_CTRL_MEAS_PRESSURE |
+ psInst->ui8Mode);
+ I2CMWrite(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 2, BMP180Callback, psInst);
+
+ //
+ // Move to the pressure reading request state.
+ //
+ psInst->ui8State = BMP180_STATE_REQ_PRES;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // The pressure has been requested.
+ //
+ case BMP180_STATE_REQ_PRES:
+ {
+ //
+ // Read the control register to see if the pressure reading is
+ // available.
+ //
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1,
+ psInst->uCommand.pui8Buffer + 1, 1, BMP180Callback,
+ psInst);
+
+ //
+ // Move to the wait for pressure state.
+ //
+ psInst->ui8State = BMP180_STATE_WAIT_PRES;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // Waiting for the pressure reading to be available.
+ //
+ case BMP180_STATE_WAIT_PRES:
+ {
+ //
+ // See if the pressure reading is available.
+ //
+ if(psInst->uCommand.pui8Buffer[1] & BMP180_CTRL_MEAS_SCO)
+ {
+ //
+ // The pressure reading is not ready yet, so read the control
+ // register again.
+ //
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1,
+ psInst->uCommand.pui8Buffer + 1, 1, BMP180Callback,
+ psInst);
+ }
+ else
+ {
+ //
+ // The pressure reading is ready, so read it now.
+ //
+ psInst->uCommand.pui8Buffer[0] = BMP180_O_OUT_MSB;
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data + 2,
+ 3, BMP180Callback, psInst);
+
+ //
+ // Move to the pressure reading state.
+ //
+ psInst->ui8State = BMP180_STATE_READ_PRES;
+ }
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == BMP180_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the BMP180 driver.
+//!
+//! \param psInst is a pointer to the BMP180 instance data.
+//! \param psI2CInst is a pointer to the I2C master driver instance data.
+//! \param ui8I2CAddr is the I2C address of the BMP180 device.
+//! \param pfnCallback is the function to be called when the initialization has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initializes the BMP180 driver, preparing it for operation.
+//!
+//! \return Returns 1 if the BMP180 driver was successfully initialized and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+BMP180Init(tBMP180 *psInst, tI2CMInstance *psI2CInst, uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Initialize the BMP180 instance structure.
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8I2CAddr;
+ psInst->ui8State = BMP180_STATE_INIT1;
+ psInst->ui8Mode = 0;
+ psInst->ui8NewMode = 0;
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Perform a soft reset of the BMP180.
+ //
+ psInst->pui8Data[0] = BMP180_O_SOFT_RESET;
+ psInst->pui8Data[1] = BMP180_SOFT_RESET_VALUE;
+ if(I2CMWrite(psI2CInst, ui8I2CAddr, psInst->pui8Data, 2, BMP180Callback,
+ psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = BMP180_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads data from BMP180 registers.
+//!
+//! \param psInst is a pointer to the BMP180 instance data.
+//! \param ui8Reg is the first register to read.
+//! \param pui8Data is a pointer to the location to store the data that is
+//! read.
+//! \param ui16Count is the number of data bytes to read.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function reads a sequence of data values from consecutive registers in
+//! the BMP180.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+BMP180Read(tBMP180 *psInst, uint_fast8_t ui8Reg, uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the BMP180 driver is not idle (in other words, there
+ // is already an outstanding request to the BMP180).
+ //
+ if(psInst->ui8State != BMP180_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read state.
+ //
+ psInst->ui8State = BMP180_STATE_READ;
+
+ //
+ // Read the requested registers from the BMP180.
+ //
+ psInst->uCommand.pui8Buffer[0] = ui8Reg;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, pui8Data, ui16Count,
+ BMP180Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = BMP180_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Writes data to BMP180 registers.
+//!
+//! \param psInst is a pointer to the BMP180 instance data.
+//! \param ui8Reg is the first register to write.
+//! \param pui8Data is a pointer to the data to write.
+//! \param ui16Count is the number of data bytes to write.
+//! \param pfnCallback is the function to be called when the data has been
+//! written (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function writes a sequence of data values to consecutive registers in
+//! the BMP180. The first byte of the \e pui8Data buffer contains the value to
+//! be written into the \e ui8Reg register, the second value contains the data
+//! to be written into the next register, and so on.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+BMP180Write(tBMP180 *psInst, uint_fast8_t ui8Reg, uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the BMP180 driver is not idle (in other words, there
+ // is already an outstanding request to the BMP180).
+ //
+ if(psInst->ui8State != BMP180_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // See if the CTRL_MEAS register is being written.
+ //
+ if((ui8Reg <= BMP180_O_CTRL_MEAS) &&
+ ((ui8Reg + ui16Count) > BMP180_O_CTRL_MEAS))
+ {
+ //
+ // Extract the measurement mode from the CTRL_MEAS register value.
+ //
+ psInst->ui8NewMode = (pui8Data[ui8Reg - BMP180_O_CTRL_MEAS] &
+ BMP180_CTRL_MEAS_OSS_M);
+ }
+
+ //
+ // Move the state machine to the wait for write state.
+ //
+ psInst->ui8State = BMP180_STATE_WRITE;
+
+ //
+ // Write the requested registers to the BMP180.
+ //
+ if(I2CMWrite8(&(psInst->uCommand.sWriteState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui8Data, ui16Count, BMP180Callback,
+ psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = BMP180_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of a BMP180 register.
+//!
+//! \param psInst is a pointer to the BMP180 instance data.
+//! \param ui8Reg is the register to modify.
+//! \param ui8Mask is the bit mask that is ANDed with the current register
+//! value.
+//! \param ui8Value is the bit mask that is ORed with the result of the AND
+//! operation.
+//! \param pfnCallback is the function to be called when the data has been
+//! changed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function changes the value of a register in the BMP180 via a
+//! read-modify-write operation, allowing one of the fields to be changed
+//! without disturbing the other fields. The \e ui8Reg register is read, ANDed
+//! with \e ui8Mask, ORed with \e ui8Value, and then written back to the
+//! BMP180.
+//!
+//! \return Returns 1 if the read-modify-write was successfully started and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+BMP180ReadModifyWrite(tBMP180 *psInst, uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask, uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the BMP180 driver is not idle (in other words, there
+ // is already an outstanding request to the BMP180).
+ //
+ if(psInst->ui8State != BMP180_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read-modify-write state.
+ //
+ psInst->ui8State = BMP180_STATE_RMW;
+
+ //
+ // Submit the read-modify-write request to the BMP180.
+ //
+ if(I2CMReadModifyWrite8(&(psInst->uCommand.sReadModifyWriteState),
+ psInst->psI2CInst, psInst->ui8Addr, ui8Reg,
+ ui8Mask, ui8Value, BMP180Callback, psInst) == 0)
+ {
+ //
+ // The I2C read-modify-write failed, so move to the idle state and
+ // return a failure.
+ //
+ psInst->ui8State = BMP180_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads the pressure data from the BMP180.
+//!
+//! \param psInst is a pointer to the BMP180 instance data.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read of the BMP180 data registers. When the
+//! read has completed (as indicated by calling the callback function), the
+//! new temperature and pressure readings can be obtained via:
+//!
+//! - BMP180DataPressureGetRaw()
+//! - BMP180DataPressureGetFloat()
+//! - BMP180DataTemperatureGetRaw()
+//! - BMP180DataTemperatureGetFloat()
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+BMP180DataRead(tBMP180 *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the BMP180 driver is not idle (in other words, there
+ // is already an outstanding request to the BMP180).
+ //
+ if(psInst->ui8State != BMP180_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the temperature reading request state.
+ //
+ psInst->ui8State = BMP180_STATE_REQ_TEMP;
+
+ //
+ // Request the temperature reading from the BMP180.
+ //
+ psInst->uCommand.pui8Buffer[0] = BMP180_O_CTRL_MEAS;
+ psInst->uCommand.pui8Buffer[1] = (BMP180_CTRL_MEAS_SCO |
+ BMP180_CTRL_MEAS_TEMPERATURE);
+ if(I2CMWrite(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 2, BMP180Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = BMP180_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Gets the raw pressure data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BMP180 instance data.
+//! \param pui32Pressure is a pointer to the value into which the raw pressure
+//! data is stored.
+//!
+//! This function returns the raw pressure data from the most recent data read.
+//! The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BMP180DataPressureGetRaw(tBMP180 *psInst, uint_fast32_t *pui32Pressure)
+{
+ //
+ // Return the raw pressure value.
+ //
+ *pui32Pressure = ((psInst->pui8Data[2] << 16) |
+ (psInst->pui8Data[3] << 8) |
+ (psInst->pui8Data[4] & BMP180_OUT_XLSB_M));
+}
+
+//*****************************************************************************
+//
+//! Gets the pressure data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BMP180 instance data.
+//! \param pfPressure is a pointer to the value into which the pressure data is
+//! stored.
+//!
+//! This function returns the pressure data from the most recent data read,
+//! converted into pascals.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BMP180DataPressureGetFloat(tBMP180 *psInst, float *pfPressure)
+{
+ float fUT, fUP, fX1, fX2, fX3, fB3, fB4, fB5, fB6, fB7, fP;
+ int_fast8_t i8Oss;
+
+ //
+ // Get the oversampling ratio.
+ //
+ i8Oss = psInst->ui8Mode >> BMP180_CTRL_MEAS_OSS_S;
+
+ //
+ // Retrieve the uncompensated temperature and pressure.
+ //
+ fUT = (float)(uint16_t)((psInst->pui8Data[0] << 8) |
+ psInst->pui8Data[1]);
+ fUP = ((float)(int32_t)((psInst->pui8Data[2] << 16) |
+ (psInst->pui8Data[3] << 8) |
+ (psInst->pui8Data[4] & BMP180_OUT_XLSB_M)) /
+ (1 << (8 - i8Oss)));
+
+ //
+ // Calculate the true temperature.
+ //
+ fX1 = ((fUT - (float)psInst->ui16AC6) * (float)psInst->ui16AC5) / 32768.f;
+ fX2 = ((float)psInst->i16MC * 2048.f) / (fX1 + (float)psInst->i16MD);
+ fB5 = fX1 + fX2;
+
+ //
+ // Calculate the true pressure.
+ //
+ fB6 = fB5 - 4000;
+ fX1 = ((float)psInst->i16B2 * ((fB6 * fB6) / 4096)) / 2048;
+ fX2 = ((float)psInst->i16AC2 * fB6) / 2048;
+ fX3 = fX1 + fX2;
+ fB3 = ((((float)psInst->i16AC1 * 4) + fX3) * (1 << i8Oss)) / 4;
+ fX1 = ((float)psInst->i16AC3 * fB6) / 8192;
+ fX2 = ((float)psInst->i16B1 * ((fB6 * fB6) / 4096)) / 65536;
+ fX3 = (fX1 + fX2) / 4;
+ fB4 = (float)psInst->ui16AC4 * ((fX3 / 32768) + 1);
+ fB7 = (fUP - fB3) * (50000 >> i8Oss);
+ fP = (fB7 * 2) / fB4;
+ fX1 = (fP / 256) * (fP / 256);
+ fX1 = (fX1 * 3038) / 65536;
+ fX2 = (fP * -7357) / 65536;
+ fP += (fX1 + fX2 + 3791) / 16;
+ *pfPressure = fP;
+}
+
+//*****************************************************************************
+//
+//! Gets the raw temperature data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BMP180 instance data.
+//! \param pui16Temperature is a pointer to the value into which the raw
+//! temperature data is stored.
+//!
+//! This function returns the raw temperature data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BMP180DataTemperatureGetRaw(tBMP180 *psInst, uint_fast16_t *pui16Temperature)
+{
+ //
+ // Return the raw temperature value.
+ //
+ *pui16Temperature = (psInst->pui8Data[0] << 8) | psInst->pui8Data[1];
+}
+
+//*****************************************************************************
+//
+//! Gets the temperature data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BMP180 instance data.
+//! \param pfTemperature is a pointer to the value into which the temperature
+//! data is stored.
+//!
+//! This function returns the temperature data from the most recent data read,
+//! converted into Celsius.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BMP180DataTemperatureGetFloat(tBMP180 *psInst, float *pfTemperature)
+{
+ float fUT, fX1, fX2, fB5;
+
+ //
+ // Get the uncompensated temperature.
+ //
+ fUT = (float)(uint16_t)((psInst->pui8Data[0] << 8) |
+ psInst->pui8Data[1]);
+
+ //
+ // Calculate the true temperature.
+ //
+ fX1 = ((fUT - (float)psInst->ui16AC6) * (float)psInst->ui16AC5) / 32768.f;
+ fX2 = ((float)psInst->i16MC * 2048.f) / (fX1 + (float)psInst->i16MD);
+ fB5 = fX1 + fX2;
+ *pfTemperature = fB5 / 160.f;
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/bmp180.h b/sensorlib/bmp180.h new file mode 100644 index 0000000..c56b4df --- /dev/null +++ b/sensorlib/bmp180.h @@ -0,0 +1,207 @@ +//*****************************************************************************
+//
+// bmp180.h - Prototypes for the BMP180 pressure sensor driver.
+//
+// Copyright (c) 2012-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_BMP180_H__
+#define __SENSORLIB_BMP180_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the BMP180 driver.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The pointer to the I2C master interface instance used to communicate
+ // with the BMP180.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The I2C address of the BMP180.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The state of the state machine used while accessing the BMP180.
+ //
+ uint8_t ui8State;
+
+ //
+ // The sampling mode to be used by the BMP180.
+ //
+ uint8_t ui8Mode;
+
+ //
+ // The new sampling mode, which is used when a register write succeeds.
+ //
+ uint8_t ui8NewMode;
+
+ //
+ // The AC1 calibration from the BMP180.
+ //
+ int16_t i16AC1;
+
+ //
+ // The AC2 calibration from the BMP180.
+ //
+ int16_t i16AC2;
+
+ //
+ // The AC3 calibration from the BMP180.
+ //
+ int16_t i16AC3;
+
+ //
+ // The AC4 calibration from the BMP180.
+ //
+ uint16_t ui16AC4;
+
+ //
+ // The AC5 calibration from the BMP180.
+ //
+ uint16_t ui16AC5;
+
+ //
+ // The AC6 calibration from the BMP180.
+ //
+ uint16_t ui16AC6;
+
+ //
+ // The B1 calibration from the BMP180.
+ //
+ int16_t i16B1;
+
+ //
+ // The B2 calibration from the BMP180.
+ //
+ int16_t i16B2;
+
+ //
+ // The MC calibration from the BMP180.
+ //
+ int16_t i16MC;
+
+ //
+ // The MD calibration from the BMP180.
+ //
+ int16_t i16MD;
+
+ //
+ // The data buffer used for sending/receiving data to/from the BMP180.
+ //
+ uint8_t pui8Data[5];
+
+ //
+ // The function that is called when the current request has completed
+ // processing.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The pointer provided to the callback function.
+ //
+ void *pvCallbackData;
+
+ //
+ // A union of structures that are used for read, write and
+ // read-modify-write operations. Since only one operation can be active at
+ // a time, it is safe to re-use the memory in this manner.
+ //
+ union
+ {
+ //
+ // A buffer used to store the write portion of a register read. This
+ // is also used to read back the calibration data from the device.
+ //
+ uint8_t pui8Buffer[22];
+
+ //
+ // The write state used to write register values.
+ //
+ tI2CMWrite8 sWriteState;
+
+ //
+ // The read-modify-write state used to modify register values.
+ //
+ tI2CMReadModifyWrite8 sReadModifyWriteState;
+ }
+ uCommand;
+}
+tBMP180;
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern uint_fast8_t BMP180Init(tBMP180 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t BMP180Read(tBMP180 *psInst, uint_fast8_t ui8Reg,
+ uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t BMP180Write(tBMP180 *psInst, uint_fast8_t ui8Reg,
+ uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t BMP180ReadModifyWrite(tBMP180 *psInst, uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask,
+ uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t BMP180DataRead(tBMP180 *psInst,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern void BMP180DataPressureGetRaw(tBMP180 *psInst,
+ uint_fast32_t *pui32Pressure);
+extern void BMP180DataPressureGetFloat(tBMP180 *psInst, float *pfPressure);
+extern void BMP180DataTemperatureGetRaw(tBMP180 *psInst,
+ uint_fast16_t *pui16Temperature);
+extern void BMP180DataTemperatureGetFloat(tBMP180 *psInst,
+ float *pfTemperature);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_BMP180_H__
diff --git a/sensorlib/bq27510g3.c b/sensorlib/bq27510g3.c new file mode 100644 index 0000000..b9453b3 --- /dev/null +++ b/sensorlib/bq27510g3.c @@ -0,0 +1,1398 @@ +//*****************************************************************************
+//
+// bq27510g3.c - Driver for the TI BQ27510G3 Battery Fuel Gauge
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <math.h>
+#include <stdint.h>
+#include "sensorlib/hw_bq27510g3.h"
+#include "sensorlib/i2cm_drv.h"
+#include "sensorlib/bq27510g3.h"
+
+//*****************************************************************************
+//
+//! \addtogroup bq27510g3_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The states of the BQ27510G3 state machine.
+//
+//*****************************************************************************
+#define BQ27510G3_STATE_IDLE 0
+#define BQ27510G3_STATE_INIT 1
+#define BQ27510G3_STATE_READ 2
+#define BQ27510G3_STATE_WRITE 3
+#define BQ27510G3_STATE_RMW 4
+#define BQ27510G3_STATE_READ_DATA_1 5
+#define BQ27510G3_STATE_READ_DATA_2 6
+#define BQ27510G3_STATE_READ_DATA_3 7
+
+//*****************************************************************************
+//
+// The constants used to calculate object temperature.
+//
+//*****************************************************************************
+#define T_REF 273
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transactions to/from the
+// BQ27510G3 have completed.
+//
+//*****************************************************************************
+static void
+BQ27510G3Callback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tBQ27510G3 *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tBQ27510G3 structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result in a callback to propagate the
+ // error).
+ //
+ if(ui8Status != I2CM_STATUS_SUCCESS)
+ {
+ psInst->ui8State = BQ27510G3_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the BQ27510G3 state machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // The first data read state, has finished setup and trigger data read
+ // state 2.
+ //
+ case BQ27510G3_STATE_READ_DATA_1:
+ {
+ //
+ // Move the state machine to the next read state.
+ //
+ psInst->ui8State = BQ27510G3_STATE_READ_DATA_2;
+
+ //
+ // Read the requested data from the BQ27510G3.
+ //
+ psInst->uCommand.pui8Buffer[0] = BQ27510G3_O_NOM_AV_CAP_LSB;
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data + 6,
+ 24, BQ27510G3Callback, psInst);
+
+ //
+ // break
+ //
+ break;
+ }
+
+ //
+ // The 2nd data read state, has finished setup and trigger data read
+ // state 3. Read state 3 is the final state and when done will return
+ // to idle and trigger the application level callback.
+ //
+ case BQ27510G3_STATE_READ_DATA_2:
+ {
+ //
+ // Move the state machine to the next read state.
+ //
+ psInst->ui8State = BQ27510G3_STATE_READ_DATA_3;
+
+ //
+ // Read the requested data from the BQ27510G3.
+ //
+ psInst->uCommand.pui8Buffer[0] = BQ27510G3_O_INT_TEMP_LSB;
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data + 30,
+ 2, BQ27510G3Callback, psInst);
+
+ //
+ // break
+ //
+ break;
+ }
+
+ //
+ // All states that trivially transition to IDLE, and all unknown
+ // states.
+ //
+ case BQ27510G3_STATE_INIT:
+ case BQ27510G3_STATE_READ:
+ case BQ27510G3_STATE_WRITE:
+ case BQ27510G3_STATE_READ_DATA_3:
+ case BQ27510G3_STATE_RMW:
+ default:
+ {
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = BQ27510G3_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == BQ27510G3_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the BQ27510G3 driver.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param psI2CInst is a pointer to the I2C driver instance data.
+//! \param ui8I2CAddr is the I2C address of the BQ27510G3 device.
+//! \param pfnCallback is the function to be called when the initialization has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initializes the BQ27510G3 driver, preparing it for operation.
+//!
+//! \return Returns 1 if the BQ27510G3 driver was successfully initialized and
+//! 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+BQ27510G3Init(tBQ27510G3 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Initialize the BQ27510G3 instance structure
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8I2CAddr;
+ psInst->ui8State = BQ27510G3_STATE_IDLE;
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // The default settings are ok. Return success and call the callback.
+ //
+ if(pfnCallback)
+ {
+ pfnCallback(pvCallbackData, 0);
+ }
+
+ //
+ // Success
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads data from BQ27510G3 registers.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param ui8Reg is the first register to read.
+//! \param pui16Data is a pointer to the location to store the data that is
+//! read.
+//! \param ui16Count the number of register values to read.
+//! \param pfnCallback is the function to be called when data read is complete
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function reads a sequence of data values from consecutive registers in
+//! the BQ27510G3.
+//!
+//! \note The BQ27510G3 does not auto-increment the register pointer, so reads
+//! of more than one value returns garbage for the subsequent values.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+BQ27510G3Read(tBQ27510G3 *psInst, uint_fast8_t ui8Reg, uint16_t *pui16Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the BQ27510G3 driver is not idle (in other words,
+ // there is already an outstanding request to the BQ27510G3).
+ //
+ if(psInst->ui8State != BQ27510G3_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read state.
+ //
+ psInst->ui8State = BQ27510G3_STATE_READ;
+
+ //
+ // Read the requested registers from the BQ27510G3.
+ //
+ if(I2CMRead16BE(&(psInst->uCommand.sReadState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui16Data, ui16Count,
+ BQ27510G3Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = BQ27510G3_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Writes data to BQ27510G3 registers.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param ui8Reg is the first register to write.
+//! \param pui16Data is a pointer to the 16-bit register data to write.
+//! \param ui16Count is the number of 16-bit registers to write.
+//! \param pfnCallback is the function to be called when the data has been
+//! written (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function writes a sequence of data values to consecutive registers in
+//! the BQ27510G3. The first value in the \e pui16Data buffer contains the
+//! data to be written into the \e ui8Reg register, the second value contains
+//! the data to be written into the next register, and so on.
+//!
+//! \note The BQ27510G3 does not auto-increment the register pointer, so writes
+//! of more than one register are rejected by the BQ27510G3.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+BQ27510G3Write(tBQ27510G3 *psInst, uint_fast8_t ui8Reg,
+ const uint16_t *pui16Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the BQ27510G3 driver is not idle (in other words,
+ // there is already an outstanding request to the BQ27510G3).
+ //
+ if(psInst->ui8State != BQ27510G3_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for write state.
+ //
+ psInst->ui8State = BQ27510G3_STATE_WRITE;
+
+ //
+ // Write the requested registers to the BQ27510G3.
+ //
+ if(I2CMWrite16BE(&(psInst->uCommand.sWriteState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui16Data, ui16Count,
+ BQ27510G3Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = BQ27510G3_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of a BQ27510G3 register.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param ui8Reg is the register offset to read modify and write
+//! \param ui16Mask is the bit mask that is ANDed with the current register
+//! value.
+//! \param ui16Value is the bit mask that is ORed with the result of the AND
+//! operation.
+//! \param pfnCallback is the function to be called when the data has been
+//! changed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function changes the value of a register in the BQ27510G3 via a
+//! read-modify-write operation, allowing one of the fields to be changed
+//! without disturbing the other fields. The \e ui8Reg register is read, ANDed
+//! with \e ui16Mask, ORed with \e ui16Value, and then written back to the
+//! BQ27510G3.
+//!
+//! \return Returns 1 if the read-modify-write was successfully started and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+BQ27510G3ReadModifyWrite(tBQ27510G3 *psInst, uint_fast8_t ui8Reg,
+ uint_fast16_t ui16Mask, uint_fast16_t ui16Value,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the BQ27510G3 driver is not idle (in other words,
+ // there is already an outstanding request to the BQ27510G3).
+ //
+ if(psInst->ui8State != BQ27510G3_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read-modify-write state.
+ //
+ psInst->ui8State = BQ27510G3_STATE_RMW;
+
+ //
+ // Submit the read-modify-write request to the BQ27510G3.
+ //
+ if(I2CMReadModifyWrite16BE(&(psInst->uCommand.sReadModifyWriteState),
+ psInst->psI2CInst, psInst->ui8Addr, ui8Reg,
+ ui16Mask, ui16Value, BQ27510G3Callback,
+ psInst) == 0)
+ {
+ //
+ // The I2C read-modify-write failed, so move to the idle state and
+ // return a failure.
+ //
+ psInst->ui8State = BQ27510G3_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Performs a read of a BQ27510G3 data register.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read of the BQ27510G3 data registers. When the
+//! read has completed (as indicated by calling the callback function), the new
+//! readings can be obtained via functions like:
+//!
+//! - BQ27510G3DataTCurrentInstantaneousGetRaw()
+//! - BQ27510G3DataTCurrentInstantaneousGetFloat()
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+BQ27510G3DataRead(tBQ27510G3 *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the BQ27510G3 driver is not idle (in other words,
+ // there is already an outstanding request to the BQ27510G3).
+ //
+ if(psInst->ui8State != BQ27510G3_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the first read state. Reads are done in three
+ // parts based on address ranges of the information being read.
+ //
+ psInst->ui8State = BQ27510G3_STATE_READ_DATA_1;
+
+ //
+ // Read the requested data from the BQ27510G3.
+ //
+ psInst->uCommand.pui8Buffer[0] = BQ27510G3_O_AT_RATE_TTE_LSB;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 6,
+ BQ27510G3Callback, psInst) == 0)
+ {
+ //
+ // The I2C read failed, so move to the idle state and return a failure.
+ //
+ psInst->ui8State = BQ27510G3_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Gets the raw "at rate time to empty" data.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pi16Data is a pointer to the value into which the raw data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataAtRateTimeToEmptyGetRaw(tBQ27510G3 *psInst, int16_t *pi16Data)
+{
+ //
+ // Return the raw data value.
+ //
+ *pi16Data = ((int16_t)psInst->pui8Data[1] << 8) | psInst->pui8Data[0];
+}
+
+//*****************************************************************************
+//
+//! Gets the "at rate time to empty" data as a floating point value.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfData is a pointer to the value into which the data is stored as
+//! floating point.
+//!
+//! This function returns the data from the most recent data read,
+//! converted into float value. Units are minutes.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataAtRateTimeToEmptyGetFloat(tBQ27510G3 *psInst, float *pfData)
+{
+ int16_t i16Data;
+
+ //
+ // Get the raw readings.
+ //
+ BQ27510G3DataAtRateTimeToEmptyGetRaw(psInst, &i16Data);
+
+ //
+ // Covert to float.
+ //
+ *pfData = (float)(i16Data);
+
+}
+
+//*****************************************************************************
+//
+//! Gets the raw battery temperature from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pi16Data is a pointer to the value into which the raw data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataTemperatureBatteryGetRaw(tBQ27510G3 *psInst, int16_t *pi16Data)
+{
+ //
+ // Return the raw data value.
+ //
+ *pi16Data = ((int16_t)psInst->pui8Data[3] << 8) | psInst->pui8Data[2];
+}
+
+//*****************************************************************************
+//
+//! Gets the battery temperature measurement data from the most recent data
+//! read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfData is a pointer to the value into which the data is stored as
+//! floating point.
+//!
+//! This function returns the data from the most recent data read,
+//! converted into float value. Units are degrees Celsius.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataTemperatureBatteryGetFloat(tBQ27510G3 *psInst, float *pfData)
+{
+ int16_t i16Data;
+
+ //
+ // Get the raw readings.
+ //
+ BQ27510G3DataTemperatureBatteryGetRaw(psInst, &i16Data);
+
+ //
+ // Device returns the units as 0.1 degrees K. Convert first to whole
+ // degrees then from K to C
+ //
+ *pfData = (float)(i16Data);
+ *pfData = *pfData / 10.0f;
+ *pfData -= 272.15f;
+
+
+}
+
+//*****************************************************************************
+//
+//! Gets the raw battery voltage measurement data from the most recent data
+//! read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pi16Data is a pointer to the value into which the raw data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataVoltageBatteryGetRaw(tBQ27510G3 *psInst, int16_t *pi16Data)
+{
+ //
+ // Return the raw data value.
+ //
+ *pi16Data = ((int16_t)psInst->pui8Data[5] << 8) | psInst->pui8Data[4];
+}
+
+//*****************************************************************************
+//
+//! Gets the battery voltage measurement from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfData is a pointer to the value into which the data is stored as
+//! floating point.
+//!
+//! This function returns the data from the most recent data read,
+//! converted into float value. Units are volts.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataVoltageBatteryGetFloat(tBQ27510G3 *psInst, float *pfData)
+{
+ int16_t i16Data;
+
+ //
+ // Get the raw readings.
+ //
+ BQ27510G3DataVoltageBatteryGetRaw(psInst, &i16Data);
+
+ //
+ // Covert to float.
+ //
+ *pfData = (float)(i16Data);
+ *pfData = *pfData / 1000.0f;
+
+}
+
+//*****************************************************************************
+//
+//! Gets the raw nominal available capacity measurement from the most recent
+//! data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pi16Data is a pointer to the value into which the raw data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataCapacityNominalAvailableGetRaw(tBQ27510G3 *psInst,
+ int16_t *pi16Data)
+{
+ //
+ // Return the raw data value.
+ //
+ *pi16Data = ((int16_t)psInst->pui8Data[7] << 8) | psInst->pui8Data[6];
+}
+
+//*****************************************************************************
+//
+//! Gets the measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfData is a pointer to the value into which the data is stored as
+//! floating point.
+//!
+//! This function returns the data from the most recent data read,
+//! converted into float value. Units are amp-hours (Ah).
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataCapacityNominalAvailableGetFloat(tBQ27510G3 *psInst, float *pfData)
+{
+ int16_t i16Data;
+
+ //
+ // Get the raw readings.
+ //
+ BQ27510G3DataCapacityNominalAvailableGetRaw(psInst, &i16Data);
+
+ //
+ // Covert to float.
+ //
+ *pfData = (float)(i16Data);
+ *pfData = *pfData / 1000.0f;
+
+}
+
+//*****************************************************************************
+//
+//! Gets the raw available capacity of a new battery from the most recent data
+//! read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pi16Data is a pointer to the value into which the raw data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataCapacityFullAvailableGetRaw(tBQ27510G3 *psInst, int16_t *pi16Data)
+{
+ //
+ // Return the raw data value.
+ //
+ *pi16Data = ((int16_t)psInst->pui8Data[9] << 8) | psInst->pui8Data[8];
+}
+
+//*****************************************************************************
+//
+//! Gets the measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfData is a pointer to the value into which the data is stored as
+//! floating point.
+//!
+//! This function returns the data from the most recent data read,
+//! converted into float value. Units are amp-hours (Ah).
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataCapacityFullAvailableGetFloat(tBQ27510G3 *psInst, float *pfData)
+{
+ int16_t i16Data;
+
+ //
+ // Get the raw readings.
+ //
+ BQ27510G3DataCapacityFullAvailableGetRaw(psInst, &i16Data);
+
+ //
+ // Covert to float.
+ //
+ *pfData = (float)(i16Data);
+ *pfData = *pfData / 1000.0f;
+
+}
+
+//*****************************************************************************
+//
+//! Gets the raw remaining capacity of measurement from the most recent data
+//! read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pi16Data is a pointer to the value into which the raw data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataCapacityRemainingGetRaw(tBQ27510G3 *psInst, int16_t *pi16Data)
+{
+ //
+ // Return the raw data value.
+ //
+ *pi16Data = ((int16_t)psInst->pui8Data[11] << 8) | psInst->pui8Data[10];
+}
+
+//*****************************************************************************
+//
+//! Gets the measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfData is a pointer to the value into which the data is stored as
+//! floating point.
+//!
+//! This function returns the data from the most recent data read,
+//! converted into float value. Units are amp-hours (Ah).
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataCapacityRemainingGetFloat(tBQ27510G3 *psInst, float *pfData)
+{
+ int16_t i16Data;
+
+ //
+ // Get the raw readings.
+ //
+ BQ27510G3DataCapacityRemainingGetRaw(psInst, &i16Data);
+
+ //
+ // Covert to float.
+ //
+ *pfData = (float)(i16Data);
+ *pfData = *pfData / 1000.0f;
+
+}
+
+//*****************************************************************************
+//
+//! Gets the raw full charge capacity from the most recent data
+//! read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pi16Data is a pointer to the value into which the raw data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataCapacityFullChargeGetRaw(tBQ27510G3 *psInst, int16_t *pi16Data)
+{
+ //
+ // Return the raw data value.
+ //
+ *pi16Data = ((int16_t)psInst->pui8Data[13] << 8) | psInst->pui8Data[12];
+}
+
+//*****************************************************************************
+//
+//! Gets the measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfData is a pointer to the value into which the data is stored as
+//! floating point.
+//!
+//! This function returns the data from the most recent data read,
+//! converted into float value. Units are amp-hours (Ah).
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataCapacityFullChargeGetFloat(tBQ27510G3 *psInst, float *pfData)
+{
+ int16_t i16Data;
+
+ //
+ // Get the raw readings.
+ //
+ BQ27510G3DataCapacityFullChargeGetRaw(psInst, &i16Data);
+
+ //
+ // Covert to float.
+ //
+ *pfData = (float)(i16Data);
+ *pfData = *pfData / 1000.0f;
+
+}
+
+
+//*****************************************************************************
+//
+//! Gets the raw average current measurement from the most recent data
+//! read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pi16Data is a pointer to the value into which the raw data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataCurrentAverageGetRaw(tBQ27510G3 *psInst, int16_t *pi16Data)
+{
+ //
+ // Return the raw data value.
+ //
+ *pi16Data = ((int16_t)psInst->pui8Data[15] << 8) | psInst->pui8Data[14];
+}
+
+//*****************************************************************************
+//
+//! Gets the measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfData is a pointer to the value into which the data is stored as
+//! floating point.
+//!
+//! This function returns the data from the most recent data read,
+//! converted into float value. Units are amps.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataCurrentAverageGetFloat(tBQ27510G3 *psInst, float *pfData)
+{
+ int16_t i16Data;
+
+ //
+ // Get the raw readings.
+ //
+ BQ27510G3DataCurrentAverageGetRaw(psInst, &i16Data);
+
+ //
+ // Covert to float.
+ //
+ *pfData = (float)(i16Data);
+ *pfData = *pfData / 1000.0f;
+
+}
+
+
+//*****************************************************************************
+//
+//! Gets the raw time to empty estimate from the most recent data
+//! read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pi16Data is a pointer to the value into which the raw data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataTimeToEmptyGetRaw(tBQ27510G3 *psInst, int16_t *pi16Data)
+{
+ //
+ // Return the raw data value.
+ //
+ *pi16Data = ((int16_t)psInst->pui8Data[17] << 8) | psInst->pui8Data[16];
+}
+
+//*****************************************************************************
+//
+//! Gets the measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfData is a pointer to the value into which the data is stored as
+//! floating point.
+//!
+//! This function returns the data from the most recent data read,
+//! converted into float value. Units are minutes. Value of 65,535 indicates
+//! battery is not being discharged.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataTimeToEmptyGetFloat(tBQ27510G3 *psInst, float *pfData)
+{
+ int16_t i16Data;
+
+ //
+ // Get the raw readings.
+ //
+ BQ27510G3DataTimeToEmptyGetRaw(psInst, &i16Data);
+
+ //
+ // Covert to float.
+ //
+ *pfData = (float)(i16Data);
+
+}
+
+//*****************************************************************************
+//
+//! Gets the raw standby current from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pi16Data is a pointer to the value into which the raw data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataCurrentStandbyGetRaw(tBQ27510G3 *psInst, int16_t *pi16Data)
+{
+ //
+ // Return the raw data value.
+ //
+ *pi16Data = ((int16_t)psInst->pui8Data[19] << 8) | psInst->pui8Data[18];
+}
+
+//*****************************************************************************
+//
+//! Gets the measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfData is a pointer to the value into which the data is stored as
+//! floating point.
+//!
+//! This function returns the data from the most recent data read,
+//! converted into float value. Units are amps.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataCurrentStandbyGetFloat(tBQ27510G3 *psInst, float *pfData)
+{
+ int16_t i16Data;
+
+ //
+ // Get the raw readings.
+ //
+ BQ27510G3DataCurrentStandbyGetRaw(psInst, &i16Data);
+
+ //
+ // Covert to float.
+ //
+ *pfData = (float)(i16Data);
+ *pfData = *pfData / 1000.0f;
+
+}
+
+//*****************************************************************************
+//
+//! Gets the raw standby time to empty data from the most recent data
+//! read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pi16Data is a pointer to the value into which the raw data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataTimeToEmptyStandbyGetRaw(tBQ27510G3 *psInst, int16_t *pi16Data)
+{
+ //
+ // Return the raw data value.
+ //
+ *pi16Data = ((int16_t)psInst->pui8Data[21] << 8) | psInst->pui8Data[20];
+}
+
+//*****************************************************************************
+//
+//! Gets the measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfData is a pointer to the value into which the data is stored as
+//! floating point.
+//!
+//! This function returns the data from the most recent data read,
+//! converted into float value. Units are minutes.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataTimeToEmptyStandbyGetFloat(tBQ27510G3 *psInst, float *pfData)
+{
+ int16_t i16Data;
+
+ //
+ // Get the raw readings.
+ //
+ BQ27510G3DataTimeToEmptyStandbyGetRaw(psInst, &i16Data);
+
+ //
+ // Covert to float.
+ //
+ *pfData = (float)(i16Data);
+
+}
+
+//*****************************************************************************
+//
+//! Gets the raw cycle count data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pi16Data is a pointer to the value into which the raw data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataCycleCountGetRaw(tBQ27510G3 *psInst, int16_t *pi16Data)
+{
+ //
+ // Return the raw data value.
+ //
+ *pi16Data = ((int16_t)psInst->pui8Data[25] << 8) | psInst->pui8Data[24];
+}
+
+//*****************************************************************************
+//
+//! Gets the measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfData is a pointer to the value into which the data is stored as
+//! floating point.
+//!
+//! This function returns the data from the most recent data read, converted
+//! into float value. This data does not have units.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataCycleCountGetFloat(tBQ27510G3 *psInst, float *pfData)
+{
+ int16_t i16Data;
+
+ //
+ // Get the raw readings.
+ //
+ BQ27510G3DataCycleCountGetRaw(psInst, &i16Data);
+
+ //
+ // Covert to float.
+ //
+ *pfData = (float)(i16Data);
+
+}
+
+//*****************************************************************************
+//
+//! Gets the raw health data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pi16Data is a pointer to the value into which the raw data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataHealthGetRaw(tBQ27510G3 *psInst, int16_t *pi16Data)
+{
+ //
+ // Return the raw data value.
+ //
+ *pi16Data = ((int16_t)psInst->pui8Data[23] << 8) | psInst->pui8Data[22];
+}
+
+//*****************************************************************************
+//
+//! Gets the health data from the most recent health data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfHealth is a pointer to the value into which the battery
+//! health data is stored as floating point ratio of current/design capacity.
+//!
+//! This function returns the health data from the most recent data read,
+//! converted into percent health. The health status bits are dropped. These
+//! can be obtained with BQ27510G3DataHealthGetRaw function.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataHealthGetFloat(tBQ27510G3 *psInst, float *pfHealth)
+{
+ int16_t i16Health;
+
+ //
+ // Get the raw readings.
+ //
+ BQ27510G3DataHealthGetRaw(psInst, &i16Health);
+
+ //
+ // Mask off health bit field
+ //
+ *pfHealth = (float)(i16Health & 0xFF);
+
+}
+
+//*****************************************************************************
+//
+//! Gets the raw charge state data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pi16Data is a pointer to the value into which the raw data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataChargeStateGetRaw(tBQ27510G3 *psInst, int16_t *pi16Data)
+{
+ //
+ // Return the raw data value.
+ //
+ *pi16Data = ((int16_t)psInst->pui8Data[27] << 8) | psInst->pui8Data[26];
+}
+
+//*****************************************************************************
+//
+//! Gets the charge state from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfData is a pointer to the value into which the data is stored as
+//! floating point.
+//!
+//! This function returns the charge state from the most recent data read,
+//! converted into percent charged.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataChargeStateGetFloat(tBQ27510G3 *psInst, float *pfData)
+{
+ int16_t i16Data;
+
+ //
+ // Get the raw readings.
+ //
+ BQ27510G3DataChargeStateGetRaw(psInst, &i16Data);
+
+ //
+ // Convert to floating point.
+ //
+ *pfData = (float)(i16Data);
+
+}
+
+//*****************************************************************************
+//
+//! Gets the instantaneous current data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pi16Data is a pointer to the value into which the raw data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataCurrentInstantaneousGetRaw(tBQ27510G3 *psInst, int16_t *pi16Data)
+{
+ //
+ // Return the raw data value.
+ //
+ *pi16Data = ((int16_t)psInst->pui8Data[29] << 8) | psInst->pui8Data[28];
+}
+
+//*****************************************************************************
+//
+//! Gets the instantaneous current data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfData is a pointer to the value into which the data is stored as
+//! floating point.
+//!
+//! This function returns the current measurement from the most recent data
+//! read, converted into floating point amps.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataCurrentInstantaneousGetFloat(tBQ27510G3 *psInst, float *pfData)
+{
+ int16_t i16Data;
+
+ //
+ // Get the raw readings.
+ //
+ BQ27510G3DataCurrentInstantaneousGetRaw(psInst, &i16Data);
+
+ //
+ // Convert to floating point.
+ //
+ *pfData = (float)(i16Data);
+ *pfData /= 1000.0f;
+
+}
+
+//*****************************************************************************
+//
+//! Gets the raw internal temparature data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pi16Data is a pointer to the value into which the raw data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataTemperatureInternalGetRaw(tBQ27510G3 *psInst, int16_t *pi16Data)
+{
+ //
+ // Return the raw data value.
+ //
+ *pi16Data = ((int16_t)psInst->pui8Data[31] << 8) | psInst->pui8Data[30];
+}
+
+//*****************************************************************************
+//
+//! Gets the internal temperature data from the most recent data read.
+//!
+//! \param psInst is a pointer to the BQ27510G3 instance data.
+//! \param pfData is a pointer to the value into which the data is stored as
+//! floating point.
+//!
+//! This function returns the internal temperature from the most recent data
+//! read.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+BQ27510G3DataTemperatureInternalGetFloat(tBQ27510G3 *psInst, float *pfData)
+{
+ int16_t i16Data;
+
+ //
+ // Get the raw readings.
+ //
+ BQ27510G3DataTemperatureInternalGetRaw(psInst, &i16Data);
+
+ //
+ // Convert to floating point Kelvin, then Celsius.
+ //
+ *pfData = (float)(i16Data);
+ *pfData = *pfData / 10.0f;
+ *pfData -= 272.15f;
+
+
+
+}
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/bq27510g3.h b/sensorlib/bq27510g3.h new file mode 100644 index 0000000..928da94 --- /dev/null +++ b/sensorlib/bq27510g3.h @@ -0,0 +1,210 @@ +//*****************************************************************************
+//
+// bq27510g3.c - Prototypes for the TI BQ27510G3 Battery Fuel Guage
+// driver.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_BQ27510G3_H__
+#define __SENSORLIB_BQ27510G3_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the BQ27510G3 driver.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The pointer to the I2C master interface instance used to communicate
+ // with the BQ27510G3.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The I2C address of the BQ27510G3.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The state of the state machine used while accessing the BQ27510G3.
+ //
+ uint8_t ui8State;
+
+ //
+ // The data buffer used for sending/receiving data to/from the BQ27510G3.
+ //
+ uint8_t pui8Data[32];
+
+ //
+ // The function that is called when the current request has completed
+ // processing.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The pointer provided to the callback function.
+ //
+ void *pvCallbackData;
+
+ //
+ // A union of structures that are used for read, write and
+ // read-modify-write operations. Since only one operation can be active at
+ // a time, it is safe to re-use the memory in this manner.
+ //
+ union
+ {
+ //
+ // A buffer used to store the write portion of a register read.
+ //
+ uint8_t pui8Buffer[4];
+
+ //
+ // The read state used to read register values.
+ //
+ tI2CMRead16BE sReadState;
+
+ //
+ // The write state used to write register values.
+ //
+ tI2CMWrite16BE sWriteState;
+
+ //
+ // The read-modify-write state used to modify register values.
+ //
+ tI2CMReadModifyWrite16 sReadModifyWriteState;
+ }
+ uCommand;
+}
+tBQ27510G3;
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern uint_fast8_t BQ27510G3Init(tBQ27510G3 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t BQ27510G3Read(tBQ27510G3 *psInst, uint_fast8_t ui8Reg,
+ uint16_t *pui16Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t BQ27510G3Write(tBQ27510G3 *psInst, uint_fast8_t ui8Reg,
+ const uint16_t *pui16Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t BQ27510G3ReadModifyWrite(tBQ27510G3 *psInst,
+ uint_fast8_t ui8Reg,
+ uint_fast16_t ui16Mask,
+ uint_fast16_t ui16Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t BQ27510G3DataRead(tBQ27510G3 *psInst,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+
+extern void BQ27510G3DataAtRateTimeToEmptyGetRaw(tBQ27510G3 *psInst,
+ int16_t *pui16Data);
+extern void BQ27510G3DataAtRateTimeToEmptyGetFloat(tBQ27510G3 *psInst,
+ float *pfData);
+extern void BQ27510G3DataTemperatureBatteryGetRaw(tBQ27510G3 *psInst,
+ int16_t *pui16Data);
+extern void BQ27510G3DataTemperatureBatteryGetFloat(tBQ27510G3 *psInst,
+ float *pfData);
+extern void BQ27510G3DataVoltageBatteryGetRaw(tBQ27510G3 *psInst,
+ int16_t *pui16Data);
+extern void BQ27510G3DataVoltageBatteryGetFloat(tBQ27510G3 *psInst,
+ float *pfData);
+extern void BQ27510G3DataCapacityNominalAvailableGetRaw(tBQ27510G3 *psInst,
+ int16_t *pui16Data);
+extern void BQ27510G3DataCapacityNominalAvailalbeGetFloat(tBQ27510G3 *psInst,
+ float *pfData);
+extern void BQ27510G3DataCapacityFullAvailableGetRaw(tBQ27510G3 *psInst,
+ int16_t *pui16Data);
+extern void BQ27510G3DataCapacityFullAvailableGetFloat(tBQ27510G3 *psInst,
+ float *pfData);
+extern void BQ27510G3DataCapacityRemainingGetRaw(tBQ27510G3 *psInst,
+ int16_t *pui16Data);
+extern void BQ27510G3DataCapacityRemainingGetFloat(tBQ27510G3 *psInst,
+ float *pfData);
+extern void BQ27510G3DataCapacityFullChargeGetRaw(tBQ27510G3 *psInst,
+ int16_t *pui16Data);
+extern void BQ27510G3DataCapacityFullChargeGetFloat(tBQ27510G3 *psInst,
+ float *pfData);
+extern void BQ27510G3DataCurrentAverageGetRaw(tBQ27510G3 *psInst,
+ int16_t *pui16Data);
+extern void BQ27510G3DataCurrentAverageGetFloat(tBQ27510G3 *psInst,
+ float *pfData);
+extern void BQ27510G3DataTimeToEmptyGetRaw(tBQ27510G3 *psInst,
+ int16_t *pui16Data);
+extern void BQ27510G3DataTimeToEmptyGetFloat(tBQ27510G3 *psInst,
+ float *pfData);
+extern void BQ27510G3DataCurrentStandbyGetRaw(tBQ27510G3 *psInst,
+ int16_t *pui16Data);
+extern void BQ27510G3DataCurrentStandbyGetFloat(tBQ27510G3 *psInst,
+ float *pfData);
+extern void BQ27510G3DataTimeToEmptyStandbyGetRaw(tBQ27510G3 *psInst,
+ int16_t *pui16Data);
+extern void BQ27510G3DataTimeToEmptyStandbyGetFloat(tBQ27510G3 *psInst,
+ float *pfData);
+extern void BQ27510G3DataCycleCountGetRaw(tBQ27510G3 *psInst,
+ int16_t *pui16Data);
+extern void BQ27510G3DataCycleCountGetFloat(tBQ27510G3 *psInst, float *pfData);
+extern void BQ27510G3DataHealthGetRaw(tBQ27510G3 *psInst, int16_t *pui16Data);
+extern void BQ27510G3DataHealthGetFloat(tBQ27510G3 *psInst, float *pfData);
+extern void BQ27510G3DataChargeStateGetRaw(tBQ27510G3 *psInst,
+ int16_t *pui16Data);
+extern void BQ27510G3DataChargeStateGetFloat(tBQ27510G3 *psInst,
+ float *pfData);
+extern void BQ27510G3DataCurrentInstantaneousGetRaw(tBQ27510G3 *psInst,
+ int16_t *pui16Data);
+extern void BQ27510G3DataCurrentInstantaneousGetFloat(tBQ27510G3 *psInst,
+ float *pfData);
+extern void BQ27510G3DataTemperatureInternalGetRaw(tBQ27510G3 *psInst,
+ int16_t *pui16Data);
+extern void BQ27510G3DataTemperatureInternalGetFloat(tBQ27510G3 *psInst,
+ float *pfData);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_BQ27510G3_H__
+
diff --git a/sensorlib/ccs/.ccsproject b/sensorlib/ccs/.ccsproject new file mode 100644 index 0000000..b4eaafa --- /dev/null +++ b/sensorlib/ccs/.ccsproject @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8" ?>
+<?ccsproject version="1.0"?>
+<projectOptions>
+ <deviceVariant value="Cortex M.TM4C1230C3PM"/>
+ <deviceFamily value="TMS470"/>
+ <deviceEndianness value="little"/>
+ <codegenToolVersion value="5.0.4"/>
+ <isElfFormat value="true"/>
+</projectOptions>
diff --git a/sensorlib/ccs/.cproject b/sensorlib/ccs/.cproject new file mode 100644 index 0000000..10acdbf --- /dev/null +++ b/sensorlib/ccs/.cproject @@ -0,0 +1,147 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?>
+
+<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+ <storageModule configRelations="2" moduleId="org.eclipse.cdt.core.settings">
+ <cconfiguration id="com.ti.ccstudio.buildDefinitions.TMS470.Debug.20798163">
+ <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.ti.ccstudio.buildDefinitions.TMS470.Debug.20798163" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+ <macros>
+ <stringMacro name="SW_ROOT" type="VALUE_PATH_DIR" value="${PROJECT_ROOT}/../.."/>
+ </macros>
+ <externalSettings/>
+ <extensions>
+ <extension id="com.ti.ccstudio.binaryparser.CoffParser" point="org.eclipse.cdt.core.BinaryParser"/>
+ <extension id="com.ti.ccstudio.errorparser.CoffErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="com.ti.ccstudio.errorparser.LinkErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="com.ti.ccstudio.errorparser.AsmErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ </extensions>
+ </storageModule>
+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+ <configuration artifactExtension="lib" artifactName="${ProjName}" buildProperties="" cleanCommand="${CG_CLEAN_CMD}" description="" id="com.ti.ccstudio.buildDefinitions.TMS470.Debug.20798163" name="Debug" parent="com.ti.ccstudio.buildDefinitions.TMS470.Debug">
+ <folderInfo id="com.ti.ccstudio.buildDefinitions.TMS470.Debug.20798163." name="/" resourcePath="">
+ <toolChain id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.libraryDebugToolchain.1583161084" name="TI Build Tools" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.libraryDebugToolchain" targetTool="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.librarianDebug.624051952">
+ <option id="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.1302413647" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS" valueType="stringList">
+ <listOptionValue builtIn="false" value="DEVICE_CONFIGURATION_ID=Cortex M.TM4C1230C3PM"/>
+ <listOptionValue builtIn="false" value="DEVICE_ENDIANNESS=little"/>
+ <listOptionValue builtIn="false" value="OUTPUT_FORMAT=ELF"/>
+ <listOptionValue builtIn="false" value="CCS_MBS_VERSION=5.1.0.01"/>
+ <listOptionValue builtIn="false" value="OUTPUT_TYPE=staticLibrary"/>
+ </option>
+ <option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.298639692" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION" value="5.0.4" valueType="string"/>
+ <targetPlatform id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.targetPlatformDebug.367896764" name="Platform" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.targetPlatformDebug"/>
+ <builder buildPath="${BuildDirectory}" id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.builderDebug.1545349647" name="GNU Make.Debug" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.builderDebug"/>
+ <tool id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.compilerDebug.1190414836" name="ARM Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.compilerDebug">
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.SILICON_VERSION.1976576711" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.SILICON_VERSION" value="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.SILICON_VERSION.7M4" valueType="enumerated"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.CODE_STATE.1809370431" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.CODE_STATE" value="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.CODE_STATE.16" valueType="enumerated"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.ABI.1323823706" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.ABI" value="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.ABI.eabi" valueType="enumerated"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.FLOAT_SUPPORT.314310918" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.FLOAT_SUPPORT" value="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.FLOAT_SUPPORT.FPv4SPD16" valueType="enumerated"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DEBUGGING_MODEL.1564303441" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DEBUGGING_MODEL" value="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DEBUGGING_MODEL.SYMDEBUG__DWARF" valueType="enumerated"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DIAG_WARNING.1640770023" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DIAG_WARNING" valueType="stringList">
+ <listOptionValue builtIn="false" value="225"/>
+ </option>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DISPLAY_ERROR_NUMBER.1528006369" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DIAG_WRAP.989036988" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DIAG_WRAP" value="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DIAG_WRAP.off" valueType="enumerated"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.INCLUDE_PATH.1393096055" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.INCLUDE_PATH" valueType="includePath">
+ <listOptionValue builtIn="false" value=""${CG_TOOL_ROOT}/include""/>
+ <listOptionValue builtIn="false" value=""${SW_ROOT}""/>
+ </option>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.LITTLE_ENDIAN.1025879328" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.LITTLE_ENDIAN" value="true" valueType="boolean"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.GEN_FUNC_SUBSECTIONS.634502098" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.GEN_FUNC_SUBSECTIONS" value="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.GEN_FUNC_SUBSECTIONS.on" valueType="enumerated"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.OPT_LEVEL.896160998" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.OPT_LEVEL" value="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.OPT_LEVEL.2" valueType="enumerated"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.GCC.1653793740" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.GCC" value="true" valueType="boolean"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.UAL.531288458" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.UAL" value="true" valueType="boolean"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DEFINE.915288487" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DEFINE" valueType="definedSymbols">
+ <listOptionValue builtIn="false" value="ccs="ccs""/>
+ </option>
+ <inputType id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compiler.inputType__C_SRCS.1957406136" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compiler.inputType__C_SRCS"/>
+ <inputType id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compiler.inputType__CPP_SRCS.2078906287" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compiler.inputType__CPP_SRCS"/>
+ <inputType id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compiler.inputType__ASM_SRCS.1259429713" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compiler.inputType__ASM_SRCS"/>
+ <inputType id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compiler.inputType__ASM2_SRCS.1619339108" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compiler.inputType__ASM2_SRCS"/>
+ </tool>
+ <tool id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.librarianDebug.624051952" name="ARM Archiver" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.librarianDebug">
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.archiverID.OUTPUT_FILE.1445718960" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.archiverID.OUTPUT_FILE" value=""${ProjName}.lib"" valueType="string"/>
+ </tool>
+ </toolChain>
+ </folderInfo>
+ </configuration>
+ </storageModule>
+ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+ </cconfiguration>
+ <cconfiguration id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1321180849">
+ <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1321180849" moduleId="org.eclipse.cdt.core.settings" name="Release">
+ <macros>
+ <stringMacro name="SW_ROOT" type="VALUE_PATH_DIR" value="${PROJECT_ROOT}/../.."/>
+ </macros>
+ <externalSettings/>
+ <extensions>
+ <extension id="com.ti.ccstudio.binaryparser.CoffParser" point="org.eclipse.cdt.core.BinaryParser"/>
+ <extension id="com.ti.ccstudio.errorparser.CoffErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="com.ti.ccstudio.errorparser.LinkErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="com.ti.ccstudio.errorparser.AsmErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ </extensions>
+ </storageModule>
+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+ <configuration artifactExtension="lib" artifactName="${ProjName}" buildProperties="" cleanCommand="${CG_CLEAN_CMD}" description="" id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1321180849" name="Release" parent="com.ti.ccstudio.buildDefinitions.TMS470.Release">
+ <folderInfo id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1321180849." name="/" resourcePath="">
+ <toolChain id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.ReleaseToolchain.1905987288" name="TI Build Tools" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.ReleaseToolchain" targetTool="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.librarianRelease.680964683">
+ <option id="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.217154684" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS" valueType="stringList">
+ <listOptionValue builtIn="false" value="DEVICE_CONFIGURATION_ID=Cortex M.TM4C1230C3PM"/>
+ <listOptionValue builtIn="false" value="DEVICE_ENDIANNESS=little"/>
+ <listOptionValue builtIn="false" value="OUTPUT_FORMAT=ELF"/>
+ <listOptionValue builtIn="false" value="CCS_MBS_VERSION=5.1.0.01"/>
+ <listOptionValue builtIn="false" value="OUTPUT_TYPE=staticLibrary"/>
+ </option>
+ <option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.1983422785" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION" value="5.0.4" valueType="string"/>
+ <targetPlatform id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.targetPlatformRelease.891055822" name="Platform" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.targetPlatformRelease"/>
+ <builder buildPath="${BuildDirectory}" id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.builderRelease.1928903911" name="GNU Make.Release" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.builderRelease"/>
+ <tool id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.compilerRelease.1258115376" name="ARM Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.compilerRelease">
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.SILICON_VERSION.390501534" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.SILICON_VERSION" value="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.SILICON_VERSION.7M4" valueType="enumerated"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.CODE_STATE.1425349915" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.CODE_STATE" value="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.CODE_STATE.16" valueType="enumerated"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.ABI.2087744685" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.ABI" value="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.ABI.eabi" valueType="enumerated"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.FLOAT_SUPPORT.917798771" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.FLOAT_SUPPORT" value="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.FLOAT_SUPPORT.FPv4SPD16" valueType="enumerated"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DIAG_WARNING.122667932" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DIAG_WARNING" valueType="stringList">
+ <listOptionValue builtIn="false" value="225"/>
+ </option>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DISPLAY_ERROR_NUMBER.1996927083" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DIAG_WRAP.1819529191" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DIAG_WRAP" value="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DIAG_WRAP.off" valueType="enumerated"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.INCLUDE_PATH.2064778685" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.INCLUDE_PATH" valueType="includePath">
+ <listOptionValue builtIn="false" value=""${CG_TOOL_ROOT}/include""/>
+ <listOptionValue builtIn="false" value=""${SW_ROOT}""/>
+ </option>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.LITTLE_ENDIAN.412050452" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.LITTLE_ENDIAN" value="true" valueType="boolean"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.GEN_FUNC_SUBSECTIONS.1185189428" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.GEN_FUNC_SUBSECTIONS" value="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.GEN_FUNC_SUBSECTIONS.on" valueType="enumerated"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.GCC.89395542" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.GCC" value="true" valueType="boolean"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.UAL.1244023322" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.UAL" value="true" valueType="boolean"/>
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DEFINE.493563444" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compilerID.DEFINE" valueType="definedSymbols">
+ <listOptionValue builtIn="false" value="ccs="ccs""/>
+ </option>
+ <inputType id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compiler.inputType__C_SRCS.404442260" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compiler.inputType__C_SRCS"/>
+ <inputType id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compiler.inputType__CPP_SRCS.1334731655" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compiler.inputType__CPP_SRCS"/>
+ <inputType id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compiler.inputType__ASM_SRCS.360970955" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compiler.inputType__ASM_SRCS"/>
+ <inputType id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compiler.inputType__ASM2_SRCS.1419155761" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.compiler.inputType__ASM2_SRCS"/>
+ </tool>
+ <tool id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.librarianRelease.680964683" name="ARM Archiver" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.library.librarianRelease">
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_5.0.archiverID.OUTPUT_FILE.1181599114" superClass="com.ti.ccstudio.buildDefinitions.TMS470_5.0.archiverID.OUTPUT_FILE" value=""${ProjName}.lib"" valueType="string"/>
+ </tool>
+ </toolChain>
+ </folderInfo>
+ </configuration>
+ </storageModule>
+ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+ </cconfiguration>
+ </storageModule>
+ <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+ <project id="sensorlib.com.ti.ccstudio.buildDefinitions.TMS470.ProjectType.2137497005" name="ARM" projectType="com.ti.ccstudio.buildDefinitions.TMS470.ProjectType"/>
+ </storageModule>
+ <storageModule moduleId="scannerConfiguration"/>
+ <storageModule moduleId="org.eclipse.cdt.core.language.mapping">
+ <project-mappings>
+ <content-type-mapping configuration="" content-type="org.eclipse.cdt.core.asmSource" language="com.ti.ccstudio.core.TIASMLanguage"/>
+ <content-type-mapping configuration="" content-type="org.eclipse.cdt.core.cHeader" language="com.ti.ccstudio.core.TIGCCLanguage"/>
+ <content-type-mapping configuration="" content-type="org.eclipse.cdt.core.cSource" language="com.ti.ccstudio.core.TIGCCLanguage"/>
+ <content-type-mapping configuration="" content-type="org.eclipse.cdt.core.cxxHeader" language="com.ti.ccstudio.core.TIGPPLanguage"/>
+ <content-type-mapping configuration="" content-type="org.eclipse.cdt.core.cxxSource" language="com.ti.ccstudio.core.TIGPPLanguage"/>
+ </project-mappings>
+ </storageModule>
+</cproject>
diff --git a/sensorlib/ccs/.project b/sensorlib/ccs/.project new file mode 100644 index 0000000..250724d --- /dev/null +++ b/sensorlib/ccs/.project @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>sensorlib</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+ <triggers>full,incremental,</triggers>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>com.ti.ccstudio.core.ccsNature</nature>
+ <nature>org.eclipse.cdt.core.cnature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+ <nature>org.eclipse.cdt.core.ccnature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+ </natures>
+ <linkedResources>
+ <link>
+ <name>ak8963.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/ak8963.c</locationURI>
+ </link>
+ <link>
+ <name>ak8975.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/ak8975.c</locationURI>
+ </link>
+ <link>
+ <name>bmp180.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/bmp180.c</locationURI>
+ </link>
+ <link>
+ <name>bq27510g3.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/bq27510g3.c</locationURI>
+ </link>
+ <link>
+ <name>cm3218.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/cm3218.c</locationURI>
+ </link>
+ <link>
+ <name>comp_dcm.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/comp_dcm.c</locationURI>
+ </link>
+ <link>
+ <name>i2cm_drv.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/i2cm_drv.c</locationURI>
+ </link>
+ <link>
+ <name>isl29023.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/isl29023.c</locationURI>
+ </link>
+ <link>
+ <name>kxti9.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/kxti9.c</locationURI>
+ </link>
+ <link>
+ <name>l3gd20h.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/l3gd20h.c</locationURI>
+ </link>
+ <link>
+ <name>lsm303d.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/lsm303d.c</locationURI>
+ </link>
+ <link>
+ <name>lsm303dlhc_accel.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/lsm303dlhc_accel.c</locationURI>
+ </link>
+ <link>
+ <name>lsm303dlhc_mag.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/lsm303dlhc_mag.c</locationURI>
+ </link>
+ <link>
+ <name>magneto.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/magneto.c</locationURI>
+ </link>
+ <link>
+ <name>mpu6050.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/mpu6050.c</locationURI>
+ </link>
+ <link>
+ <name>mpu9150.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/mpu9150.c</locationURI>
+ </link>
+ <link>
+ <name>quaternion.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/quaternion.c</locationURI>
+ </link>
+ <link>
+ <name>sht21.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/sht21.c</locationURI>
+ </link>
+ <link>
+ <name>tmp006.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/tmp006.c</locationURI>
+ </link>
+ <link>
+ <name>tmp100.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/tmp100.c</locationURI>
+ </link>
+ <link>
+ <name>vector.c</name>
+ <type>1</type>
+ <locationURI>SW_ROOT/sensorlib/vector.c</locationURI>
+ </link>
+ </linkedResources>
+ <variableList>
+ <variable>
+ <name>SW_ROOT</name>
+ <value>$%7BPARENT-2-PROJECT_LOC%7D</value>
+ </variable>
+ </variableList>
+</projectDescription>
diff --git a/sensorlib/ccs/.settings/org.eclipse.cdt.codan.core.prefs b/sensorlib/ccs/.settings/org.eclipse.cdt.codan.core.prefs new file mode 100644 index 0000000..98b6350 --- /dev/null +++ b/sensorlib/ccs/.settings/org.eclipse.cdt.codan.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1
+inEditor=false
+onBuild=false
diff --git a/sensorlib/ccs/Debug/sensorlib.lib b/sensorlib/ccs/Debug/sensorlib.lib Binary files differnew file mode 100644 index 0000000..953d9c6 --- /dev/null +++ b/sensorlib/ccs/Debug/sensorlib.lib diff --git a/sensorlib/ccs/macros.ini_initial b/sensorlib/ccs/macros.ini_initial new file mode 100644 index 0000000..08b716d --- /dev/null +++ b/sensorlib/ccs/macros.ini_initial @@ -0,0 +1 @@ +SW_ROOT = ../..
diff --git a/sensorlib/cm3218.c b/sensorlib/cm3218.c new file mode 100644 index 0000000..bb2251f --- /dev/null +++ b/sensorlib/cm3218.c @@ -0,0 +1,468 @@ +//*****************************************************************************
+//
+// cm3218.c - Driver for the CM3218 light sensor
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <math.h>
+#include <stdint.h>
+#include "sensorlib/hw_cm3218.h"
+#include "sensorlib/i2cm_drv.h"
+#include "sensorlib/cm3218.h"
+
+//*****************************************************************************
+//
+//! \addtogroup cm3218_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The states of the CM3218 state machine.
+//
+//*****************************************************************************
+#define CM3218_STATE_IDLE 0
+#define CM3218_STATE_INIT 1
+#define CM3218_STATE_READ 2
+#define CM3218_STATE_WRITE 3
+
+//*****************************************************************************
+//
+// Sensitivity setting to floating point range value lookup table.
+//
+//*****************************************************************************
+const float g_pfSensitivityLookup[4] =
+{
+ 0.02857,
+ 0.01328,
+ 0.00714,
+ 0.003571
+};
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transations to/from the CM3218
+// have completed.
+//
+//*****************************************************************************
+static void
+CM3218Callback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tCM3218 *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tCM3218 structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result in a callback to propagate the
+ // error).
+ //
+ if(ui8Status != I2CM_STATUS_SUCCESS)
+ {
+ psInst->ui8State = CM3218_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the CM3218 state machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // All states that trivially transition to IDLE, and all unknown
+ // states.
+ //
+ case CM3218_STATE_INIT:
+ case CM3218_STATE_READ:
+ default:
+ {
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = CM3218_STATE_IDLE;
+ break;
+ }
+
+ //
+ // A write has just completed.
+ //
+ case CM3218_STATE_WRITE:
+ {
+ //
+ // Set the integration time to the new integration time. If the
+ // register was not modified, the values will be the same so this
+ // has no effect.
+ //
+ psInst->ui8IntTime = psInst->ui8NewIntTime;
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = CM3218_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == CM3218_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the CM3218 driver.
+//!
+//! \param psInst is a pointer to the CM3218 instance data.
+//! \param psI2CInst is a pointer to the I2C driver instance data.
+//! \param ui8I2CAddr is the I2C address of the CM3218 device.
+//! \param pfnCallback is the function to be called when the initialization has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initializes the CM3218 driver, preparing it for operation.
+//!
+//! \return Returns 1 if the CM3218 driver was successfully initialized and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+CM3218Init(tCM3218 *psInst, tI2CMInstance *psI2CInst, uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Initialize the CM3218 instance structure
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8I2CAddr;
+ psInst->ui8State = CM3218_STATE_IDLE;
+ psInst->ui8IntTime = CM3218_CMD_CONFIG_IT_10 >> CM3218_CMD_CONFIG_IT_S;
+ psInst->ui8NewIntTime = CM3218_CMD_CONFIG_IT_10 >> CM3218_CMD_CONFIG_IT_S;
+
+ //
+ // The default settings are ok. Call the callback function if provided.
+ //
+ if(pfnCallback)
+ {
+ pfnCallback(pvCallbackData, 0);
+ }
+
+ //
+ // Success
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads data from CM3218 registers.
+//!
+//! \param psInst is a pointer to the CM3218 instance data.
+//! \param ui8Reg is the first register to read.
+//! \param pui16Data is a pointer to the location to store the data that is
+//! read.
+//! \param ui16Count the number of register values bytes to read.
+//! \param pfnCallback is the function to be called when data read is complete
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function reads a sequence of data values from consecutive registers in
+//! the CM3218.
+//!
+//! \note The CM3218 does not auto-increment the register pointer, so reads of
+//! more than one value returns the same data.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+CM3218Read(tCM3218 *psInst, uint_fast8_t ui8Reg, uint16_t *pui16Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the CM3218 driver is not idle (in other words, there
+ // is already an outstanding request to the CM3218).
+ //
+ if(psInst->ui8State != CM3218_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read state.
+ //
+ psInst->ui8State = CM3218_STATE_READ;
+
+ //
+ // Read the requested registers from the CM3218.
+ //
+ if(I2CMRead16BE(&(psInst->uCommand.sReadState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui16Data, ui16Count,
+ CM3218Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = CM3218_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Writes data to CM3218 registers.
+//!
+//! \param psInst is a pointer to the CM3218 instance data.
+//! \param ui8Reg is the first register to write.
+//! \param pui16Data is a pointer to the 16-bit register data to write.
+//! \param ui16Count is the number of data bytes to write.
+//! \param pfnCallback is the function to be called when the data has been
+//! written (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function writes a sequence of data values to consecutive registers in
+//! the CM3218. The first value in the \e pui16Data buffer contains the data
+//! to be written into the \e ui8Reg register, the second value contains the
+//! data to be written into the next register, and so on.
+//!
+//! \note The CM3218 does not auto-increment the register pointer, so writes of
+//! more than one register are rejected by the CM3218.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+CM3218Write(tCM3218 *psInst, uint_fast8_t ui8Reg, const uint16_t *pui16Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the CM3218 driver is not idle (in other words, there
+ // is already an outstanding request to the CM3218).
+ //
+ if(psInst->ui8State != CM3218_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // See if the CMD_CONFIG register is being written.
+ //
+ if((ui8Reg <= CM3218_CMD_CONFIG) &&
+ ((ui8Reg + ui16Count) > CM3218_CMD_CONFIG))
+ {
+ //
+ // Extract the integration time from the CMD_CONFIG register value.
+ //
+ psInst->ui8NewIntTime = ((pui16Data[ui8Reg - CM3218_CMD_CONFIG] &
+ CM3218_CMD_CONFIG_IT_M) >>
+ CM3218_CMD_CONFIG_IT_S);
+ }
+
+ //
+ // Move the state machine to the wait for write state.
+ //
+ psInst->ui8State = CM3218_STATE_WRITE;
+
+ //
+ // Write the requested registers to the CM3218.
+ //
+ if(I2CMWrite16BE(&(psInst->uCommand.sWriteState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui16Data, ui16Count,
+ CM3218Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = CM3218_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads the light data from the CM3218.
+//!
+//! \param psInst is a pointer to the CM3218 instance data.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read of the CM3218 data registers. When the read
+//! has completed (as indicated by calling the callback function), the new
+//! readings can be obtained via:
+//!
+//! - CM3218DataLightVisibleGetRaw()
+//! - CM3218DataLightVisibleGetFloat()
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+CM3218DataRead(tCM3218 *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the CM3218 driver is not idle (in other words, there
+ // is already an outstanding request to the CM3218).
+ //
+ if(psInst->ui8State != CM3218_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for data read
+ //
+ psInst->ui8State = CM3218_STATE_READ;
+
+ //
+ // Read the ambient light data from the CM3218.
+ //
+ psInst->uCommand.pui8Buffer[0] = CM3218_CMD_ALS_DATA;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 2,
+ CM3218Callback, psInst) == 0)
+ {
+ //
+ // The I2C read failed, so move to the idle state and return a failure.
+ //
+ psInst->ui8State = CM3218_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Gets the raw measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the CM3218 instance data.
+//! \param pui16Visible is a pointer to the value into which the raw visible
+//! light data is stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+CM3218DataLightVisibleGetRaw(tCM3218 *psInst, uint16_t *pui16Visible)
+{
+ //
+ // Return the raw Light value.
+ //
+ *pui16Visible = (psInst->pui8Data[1] << 8) | psInst->pui8Data[0];
+}
+
+//*****************************************************************************
+//
+//! Gets the measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the CM3218 instance data.
+//! \param pfVisibleLight is a pointer to the value into which the light
+//! data is stored as floating point lux.
+//!
+//! This function returns the light data from the most recent data read,
+//! converted into lux.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+CM3218DataLightVisibleGetFloat(tCM3218 *psInst, float *pfVisibleLight)
+{
+ uint16_t ui16Light;
+ float fSensitivity;
+
+ //
+ // Get the raw light data from the instance structure
+ //
+ CM3218DataLightVisibleGetRaw(psInst, &ui16Light);
+
+ //
+ // Get the floating point values for sensitivity
+ //
+ fSensitivity = g_pfSensitivityLookup[psInst->ui8IntTime];
+
+ //
+ // Calculate light reading in lux.
+ //
+ *pfVisibleLight = ((float)ui16Light) * fSensitivity;
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/cm3218.h b/sensorlib/cm3218.h new file mode 100644 index 0000000..fad9f11 --- /dev/null +++ b/sensorlib/cm3218.h @@ -0,0 +1,149 @@ +//*****************************************************************************
+//
+// CM3218.h - Prototypes for the CM3218 light sensor
+// driver.
+//
+// Copyright (c) 2012-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_CM3218_H__
+#define __SENSORLIB_CM3218_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the CM3218 driver.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The pointer to the I2C master interface instance used to communicate
+ // with the CM3218.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The I2C address of the CM3218.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The state of the state machine used while accessing the CM3218.
+ //
+ uint8_t ui8State;
+
+ //
+ // The data buffer used for sending/receiving data to/from the CM3218.
+ //
+ uint8_t pui8Data[4];
+
+ //
+ // The integration time, which determines the sensitivity.
+ //
+ uint8_t ui8IntTime;
+
+ //
+ // The new integration time, which is used when a register write succeeds.
+ //
+ uint8_t ui8NewIntTime;
+
+ //
+ // The function that is called when the current request has completed
+ // processing.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The pointer provided to the callback function.
+ //
+ void *pvCallbackData;
+
+ //
+ // A union of structures that are used for read and write operations.
+ // Since only one operation can be active at a time, it is safe to re-use
+ // the memory in this manner.
+ //
+ union
+ {
+ //
+ // A buffer used to store the write portion of a register read.
+ //
+ uint8_t pui8Buffer[4];
+
+ //
+ // The read state used to read register values.
+ //
+ tI2CMRead16BE sReadState;
+
+ //
+ // The write state used to write register values.
+ //
+ tI2CMWrite16BE sWriteState;
+ }
+ uCommand;
+}
+tCM3218;
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern uint_fast8_t CM3218Init(tCM3218 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t CM3218Read(tCM3218 *psInst, uint_fast8_t ui8Reg,
+ uint16_t *pui16Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t CM3218Write(tCM3218 *psInst, uint_fast8_t ui8Reg,
+ const uint16_t *pui16Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t CM3218DataRead(tCM3218 *psInst,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern void CM3218DataLightVisibleGetRaw(tCM3218 *psInst,
+ uint16_t *pui16Visible);
+extern void CM3218DataLightVisibleGetFloat(tCM3218 *psInst, float *pfVisible);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_CM3218_H__
diff --git a/sensorlib/comp_dcm.c b/sensorlib/comp_dcm.c new file mode 100644 index 0000000..42db71d --- /dev/null +++ b/sensorlib/comp_dcm.c @@ -0,0 +1,634 @@ +//*****************************************************************************
+//
+// comp_dcm.c - Complementary filter algorithm on a Direction Cosine Matrix for
+// fusing sensor data from an accelerometer, gyroscope, and
+// magnetometer.
+//
+// Copyright (c) 2012-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <math.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include "driverlib/debug.h"
+#include "sensorlib/comp_dcm.h"
+#include "sensorlib/vector.h"
+
+//*****************************************************************************
+//
+//! \addtogroup comp_dcm_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// If M_PI has not been defined by the system headers, define it here.
+//
+//*****************************************************************************
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+//*****************************************************************************
+//
+//! Initializes the complementary filter DCM attitude estimation state.
+//!
+//! \param psDCM is a pointer to the DCM state structure.
+//! \param fDeltaT is the amount of time between DCM updates, in seconds.
+//! \param fScaleA is the weight of the accelerometer reading in determining
+//! the updated attitude estimation.
+//! \param fScaleG is the weight of the gyroscope reading in determining the
+//! updated attitude estimation.
+//! \param fScaleM is the weight of the magnetometer reading in determining the
+//! updated attitude estimation.
+//!
+//! This function initializes the complementary filter DCM attitude estimation
+//! state, and must be called prior to performing any attitude estimation.
+//!
+//! New readings must be supplied to the complementary filter DCM attitude
+//! estimation algorithm at the rate specified by the \e fDeltaT parameter.
+//! Failure to provide new readings at this rate results in inaccuracies in the
+//! attitude estimation.
+//!
+//! The \e fScaleA, \e fScaleG, and \e fScaleM weights must sum to one.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+CompDCMInit(tCompDCM *psDCM, float fDeltaT, float fScaleA, float fScaleG,
+ float fScaleM)
+{
+ //
+ // Initialize the DCM matrix to the identity matrix.
+ //
+ psDCM->ppfDCM[0][0] = 1.0;
+ psDCM->ppfDCM[0][1] = 0.0;
+ psDCM->ppfDCM[0][2] = 0.0;
+ psDCM->ppfDCM[1][0] = 0.0;
+ psDCM->ppfDCM[1][1] = 1.0;
+ psDCM->ppfDCM[1][2] = 0.0;
+ psDCM->ppfDCM[2][0] = 0.0;
+ psDCM->ppfDCM[2][1] = 0.0;
+ psDCM->ppfDCM[2][2] = 1.0;
+
+ //
+ // Save the time delta between DCM updates.
+ //
+ psDCM->fDeltaT = fDeltaT;
+
+ //
+ // Save the scaling factors that are applied to the accelerometer,
+ // gyroscope, and magnetometer readings.
+ //
+ psDCM->fScaleA = fScaleA;
+ psDCM->fScaleG = fScaleG;
+ psDCM->fScaleM = fScaleM;
+}
+
+//*****************************************************************************
+//
+//! Updates the accelerometer reading used by the complementary filter DCM
+//! algorithm.
+//!
+//! \param psDCM is a pointer to the DCM state structure.
+//! \param fAccelX is the accelerometer reading in the X body axis.
+//! \param fAccelY is the accelerometer reading in the Y body axis.
+//! \param fAccelZ is the accelerometer reading in the Z body axis.
+//!
+//! This function updates the accelerometer reading used by the complementary
+//! filter DCM algorithm. The accelerometer readings provided to this function
+//! are used by subsequent calls to CompDCMStart() and CompDCMUpdate() to
+//! compute the attitude estimate.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+CompDCMAccelUpdate(tCompDCM *psDCM, float fAccelX, float fAccelY,
+ float fAccelZ)
+{
+ //
+ // The user should never pass in values that are not-a-number
+ //
+ ASSERT(!isnan(fAccelX));
+ ASSERT(!isnan(fAccelY));
+ ASSERT(!isnan(fAccelZ));
+
+ //
+ // Save the new accelerometer reading.
+ //
+ psDCM->pfAccel[0] = fAccelX;
+ psDCM->pfAccel[1] = fAccelY;
+ psDCM->pfAccel[2] = fAccelZ;
+}
+
+//*****************************************************************************
+//
+//! Updates the gyroscope reading used by the complementary filter DCM
+//! algorithm.
+//!
+//! \param psDCM is a pointer to the DCM state structure.
+//! \param fGyroX is the gyroscope reading in the X body axis.
+//! \param fGyroY is the gyroscope reading in the Y body axis.
+//! \param fGyroZ is the gyroscope reading in the Z body axis.
+//!
+//! This function updates the gyroscope reading used by the complementary
+//! filter DCM algorithm. The gyroscope readings provided to this function are
+//! used by subsequent calls to CompDCMUpdate() to compute the attitude
+//! estimate.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+CompDCMGyroUpdate(tCompDCM *psDCM, float fGyroX, float fGyroY, float fGyroZ)
+{
+ //
+ // The user should never pass in values that are not-a-number
+ //
+ ASSERT(!isnan(fGyroX));
+ ASSERT(!isnan(fGyroY));
+ ASSERT(!isnan(fGyroZ));
+
+ //
+ // Save the new gyroscope reading.
+ //
+ psDCM->pfGyro[0] = fGyroX;
+ psDCM->pfGyro[1] = fGyroY;
+ psDCM->pfGyro[2] = fGyroZ;
+}
+
+//*****************************************************************************
+//
+//! Updates the magnetometer reading used by the complementary filter DCM
+//! algorithm.
+//!
+//! \param psDCM is a pointer to the DCM state structure.
+//! \param fMagnetoX is the magnetometer reading in the X body axis.
+//! \param fMagnetoY is the magnetometer reading in the Y body axis.
+//! \param fMagnetoZ is the magnetometer reading in the Z body axis.
+//!
+//! This function updates the magnetometer reading used by the complementary
+//! filter DCM algorithm. The magnetometer readings provided to this function
+//! are used by subsequent calls to CompDCMStart() and CompDCMUpdate() to
+//! compute the attitude estimate.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+CompDCMMagnetoUpdate(tCompDCM *psDCM, float fMagnetoX, float fMagnetoY,
+ float fMagnetoZ)
+{
+ //
+ // The user should never pass in values that are not-a-number
+ //
+ ASSERT(!isnan(fMagnetoX));
+ ASSERT(!isnan(fMagnetoY));
+ ASSERT(!isnan(fMagnetoZ));
+
+ //
+ // Save the new magnetometer reading.
+ //
+ psDCM->pfMagneto[0] = fMagnetoX;
+ psDCM->pfMagneto[1] = fMagnetoY;
+ psDCM->pfMagneto[2] = fMagnetoZ;
+}
+
+//*****************************************************************************
+//
+//! Starts the complementary filter DCM attitude estimation from an initial
+//! sensor reading.
+//!
+//! \param psDCM is a pointer to the DCM state structure.
+//!
+//! This function computes the initial complementary filter DCM attitude
+//! estimation state based on the initial accelerometer and magnetometer
+//! reading. While not necessary for the attitude estimation to converge,
+//! using an initial state based on sensor readings results in quicker
+//! convergence.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+CompDCMStart(tCompDCM *psDCM)
+{
+ float pfI[3], pfJ[3], pfK[3];
+
+ //
+ // The magnetometer reading forms the initial I vector, pointing north.
+ //
+ pfI[0] = psDCM->pfMagneto[0];
+ pfI[1] = psDCM->pfMagneto[1];
+ pfI[2] = psDCM->pfMagneto[2];
+
+ //
+ // The accelerometer reading forms the initial K vector, pointing down.
+ //
+ pfK[0] = psDCM->pfAccel[0];
+ pfK[1] = psDCM->pfAccel[1];
+ pfK[2] = psDCM->pfAccel[2];
+
+ //
+ // Compute the initial J vector, which is the cross product of the K and I
+ // vectors.
+ //
+ VectorCrossProduct(pfJ, pfK, pfI);
+
+ //
+ // Recompute the I vector from the cross product of the J and K vectors.
+ // This makes it fully orthogonal, which it wasn't before since magnetic
+ // north points inside the Earth in many places.
+ //
+ VectorCrossProduct(pfI, pfJ, pfK);
+
+ //
+ // Normalize the I, J, and K vectors.
+ //
+ VectorScale(pfI, pfI, 1 / sqrtf(VectorDotProduct(pfI, pfI)));
+ VectorScale(pfJ, pfJ, 1 / sqrtf(VectorDotProduct(pfJ, pfJ)));
+ VectorScale(pfK, pfK, 1 / sqrtf(VectorDotProduct(pfK, pfK)));
+
+ //
+ // Initialize the DCM matrix from the I, J, and K vectors.
+ //
+ psDCM->ppfDCM[0][0] = pfI[0];
+ psDCM->ppfDCM[0][1] = pfI[1];
+ psDCM->ppfDCM[0][2] = pfI[2];
+ psDCM->ppfDCM[1][0] = pfJ[0];
+ psDCM->ppfDCM[1][1] = pfJ[1];
+ psDCM->ppfDCM[1][2] = pfJ[2];
+ psDCM->ppfDCM[2][0] = pfK[0];
+ psDCM->ppfDCM[2][1] = pfK[1];
+ psDCM->ppfDCM[2][2] = pfK[2];
+}
+
+//*****************************************************************************
+//
+//! Updates the complementary filter DCM attitude estimation based on an
+//! updated set of sensor readings.
+//!
+//! \param psDCM is a pointer to the DCM state structure.
+//!
+//! This function updates the complementary filter DCM attitude estimation
+//! state based on the current sensor readings. This function must be called
+//! at the rate specified to CompDCMInit(), with new readings supplied at an
+//! appropriate rate (for example, magnetometers typically sample at a much
+//! slower rate than accelerometers and gyroscopes).
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+CompDCMUpdate(tCompDCM *psDCM)
+{
+ float pfI[3], pfJ[3], pfK[3], pfDelta[3], pfTemp[3], fError;
+ bool bNAN;
+
+ //
+ // The magnetometer reading forms the new Im vector, pointing north.
+ //
+ pfI[0] = psDCM->pfMagneto[0];
+ pfI[1] = psDCM->pfMagneto[1];
+ pfI[2] = psDCM->pfMagneto[2];
+
+ //
+ // The accelerometer reading forms the new Ka vector, pointing down.
+ //
+ pfK[0] = psDCM->pfAccel[0];
+ pfK[1] = psDCM->pfAccel[1];
+ pfK[2] = psDCM->pfAccel[2];
+
+ //
+ // Compute the new J vector, which is the cross product of the Ka and Im
+ // vectors.
+ //
+ VectorCrossProduct(pfJ, pfK, pfI);
+
+ //
+ // Recompute the Im vector from the cross product of the J and Ka vectors.
+ // This makes it fully orthogonal, which it wasn't before since magnetic
+ // north points inside the Earth in many places.
+ //
+ VectorCrossProduct(pfI, pfJ, pfK);
+
+ //
+ // Normalize the Im and Ka vectors.
+ //
+ VectorScale(pfI, pfI, 1 / sqrtf(VectorDotProduct(pfI, pfI)));
+ VectorScale(pfK, pfK, 1 / sqrtf(VectorDotProduct(pfK, pfK)));
+
+ //
+ // Compute and scale the rotation as inferred from the accelerometer,
+ // storing it in the rotation accumulator.
+ //
+ VectorCrossProduct(pfTemp, psDCM->ppfDCM[2], pfK);
+ VectorScale(pfDelta, pfTemp, psDCM->fScaleA);
+
+ //
+ // Compute and scale the rotation as measured by the gyroscope, adding it
+ // to the rotation accumulator.
+ //
+ pfTemp[0] = psDCM->pfGyro[0] * psDCM->fDeltaT * psDCM->fScaleG;
+ pfTemp[1] = psDCM->pfGyro[1] * psDCM->fDeltaT * psDCM->fScaleG;
+ pfTemp[2] = psDCM->pfGyro[2] * psDCM->fDeltaT * psDCM->fScaleG;
+ VectorAdd(pfDelta, pfDelta, pfTemp);
+
+ //
+ // Compute and scale the rotation as inferred from the magnetometer, adding
+ // it to the rotation accumulator.
+ //
+ VectorCrossProduct(pfTemp, psDCM->ppfDCM[0], pfI);
+ VectorScale(pfTemp, pfTemp, psDCM->fScaleM);
+ VectorAdd(pfDelta, pfDelta, pfTemp);
+
+ //
+ // Rotate the I vector from the DCM matrix by the scaled rotation.
+ //
+ VectorCrossProduct(pfI, pfDelta, psDCM->ppfDCM[0]);
+ VectorAdd(psDCM->ppfDCM[0], psDCM->ppfDCM[0], pfI);
+
+ //
+ // Rotate the K vector from the DCM matrix by the scaled rotation.
+ //
+ VectorCrossProduct(pfK, pfDelta, psDCM->ppfDCM[2]);
+ VectorAdd(psDCM->ppfDCM[2], psDCM->ppfDCM[2], pfK);
+
+ //
+ // Compute the orthogonality error between the rotated I and K vectors and
+ // adjust each by half the error, bringing them closer to orthogonality.
+ //
+ fError = VectorDotProduct(psDCM->ppfDCM[0], psDCM->ppfDCM[2]) / -2.0;
+ VectorScale(pfI, psDCM->ppfDCM[0], fError);
+ VectorScale(pfK, psDCM->ppfDCM[2], fError);
+ VectorAdd(psDCM->ppfDCM[0], psDCM->ppfDCM[0], pfK);
+ VectorAdd(psDCM->ppfDCM[2], psDCM->ppfDCM[2], pfI);
+
+ //
+ // Normalize the I and K vectors.
+ //
+ VectorScale(psDCM->ppfDCM[0], psDCM->ppfDCM[0],
+ 0.5 * (3.0 - VectorDotProduct(psDCM->ppfDCM[0],
+ psDCM->ppfDCM[0])));
+ VectorScale(psDCM->ppfDCM[2], psDCM->ppfDCM[2],
+ 0.5 * (3.0 - VectorDotProduct(psDCM->ppfDCM[2],
+ psDCM->ppfDCM[2])));
+
+ //
+ // Compute the rotated J vector from the cross product of the rotated,
+ // corrected K and I vectors.
+ //
+ VectorCrossProduct(psDCM->ppfDCM[1], psDCM->ppfDCM[2], psDCM->ppfDCM[0]);
+
+ //
+ // Determine if the newly updated DCM contains any invalid (in other words,
+ // NaN) values.
+ //
+ bNAN = (isnan(psDCM->ppfDCM[0][0]) ||
+ isnan(psDCM->ppfDCM[0][1]) ||
+ isnan(psDCM->ppfDCM[0][2]) ||
+ isnan(psDCM->ppfDCM[1][0]) ||
+ isnan(psDCM->ppfDCM[1][1]) ||
+ isnan(psDCM->ppfDCM[1][2]) ||
+ isnan(psDCM->ppfDCM[2][0]) ||
+ isnan(psDCM->ppfDCM[2][1]) ||
+ isnan(psDCM->ppfDCM[2][2]));
+
+ //
+ // As a debug measure, we check for NaN in the DCM. The user can trap
+ // this event depending on their implementation of __error__. Should they
+ // choose to disable interrupts and loop forever then they will have
+ // preserved the stack and can analyze how they arrived at NaN.
+ //
+ ASSERT(!bNAN);
+
+ //
+ // If any part of the matrix is not-a-number then reset the DCM back to the
+ // identity matrix.
+ //
+ if(bNAN)
+ {
+ psDCM->ppfDCM[0][0] = 1.0;
+ psDCM->ppfDCM[0][1] = 0.0;
+ psDCM->ppfDCM[0][2] = 0.0;
+ psDCM->ppfDCM[1][0] = 0.0;
+ psDCM->ppfDCM[1][1] = 1.0;
+ psDCM->ppfDCM[1][2] = 0.0;
+ psDCM->ppfDCM[2][0] = 0.0;
+ psDCM->ppfDCM[2][1] = 0.0;
+ psDCM->ppfDCM[2][2] = 1.0;
+ }
+}
+
+//*****************************************************************************
+//
+//! Returns the current DCM attitude estimation matrix.
+//!
+//! \param psDCM is a pointer to the DCM state structure.
+//! \param ppfDCM is a pointer to the array into which to store the DCM matrix
+//! values.
+//!
+//! This function returns the current value of the DCM matrix.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+CompDCMMatrixGet(tCompDCM *psDCM, float ppfDCM[3][3])
+{
+ //
+ // Return the current DCM matrix.
+ //
+ ppfDCM[0][0] = psDCM->ppfDCM[0][0];
+ ppfDCM[0][1] = psDCM->ppfDCM[0][1];
+ ppfDCM[0][2] = psDCM->ppfDCM[0][2];
+ ppfDCM[1][0] = psDCM->ppfDCM[1][0];
+ ppfDCM[1][1] = psDCM->ppfDCM[1][1];
+ ppfDCM[1][2] = psDCM->ppfDCM[1][2];
+ ppfDCM[2][0] = psDCM->ppfDCM[2][0];
+ ppfDCM[2][1] = psDCM->ppfDCM[2][1];
+ ppfDCM[2][2] = psDCM->ppfDCM[2][2];
+}
+
+//*****************************************************************************
+//
+//! Computes the Euler angles from the DCM attitude estimation matrix.
+//!
+//! \param psDCM is a pointer to the DCM state structure.
+//! \param pfRoll is a pointer to the value into which the roll is stored.
+//! \param pfPitch is a pointer to the value into which the pitch is stored.
+//! \param pfYaw is a pointer to the value into which the yaw is stored.
+//!
+//! This function computes the Euler angles that are represented by the DCM
+//! attitude estimation matrix. If any of the Euler angles is not required,
+//! the corresponding parameter can be \b NULL.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+CompDCMComputeEulers(tCompDCM *psDCM, float *pfRoll, float *pfPitch,
+ float *pfYaw)
+{
+ //
+ // Compute the roll, pitch, and yaw as required.
+ //
+ if(pfRoll)
+ {
+ *pfRoll = atan2f(psDCM->ppfDCM[2][1], psDCM->ppfDCM[2][2]);
+ }
+ if(pfPitch)
+ {
+ *pfPitch = -asinf(psDCM->ppfDCM[2][0]);
+ }
+ if(pfYaw)
+ {
+ *pfYaw = atan2f(psDCM->ppfDCM[1][0], psDCM->ppfDCM[0][0]);
+ }
+}
+
+//*****************************************************************************
+//
+//! Computes the quaternion from the DCM attitude estimation matrix.
+//!
+//! \param psDCM is a pointer to the DCM state structure.
+//! \param pfQuaternion is an array into which the quaternion is stored.
+//!
+//! This function computes the quaternion that is represented by the DCM
+//! attitude estimation matrix.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+CompDCMComputeQuaternion(tCompDCM *psDCM, float pfQuaternion[4])
+{
+ float fQs, fQx, fQy, fQz;
+
+ //
+ // Partially compute Qs, Qx, Qy, and Qz based on the DCM diagonals. The
+ // square root, an expensive operation, is computed for only one of these
+ // as determined later.
+ //
+ fQs = 1 + psDCM->ppfDCM[0][0] + psDCM->ppfDCM[1][1] + psDCM->ppfDCM[2][2];
+ fQx = 1 + psDCM->ppfDCM[0][0] - psDCM->ppfDCM[1][1] - psDCM->ppfDCM[2][2];
+ fQy = 1 - psDCM->ppfDCM[0][0] + psDCM->ppfDCM[1][1] - psDCM->ppfDCM[2][2];
+ fQz = 1 - psDCM->ppfDCM[0][0] - psDCM->ppfDCM[1][1] + psDCM->ppfDCM[2][2];
+
+ //
+ // See if Qs is the largest of the diagonal values.
+ //
+ if((fQs > fQx) && (fQs > fQy) && (fQs > fQz))
+ {
+ //
+ // Finish the computation of Qs.
+ //
+ fQs = sqrtf(fQs) / 2;
+
+ //
+ // Compute the values of the quaternion based on Qs.
+ //
+ pfQuaternion[0] = fQs;
+ pfQuaternion[1] = ((psDCM->ppfDCM[2][1] - psDCM->ppfDCM[1][2]) /
+ (4 * fQs));
+ pfQuaternion[2] = ((psDCM->ppfDCM[0][2] - psDCM->ppfDCM[2][0]) /
+ (4 * fQs));
+ pfQuaternion[3] = ((psDCM->ppfDCM[1][0] - psDCM->ppfDCM[0][1]) /
+ (4 * fQs));
+ }
+
+ //
+ // Qs is not the largest, so see if Qx is the largest remaining diagonal
+ // value.
+ //
+ else if((fQx > fQy) && (fQx > fQz))
+ {
+ //
+ // Finish the computation of Qx.
+ //
+ fQx = sqrtf(fQx) / 2;
+
+ //
+ // Compute the values of the quaternion based on Qx.
+ //
+ pfQuaternion[0] = ((psDCM->ppfDCM[2][1] - psDCM->ppfDCM[1][2]) /
+ (4 * fQx));
+ pfQuaternion[1] = fQx;
+ pfQuaternion[2] = ((psDCM->ppfDCM[1][0] + psDCM->ppfDCM[0][1]) /
+ (4 * fQx));
+ pfQuaternion[3] = ((psDCM->ppfDCM[0][2] + psDCM->ppfDCM[2][0]) /
+ (4 * fQx));
+ }
+
+ //
+ // Qs and Qx are not the largest, so see if Qy is the largest remaining
+ // diagonal value.
+ //
+ else if(fQy > fQz)
+ {
+ //
+ // Finish the computation of Qy.
+ //
+ fQy = sqrtf(fQy) / 2;
+
+ //
+ // Compute the values of the quaternion based on Qy.
+ //
+ pfQuaternion[0] = ((psDCM->ppfDCM[0][2] - psDCM->ppfDCM[2][0]) /
+ (4 * fQy));
+ pfQuaternion[1] = ((psDCM->ppfDCM[1][0] + psDCM->ppfDCM[0][1]) /
+ (4 * fQy));
+ pfQuaternion[2] = fQy;
+ pfQuaternion[3] = ((psDCM->ppfDCM[2][1] + psDCM->ppfDCM[1][2]) /
+ (4 * fQy));
+ }
+
+ //
+ // Qz is the largest diagonal value.
+ //
+ else
+ {
+ //
+ // Finish the computation of Qz.
+ //
+ fQz = sqrtf(fQz) / 2;
+
+ //
+ // Compute the values of the quaternion based on Qz.
+ //
+ pfQuaternion[0] = ((psDCM->ppfDCM[1][0] - psDCM->ppfDCM[0][1]) /
+ (4 * fQz));
+ pfQuaternion[1] = ((psDCM->ppfDCM[0][2] + psDCM->ppfDCM[2][0]) /
+ (4 * fQz));
+ pfQuaternion[2] = ((psDCM->ppfDCM[2][1] + psDCM->ppfDCM[1][2]) /
+ (4 * fQz));
+ pfQuaternion[3] = fQz;
+ }
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/comp_dcm.h b/sensorlib/comp_dcm.h new file mode 100644 index 0000000..860bda9 --- /dev/null +++ b/sensorlib/comp_dcm.h @@ -0,0 +1,120 @@ +//*****************************************************************************
+//
+// comp_dcm.h - Prototypes for the complementary filter direction cosine matrix
+// functions.
+//
+// Copyright (c) 2012-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_COMP_DCM_H__
+#define __SENSORLIB_COMP_DCM_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the complementary filter
+// DCM algorithm.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The state of the direction cosine matrix.
+ //
+ float ppfDCM[3][3];
+
+ //
+ // The time delta between updates to the DCM.
+ //
+ float fDeltaT;
+
+ //
+ // The scaling factor for the DCM update based on the accelerometer
+ // reading.
+ //
+ float fScaleA;
+
+ //
+ // The scaling factor for the DCM update based on the gyroscope reading.
+ //
+ float fScaleG;
+
+ //
+ // The scaling factor for the DCM update based on the magnetometer reading.
+ //
+ float fScaleM;
+
+ //
+ // The most recent accelerometer readings.
+ //
+ float pfAccel[3];
+
+ //
+ // The most recent gyroscope readings.
+ //
+ float pfGyro[3];
+
+ //
+ // The most recent magnetometer readings.
+ //
+ float pfMagneto[3];
+}
+tCompDCM;
+
+//*****************************************************************************
+//
+// Prototypes.
+//
+//*****************************************************************************
+extern void CompDCMInit(tCompDCM *psDCM, float fDeltaT, float fScaleA,
+ float fScaleG, float fScaleM);
+extern void CompDCMAccelUpdate(tCompDCM *psDCM, float fAccelX, float fAccelY,
+ float fAccelZ);
+extern void CompDCMGyroUpdate(tCompDCM *psDCM, float fGyroX, float fGyroY,
+ float fGyroZ);
+extern void CompDCMMagnetoUpdate(tCompDCM *psDCM, float fMagnetoX,
+ float fMagnetoY, float fMagnetoZ);
+extern void CompDCMStart(tCompDCM *psDCM);
+extern void CompDCMUpdate(tCompDCM *psDCM);
+extern void CompDCMMatrixGet(tCompDCM *psDCM, float ppfDCM[3][3]);
+extern void CompDCMComputeEulers(tCompDCM *psDCM, float *pfRoll,
+ float *pfPitch, float *pfYaw);
+extern void CompDCMComputeQuaternion(tCompDCM *psDCM, float pfQuaternion[4]);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_COMP_DCM_H__
diff --git a/sensorlib/ewarm/Exe/sensorlib.a b/sensorlib/ewarm/Exe/sensorlib.a Binary files differnew file mode 100644 index 0000000..408cb46 --- /dev/null +++ b/sensorlib/ewarm/Exe/sensorlib.a diff --git a/sensorlib/gcc/libsensor.a b/sensorlib/gcc/libsensor.a Binary files differnew file mode 100644 index 0000000..ae22311 --- /dev/null +++ b/sensorlib/gcc/libsensor.a diff --git a/sensorlib/hw_ak8963.h b/sensorlib/hw_ak8963.h new file mode 100644 index 0000000..53e43f2 --- /dev/null +++ b/sensorlib/hw_ak8963.h @@ -0,0 +1,209 @@ +//*****************************************************************************
+//
+// hw_ak8963.h - Macros used when accessing the Asahi Kasei AK8963
+// magnetometer.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_HW_AK8963_H__
+#define __SENSORLIB_HW_AK8963_H__
+
+//*****************************************************************************
+//
+// The following are defines for the AK8963 register addresses.
+//
+//*****************************************************************************
+#define AK8963_O_WIA 0x00 // Device ID register
+#define AK8963_O_INFO 0x01 // Information register
+#define AK8963_O_ST1 0x02 // Status 1 register
+#define AK8963_O_HXL 0x03 // X-axis LSB output register
+#define AK8963_O_HXH 0x04 // X-axis MSB output register
+#define AK8963_O_HYL 0x05 // Y-axis LSB output register
+#define AK8963_O_HYH 0x06 // Y-axis MSB output register
+#define AK8963_O_HZL 0x07 // Z-axis LSB output register
+#define AK8963_O_HZH 0x08 // Z-axis MSB output register
+#define AK8963_O_ST2 0x09 // Status 2 register
+#define AK8963_O_CNTL 0x0A // Control register
+#define AK8963_O_CNTL2 0x0B // Control 2 register
+#define AK8963_O_ASTC 0x0C // Self-test register
+#define AK8963_O_I2CDIS 0x0F // Disable I2C bus interface
+#define AK8963_O_ASAX 0x10 // X-axis sensitivity register
+#define AK8963_O_ASAY 0x11 // Y-axis sensitivity register
+#define AK8963_O_ASAZ 0x12 // Z-axis sensitivity register
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_WIA register.
+//
+//*****************************************************************************
+#define AK8963_WIA_M 0xFF // Device ID
+#define AK8963_WIA_AK8963 0x48 // AK8963
+#define AK8963_WIA_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_INFO register.
+//
+//*****************************************************************************
+#define AK8963_INFO_M 0xFF // Device information value
+#define AK8963_INFO_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_ST1 register.
+//
+//*****************************************************************************
+#define AK8963_ST1_DOR 0x02 // Data overrun
+#define AK8963_ST1_DRDY 0x01 // Data ready
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_HXL register.
+//
+//*****************************************************************************
+#define AK8963_HXL_M 0xFF // Output data
+#define AK8963_HXL_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_HXH register.
+//
+//*****************************************************************************
+#define AK8963_HXH_M 0xFF // Output data
+#define AK8963_HXH_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_HYL register.
+//
+//*****************************************************************************
+#define AK8963_HYL_M 0xFF // Output data
+#define AK8963_HYL_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_HYH register.
+//
+//*****************************************************************************
+#define AK8963_HYH_M 0xFF // Output data
+#define AK8963_HYH_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_HZL register.
+//
+//*****************************************************************************
+#define AK8963_HZL_M 0xFF // Output data
+#define AK8963_HZL_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_HZH register.
+//
+//*****************************************************************************
+#define AK8963_HZH_M 0xFF // Output data
+#define AK8963_HZH_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_ST2 register.
+//
+//*****************************************************************************
+#define AK8963_ST2_BITM_M 0x10 // Output bit setting
+#define AK8963_ST2_BITM_14BIT 0x00 // 14-bit output
+#define AK8963_ST2_BITM_16BIT 0x10 // 16-bit output
+#define AK8963_ST2_HOFL 0x08 // Magnetic sensor overflow
+#define AK8963_ST2_BITM_S 4
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_CNTL register.
+//
+//*****************************************************************************
+#define AK8963_CNTL_BITM_M 0x10 // Output bit setting
+#define AK8963_CNTL_BITM_14BIT 0x00 // 14-bit output
+#define AK8963_CNTL_BITM_16BIT 0x10 // 16-bit output
+#define AK8963_CNTL_MODE_M 0x0F // Operation mode
+#define AK8963_CNTL_MODE_POWER_DOWN \
+ 0x00 // Power-down mode
+#define AK8963_CNTL_MODE_SINGLE 0x01 // Single measurement mode
+#define AK8963_CNTL_MODE_CONT_1 0x02 // Continuous measurement mode 1
+ // (8Hz)
+#define AK8963_CNTL_MODE_EXT_TRIG \
+ 0x04 // External trigger measurement
+ // mode
+#define AK8963_CNTL_MODE_CONT_2 0x06 // Continuous measurement mode 2
+ // (100Hz)
+#define AK8963_CNTL_MODE_SELF_TEST \
+ 0x08 // Self-test mode
+#define AK8963_CNTL_MODE_FUSE_ROM \
+ 0x0F // Fuse ROM access mode
+#define AK8963_CNTL_BITM_S 4
+#define AK8963_CNTL_MODE_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_CNTL2 register.
+//
+//*****************************************************************************
+#define AK8963_CNTL2_SRST 0x01 // Register reset
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_ASTC register.
+//
+//*****************************************************************************
+#define AK8963_ASTC_SELF 0x40 // Generate magnetic field for
+ // self-test
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_I2CDIS
+// register.
+//
+//*****************************************************************************
+#define AK8963_I2CDIS_I2CDIS 0xFF // Disable I2C bus interface
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_ASAX register.
+//
+//*****************************************************************************
+#define AK8963_ASAX_M 0xFF // X-axis sensitivity adjustment
+#define AK8963_ASAX_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_ASAY register.
+//
+//*****************************************************************************
+#define AK8963_ASAY_M 0xFF // Y-axis sensitivity adjustment
+#define AK8963_ASAY_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8963_O_ASAZ register.
+//
+//*****************************************************************************
+#define AK8963_ASAZ_M 0xFF // Z-axis sensitivity adjustment
+#define AK8963_ASAZ_S 0
+
+#endif // __SENSORLIB_HW_AK8963_H__
diff --git a/sensorlib/hw_ak8975.h b/sensorlib/hw_ak8975.h new file mode 100644 index 0000000..e1cb847 --- /dev/null +++ b/sensorlib/hw_ak8975.h @@ -0,0 +1,177 @@ +//*****************************************************************************
+//
+// hw_ak8975.h - Macros used when accessing the Asahi Kasei AK8975
+// magnetometer.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_HW_AK8975_H__
+#define __SENSORLIB_HW_AK8975_H__
+
+//*****************************************************************************
+//
+// The following are defines for the AK8975 register addresses.
+//
+//*****************************************************************************
+#define AK8975_O_WIA 0x00 // Device ID register
+#define AK8975_O_INFO 0x01 // Information register
+#define AK8975_O_ST1 0x02 // Status 1 register
+#define AK8975_O_HXL 0x03 // X-axis LSB output register
+#define AK8975_O_HXH 0x04 // X-axis MSB output register
+#define AK8975_O_HYL 0x05 // Y-axis LSB output register
+#define AK8975_O_HYH 0x06 // Y-axis MSB output register
+#define AK8975_O_HZL 0x07 // Z-axis LSB output register
+#define AK8975_O_HZH 0x08 // Z-axis MSB output register
+#define AK8975_O_ST2 0x09 // Status 2 register
+#define AK8975_O_CNTL 0x0A // Control register
+#define AK8975_O_ASTC 0x0C // Self-test register
+#define AK8975_O_ASAX 0x10 // X-axis sensitivity register
+#define AK8975_O_ASAY 0x11 // Y-axis sensitivity register
+#define AK8975_O_ASAZ 0x12 // Z-axis sensitivity register
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8975_O_WIA register.
+//
+//*****************************************************************************
+#define AK8975_WIA_M 0xFF // Device ID
+#define AK8975_WIA_AK8975 0x48 // AK8975
+#define AK8975_WIA_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8975_O_INFO register.
+//
+//*****************************************************************************
+#define AK8975_INFO_M 0xFF // Device information value
+#define AK8975_INFO_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8975_O_ST1 register.
+//
+//*****************************************************************************
+#define AK8975_ST1_DRDY 0x01 // Data ready
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8975_O_HXL register.
+//
+//*****************************************************************************
+#define AK8975_HXL_M 0xFF // Output data
+#define AK8975_HXL_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8975_O_HXH register.
+//
+//*****************************************************************************
+#define AK8975_HXH_M 0xFF // Output data
+#define AK8975_HXH_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8975_O_HYL register.
+//
+//*****************************************************************************
+#define AK8975_HYL_M 0xFF // Output data
+#define AK8975_HYL_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8975_O_HYH register.
+//
+//*****************************************************************************
+#define AK8975_HYH_M 0xFF // Output data
+#define AK8975_HYH_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8975_O_HZL register.
+//
+//*****************************************************************************
+#define AK8975_HZL_M 0xFF // Output data
+#define AK8975_HZL_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8975_O_HZH register.
+//
+//*****************************************************************************
+#define AK8975_HZH_M 0xFF // Output data
+#define AK8975_HZH_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8975_O_ST2 register.
+//
+//*****************************************************************************
+#define AK8975_ST2_HOFL 0x08 // Magnetic sensor overflow
+#define AK8975_ST2_DERR 0x04 // Data error
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8975_O_CNTL register.
+//
+//*****************************************************************************
+#define AK8975_CNTL_MODE_M 0x0F // Operation mode
+#define AK8975_CNTL_MODE_POWER_DOWN \
+ 0x00 // Power-down mode
+#define AK8975_CNTL_MODE_SINGLE 0x01 // Single measurement mode
+#define AK8975_CNTL_MODE_SELF_TEST \
+ 0x08 // Self-test mode
+#define AK8975_CNTL_MODE_FUSE_ROM \
+ 0x0F // Fuse ROM access mode
+#define AK8975_CNTL_MODE_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8975_O_ASTC register.
+//
+//*****************************************************************************
+#define AK8975_ASTC_SELF 0x40 // Generate magnetic field for
+ // self-test
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8975_O_ASAX register.
+//
+//*****************************************************************************
+#define AK8975_ASAX_M 0xFF // X-axis sensitivity adjustment
+#define AK8975_ASAX_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8975_O_ASAY register.
+//
+//*****************************************************************************
+#define AK8975_ASAY_M 0xFF // Y-axis sensitivity adjustment
+#define AK8975_ASAY_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the AK8975_O_ASAZ register.
+//
+//*****************************************************************************
+#define AK8975_ASAZ_M 0xFF // Z-axis sensitivity adjustment
+#define AK8975_ASAZ_S 0
+
+#endif // __SENSORLIB_HW_AK8975_H__
diff --git a/sensorlib/hw_bmp180.h b/sensorlib/hw_bmp180.h new file mode 100644 index 0000000..7f8e3fe --- /dev/null +++ b/sensorlib/hw_bmp180.h @@ -0,0 +1,349 @@ +//*****************************************************************************
+//
+// hw_bmp180.h - Macros used when accessing the Bosch BMP180 barometric
+// pressure sensor.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_HW_BMP180_H__
+#define __SENSORLIB_HW_BMP180_H__
+
+//*****************************************************************************
+//
+// The following are defines for the BMP180 register addresses.
+//
+//*****************************************************************************
+#define BMP180_O_AC1_MSB 0xAA // AC1 MSB register
+#define BMP180_O_AC1_LSB 0xAB // AC1 LSB register
+#define BMP180_O_AC2_MSB 0xAC // AC2 MSB register
+#define BMP180_O_AC2_LSB 0xAD // AC2 LSB register
+#define BMP180_O_AC3_MSB 0xAE // AC3 MSB register
+#define BMP180_O_AC3_LSB 0xAF // AC3 LSB register
+#define BMP180_O_AC4_MSB 0xB0 // AC4 MSB register
+#define BMP180_O_AC4_LSB 0xB1 // AC4 LSB register
+#define BMP180_O_AC5_MSB 0xB2 // AC5 MSB register
+#define BMP180_O_AC5_LSB 0xB3 // AC5 LSB register
+#define BMP180_O_AC6_MSB 0xB4 // AC6 MSB register
+#define BMP180_O_AC6_LSB 0xB5 // AC6 LSB register
+#define BMP180_O_B1_MSB 0xB6 // B1 MSB register
+#define BMP180_O_B1_LSB 0xB7 // B1 LSB register
+#define BMP180_O_B2_MSB 0xB8 // B2 MSB register
+#define BMP180_O_B2_LSB 0xB9 // B2 LSB register
+#define BMP180_O_MB_MSB 0xBA // MB MSB register
+#define BMP180_O_MB_LSB 0xBB // MB LSB register
+#define BMP180_O_MC_MSB 0xBC // MC MSB register
+#define BMP180_O_MC_LSB 0xBD // MC LSB register
+#define BMP180_O_MD_MSB 0xBE // MD MSB register
+#define BMP180_O_MD_LSB 0xBF // MD LSB register
+#define BMP180_O_ID 0xD0 // Device ID register
+#define BMP180_O_SOFT_RESET 0xE0 // Soft reset register
+#define BMP180_O_CTRL_MEAS 0xF4 // Measurement control register
+#define BMP180_O_OUT_MSB 0xF6 // ADC data MSB register
+#define BMP180_O_OUT_LSB 0xF7 // ADC data LSB register
+#define BMP180_O_OUT_XLSB 0xF8 // ADC data XLSB register
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_AC1_MSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_AC1_MSB_M 0xFF // MSB of AC1 calibration
+ // coefficient
+#define BMP180_AC1_MSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_AC1_LSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_AC1_LSB_M 0xFF // LSB of AC1 calibration
+ // coefficient
+#define BMP180_AC1_LSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_AC2_MSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_AC2_MSB_M 0xFF // MSB of AC2 calibration
+ // coefficient
+#define BMP180_AC2_MSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_AC2_LSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_AC2_LSB_M 0xFF // LSB of AC2 calibration
+ // coefficient
+#define BMP180_AC2_LSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_AC3_MSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_AC3_MSB_M 0xFF // MSB of AC3 calibration
+ // coefficient
+#define BMP180_AC3_MSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_AC3_LSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_AC3_LSB_M 0xFF // LSB of AC3 calibration
+ // coefficient
+#define BMP180_AC3_LSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_AC4_MSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_AC4_MSB_M 0xFF // MSB of AC4 calibration
+ // coefficient
+#define BMP180_AC4_MSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_AC4_LSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_AC4_LSB_M 0xFF // LSB of AC4 calibration
+ // coefficient
+#define BMP180_AC4_LSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_AC5_MSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_AC5_MSB_M 0xFF // MSB of AC5 calibration
+ // coefficient
+#define BMP180_AC5_MSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_AC5_LSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_AC5_LSB_M 0xFF // LSB of AC5 calibration
+ // coefficient
+#define BMP180_AC5_LSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_AC6_MSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_AC6_MSB_M 0xFF // MSB of AC6 calibration
+ // coefficient
+#define BMP180_AC6_MSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_AC6_LSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_AC6_LSB_M 0xFF // LSB of AC6 calibration
+ // coefficient
+#define BMP180_AC6_LSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_B1_MSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_B1_MSB_M 0xFF // MSB of B1 calibration
+ // coefficient
+#define BMP180_B1_MSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_B1_LSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_B1_LSB_M 0xFF // LSB of B1 calibration
+ // coefficient
+#define BMP180_B1_LSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_B2_MSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_B2_MSB_M 0xFF // MSB of B2 calibration
+ // coefficient
+#define BMP180_B2_MSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_B2_LSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_B2_LSB_M 0xFF // LSB of B2 calibration
+ // coefficient
+#define BMP180_B2_LSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_MB_MSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_MB_MSB_M 0xFF // MSB of MB calibration
+ // coefficient
+#define BMP180_MB_MSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_MB_LSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_MB_LSB_M 0xFF // LSB of MB calibration
+ // coefficient
+#define BMP180_MB_LSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_MC_MSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_MC_MSB_M 0xFF // MSB of MC calibration
+ // coefficient
+#define BMP180_MC_MSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_MC_LSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_MC_LSB_M 0xFF // LSB of MC calibration
+ // coefficient
+#define BMP180_MC_LSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_MD_MSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_MD_MSB_M 0xFF // MSB of MD calibration
+ // coefficient
+#define BMP180_MD_MSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_MD_LSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_MD_LSB_M 0xFF // LSB of MD calibration
+ // coefficient
+#define BMP180_MD_LSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_ID register.
+//
+//*****************************************************************************
+#define BMP180_ID_M 0xFF // Device ID
+#define BMP180_ID_BMP180 0x55 // BMP180
+#define BMP180_ID_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_SOFT_RESET
+// register.
+//
+//*****************************************************************************
+#define BMP180_SOFT_RESET_M 0xFF // Soft reset value
+#define BMP180_SOFT_RESET_VALUE 0xB6 // Request a soft reset
+#define BMP180_SOFT_RESET_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_CTRL_MEAS
+// register.
+//
+//*****************************************************************************
+#define BMP180_CTRL_MEAS_OSS_M 0xC0 // Oversampling ratio
+#define BMP180_CTRL_MEAS_OSS_1 0x00 // Single sampling
+#define BMP180_CTRL_MEAS_OSS_2 0x40 // 2x oversampling
+#define BMP180_CTRL_MEAS_OSS_4 0x80 // 4x oversampling
+#define BMP180_CTRL_MEAS_OSS_8 0xC0 // 8x oversampling
+#define BMP180_CTRL_MEAS_SCO 0x20 // Start of conversion
+#define BMP180_CTRL_MEAS_M 0x1F // Measurement control
+#define BMP180_CTRL_MEAS_TEMPERATURE \
+ 0x0E // Temperature measurement
+#define BMP180_CTRL_MEAS_PRESSURE \
+ 0x14 // Pressure measurement
+#define BMP180_CTRL_MEAS_OSS_S 6
+#define BMP180_CTRL_MEAS_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_OUT_MSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_OUT_MSB_M 0xFF // Bits [20:13] of the ADC data
+#define BMP180_OUT_MSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_OUT_LSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_OUT_LSB_M 0xFF // Bits [12:5] of the ADC data
+#define BMP180_OUT_LSB_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BMP180_O_OUT_XLSB
+// register.
+//
+//*****************************************************************************
+#define BMP180_OUT_XLSB_M 0xF8 // Bits [4:0] of the ADC data
+#define BMP180_OUT_XLSB_S 3
+
+#endif // __SENSORLIB_HW_BMP180_H__
diff --git a/sensorlib/hw_bq27510g3.h b/sensorlib/hw_bq27510g3.h new file mode 100644 index 0000000..f0b3309 --- /dev/null +++ b/sensorlib/hw_bq27510g3.h @@ -0,0 +1,148 @@ +//*****************************************************************************
+//
+// hw_bq27510g3.h - Macros used when accessing the TI BQ27510-G3 Fuel Gauge
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_HW_BQ27510G3_H__
+#define __SENSORLIB_HW_BQ27510G3_H__
+
+//*****************************************************************************
+//
+// The following are defines for the BQ27510G3 register addresses
+//
+//*****************************************************************************
+#define BQ27510G3_O_CNTL_LSB 0x00 // System Control Register LSB
+#define BQ27510G3_O_CNTL_MSB 0x01 // System Control Register MSB
+#define BQ27510G3_O_AT_RATE_LSB 0x02 // Discharge current value LSB
+#define BQ27510G3_O_AT_RATE_MSB 0x03 // Discharge current value MSB
+#define BQ27510G3_O_AT_RATE_TTE_LSB \
+ 0x04 // Remaining operating time of
+ // battery with current AT_RATE LSB
+#define BQ27510G3_O_AT_RATE_TTE_MSB \
+ 0x05 // Remaining operating time of
+ // battery with current AT_RATE MSB
+#define BQ27510G3_O_TEMP_LSB 0x06 // Battery temperature LSB
+#define BQ27510G3_O_TEMP_MSB 0x07 // Battery temperature MSB
+#define BQ27510G3_O_VOLT_LSB 0x08 // Battery cell-pack voltage LSB
+#define BQ27510G3_O_VOLT_MSB 0x09 // Battery cell-pack voltage MSB
+#define BQ27510G3_O_FLAGS_LSB 0x0A // Holds various operating status
+ // value of gas-guage LSB
+#define BQ27510G3_O_FLAGS_MSB 0x0B // Holds various operating status
+ // value of gas-guage MSB
+#define BQ27510G3_O_NOM_AV_CAP_LSB \
+ 0x0C // Uncompensated battery capacity
+ // remaining LSB
+#define BQ27510G3_O_NOM_AV_CAP_MSB \
+ 0x0D // Uncompensated battery capacity
+ // remaining MSB
+#define BQ27510G3_O_FULL_AV_CAP_LSB \
+ 0x0E // Uncompensated capacity of fully
+ // charged battery LSB
+#define BQ27510G3_O_FULL_AV_CAP_MSB \
+ 0x0F // Uncompensated capacity of fully
+ // charged battery MSB
+#define BQ27510G3_O_REM_CAP_LSB 0x10 // Compensated battery capacity
+ // remaining LSB
+#define BQ27510G3_O_REM_CAP_MSB 0x11 // Compensated battery capacity
+ // remaining MSB
+#define BQ27510G3_O_FULL_CHRG_CAP_LSB \
+ 0x12 // Compensated battery capacity
+ // when fully charged LSB
+#define BQ27510G3_O_FULL_CHRG_CAP_MSB \
+ 0x13 // Compensated battery capacity
+ // when fully charged MSB
+#define BQ27510G3_O_AVG_I_LSB 0x14 // Average current flow through
+ // sense resistor LSB
+#define BQ27510G3_O_AVG_I_MSB 0x15 // Average current flow through
+ // sense resistor MSB
+#define BQ27510G3_O_TTE_LSB 0x16 // Predicted remaining battery life
+ // (minutes) LSB
+#define BQ27510G3_O_TTE_MSB 0x17 // Predicted remaining battery life
+ // (minutes) MSB
+#define BQ27510G3_O_STBY_I_LSB 0x18 // Standbye current through sense
+ // resistor LSB
+#define BQ27510G3_O_STBY_I_MSB 0x19 // Standbye current through sense
+ // resistor MSB
+#define BQ27510G3_O_STBY_TTE_LSB \
+ 0x1A // Predicted remaining standby
+ // battery life LSB
+#define BQ27510G3_O_STBY_TTE_MSB \
+ 0x1B // Predicted remaining standby
+ // battery life MSB
+#define BQ27510G3_O_STATE_OF_HEALTH_LSB \
+ 0x1C // State of health (percent) LSB
+#define BQ27510G3_O_STATE_OF_HEALTH_MSB \
+ 0x1D // State of health (percent) MSB
+#define BQ27510G3_O_CYC_COUNT_LSB \
+ 0x1E // Number of battery cycles
+ // experienced LSB
+#define BQ27510G3_O_CYC_COUNT_MSB \
+ 0x1F // Number of battery cycles
+ // experienced MSB
+#define BQ27510G3_O_STATE_OF_CHRG_LSB \
+ 0x20 // State of charge (percent) LSB
+#define BQ27510G3_O_STATE_OF_CHRG_MSB \
+ 0x21 // State of charge (percent) MSB
+#define BQ27510G3_O_INST_I_LSB 0x22 // Instananeous current flow
+ // through sense resistor LSB
+#define BQ27510G3_O_INST_I_MSB 0x23 // Instananeous current flow
+ // through sense resistor MSB
+#define BQ27510G3_O_INT_TEMP_LSB \
+ 0x28 // Internal tmeperature LSB
+#define BQ27510G3_O_INT_TEMP_MSB \
+ 0x29 // Internal tmeperature MSB
+#define BQ27510G3_O_RES_SCALE_LSB \
+ 0x2A // Resistance Scale LSB
+#define BQ27510G3_O_RES_SCALE_MSB \
+ 0x2B // Resistance Scale MSB
+#define BQ27510G3_O_OP_CFG_LSB 0x2C // Operating Configuration LSB
+#define BQ27510G3_O_OP_CFG_MSB 0x2D // Operating Configuration MSB
+#define BQ27510G3_O_DCAP_LSB 0x2E // Designed capacity of battery LSB
+#define BQ27510G3_O_DCAP_MSB 0x2F // Designed capacity of battery MSB
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the BQ27510G3_O_CNTL_LSB
+// register.
+//
+//*****************************************************************************
+#define BQ27510G3_CNTL_LSB_FUNC_M \
+ 0xFF // Functions
+#define BQ27510G3_CNTL_LSB_FUNC_STATUS \
+ 0x00 // reports DF checksum, hibernate,
+ // IT, etc
+#define BQ27510G3_CNTL_LSB_FUNC_DEVTYPE \
+ 0x01 // reports device type (for
+ // example: 0x0520)
+#define BQ27510G3_CNTL_LSB_FUNC_FWVER \
+ 0x02 // reports firmware version on the
+ // device type
+#define BQ27510G3_CNTL_LSB_FUNC_PREVCMD \
+ 0x07 // reports previous Control()
+ // subcommand code
+#define BQ27510G3_CNTL_LSB_FUNC_RESET \
+ 0x41 // forces a full reset of the fuel
+ // gauge
+#define BQ27510G3_CNTL_LSB_FUNC_S \
+ 0
+
+#endif // __SENSORLIB_HW_BQ27510G3_H__
diff --git a/sensorlib/hw_cm3218.h b/sensorlib/hw_cm3218.h new file mode 100644 index 0000000..87f959b --- /dev/null +++ b/sensorlib/hw_cm3218.h @@ -0,0 +1,96 @@ +//*****************************************************************************
+//
+// hw_cm3218.h - Macros used for accessing the Capella CM3218 ambient light
+// sensor
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_HW_CM3218_H__
+#define __SENSORLIB_HW_CM3218_H__
+
+//*****************************************************************************
+//
+// The following are defines for the CM3218 Commands and Registers
+//
+//*****************************************************************************
+#define CM3218_CMD_CONFIG 0x00 // Configure sensitivity,
+ // integration time, persistence
+ // protect, interrupts, and power
+#define CM3218_CMD_HIGH_THRESHOLD \
+ 0x01 // High threshold window setting
+#define CM3218_CMD_LOW_THRESHOLD \
+ 0x02 // Low threshold window setting
+#define CM3218_CMD_ALS_DATA 0x04 // Read ambient light data
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the CM3218_CMD_CONFIG
+// register.
+//
+//*****************************************************************************
+#define CM3218_CMD_CONFIG_SM_M 0x1800 // ALS sensitivity mode selection
+#define CM3218_CMD_CONFIG_SM_10 0x0000 // Sensitivty * 1.0
+#define CM3218_CMD_CONFIG_SM_20 0x0800 // Sensitivty * 2.0
+#define CM3218_CMD_CONFIG_SM_05 0x1000 // Sensitivty * 0.5
+#define CM3218_CMD_CONFIG_SM_RSVD \
+ 0x1800 // Reserved
+#define CM3218_CMD_CONFIG_IT_M 0x00C0 // ALS integration time setting
+#define CM3218_CMD_CONFIG_IT_05 0x0000 // integration time 0.5T
+#define CM3218_CMD_CONFIG_IT_10 0x0040 // integration time 1.0T (default)
+#define CM3218_CMD_CONFIG_IT_20 0x0080 // integration time 2.0T
+#define CM3218_CMD_CONFIG_IT_40 0x00C0 // integration time 4.0T
+#define CM3218_CMD_CONFIG_PERS_M \
+ 0x0030 // ALS persistence protect number
+ // setting
+#define CM3218_CMD_CONFIG_PERS_1 \
+ 0x0000 // Persistence setting of 1
+#define CM3218_CMD_CONFIG_PERS_2 \
+ 0x0010 // Persistence setting of 2
+#define CM3218_CMD_CONFIG_PERS_4 \
+ 0x0020 // Persistence setting of 4
+#define CM3218_CMD_CONFIG_PERS_8 \
+ 0x0030 // Persistence setting of 8
+#define CM3218_CMD_CONFIG_RSVD_M \
+ 0x00C // Reserved
+#define CM3218_CMD_CONFIG_RSVD_DEFAULT \
+ 0x0004 // Default setting
+#define CM3218_CMD_CONFIG_INT_M 0x2 // Interrupt Control
+#define CM3218_CMD_CONFIG_INT_DISABLE \
+ 0x0 // Disable interrupts
+#define CM3218_CMD_CONFIG_INT_ENABLE \
+ 0x2 // Enable interrupts
+#define CM3218_CMD_CONFIG_POWER_M \
+ 0x1 // Power Control
+#define CM3218_CMD_CONFIG_POWER_ON \
+ 0x0 // Power On
+#define CM3218_CMD_CONFIG_POWER_OFF \
+ 0x1 // Power Off
+#define CM3218_CMD_CONFIG_SM_S 11
+#define CM3218_CMD_CONFIG_IT_S 6
+#define CM3218_CMD_CONFIG_PERS_S \
+ 4
+#define CM3218_CMD_CONFIG_RSVD_S \
+ 2
+#define CM3218_CMD_CONFIG_INT_S 1
+#define CM3218_CMD_CONFIG_POWER_S \
+ 0
+
+#endif // __SENSORLIB_HW_CM3218_H__
diff --git a/sensorlib/hw_isl29023.h b/sensorlib/hw_isl29023.h new file mode 100644 index 0000000..66f65ea --- /dev/null +++ b/sensorlib/hw_isl29023.h @@ -0,0 +1,128 @@ +//*****************************************************************************
+//
+// hw_isl29023.h - Macros used when accessing the Intersil ISL29023 ambient
+// light sensor
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_HW_ISL29023_H__
+#define __SENSORLIB_HW_ISL29023_H__
+
+//*****************************************************************************
+//
+// The following are defines for the ISL29023 Register Addresses
+//
+//*****************************************************************************
+#define ISL29023_O_CMD_I 0x00 // ISL29023 command register one
+#define ISL29023_O_CMD_II 0x01
+#define ISL29023_O_DATA_OUT_LSB 0x02 // Least significant byte of data
+#define ISL29023_O_DATA_OUT_MSB 0x03 // Most significant byte of data
+#define ISL29023_O_INT_LT_LSB 0x04 // Interrupt lower threshold least
+ // significant byte.
+#define ISL29023_O_INT_LT_MSB 0x05 // Interrupt lower threshold most
+ // significant byte.
+#define ISL29023_O_INT_HT_LSB 0x06 // Interrupt high threshold least
+ // significant byte.
+#define ISL29023_O_INT_HT_MSB 0x07 // Interrupt high threshold most
+ // signficant byte
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the ISL29023_O_CMD_I
+// register.
+//
+//*****************************************************************************
+#define ISL29023_CMD_I_OP_MODE_M \
+ 0xE0 // Operation Mode
+#define ISL29023_CMD_I_OP_MODE_POWER_DOWN \
+ 0x00 // Power Down the device (Default)
+#define ISL29023_CMD_I_OP_MODE_RESERVED_3 \
+ 0x0E // RESERVED
+#define ISL29023_CMD_I_OP_MODE_ALS_LOW \
+ 0x20 // Measure ALS once per integration
+ // cyle
+#define ISL29023_CMD_I_OP_MODE_IR_ONCE \
+ 0x40 // Measure IR once
+#define ISL29023_CMD_I_OP_MODE_RESERVED_1 \
+ 0x60 // RESERVED
+#define ISL29023_CMD_I_OP_MODE_RESERVED_2 \
+ 0x80 // RESERVED
+#define ISL29023_CMD_I_OP_MODE_ALS_CONT \
+ 0xA0 // Measure ambient light sensor
+ // continuously.
+#define ISL29023_CMD_I_OP_MODE_IR_CONT \
+ 0xC // Measure infrared sensor
+ // continuously
+#define ISL29023_CMD_I_INT_FLAG_M \
+ 0x04 // Interrupt flag
+#define ISL29023_CMD_I_INT_FLAG 0x04 // Interrupt flag
+#define ISL29023_CMD_I_INT_PERSIST_M \
+ 0x03 // Consecutive measurements outside
+ // threshold before interrupt
+#define ISL29023_CMD_I_INT_PERSIST_1 \
+ 0x00 // Interrupt on first cycle outside
+ // threshold
+#define ISL29023_CMD_I_INT_PERSIST_4 \
+ 0x01 // Interrupt on fourth cycle
+ // oustside threshold
+#define ISL29023_CMD_I_INT_PERSIST_8 \
+ 0x02 // Interrupt on eigth cycle outside
+ // threshold
+#define ISL29023_CMD_I_INT_PERSIST_16 \
+ 0x03 // Interrupt on sixteenth cycle
+ // outside threshold
+#define ISL29023_CMD_I_OP_MODE_S \
+ 5
+#define ISL29023_CMD_I_INT_FLAG_S \
+ 2
+#define ISL_29023_CMD_I_INT_PERSIST_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the ISL29023_O_CMD_II
+// register.
+//
+//*****************************************************************************
+#define ISL29023_CMD_II_ADC_RES_M \
+ 0x0C // ADC resolution setting
+#define ISL29023_CMD_II_ADC_RES_16 \
+ 0x00 // 16 bit resolution
+#define ISL29023_CMD_II_ADC_RES_12 \
+ 0x04 // 12 bit resolution
+#define ISL29023_CMD_II_ADC_RES_8 \
+ 0x08 // 8 bit resolution
+#define ISL29023_CMD_II_ADC_RES_4 \
+ 0x0C // 4 bit resolution
+#define ISL29023_CMD_II_RANGE_M 0x03 // Sensor Range Setting in Lux
+#define ISL29023_CMD_II_RANGE_1K \
+ 0x00 // 1000 lux range
+#define ISL29023_CMD_II_RANGE_4K \
+ 0x01 // 4000 lux range
+#define ISL29023_CMD_II_RANGE_16K \
+ 0x02 // 16000 lux range
+#define ISL29023_CMD_II_RANGE_64K \
+ 0x03 // 64000 lux range
+#define ISL29023_CMD_II_ADC_RES_S \
+ 2
+#define ISL29023_CMD_II_RANGE_S 0
+
+#endif // __SENSORLIB_HW_ISL29023_H__
diff --git a/sensorlib/hw_kxti9.h b/sensorlib/hw_kxti9.h new file mode 100644 index 0000000..4ffc53a --- /dev/null +++ b/sensorlib/hw_kxti9.h @@ -0,0 +1,619 @@ +//*****************************************************************************
+//
+// hw_kxti9.h - Macros used when accessing the Kionix KXTI9 accelerometer.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_HW_KXTI9_H__
+#define __SENSORLIB_HW_KXTI9_H__
+
+//*****************************************************************************
+//
+// The following are defines for the KXTI9 register addresses.
+//
+//*****************************************************************************
+#define KXTI9_O_XOUT_HFP_L 0x00 // X-axis high-pass data LSB
+ // register
+#define KXTI9_O_XOUT_HFP_H 0x01 // X-axis high-pass data MSB
+ // register
+#define KXTI9_O_YOUT_HFP_L 0x02 // Y-axis high-pass data LSB
+ // register
+#define KXTI9_O_YOUT_HFP_H 0x03 // Y-axis high-pass data MSB
+ // register
+#define KXTI9_O_ZOUT_HFP_L 0x04 // Z-axis high-pass data LSB
+ // register
+#define KXTI9_O_ZOUT_HFP_H 0x05 // Z-axis high-pass data MSB
+ // register
+#define KXTI9_O_XOUT_L 0x06 // X-axis data LSB register
+#define KXTI9_O_XOUT_H 0x07 // X-axis data MSB register
+#define KXTI9_O_YOUT_L 0x08 // Y-axis data LSB register
+#define KXTI9_O_YOUT_H 0x09 // Y-axis data MSB register
+#define KXTI9_O_ZOUT_L 0x0A // Z-axis data LSB register
+#define KXTI9_O_ZOUT_H 0x0B // Z-axis data MSB register
+#define KXTI9_O_DCST_RESP 0x0C // Digital Control Status register
+#define KXTI9_O_WHO_AM_I 0x0F // Who Am I register
+#define KXTI9_O_TILT_POS_CUR 0x10 // Current tilt position register
+#define KXTI9_O_TILT_POS_PRE 0x11 // Previous tilt position register
+#define KXTI9_O_INT_SRC1 0x15 // Interrupt source register 1
+#define KXTI9_O_INT_SRC2 0x16 // Interrupt source register2
+#define KXTI9_O_STATUS 0x18 // Status register
+#define KXTI9_O_INT_REL 0x1A // Interrupt clear/release register
+#define KXTI9_O_CTRL1 0x1B // Control register 1
+#define KXTI9_O_CTRL2 0x1C // Control register 2
+#define KXTI9_O_CTRL3 0x1D // Control register 3
+#define KXTI9_O_INT_CTRL1 0x1E // Interrupt control register 1
+#define KXTI9_O_INT_CTRL2 0x1F // Interrupt control register 2
+#define KXTI9_O_INT_CTRL3 0x20 // Interrupt control register 3
+#define KXTI9_O_DATA_CTRL 0x21 // Data control register
+#define KXTI9_O_TILT_TIMER 0x28 // Tilt timer register
+#define KXTI9_O_WUF_TIMER 0x29 // Wake-up timer register
+#define KXTI9_O_TDT_TIMER 0x2B // TDT timer register
+#define KXTI9_O_TDT_H_THRESH 0x2C // Jerk threshold high register
+#define KXTI9_O_TDT_L_THRESH 0x2D // Jerk threshold low register
+#define KXTI9_O_TDT_TAP_TIMER 0x2E // TDT tap timer register
+#define KXTI9_O_TDT_TOTAL_TIMER 0x2F // TDT double tap timer register
+#define KXTI9_O_TDT_LATENCY_TIMER \
+ 0x30 // TDT tap latency timer register
+#define KXTI9_O_TDT_WINDOW_TIMER \
+ 0x31 // TDT tap window timer register
+#define KXTI9_O_BUF_CTRL1 0x32 // Buffer control 1 register
+#define KXTI9_O_BUF_CTRL2 0x33 // Buffer control 2 register
+#define KXTI9_O_STATUS1 0x34 // Buffer status 1 register
+#define KXTI9_O_STATUS2 0x35 // Buffer status 2 register
+#define KXTI9_O_BUF_CLEAR 0x36 // Buffer status clear register
+#define KXTI9_O_SELF_TEST 0x3A // Self-test register
+#define KXTI9_O_WUF_THRESH 0x5A // Wake-up threshold register
+#define KXTI9_O_TILT_ANGLE 0x5C // Tilt angle register
+#define KXTI9_O_HYST_SET 0x5F // Hysteresis set register
+#define KXTI9_O_BUF_READ 0x7F // Buffer read register
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_XOUT_HPF_L
+// register.
+//
+//*****************************************************************************
+#define KXTI9_XOUT_HPF_L_M 0xF0 // Bits [3:0] of high-pass filtered
+ // X-axis data
+#define KXTI9_XOUT_HPF_L_S 4
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_XOUT_HPF_H
+// register.
+//
+//*****************************************************************************
+#define KXTI9_XOUT_HPF_H_M 0xFF // Bits [11:4] of high-pass
+ // filtered X-axis data
+#define KXTI9_XOUT_HPF_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_YOUT_HPF_L
+// register.
+//
+//*****************************************************************************
+#define KXTI9_YOUT_HPF_L_M 0xF0 // Bits [3:0] of high-pass filtered
+ // Y-axis data
+#define KXTI9_YOUT_HPF_L_S 4
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_YOUT_HPF_H
+// register.
+//
+//*****************************************************************************
+#define KXTI9_YOUT_HPF_H_M 0xFF // Bits [11:4] of high-pass
+ // filtered Y-axis data
+#define KXTI9_YOUT_HPF_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_ZOUT_HPF_L
+// register.
+//
+//*****************************************************************************
+#define KXTI9_ZOUT_HPF_L_M 0xF0 // Bits [3:0] of high-pass filtered
+ // Z-axis data
+#define KXTI9_ZOUT_HPF_L_S 4
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_ZOUT_HPF_H
+// register.
+//
+//*****************************************************************************
+#define KXTI9_ZOUT_HPF_H_M 0xFF // Bits [11:4] of high-pass
+ // filtered Z-axis data
+#define KXTI9_ZOUT_HPF_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_XOUT_L register.
+//
+//*****************************************************************************
+#define KXTI9_XOUT_L_M 0xF0 // Bits [3:0] of X-axis data
+#define KXTI9_XOUT_L_S 4
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_XOUT_H register.
+//
+//*****************************************************************************
+#define KXTI9_XOUT_H_M 0xFF // Bits [11:4] of X-axis data
+#define KXTI9_XOUT_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_YOUT_L register.
+//
+//*****************************************************************************
+#define KXTI9_YOUT_L_M 0xF0 // Bits [3:0] of Y-axis data
+#define KXTI9_YOUT_L_S 4
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_YOUT_H register.
+//
+//*****************************************************************************
+#define KXTI9_YOUT_H_M 0xFF // Bits [11:4] of Y-axis data
+#define KXTI9_YOUT_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_ZOUT_L register.
+//
+//*****************************************************************************
+#define KXTI9_ZOUT_L_M 0xF0 // Bits [3:0] of Z-axis data
+#define KXTI9_ZOUT_L_S 4
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_ZOUT_H register.
+//
+//*****************************************************************************
+#define KXTI9_ZOUT_H_M 0xFF // Bits [11:4] of Z-axis data
+#define KXTI9_ZOUT_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_DCST_RESP
+// register.
+//
+//*****************************************************************************
+#define KXTI9_DCST_RESP_M 0xFF // Check field
+#define KXTI9_DCST_RESP_DEF 0x55 // Default response
+#define KXTI9_DCST_RESP_INIT 0xAA // Post-initialization response
+#define KXTI9_DCST_RESP_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_WHO_AM_I
+// register.
+//
+//*****************************************************************************
+#define KXTI9_DCST_RESP_M 0xFF // Identification field
+#define KXTI9_WHO_AM_I_KXTI9 0x04 // KXTI9
+#define KXTI9_WHO_AM_I_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_TILT_POS_CUR
+// register.
+//
+//*****************************************************************************
+#define KXTI9_TILT_POS_CUR_LE 0x20 // Left state (X-)
+#define KXTI9_TILT_POS_CUR_RI 0x10 // Right state (X+)
+#define KXTI9_TILT_POS_CUR_DO 0x08 // Down state (Y-)
+#define KXTI9_TILT_POS_CUR_UP 0x04 // Up state (Y+)
+#define KXTI9_TILT_POS_CUR_FD 0x02 // Face-down state (Z-)
+#define KXTI9_TILT_POS_CUR_FU 0x01 // Face-up state (Z+)
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_TILT_POS_PRE
+// register.
+//
+//*****************************************************************************
+#define KXTI9_TILT_POS_PRE_LE 0x20 // Left state (X-)
+#define KXTI9_TILT_POS_PRE_RI 0x10 // Right state (X+)
+#define KXTI9_TILT_POS_PRE_DO 0x08 // Down state (Y-)
+#define KXTI9_TILT_POS_PRE_UP 0x04 // Up state (Y+)
+#define KXTI9_TILT_POS_PRE_FD 0x02 // Face-down state (Z-)
+#define KXTI9_TILT_POS_PRE_FU 0x01 // Face-up state (Z+)
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_INT_SRC1
+// register.
+//
+//*****************************************************************************
+#define KXTI9_INT_SRC1_TLE 0x20 // X negative (X-) reported
+#define KXTI9_INT_SRC1_TRI 0x10 // X positive (X+) reported
+#define KXTI9_INT_SRC1_TDO 0x08 // Y negative (Y-) reported
+#define KXTI9_INT_SRC1_TUP 0x04 // Y positive (Y+) reported
+#define KXTI9_INT_SRC1_TFD 0x02 // Z negative (Z-) reported
+#define KXTI9_INT_SRC1_TFU 0x01 // Z positive (Z+) reported
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_INT_SRC2
+// register.
+//
+//*****************************************************************************
+#define KXTI9_INT_SRC2_WMI 0x20 // Buffer sample threshold reached
+#define KXTI9_INT_SRC2_DRDY 0x10 // New accel data ready
+#define KXTI9_INT_SRC2_TDTS_M 0x0C // Tap event detected
+#define KXTI9_INT_SRC2_TDTS_NONE \
+ 0x00 // No tap event
+#define KXTI9_INT_SRC2_TDTS_SINGLE \
+ 0x01 // Single tap event
+#define KXTI9_INT_SRC2_TDTS_DOUBLE \
+ 0x02 // Double tap event
+#define KXTI9_INT_SRC2_TDTS_DIRECTIONAL \
+ 0x03 // Double tap event
+#define KXTI9_INT_SRC2_WUFS 0x02 // Wake-up
+#define KXTI9_INT_SRC2_TPS 0x01 // Tilt position change
+#define KXTI9_INT_SRC2_S 2
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_STATUS register.
+//
+//*****************************************************************************
+#define KXTI9_STATUS_INT 0x10 // Interrupt event
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_INT_REL
+// register.
+//
+//*****************************************************************************
+#define KXTI9_INT_REL_M 0xFF // Data is unpredictable
+#define KXTI9_INT_REL_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_CTRL1 register.
+//
+//*****************************************************************************
+#define KXTI9_CTRL1_PC1 0x80 // Operating mode
+#define KXTI9_CTRL1_RES 0x40 // Performance (resolution) mode
+#define KXTI9_CTRL1_DRDYE 0x20 // New data interrupt enable
+#define KXTI9_CTRL1_GSEL_M 0x18 // Acceleration range
+#define KXTI9_CTRL1_GSEL_2G 0x00 // +/-2g
+#define KXTI9_CTRL1_GSEL_4G 0x01 // +/-4g
+#define KXTI9_CTRL1_GSEL_8G 0x02 // +/-8g
+#define KXTI9_CTRL1_TDTE 0x04 // Directional tap enable
+#define KXTI9_CTRL1_WUFE 0x02 // Wake-up enable
+#define KXTI9_CTRL1_TPE 0x01 // Tilt position enable
+#define KXTI9_CTRL1_GSEL_S 3
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_CTRL2 register.
+//
+//*****************************************************************************
+#define KXTI9_CTRL2_OTDTH 0x80 // Output data rate selection for
+ // directional tap
+#define KXTI9_CTRL2_LEM 0x20 // Left state tilt enable
+#define KXTI9_CTRL2_RIM 0x10 // Right state tilt enable
+#define KXTI9_CTRL2_DOM 0x08 // Down state tilt enable
+#define KXTI9_CTRL2_UPM 0x04 // Up state tilt enable
+#define KXTI9_CTRL2_FDM 0x02 // Face-down state tilt enable
+#define KXTI9_CTRL2_FUM 0x01 // Face-up state tilt enable
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_CTRL3 register.
+//
+//*****************************************************************************
+#define KXTI9_CTRL3_SRST 0x80 // Initiate software reset
+#define KXTI9_CTRL3_OTP_M 0x60 // Output data rate for tilt
+ // position
+#define KXTI9_CTRL3_OTP_1_6HZ 0x00 // Data rate is 1.6Hz
+#define KXTI9_CTRL3_OTP_6_3HZ 0x01 // Data rate is 6.3Hz
+#define KXTI9_CTRL3_OTP_12_5HZ 0x02 // Data rate is 12.5Hz
+#define KXTI9_CTRL3_OTP_50HZ 0x03 // Data rate is 50Hz
+#define KXTI9_CTRL3_OWUF_M 0x60 // Output data rate for motion
+ // detection and high-pass outputs
+#define KXTI9_CTRL3_OWUF_25HZ 0x00 // Data rate is 25Hz
+#define KXTI9_CTRL3_OWUF_50HZ 0x01 // Data rate is 50Hz
+#define KXTI9_CTRL3_OWUF_100HZ 0x02 // Data rate is 100Hz
+#define KXTI9_CTRL3_OWUF_200HZ 0x03 // Data rate is 200Hz
+#define KXTI9_CTRL3_DCST 0x10 // Digital communication self-test
+#define KXTI9_CTRL3_OTDT_M 0x0C // Encoding values change based on
+ // value of OTDTH bit
+#define KXTI9_CTRL3_OTDT_0 0x00 // Encoding 0 is 50Hz or 12.5Hz
+#define KXTI9_CTRL3_OTDT_1 0x01 // Encoding 1 is 100Hz or 25Hz
+#define KXTI9_CTRL3_OTDT_2 0x02 // Encoding 2 is 200Hz or 800Hz
+#define KXTI9_CTRL3_OTDT_3 0x03 // Encoding 3 is 400Hz or 1600Hz
+#define KXTI9_CTRL3_OTP_S 5
+#define KXTI9_CTRL3_OTDT_S 2
+#define KXTI9_CTRL3_OWUF_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_INT_CTRL1
+// register.
+//
+//*****************************************************************************
+#define KXTI9_INT_CTRL1_IEN 0x20 // Interrupt pin enable
+#define KXTI9_INT_CTRL1_IEA 0x10 // Interrupt pin polarity
+#define KXTI9_INT_CTRL1_IEL 0x08 // Interrupt pin response
+#define KXTI9_INT_CTRL1_IEU 0x04 // Interrupt pin alternative
+ // response
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_INT_CTRL2
+// register.
+//
+//*****************************************************************************
+#define KXTI9_INT_CTRL2_XBW 0x80 // X-axis motion interrupt enable
+#define KXTI9_INT_CTRL2_YBW 0x40 // Y-axis motion interrupt enable
+#define KXTI9_INT_CTRL2_ZBW 0x20 // Z-axis motion interrupt enable
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_INT_CTRL3
+// register.
+//
+//*****************************************************************************
+#define KXTI9_INT_CTRL3_TMEN 0x40 // Tap masking scheme enable
+#define KXTI9_INT_CTRL3_TLEM 0x20 // X negative interrupt enable
+#define KXTI9_INT_CTRL3_TRIM 0x10 // X positive interrupt enable
+#define KXTI9_INT_CTRL3_TDOM 0x08 // Y negative interrupt enable
+#define KXTI9_INT_CTRL3_TUPM 0x04 // Y positive interrupt enable
+#define KXTI9_INT_CTRL3_TFDM 0x02 // Z negative interrupt enable
+#define KXTI9_INT_CTRL3_TFUM 0x01 // Z positive interrupt enable
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_DATA_CTRL
+// register.
+//
+//*****************************************************************************
+#define KXTI9_DATA_CTRL_HPFRO_M 0x30 // High-pass filter roll-off
+ // frequency
+#define KXTI9_DATA_CTRL_HPFRO_50HZ \
+ 0x00 // Roll-off at 50Hz
+#define KXTI9_DATA_CTRL_HPFRO_100HZ \
+ 0x01 // Roll-off at 100Hz
+#define KXTI9_DATA_CTRL_HPFRO_200HZ \
+ 0x02 // Roll-off at 200Hz
+#define KXTI9_DATA_CTRL_HPFRO_400HZ \
+ 0x03 // Roll-off at 400Hz
+#define KXTI9_DATA_CTRL_OSA_M 0x07 // Output data rate and roll-off
+ // for low-pass filter outputs
+#define KXTI9_DATA_CTRL_OSA_12_5HZ \
+ 0x00 // 12.5Hz data rate, 6.25Hz LPF
+ // roll-off
+#define KXTI9_DATA_CTRL_OSA_25HZ \
+ 0x01 // 25Hz data rate, 12.5Hz LPF
+ // roll-off
+#define KXTI9_DATA_CTRL_OSA_50HZ \
+ 0x02 // 50Hz data rate, 25Hz LPF
+ // roll-off
+#define KXTI9_DATA_CTRL_OSA_100HZ \
+ 0x03 // 100Hz data rate, 50Hz LPF
+ // roll-off
+#define KXTI9_DATA_CTRL_OSA_200HZ \
+ 0x04 // 200Hz data rate, 100Hz LPF
+ // roll-off
+#define KXTI9_DATA_CTRL_OSA_400HZ \
+ 0x05 // 400Hz data rate, 200Hz LPF
+ // roll-off
+#define KXTI9_DATA_CTRL_OSA_800HZ \
+ 0x06 // 800Hz data rate, 400Hz LPF
+ // roll-off
+#define KXTI9_DATA_CTRL_HPFRO_S 4
+#define KXTI9_DATA_CTRL_OSA_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_TILT_TIMER
+// register.
+//
+//*****************************************************************************
+#define KXTI9_TILT_TIMER_M 0xFF // Initial timer count
+#define KXTI9_TILT_TIMER_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_WUF_TIMER
+// register.
+//
+//*****************************************************************************
+#define KXTI9_WUF_TIMER_M 0xFF // Initial timer count
+#define KXTI9_WUF_TIMER_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_TDT_TIMER
+// register.
+//
+//*****************************************************************************
+#define KXTI9_TDT_TIMER_M 0xFF // Initial timer count
+#define KXTI9_TDT_TIMER_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_TDT_H_THRESH
+// register.
+//
+//*****************************************************************************
+#define KXTI9_TDT_H_THRESH_M 0xFF // Threshold high value
+#define KXTI9_TDT_H_THRESH_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_TDT_L_THRESH
+// register.
+//
+//*****************************************************************************
+#define KXTI9_TDT_L_THRESH_M 0xFF // Threshold low value
+#define KXTI9_TDT_L_THRESH_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_TDT_TAP_TIMER
+// register.
+//
+//*****************************************************************************
+#define KXTI9_TDT_TAP_TIMER_M 0xFF // Tap event counter
+#define KXTI9_TDT_TAP_TIMER_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_TDT_TOTAL_TIMER
+// register.
+//
+//*****************************************************************************
+#define KXTI9_TDT_TOTAL_TIMER_M 0xFF // Double tap event counter
+#define KXTI9_TDT_TOTAL_TIMER_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// KXTI9_O_TDT_LATENCY_TIMER register.
+//
+//*****************************************************************************
+#define KXTI9_TDT_LATENCY_TIMER_M \
+ 0xFF // Tap event latency counter
+#define KXTI9_TDT_LATENCY_TIMER_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_TDT_WINDOW_TIMER
+// register.
+//
+//*****************************************************************************
+#define KXTI9_TDT_WINDOW_TIMER_M \
+ 0xFF // Tap event window counter
+#define KXTI9_TDT_WINDOW_TIMER_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_BUF_CTRL1
+// register.
+//
+//*****************************************************************************
+#define KXTI9_BUF_CTRL1_M 0x7F // Buffer sample threshold
+#define KXTI9_BUF_CTRL1_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_BUF_CTRL2
+// register.
+//
+//*****************************************************************************
+#define KXTI9_BUF_CTRL2_BUFE 0x80 // Buffer enable
+#define KXTI9_BUF_CTRL2_BUF_RES 0x40 // Buffer resolution
+#define KXTI9_BUF_CTRL2_BUF_M_M 0x03 // Buffer mode
+#define KXTI9_BUF_CTRL2_BUF_M_FIFO \
+ 0x00 // FIFO mode
+#define KXTI9_BUF_CTRL2_BUF_M_STREAM \
+ 0x01 // Stream mode
+#define KXTI9_BUF_CTRL2_BUF_M_TRIG \
+ 0x02 // Trigger mode
+#define KXTI9_BUF_CTRL2_BUF_M_FILO \
+ 0x03 // FILO mode
+#define KXTI9_BUF_CTRL2_BUF_M_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_STATUS1
+// register.
+//
+//*****************************************************************************
+#define KXTI9_STATUS1_SMP_LEV_M 0xFF // Number of bytes in sample buffer
+#define KXTI9_STATUS1_SMP_LEV_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_STATUS2
+// register.
+//
+//*****************************************************************************
+#define KXTI9_STATUS2_BUF_TRIG 0x80 // Trigger mode status
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_BUF_CLEAR
+// register.
+//
+//*****************************************************************************
+#define KXTI9_BUF_CLEAR_M 0xFF // Data is unpredictable
+#define KXTI9_BUF_CLEAR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_SELF_TEST
+// register.
+//
+//*****************************************************************************
+#define KXTI9_SELF_TEST_M 0xFF // Writing 0xCA enables MEMS
+ // self-test
+#define KXTI9_SELF_TEST_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_WUF_THRESH
+// register.
+//
+//*****************************************************************************
+#define KXTI9_WUF_THRESH_M 0xFF // Acceleration wake-up threshold
+#define KXTI9_WUF_THRESH_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_TILT_ANGLE
+// register.
+//
+//*****************************************************************************
+#define KXTI9_TILT_ANGLE_M 0xFF // Tilt angle threshold
+#define KXTI9_TILT_ANGLE_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_HYST_SET
+// register.
+//
+//*****************************************************************************
+#define KXTI9_HYST_SET_RES_M 0xE0 // Factory set value - do not
+ // change
+#define KXTI9_HYST_SET_HYST_M 0x1F // Hysteresis angle
+#define KXTI9_HYST_SET_RES_S 5
+#define KXTI9_HYST_SET_HYST_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the KXTI9_O_BUF_READ
+// register.
+//
+//*****************************************************************************
+#define KXTI9_BUF_READ_M 0xFF // Read data from buffer
+#define KXTI9_BUF_READ_S 0
+
+#endif // __SENSORLIB_HW_KXTI9_H__
diff --git a/sensorlib/hw_l3gd20h.h b/sensorlib/hw_l3gd20h.h new file mode 100644 index 0000000..4a9a459 --- /dev/null +++ b/sensorlib/hw_l3gd20h.h @@ -0,0 +1,468 @@ +//*****************************************************************************
+//
+// hw_l3gd20h.h - Macros used when accessing the ST L3GD20H gyroscope
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_HW_L3GD20H_H__
+#define __SENSORLIB_HW_L3GD20H_H__
+
+//*****************************************************************************
+//
+// The following are defines for the L3GD20H register addresses
+//
+//*****************************************************************************
+#define L3GD20H_O_WHOAMI 0x0F // Device idenfitication register
+#define L3GD20H_O_CTRL1 0x20 // Control 1 - power settings
+#define L3GD20H_O_CTRL2 0x21 // control 2
+#define L3GD20H_O_CTRL3 0x22 // Control 3
+#define L3GD20H_O_CTRL4 0x23 // Control 4
+#define L3GD20H_O_CTRL5 0x24 // Control 5
+#define L3GD20H_O_REFERENCE 0x25 // Reference register
+#define L3GD20H_O_OUT_TEMP 0x26 // Temperature data; -1LSB/deg,
+ // two's complement
+#define L3GD20H_O_STATUS 0x27 // Status register
+#define L3GD20H_O_OUT_X_LSB 0x28 // X-axis LSB
+#define L3GD20H_O_OUT_X_MSB 0x29 // X-axis MSB
+#define L3GD20H_O_OUT_Y_LSB 0x2A // Y-axis LSB
+#define L3GD20H_O_OUT_Y_MSB 0x2B // Y-axis MSB
+#define L3GD20H_O_OUT_Z_LSB 0x2C // Z-axis LSB
+#define L3GD20H_O_OUT_Z_MSB 0x2D // Z-axis MSB
+#define L3GD20H_O_FIFO_CTRL 0x2E // FIFO control
+#define L3GD20H_O_FIFO_SRC 0x2F // FIFO_SRC register
+#define L3GD20H_O_IG_CFG 0x30 // Interrupt generation control
+#define L3GD20H_O_IG_SRC 0x31 // interrupt source register (read
+ // only)
+#define L3GD20H_O_IG_THS_XH 0x32 // Hi-X threshold
+#define L3GD20H_O_IG_THS_XL 0x33 // Lo-X threshold
+#define L3GD20H_O_IG_THS_TH 0x34 // Hi-Y threshold
+#define L3GD20H_O_IG_THS_TL 0x35 // Lo-Y threshold
+#define L3GD20H_O_IG_THS_ZH 0x36 // Hi-Z threshold
+#define L3GD20H_O_IG_THS_ZL 0x37 // Lo-X threshold
+#define L3GD20H_O_IG_DURATION 0x38 // Interrupt generation duration
+ // register
+#define L3GD20H_O_LOW_ODR 0x39 // Low-speed output data rate (ODR)
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the L3GD20H_O_CTRL1
+// register.
+//
+//*****************************************************************************
+#define L3GD20H_CTRL1_DR_M 0xC0 // ODR select, x8 if Low_ODR = 0
+#define L3GD20H_CTRL1_DR_12_5_HZ \
+ 0x00 // 12.5Hz or 100Hz
+#define L3GD20H_CTRL1_DR_25_HZ 0x40 // 25Hz or 200Hz
+#define L3GD20H_CTRL1_DR_50_HZ 0x80 // 50Hz or 400Hz
+#define L3GD20H_CTRL1_DR_800_HZ 0xC0 // 800Hz of Low_ODR=0, or 50Hz
+ // otherwise
+#define L3GD20H_CTRL1_BW_M 0x30 // Bandwidth select
+#define L3GD20H_CTRL1_POWER_M 0x08 // Power control
+#define L3GD20H_CTRL1_POWER_LOWPOW \
+ 0x00
+#define L3GD20H_CTRL1_POWER_NORMAL \
+ 0x08
+#define L3GD20H_CTRL1_AXIS_M 0x7 // Axis power control
+#define L3GD20H_CTRL1_AXIS_Y_EN 0x01 // Y-axis enable
+#define L3GD20H_CTRL1_AXIS_X_EN 0x02 // X-axis enable
+#define L3GD20H_CTRL1_AXIS_Z_EN 0x04 // Z-axis enable
+#define L3GD20H_CTRL1_DR_S 6
+#define L3GD20H_CTRL1_BW_S 4
+#define L3GD20H_CTRL1_AXIS_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the L3GD20H_O_CTRL2
+// register.
+//
+//*****************************************************************************
+#define L3GD20H_CTRL2_EXTREN_M 0x80 // edge sensitive
+#define L3GD20H_CTRL2_EXTREN_DIS \
+ 0x00
+#define L3GD20H_CTRL2_EXTREN_EN 0x80
+#define L3GD20H_CTRL2_LVLEN_M 0x40 // level sensitive
+#define L3GD20H_CTRL2_LVLEN_DIS 0x00
+#define L3GD20H_CTRL2_LVLEN_EN 0x40
+#define L3GD20H_CTRL2_HPM_M 0x30 // high pass filter mode selection
+#define L3GD20H_CTRL2_HPCF_M 0x0F // high pass cutoff frequency
+ // selection
+#define L3GD20H_CTRL2_HPM_S 4
+#define L3GD20H_CTRL2_HPCF_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the L3GD20H_O_CTRL3
+// register.
+//
+//*****************************************************************************
+#define L3GD20H_CTRL3_INT1_IG_M 0x80 // Interrupt enable on INT1 pin
+#define L3GD20H_CTRL3_INT1_IG_DIS \
+ 0x00
+#define L3GD20H_CTRL3_INT1_IG_EN \
+ 0x80
+#define L3GD20H_CTRL3_INT1_BOOT_M \
+ 0x40 // Boot status available on INT1
+ // pin.
+#define L3GD20H_CTRL3_INT1_BOOT_DIS \
+ 0x00
+#define L3GD20H_CTRL3_INT1_BOOT_EN \
+ 0x40
+#define L3GD20H_CTRL3_H_LACTIVE_M \
+ 0x20 // Interrupt active configuration
+ // on INT; default value: 0 (0:
+ // high; 1:low)
+#define L3GD20H_CTRL3_H_LACTIVE_HI \
+ 0x00
+#define L3GD20H_CTRL3_H_LACTIVE_LOW \
+ 0x20
+#define L3GD20H_CTRL3_DRIVE_TYPE_M \
+ 0x10 // Push- Pull / Open drain; default
+ // value: 0 (0: push-pull; 1: open
+ // drain)
+#define L3GD20H_CTRL3_DRIVE_TYPE_PP \
+ 0x00
+#define L3GD20H_CTRL3_DRIVE_TYPE_OD \
+ 0x10
+#define L3GD20H_CTRL3_INT2_DRDY_M \
+ 0x08 // Date Ready on DRDY/INT2 pin;
+ // default value: 0
+#define L3GD20H_CTRL3_INT2_DRDY_DIS \
+ 0x00
+#define L3GD20H_CTRL3_INT2_DRDY_EN \
+ 0x08
+#define L3GD20H_CTRL3_INT2_FTH_M \
+ 0x04 // FIFO Threshold interrupt on
+ // DRDY/INT2 pin; default value: 0
+#define L3GD20H_CTRL3_INT2_FTH_DIS \
+ 0x00
+#define L3GD20H_CTRL3_INT2_FTH_EN \
+ 0x04
+#define L3GD20H_CTRL3_INT2_ORUN_M \
+ 0x02 // FIFO Overrun interrupt on
+ // DRDY/INT2 pin; default value: 0
+#define L3GD20H_CTRL3_INT2_ORUN_DIS \
+ 0x00
+#define L3GD20H_CTRL3_INT2_ORUN_EN \
+ 0x02
+#define L3GD20H_CTRL3_INT2_EMPTY_M \
+ 0x01 // FIFO Empty interrupt on
+ // DRDY/INT2 pin; default value: 0
+#define L3GD20H_CTRL3_INT2_EMPTY_DIS \
+ 0x00
+#define L3GD20H_CTRL3_INT2_EMPTY_EN \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the L3GD20H_O_CTRL4
+// register.
+//
+//*****************************************************************************
+#define L3GD20H_CTRL4_BDU_M 0x80 // Block data update; default
+ // value: 0 (0: continuous update;
+ // 1: output registers not updated
+ // until MSB and LSB reading)
+#define L3GD20H_CTRL4_BDU_CONTINUOUS \
+ 0x00
+#define L3GD20H_CTRL4_BDU_MSBLSB \
+ 0x80
+#define L3GD20H_CTRL4_ENDIAN_M 0x40 // Endian selection
+#define L3GD20H_CTRL4_ENDIAN_LITTLE \
+ 0x00
+#define L3GD20H_CTRL4_ENDIAN_BIG \
+ 0x40
+#define L3GD20H_CTRL4_FS_M 0x30 // full scale selection; default
+ // value: 0
+#define L3GD20H_CTRL4_FS_245DPS 0x00 // 245 degrees per second
+#define L3GD20H_CTRL4_FS_500DPS 0x10 // 500 degrees per second
+#define L3GD20H_CTRL4_FS_2000DPS \
+ 0x30 // 2000 degrees per second
+#define L3GD20H_CTRL4_IMPEN_M 0x08 // level sensitive latched enable;
+ // default value: 0
+#define L3GD20H_CTRL4_IMPEN_LVL_DIS \
+ 0x00
+#define L3GD20H_CTRL4_IMPEN_LVL_EN \
+ 0x08
+#define L3GD20H_CTRL4_SELFTEST_M \
+ 0x06 // self-test mode
+#define L3GD20H_CTRL4_SELFTEST_NORMAL \
+ 0x00 // Normal mode (not self test,
+ // default)
+#define L3GD20H_CTRL4_SELFTEST_MODE0 \
+ 0x02 // Self-test mode 0 (+)
+#define L3GD20H_CTRL4_SELFTEST_MODE1 \
+ 0x06 // Self-test mode 1 (-)
+#define L3GD20H_CTRL4_SIM_M 0x01 // SPI Serial Interface Mode
+ // selection (default = 0, 4-wire)
+#define L3GD20H_CTRL4_SIM_4WIRE 0x00
+#define L3GD20H_CTRL4_SIM_3WIRE 0x01
+#define L3GD20H_CTRL4_FS_S 4
+#define L3GD20H_CTRL4_SELFTEST_S \
+ 1
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the L3GD20H_O_CTRL5
+// register.
+//
+//*****************************************************************************
+#define L3GD20H_CTRL5_REBOOTCTL_M \
+ 0x80 // Reboot memory conent
+#define L3GD20H_CTRL5_REBOOTCTL_NORMAL \
+ 0x00
+#define L3GD20H_CTRL5_REBOOTCTL_REBOOT \
+ 0x80
+#define L3GD20H_CTRL5_FIFOCTL_M 0x40 // FIFO control
+#define L3GD20H_CTRL5_FIFOCTL_DIS \
+ 0x00
+#define L3GD20H_CTRL5_FIFOCTL_EN \
+ 0x40
+#define L3GD20H_CTRL5_STOPONFTH_M \
+ 0x20 // Sensing chain FIFO stop values
+ // memorization at FIFO Threshold;
+ // default value: 0
+#define L3GD20H_CTRL5_STOPONFTH_UNLIMITED \
+ 0x00
+#define L3GD20H_CTRL5_STOPONFTH_THRESH_LIMITED \
+ 0x20
+#define L3GD20H_CTRL5_HPEN_M 0x10 // high pass filtern enable
+ // (default 0)
+#define L3GD20H_CTRL5_HPEN_DIS 0x00
+#define L3GD20H_CTRL5_HPEN_EN 0x10
+#define L3GD20H_CTRL5_IG_SEL_M 0x0C // interrupt generator section
+ // configuration
+#define L3GD20H_CTRL5_OUT_SEL_M 0x03 // out selection configuration
+#define L3GD20H_CTRL5_IG_SEL_S 2
+#define L3GD20H_CTRL5_OUT_SEL_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the L3GD20H_O_STATUS
+// register.
+//
+//*****************************************************************************
+#define L3GD20H_STATUS_OR_M 0xF0 // Axis data overrun
+#define L3GD20H_STATUS_OR_X 0x10 // X-axis data overrun
+#define L3GD20H_STATUS_OR_Y 0x20 // Y-axis data overrun
+#define L3GD20H_STATUS_OR_Z 0x40 // Z-axis data overrun
+#define L3GD20H_STATUS_OR_ZYX 0x80 // X, Y, and X data overrun
+#define L3GD20H_STATUS_DA_M 0xF // Axis data available
+#define L3GD20H_STATUS_DA_X 0x01 // X-axis data available
+#define L3GD20H_STATUS_DA_Y 0x02 // Y-axis data available
+#define L3GD20H_STATUS_DA_Z 0x04 // Z-axis data available
+#define L3GD20H_STATUS_DA_ZYX 0x08 // X, Y, and X data available
+#define L3GD20H_STATUS_OR_S 4
+#define L3GD20H_STATUS_DA_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the L3GD20H_O_FIFO_CTRL
+// register.
+//
+//*****************************************************************************
+#define L3GD20H_FIFO_CTRL_THRESH_M \
+ 0x1F // FIFO Threshold setting
+#define L3GD20H_FIFO_CTRL_MODE_M \
+ 0xE // FIFO mode setting
+#define L3GD20H_FIFO_CTRL_MODE_S \
+ 5
+#define L3GD20H_FIFO_CTRL_THRESH_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the L3GD20H_O_FIFO_SRC
+// register.
+//
+//*****************************************************************************
+#define L3GD20H_FIFO_SRC_FTH_M 0x80 // FIFO threshold is greater than
+ // or equal to level or less than
+ // level
+#define L3GD20H_FIFO_SRC_FTH_LT 0x00
+#define L3GD20H_FIFO_SRC_FTH_GEQ \
+ 0x80
+#define L3GD20H_FIFO_SRC_OVRN_M 0x40 // overrun status bit
+#define L3GD20H_FIFO_SRC_OVRN_FILLED \
+ 0x40
+#define L3GD20H_FIFO_SRC_EMPTY_M \
+ 0x20 // FIFO empty
+#define L3GD20H_FIFO_SRC_EMPTY_EMPTY \
+ 0x20
+#define L3GD20H_FIFO_SRC_STORE_SAMPLES_M \
+ 0x1F // FIFO stored data level of the
+ // unread samples
+#define L3GD20H_FIFO_SRC_STORE_SAMPLES_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the L3GD20H_O_IG_CFG
+// register.
+//
+//*****************************************************************************
+#define L3GD20H_IG_CFG_ANDOR_M 0x80 // AND/OR combination of Interrupt
+ // events; default value: 0
+#define L3GD20H_IG_CFG_ANDOR_OR 0x00
+#define L3GD20H_IG_CFG_ANDOR_AND \
+ 0x80
+#define L3GD20H_IG_CFG_LIR_M 0x40 // Latch Interrupt Request; default
+ // value: 0
+#define L3GD20H_IG_CFG_LIR_LATCHED \
+ 0x40
+#define L3GD20H_IG_CFG_ZHI_M 0x20 // enable interrupt generation on
+ // Z-hi event
+#define L3GD20H_IG_CFG_ZHI_EN 0x20
+#define L3GD20H_IG_CFG_ZLI_M 0x10 // enable interrupt generation on
+ // Z-low event
+#define L3GD20H_IG_CFG_ZLI_EN 0x10
+#define L3GD20H_IG_CFG_YHI_M 0x08 // enable interrupt generation on
+ // Y-hi event
+#define L3GD20H_IG_CFG_YHI_EN 0x08
+#define L3GD20H_IG_CFG_YLI_M 0x04 // enable interrupt generation on
+ // Y-low event
+#define L3GD20H_IG_CFG_YLI_EN 0x04
+#define L3GD20H_IG_CFG_XHI_M 0x02 // enable interrupt generation on
+ // X-hi event
+#define L3GD20H_IG_CFG_XHI_EN 0x02
+#define L3GD20H_IG_CFG_XLI_M 0x01 // enable interrupt generation on
+ // X-low event
+#define L3GD20H_IG_CFG_XLI_EN 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the L3GD20H_O_IG_SRC
+// register.
+//
+//*****************************************************************************
+#define L3GD20H_IG_SRC_IA_M 0x40 // interrupt active
+#define L3GD20H_IG_SRC_IA_ACTIVE \
+ 0x40
+#define L3GD20H_IG_SRC_ZH_M 0x20 // Z-Hi event occurred
+#define L3GD20H_IG_SRC_ZH_OCCURRED \
+ 0x20
+#define L3GD20H_IG_SRC_ZL_M 0x10 // Z-Low event occurred
+#define L3GD20H_IG_SRC_ZL_OCCURRED \
+ 0x10
+#define L3GD20H_IG_SRC_YH_M 0x08 // Y-Hi event occurred
+#define L3GD20H_IG_SRC_YH_OCCURRED \
+ 0x08
+#define L3GD20H_IG_SRC_YL_M 0x04 // Y-Low event occurred
+#define L3GD20H_IG_SRC_YL_OCCURRED \
+ 0x04
+#define L3GD20H_IG_SRC_XH_M 0x02 // X-Hi event occurred
+#define L3GD20H_IG_SRC_XH_OCCURRED \
+ 0x02
+#define L3GD20H_IG_SRC_XL_M 0x01 // X-Low event occurred
+#define L3GD20H_IG_SRC_XL_OCCURRED \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the L3GD20H_O_IG_THS_XH
+// register.
+//
+//*****************************************************************************
+#define L3GD20H_IG_THS_XH_DCRM_M \
+ 0x80 // interrupt generation counter
+ // mode
+#define L3GD20H_IG_THS_XH_DCRM_RESET \
+ 0x00
+#define L3GD20H_IG_THS_XH_DCRM_DECREMENT \
+ 0x80
+#define L3GD20H_IG_THS_XH_THSX_M \
+ 0x7F // THSX[14-8], default 0x0
+#define L3GD20H_IG_THS_XH_THSX_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the L3GD20H_O_IG_THS_TH
+// register.
+//
+//*****************************************************************************
+#define L3GD20H_IG_THS_TH_THSY_M \
+ 0x7F // THSY[14-8], default 0x0
+#define L3GD20H_IG_THS_TH_THSY_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the L3GD20H_O_IG_THS_ZH
+// register.
+//
+//*****************************************************************************
+#define L3GD20H_IG_THS_ZH_THSX_M \
+ 0x7F // THSZ[14-8], default 0x0
+#define L3GD20H_IG_THS_ZH_THSX_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the L3GD20H_O_IG_DURATION
+// register.
+//
+//*****************************************************************************
+#define L3GD20H_IG_DURATION_WAIT_M \
+ 0x80 // If WAIT is enabled then DURATION
+ // samples must occur before
+ // asserting the interrupt.
+#define L3GD20H_IG_DURATION_WAIT_DIS \
+ 0x00
+#define L3GD20H_IG_DURATION_WAIT_EN \
+ 0x80
+#define L3GD20H_IG_DURATION_DURATION_M \
+ 0x7F // Duration D[6-0]
+#define L3GD20H_IG_DURATION_DURATION_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the L3GD20H_O_LOW_ODR
+// register.
+//
+//*****************************************************************************
+#define L3GD20H_LOW_ODR_DRDY_HL_M \
+ 0x20 // DRDY/INT2 active level
+#define L3GD20H_LOW_ODR_DRDY_HL_ACTIVE_LOW \
+ 0x00
+#define L3GD20H_LOW_ODR_DRDY_HL_ACTIVE_HIGH \
+ 0x20
+#define L3GD20H_LOW_ODR_I2C_DISABLE_M \
+ 0x08 // disable I2C interface
+#define L3GD20H_LOW_ODR_I2C_DISABLE_BOTH \
+ 0x00
+#define L3GD20H_LOW_ODR_I2C_DISABLE_SPI_ONLY \
+ 0x08
+#define L3GD20H_LOW_ODR_SWRESET_M \
+ 0x04 // software reset
+#define L3GD20H_LOW_ODR_SWRESET_NORMAL \
+ 0x00
+#define L3GD20H_LOW_ODR_SWRESET_RESET \
+ 0x04
+#define L3GD20H_LOW_ODR_DATARATE_M \
+ 0x01 // Low-speed data rate enable;
+ // default value: 0
+#define L3GD20H_LOW_ODR_DATARATE_HIGH \
+ 0x00
+#define L3GD20H_LOW_ODR_DATARATE_LOW \
+ 0x01
+
+#endif // __SENSORLIB_HW_L3GD20H_H__
diff --git a/sensorlib/hw_lsm303d.h b/sensorlib/hw_lsm303d.h new file mode 100644 index 0000000..19ea89e --- /dev/null +++ b/sensorlib/hw_lsm303d.h @@ -0,0 +1,1017 @@ +//*****************************************************************************
+//
+// hw_lsm303d.h - Macros used when accessing the ST LSM303D
+// accelerometer/magnetometer
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_HW_LSM303D_H__
+#define __SENSORLIB_HW_LSM303D_H__
+
+//*****************************************************************************
+//
+// The following are defines for the LSM303D register addresses
+//
+//*****************************************************************************
+#define LSM303D_O_TEMP_OUT_LSB 0x5 // Temperature bits 7-0
+#define LSM303D_O_TEMP_OUT_MSB 0x6 // Temperature bits 11-8
+#define LSM303D_O_MAG_STATUS 0x7 // Magnetic status register
+#define LSM303D_O_MAG_OUT_X_MSB 0x08 // X-axis MSB
+#define LSM303D_O_MAG_OUT_X_LSB 0x09 // X-axis LSB
+#define LSM303D_O_MAG_OUT_Y_MSB 0x0A // Y-axis MSB
+#define LSM303D_O_MAG_OUT_Y_LSB 0x0B // Y-axis LSB
+#define LSM303D_O_MAG_OUT_Z_MSB 0x0C // Z-axis MSB
+#define LSM303D_O_MAG_OUT_Z_LSB 0x0D // Z-axis LSB
+#define LSM303D_O_WHO_AM_I 0x0F // ID register, constant 0x49
+#define LSM303D_O_MAG_INT_CTRL 0x12 // magnetic control register
+#define LSM303D_O_MAG_INT_SRC 0x13 // Interrupt source (status) for
+ // magnetometer interrupt
+#define LSM303D_O_MAG_THS_MSB 0x14 // Threshold MSB
+#define LSM303D_O_MAG_THS_LSB 0x15 // Threshold LSB. Even though the
+ // threshold is expressed in
+ // absolute value, the device
+ // detects both positive and
+ // negative thresholds.
+#define LSM303D_O_MAG_OFFSET_X_MSB \
+ 0x16 // MSB of Magnetic offset for
+ // X-axis. The value is expressed
+ // in 16-bit as 2s complement.
+#define LSM303D_O_MAG_OFFSET_X_LSB \
+ 0x17 // LSB of Magnetic offset for
+ // X-axis. The value is expressed
+ // in 16-bit as 2s complement.
+#define LSM303D_O_MAG_OFFSET_Y_MSB \
+ 0x18 // MSB of Magnetic offset for
+ // Y-axis. The value is expressed
+ // in 16-bit as 2s complement.
+#define LSM303D_O_MAG_OFFSET_Y_LSB \
+ 0x19 // LSB of Magnetic offset for
+ // Y-axis. The value is expressed
+ // in 16-bit as 2s complement.
+#define LSM303D_O_MAG_OFFSET_Z_MSB \
+ 0x1A // MSB of Magnetic offset for
+ // Z-axis. The value is expressed
+ // in 16-bit as 2s complement.
+#define LSM303D_O_MAG_OFFSET_Z_LSB \
+ 0x1B // LSB of Magnetic offset for
+ // Z-axis. The value is expressed
+ // in 16-bit as 2s complement.
+#define LSM303D_O_ACCEL_REFERENCE_X \
+ 0x1C // Reference value for high-pass
+ // filter for X-axis acceleration
+ // data.
+#define LSM303D_O_ACCEL_REFERENCE_Y \
+ 0x1D // Reference value for high-pass
+ // filter for Y-axis acceleration
+ // data.
+#define LSM303D_O_ACCEL_REFERENCE_Z \
+ 0x1E // Reference value for high-pass
+ // filter for Z-axis acceleration
+ // data.
+#define LSM303D_O_CTRL0 0x1F // Accel control 0
+#define LSM303D_O_CTRL1 0x20 // Control 1 - power settings
+#define LSM303D_O_CTRL2 0x21 // Control 2
+#define LSM303D_O_CTRL3 0x22 // Control 3
+#define LSM303D_O_CTRL4 0x23 // Control 4
+#define LSM303D_O_CTRL5 0x24 // Control 5
+#define LSM303D_O_CTRL6 0x25 // Control 6
+#define LSM303D_O_CTRL7 0x26 // Control 7
+#define LSM303D_O_STATUS 0x27 // Status register
+#define LSM303D_O_OUT_X_LSB 0x28 // X-axis LSB
+#define LSM303D_O_OUT_X_MSB 0x29 // X-axis MSB
+#define LSM303D_O_OUT_Y_LSB 0x2A // Y-axis LSB
+#define LSM303D_O_OUT_Y_MSB 0x2B // Y-axis MSB
+#define LSM303D_O_OUT_Z_LSB 0x2C // Z-axis LSB
+#define LSM303D_O_OUT_Z_MSB 0x2D // Z-axis MSB
+#define LSM303D_O_FIFO_CTRL 0x2E // FIFO control
+#define LSM303D_O_FIFO_SRC 0x2F // FIFO_SRC register
+#define LSM303D_O_INT1_CFG 0x30 // INT1 interrupt generation; this
+ // register only writable after
+ // boot
+#define LSM303D_O_INT1_SRC 0x31 // interrupt source register (read
+ // only)
+#define LSM303D_O_INT1_THS 0x32 // Interrupt 1 threshold
+#define LSM303D_O_INT1_DURATION 0x33 // INT1 duration register
+#define LSM303D_O_INT2_CFG 0x34 // INT2 interrupt generation; this
+ // register only writable after
+ // boot
+#define LSM303D_O_INT2_SRC 0x35 // INT2 source register (read only)
+#define LSM303D_O_INT2_THS 0x36 // INT2 threshold
+#define LSM303D_O_INT2_DURATION 0x37 // INT2 duration register
+#define LSM303D_O_CLICK_CFG 0x38 // Click config A register
+#define LSM303D_O_CLICK_SRC 0x39 // Click source A
+#define LSM303D_O_CLICK_THS 0x3A // click-click threshold
+#define LSM303D_O_TIME_LIMIT 0x3B // Time Limit A register
+#define LSM303D_O_TIME_LATENCY 0x3C // Time Latency A register; 1 LSB =
+ // 1/ODR; TLA7 through TLA0 define
+ // the time interval that starts
+ // after the first click detection
+ // where the click detection
+ // procedure is disabled, in cases
+ // where the device is configured
+ // for double click detection
+#define LSM303D_O_TIME_WINDOW 0x3D // Time Window A register; 1 LSB =
+ // 1/ODR; TW7 through TW0 define
+ // the maximum interval of time
+ // that can elapse after the end of
+ // the latency interval in which
+ // the click detection procedure
+ // can start, in cases where the
+ // device is configured for double
+ // click detection
+#define LSM303D_O_ACT_THS 0x3E // Sleep to Wake, Return to Sleep
+ // activation threshold 1LSb = 16mg
+#define LSM303D_O_ACT_DUR 0x3F // Sleep to Wake, Return to Sleep
+ // duration DUR = (Act_DUR +
+ // 1)*8/ODR
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_TEMP_OUT_LSB
+// register.
+//
+//*****************************************************************************
+#define LSM303D_TEMP_OUT_LSB_LSB_M \
+ 0xFF
+#define LSM303D_TEMP_OUT_LSB_LSB_S \
+ 4
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_TEMP_OUT_MSB
+// register.
+//
+//*****************************************************************************
+#define LSM303D_TEMP_OUT_MSB_MSB_M \
+ 0x0F
+#define LSM303D_TEMP_OUT_MSB_MSB_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_MAG_STATUS
+// register.
+//
+//*****************************************************************************
+#define LSM303D_MAG_STATUS_ZYXTMOR_M \
+ 0x80 // X,Y,Z axis and temp data overrun
+#define LSM303D_MAG_STATUS_ZYXTMOR_TRUE \
+ 0x80
+#define LSM303D_MAG_STATUS_ZMOR_M \
+ 0x40 // Z-axis mag data overrun
+#define LSM303D_MAG_STATUS_ZMOR_TRUE \
+ 0x40
+#define LSM303D_MAG_STATUS_YMOR_M \
+ 0x20 // Y-axis mag data overrun
+#define LSM303D_MAG_STATUS_YMOR_TRUE \
+ 0x20
+#define LSM303D_MAG_STATUS_XMOR_M \
+ 0x10 // X-axis mag data overrun
+#define LSM303D_MAG_STATUS_XMOR_TRUE \
+ 0x10
+#define LSM303D_MAG_STATUS_ZYXTMD_M \
+ 0x08 // X,Y,Z axis and temp data
+ // available
+#define LSM303D_MAG_STATUS_ZYXTMD_AVAIL \
+ 0x08
+#define LSM303D_MAG_STATUS_ZMD_M \
+ 0x04 // New mag data available for Z
+ // axis
+#define LSM303D_MAG_STATUS_ZMD_AVAIL \
+ 0x04
+#define LSM303D_MAG_STATUS_YMD_M \
+ 0x02 // New mag data available for Y
+ // axis
+#define LSM303D_MAG_STATUS_YMD_AVAIL \
+ 0x02
+#define LSM303D_MAG_STATUS_XMD_M \
+ 0x01 // New mag data available for X
+ // axis
+#define LSM303D_MAG_STATUS_XMD_AVAIL \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_MAG_INT_CTRL
+// register.
+//
+//*****************************************************************************
+#define LSM303D_MAG_INT_CTRL_XINT_M \
+ 0x80 // Enable interrupt recognition on
+ // X-axis for magnetic data.
+#define LSM303D_MAG_INT_CTRL_XINT_ENABLE \
+ 0x80
+#define LSM303D_MAG_INT_CTRL_YINT_M \
+ 0x40 // Enable interrupt recognition on
+ // Y-axis for magnetic data.
+#define LSM303D_MAG_INT_CTRL_YINT_ENABLE \
+ 0x40
+#define LSM303D_MAG_INT_CTRL_ZINT_M \
+ 0x20 // Enable interrupt recognition on
+ // Z-axis for magnetic data.
+#define LSM303D_MAG_INT_CTRL_ZINT_ENABLE \
+ 0x20
+#define LSM303D_MAG_INT_CTRL_PINCFG_M \
+ 0x10 // interrupt pin drive
+ // configuration
+#define LSM303D_MAG_INT_CTRL_PINCFG_PUSHPULL \
+ 0x00
+#define LSM303D_MAG_INT_CTRL_PINCFG_OPENDRAIN \
+ 0x10
+#define LSM303D_MAG_INT_CTRL_POLARITY_M \
+ 0x08 // interrupt polarity
+#define LSM303D_MAG_INT_CTRL_POLARITY_LOW \
+ 0x00
+#define LSM303D_MAG_INT_CTRL_POLARITY_HIGH \
+ 0x08
+#define LSM303D_MAG_INT_CTRL_LATCH_M \
+ 0x04 // latch interrupt request
+#define LSM303D_MAG_INT_CTRL_LATCH_ENABLE \
+ 0x04
+#define LSM303D_MAG_INT_CTRL_4D_M \
+ 0x02 // 4D detection on acceleration
+ // data is enabled when 6D bit in
+ // IG_CFG1
+#define LSM303D_MAG_INT_CTRL_4D_ENABLE \
+ 0x02
+#define LSM303D_MAG_INT_CTRL_MI_M \
+ 0x01 // Interrupt generation for
+ // magnetic data
+#define LSM303D_MAG_INT_CTRL_MI_ENABLE \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_MAG_INT_SRC
+// register.
+//
+//*****************************************************************************
+#define LSM303D_MAG_INT_SRC_M_PTH_X_M \
+ 0x80 // Magnetic value on X-axis exceeds
+ // the threshold on the positive
+ // side.
+#define LSM303D_MAG_INT_SRC_M_PTH_X_ACTIVE \
+ 0x80
+#define LSM303D_MAG_INT_SRC_M_PTH_Y_M \
+ 0x40 // Magnetic value on Y-axis exceeds
+ // the threshold on the positive
+ // side.
+#define LSM303D_MAG_INT_SRC_M_PTH_Y_ACTIVE \
+ 0x40
+#define LSM303D_MAG_INT_SRC_M_PTH_Z_M \
+ 0x20 // Magnetic value on Z-axis exceeds
+ // the threshold on the positive
+ // side.
+#define LSM303D_MAG_INT_SRC_M_PTH_Z_ACTIVE \
+ 0x20
+#define LSM303D_MAG_INT_SRC_M_NTH_X_M \
+ 0x10 // Magnetic value on X-axis exceeds
+ // the threshold on the negative
+ // side.
+#define LSM303D_MAG_INT_SRC_M_NTH_X_ACTIVE \
+ 0x10
+#define LSM303D_MAG_INT_SRC_M_NTH_Y_M \
+ 0x08 // Magnetic value on Y-axis exceeds
+ // the threshold on the negative
+ // side.
+#define LSM303D_MAG_INT_SRC_M_NTH_Y_ACTIVE \
+ 0x08
+#define LSM303D_MAG_INT_SRC_M_NTH_Z_M \
+ 0x04 // Magnetic value on Z-axis exceeds
+ // the threshold on the negative
+ // side.
+#define LSM303D_MAG_INT_SRC_M_NTH_Z_ACTIVE \
+ 0x04
+#define LSM303D_MAG_INT_SRC_MROI_M \
+ 0x02 // Internal measurement range
+ // overflow on magnetic value.
+#define LSM303D_MAG_INT_SRC_MROI_ACTIVE \
+ 0x02
+#define LSM303D_MAG_INT_SRC_MINT_M \
+ 0x01 // Magnetic interrupt event. The
+ // magnetic field value exceeds the
+ // threshold.
+#define LSM303D_MAG_INT_SRC_MINT_ACTIVE \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_CTRL0
+// register.
+//
+//*****************************************************************************
+#define LSM303D_CTRL0_BOOT_M 0x80 // Reboot memory content.
+#define LSM303D_CTRL0_BOOT_REBOOT \
+ 0x80
+#define LSM303D_CTRL0_FIFO_M 0x40 // FIFO enable.
+#define LSM303D_CTRL0_FIFO_ENABLE \
+ 0x40
+#define LSM303D_CTRL0_FTH_M 0x20 // FIFO programmable threshold
+ // enable.
+#define LSM303D_CTRL0_FTH_ENABLE \
+ 0x20
+#define LSM303D_CTRL0_HPCLICK_M 0x04 // High-pass filter enabled for
+ // click function.
+#define LSM303D_CTRL0_HPCLICK_ENABLE \
+ 0x04
+#define LSM303D_CTRL0_HPIS1_M 0x02 // High-pass filter enabled for
+ // interrupt generator 1
+#define LSM303D_CTRL0_HPIS1_ENABLE \
+ 0x02
+#define LSM303D_CTRL0_HPIS2_M 0x01 // High-pass filter enabled for
+ // interrupt generator 2
+#define LSM303D_CTRL0_HPIS2_ENABLE \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_CTRL1
+// register.
+//
+//*****************************************************************************
+#define LSM303D_CTRL1_AODR_M 0xF0 // accel output data rate selection
+#define LSM303D_CTRL1_AODR_PD 0x00 // Power-down mode
+#define LSM303D_CTRL1_AODR_3_125HZ \
+ 0x10
+#define LSM303D_CTRL1_AODR_6_2HZ \
+ 0x20
+#define LSM303D_CTRL1_AODR_12_5HZ \
+ 0x30
+#define LSM303D_CTRL1_AODR_25HZ 0x40
+#define LSM303D_CTRL1_AODR_50HZ 0x50
+#define LSM303D_CTRL1_AODR_100HZ \
+ 0x60
+#define LSM303D_CTRL1_AODR_200HZ \
+ 0x70
+#define LSM303D_CTRL1_AODR_400HZ \
+ 0x80
+#define LSM303D_CTRL1_AODR_800HZ \
+ 0x90
+#define LSM303D_CTRL1_AODR_1600HZ \
+ 0xA0
+#define LSM303D_CTRL1_BDU_M 0x08 // Block data update for
+ // acceleration and magnetic data.
+ // (0: continuous update; 1: output
+ // registers not updated until MSB
+ // and LSB have been read), default
+ // continuous
+#define LSM303D_CTRL1_BDU_CONTINUOUS \
+ 0x00
+#define LSM303D_CTRL1_BDU_BLOCK 0x08
+#define LSM303D_CTRL1_AXIS_M 0x7 // Axis power control
+#define LSM303D_CTRL1_AXIS_Y_EN 0x01 // Y-axis enable
+#define LSM303D_CTRL1_AXIS_X_EN 0x02 // X-axis enable
+#define LSM303D_CTRL1_AXIS_Z_EN 0x04 // Z-axis enable
+#define LSM303D_CTRL1_AODR_S 4
+#define LSM303D_CTRL1_AXIS_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_CTRL2
+// register.
+//
+//*****************************************************************************
+#define LSM303D_CTRL2_AFS_M 0x38 // Acceleration full-scale
+ // selection.
+#define LSM303D_CTRL2_AFS_2G 0x00 // +/- 2G sensitivity
+#define LSM303D_CTRL2_AFS_4G 0x08 // +/- 4G sensitivity
+#define LSM303D_CTRL2_AFS_6G 0x10 // +/- 6G sensitivity
+#define LSM303D_CTRL2_AFS_8G 0x18 // +/- 8G sensitivity
+#define LSM303D_CTRL2_AFS_16G 0x40 // +/- 16G sensitivity
+#define LSM303D_CTRL2_ABW_M 0xC // anti-alias filter bandwidth
+#define LSM303D_CTRL2_ABW_773HZ 0x00
+#define LSM303D_CTRL2_ABW_194HZ 0x40
+#define LSM303D_CTRL2_ABW_362HZ 0x80
+#define LSM303D_CTRL2_ABW_50HZ 0xC0
+#define LSM303D_CTRL2_AST_M 0x02 // Acceleration self-test enable.
+#define LSM303D_CTRL2_AST_ENABLE \
+ 0x02
+#define LSM303D_CTRL2_SIM_M 0x01 // SPI Serial Interface mode
+ // selection. (default: 4 wire)
+#define LSM303D_CTRL2_SIM_4WIRE 0x00
+#define LSM303D_CTRL2_SIM_3WIRE 0x01
+#define LSM303D_CTRL2_ABW_S 6
+#define LSM303D_CTRL2_AFS_S 3
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_CTRL3
+// register.
+//
+//*****************************************************************************
+#define LSM303D_CTRL3_INT1_BOOT_M \
+ 0x80 // Boot on INT1 enable
+#define LSM303D_CTRL3_INT1_BOOT_EN \
+ 0x80
+#define LSM303D_CTRL3_INT1_CLICK_M \
+ 0x40 // Click generator interrupt on
+ // INT1.
+#define LSM303D_CTRL3_INT1_CLICK_EN \
+ 0x40
+#define LSM303D_CTRL3_INT1_IG1_M \
+ 0x20 // Inertial interrupt generator 1
+ // on INT1
+#define LSM303D_CTRL3_INT1_IG1_EN \
+ 0x20
+#define LSM303D_CTRL3_INT1_IG2_M \
+ 0x10 // Inertial interrupt generator 2
+ // on INT1
+#define LSM303D_CTRL3_INT1_IG2_EN \
+ 0x10
+#define LSM303D_CTRL3_INT1_IGM_M \
+ 0x08 // Magnetic interrupt generator on
+ // INT1
+#define LSM303D_CTRL3_INT1_IGM_EN \
+ 0x08
+#define LSM303D_CTRL3_INT1_ACCEL_DRDY_M \
+ 0x04 // Accelerometer data-ready signal
+ // on INT1
+#define LSM303D_CTRL3_INT1_ACCEL_DRDY_EN \
+ 0x04
+#define LSM303D_CTRL3_INT1_MAG_DRDY_M \
+ 0x02 // Magnetometer data-ready signal
+ // on INT1.
+#define LSM303D_CTRL3_INT1_MAG_DRDY_EN \
+ 0x02
+#define LSM303D_CTRL3_INT1_EMPTY_M \
+ 0x01 // FIFO empty indication on INT1
+#define LSM303D_CTRL3_INT1_EMPTY_EN \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_CTRL4
+// register.
+//
+//*****************************************************************************
+#define LSM303D_CTRL4_INT2_CLICK_M \
+ 0x80 // Click generator interrupt on
+ // INT2
+#define LSM303D_CTRL4_INT2_CLICK_EN \
+ 0x80
+#define LSM303D_CTRL4_INT2_IG1_M \
+ 0x40 // Inertial interrupt generator 1
+ // on INT2
+#define LSM303D_CTRL4_INT2_IG1_EN \
+ 0x40
+#define LSM303D_CTRL4_INT2_IG2_M \
+ 0x20 // Inertial interrupt generator 2
+ // on INT2
+#define LSM303D_CTRL4_INT2_IG2_EN \
+ 0x20
+#define LSM303D_CTRL4_INT2_IGM_M \
+ 0x10 // Magnetic interrupt generator on
+ // INT2
+#define LSM303D_CTRL4_INT2_IGM_EN \
+ 0x10
+#define LSM303D_CTRL4_INT2_ACCEL_DRDY_M \
+ 0x08 // Accelerometer data-ready signal
+ // on INT2
+#define LSM303D_CTRL4_INT2_ACCEL_DRDY_EN \
+ 0x08
+#define LSM303D_CTRL4_INT2_MAG_DRDY_M \
+ 0x04 // Magnetometer data-ready signal
+ // on INT2
+#define LSM303D_CTRL4_INT2_MAG_DRDY_EN \
+ 0x04
+#define LSM303D_CTRL4_INT2_OVR_M \
+ 0x02 // FIFO overrun interrupt on INT2
+#define LSM303D_CTRL4_INT2_OVR_EN \
+ 0x02
+#define LSM303D_CTRL4_INT2_FTH_M \
+ 0x01 // FIFO threshold interrupt on INT2
+#define LSM303D_CTRL4_INT2_FTH_EN \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_CTRL5
+// register.
+//
+//*****************************************************************************
+#define LSM303D_CTRL5_TEMP_M 0x80 // Temperature sensor enable.
+#define LSM303D_CTRL5_TEMP_EN 0x80
+#define LSM303D_CTRL5_MRES_M 0x60 // Magnetic resolution selection
+#define LSM303D_CTRL5_MRES_LOW 0x00 // low resolution
+#define LSM303D_CTRL5_MRES_HIGH 0x60 // high resolution
+#define LSM303D_CTRL5_MODR_M 0x1C // mag output data rate selection
+#define LSM303D_CTRL5_MODR_3_125HZ \
+ 0x00
+#define LSM303D_CTRL5_MODR_6_2HZ \
+ 0x04
+#define LSM303D_CTRL5_MODR_12_5HZ \
+ 0x08
+#define LSM303D_CTRL5_MODR_25HZ 0x0C
+#define LSM303D_CTRL5_MODR_50HZ 0x10
+#define LSM303D_CTRL5_MODR_100HZ \
+ 0x14
+#define LSM303D_CTRL5_LIR2_M 0x02 // latch interrupt request on int2
+#define LSM303D_CTRL5_LIR2_EN 0x02
+#define LSM303D_CTRL5_LIR1_M 0x01 // latch interrupt request on int1
+#define LSM303D_CTRL5_LIR1_EN 0x01
+#define LSM303D_CTRL5_MRES_S 5
+#define LSM303D_CTRL5_MODR_S 2
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_CTRL6
+// register.
+//
+//*****************************************************************************
+#define LSM303D_CTRL6_MFS_M 0x60 // magnetic full scale select
+#define LSM303D_CTRL6_MFS_2G 0x00 // +/- 2 gauss
+#define LSM303D_CTRL6_MFS_4G 0x20 // +/- 4 gauss
+#define LSM303D_CTRL6_MFS_8G 0x40 // +/- 8 gauss
+#define LSM303D_CTRL6_MFS_12G 0x60 // +/- 16 gauss
+#define LSM303D_CTRL6_MFS_S 5
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_CTRL7
+// register.
+//
+//*****************************************************************************
+#define LSM303D_CTRL7_AHPM_M 0xC0 // High-pass filter mode selection
+ // for acceleration data
+#define LSM303D_CTRL7_AHPM_NORMAL \
+ 0x00
+#define LSM303D_CTRL7_AHPM_REFERENCE \
+ 0x40
+#define LSM303D_CTRL7_AHPM_AUTORESET \
+ 0xC0
+#define LSM303D_CTRL7_AFDS_M 0x20 // default: internal filter
+ // bypassed
+#define LSM303D_CTRL7_AFDS_BYPASSED \
+ 0x00
+#define LSM303D_CTRL7_AFDS_FILTERED \
+ 0x20
+#define LSM303D_CTRL7_TEMP_ONLY_M \
+ 0x10 // Temperature sensor only mode,
+ // mag off
+#define LSM303D_CTRL7_TEMP_ONLY_EN \
+ 0x10
+#define LSM303D_CTRL7_MLP_M 0x04 // Magnetic data low-power mode. If
+ // this bit is 1, the M_ODR [2:0]
+ // is set to 3.125 Hz independently
+ // from the MODR settings.
+#define LSM303D_CTRL7_MLP_NORMAL \
+ 0x00
+#define LSM303D_CTRL7_MLP_LOWPOWER \
+ 0x04
+#define LSM303D_CTRL7_MD_M 0x3 // Magnetic sensor mode selection
+#define LSM303D_CTRL7_MD_CONTINUOUS \
+ 0x00
+#define LSM303D_CTRL7_MD_SINGLE 0x01
+#define LSM303D_CTRL7_MD_POWERDOWN \
+ 0x02
+#define LSM303D_CTRL7_AHPM_S 6
+#define LSM303D_CTRL7_MD_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_STATUS
+// register.
+//
+//*****************************************************************************
+#define LSM303D_STATUS_OR_M 0xF0 // Accel Axis data overrun
+#define LSM303D_STATUS_OR_X 0x10 // Accel X-axis data overrun
+#define LSM303D_STATUS_OR_Y 0x20 // Accel Y-axis data overrun
+#define LSM303D_STATUS_OR_Z 0x40 // Accel Z-axis data overrun
+#define LSM303D_STATUS_OR_ZYX 0x80 // Accel X, Y, and X data overrun
+#define LSM303D_STATUS_DA_M 0xF // Accel data available
+#define LSM303D_STATUS_DA_X 0x01 // Accel X-axis data available
+#define LSM303D_STATUS_DA_Y 0x02 // Accel Y-axis data available
+#define LSM303D_STATUS_DA_Z 0x04 // Accel Z-axis data available
+#define LSM303D_STATUS_DA_ZYX 0x08 // Accel X, Y, and X data available
+#define LSM303D_STATUS_OR_S 4
+#define LSM303D_STATUS_DA_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_FIFO_CTRL
+// register.
+//
+//*****************************************************************************
+#define LSM303D_FIFO_CTRL_MODE_M \
+ 0xE0 // FIFO mode setting
+#define LSM303D_FIFO_CTRL_MODE_BYPASS \
+ 0x00 // Bypass mode
+#define LSM303D_FIFO_CTRL_MODE_FIFO \
+ 0x20 // FIFO mode
+#define LSM303D_FIFO_CTRL_MODE_STREAM \
+ 0x40 // Stream mode
+#define LSM303D_FIFO_CTRL_MODE_S2F \
+ 0x60 // Stream-to-FIFO mode
+#define LSM303D_FIFO_CTRL_MODE_B2S \
+ 0x80 // Bypass-to-stream mode
+#define LSM303D_FIFO_CTRL_THRESH_M \
+ 0x1F // FIFO Threshold setting
+#define LSM303D_FIFO_CTRL_MODE_S \
+ 5
+#define LSM303D_FIFO_CTRL_THRESH_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_FIFO_SRC
+// register.
+//
+//*****************************************************************************
+#define LSM303D_FIFO_SRC_FTH_M 0x80 // FIFO threshold is greater than
+ // or equal to level or less than
+ // level
+#define LSM303D_FIFO_SRC_FTH_LT 0x00
+#define LSM303D_FIFO_SRC_FTH_GEQ \
+ 0x80
+#define LSM303D_FIFO_SRC_OVRN_M 0x40 // overrun status bit
+#define LSM303D_FIFO_SRC_OVRN_FILLED \
+ 0x40
+#define LSM303D_FIFO_SRC_EMPTY_M \
+ 0x20 // FIFO empty
+#define LSM303D_FIFO_SRC_EMPTY_EMPTY \
+ 0x20
+#define LSM303D_FIFO_SRC_STORE_SAMPLES_M \
+ 0x1F // FIFO stored data level of the
+ // unread samples
+#define LSM303D_FIFO_SRC_STORE_SAMPLES_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_INT1_CFG
+// register.
+//
+//*****************************************************************************
+#define LSM303D_INT1_CFG_ANDOR_M \
+ 0x80 // AND/OR combination of Interrupt
+ // events; default value: 0
+#define LSM303D_INT1_CFG_ANDOR_OR \
+ 0x00
+#define LSM303D_INT1_CFG_ANDOR_AND \
+ 0x80
+#define LSM303D_INT1_CFG_6D_M 0x40 // 6-direction function enabled
+#define LSM303D_INT1_CFG_6D_EN 0x40
+#define LSM303D_INT1_CFG_ZHI_M 0x20 // enable interrupt generation on
+ // Z-hi event
+#define LSM303D_INT1_CFG_ZHI_EN 0x20
+#define LSM303D_INT1_CFG_ZUPE_M 0x20 // enable interrupt generation on
+ // Z-hi event
+#define LSM303D_INT1_CFG_ZUPE_EN \
+ 0x20
+#define LSM303D_INT1_CFG_ZDOWNE_M \
+ 0x10 // enable interrupt generation on
+ // Z-low event
+#define LSM303D_INT1_CFG_ZDOWNE_EN \
+ 0x10
+#define LSM303D_INT1_CFG_ZLI_M 0x10 // enable interrupt generation on
+ // Z-low event
+#define LSM303D_INT1_CFG_ZLI_EN 0x10
+#define LSM303D_INT1_CFG_YUPE_M 0x08 // enable interrupt generation on
+ // Y-hi event
+#define LSM303D_INT1_CFG_YUPE_EN \
+ 0x08
+#define LSM303D_INT1_CFG_YHI_M 0x08 // enable interrupt generation on
+ // Y-hi event
+#define LSM303D_INT1_CFG_YHI_EN 0x08
+#define LSM303D_INT1_CFG_YDOWNE_M \
+ 0x04 // enable interrupt generation on
+ // Y-low event
+#define LSM303D_INT1_CFG_YDOWNE_EN \
+ 0x04
+#define LSM303D_INT1_CFG_YLI_M 0x04 // enable interrupt generation on
+ // Y-low event
+#define LSM303D_INT1_CFG_YLI_EN 0x04
+#define LSM303D_INT1_CFG_XUPE_M 0x02 // enable interrupt generation on
+ // X-hi event
+#define LSM303D_INT1_CFG_XUPE_EN \
+ 0x02
+#define LSM303D_INT1_CFG_XHI_M 0x02 // enable interrupt generation on
+ // X-hi event
+#define LSM303D_INT1_CFG_XHI_EN 0x02
+#define LSM303D_INT1_CFG_XDOWNE_M \
+ 0x01 // enable interrupt generation on
+ // X-low event
+#define LSM303D_INT1_CFG_XDOWNE_EN \
+ 0x01
+#define LSM303D_INT1_CFG_XLI_M 0x01 // enable interrupt generation on
+ // X-low event
+#define LSM303D_INT1_CFG_XLI_EN 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_INT1_SRC
+// register.
+//
+//*****************************************************************************
+#define LSM303D_INT1_SRC_ZERO_M 0x80 // This bit must be zero
+#define LSM303D_INT1_SRC_ZERO_ZERO \
+ 0x00
+#define LSM303D_INT1_SRC_ZERO_INVALID \
+ 0x80
+#define LSM303D_INT1_SRC_IA_M 0x40 // interrupt active
+#define LSM303D_INT1_SRC_IA_ACTIVE \
+ 0x40
+#define LSM303D_INT1_SRC_ZH_M 0x20 // Z-Hi event occurred
+#define LSM303D_INT1_SRC_ZH_OCCURRED \
+ 0x20
+#define LSM303D_INT1_SRC_ZL_M 0x10 // Z-Low event occurred
+#define LSM303D_INT1_SRC_ZL_OCCURRED \
+ 0x10
+#define LSM303D_INT1_SRC_YH_M 0x08 // Y-Hi event occurred
+#define LSM303D_INT1_SRC_YH_OCCURRED \
+ 0x08
+#define LSM303D_INT1_SRC_YL_M 0x04 // Y-Low event occurred
+#define LSM303D_INT1_SRC_YL_OCCURRED \
+ 0x04
+#define LSM303D_INT1_SRC_XH_M 0x02 // X-Hi event occurred
+#define LSM303D_INT1_SRC_XH_OCCURRED \
+ 0x02
+#define LSM303D_INT1_SRC_XL_M 0x01 // X-Low event occurred
+#define LSM303D_INT1_SRC_XL_OCCURRED \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_INT1_THS
+// register.
+//
+//*****************************************************************************
+#define LSM303D_INT1_THS_ZERO_M 0x80 // This bit must be zero
+#define LSM303D_INT1_THS_ZERO_ZERO \
+ 0x00
+#define LSM303D_INT1_THS_ZERO_INVALID \
+ 0x80
+#define LSM303D_INT1_THS_THS_M 0x7F // THS[6-0] Interrupt threshold,
+ // default 0x0
+#define LSM303D_INT1_THS_THS_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_INT1_DURATION
+// register.
+//
+//*****************************************************************************
+#define LSM303D_INT1_DURATION_ZERO_M \
+ 0x80 // This bit must be zero
+#define LSM303D_INT1_DURATION_ZERO_ZERO \
+ 0x00
+#define LSM303D_INT1_DURATION_ZERO_INVALID \
+ 0x80
+#define LSM303D_INT1_DURATION_DURATION_M \
+ 0x7F // Duration D[6-0]
+#define LSM303D_INT1_DURATION_DURATION_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_INT2_CFG
+// register.
+//
+//*****************************************************************************
+#define LSM303D_INT2_CFG_ANDOR_M \
+ 0x80 // AND/OR combination of Interrupt
+ // events; default value: 0
+#define LSM303D_INT2_CFG_ANDOR_OR \
+ 0x00
+#define LSM303D_INT2_CFG_ANDOR_AND \
+ 0x80
+#define LSM303D_INT2_CFG_6D_M 0x40 // 6-direction function enabled
+#define LSM303D_INT2_CFG_6D_EN 0x40
+#define LSM303D_INT2_CFG_ZHI_M 0x20 // enable interrupt generation on
+ // Z-hi event
+#define LSM303D_INT2_CFG_ZHI_EN 0x20
+#define LSM303D_INT2_CFG_ZLI_M 0x10 // enable interrupt generation on
+ // Z-low event
+#define LSM303D_INT2_CFG_ZLI_EN 0x10
+#define LSM303D_INT2_CFG_YHI_M 0x08 // enable interrupt generation on
+ // Y-hi event
+#define LSM303D_INT2_CFG_YHI_EN 0x08
+#define LSM303D_INT2_CFG_YLI_M 0x04 // enable interrupt generation on
+ // Y-low event
+#define LSM303D_INT2_CFG_YLI_EN 0x04
+#define LSM303D_INT2_CFG_XHI_M 0x02 // enable interrupt generation on
+ // X-hi event
+#define LSM303D_INT2_CFG_XHI_EN 0x02
+#define LSM303D_INT2_CFG_XLI_M 0x01 // enable interrupt generation on
+ // X-low event
+#define LSM303D_INT2_CFG_XLI_EN 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_INT2_SRC
+// register.
+//
+//*****************************************************************************
+#define LSM303D_INT2_SRC_ZERO_M 0x80 // This bit must be zero
+#define LSM303D_INT2_SRC_ZERO_ZERO \
+ 0x00
+#define LSM303D_INT2_SRC_ZERO_INVALID \
+ 0x80
+#define LSM303D_INT2_SRC_IA_M 0x40 // interrupt active
+#define LSM303D_INT2_SRC_IA_ACTIVE \
+ 0x40
+#define LSM303D_INT2_SRC_ZH_M 0x20 // Z-Hi event occurred
+#define LSM303D_INT2_SRC_ZH_OCCURRED \
+ 0x20
+#define LSM303D_INT2_SRC_ZL_M 0x10 // Z-Low event occurred
+#define LSM303D_INT2_SRC_ZL_OCCURRED \
+ 0x10
+#define LSM303D_INT2_SRC_YH_M 0x08 // Y-Hi event occurred
+#define LSM303D_INT2_SRC_YH_OCCURRED \
+ 0x08
+#define LSM303D_INT2_SRC_YL_M 0x04 // Y-Low event occurred
+#define LSM303D_INT2_SRC_YL_OCCURRED \
+ 0x04
+#define LSM303D_INT2_SRC_XH_M 0x02 // X-Hi event occurred
+#define LSM303D_INT2_SRC_XH_OCCURRED \
+ 0x02
+#define LSM303D_INT2_SRC_XL_M 0x01 // X-Low event occurred
+#define LSM303D_INT2_SRC_XL_OCCURRED \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_INT2_THS
+// register.
+//
+//*****************************************************************************
+#define LSM303D_INT2_THS_ZERO_M 0x80 // This bit must be zero
+#define LSM303D_INT2_THS_ZERO_ZERO \
+ 0x00
+#define LSM303D_INT2_THS_ZERO_INVALID \
+ 0x80
+#define LSM303D_INT2_THS_THS_M 0x7F // THS[6-0] Interrupt threshold,
+ // default 0x0
+#define LSM303D_INT2_THS_THS_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_INT2_DURATION
+// register.
+//
+//*****************************************************************************
+#define LSM303D_INT2_DURATION_ZERO_M \
+ 0x80 // This bit must be zero
+#define LSM303D_INT2_DURATION_ZERO_ZERO \
+ 0x00
+#define LSM303D_INT2_DURATION_ZERO_INVALID \
+ 0x80
+#define LSM303D_INT2_DURATION_DURATION_M \
+ 0x7F // Duration D[6-0]
+#define LSM303D_INT2_DURATION_DURATION_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_CLICK_CFG
+// register.
+//
+//*****************************************************************************
+#define LSM303D_CLICK_CFG_ZD_M 0x20 // Enable interrupt double click on
+ // Z axis
+#define LSM303D_CLICK_CFG_ZD_DIS \
+ 0x00
+#define LSM303D_CLICK_CFG_ZD_EN 0x20
+#define LSM303D_CLICK_CFG_ZS_M 0x10 // Enable interrupt single click on
+ // Z axis
+#define LSM303D_CLICK_CFG_ZS_DIS \
+ 0x00
+#define LSM303D_CLICK_CFG_ZS_EN 0x10
+#define LSM303D_CLICK_CFG_YD_M 0x08 // Enable interrupt double click on
+ // Y axis
+#define LSM303D_CLICK_CFG_YD_DIS \
+ 0x00
+#define LSM303D_CLICK_CFG_YD_EN 0x08
+#define LSM303D_CLICK_CFG_YS_M 0x04 // Enable interrupt single click on
+ // Y axis
+#define LSM303D_CLICK_CFG_YS_DIS \
+ 0x00
+#define LSM303D_CLICK_CFG_YS_EN 0x04
+#define LSM303D_CLICK_CFG_XD_M 0x02 // Enable interrupt double click on
+ // X axis
+#define LSM303D_CLICK_CFG_XD_DIS \
+ 0x00
+#define LSM303D_CLICK_CFG_XD_EN 0x02
+#define LSM303D_CLICK_CFG_XS_M 0x01 // Enable interrupt single click on
+ // X axis
+#define LSM303D_CLICK_CFG_XS_DIS \
+ 0x00
+#define LSM303D_CLICK_CFG_XS_EN 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_CLICK_SRC
+// register.
+//
+//*****************************************************************************
+#define LSM303D_CLICK_SRC_IA_M 0x40 // Interrupt pending
+#define LSM303D_CLICK_SRC_IA_NONE \
+ 0x00
+#define LSM303D_CLICK_SRC_IA_PENDING \
+ 0x40
+#define LSM303D_CLICK_SRC_DCLICK_M \
+ 0x20 // double click-click enable
+#define LSM303D_CLICK_SRC_DCLICK_DIS \
+ 0x00
+#define LSM303D_CLICK_SRC_DCLICK_EN \
+ 0x20
+#define LSM303D_CLICK_SRC_SCLICK_M \
+ 0x10 // single click-click enable
+#define LSM303D_CLICK_SRC_SCLICK_DIS \
+ 0x00
+#define LSM303D_CLICK_SRC_SCLICK_EN \
+ 0x10
+#define LSM303D_CLICK_SRC_SIGN_M \
+ 0x08 // click-click sign
+#define LSM303D_CLICK_SRC_SIGN_POSITIVE \
+ 0x00
+#define LSM303D_CLICK_SRC_SIGN_NEGATIVE \
+ 0x08
+#define LSM303D_CLICK_SRC_AXIS_M \
+ 0x7 // Axis click detection
+#define LSM303D_CLICK_SRC_AXIS_X \
+ 0x01 // X click-click detection
+#define LSM303D_CLICK_SRC_AXIS_Y \
+ 0x02 // Y click-click detection
+#define LSM303D_CLICK_SRC_AXIS_Z \
+ 0x04 // Z click-click detection
+#define LSM303D_CLICK_SRC_AXIS_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_CLICK_THS
+// register.
+//
+//*****************************************************************************
+#define LSM303D_CLICK_THS_THS_M 0x7F // Threshold; 1 LSB = full-scale /
+ // 128; THS6 through THS0 define
+ // the threshold which is used by
+ // the system to start the click
+ // detection procedure; the
+ // threshold value is expressed
+ // over 7 bits as an unsigned
+ // number
+#define LSM303D_CLICK_THS_THS_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_TIME_LIMIT
+// register.
+//
+//*****************************************************************************
+#define LSM303D_TIME_LIMIT_TLI_M \
+ 0x7F // Time Limit; 1 LSB = 1/ODR; TLI7
+ // through TLI0 define the maximum
+ // time interval that can elapse
+ // between the start of the click
+ // detection procedure (the
+ // acceleration on the selected
+ // channel exceeds the programmed
+ // threshold) and when the
+ // acceleration goes back below the
+ // threshold
+#define LSM303D_TIME_LIMIT_TLI_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_ACT_THS
+// register.
+//
+//*****************************************************************************
+#define LSM303D_ACT_THS_THRESHOLD_M \
+ 0x7F
+#define LSM303D_ACT_THS_THRESHOLD_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303D_O_ACT_DUR
+// register.
+//
+//*****************************************************************************
+#define LSM303D_ACT_DUR_THRESHOLD_M \
+ 0x7F
+#define LSM303D_ACT_DUR_THRESHOLD_S \
+ 0
+
+#endif // __SENSORLIB_HW_LSM303D_H__
diff --git a/sensorlib/hw_lsm303dlhc.h b/sensorlib/hw_lsm303dlhc.h new file mode 100644 index 0000000..06cf9ba --- /dev/null +++ b/sensorlib/hw_lsm303dlhc.h @@ -0,0 +1,1034 @@ +//*****************************************************************************
+//
+// hw_lsm303dlhc.h - Macros used when accessing the ST LSM303DLHC accel/mag
+// combo
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_HW_LSM303DLHC_H__
+#define __SENSORLIB_HW_LSM303DLHC_H__
+
+//*****************************************************************************
+//
+// The following are defines for the LSM303DLHC register addresses
+//
+//*****************************************************************************
+#define LSM303DLHC_O_MAG_CRA 0x0 // Magnetometer control
+#define LSM303DLHC_O_MAG_CRB 0x01 // Gain configuration
+#define LSM303DLHC_O_MAG_MR 0x02 // Mode configuration
+#define LSM303DLHC_O_MAG_OUT_X_MSB \
+ 0x03 // X-axis MSB
+#define LSM303DLHC_O_MAG_OUT_X_LSB \
+ 0x04 // X-axis LSB
+#define LSM303DLHC_O_MAG_OUT_Y_MSB \
+ 0x05 // Y-axis MSB
+#define LSM303DLHC_O_MAG_OUT_Y_LSB \
+ 0x06 // Y-axis LSB
+#define LSM303DLHC_O_MAG_OUT_Z_MSB \
+ 0x07 // Z-axis MSB
+#define LSM303DLHC_O_MAG_OUT_Z_LSB \
+ 0x08 // Z-axis LSB
+#define LSM303DLHC_O_MAG_SR 0x09 // Status register
+#define LSM303DLHC_O_MAG_IRA 0x0A
+#define LSM303DLHC_O_MAG_IRB 0x0B
+#define LSM303DLHC_O_MAG_IRC 0x0C
+#define LSM303DLHC_O_CTRL1 0x20 // Control 1 - power settings
+#define LSM303DLHC_O_CTRL2 0x21 // Control 2
+#define LSM303DLHC_O_CTRL3 0x22 // Control 3
+#define LSM303DLHC_O_CTRL4 0x23 // Control 4
+#define LSM303DLHC_O_CTRL5 0x24 // Control 5
+#define LSM303DLHC_O_CTRL6 0x25 // Control 6
+#define LSM303DLHC_O_REFERENCE 0x26 // Reference/Datacapture_A
+#define LSM303DLHC_O_STATUS 0x27 // Status register
+#define LSM303DLHC_O_OUT_X_LSB 0x28 // X-axis LSB
+#define LSM303DLHC_O_OUT_X_MSB 0x29 // X-axis MSB
+#define LSM303DLHC_O_OUT_Y_LSB 0x2A // Y-axis LSB
+#define LSM303DLHC_O_OUT_Y_MSB 0x2B // Y-axis MSB
+#define LSM303DLHC_O_OUT_Z_LSB 0x2C // Z-axis LSB
+#define LSM303DLHC_O_OUT_Z_MSB 0x2D // Z-axis MSB
+#define LSM303DLHC_O_FIFO_CTRL 0x2E // FIFO control
+#define LSM303DLHC_O_FIFO_SRC 0x2F // FIFO_SRC register
+#define LSM303DLHC_O_INT1_CFG_A 0x30 // INT1 interrupt generation; this
+ // register only writable after
+ // boot
+#define LSM303DLHC_O_INT1_SRC_A 0x31 // interrupt source register (read
+ // only)
+#define LSM303DLHC_O_MAG_TEMP_OUT_MSB \
+ 0x31 // Temperature bits 11-4
+#define LSM303DLHC_O_MAG_TEMP_OUT_LSB \
+ 0x32 // Temperature bits 3-0
+#define LSM303DLHC_O_INT1_THS_A 0x32 // Interrupt 1 threshold
+#define LSM303DLHC_O_INT1_DURATION_A \
+ 0x33 // INT1 duration register
+#define LSM303DLHC_O_INT2_CFG_A 0x34 // INT2 interrupt generation; this
+ // register only writable after
+ // boot
+#define LSM303DLHC_O_INT2_SRC_A 0x35 // INT2 source register (read only)
+#define LSM303DLHC_O_INT2_THS_A 0x36 // INT2 threshold
+#define LSM303DLHC_O_INT2_DURATION_A \
+ 0x37 // INT2 duration register
+#define LSM303DLHC_O_CLICK_CFG_A \
+ 0x38 // Click config A register
+#define LSM303DLHC_O_CLICK_SRC_A \
+ 0x39 // Click source A
+#define LSM303DLHC_O_CLICK_THS_A \
+ 0x3A // click-click threshold
+#define LSM303DLHC_O_TIME_LIMIT_A \
+ 0x3B // Time Limit A register
+#define LSM303DLHC_O_TIME_LATENCY_A \
+ 0x3C // Time Latency A register; 1 LSB =
+ // 1/ODR; TLA7 through TLA0 define
+ // the time interval that starts
+ // after the first click detection
+ // where the click detection
+ // procedure is disabled, in cases
+ // where the device is configured
+ // for double click detection
+#define LSM303DLHC_O_TIME_WINDOW_A \
+ 0x3D // Time Window A register; 1 LSB =
+ // 1/ODR; TW7 through TW0 define
+ // the maximum interval of time
+ // that can elapse after the end of
+ // the latency interval in which
+ // the click detection procedure
+ // can start, in cases where the
+ // device is configured for double
+ // click detection
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_MAG_CRA
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_MAG_CRA_TEMP_M \
+ 0x80 // Temperature sensor enable
+#define LSM303DLHC_MAG_CRA_TEMP_DIS \
+ 0x00
+#define LSM303DLHC_MAG_CRA_TEMP_EN \
+ 0x80
+#define LSM303DLHC_MAG_CRA_DO_M 0x1C // Data output rate
+#define LSM303DLHC_MAG_CRA_DO_0_75HZ \
+ 0x00 // 0.75 Hz
+#define LSM303DLHC_MAG_CRA_DO_1_5HZ \
+ 0x04 // 1.5 Hz
+#define LSM303DLHC_MAG_CRA_DO_3_0HZ \
+ 0x08 // 3.0 Hz
+#define LSM303DLHC_MAG_CRA_DO_7_5HZ \
+ 0x0C // 7.5 Hz
+#define LSM303DLHC_MAG_CRA_DO_15HZ \
+ 0x10 // 15 Hz
+#define LSM303DLHC_MAG_CRA_DO_30HZ \
+ 0x14 // 30 Hz
+#define LSM303DLHC_MAG_CRA_DO_75HZ \
+ 0x18 // 75 Hz
+#define LSM303DLHC_MAG_CRA_DO_220HZ \
+ 0x1C // 220 Hz
+#define LSM303DLHC_MAG_CRA_DO_S 2
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_MAG_CRB
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_MAG_CRB_GAIN_M \
+ 0xE0 // Gain selection
+#define LSM303DLHC_MAG_CRB_GAIN_1_3GAUSS \
+ 0x20 // +/- 1.3 gauss, 1100 LSB/gauss
+#define LSM303DLHC_MAG_CRB_GAIN_1_9GAUSS \
+ 0x40 // +/- 1.9 gauss, 855 LSB/gauss
+#define LSM303DLHC_MAG_CRB_GAIN_2_5GAUSS \
+ 0x60 // +/- 2.5 gauss, 670 LSB/gauss
+#define LSM303DLHC_MAG_CRB_GAIN_4_0GAUSS \
+ 0x80 // +/- 4.0 gauss, 450 LSB/guass
+#define LSM303DLHC_MAG_CRB_GAIN_4_7GAUSS \
+ 0xA0 // +/- 4.7 gauss, 400 LSB/gauss
+#define LSM303DLHC_MAG_CRB_GAIN_5_6GAUSS \
+ 0xC0 // +/- 5.6 gauss, 330 LSB/gauss
+#define LSM303DLHC_MAG_CRB_GAIN_8_1GAUSS \
+ 0xE0 // +/- 8.1 gauss, 230 LSB/gauss
+#define LSM303DLHC_MAG_CRB_GAIN_S \
+ 5
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_MAG_MR
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_MAG_MR_MODE_M \
+ 0x3 // Mode select bits
+#define LSM303DLHC_MAG_MR_MODE_CONTINUOUS \
+ 0x00 // Continuous conversion mode
+#define LSM303DLHC_MAG_MR_MODE_SINGLE \
+ 0x01 // Single conversion mode
+#define LSM303DLHC_MAG_MR_MODE_SLEEP \
+ 0x02 // Sleep mode
+#define LSM303DLHC_MAG_MR_MODE_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_MAG_SR
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_MAG_SR_LOCK_M \
+ 0x02 // Data output register lock; once
+ // a new set of measurements is
+ // available, this bit is set when
+ // the first magnetic field data
+ // register has been read
+#define LSM303DLHC_MAG_SR_LOCK_LOCKED \
+ 0x02
+#define LSM303DLHC_MAG_SR_DATA_M \
+ 0x01 // Data ready bit; this bit is set
+ // when a new set of measures are
+ // available
+#define LSM303DLHC_MAG_SR_DATA_READ \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_MAG_IRA
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_MAG_IRA_CONSTANT_M \
+ 0xFF
+#define LSM303DLHC_MAG_IRA_CONSTANT_VAL \
+ 0x48
+#define LSM303DLHC_MAG_IRA_CONSTANT_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_MAG_IRB
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_MAG_IRB_CONSTANT_M \
+ 0xFF
+#define LSM303DLHC_MAG_IRB_CONSTANT_VAL \
+ 0x34
+#define LSM303DLHC_MAG_IRB_CONSTANT_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_MAG_IRC
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_MAG_IRC_CONSTANT_M \
+ 0xFF
+#define LSM303DLHC_MAG_IRC_CONSTANT_VAL \
+ 0x33
+#define LSM303DLHC_MAG_IRC_CONSTANT_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_CTRL1
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_CTRL1_ODR_M 0xF0 // data rate selection
+#define LSM303DLHC_CTRL1_ODR_PD 0x00 // Power-down mode
+#define LSM303DLHC_CTRL1_ODR_1HZ \
+ 0x10
+#define LSM303DLHC_CTRL1_ODR_10HZ \
+ 0x20
+#define LSM303DLHC_CTRL1_ODR_25HZ \
+ 0x30
+#define LSM303DLHC_CTRL1_ODR_50HZ \
+ 0x40
+#define LSM303DLHC_CTRL1_ODR_100HZ \
+ 0x50
+#define LSM303DLHC_CTRL1_ODR_200HZ \
+ 0x60
+#define LSM303DLHC_CTRL1_ODR_400HZ \
+ 0x70
+#define LSM303DLHC_CTRL1_ODR_1620HZ \
+ 0x80 // Low power mode
+#define LSM303DLHC_CTRL1_ODR_5376HZ \
+ 0x90 // 1.344KHz normal, 5.376KHz low
+ // power
+#define LSM303DLHC_CTRL1_POWER_M \
+ 0x08 // Power control
+#define LSM303DLHC_CTRL1_POWER_LOWPOW \
+ 0x00
+#define LSM303DLHC_CTRL1_POWER_NORMAL \
+ 0x08
+#define LSM303DLHC_CTRL1_AXIS_M 0x7 // Axis power control
+#define LSM303DLHC_CTRL1_AXIS_Y_EN \
+ 0x01 // Y-axis enable
+#define LSM303DLHC_CTRL1_AXIS_X_EN \
+ 0x02 // X-axis enable
+#define LSM303DLHC_CTRL1_AXIS_Z_EN \
+ 0x04 // Z-axis enable
+#define LSM303DLHC_CTRL1_ODR_S 4
+#define LSM303DLHC_CTRL1_AXIS_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_CTRL2
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_CTRL2_HPMODE_M \
+ 0xC0 // high pass filter mode selection
+#define LSM303DLHC_CTRL2_HPMODE_NORMAL_RESET \
+ 0x00 // normal mode (reset reading
+ // HP_RESET_FILTER)
+#define LSM303DLHC_CTRL2_HPMODE_REFERENCE \
+ 0x40 // reference signal for filtering
+#define LSM303DLHC_CTRL2_HPMODE_NORMAL \
+ 0x80 // Normal mode
+#define LSM303DLHC_CTRL2_HPMODE_AUTORESET \
+ 0xC0 // autoreset on interrupt event
+#define LSM303DLHC_CTRL2_HPCUTOFF_M \
+ 0x30 // high pass filter cut-off
+ // frequency selection
+#define LSM303DLHC_CTRL2_FDS_M 0x08 // Filtered data selection
+#define LSM303DLHC_CTRL2_FDS_BYPASSED \
+ 0x00
+#define LSM303DLHC_CTRL2_FDS_FILTERED \
+ 0x08
+#define LSM303DLHC_CTRL2_HPCLICK_M \
+ 0x04 // High pass filter enabled for
+ // CLICK function
+#define LSM303DLHC_CTRL2_HPCLICK_BYPASSED \
+ 0x00
+#define LSM303DLHC_CTRL2_HPCLICK_FILTERED \
+ 0x04
+#define LSM303DLHC_CTRL2_HPIS2_M \
+ 0x02 // High pass filter enabled for AOI
+ // function on Interrupt 2
+#define LSM303DLHC_CTRL2_HPIS2_BYPASSED \
+ 0x00
+#define LSM303DLHC_CTRL2_HPIS2_FILTERED \
+ 0x02
+#define LSM303DLHC_CTRL2_HPIS1_M \
+ 0x01 // High pass filter enabled for AOI
+ // function on Interrupt 1
+#define LSM303DLHC_CTRL2_HPIS1_BYPASSED \
+ 0x00
+#define LSM303DLHC_CTRL2_HPIS1_FILTERED \
+ 0x01
+#define LSM303DLHC_CTRL2_HPMODE_S \
+ 6
+#define LSM303DLHC_CTRL2_HPCUTOFF_S \
+ 4
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_CTRL3
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_CTRL3_I1CLICK_M \
+ 0x80 // CLICK on INT1
+#define LSM303DLHC_CTRL3_I1CLICK_DIS \
+ 0x00
+#define LSM303DLHC_CTRL3_I1CLICK_EN \
+ 0x80
+#define LSM303DLHC_CTRL3_I1AOI1_M \
+ 0x40 // AOI1 on INT1
+#define LSM303DLHC_CTRL3_I1AOI1_DIS \
+ 0x00
+#define LSM303DLHC_CTRL3_I1AOI1_EN \
+ 0x40
+#define LSM303DLHC_CTRL3_I1AOI2_M \
+ 0x20 // AOI2 on INT1
+#define LSM303DLHC_CTRL3_I1AOI2_DIS \
+ 0x00
+#define LSM303DLHC_CTRL3_I1AOI2_EN \
+ 0x20
+#define LSM303DLHC_CTRL3_I1DRDY1_M \
+ 0x10 // DRDY1 on INT1
+#define LSM303DLHC_CTRL3_I1DRDY1_DIS \
+ 0x00
+#define LSM303DLHC_CTRL3_I1DRDY1_EN \
+ 0x10
+#define LSM303DLHC_CTRL3_I1DRDY2_M \
+ 0x08 // DRDY2 on INT1
+#define LSM303DLHC_CTRL3_I1DRDY2_DIS \
+ 0x00
+#define LSM303DLHC_CTRL3_I1DRDY2_EN \
+ 0x08
+#define LSM303DLHC_CTRL3_I1WTM_M \
+ 0x04 // FIFO watermark interrupt on INT1
+#define LSM303DLHC_CTRL3_I1WTM_DIS \
+ 0x00
+#define LSM303DLHC_CTRL3_I1WTM_EN \
+ 0x04
+#define LSM303DLHC_CTRL3_I1OVERRUN_M \
+ 0x02 // FIFO overrun interrupt on INT1
+#define LSM303DLHC_CTRL3_I1OVERRUN_DIS \
+ 0x00
+#define LSM303DLHC_CTRL3_I1OVERRUN_EN \
+ 0x02
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_CTRL4
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_CTRL4_BDU_M 0x80 // Block data update; default
+ // value: 0 (0: continuous update;
+ // 1: output registers not updated
+ // until MSB and LSB reading)
+#define LSM303DLHC_CTRL4_BDU_CONTINUOUS \
+ 0x00
+#define LSM303DLHC_CTRL4_BDU_MSBLSB \
+ 0x80
+#define LSM303DLHC_CTRL4_ENDIAN_M \
+ 0x40 // Endian selection
+#define LSM303DLHC_CTRL4_ENDIAN_LITTLE \
+ 0x00
+#define LSM303DLHC_CTRL4_ENDIAN_BIG \
+ 0x40
+#define LSM303DLHC_CTRL4_FS_M 0x30 // full scale selection; default
+ // value: 0
+#define LSM303DLHC_CTRL4_FS_2G 0x00
+#define LSM303DLHC_CTRL4_FS_4G 0x10
+#define LSM303DLHC_CTRL4_FS_8G 0x20
+#define LSM303DLHC_CTRL4_FS_16G 0x30
+#define LSM303DLHC_CTRL4_RESOLUTION_M \
+ 0x08 // resolution output mode
+#define LSM303DLHC_CTRL4_RESOLUTION_LOW \
+ 0x00
+#define LSM303DLHC_CTRL4_RESOLUTION_HIGH \
+ 0x08
+#define LSM303DLHC_CTRL4_SIM_M 0x01 // SPI Serial Interface Mode
+ // selection (default = 0, 4-wire)
+#define LSM303DLHC_CTRL4_SIM_4WIRE \
+ 0x00
+#define LSM303DLHC_CTRL4_SIM_3WIRE \
+ 0x01
+#define LSM303DLHC_CTRL4_FS_S 4
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_CTRL5
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_CTRL5_REBOOTCTL_M \
+ 0x80 // Reboot memory conent
+#define LSM303DLHC_CTRL5_REBOOTCTL_NORMAL \
+ 0x00
+#define LSM303DLHC_CTRL5_REBOOTCTL_REBOOT \
+ 0x80
+#define LSM303DLHC_CTRL5_FIFO_M 0x40 // FIFO enable
+#define LSM303DLHC_CTRL5_FIFO_DIS \
+ 0x00
+#define LSM303DLHC_CTRL5_FIFO_EN \
+ 0x40
+#define LSM303DLHC_CTRL5_LIR_INT1_M \
+ 0x08 // Latch interrupt on INT1
+#define LSM303DLHC_CTRL5_LIR_INT1_DIS \
+ 0x00
+#define LSM303DLHC_CTRL5_LIR_INT1_EN \
+ 0x08
+#define LSM303DLHC_CTRL5_D4D_INT1_M \
+ 0x04 // 4D Int enable on INT1
+#define LSM303DLHC_CTRL5_D4D_INT1_DIS \
+ 0x00
+#define LSM303DLHC_CTRL5_D4D_INT1_EN \
+ 0x04
+#define LSM303DLHC_CTRL5_LIR_INT2_M \
+ 0x02 // Latch interrupt request on
+ // INT2_SRC register, with INT2_SRC
+ // register cleared by reading
+ // INT2_SRC itself; default value:
+ // 0
+#define LSM303DLHC_CTRL5_LIR_INT2_DIS \
+ 0x00
+#define LSM303DLHC_CTRL5_LIR_INT2_EN \
+ 0x02
+#define LSM303DLHC_CTRL5_D4D_INT2_M \
+ 0x01 // 4D enable: 4D detection is
+ // enabled on INT2 when 6D bit on
+ // INT2_CFG is set to 1
+#define LSM303DLHC_CTRL5_D4D_INT2_DIS \
+ 0x00
+#define LSM303DLHC_CTRL5_D4D_INT2_EN \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_CTRL6
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_CTRL6_I2_CLICK_M \
+ 0x80 // CLICK interrupt on PAD2
+#define LSM303DLHC_CTRL6_I2_CLICK_DIS \
+ 0x00
+#define LSM303DLHC_CTRL6_I2_CLICK_EN \
+ 0x80
+#define LSM303DLHC_CTRL6_I2_INT1_M \
+ 0x40 // Interrupt 1 on PAD2; default
+ // value 0
+#define LSM303DLHC_CTRL6_I2_INT1_DIS \
+ 0x00
+#define LSM303DLHC_CTRL6_I2_INT1_EN \
+ 0x40
+#define LSM303DLHC_CTRL6_I2_INT2_M \
+ 0x20 // Interrupt 2 on PAD2; default
+ // value 0
+#define LSM303DLHC_CTRL6_I2_INT2_DIS \
+ 0x00
+#define LSM303DLHC_CTRL6_I2_INT2_EN \
+ 0x20
+#define LSM303DLHC_CTRL6_BOOT_I2_M \
+ 0x10 // Reboot memory content on PAD2;
+ // default value: 0
+#define LSM303DLHC_CTRL6_BOOT_I2_DIS \
+ 0x00
+#define LSM303DLHC_CTRL6_BOOT_I2_EN \
+ 0x10
+#define LSM303DLHC_CTRL6_P2_ACT_M \
+ 0x08 // active function status on PAD2
+#define LSM303DLHC_CTRL6_P2_ACT_DIS \
+ 0x00
+#define LSM303DLHC_CTRL6_P2_ACT_EN \
+ 0x08
+#define LSM303DLHC_CTRL6_H_LACTIVE_M \
+ 0x02 // interrupt active configuration
+ // on INT; default value 0 (0:
+ // high; 1:low)
+#define LSM303DLHC_CTRL6_H_LACTIVE_HI \
+ 0x00
+#define LSM303DLHC_CTRL6_H_LACTIVE_LOW \
+ 0x02
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_STATUS
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_STATUS_OR_M 0xF0 // Axis data overrun
+#define LSM303DLHC_STATUS_OR_X 0x10 // X-axis data overrun
+#define LSM303DLHC_STATUS_OR_Y 0x20 // Y-axis data overrun
+#define LSM303DLHC_STATUS_OR_Z 0x40 // Z-axis data overrun
+#define LSM303DLHC_STATUS_OR_ZYX \
+ 0x80 // X, Y, and X data overrun
+#define LSM303DLHC_STATUS_DA_M 0xF // Axis data available
+#define LSM303DLHC_STATUS_DA_X 0x01 // X-axis data available
+#define LSM303DLHC_STATUS_DA_Y 0x02 // Y-axis data available
+#define LSM303DLHC_STATUS_DA_Z 0x04 // Z-axis data available
+#define LSM303DLHC_STATUS_DA_ZYX \
+ 0x08 // X, Y, and X data available
+#define LSM303DLHC_STATUS_OR_S 4
+#define LSM303DLHC_STATUS_DA_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_FIFO_CTRL
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_FIFO_CTRL_TR_M \
+ 0x20
+#define LSM303DLHC_FIFO_CTRL_TR_INT1 \
+ 0x00
+#define LSM303DLHC_FIFO_CTRL_TR_INT2 \
+ 0x20
+#define LSM303DLHC_FIFO_CTRL_THRESH_M \
+ 0x1F // FIFO Threshold setting
+#define LSM303DLHC_FIFO_CTRL_MODE_M \
+ 0xC // FIFO mode setting
+#define LSM303DLHC_FIFO_CTRL_MODE_BYPASS \
+ 0x00 // Bypass mode
+#define LSM303DLHC_FIFO_CTRL_MODE_FIFO \
+ 0x40 // FIFO mode
+#define LSM303DLHC_FIFO_CTRL_MODE_STREAM \
+ 0x80 // Stream mode
+#define LSM303DLHC_FIFO_CTRL_MODE_TRIGGER \
+ 0xC0 // Trigger mode
+#define LSM303DLHC_FIFO_CTRL_MODE_S \
+ 6
+#define LSM303DLHC_FIFO_CTRL_THRESH_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_FIFO_SRC
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_FIFO_SRC_FTH_M \
+ 0x80 // FIFO threshold is greater than
+ // or equal to level or less than
+ // level
+#define LSM303DLHC_FIFO_SRC_FTH_LT \
+ 0x00
+#define LSM303DLHC_FIFO_SRC_FTH_GEQ \
+ 0x80
+#define LSM303DLHC_FIFO_SRC_OVRN_M \
+ 0x40 // overrun status bit
+#define LSM303DLHC_FIFO_SRC_OVRN_FILLED \
+ 0x40
+#define LSM303DLHC_FIFO_SRC_EMPTY_M \
+ 0x20 // FIFO empty
+#define LSM303DLHC_FIFO_SRC_EMPTY_EMPTY \
+ 0x20
+#define LSM303DLHC_FIFO_SRC_STORE_SAMPLES_M \
+ 0x1F // FIFO stored data level of the
+ // unread samples
+#define LSM303DLHC_FIFO_SRC_STORE_SAMPLES_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_INT1_CFG_A
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_INT1_CFG_A_ANDOR_M \
+ 0x80 // AND/OR combination of Interrupt
+ // events; default value: 0
+#define LSM303DLHC_INT1_CFG_A_ANDOR_OR \
+ 0x00
+#define LSM303DLHC_INT1_CFG_A_ANDOR_AND \
+ 0x80
+#define LSM303DLHC_INT1_CFG_A_6D_M \
+ 0x40 // 6-direction function enabled
+#define LSM303DLHC_INT1_CFG_A_6D_EN \
+ 0x40
+#define LSM303DLHC_INT1_CFG_A_ZHI_M \
+ 0x20 // enable interrupt generation on
+ // Z-hi event
+#define LSM303DLHC_INT1_CFG_A_ZHI_EN \
+ 0x20
+#define LSM303DLHC_INT1_CFG_A_ZUPE_M \
+ 0x20 // enable interrupt generation on
+ // Z-hi event
+#define LSM303DLHC_INT1_CFG_A_ZUPE_EN \
+ 0x20
+#define LSM303DLHC_INT1_CFG_A_ZDOWNE_M \
+ 0x10 // enable interrupt generation on
+ // Z-low event
+#define LSM303DLHC_INT1_CFG_A_ZDOWNE_EN \
+ 0x10
+#define LSM303DLHC_INT1_CFG_A_ZLI_M \
+ 0x10 // enable interrupt generation on
+ // Z-low event
+#define LSM303DLHC_INT1_CFG_A_ZLI_EN \
+ 0x10
+#define LSM303DLHC_INT1_CFG_A_YUPE_M \
+ 0x08 // enable interrupt generation on
+ // Y-hi event
+#define LSM303DLHC_INT1_CFG_A_YUPE_EN \
+ 0x08
+#define LSM303DLHC_INT1_CFG_A_YHI_M \
+ 0x08 // enable interrupt generation on
+ // Y-hi event
+#define LSM303DLHC_INT1_CFG_A_YHI_EN \
+ 0x08
+#define LSM303DLHC_INT1_CFG_A_YDOWNE_M \
+ 0x04 // enable interrupt generation on
+ // Y-low event
+#define LSM303DLHC_INT1_CFG_A_YDOWNE_EN \
+ 0x04
+#define LSM303DLHC_INT1_CFG_A_YLI_M \
+ 0x04 // enable interrupt generation on
+ // Y-low event
+#define LSM303DLHC_INT1_CFG_A_YLI_EN \
+ 0x04
+#define LSM303DLHC_INT1_CFG_A_XHI_M \
+ 0x02 // enable interrupt generation on
+ // X-hi event
+#define LSM303DLHC_INT1_CFG_A_XHI_EN \
+ 0x02
+#define LSM303DLHC_INT1_CFG_A_XUPE_M \
+ 0x02 // enable interrupt generation on
+ // X-hi event
+#define LSM303DLHC_INT1_CFG_A_XUPE_EN \
+ 0x02
+#define LSM303DLHC_INT1_CFG_A_XLI_M \
+ 0x01 // enable interrupt generation on
+ // X-low event
+#define LSM303DLHC_INT1_CFG_A_XLI_EN \
+ 0x01
+#define LSM303DLHC_INT1_CFG_A_XDOWNE_M \
+ 0x01 // enable interrupt generation on
+ // X-low event
+#define LSM303DLHC_INT1_CFG_A_XDOWNE_EN \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_INT1_SRC_A
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_INT1_SRC_A_ZERO_M \
+ 0x80 // This bit must be zero
+#define LSM303DLHC_INT1_SRC_A_ZERO_ZERO \
+ 0x00
+#define LSM303DLHC_INT1_SRC_A_ZERO_INVALID \
+ 0x80
+#define LSM303DLHC_INT1_SRC_A_IA_M \
+ 0x40 // interrupt active
+#define LSM303DLHC_INT1_SRC_A_IA_ACTIVE \
+ 0x40
+#define LSM303DLHC_INT1_SRC_A_ZH_M \
+ 0x20 // Z-Hi event occurred
+#define LSM303DLHC_INT1_SRC_A_ZH_OCCURRED \
+ 0x20
+#define LSM303DLHC_INT1_SRC_A_ZL_M \
+ 0x10 // Z-Low event occurred
+#define LSM303DLHC_INT1_SRC_A_ZL_OCCURRED \
+ 0x10
+#define LSM303DLHC_INT1_SRC_A_YH_M \
+ 0x08 // Y-Hi event occurred
+#define LSM303DLHC_INT1_SRC_A_YH_OCCURRED \
+ 0x08
+#define LSM303DLHC_INT1_SRC_A_YL_M \
+ 0x04 // Y-Low event occurred
+#define LSM303DLHC_INT1_SRC_A_YL_OCCURRED \
+ 0x04
+#define LSM303DLHC_INT1_SRC_A_XH_M \
+ 0x02 // X-Hi event occurred
+#define LSM303DLHC_INT1_SRC_A_XH_OCCURRED \
+ 0x02
+#define LSM303DLHC_INT1_SRC_A_XL_M \
+ 0x01 // X-Low event occurred
+#define LSM303DLHC_INT1_SRC_A_XL_OCCURRED \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// LSM303DLHC_O_MAG_TEMP_OUT_MSB register.
+//
+//*****************************************************************************
+#define LSM303DLHC_MAG_TEMP_OUT_MSB_MSB_M \
+ 0xFF
+#define LSM303DLHC_MAG_TEMP_OUT_MSB_MSB_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// LSM303DLHC_O_MAG_TEMP_OUT_LSB register.
+//
+//*****************************************************************************
+#define LSM303DLHC_MAG_TEMP_OUT_LSB_LSB_M \
+ 0xF0
+#define LSM303DLHC_MAG_TEMP_OUT_LSB_LSB_S \
+ 4
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_INT1_THS_A
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_INT1_THS_A_ZERO_M \
+ 0x80 // This bit must be zero
+#define LSM303DLHC_INT1_THS_A_ZERO_ZERO \
+ 0x00
+#define LSM303DLHC_INT1_THS_A_ZERO_INVALID \
+ 0x80
+#define LSM303DLHC_INT1_THS_A_THS_M \
+ 0x7F // THS[6-0] Interrupt threshold,
+ // default 0x0
+#define LSM303DLHC_INT1_THS_A_THS_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// LSM303DLHC_O_INT1_DURATION_A register.
+//
+//*****************************************************************************
+#define LSM303DLHC_INT1_DURATION_A_ZERO_M \
+ 0x80 // This bit must be zero
+#define LSM303DLHC_INT1_DURATION_A_ZERO_ZERO \
+ 0x00
+#define LSM303DLHC_INT1_DURATION_A_ZERO_INVALID \
+ 0x80
+#define LSM303DLHC_INT1_DURATION_A_DURATION_M \
+ 0x7F // Duration D[6-0]
+#define LSM303DLHC_INT1_DURATION_A_DURATION_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_INT2_CFG_A
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_INT2_CFG_A_ANDOR_M \
+ 0x80 // AND/OR combination of Interrupt
+ // events; default value: 0
+#define LSM303DLHC_INT2_CFG_A_ANDOR_OR \
+ 0x00
+#define LSM303DLHC_INT2_CFG_A_ANDOR_AND \
+ 0x80
+#define LSM303DLHC_INT2_CFG_A_6D_M \
+ 0x40 // 6-direction function enabled
+#define LSM303DLHC_INT2_CFG_A_6D_EN \
+ 0x40
+#define LSM303DLHC_INT2_CFG_A_ZHI_M \
+ 0x20 // enable interrupt generation on
+ // Z-hi event
+#define LSM303DLHC_INT2_CFG_A_ZHI_EN \
+ 0x20
+#define LSM303DLHC_INT2_CFG_A_ZLI_M \
+ 0x10 // enable interrupt generation on
+ // Z-low event
+#define LSM303DLHC_INT2_CFG_A_ZLI_EN \
+ 0x10
+#define LSM303DLHC_INT2_CFG_A_YHI_M \
+ 0x08 // enable interrupt generation on
+ // Y-hi event
+#define LSM303DLHC_INT2_CFG_A_YHI_EN \
+ 0x08
+#define LSM303DLHC_INT2_CFG_A_YLI_M \
+ 0x04 // enable interrupt generation on
+ // Y-low event
+#define LSM303DLHC_INT2_CFG_A_YLI_EN \
+ 0x04
+#define LSM303DLHC_INT2_CFG_A_XHI_M \
+ 0x02 // enable interrupt generation on
+ // X-hi event
+#define LSM303DLHC_INT2_CFG_A_XHI_EN \
+ 0x02
+#define LSM303DLHC_INT2_CFG_A_XLI_M \
+ 0x01 // enable interrupt generation on
+ // X-low event
+#define LSM303DLHC_INT2_CFG_A_XLI_EN \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_INT2_SRC_A
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_INT2_SRC_A_ZERO_M \
+ 0x80 // This bit must be zero
+#define LSM303DLHC_INT2_SRC_A_ZERO_ZERO \
+ 0x00
+#define LSM303DLHC_INT2_SRC_A_ZERO_INVALID \
+ 0x80
+#define LSM303DLHC_INT2_SRC_A_IA_M \
+ 0x40 // interrupt active
+#define LSM303DLHC_INT2_SRC_A_IA_ACTIVE \
+ 0x40
+#define LSM303DLHC_INT2_SRC_A_ZH_M \
+ 0x20 // Z-Hi event occurred
+#define LSM303DLHC_INT2_SRC_A_ZH_OCCURRED \
+ 0x20
+#define LSM303DLHC_INT2_SRC_A_ZL_M \
+ 0x10 // Z-Low event occurred
+#define LSM303DLHC_INT2_SRC_A_ZL_OCCURRED \
+ 0x10
+#define LSM303DLHC_INT2_SRC_A_YH_M \
+ 0x08 // Y-Hi event occurred
+#define LSM303DLHC_INT2_SRC_A_YH_OCCURRED \
+ 0x08
+#define LSM303DLHC_INT2_SRC_A_YL_M \
+ 0x04 // Y-Low event occurred
+#define LSM303DLHC_INT2_SRC_A_YL_OCCURRED \
+ 0x04
+#define LSM303DLHC_INT2_SRC_A_XH_M \
+ 0x02 // X-Hi event occurred
+#define LSM303DLHC_INT2_SRC_A_XH_OCCURRED \
+ 0x02
+#define LSM303DLHC_INT2_SRC_A_XL_M \
+ 0x01 // X-Low event occurred
+#define LSM303DLHC_INT2_SRC_A_XL_OCCURRED \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_INT2_THS_A
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_INT2_THS_A_ZERO_M \
+ 0x80 // This bit must be zero
+#define LSM303DLHC_INT2_THS_A_ZERO_ZERO \
+ 0x00
+#define LSM303DLHC_INT2_THS_A_ZERO_INVALID \
+ 0x80
+#define LSM303DLHC_INT2_THS_A_THS_M \
+ 0x7F // THS[6-0] Interrupt threshold,
+ // default 0x0
+#define LSM303DLHC_INT2_THS_A_THS_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// LSM303DLHC_O_INT2_DURATION_A register.
+//
+//*****************************************************************************
+#define LSM303DLHC_INT2_DURATION_A_ZERO_M \
+ 0x80 // This bit must be zero
+#define LSM303DLHC_INT2_DURATION_A_ZERO_ZERO \
+ 0x00
+#define LSM303DLHC_INT2_DURATION_A_ZERO_INVALID \
+ 0x80
+#define LSM303DLHC_INT2_DURATION_A_DURATION_M \
+ 0x7F // Duration D[6-0]
+#define LSM303DLHC_INT2_DURATION_A_DURATION_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_CLICK_CFG_A
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_CLICK_CFG_A_ZD_M \
+ 0x20 // Enable interrupt double click on
+ // Z axis
+#define LSM303DLHC_CLICK_CFG_A_ZD_DIS \
+ 0x00
+#define LSM303DLHC_CLICK_CFG_A_ZD_EN \
+ 0x20
+#define LSM303DLHC_CLICK_CFG_A_ZS_M \
+ 0x10 // Enable interrupt single click on
+ // Z axis
+#define LSM303DLHC_CLICK_CFG_A_ZS_DIS \
+ 0x00
+#define LSM303DLHC_CLICK_CFG_A_ZS_EN \
+ 0x10
+#define LSM303DLHC_CLICK_CFG_A_YD_M \
+ 0x08 // Enable interrupt double click on
+ // Y axis
+#define LSM303DLHC_CLICK_CFG_A_YD_DIS \
+ 0x00
+#define LSM303DLHC_CLICK_CFG_A_YD_EN \
+ 0x08
+#define LSM303DLHC_CLICK_CFG_A_YS_M \
+ 0x04 // Enable interrupt single click on
+ // Y axis
+#define LSM303DLHC_CLICK_CFG_A_YS_DIS \
+ 0x00
+#define LSM303DLHC_CLICK_CFG_A_YS_EN \
+ 0x04
+#define LSM303DLHC_CLICK_CFG_A_XD_M \
+ 0x02 // Enable interrupt double click on
+ // X axis
+#define LSM303DLHC_CLICK_CFG_A_XD_DIS \
+ 0x00
+#define LSM303DLHC_CLICK_CFG_A_XD_EN \
+ 0x02
+#define LSM303DLHC_CLICK_CFG_A_XS_M \
+ 0x01 // Enable interrupt single click on
+ // X axis
+#define LSM303DLHC_CLICK_CFG_A_XS_DIS \
+ 0x00
+#define LSM303DLHC_CLICK_CFG_A_XS_EN \
+ 0x01
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_CLICK_SRC_A
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_CLICK_SRC_A_IA_M \
+ 0x40 // Interrupt pending
+#define LSM303DLHC_CLICK_SRC_A_IA_NONE \
+ 0x00
+#define LSM303DLHC_CLICK_SRC_A_IA_PENDING \
+ 0x40
+#define LSM303DLHC_CLICK_SRC_A_DCLICK_M \
+ 0x20 // double click-click enable
+#define LSM303DLHC_CLICK_SRC_A_DCLICK_DIS \
+ 0x00
+#define LSM303DLHC_CLICK_SRC_A_DCLICK_EN \
+ 0x20
+#define LSM303DLHC_CLICK_SRC_A_SCLICK_M \
+ 0x10 // single click-click enable
+#define LSM303DLHC_CLICK_SRC_A_SCLICK_DIS \
+ 0x00
+#define LSM303DLHC_CLICK_SRC_A_SCLICK_EN \
+ 0x10
+#define LSM303DLHC_CLICK_SRC_A_SIGN_M \
+ 0x08 // click-click sign
+#define LSM303DLHC_CLICK_SRC_A_SIGN_POSITIVE \
+ 0x00
+#define LSM303DLHC_CLICK_SRC_A_SIGN_NEGATIVE \
+ 0x08
+#define LSM303DLHC_CLICK_SRC_A_AXIS_M \
+ 0x7 // Axis click detection
+#define LSM303DLHC_CLICK_SRC_A_AXIS_X \
+ 0x01 // X click-click detection
+#define LSM303DLHC_CLICK_SRC_A_AXIS_Y \
+ 0x02 // Y click-click detection
+#define LSM303DLHC_CLICK_SRC_A_AXIS_Z \
+ 0x04 // Z click-click detection
+#define LSM303DLHC_CLICK_SRC_A_AXIS_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the LSM303DLHC_O_CLICK_THS_A
+// register.
+//
+//*****************************************************************************
+#define LSM303DLHC_CLICK_THS_A_THS_M \
+ 0x7F // Threshold; 1 LSB = full-scale /
+ // 128; THS6 through THS0 define
+ // the threshold which is used by
+ // the system to start the click
+ // detection procedure; the
+ // threshold value is expressed
+ // over 7 bits as an unsigned
+ // number
+#define LSM303DLHC_CLICK_THS_A_THS_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// LSM303DLHC_O_TIME_LIMIT_A register.
+//
+//*****************************************************************************
+#define LSM303DLHC_TIME_LIMIT_A_TLI_M \
+ 0x7F // Time Limit; 1 LSB = 1/ODR; TLI7
+ // through TLI0 define the maximum
+ // time interval that can elapse
+ // between the start of the click
+ // detection procedure (the
+ // acceleration on the selected
+ // channel exceeds the programmed
+ // threshold) and when the
+ // acceleration goes back below the
+ // threshold
+#define LSM303DLHC_TIME_LIMIT_A_TLI_S \
+ 0
+
+#endif // __SENSORLIB_HW_LSM303DLHC_H__
diff --git a/sensorlib/hw_mpu6050.h b/sensorlib/hw_mpu6050.h new file mode 100644 index 0000000..32706e9 --- /dev/null +++ b/sensorlib/hw_mpu6050.h @@ -0,0 +1,1313 @@ +//*****************************************************************************
+//
+// hw_mpu6050.h - Macros used when accessing the Invensense MPU6050
+// accelerometer/gyroscope/magnetometer.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_HW_MPU6050_H__
+#define __SENSORLIB_HW_MPU6050_H__
+
+//*****************************************************************************
+//
+// The following are defines for the MPU6050 register addresses.
+//
+//*****************************************************************************
+#define MPU6050_O_SELF_TEST_X 0x0D // Self test X register
+#define MPU6050_O_SELF_TEST_Y 0x0E // Self test Y register
+#define MPU6050_O_SELF_TEST_Z 0x0F // Self test Z register
+#define MPU6050_O_SELF_TEST_A 0x10 // Self test A register
+#define MPU6050_O_SMPLRT_DIV 0x19 // Sample rate divider register
+#define MPU6050_O_CONFIG 0x1A // Configuration register
+#define MPU6050_O_GYRO_CONFIG 0x1B // Gyro configuration register
+#define MPU6050_O_ACCEL_CONFIG 0x1C // Accelerometer configuration
+ // register
+#define MPU6050_O_MOT_THR 0x1F // Motion detection threshold
+ // register
+#define MPU6050_O_FIFO_EN 0x23 // FIFO enable register
+#define MPU6050_O_I2C_MST_CTRL 0x24 // I2C master control register
+#define MPU6050_O_I2C_SLV0_ADDR 0x25 // I2C slave 0 address register
+#define MPU6050_O_I2C_SLV0_REG 0x26 // I2C slave 0 register number
+ // register
+#define MPU6050_O_I2C_SLV0_CTRL 0x27 // I2C slave 0 control register
+#define MPU6050_O_I2C_SLV1_ADDR 0x28 // I2C slave 1 address register
+#define MPU6050_O_I2C_SLV1_REG 0x29 // I2C slave 1 register number
+ // register
+#define MPU6050_O_I2C_SLV1_CTRL 0x2A // I2C slave 1 control register
+#define MPU6050_O_I2C_SLV2_ADDR 0x2B // I2C slave 2 address register
+#define MPU6050_O_I2C_SLV2_REG 0x2C // I2C slave 2 register number
+ // register
+#define MPU6050_O_I2C_SLV2_CTRL 0x2D // I2C slave 2 control register
+#define MPU6050_O_I2C_SLV3_ADDR 0x2E // I2C slave 3 address register
+#define MPU6050_O_I2C_SLV3_REG 0x2F // I2C slave 3 register number
+ // register
+#define MPU6050_O_I2C_SLV3_CTRL 0x30 // I2C slave 3 control register
+#define MPU6050_O_I2C_SLV4_ADDR 0x31 // I2C slave 4 address register
+#define MPU6050_O_I2C_SLV4_REG 0x32 // I2C slave 4 register number
+ // register
+#define MPU6050_O_I2C_SLV4_DO 0x33 // I2C slave 4 output data register
+#define MPU6050_O_I2C_SLV4_CTRL 0x34 // I2C slave 4 control register
+#define MPU6050_O_I2C_SLV4_DI 0x35 // I2C slave 4 input data register
+#define MPU6050_O_I2C_MST_STATUS \
+ 0x36 // I2C master status register
+#define MPU6050_O_INT_PIN_CFG 0x37 // INT pin configuration register
+#define MPU6050_O_INT_ENABLE 0x38 // Interrupt enable register
+#define MPU6050_O_INT_STATUS 0x3A // Interrupt status register
+#define MPU6050_O_ACCEL_XOUT_H 0x3B // X-axis acceleration data MSB
+ // register
+#define MPU6050_O_ACCEL_XOUT_L 0x3C // X-axis acceleration data LSB
+ // register
+#define MPU6050_O_ACCEL_YOUT_H 0x3D // Y-axis acceleration data MSB
+ // register
+#define MPU6050_O_ACCEL_YOUT_L 0x3E // Y-axis accelearation data LSB
+ // register
+#define MPU6050_O_ACCEL_ZOUT_H 0x3F // Z-axis acceleration data MSB
+ // register
+#define MPU6050_O_ACCEL_ZOUT_L 0x40 // Z-axis acceleration data LSB
+ // register
+#define MPU6050_O_TEMP_OUT_H 0x41 // Temperature data MSB register
+#define MPU6050_O_TEMP_OUT_L 0x42 // Temperature data LSB register
+#define MPU6050_O_GYRO_XOUT_H 0x43 // X-axis gyro data MSB register
+#define MPU6050_O_GYRO_XOUT_L 0x44 // X-axis gyro data LSB register
+#define MPU6050_O_GYRO_YOUT_H 0x45 // Y-axis gyro data MSB register
+#define MPU6050_O_GYRO_YOUT_L 0x46 // Y-axis gyro data LSB register
+#define MPU6050_O_GYRO_ZOUT_H 0x47 // Z-axis gyro data MSB register
+#define MPU6050_O_GYRO_ZOUT_L 0x48 // Z-axis gyro data LSB register
+#define MPU6050_O_EXT_SENS_DATA_00 \
+ 0x49 // External sensor data 0 register
+#define MPU6050_O_EXT_SENS_DATA_01 \
+ 0x4A // External sensor data 1 register
+#define MPU6050_O_EXT_SENS_DATA_02 \
+ 0x4B // External sensor data 2 register
+#define MPU6050_O_EXT_SENS_DATA_03 \
+ 0x4C // External sensor data 3 register
+#define MPU6050_O_EXT_SENS_DATA_04 \
+ 0x4D // External sensor data 4 register
+#define MPU6050_O_EXT_SENS_DATA_05 \
+ 0x4E // External sensor data 5 register
+#define MPU6050_O_EXT_SENS_DATA_06 \
+ 0x4F // External sensor data 6 register
+#define MPU6050_O_EXT_SENS_DATA_07 \
+ 0x50 // External sensor data 7 register
+#define MPU6050_O_EXT_SENS_DATA_08 \
+ 0x51 // External sensor data 8 register
+#define MPU6050_O_EXT_SENS_DATA_09 \
+ 0x52 // External sensor data 9 register
+#define MPU6050_O_EXT_SENS_DATA_10 \
+ 0x53 // External sensor data 10 register
+#define MPU6050_O_EXT_SENS_DATA_11 \
+ 0x54 // External sensor data 11 register
+#define MPU6050_O_EXT_SENS_DATA_12 \
+ 0x55 // External sensor data 12 register
+#define MPU6050_O_EXT_SENS_DATA_13 \
+ 0x56 // External sensor data 13 register
+#define MPU6050_O_EXT_SENS_DATA_14 \
+ 0x57 // External sensor data 14 register
+#define MPU6050_O_EXT_SENS_DATA_15 \
+ 0x58 // External sensor data 15 register
+#define MPU6050_O_EXT_SENS_DATA_16 \
+ 0x59 // External sensor data 16 register
+#define MPU6050_O_EXT_SENS_DATA_17 \
+ 0x5A // External sensor data 17 register
+#define MPU6050_O_EXT_SENS_DATA_18 \
+ 0x5B // External sensor data 18 register
+#define MPU6050_O_EXT_SENS_DATA_19 \
+ 0x5C // External sensor data 19 register
+#define MPU6050_O_EXT_SENS_DATA_20 \
+ 0x5D // External sensor data 20 register
+#define MPU6050_O_EXT_SENS_DATA_21 \
+ 0x5E // External sensor data 21 register
+#define MPU6050_O_EXT_SENS_DATA_22 \
+ 0x5F // External sensor data 22 register
+#define MPU6050_O_EXT_SENS_DATA_23 \
+ 0x60 // External sensor data 23 register
+#define MPU6050_O_I2C_SLV0_DO 0x63 // I2C slave 0 output data register
+#define MPU6050_O_I2C_SLV1_DO 0x64 // I2C slave 1 output data register
+#define MPU6050_O_I2C_SLV2_DO 0x65 // I2C slave 2 output data register
+#define MPU6050_O_I2C_SLV3_DO 0x66 // I2C slave 3 output data register
+#define MPU6050_O_I2C_MST_DELAY_CTRL \
+ 0x67 // I2C master delay control
+ // register
+#define MPU6050_O_SIGNAL_PATH_RESET \
+ 0x68 // Signal path reset register
+#define MPU6050_O_MOT_DETECT_CTRL \
+ 0x69 // Motion detection control
+ // register
+#define MPU6050_O_USER_CTRL 0x6A // User control register
+#define MPU6050_O_PWR_MGMT_1 0x6B // Power management 1 register
+#define MPU6050_O_PWR_MGMT_2 0x6C // Power management 2 register
+#define MPU6050_O_FIFO_COUNTH 0x72 // FIFO count MSB register
+#define MPU6050_O_FIFO_COUNTL 0x73 // FIFO count LSB register
+#define MPU6050_O_FIFO_R_W 0x74 // FIFO read write register
+#define MPU6050_O_WHO_AM_I 0x75 // Who am I register
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_SELF_TEST_X
+// register.
+//
+//*****************************************************************************
+#define MPU6050_SELF_TEST_X_XA_TEST_M \
+ 0xE0 // Accelerometer XA_TEST[4:2]
+#define MPU6050_SELF_TEST_X_XG_TEST_M \
+ 0x1F // Gyro XG_TEST[4:0]
+#define MPU6050_SELF_TEST_X_XA_TEST_S \
+ 5
+#define MPU6050_SELF_TEST_X_XG_TEST_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_SELF_TEST_Y
+// register.
+//
+//*****************************************************************************
+#define MPU6050_SELF_TEST_Y_YA_TEST_M \
+ 0xE0 // Accelerometer YA_TEST[4:2]
+#define MPU6050_SELF_TEST_Y_YG_TEST_M \
+ 0x1F // Gyro YG_TEST[4:0]
+#define MPU6050_SELF_TEST_Y_YA_TEST_S \
+ 5
+#define MPU6050_SELF_TEST_Y_YG_TEST_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_SELF_TEST_Z
+// register.
+//
+//*****************************************************************************
+#define MPU6050_SELF_TEST_Z_ZA_TEST_M \
+ 0xE0 // Accelerometer ZA_TEST[4:2]
+#define MPU6050_SELF_TEST_Z_ZG_TEST_M \
+ 0x1F // Gyro ZG_TEST[4:0]
+#define MPU6050_SELF_TEST_Z_ZA_TEST_S \
+ 5
+#define MPU6050_SELF_TEST_Z_ZG_TEST_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_SELF_TEST_A
+// register.
+//
+//*****************************************************************************
+#define MPU6050_SELF_TEST_A_XA_TEST_M \
+ 0x30 // Accelerometer XA_TEST[1:0]
+#define MPU6050_SELF_TEST_A_YA_TEST_M \
+ 0x0C // Accelerometer YA_TEST[1:0]
+#define MPU6050_SELF_TEST_A_ZA_TEST_M \
+ 0x03 // Accelerometer ZA_TEST[1:0]
+#define MPU6050_SELF_TEST_A_XA_TEST_S \
+ 4
+#define MPU6050_SELF_TEST_A_YA_TEST_S \
+ 2
+#define MPU6050_SELF_TEST_A_ZA_TEST_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_SMPLRT_DIV
+// register.
+//
+//*****************************************************************************
+#define MPU6050_SMPLRT_DIV_M 0xFF // Gyro output rate divider
+#define MPU6050_SMPLRT_DIV_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_CONFIG
+// register.
+//
+//*****************************************************************************
+#define MPU6050_CONFIG_EXT_SYNC_SET_M \
+ 0x38 // FSYNC pin sample location
+#define MPU6050_CONFIG_EXT_SYNC_SET_DIS \
+ 0x00 // FSYNC input disabled
+#define MPU6050_CONFIG_EXT_SYNC_SET_TEMP_OUT_L \
+ 0x08 // FSYNC on TEMP_OUT_L[0]
+#define MPU6050_CONFIG_EXT_SYNC_SET_GYRO_XOUT_L \
+ 0x10 // FSYNC on GYRO_XOUT_L[0]
+#define MPU6050_CONFIG_EXT_SYNC_SET_GYRO_YOUT_L \
+ 0x18 // FSYNC on GYRO_YOUT_L[0]
+#define MPU6050_CONFIG_EXT_SYNC_SET_GYRO_ZOUT_L \
+ 0x20 // FSYNC on GYRO_ZOUT_L[0]
+#define MPU6050_CONFIG_EXT_SYNC_SET_ACCEL_XOUT_L \
+ 0x28 // FSYNC on ACCEL_XOUT_L[0]
+#define MPU6050_CONFIG_EXT_SYNC_SET_ACCEL_YOUT_L \
+ 0x30 // FSYNC on ACCEL_YOUT_L[0]
+#define MPU6050_CONFIG_EXT_SYNC_SET_ACCEL_ZOUT_L \
+ 0x38 // FSYNC on ACCEL_ZOUT_L[0]
+#define MPU6050_CONFIG_DLPF_CFG_M \
+ 0x07 // Digital low-pass filter
+ // configuration
+#define MPU6050_CONFIG_DLPF_CFG_260_256 \
+ 0x00 // 260 Hz accelerometer bandwidth,
+ // 256 Hz gyro bandwidth
+#define MPU6050_CONFIG_DLPF_CFG_184_188 \
+ 0x01 // 184 Hz accelerometer bandwidth,
+ // 188 Hz gyro bandwidth
+#define MPU6050_CONFIG_DLPF_CFG_94_98 \
+ 0x02 // 94 Hz accelerometer bandwidth,
+ // 98 Hz gyro bandwidth
+#define MPU6050_CONFIG_DLPF_CFG_44_42 \
+ 0x03 // 44 Hz accelerometer bandwidth,
+ // 42 Hz gyro bandwidth
+#define MPU6050_CONFIG_DLPF_CFG_21_20 \
+ 0x04 // 21 Hz accelerometer bandwidth,
+ // 20 Hz gyro bandwidth
+#define MPU6050_CONFIG_DLPF_CFG_10_10 \
+ 0x05 // 10 Hz accelerometer bandwidth,
+ // 10 Hz gyro bandwidth
+#define MPU6050_CONFIG_DLPF_CFG_5_5 \
+ 0x06 // 5 Hz accelerometer bandwidth, 5
+ // Hz gyro bandwidth
+#define MPU6050_CONFIG_EXT_SYNC_SET_S \
+ 3
+#define MPU6050_CONFIG_DLPF_CFG_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_GYRO_CONFIG
+// register.
+//
+//*****************************************************************************
+#define MPU6050_GYRO_CONFIG_FS_SEL_M \
+ 0x18 // Gyro full-scale range
+#define MPU6050_GYRO_CONFIG_FS_SEL_250 \
+ 0x00 // Gyro full-scale range +/- 250
+ // degrees/sec
+#define MPU6050_GYRO_CONFIG_FS_SEL_500 \
+ 0x08 // Gyro full-scale range +/- 500
+ // degrees/sec
+#define MPU6050_GYRO_CONFIG_FS_SEL_1000 \
+ 0x10 // Gyro full-scale range +/- 1000
+ // degrees/sec
+#define MPU6050_GYRO_CONFIG_FS_SEL_2000 \
+ 0x18 // Gyro full-scale range +/- 2000
+ // degrees/sec
+#define MPU6050_GYRO_CONFIG_FS_SEL_S \
+ 3
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_ACCEL_CONFIG
+// register.
+//
+//*****************************************************************************
+#define MPU6050_ACCEL_CONFIG_XA_ST \
+ 0x80 // X-axis accelerometer self-test
+ // enable
+#define MPU6050_ACCEL_CONFIG_YA_ST \
+ 0x40 // Y-axis accelerometer self-test
+ // enable
+#define MPU6050_ACCEL_CONFIG_ZA_ST \
+ 0x20 // Z-axis accelerometer self-test
+ // enable
+#define MPU6050_ACCEL_CONFIG_AFS_SEL_M \
+ 0x18 // Accelerometer full-scale range
+#define MPU6050_ACCEL_CONFIG_AFS_SEL_2G \
+ 0x00 // Accelerometer full-scale range 2
+ // g
+#define MPU6050_ACCEL_CONFIG_AFS_SEL_4G \
+ 0x08 // Accelerometer full-scale range 4
+ // g
+#define MPU6050_ACCEL_CONFIG_AFS_SEL_8G \
+ 0x10 // Accelerometer full-scale range 8
+ // g
+#define MPU6050_ACCEL_CONFIG_AFS_SEL_16G \
+ 0x18 // Accelerometer full-scale range
+ // 16 g
+#define MPU6050_ACCEL_CONFIG_AFS_SEL_S \
+ 3
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_MOT_THR
+// register.
+//
+//*****************************************************************************
+#define MPU6050_MOT_THR_M 0xFF // Motion detection threshold value
+#define MPU6050_MOT_THR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_FIFO_EN
+// register.
+//
+//*****************************************************************************
+#define MPU6050_FIFO_EN_TEMP 0x80 // Temperature sensor FIFO enable
+#define MPU6050_FIFO_EN_XG 0x40 // X-axis gyro FIFO enable
+#define MPU6050_FIFO_EN_YG 0x20 // Y-axis gyro FIFO enable
+#define MPU6050_FIFO_EN_ZG 0x10 // Z-axis gyro FIFO enable
+#define MPU6050_FIFO_EN_ACCEL 0x08 // Accelerometer FIFO enable
+#define MPU6050_FIFO_EN_SLV2 0x04 // Slave 2 FIFO enable
+#define MPU6050_FIFO_EN_SLV1 0x02 // Slave 1 FIFO enable
+#define MPU6050_FIFO_EN_SLV0 0x01 // Slave 0 FIFO enable
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_MST_CTRL
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_MST_CTRL_MULT_MST_EN \
+ 0x80 // Multi-master enable
+#define MPU6050_I2C_MST_CTRL_WAIT_FOR_ES \
+ 0x40 // Wait for external sensor data
+#define MPU6050_I2C_MST_CTRL_SLV3_FIFO_EN \
+ 0x20 // Slave 3 FIFO enable
+#define MPU6050_I2C_MST_CTRL_I2C_MST_P_NSR \
+ 0x10 // No repeated start conditions
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_M \
+ 0x0F // I2C master clock speed
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_348 \
+ 0x00 // 348 kHz I2C master clock
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_333 \
+ 0x01 // 333 kHz I2C master clock
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_320 \
+ 0x02 // 320 kHz I2C master clock
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_308 \
+ 0x03 // 308 kHz I2C master clock
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_296 \
+ 0x04 // 296 kHz I2C master clock
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_286 \
+ 0x05 // 286 kHz I2C master clock
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_276 \
+ 0x06 // 276 kHz I2C master clock
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_267 \
+ 0x07 // 267 kHz I2C master clock
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_258 \
+ 0x08 // 258 kHz I2C master clock
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_500 \
+ 0x09 // 500 kHz I2C master clock
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_471 \
+ 0x0A // 471 kHz I2C master clock
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_444 \
+ 0x0B // 444 kHz I2C master clock
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_421 \
+ 0x0C // 421 kHz I2C master clock
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_400 \
+ 0x0D // 400 kHz I2C master clock
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_381 \
+ 0x0E // 381 kHz I2C master clock
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_364 \
+ 0x0F // 364 kHz I2C master clock
+#define MPU6050_I2C_MST_CTRL_I2C_MST_CLK_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV0_ADDR
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV0_ADDR_RW \
+ 0x80 // Read/not write
+#define MPU6050_I2C_SLV0_ADDR_M 0x7F // Slave address
+#define MPU6050_I2C_SLV0_ADDR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV0_REG
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV0_REG_M 0xFF // Slave register number
+#define MPU6050_I2C_SLV0_REG_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV0_CTRL
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV0_CTRL_EN \
+ 0x80 // Enable slave
+#define MPU6050_I2C_SLV0_CTRL_BYTE_SW \
+ 0x40 // Byte-swap word pairs
+#define MPU6050_I2C_SLV0_CTRL_REG_DIS \
+ 0x20 // Disable register number transfer
+#define MPU6050_I2C_SLV0_CTRL_GRP \
+ 0x10 // Word pair grouping
+#define MPU6050_I2C_SLV0_CTRL_LEN_M \
+ 0x0F // Number of bytes to transfer
+#define MPU6050_I2C_SLV0_CTRL_LEN_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV1_ADDR
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV1_ADDR_RW \
+ 0x80 // Read/not write
+#define MPU6050_I2C_SLV1_ADDR_M 0x7F // Slave address
+#define MPU6050_I2C_SLV1_ADDR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV1_REG
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV1_REG_M 0xFF // Slave register number
+#define MPU6050_I2C_SLV1_REG_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV1_CTRL
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV1_CTRL_EN \
+ 0x80 // Enable slave
+#define MPU6050_I2C_SLV1_CTRL_BYTE_SW \
+ 0x40 // Byte-swap word pairs
+#define MPU6050_I2C_SLV1_CTRL_REG_DIS \
+ 0x20 // Disable register number transfer
+#define MPU6050_I2C_SLV1_CTRL_GRP \
+ 0x10 // Word pair grouping
+#define MPU6050_I2C_SLV1_CTRL_LEN_M \
+ 0x0F // Number of bytes to transfer
+#define MPU6050_I2C_SLV1_CTRL_LEN_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV2_ADDR
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV2_ADDR_RW \
+ 0x80 // Read/not write
+#define MPU6050_I2C_SLV2_ADDR_M 0x7F // Slave address
+#define MPU6050_I2C_SLV2_ADDR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV2_REG
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV2_REG_M 0xFF // Slave register number
+#define MPU6050_I2C_SLV2_REG_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV2_CTRL
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV2_CTRL_EN \
+ 0x80 // Enable slave
+#define MPU6050_I2C_SLV2_CTRL_BYTE_SW \
+ 0x40 // Byte-swap word pairs
+#define MPU6050_I2C_SLV2_CTRL_REG_DIS \
+ 0x20 // Disable register number transfer
+#define MPU6050_I2C_SLV2_CTRL_GRP \
+ 0x10 // Word pair grouping
+#define MPU6050_I2C_SLV2_CTRL_LEN_M \
+ 0x0F // Number of bytes to transfer
+#define MPU6050_I2C_SLV2_CTRL_LEN_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV3_ADDR
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV3_ADDR_RW \
+ 0x80 // Read/not write
+#define MPU6050_I2C_SLV3_ADDR_M 0x7F // Slave address
+#define MPU6050_I2C_SLV3_ADDR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV3_REG
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV3_REG_M 0xFF // Slave register number
+#define MPU6050_I2C_SLV3_REG_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV3_CTRL
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV3_CTRL_EN \
+ 0x80 // Enable slave
+#define MPU6050_I2C_SLV3_CTRL_BYTE_SW \
+ 0x40 // Byte-swap word pairs
+#define MPU6050_I2C_SLV3_CTRL_REG_DIS \
+ 0x20 // Disable register number transfer
+#define MPU6050_I2C_SLV3_CTRL_GRP \
+ 0x10 // Word pair grouping
+#define MPU6050_I2C_SLV3_CTRL_LEN_M \
+ 0x0F // Number of bytes to transfer
+#define MPU6050_I2C_SLV3_CTRL_LEN_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV4_ADDR
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV4_ADDR_RW \
+ 0x80 // Read/not write
+#define MPU6050_I2C_SLV4_ADDR_M 0x7F // Slave address
+#define MPU6050_I2C_SLV4_ADDR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV4_REG
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV4_REG_M 0xFF // Slave register number
+#define MPU6050_I2C_SLV4_REG_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV4_CTRL
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV4_CTRL_EN \
+ 0x80 // Enable slave
+#define MPU6050_I2C_SLV4_CTRL_INT_EN \
+ 0x40 // Interrupt enable
+#define MPU6050_I2C_SLV4_CTRL_REG_DIS \
+ 0x20 // Disable register number transfer
+#define MPU6050_I2C_SLV4_CTRL_I2C_MST_DLY_M \
+ 0x1F // Slave access delay
+#define MPU6050_I2C_SLV4_CTRL_I2C_MST_DLY_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV4_DI
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV4_DI_M 0xFF // Input data
+#define MPU6050_I2C_SLV4_DI_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_MST_STATUS
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_MST_STATUS_PASS_THROUGH \
+ 0x80 // Pass through FSYNC interrupt
+ // status
+#define MPU6050_I2C_MST_STATUS_I2C_SLV4_DONE \
+ 0x40 // I2C slave 4 completion status
+#define MPU6050_I2C_MST_STATUS_I2C_LOST_ARB \
+ 0x20 // I2C arbitration lost status
+#define MPU6050_I2C_MST_STATUS_I2C_SLV4_NACK \
+ 0x10 // I2C slave 4 NACK status
+#define MPU6050_I2C_MST_STATUS_I2C_SLV3_NACK \
+ 0x08 // I2C slave 3 NACK status
+#define MPU6050_I2C_MST_STATUS_I2C_SLV2_NACK \
+ 0x04 // I2C slave 2 NACK status
+#define MPU6050_I2C_MST_STATUS_I2C_SLV1_NACK \
+ 0x02 // I2C slave 1 NACK status
+#define MPU6050_I2C_MST_STATUS_I2C_SLV0_NACK \
+ 0x01 // I2C slave 0 NACK status
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_INT_PIN_CFG
+// register.
+//
+//*****************************************************************************
+#define MPU6050_INT_PIN_CFG_INT_LEVEL \
+ 0x80 // INT pin active low
+#define MPU6050_INT_PIN_CFG_INT_OPEN \
+ 0x40 // INT pin open-drain
+#define MPU6050_INT_PIN_CFG_LATCH_INT_EN \
+ 0x20 // Latch INT pin output
+#define MPU6050_INT_PIN_CFG_INT_RD_CLEAR \
+ 0x10 // Interrupt clear on any read
+#define MPU6050_INT_PIN_CFG_FSYNC_INT_LEVEL \
+ 0x08 // FSYNC pin active low
+#define MPU6050_INT_PIN_CFG_FSYNC_INT_EN \
+ 0x04 // FSYNC pin interrupt enable
+#define MPU6050_INT_PIN_CFG_I2C_BYPASS_EN \
+ 0x02 // I2C bypass enable
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_INT_ENABLE
+// register.
+//
+//*****************************************************************************
+#define MPU6050_INT_ENABLE_MOT_EN \
+ 0x40 // Motion detection interrupt
+ // enable
+#define MPU6050_INT_ENABLE_FIFO_OFLOW_EN \
+ 0x10 // FIFO overflow interrupt enable
+#define MPU6050_INT_ENABLE_I2C_MST_INT_EN \
+ 0x08 // I2C master interrupt enable
+#define MPU6050_INT_ENABLE_DATA_RDY_EN \
+ 0x01 // Data ready interrupt enable
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_INT_STATUS
+// register.
+//
+//*****************************************************************************
+#define MPU6050_INT_STATUS_MOT_INT \
+ 0x40 // Motion detection interrupt
+ // status
+#define MPU6050_INT_STATUS_FIFO_OFLOW_INT \
+ 0x10 // FIFO overflow interrupt status
+#define MPU6050_INT_STATUS_I2C_MST_INT \
+ 0x08 // I2C master interrupt status
+#define MPU6050_INT_STATUS_DATA_RDY_INT \
+ 0x01 // Data ready interrupt status
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_ACCEL_XOUT_H
+// register.
+//
+//*****************************************************************************
+#define MPU6050_ACCEL_XOUT_H_M 0xFF // Bits [15:8] of X-axis
+ // acceleration data
+#define MPU6050_ACCEL_XOUT_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_ACCEL_XOUT_L
+// register.
+//
+//*****************************************************************************
+#define MPU6050_ACCEL_XOUT_L_M 0xFF // Bits [7:0] of X-axis
+ // acceleration data
+#define MPU6050_ACCEL_XOUT_L_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_ACCEL_YOUT_H
+// register.
+//
+//*****************************************************************************
+#define MPU6050_ACCEL_YOUT_H_M 0xFF // Bits [15:8] of Y-axis
+ // acceleration data
+#define MPU6050_ACCEL_YOUT_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_ACCEL_YOUT_L
+// register.
+//
+//*****************************************************************************
+#define MPU6050_ACCEL_YOUT_L_M 0xFF // Bits [7:0] of Y-axis
+ // acceleration data
+#define MPU6050_ACCEL_YOUT_L_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_ACCEL_ZOUT_H
+// register.
+//
+//*****************************************************************************
+#define MPU6050_ACCEL_ZOUT_H_M 0xFF // Bits [15:8] of Z-axis
+ // acceleration data
+#define MPU6050_ACCEL_ZOUT_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_ACCEL_ZOUT_L
+// register.
+//
+//*****************************************************************************
+#define MPU6050_ACCEL_ZOUT_L_M 0xFF // Bits [7:0] of Z-axis
+ // acceleration data
+#define MPU6050_ACCEL_ZOUT_L_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_TEMP_OUT_H
+// register.
+//
+//*****************************************************************************
+#define MPU6050_ACCEL_TEMP_OUT_H_M \
+ 0xFF // Bits [15:8] of temperature data
+#define MPU6050_ACCEL_TEMP_OUT_H_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_TEMP_OUT_L
+// register.
+//
+//*****************************************************************************
+#define MPU6050_ACCEL_TEMP_OUT_L_M \
+ 0xFF // Bits [7:0] of temperature data
+#define MPU6050_ACCEL_TEMP_OUT_L_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_GYRO_XOUT_H
+// register.
+//
+//*****************************************************************************
+#define MPU6050_GYRO_XOUT_H_M 0xFF // Bits [15:8] of X-axis gyro data
+#define MPU6050_GYRO_XOUT_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_GYRO_XOUT_L
+// register.
+//
+//*****************************************************************************
+#define MPU6050_GYRO_XOUT_L_M 0xFF // Bits [7:0] of X-axis gyro data
+#define MPU6050_GYRO_XOUT_L_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_GYRO_YOUT_H
+// register.
+//
+//*****************************************************************************
+#define MPU6050_GYRO_YOUT_H_M 0xFF // Bits [15:8] of Y-axis gyro data
+#define MPU6050_GYRO_YOUT_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_GYRO_YOUT_L
+// register.
+//
+//*****************************************************************************
+#define MPU6050_GYRO_YOUT_L_M 0xFF // Bits [7:0] of Y-axis gyro data
+#define MPU6050_GYRO_YOUT_L_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_GYRO_ZOUT_H
+// register.
+//
+//*****************************************************************************
+#define MPU6050_GYRO_ZOUT_H_M 0xFF // Bits [15:8] of Z-axis gyro data
+#define MPU6050_GYRO_ZOUT_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_GYRO_ZOUT_L
+// register.
+//
+//*****************************************************************************
+#define MPU6050_GYRO_ZOUT_L_M 0xFF // Bits [7:0] of Z-axis gyro data
+#define MPU6050_GYRO_ZOUT_L_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_00 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_00_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_00_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_01 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_01_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_01_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_02 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_02_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_02_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_03 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_03_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_03_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_04 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_04_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_04_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_05 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_05_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_05_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_06 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_06_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_06_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_07 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_07_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_07_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_08 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_08_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_08_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_09 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_09_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_09_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_10 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_10_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_10_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_11 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_11_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_11_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_12 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_12_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_12_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_13 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_13_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_13_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_14 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_14_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_14_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_15 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_15_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_15_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_16 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_16_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_16_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_17 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_17_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_17_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_18 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_18_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_18_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_19 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_19_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_19_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_20 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_20_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_20_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_21 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_21_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_21_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_22 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_22_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_22_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_EXT_SENS_DATA_23 register.
+//
+//*****************************************************************************
+#define MPU6050_EXT_SENS_DATA_23_M \
+ 0xFF // External sensor data
+#define MPU6050_EXT_SENS_DATA_23_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV0_DO
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV0_DO_M 0xFF // Output data
+#define MPU6050_I2C_SLV0_DO_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV1_DO
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV1_DO_M 0xFF // Output data
+#define MPU6050_I2C_SLV1_DO_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV2_DO
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV2_DO_M 0xFF // Output data
+#define MPU6050_I2C_SLV2_DO_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_I2C_SLV3_DO
+// register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_SLV3_DO_M 0xFF // Output data
+#define MPU6050_I2C_SLV3_DO_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_I2C_MST_DELAY_CTRL register.
+//
+//*****************************************************************************
+#define MPU6050_I2C_MST_DELAY_CTRL_DELAY_ES_SHADOW \
+ 0x80 // Delay external sensor data
+#define MPU6050_I2C_MST_DELAY_CTRL_I2C_SLV4_DLY_EN \
+ 0x10 // I2C slave 4 delay enable
+#define MPU6050_I2C_MST_DELAY_CTRL_I2C_SLV3_DLY_EN \
+ 0x08 // I2C slave 3 delay enable
+#define MPU6050_I2C_MST_DELAY_CTRL_I2C_SLV2_DLY_EN \
+ 0x04 // I2C slave 2 delay enable
+#define MPU6050_I2C_MST_DELAY_CTRL_I2C_SLV1_DLY_EN \
+ 0x02 // I2C slave 1 delay enable
+#define MPU6050_I2C_MST_DELAY_CTRL_I2C_SLV0_DLY_EN \
+ 0x01 // I2C slave 0 delay enable
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_SIGNAL_PATH_RESET register.
+//
+//*****************************************************************************
+#define MPU6050_SIGNAL_PATH_RESET_GYRO \
+ 0x04 // Reset gyro
+#define MPU6050_SIGNAL_PATH_RESET_ACCEL \
+ 0x02 // Reset accelerometer
+#define MPU6050_SIGNAL_PATH_RESET_TEMP \
+ 0x01 // Reset temperature sensor
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU6050_O_MOT_DETECT_CTRL register.
+//
+//*****************************************************************************
+#define MPU6050_MOT_DETECT_CTRL_ACCEL_ON_DELAY_M \
+ 0x30 // Accelerometer wake-up delay
+#define MPU6050_MOT_DETECT_CTRL_ACCEL_ON_DELAY_4MS \
+ 0x00 // Delay 4 ms
+#define MPU6050_MOT_DETECT_CTRL_ACCEL_ON_DELAY_5MS \
+ 0x10 // Delay 5 ms
+#define MPU6050_MOT_DETECT_CTRL_ACCEL_ON_DELAY_6MS \
+ 0x20 // Delay 6 ms
+#define MPU6050_MOT_DETECT_CTRL_ACCEL_ON_DELAY_7MS \
+ 0x30 // Delay 7 ms
+#define MPU6050_MOT_DETECT_CTRL_ACCEL_ON_DELAY_S \
+ 4
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_USER_CTRL
+// register.
+//
+//*****************************************************************************
+#define MPU6050_USER_CTRL_FIFO_EN \
+ 0x40 // FIFO enable
+#define MPU6050_USER_CTRL_I2C_MST_EN \
+ 0x20 // I2C master mode enable
+#define MPU6050_USER_CTRL_I2C_IF_DIS \
+ 0x10 // Write as zero
+#define MPU6050_USER_CTRL_FIFO_RESET \
+ 0x04 // Reset FIFO buffer
+#define MPU6050_USER_CTRL_I2C_MST_RESET \
+ 0x02 // Reset I2C master
+#define MPU6050_USER_CTRL_SIG_COND_RESET \
+ 0x01 // Reset all sensors
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_PWR_MGMT_1
+// register.
+//
+//*****************************************************************************
+#define MPU6050_PWR_MGMT_1_DEVICE_RESET \
+ 0x80 // Device reset
+#define MPU6050_PWR_MGMT_1_SLEEP \
+ 0x40 // Enter sleep mode
+#define MPU6050_PWR_MGMT_1_CYCLE \
+ 0x20 // Enable automatic sleep
+#define MPU6050_PWR_MGMT_1_TEMP_DIS \
+ 0x08 // Disable temperature sensor
+#define MPU6050_PWR_MGMT_1_CLKSEL_M \
+ 0x07 // Clock source select
+#define MPU6050_PWR_MGMT_1_CLKSEL_INT \
+ 0x00 // Internal 8 MHz oscillator
+#define MPU6050_PWR_MGMT_1_CLKSEL_XG \
+ 0x01 // PLL with X-axis gyro reference
+#define MPU6050_PWR_MGMT_1_CLKSEL_YG \
+ 0x02 // PLL with Y-axis gyro reference
+#define MPU6050_PWR_MGMT_1_CLKSEL_ZG \
+ 0x03 // PLL with Z-axis gyro reference
+#define MPU6050_PWR_MGMT_1_CLKSEL_EXT32K \
+ 0x04 // PLL with external 32.768 kHz
+ // reference
+#define MPU6050_PWR_MGMT_1_CLKSEL_EXT19M \
+ 0x05 // PLL with external 19.2 MHz
+ // reference
+#define MPU6050_PWR_MGMT_1_CLKSEL_STOP \
+ 0x07 // Clock disable
+#define MPU6050_PWR_MGMT_1_CLKSEL_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_PWR_MGMT_2
+// register.
+//
+//*****************************************************************************
+#define MPU6050_PWR_MGMT_2_LP_WAKE_CTRL_M \
+ 0xC0 // Wake-up frequency
+#define MPU6050_PWR_MGMT_2_LP_WAKE_CTRL_1_25 \
+ 0x00 // Wake-up at 1.25 Hz
+#define MPU6050_PWR_MGMT_2_LP_WAKE_CTRL_5 \
+ 0x40 // Wake-up at 5 Hz
+#define MPU6050_PWR_MGMT_2_LP_WAKE_CTRL_20 \
+ 0x80 // Wake-up at 20 Hz
+#define MPU6050_PWR_MGMT_2_LP_WAKE_CTRL_40 \
+ 0xC0 // Wake-up at 40 Hz
+#define MPU6050_PWR_MGMT_2_STBY_XA \
+ 0x20 // Put X-axis accelerometer into
+ // standby mode
+#define MPU6050_PWR_MGMT_2_STBY_YA \
+ 0x10 // Put Y-axis accelerometer into
+ // standby mode
+#define MPU6050_PWR_MGMT_2_STBY_ZA \
+ 0x08 // Put Z-axis accelerometer into
+ // standby mode
+#define MPU6050_PWR_MGMT_2_STBY_XG \
+ 0x04 // Put X-axis gyro into standby
+ // mode
+#define MPU6050_PWR_MGMT_2_STBY_YG \
+ 0x02 // Put Y-axis gyro into standby
+ // mode
+#define MPU6050_PWR_MGMT_2_STBY_ZG \
+ 0x01 // Put Z-axis gyro into standby
+ // mode
+#define MPU6050_PWR_MGMT_2_LP_WAKE_CTRL_S \
+ 6
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_FIFO_COUNTH
+// register.
+//
+//*****************************************************************************
+#define MPU6050_FIFO_COUNTH_M 0xFF // FIFO count [15:8]
+#define MPU6050_FIFO_COUNTH_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_FIFO_COUNTL
+// register.
+//
+//*****************************************************************************
+#define MPU6050_FIFO_COUNTL_M 0xFF // FIFO count [7:0]
+#define MPU6050_FIFO_COUNTL_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_FIFO_R_W
+// register.
+//
+//*****************************************************************************
+#define MPU6050_FIFO_R_W_M 0xFF // FIFO data
+#define MPU6050_FIFO_R_W_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU6050_O_WHO_AM_I
+// register.
+//
+//*****************************************************************************
+#define MPU6050_WHO_AM_I_M 0x7E // I2C address
+#define MPU6050_WHO_AM_I_MPU6050 \
+ 0x68 // MPU6050
+#define MPU6050_WHO_AM_I_S 1
+
+#endif // __SENSORLIB_HW_MPU6050_H__
diff --git a/sensorlib/hw_mpu9150.h b/sensorlib/hw_mpu9150.h new file mode 100644 index 0000000..b586d1b --- /dev/null +++ b/sensorlib/hw_mpu9150.h @@ -0,0 +1,1454 @@ +//*****************************************************************************
+//
+// hw_mpu9150.h - Macros used when accessing the Invensense MPU9150
+// accelerometer/gyroscope/magnetometer.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_HW_MPU9150_H__
+#define __SENSORLIB_HW_MPU9150_H__
+
+//*****************************************************************************
+//
+// The following are defines for the MPU9150 register addresses.
+//
+//*****************************************************************************
+#define MPU9150_O_SELF_TEST_X 0x0D // Self test X register
+#define MPU9150_O_SELF_TEST_Y 0x0E // Self test Y register
+#define MPU9150_O_SELF_TEST_Z 0x0F // Self test Z register
+#define MPU9150_O_SELF_TEST_A 0x10 // Self test A register
+#define MPU9150_O_SMPLRT_DIV 0x19 // Sample rate divider register
+#define MPU9150_O_CONFIG 0x1A // Configuration register
+#define MPU9150_O_GYRO_CONFIG 0x1B // Gyro configuration register
+#define MPU9150_O_ACCEL_CONFIG 0x1C // Accelerometer configuration
+ // register
+#define MPU9150_O_FF_THR 0x1D // Free-fall threshold register
+#define MPU9150_O_FF_DUR 0x1E // Free-fall duration register
+#define MPU9150_O_MOT_THR 0x1F // Motion detection threshold
+ // register
+#define MPU9150_O_MOT_DUR 0x20 // Motion detection duration
+ // register
+#define MPU9150_O_ZRMOT_THR 0x21 // Zero motion detection threshold
+ // register
+#define MPU9150_O_ZRMOT_DUR 0x22 // Zero motion detection duration
+ // register
+#define MPU9150_O_FIFO_EN 0x23 // FIFO enable register
+#define MPU9150_O_I2C_MST_CTRL 0x24 // I2C master control register
+#define MPU9150_O_I2C_SLV0_ADDR 0x25 // I2C slave 0 address register
+#define MPU9150_O_I2C_SLV0_REG 0x26 // I2C slave 0 register number
+ // register
+#define MPU9150_O_I2C_SLV0_CTRL 0x27 // I2C slave 0 control register
+#define MPU9150_O_I2C_SLV1_ADDR 0x28 // I2C slave 1 address register
+#define MPU9150_O_I2C_SLV1_REG 0x29 // I2C slave 1 register number
+ // register
+#define MPU9150_O_I2C_SLV1_CTRL 0x2A // I2C slave 1 control register
+#define MPU9150_O_I2C_SLV2_ADDR 0x2B // I2C slave 2 address register
+#define MPU9150_O_I2C_SLV2_REG 0x2C // I2C slave 2 register number
+ // register
+#define MPU9150_O_I2C_SLV2_CTRL 0x2D // I2C slave 2 control register
+#define MPU9150_O_I2C_SLV3_ADDR 0x2E // I2C slave 3 address register
+#define MPU9150_O_I2C_SLV3_REG 0x2F // I2C slave 3 register number
+ // register
+#define MPU9150_O_I2C_SLV3_CTRL 0x30 // I2C slave 3 control register
+#define MPU9150_O_I2C_SLV4_ADDR 0x31 // I2C slave 4 address register
+#define MPU9150_O_I2C_SLV4_REG 0x32 // I2C slave 4 register number
+ // register
+#define MPU9150_O_I2C_SLV4_DO 0x33 // I2C slave 4 output data register
+#define MPU9150_O_I2C_SLV4_CTRL 0x34 // I2C slave 4 control register
+#define MPU9150_O_I2C_SLV4_DI 0x35 // I2C slave 4 input data register
+#define MPU9150_O_I2C_MST_STATUS \
+ 0x36 // I2C master status register
+#define MPU9150_O_INT_PIN_CFG 0x37 // INT pin configuration register
+#define MPU9150_O_INT_ENABLE 0x38 // Interrupt enable register
+#define MPU9150_O_INT_STATUS 0x3A // Interrupt status register
+#define MPU9150_O_ACCEL_XOUT_H 0x3B // X-axis acceleration data MSB
+ // register
+#define MPU9150_O_ACCEL_XOUT_L 0x3C // X-axis acceleration data LSB
+ // register
+#define MPU9150_O_ACCEL_YOUT_H 0x3D // Y-axis acceleration data MSB
+ // register
+#define MPU9150_O_ACCEL_YOUT_L 0x3E // Y-axis accelearation data LSB
+ // register
+#define MPU9150_O_ACCEL_ZOUT_H 0x3F // Z-axis acceleration data MSB
+ // register
+#define MPU9150_O_ACCEL_ZOUT_L 0x40 // Z-axis acceleration data LSB
+ // register
+#define MPU9150_O_TEMP_OUT_H 0x41 // Temperature data MSB register
+#define MPU9150_O_TEMP_OUT_L 0x42 // Temperature data LSB register
+#define MPU9150_O_GYRO_XOUT_H 0x43 // X-axis gyro data MSB register
+#define MPU9150_O_GYRO_XOUT_L 0x44 // X-axis gyro data LSB register
+#define MPU9150_O_GYRO_YOUT_H 0x45 // Y-axis gyro data MSB register
+#define MPU9150_O_GYRO_YOUT_L 0x46 // Y-axis gyro data LSB register
+#define MPU9150_O_GYRO_ZOUT_H 0x47 // Z-axis gyro data MSB register
+#define MPU9150_O_GYRO_ZOUT_L 0x48 // Z-axis gyro data LSB register
+#define MPU9150_O_EXT_SENS_DATA_00 \
+ 0x49 // External sensor data 0 register
+#define MPU9150_O_EXT_SENS_DATA_01 \
+ 0x4A // External sensor data 1 register
+#define MPU9150_O_EXT_SENS_DATA_02 \
+ 0x4B // External sensor data 2 register
+#define MPU9150_O_EXT_SENS_DATA_03 \
+ 0x4C // External sensor data 3 register
+#define MPU9150_O_EXT_SENS_DATA_04 \
+ 0x4D // External sensor data 4 register
+#define MPU9150_O_EXT_SENS_DATA_05 \
+ 0x4E // External sensor data 5 register
+#define MPU9150_O_EXT_SENS_DATA_06 \
+ 0x4F // External sensor data 6 register
+#define MPU9150_O_EXT_SENS_DATA_07 \
+ 0x50 // External sensor data 7 register
+#define MPU9150_O_EXT_SENS_DATA_08 \
+ 0x51 // External sensor data 8 register
+#define MPU9150_O_EXT_SENS_DATA_09 \
+ 0x52 // External sensor data 9 register
+#define MPU9150_O_EXT_SENS_DATA_10 \
+ 0x53 // External sensor data 10 register
+#define MPU9150_O_EXT_SENS_DATA_11 \
+ 0x54 // External sensor data 11 register
+#define MPU9150_O_EXT_SENS_DATA_12 \
+ 0x55 // External sensor data 12 register
+#define MPU9150_O_EXT_SENS_DATA_13 \
+ 0x56 // External sensor data 13 register
+#define MPU9150_O_EXT_SENS_DATA_14 \
+ 0x57 // External sensor data 14 register
+#define MPU9150_O_EXT_SENS_DATA_15 \
+ 0x58 // External sensor data 15 register
+#define MPU9150_O_EXT_SENS_DATA_16 \
+ 0x59 // External sensor data 16 register
+#define MPU9150_O_EXT_SENS_DATA_17 \
+ 0x5A // External sensor data 17 register
+#define MPU9150_O_EXT_SENS_DATA_18 \
+ 0x5B // External sensor data 18 register
+#define MPU9150_O_EXT_SENS_DATA_19 \
+ 0x5C // External sensor data 19 register
+#define MPU9150_O_EXT_SENS_DATA_20 \
+ 0x5D // External sensor data 20 register
+#define MPU9150_O_EXT_SENS_DATA_21 \
+ 0x5E // External sensor data 21 register
+#define MPU9150_O_EXT_SENS_DATA_22 \
+ 0x5F // External sensor data 22 register
+#define MPU9150_O_EXT_SENS_DATA_23 \
+ 0x60 // External sensor data 23 register
+#define MPU9150_O_MOT_DETECT_STATUS \
+ 0x61 // Motion detection status register
+#define MPU9150_O_I2C_SLV0_DO 0x63 // I2C slave 0 output data register
+#define MPU9150_O_I2C_SLV1_DO 0x64 // I2C slave 1 output data register
+#define MPU9150_O_I2C_SLV2_DO 0x65 // I2C slave 2 output data register
+#define MPU9150_O_I2C_SLV3_DO 0x66 // I2C slave 3 output data register
+#define MPU9150_O_I2C_MST_DELAY_CTRL \
+ 0x67 // I2C master delay control
+ // register
+#define MPU9150_O_SIGNAL_PATH_RESET \
+ 0x68 // Signal path reset register
+#define MPU9150_O_MOT_DETECT_CTRL \
+ 0x69 // Motion detection control
+ // register
+#define MPU9150_O_USER_CTRL 0x6A // User control register
+#define MPU9150_O_PWR_MGMT_1 0x6B // Power management 1 register
+#define MPU9150_O_PWR_MGMT_2 0x6C // Power management 2 register
+#define MPU9150_O_FIFO_COUNTH 0x72 // FIFO count MSB register
+#define MPU9150_O_FIFO_COUNTL 0x73 // FIFO count LSB register
+#define MPU9150_O_FIFO_R_W 0x74 // FIFO read write register
+#define MPU9150_O_WHO_AM_I 0x75 // Who am I register
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_SELF_TEST_X
+// register.
+//
+//*****************************************************************************
+#define MPU9150_SELF_TEST_X_XA_TEST_M \
+ 0xE0 // Accelerometer XA_TEST[4:2]
+#define MPU9150_SELF_TEST_X_XG_TEST_M \
+ 0x1F // Gyro XG_TEST[4:0]
+#define MPU9150_SELF_TEST_X_XA_TEST_S \
+ 5
+#define MPU9150_SELF_TEST_X_XG_TEST_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_SELF_TEST_Y
+// register.
+//
+//*****************************************************************************
+#define MPU9150_SELF_TEST_Y_YA_TEST_M \
+ 0xE0 // Accelerometer YA_TEST[4:2]
+#define MPU9150_SELF_TEST_Y_YG_TEST_M \
+ 0x1F // Gyro YG_TEST[4:0]
+#define MPU9150_SELF_TEST_Y_YA_TEST_S \
+ 5
+#define MPU9150_SELF_TEST_Y_YG_TEST_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_SELF_TEST_Z
+// register.
+//
+//*****************************************************************************
+#define MPU9150_SELF_TEST_Z_ZA_TEST_M \
+ 0xE0 // Accelerometer ZA_TEST[4:2]
+#define MPU9150_SELF_TEST_Z_ZG_TEST_M \
+ 0x1F // Gyro ZG_TEST[4:0]
+#define MPU9150_SELF_TEST_Z_ZA_TEST_S \
+ 5
+#define MPU9150_SELF_TEST_Z_ZG_TEST_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_SELF_TEST_A
+// register.
+//
+//*****************************************************************************
+#define MPU9150_SELF_TEST_A_XA_TEST_M \
+ 0x30 // Accelerometer XA_TEST[1:0]
+#define MPU9150_SELF_TEST_A_YA_TEST_M \
+ 0x0C // Accelerometer YA_TEST[1:0]
+#define MPU9150_SELF_TEST_A_ZA_TEST_M \
+ 0x03 // Accelerometer ZA_TEST[1:0]
+#define MPU9150_SELF_TEST_A_XA_TEST_S \
+ 4
+#define MPU9150_SELF_TEST_A_YA_TEST_S \
+ 2
+#define MPU9150_SELF_TEST_A_ZA_TEST_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_SMPLRT_DIV
+// register.
+//
+//*****************************************************************************
+#define MPU9150_SMPLRT_DIV_M 0xFF // Gyro output rate divider
+#define MPU9150_SMPLRT_DIV_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_CONFIG
+// register.
+//
+//*****************************************************************************
+#define MPU9150_CONFIG_EXT_SYNC_SET_M \
+ 0x38 // FSYNC pin sample location
+#define MPU9150_CONFIG_EXT_SYNC_SET_DIS \
+ 0x00 // FSYNC input disabled
+#define MPU9150_CONFIG_EXT_SYNC_SET_TEMP_OUT_L \
+ 0x08 // FSYNC on TEMP_OUT_L[0]
+#define MPU9150_CONFIG_EXT_SYNC_SET_GYRO_XOUT_L \
+ 0x10 // FSYNC on GYRO_XOUT_L[0]
+#define MPU9150_CONFIG_EXT_SYNC_SET_GYRO_YOUT_L \
+ 0x18 // FSYNC on GYRO_YOUT_L[0]
+#define MPU9150_CONFIG_EXT_SYNC_SET_GYRO_ZOUT_L \
+ 0x20 // FSYNC on GYRO_ZOUT_L[0]
+#define MPU9150_CONFIG_EXT_SYNC_SET_ACCEL_XOUT_L \
+ 0x28 // FSYNC on ACCEL_XOUT_L[0]
+#define MPU9150_CONFIG_EXT_SYNC_SET_ACCEL_YOUT_L \
+ 0x30 // FSYNC on ACCEL_YOUT_L[0]
+#define MPU9150_CONFIG_EXT_SYNC_SET_ACCEL_ZOUT_L \
+ 0x38 // FSYNC on ACCEL_ZOUT_L[0]
+#define MPU9150_CONFIG_DLPF_CFG_M \
+ 0x07 // Digital low-pass filter
+ // configuration
+#define MPU9150_CONFIG_DLPF_CFG_260_256 \
+ 0x00 // 260 Hz accelerometer bandwidth,
+ // 256 Hz gyro bandwidth
+#define MPU9150_CONFIG_DLPF_CFG_184_188 \
+ 0x01 // 184 Hz accelerometer bandwidth,
+ // 188 Hz gyro bandwidth
+#define MPU9150_CONFIG_DLPF_CFG_94_98 \
+ 0x02 // 94 Hz accelerometer bandwidth,
+ // 98 Hz gyro bandwidth
+#define MPU9150_CONFIG_DLPF_CFG_44_42 \
+ 0x03 // 44 Hz accelerometer bandwidth,
+ // 42 Hz gyro bandwidth
+#define MPU9150_CONFIG_DLPF_CFG_21_20 \
+ 0x04 // 21 Hz accelerometer bandwidth,
+ // 20 Hz gyro bandwidth
+#define MPU9150_CONFIG_DLPF_CFG_10_10 \
+ 0x05 // 10 Hz accelerometer bandwidth,
+ // 10 Hz gyro bandwidth
+#define MPU9150_CONFIG_DLPF_CFG_5_5 \
+ 0x06 // 5 Hz accelerometer bandwidth, 5
+ // Hz gyro bandwidth
+#define MPU9150_CONFIG_EXT_SYNC_SET_S \
+ 3
+#define MPU9150_CONFIG_DLPF_CFG_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_GYRO_CONFIG
+// register.
+//
+//*****************************************************************************
+#define MPU9150_GYRO_CONFIG_XG_ST \
+ 0x80 // X-axis gyro self-test enable
+#define MPU9150_GYRO_CONFIG_YG_ST \
+ 0x40 // Y-axis gyro self-test enable
+#define MPU9150_GYRO_CONFIG_ZG_ST \
+ 0x20 // Z-axis gyro self-test enable
+#define MPU9150_GYRO_CONFIG_FS_SEL_M \
+ 0x18 // Gyro full-scale range
+#define MPU9150_GYRO_CONFIG_FS_SEL_250 \
+ 0x00 // Gyro full-scale range +/- 250
+ // degrees/sec
+#define MPU9150_GYRO_CONFIG_FS_SEL_500 \
+ 0x08 // Gyro full-scale range +/- 500
+ // degrees/sec
+#define MPU9150_GYRO_CONFIG_FS_SEL_1000 \
+ 0x10 // Gyro full-scale range +/- 1000
+ // degrees/sec
+#define MPU9150_GYRO_CONFIG_FS_SEL_2000 \
+ 0x18 // Gyro full-scale range +/- 2000
+ // degrees/sec
+#define MPU9150_GYRO_CONFIG_FS_SEL_S \
+ 3
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_ACCEL_CONFIG
+// register.
+//
+//*****************************************************************************
+#define MPU9150_ACCEL_CONFIG_XA_ST \
+ 0x80 // X-axis accelerometer self-test
+ // enable
+#define MPU9150_ACCEL_CONFIG_YA_ST \
+ 0x40 // Y-axis accelerometer self-test
+ // enable
+#define MPU9150_ACCEL_CONFIG_ZA_ST \
+ 0x20 // Z-axis accelerometer self-test
+ // enable
+#define MPU9150_ACCEL_CONFIG_AFS_SEL_M \
+ 0x18 // Accelerometer full-scale range
+#define MPU9150_ACCEL_CONFIG_AFS_SEL_2G \
+ 0x00 // Accelerometer full-scale range 2
+ // g
+#define MPU9150_ACCEL_CONFIG_AFS_SEL_4G \
+ 0x08 // Accelerometer full-scale range 4
+ // g
+#define MPU9150_ACCEL_CONFIG_AFS_SEL_8G \
+ 0x10 // Accelerometer full-scale range 8
+ // g
+#define MPU9150_ACCEL_CONFIG_AFS_SEL_16G \
+ 0x18 // Accelerometer full-scale range
+ // 16 g
+#define MPU9150_ACCEL_CONFIG_ACCEL_HPF_M \
+ 0x07 // High-pass filter setting
+#define MPU9150_ACCEL_CONFIG_ACCEL_HPF_RESET \
+ 0x00 // High-pass filter reset
+#define MPU9150_ACCEL_CONFIG_ACCEL_HPF_5HZ \
+ 0x01 // High-pass filter at 5 Hz
+#define MPU9150_ACCEL_CONFIG_ACCEL_HPF_2_5HZ \
+ 0x02 // High-pass filter at 2.5 Hz
+#define MPU9150_ACCEL_CONFIG_ACCEL_HPF_1_25HZ \
+ 0x03 // High-pass filter at 1.25 Hz
+#define MPU9150_ACCEL_CONFIG_ACCEL_HPF_0_63HZ \
+ 0x04 // High-pass filter at 0.63 Hz
+#define MPU9150_ACCEL_CONFIG_ACCEL_HPF_HOLD \
+ 0x07 // High-pass filter hold
+#define MPU9150_ACCEL_CONFIG_AFS_SEL_S \
+ 3
+#define MPU9150_ACCEL_CONFIG_ACCEL_HPF_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_FF_THR
+// register.
+//
+//*****************************************************************************
+#define MPU9150_FF_THR_M 0xFF // Free-fall threshold value
+#define MPU9150_FF_THR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_FF_DUR
+// register.
+//
+//*****************************************************************************
+#define MPU9150_FF_DUR_M 0xFF // Free-fall duration value
+#define MPU9150_FF_DUR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_MOT_THR
+// register.
+//
+//*****************************************************************************
+#define MPU9150_MOT_THR_M 0xFF // Motion detection threshold value
+#define MPU9150_MOT_THR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_MOT_DUR
+// register.
+//
+//*****************************************************************************
+#define MPU9150_MOT_DUR_M 0xFF // Motion detection duration value
+#define MPU9150_MOT_DUR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_ZRMOT_THR
+// register.
+//
+//*****************************************************************************
+#define MPU9150_ZRMOT_THR_M 0xFF // Zero motion detection threshold
+ // value
+#define MPU9150_ZRMOT_THR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_ZRMOT_DUR
+// register.
+//
+//*****************************************************************************
+#define MPU9150_ZRMOT_DUR_M 0xFF // Zero motion detection duration
+ // value
+#define MPU9150_ZRMOT_DUR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_FIFO_EN
+// register.
+//
+//*****************************************************************************
+#define MPU9150_FIFO_EN_TEMP 0x80 // Temperature sensor FIFO enable
+#define MPU9150_FIFO_EN_XG 0x40 // X-axis gyro FIFO enable
+#define MPU9150_FIFO_EN_YG 0x20 // Y-axis gyro FIFO enable
+#define MPU9150_FIFO_EN_ZG 0x10 // Z-axis gyro FIFO enable
+#define MPU9150_FIFO_EN_ACCEL 0x08 // Accelerometer FIFO enable
+#define MPU9150_FIFO_EN_SLV2 0x04 // Slave 2 FIFO enable
+#define MPU9150_FIFO_EN_SLV1 0x02 // Slave 1 FIFO enable
+#define MPU9150_FIFO_EN_SLV0 0x01 // Slave 0 FIFO enable
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_MST_CTRL
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_MST_CTRL_MULT_MST_EN \
+ 0x80 // Multi-master enable
+#define MPU9150_I2C_MST_CTRL_WAIT_FOR_ES \
+ 0x40 // Wait for external sensor data
+#define MPU9150_I2C_MST_CTRL_SLV3_FIFO_EN \
+ 0x20 // Slave 3 FIFO enable
+#define MPU9150_I2C_MST_CTRL_I2C_MST_P_NSR \
+ 0x10 // No repeated start conditions
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_M \
+ 0x0F // I2C master clock speed
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_348 \
+ 0x00 // 348 kHz I2C master clock
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_333 \
+ 0x01 // 333 kHz I2C master clock
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_320 \
+ 0x02 // 320 kHz I2C master clock
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_308 \
+ 0x03 // 308 kHz I2C master clock
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_296 \
+ 0x04 // 296 kHz I2C master clock
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_286 \
+ 0x05 // 286 kHz I2C master clock
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_276 \
+ 0x06 // 276 kHz I2C master clock
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_267 \
+ 0x07 // 267 kHz I2C master clock
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_258 \
+ 0x08 // 258 kHz I2C master clock
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_500 \
+ 0x09 // 500 kHz I2C master clock
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_471 \
+ 0x0A // 471 kHz I2C master clock
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_444 \
+ 0x0B // 444 kHz I2C master clock
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_421 \
+ 0x0C // 421 kHz I2C master clock
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_400 \
+ 0x0D // 400 kHz I2C master clock
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_381 \
+ 0x0E // 381 kHz I2C master clock
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_364 \
+ 0x0F // 364 kHz I2C master clock
+#define MPU9150_I2C_MST_CTRL_I2C_MST_CLK_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV0_ADDR
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV0_ADDR_RW \
+ 0x80 // Read/not write
+#define MPU9150_I2C_SLV0_ADDR_M 0x7F // Slave address
+#define MPU9150_I2C_SLV0_ADDR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV0_REG
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV0_REG_M 0xFF // Slave register number
+#define MPU9150_I2C_SLV0_REG_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV0_CTRL
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV0_CTRL_EN \
+ 0x80 // Enable slave
+#define MPU9150_I2C_SLV0_CTRL_BYTE_SW \
+ 0x40 // Byte-swap word pairs
+#define MPU9150_I2C_SLV0_CTRL_REG_DIS \
+ 0x20 // Disable register number transfer
+#define MPU9150_I2C_SLV0_CTRL_GRP \
+ 0x10 // Word pair grouping
+#define MPU9150_I2C_SLV0_CTRL_LEN_M \
+ 0x0F // Number of bytes to transfer
+#define MPU9150_I2C_SLV0_CTRL_LEN_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV1_ADDR
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV1_ADDR_RW \
+ 0x80 // Read/not write
+#define MPU9150_I2C_SLV1_ADDR_M 0x7F // Slave address
+#define MPU9150_I2C_SLV1_ADDR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV1_REG
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV1_REG_M 0xFF // Slave register number
+#define MPU9150_I2C_SLV1_REG_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV1_CTRL
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV1_CTRL_EN \
+ 0x80 // Enable slave
+#define MPU9150_I2C_SLV1_CTRL_BYTE_SW \
+ 0x40 // Byte-swap word pairs
+#define MPU9150_I2C_SLV1_CTRL_REG_DIS \
+ 0x20 // Disable register number transfer
+#define MPU9150_I2C_SLV1_CTRL_GRP \
+ 0x10 // Word pair grouping
+#define MPU9150_I2C_SLV1_CTRL_LEN_M \
+ 0x0F // Number of bytes to transfer
+#define MPU9150_I2C_SLV1_CTRL_LEN_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV2_ADDR
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV2_ADDR_RW \
+ 0x80 // Read/not write
+#define MPU9150_I2C_SLV2_ADDR_M 0x7F // Slave address
+#define MPU9150_I2C_SLV2_ADDR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV2_REG
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV2_REG_M 0xFF // Slave register number
+#define MPU9150_I2C_SLV2_REG_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV2_CTRL
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV2_CTRL_EN \
+ 0x80 // Enable slave
+#define MPU9150_I2C_SLV2_CTRL_BYTE_SW \
+ 0x40 // Byte-swap word pairs
+#define MPU9150_I2C_SLV2_CTRL_REG_DIS \
+ 0x20 // Disable register number transfer
+#define MPU9150_I2C_SLV2_CTRL_GRP \
+ 0x10 // Word pair grouping
+#define MPU9150_I2C_SLV2_CTRL_LEN_M \
+ 0x0F // Number of bytes to transfer
+#define MPU9150_I2C_SLV2_CTRL_LEN_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV3_ADDR
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV3_ADDR_RW \
+ 0x80 // Read/not write
+#define MPU9150_I2C_SLV3_ADDR_M 0x7F // Slave address
+#define MPU9150_I2C_SLV3_ADDR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV3_REG
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV3_REG_M 0xFF // Slave register number
+#define MPU9150_I2C_SLV3_REG_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV3_CTRL
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV3_CTRL_EN \
+ 0x80 // Enable slave
+#define MPU9150_I2C_SLV3_CTRL_BYTE_SW \
+ 0x40 // Byte-swap word pairs
+#define MPU9150_I2C_SLV3_CTRL_REG_DIS \
+ 0x20 // Disable register number transfer
+#define MPU9150_I2C_SLV3_CTRL_GRP \
+ 0x10 // Word pair grouping
+#define MPU9150_I2C_SLV3_CTRL_LEN_M \
+ 0x0F // Number of bytes to transfer
+#define MPU9150_I2C_SLV3_CTRL_LEN_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV4_ADDR
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV4_ADDR_RW \
+ 0x80 // Read/not write
+#define MPU9150_I2C_SLV4_ADDR_M 0x7F // Slave address
+#define MPU9150_I2C_SLV4_ADDR_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV4_REG
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV4_REG_M 0xFF // Slave register number
+#define MPU9150_I2C_SLV4_REG_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV4_CTRL
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV4_CTRL_EN \
+ 0x80 // Enable slave
+#define MPU9150_I2C_SLV4_CTRL_INT_EN \
+ 0x40 // Interrupt enable
+#define MPU9150_I2C_SLV4_CTRL_REG_DIS \
+ 0x20 // Disable register number transfer
+#define MPU9150_I2C_SLV4_CTRL_I2C_MST_DLY_M \
+ 0x1F // Slave access delay
+#define MPU9150_I2C_SLV4_CTRL_I2C_MST_DLY_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV4_DI
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV4_DI_M 0xFF // Input data
+#define MPU9150_I2C_SLV4_DI_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_MST_STATUS
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_MST_STATUS_PASS_THROUGH \
+ 0x80 // Pass through FSYNC interrupt
+ // status
+#define MPU9150_I2C_MST_STATUS_I2C_SLV4_DONE \
+ 0x40 // I2C slave 4 completion status
+#define MPU9150_I2C_MST_STATUS_I2C_LOST_ARB \
+ 0x20 // I2C arbitration lost status
+#define MPU9150_I2C_MST_STATUS_I2C_SLV4_NACK \
+ 0x10 // I2C slave 4 NACK status
+#define MPU9150_I2C_MST_STATUS_I2C_SLV3_NACK \
+ 0x08 // I2C slave 3 NACK status
+#define MPU9150_I2C_MST_STATUS_I2C_SLV2_NACK \
+ 0x04 // I2C slave 2 NACK status
+#define MPU9150_I2C_MST_STATUS_I2C_SLV1_NACK \
+ 0x02 // I2C slave 1 NACK status
+#define MPU9150_I2C_MST_STATUS_I2C_SLV0_NACK \
+ 0x01 // I2C slave 0 NACK status
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_INT_PIN_CFG
+// register.
+//
+//*****************************************************************************
+#define MPU9150_INT_PIN_CFG_INT_LEVEL \
+ 0x80 // INT pin active low
+#define MPU9150_INT_PIN_CFG_INT_OPEN \
+ 0x40 // INT pin open-drain
+#define MPU9150_INT_PIN_CFG_LATCH_INT_EN \
+ 0x20 // Latch INT pin output
+#define MPU9150_INT_PIN_CFG_INT_RD_CLEAR \
+ 0x10 // Interrupt clear on any read
+#define MPU9150_INT_PIN_CFG_FSYNC_INT_LEVEL \
+ 0x08 // FSYNC pin active low
+#define MPU9150_INT_PIN_CFG_FSYNC_INT_EN \
+ 0x04 // FSYNC pin interrupt enable
+#define MPU9150_INT_PIN_CFG_I2C_BYPASS_EN \
+ 0x02 // I2C bypass enable
+#define MPU9150_INT_PIN_CFG_CLKOUT_EN \
+ 0x01 // CLKOUT enable
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_INT_ENABLE
+// register.
+//
+//*****************************************************************************
+#define MPU9150_INT_ENABLE_FF_EN \
+ 0x80 // Free-fall interrupt enable
+#define MPU9150_INT_ENABLE_MOT_EN \
+ 0x40 // Motion detection interrupt
+ // enable
+#define MPU9150_INT_ENABLE_ZMOT_EN \
+ 0x20 // Zero motion interrupt enable
+#define MPU9150_INT_ENABLE_FIFO_OFLOW_EN \
+ 0x10 // FIFO overflow interrupt enable
+#define MPU9150_INT_ENABLE_I2C_MST_INT_EN \
+ 0x08 // I2C master interrupt enable
+#define MPU9150_INT_ENABLE_DATA_RDY_EN \
+ 0x01 // Data ready interrupt enable
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_INT_STATUS
+// register.
+//
+//*****************************************************************************
+#define MPU9150_INT_STATUS_FF_INT \
+ 0x80 // Free-fall interrupt status
+#define MPU9150_INT_STATUS_MOT_INT \
+ 0x40 // Motion detection interrupt
+ // status
+#define MPU9150_INT_STATUS_ZMOT_INT \
+ 0x20 // Zero motion interrupt status
+#define MPU9150_INT_STATUS_FIFO_OFLOW_INT \
+ 0x10 // FIFO overflow interrupt status
+#define MPU9150_INT_STATUS_I2C_MST_INT \
+ 0x08 // I2C master interrupt status
+#define MPU9150_INT_STATUS_DATA_RDY_INT \
+ 0x01 // Data ready interrupt status
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_ACCEL_XOUT_H
+// register.
+//
+//*****************************************************************************
+#define MPU9150_ACCEL_XOUT_H_M 0xFF // Bits [15:8] of X-axis
+ // acceleration data
+#define MPU9150_ACCEL_XOUT_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_ACCEL_XOUT_L
+// register.
+//
+//*****************************************************************************
+#define MPU9150_ACCEL_XOUT_L_M 0xFF // Bits [7:0] of X-axis
+ // acceleration data
+#define MPU9150_ACCEL_XOUT_L_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_ACCEL_YOUT_H
+// register.
+//
+//*****************************************************************************
+#define MPU9150_ACCEL_YOUT_H_M 0xFF // Bits [15:8] of Y-axis
+ // acceleration data
+#define MPU9150_ACCEL_YOUT_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_ACCEL_YOUT_L
+// register.
+//
+//*****************************************************************************
+#define MPU9150_ACCEL_YOUT_L_M 0xFF // Bits [7:0] of Y-axis
+ // acceleration data
+#define MPU9150_ACCEL_YOUT_L_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_ACCEL_ZOUT_H
+// register.
+//
+//*****************************************************************************
+#define MPU9150_ACCEL_ZOUT_H_M 0xFF // Bits [15:8] of Z-axis
+ // acceleration data
+#define MPU9150_ACCEL_ZOUT_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_ACCEL_ZOUT_L
+// register.
+//
+//*****************************************************************************
+#define MPU9150_ACCEL_ZOUT_L_M 0xFF // Bits [7:0] of Z-axis
+ // acceleration data
+#define MPU9150_ACCEL_ZOUT_L_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_TEMP_OUT_H
+// register.
+//
+//*****************************************************************************
+#define MPU9150_ACCEL_TEMP_OUT_H_M \
+ 0xFF // Bits [15:8] of temperature data
+#define MPU9150_ACCEL_TEMP_OUT_H_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_TEMP_OUT_L
+// register.
+//
+//*****************************************************************************
+#define MPU9150_ACCEL_TEMP_OUT_L_M \
+ 0xFF // Bits [7:0] of temperature data
+#define MPU9150_ACCEL_TEMP_OUT_L_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_GYRO_XOUT_H
+// register.
+//
+//*****************************************************************************
+#define MPU9150_GYRO_XOUT_H_M 0xFF // Bits [15:8] of X-axis gyro data
+#define MPU9150_GYRO_XOUT_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_GYRO_XOUT_L
+// register.
+//
+//*****************************************************************************
+#define MPU9150_GYRO_XOUT_L_M 0xFF // Bits [7:0] of X-axis gyro data
+#define MPU9150_GYRO_XOUT_L_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_GYRO_YOUT_H
+// register.
+//
+//*****************************************************************************
+#define MPU9150_GYRO_YOUT_H_M 0xFF // Bits [15:8] of Y-axis gyro data
+#define MPU9150_GYRO_YOUT_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_GYRO_YOUT_L
+// register.
+//
+//*****************************************************************************
+#define MPU9150_GYRO_YOUT_L_M 0xFF // Bits [7:0] of Y-axis gyro data
+#define MPU9150_GYRO_YOUT_L_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_GYRO_ZOUT_H
+// register.
+//
+//*****************************************************************************
+#define MPU9150_GYRO_ZOUT_H_M 0xFF // Bits [15:8] of Z-axis gyro data
+#define MPU9150_GYRO_ZOUT_H_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_GYRO_ZOUT_L
+// register.
+//
+//*****************************************************************************
+#define MPU9150_GYRO_ZOUT_L_M 0xFF // Bits [7:0] of Z-axis gyro data
+#define MPU9150_GYRO_ZOUT_L_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_00 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_00_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_00_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_01 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_01_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_01_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_02 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_02_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_02_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_03 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_03_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_03_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_04 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_04_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_04_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_05 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_05_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_05_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_06 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_06_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_06_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_07 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_07_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_07_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_08 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_08_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_08_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_09 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_09_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_09_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_10 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_10_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_10_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_11 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_11_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_11_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_12 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_12_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_12_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_13 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_13_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_13_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_14 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_14_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_14_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_15 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_15_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_15_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_16 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_16_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_16_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_17 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_17_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_17_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_18 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_18_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_18_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_19 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_19_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_19_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_20 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_20_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_20_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_21 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_21_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_21_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_22 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_22_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_22_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_EXT_SENS_DATA_23 register.
+//
+//*****************************************************************************
+#define MPU9150_EXT_SENS_DATA_23_M \
+ 0xFF // External sensor data
+#define MPU9150_EXT_SENS_DATA_23_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_MOT_DETECT_STATUS register.
+//
+//*****************************************************************************
+#define MPU9150_MOT_DETECT_STATUS_MOT_XNEG \
+ 0x80 // Negative X-axis motion detect
+ // status
+#define MPU9150_MOT_DETECT_STATUS_MOT_XPOS \
+ 0x40 // Positive X-axis motion detect
+ // status
+#define MPU9150_MOT_DETECT_STATUS_MOT_YNEG \
+ 0x20 // Negative Y-axis motion detect
+ // status
+#define MPU9150_MOT_DETECT_STATUS_MOT_YPOS \
+ 0x10 // Positive Y-axis motion detect
+ // status
+#define MPU9150_MOT_DETECT_STATUS_MOT_ZNEG \
+ 0x08 // Negative Z-axis motion detect
+ // status
+#define MPU9150_MOT_DETECT_STATUS_MOT_ZPOS \
+ 0x04 // Positive Z-axis motion detect
+ // status
+#define MPU9150_MOT_DETECT_STATUS_MOT_ZRMOT \
+ 0x01 // Zero motion detect status
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV0_DO
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV0_DO_M 0xFF // Output data
+#define MPU9150_I2C_SLV0_DO_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV1_DO
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV1_DO_M 0xFF // Output data
+#define MPU9150_I2C_SLV1_DO_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV2_DO
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV2_DO_M 0xFF // Output data
+#define MPU9150_I2C_SLV2_DO_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_I2C_SLV3_DO
+// register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_SLV3_DO_M 0xFF // Output data
+#define MPU9150_I2C_SLV3_DO_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_I2C_MST_DELAY_CTRL register.
+//
+//*****************************************************************************
+#define MPU9150_I2C_MST_DELAY_CTRL_DELAY_ES_SHADOW \
+ 0x80 // Delay external sensor data
+#define MPU9150_I2C_MST_DELAY_CTRL_I2C_SLV4_DLY_EN \
+ 0x10 // I2C slave 4 delay enable
+#define MPU9150_I2C_MST_DELAY_CTRL_I2C_SLV3_DLY_EN \
+ 0x08 // I2C slave 3 delay enable
+#define MPU9150_I2C_MST_DELAY_CTRL_I2C_SLV2_DLY_EN \
+ 0x04 // I2C slave 2 delay enable
+#define MPU9150_I2C_MST_DELAY_CTRL_I2C_SLV1_DLY_EN \
+ 0x02 // I2C slave 1 delay enable
+#define MPU9150_I2C_MST_DELAY_CTRL_I2C_SLV0_DLY_EN \
+ 0x01 // I2C slave 0 delay enable
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_SIGNAL_PATH_RESET register.
+//
+//*****************************************************************************
+#define MPU9150_SIGNAL_PATH_RESET_GYRO \
+ 0x04 // Reset gyro
+#define MPU9150_SIGNAL_PATH_RESET_ACCEL \
+ 0x02 // Reset accelerometer
+#define MPU9150_SIGNAL_PATH_RESET_TEMP \
+ 0x01 // Reset temperature sensor
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the
+// MPU9150_O_MOT_DETECT_CTRL register.
+//
+//*****************************************************************************
+#define MPU9150_MOT_DETECT_CTRL_ACCEL_ON_DELAY_M \
+ 0x30 // Accelerometer wake-up delay
+#define MPU9150_MOT_DETECT_CTRL_ACCEL_ON_DELAY_4MS \
+ 0x00 // Delay 4 ms
+#define MPU9150_MOT_DETECT_CTRL_ACCEL_ON_DELAY_5MS \
+ 0x10 // Delay 5 ms
+#define MPU9150_MOT_DETECT_CTRL_ACCEL_ON_DELAY_6MS \
+ 0x20 // Delay 6 ms
+#define MPU9150_MOT_DETECT_CTRL_ACCEL_ON_DELAY_7MS \
+ 0x30 // Delay 7 ms
+#define MPU9150_MOT_DETECT_CTRL_FF_COUNT_M \
+ 0x0C // Free-fall counter decrement rate
+#define MPU9150_MOT_DETECT_CTRL_FF_COUNT_RESET \
+ 0x00 // Reset counter
+#define MPU9150_MOT_DETECT_CTRL_FF_COUNT_1 \
+ 0x04 // Decrement by 1
+#define MPU9150_MOT_DETECT_CTRL_FF_COUNT_2 \
+ 0x08 // Decrement by 2
+#define MPU9150_MOT_DETECT_CTRL_FF_COUNT_4 \
+ 0x0C // Decrement by 4
+#define MPU9150_MOT_DETECT_CTRL_MOT_COUNT_M \
+ 0x03 // Motion detect counter decrement
+ // rate
+#define MPU9150_MOT_DETECT_CTRL_MOT_COUNT_RESET \
+ 0x00 // Reset counter
+#define MPU9150_MOT_DETECT_CTRL_MOT_COUNT_1 \
+ 0x04 // Decrement by 1
+#define MPU9150_MOT_DETECT_CTRL_MOT_COUNT_2 \
+ 0x08 // Decrement by 2
+#define MPU9150_MOT_DETECT_CTRL_MOT_COUNT_4 \
+ 0x0C // Decrement by 4
+#define MPU9150_MOT_DETECT_CTRL_ACCEL_ON_DELAY_S \
+ 4
+#define MPU9150_MOT_DETECT_CTRL_FF_COUNT_S \
+ 2
+#define MPU9150_MOT_DETECT_CTRL_MOT_COUNT_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_USER_CTRL
+// register.
+//
+//*****************************************************************************
+#define MPU9150_USER_CTRL_FIFO_EN \
+ 0x40 // FIFO enable
+#define MPU9150_USER_CTRL_I2C_MST_EN \
+ 0x20 // I2C master mode enable
+#define MPU9150_USER_CTRL_I2C_IF_DIS \
+ 0x10 // Write as zero
+#define MPU9150_USER_CTRL_FIFO_RESET \
+ 0x04 // Reset FIFO buffer
+#define MPU9150_USER_CTRL_I2C_MST_RESET \
+ 0x02 // Reset I2C master
+#define MPU9150_USER_CTRL_SIG_COND_RESET \
+ 0x01 // Reset all sensors
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_PWR_MGMT_1
+// register.
+//
+//*****************************************************************************
+#define MPU9150_PWR_MGMT_1_DEVICE_RESET \
+ 0x80 // Device reset
+#define MPU9150_PWR_MGMT_1_SLEEP \
+ 0x40 // Enter sleep mode
+#define MPU9150_PWR_MGMT_1_CYCLE \
+ 0x20 // Enable automatic sleep
+#define MPU9150_PWR_MGMT_1_TEMP_DIS \
+ 0x08 // Disable temperature sensor
+#define MPU9150_PWR_MGMT_1_CLKSEL_M \
+ 0x07 // Clock source select
+#define MPU9150_PWR_MGMT_1_CLKSEL_INT \
+ 0x00 // Internal 8 MHz oscillator
+#define MPU9150_PWR_MGMT_1_CLKSEL_XG \
+ 0x01 // PLL with X-axis gyro reference
+#define MPU9150_PWR_MGMT_1_CLKSEL_YG \
+ 0x02 // PLL with Y-axis gyro reference
+#define MPU9150_PWR_MGMT_1_CLKSEL_ZG \
+ 0x03 // PLL with Z-axis gyro reference
+#define MPU9150_PWR_MGMT_1_CLKSEL_EXT32K \
+ 0x04 // PLL with external 32.768 kHz
+ // reference
+#define MPU9150_PWR_MGMT_1_CLKSEL_EXT19M \
+ 0x05 // PLL with external 19.2 MHz
+ // reference
+#define MPU9150_PWR_MGMT_1_CLKSEL_STOP \
+ 0x07 // Clock disable
+#define MPU9150_PWR_MGMT_1_CLKSEL_S \
+ 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_PWR_MGMT_2
+// register.
+//
+//*****************************************************************************
+#define MPU9150_PWR_MGMT_2_LP_WAKE_CTRL_M \
+ 0xC0 // Wake-up frequency
+#define MPU9150_PWR_MGMT_2_LP_WAKE_CTRL_1_25 \
+ 0x00 // Wake-up at 1.25 Hz
+#define MPU9150_PWR_MGMT_2_LP_WAKE_CTRL_5 \
+ 0x40 // Wake-up at 5 Hz
+#define MPU9150_PWR_MGMT_2_LP_WAKE_CTRL_20 \
+ 0x80 // Wake-up at 20 Hz
+#define MPU9150_PWR_MGMT_2_LP_WAKE_CTRL_40 \
+ 0xC0 // Wake-up at 40 Hz
+#define MPU9150_PWR_MGMT_2_STBY_XA \
+ 0x20 // Put X-axis accelerometer into
+ // standby mode
+#define MPU9150_PWR_MGMT_2_STBY_YA \
+ 0x10 // Put Y-axis accelerometer into
+ // standby mode
+#define MPU9150_PWR_MGMT_2_STBY_ZA \
+ 0x08 // Put Z-axis accelerometer into
+ // standby mode
+#define MPU9150_PWR_MGMT_2_STBY_XG \
+ 0x04 // Put X-axis gyro into standby
+ // mode
+#define MPU9150_PWR_MGMT_2_STBY_YG \
+ 0x02 // Put Y-axis gyro into standby
+ // mode
+#define MPU9150_PWR_MGMT_2_STBY_ZG \
+ 0x01 // Put Z-axis gyro into standby
+ // mode
+#define MPU9150_PWR_MGMT_2_LP_WAKE_CTRL_S \
+ 6
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_FIFO_COUNTH
+// register.
+//
+//*****************************************************************************
+#define MPU9150_FIFO_COUNTH_M 0x07 // FIFO count [10:8]
+#define MPU9150_FIFO_COUNTH_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_FIFO_COUNTL
+// register.
+//
+//*****************************************************************************
+#define MPU9150_FIFO_COUNTL_M 0xFF // FIFO count [7:0]
+#define MPU9150_FIFO_COUNTL_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_FIFO_R_W
+// register.
+//
+//*****************************************************************************
+#define MPU9150_FIFO_R_W_M 0xFF // FIFO data
+#define MPU9150_FIFO_R_W_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the MPU9150_O_WHO_AM_I
+// register.
+//
+//*****************************************************************************
+#define MPU9150_WHO_AM_I_M 0x7E // I2C address
+#define MPU9150_WHO_AM_I_MPU9150 \
+ 0x68 // MPU9150
+#define MPU9150_WHO_AM_I_S 1
+
+#endif // __SENSORLIB_HW_MPU9150_H__
diff --git a/sensorlib/hw_sht21.h b/sensorlib/hw_sht21.h new file mode 100644 index 0000000..550af75 --- /dev/null +++ b/sensorlib/hw_sht21.h @@ -0,0 +1,76 @@ +//*****************************************************************************
+//
+// hw_sht21.h - Macros used for accessing the Intersil SHT21 humidity sensor
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_HW_SHT21_H__
+#define __SENSORLIB_HW_SHT21_H__
+
+//*****************************************************************************
+//
+// The following are defines for the SHT21 Commands and Registers
+//
+//*****************************************************************************
+#define SHT21_CMD_MEAS_T_HOLD 0xE3 // Measure temperatue with I2C bus
+ // hold
+#define SHT21_CMD_MEAS_RH_HOLD 0xE5 // Measure humidity with I2C bus
+ // hold
+#define SHT21_CMD_WRITE_CONFIG 0xE6 // Write the user config register
+#define SHT21_CMD_READ_CONFIG 0xE7 // Read the user config register
+#define SHT21_CMD_MEAS_T 0xF3 // Measure temperature polled
+#define SHT21_CMD_MEAS_RH 0xF5 // Measure humidity polled
+#define SHT21_CMD_SOFT_RESET 0xFE // Perform a device reset
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the SHT21_CONFIG register.
+//
+//*****************************************************************************
+#define SHT21_CONFIG_RES_M 0x81 // Resolution config for
+ // temperature and humidity
+#define SHT21_CONFIG_RES_12 0x00 // RH 12 bit, T 14 bit
+#define SHT21_CONFIG_RES_8 0x01 // RH 8 bit, T 12 bit
+#define SHT21_CONFIG_RES_10 0x80 // RH 10 bit, T 13 bit
+#define SHT21_CONFIG_RES_11 0x81 // RH 11 bit, T 11 bit
+#define SHT21_CONFIG_BATT_M 0x40 // Battery status indicator
+#define SHT21_CONFIG_BATT_GOOD 0x00
+#define SHT21_CONFIG_BATT_LOW 0x40
+#define SHT21_CONFIG_HEATER_M 0x04 // On chip heater for test and
+ // diagnostics
+#define SHT21_CONFIG_HEATER_DISABLE \
+ 0x00 // Heater off
+#define SHT21_CONFIG_HEATER_ENABLE \
+ 0x04 // Heater on
+#define SHT21_CONFIG_OTP_RELOAD_M \
+ 0x02 // OTP reload control; soft reset
+ // is preferred
+#define SHT21_CONFIG_OTP_RELOAD_ENABLE \
+ 0x00 // OTP reload enabled
+#define SHT21_CONFIG_OTP_RELOAD_DISABLE \
+ 0x02 // OTP reload disabled
+#define SHT21_CONFIG_BATT_S 6
+#define SHT21_CONFIG_HEATER_S 2
+#define SHT21_CONFIG_OTP_RELOAD_S \
+ 1
+#define SHT21_CONFIG_RES_S 0
+
+#endif // __SENSORLIB_HW_SHT21_H__
diff --git a/sensorlib/hw_tmp006.h b/sensorlib/hw_tmp006.h new file mode 100644 index 0000000..6c350c8 --- /dev/null +++ b/sensorlib/hw_tmp006.h @@ -0,0 +1,75 @@ +//*****************************************************************************
+//
+// hw_tmp006.h - Macros used when accessing the Texas Instruments TMP006
+// Infrared Temperature Sensor
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_HW_TMP006_H__
+#define __SENSORLIB_HW_TMP006_H__
+
+//*****************************************************************************
+//
+// The following are defines for the TMP006 Register Addresses
+//
+//*****************************************************************************
+#define TMP006_O_VOBJECT 0x00 // Raw object voltage measurement
+#define TMP006_O_TAMBIENT 0x01 // Die temperature of the TMP006
+#define TMP006_O_CONFIG 0x02 // TMP006 Configuration
+#define TMP006_O_MFG_ID 0xFE // TMP006 Manufacture
+ // Identification
+#define TMP006_O_DEV_ID 0xFF // TMP006 Device Identification
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the TMP006_O_CONFIG
+// register.
+//
+//*****************************************************************************
+#define TMP006_CONFIG_RESET_M 0x8000 // TMP006 device reset
+#define TMP006_CONFIG_RESET_ASSERT \
+ 0x8000 // Reset TMP006; self clearing
+#define TMP006_CONFIG_MODE_M 0x7000 // Operation mode
+#define TMP006_CONFIG_MODE_PD 0x0000 // Power down
+#define TMP006_CONFIG_MODE_CONT 0x7000 // Continuous sampling
+#define TMP006_CONFIG_CR_M 0x0E00 // Conversion rate setting
+#define TMP006_CONFIG_CR_4 0x0000 // 4Hz conversion rate
+#define TMP006_CONFIG_CR_2 0x0200 // 2Hz conversion rate
+#define TMP006_CONFIG_CR_1 0x0400 // 1Hz conversion rate
+#define TMP006_CONFIG_CR_0_5 0x0600 // 0.5Hz conversion rate
+#define TMP006_CONFIG_CR_0_25 0x0800 // 0.25Hz conversion rate
+#define TMP006_CONFIG_EN_DRDY_PIN_M \
+ 0x0100 // Enable the DRDY output pin
+#define TMP006_CONFIG_DIS_DRDY_PIN \
+ 0x0000 // DRDY pin disabled
+#define TMP006_CONFIG_EN_DRDY_PIN \
+ 0x0100 // DRDY pin enabled
+#define TMP006_CONFIG_DRDY_M 0x0080 // Data ready flag
+#define TMP006_CONFIG_IN_PROG 0x0000 // Conversion in progress
+#define TMP006_CONFIG_DRDY 0x0080 // Conversion complete
+#define TMP006_CONFIG_RESET_S 15
+#define TMP006_CONFIG_MODE_S 12
+#define TMP006_CONFIG_CR_S 9
+#define TMP006_CONFIG_EN_DRDY_PIN_S \
+ 8
+#define TMP006_CONFIG_DRDY_S 7
+
+#endif // __SENSORLIB_HW_TMP006_H__
diff --git a/sensorlib/hw_tmp100.h b/sensorlib/hw_tmp100.h new file mode 100644 index 0000000..5debb87 --- /dev/null +++ b/sensorlib/hw_tmp100.h @@ -0,0 +1,93 @@ +//*****************************************************************************
+//
+// hw_tmp100.h - Macros used when accessing the Texas Instruments TMP100
+// Temperature Sensor
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_HW_TMP100_H__
+#define __SENSORLIB_HW_TMP100_H__
+
+//*****************************************************************************
+//
+// The following are defines for the TMP100 Register Addresses
+//
+//*****************************************************************************
+#define TMP100_O_TEMP 0x00 // Temperature register
+#define TMP100_O_CONFIG 0x01 // Configuration register
+#define TMP100_O_TEMP_LOW 0x02 // Temperature low register
+#define TMP100_O_TEMP_HIGH 0x03 // Temperature high register
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the TMP100_O_TEMP register.
+//
+//*****************************************************************************
+#define TMP100_TEMP_M 0xFFFF // Temperature data
+#define TMP100_TEMP_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the TMP100_O_CONFIG
+// register.
+//
+//*****************************************************************************
+#define TMP100_CONFIG_OS_ALERT 0x80 // Starts a one-shot when written,
+ // reports alert when read
+#define TMP100_CONFIG_RES_M 0x60 // Converter resolution
+#define TMP100_CONFIG_RES_9BIT 0x00 // 9-bit resolution (40 ms
+ // conversion time)
+#define TMP100_CONFIG_RES_10BIT 0x20 // 10-bit resolution (80 ms
+ // conversion time)
+#define TMP100_CONFIG_RES_11BIT 0x40 // 11-bit resolution (160 ms
+ // conversion time)
+#define TMP100_CONFIG_RES_12BIT 0x60 // 12-bit resolution (320 ms
+ // conversion time)
+#define TMP100_CONFIG_CR_M 0x18 // Consecutive fault configuration
+#define TMP100_CONFIG_FAULT_1 0x00 // 1 consecutive fault
+#define TMP100_CONFIG_FAULT_2 0x08 // 2 consecutive faults
+#define TMP100_CONFIG_FAULT_4 0x10 // 4 consecutive faults
+#define TMP100_CONFIG_FAULT_6 0x18 // 6 consecutive faults
+#define TMP100_CONFIG_POL 0x04 // Alert pin polarity
+#define TMP100_CONFIG_TM 0x02 // Thermostat mode
+#define TMP100_CONFIG_SD 0x01 // Shutdown mode
+#define TMP100_CONFIG_RES_S 5
+#define TMP100_CONFIG_FAULT_S 3
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the TMP100_O_TEMP_LOW
+// register.
+//
+//*****************************************************************************
+#define TMP100_TEMP_LOW_M 0xFFFF // Temperature low data
+#define TMP100_TEMP_LOW_S 0
+
+//*****************************************************************************
+//
+// The following are defines for the bit fields in the TMP100_O_TEMP_HIGH
+// register.
+//
+//*****************************************************************************
+#define TMP100_TEMP_HIGH_M 0xFFFF // Temperature high data
+#define TMP100_TEMP_HIGH_S 0
+
+#endif // __SENSORLIB_HW_TMP100_H__
diff --git a/sensorlib/i2cm_drv.c b/sensorlib/i2cm_drv.c new file mode 100644 index 0000000..1e603e2 --- /dev/null +++ b/sensorlib/i2cm_drv.c @@ -0,0 +1,2256 @@ +//*****************************************************************************
+//
+// i2cm_drv.c - Interrupt-driven I2C master driver.
+//
+// Copyright (c) 2012-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "inc/hw_i2c.h"
+#include "inc/hw_memmap.h"
+#include "inc/hw_types.h"
+#include "driverlib/debug.h"
+#include "driverlib/i2c.h"
+#include "driverlib/interrupt.h"
+#include "driverlib/rom.h"
+#include "driverlib/rom_map.h"
+#include "sensorlib/i2cm_drv.h"
+
+//*****************************************************************************
+//
+//! \addtogroup i2cm_drv_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The states in the interrupt handler state machine.
+//
+//*****************************************************************************
+#define STATE_IDLE 0
+#define STATE_WRITE_NEXT 1
+#define STATE_WRITE_FINAL 2
+#define STATE_WRITE_PAUSE 3
+#define STATE_READ_ONE 4
+#define STATE_READ_FIRST 5
+#define STATE_READ_NEXT 6
+#define STATE_READ_FINAL 7
+#define STATE_READ_PAUSE 8
+#define STATE_READ_WAIT 9
+#define STATE_CALLBACK 10
+
+//*****************************************************************************
+//
+// The states in the I2C read-modify-write state machine.
+//
+//*****************************************************************************
+#define I2CM_RMW_STATE_IDLE 0
+#define I2CM_RMW_STATE_READ 1
+#define I2CM_RMW_STATE_WRITE 2
+
+//*****************************************************************************
+//
+//! Writes data to an I2C device.
+//!
+//! \param psInst is a pointer to the I2C master instance data.
+//! \param ui8Addr is the address of the I2C device to access.
+//! \param pui8Data is a pointer to the data buffer to be written.
+//! \param ui16Count is the number of bytes to be written.
+//! \param pfnCallback is the function to be called when the write has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function adds an I2C write to the queue of commands to be sent. If
+//! successful, the I2C write is then performed in the background using the
+//! interrupt handler. When the write is complete, the callback function, if
+//! provided, is called in the context of the I2C master interrupt handler.
+//!
+//! The first byte of the data buffer contains the I2C address of the device to
+//! access, and the remaining \e ui16Count bytes contain the data to be written
+//! to the device. The \e ui16Count parameter can be zero if there are no
+//! bytes to be written.
+//!
+//! \return Returns 1 if the command was successfully added to the queue and 0
+//! if it was not.
+//
+// The extern here provides a non-inline definition for this function to handle
+// the case where the compiler chooses not to inline the function (which is a
+// valid choice for the compiler to make).
+//
+//*****************************************************************************
+extern uint_fast8_t I2CMWrite(tI2CMInstance *psInst, uint_fast8_t ui8Addr,
+ const uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback pfnCallback,
+ void *pvCallbackData);
+
+//*****************************************************************************
+//
+//! Reads data from an I2C device.
+//!
+//! \param psInst is a pointer to the I2C master instance data.
+//! \param ui8Addr is the address of the I2C device to access.
+//! \param pui8WriteData is a pointer to the data buffer to be written.
+//! \param ui16WriteCount is the number of bytes to be written.
+//! \param pui8ReadData is a pointer to the buffer to be filled with the read
+//! data.
+//! \param ui16ReadCount is the number of bytes to be read.
+//! \param pfnCallback is the function to be called when the transfer has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function adds an I2C read to the queue of commands to be sent. If
+//! successful, the I2C read is then performed in the background using the
+//! interrupt handler. When the read is complete, the callback function, if
+//! provided, is called in the context of the I2C master interrupt handler.
+//!
+//! The first byte of \e pui8WriteData contains the I2C address of the device
+//! to access, the next \e ui16WriteCount bytes contains the data to be written
+//! to the device. The data read from the device is written into the first
+//! \e ui16ReadCount bytes of \e pui8ReadData. The \e ui16WriteCount or
+//! \e ui16ReadCount parameters can be zero if there are no bytes to be read or
+//! written. The write bytes are sent to the device first, and then the read
+//! bytes are read from the device afterward.
+//!
+//! \return Returns 1 if the command was successfully added to the queue and 0
+//! if it was not.
+//
+// The extern here provides a non-inline definition for this function to handle
+// the case where the compiler chooses not to inline the function (which is a
+// valid choice for the compiler to make).
+//
+//*****************************************************************************
+extern uint_fast8_t I2CMRead(tI2CMInstance *psInst, uint_fast8_t ui8Addr,
+ const uint8_t *pui8WriteData,
+ uint_fast16_t ui16WriteCount,
+ uint8_t *pui8ReadData,
+ uint_fast16_t ui16ReadCount,
+ tSensorCallback pfnCallback,
+ void *pvCallbackData);
+
+//*****************************************************************************
+//
+//! Writes data in batches to an I2C device.
+//!
+//! \param psInst is a pointer to the I2C master instance data.
+//! \param ui8Addr is the address of the I2C device to access.
+//! \param pui8Data is a pointer to the data buffer to be written.
+//! \param ui16Count is the number of bytes to be written.
+//! \param ui16BatchSize is the number of bytes in each write batch.
+//! \param pfnCallback is the function to be called when the transfer has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function adds an I2C write to the queue of commands to be sent. If
+//! successful, the I2C write is then performed in the background using the
+//! interrupt handler. When the write is complete, the callback function, if
+//! provided, is called in the context of the I2C master interrupt handler.
+//!
+//! The first byte of the data buffer contains the I2C address of the device to
+//! access, and the remaining \e ui16Count bytes contain the data to be written
+//! to the device. The \e ui16Count parameter can be zero if there are no
+//! bytes to be written.
+//!
+//! The data is written in batches of \e ui16WriteBatchSize. The callback
+//! function is called after each batch is written, and I2CMTransferResume()
+//! must be called when the next batch should be written.
+//!
+//! \return Returns 1 if the command was successfully added to the queue and 0
+//! if it was not.
+//
+// The extern here provides a non-inline definition for this function to handle
+// the case where the compiler chooses not to inline the function (which is a
+// valid choice for the compiler to make).
+//
+//*****************************************************************************
+extern uint_fast8_t I2CMWriteBatched(tI2CMInstance *psInst,
+ uint_fast8_t ui8Addr,
+ const uint8_t *pui8Data,
+ uint_fast16_t ui16Count,
+ uint_fast16_t ui16BatchSize,
+ tSensorCallback pfnCallback,
+ void *pvCallbackData);
+
+//*****************************************************************************
+//
+//! Reads data in batches from an I2C device.
+//!
+//! \param psInst is a pointer to the I2C master instance data.
+//! \param ui8Addr is the address of the I2C device to access.
+//! \param pui8WriteData is a pointer to the data buffer to be written.
+//! \param ui16WriteCount is the number of bytes to be written.
+//! \param ui16WriteBatchSize is the number of bytes in each write batch.
+//! \param pui8ReadData is a pointer to the buffer to be filled with the read
+//! data.
+//! \param ui16ReadCount is the number of bytes to be read.
+//! \param ui16ReadBatchSize is the number of bytes in each read batch.
+//! \param pfnCallback is the function to be called when the transfer has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function adds an I2C read to the queue of commands to be sent. If
+//! successful, the I2C read is then performed in the background using the
+//! interrupt handler. When the read is complete, the callback function, if
+//! provided, is called in the context of the I2C master interrupt handler.
+//!
+//! The first byte of \e pui8WriteData contains the I2C address of the device
+//! to access, the next \e ui16WriteCount bytes contains the data to be written
+//! to the device. The data read from the device is written into the first
+//! \e ui16ReadCount bytes of \e pui8ReadData. The \e ui16WriteCount or
+//! \e ui16ReadCount parameters can be zero if there are no bytes to be read or
+//! written. The write bytes are sent to the device first, and then the read
+//! bytes are read from the device afterward.
+//!
+//! The data is written in batches of \e ui16WriteBatchSize. The callback
+//! function is called after each batch is written, and I2CMTransferResume()
+//! must be called when the next batch should be written.
+//!
+//! The data is read in batches of \e ui16ReadBatchSize. The callback function
+//! is called after each batch is read, and I2CMTransferResume() must be called
+//! when the next batch should be read.
+//!
+//! \return Returns 1 if the command was successfully added to the queue and 0
+//! if it was not.
+//
+// The extern here provides a non-inline definition for this function to handle
+// the case where the compiler chooses not to inline the function (which is a
+// valid choice for the compiler to make).
+//
+//*****************************************************************************
+extern uint_fast8_t I2CMReadBatched(tI2CMInstance *psInst,
+ uint_fast8_t ui8Addr,
+ const uint8_t *pui8WriteData,
+ uint_fast16_t ui16WriteCount,
+ uint_fast16_t ui16WriteBatchSize,
+ uint8_t *pui8ReadData,
+ uint_fast16_t ui16ReadCount,
+ uint_fast16_t ui16ReadBatchSize,
+ tSensorCallback pfnCallback,
+ void *pvCallbackData);
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of 16 bits of big-endian data in an I2C
+//! device.
+//!
+//! \param psInst is a pointer to the read-modify-write instance data.
+//! \param psI2CInst is a pointer to the I2C master instance data.
+//! \param ui8Addr is the address of the I2C device to access.
+//! \param ui8Reg is the register in the I2C device to access.
+//! \param ui16Mask is the mask indicating the register bits that should be
+//! maintained.
+//! \param ui16Value is the value indicating the new value for the register
+//! bits that are not maintained.
+//! \param pfnCallback is the function to be called when the write has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read-modify-write transaction of 16 bits of
+//! big-endian data in an I2C device. The modify portion of the operation is
+//! performed by AND-ing the register value with \e ui16Mask and then OR-ing
+//! the result with \e ui16Value. When the read-modify-write is complete, the
+//! callback function, if provided, is called in the context of the I2C master
+//! interrupt handler.
+//!
+//! If the mask (in \e ui16Mask) is zero, then none of the bits in the current
+//! register value are maintained. In this case, the read portion of the
+//! read-modify-write is bypassed, and the new register value (in \e ui16Value)
+//! is directly written to the I2C device.
+//!
+//! \return Returns 1 if the command was successfully added to the queue and 0
+//! if it was not.
+//
+// The extern here provides a non-inline definition for this function to handle
+// the case where the compiler chooses not to inline the function (which is a
+// valid choice for the compiler to make).
+//
+//*****************************************************************************
+extern uint_fast8_t I2CMReadModifyWrite16BE(tI2CMReadModifyWrite16 *psInst,
+ tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8Addr,
+ uint_fast8_t ui8Reg,
+ uint_fast16_t ui16Mask,
+ uint_fast16_t ui16Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+
+//*****************************************************************************
+//
+// This function handles the idle state of the I2C master state machine.
+//
+//*****************************************************************************
+static void
+I2CMStateIdle(tI2CMInstance *psInst, tI2CMCommand *pCommand)
+{
+ //
+ // Do nothing if there is not another transfer in the queue.
+ //
+ if(psInst->ui8ReadPtr == psInst->ui8WritePtr)
+ {
+ return;
+ }
+
+ //
+ // See if there is any data to be written.
+ //
+ if(pCommand->ui16WriteCount != 0)
+ {
+ //
+ // Set the slave address and indicate a write.
+ //
+ MAP_I2CMasterSlaveAddrSet(psInst->ui32Base, pCommand->ui8Addr, false);
+
+ //
+ // Place the first data byte to be written in the data register.
+ //
+ MAP_I2CMasterDataPut(psInst->ui32Base, pCommand->pui8WriteData[0]);
+
+ //
+ // See if there is just a single byte to be written and no bytes to be
+ // read.
+ //
+ if((pCommand->ui16WriteCount == 1) && (pCommand->ui16ReadCount == 0))
+ {
+ //
+ // Perform a single byte send.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base, I2C_MASTER_CMD_SINGLE_SEND);
+
+ //
+ // The next state is the callback state.
+ //
+ psInst->ui8State = STATE_CALLBACK;
+ }
+
+ //
+ // Otherwise, see if there is just a single byte to be written and at
+ // least one byte to be read.
+ //
+ else if(pCommand->ui16WriteCount == 1)
+ {
+ //
+ // Perform a single send, writing the first byte as the only byte.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base,
+ I2C_MASTER_CMD_BURST_SEND_START);
+
+ //
+ // Set the next state of the interrupt state machine based on the
+ // number of bytes to read.
+ //
+ psInst->ui8State = ((pCommand->ui16ReadCount == 1) ?
+ STATE_READ_ONE : STATE_READ_FIRST);
+ }
+
+ //
+ // Otherwise, there is more than one byte to be written.
+ //
+ else
+ {
+ //
+ // Start the burst cycle, writing the first byte.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base,
+ I2C_MASTER_CMD_BURST_SEND_START);
+
+ //
+ // Set the index to indicate that the first byte has been
+ // transmitted.
+ //
+ psInst->ui16Index = 1;
+
+ //
+ // Set the next state of the interrupt state machine based on the
+ // number of bytes to write.
+ //
+ psInst->ui8State = ((pCommand->ui16WriteCount != 2) ?
+ STATE_WRITE_NEXT : STATE_WRITE_FINAL);
+ }
+ }
+ else
+ {
+ //
+ // Set the slave address and indicate a read.
+ //
+ MAP_I2CMasterSlaveAddrSet(psInst->ui32Base, pCommand->ui8Addr, true);
+
+ //
+ // Set the index to indicate that the first byte is being read.
+ //
+ psInst->ui16Index = 0;
+
+ //
+ // See if there is just a single byte to be read.
+ //
+ if(pCommand->ui16ReadCount == 1)
+ {
+ //
+ // Perform a single byte read.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base,
+ I2C_MASTER_CMD_SINGLE_RECEIVE);
+
+ //
+ // The next state is the wait for final read state.
+ //
+ psInst->ui8State = STATE_READ_WAIT;
+ }
+ else
+ {
+ //
+ // Start the burst receive.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base,
+ I2C_MASTER_CMD_BURST_RECEIVE_START);
+
+ //
+ // Set the next state appropriately. If the read count is two, the
+ // next state must finish the transaction. If it is greater than
+ // two, the burst read must be continued.
+ //
+ psInst->ui8State = ((pCommand->ui16ReadCount == 2) ?
+ STATE_READ_FINAL : STATE_READ_NEXT);
+ }
+ }
+}
+
+//*****************************************************************************
+//
+// This function handles the write next state of the I2C master state machine.
+//
+//*****************************************************************************
+static void
+I2CMStateWriteNext(tI2CMInstance *psInst, tI2CMCommand *pCommand)
+{
+ //
+ // See if the write batch has been sent.
+ //
+ if(psInst->ui16Index == pCommand->ui16WriteBatchSize)
+ {
+ //
+ // Move to the write pause state.
+ //
+ psInst->ui8State = STATE_WRITE_PAUSE;
+
+ //
+ // Call the callback function.
+ //
+ if(pCommand->pfnCallback)
+ {
+ pCommand->pfnCallback(pCommand->pvCallbackData,
+ I2CM_STATUS_BATCH_DONE);
+ }
+ }
+ else
+ {
+ //
+ // Write the next byte to the data register.
+ //
+ MAP_I2CMasterDataPut(psInst->ui32Base,
+ pCommand->pui8WriteData[psInst->ui16Index]);
+ psInst->ui16Index++;
+
+ //
+ // Continue the burst write.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base, I2C_MASTER_CMD_BURST_SEND_CONT);
+
+ //
+ // If there is one byte left, set the next state to the final write
+ // state.
+ //
+ if((pCommand->ui16WriteCount - psInst->ui16Index) == 1)
+ {
+ psInst->ui8State = STATE_WRITE_FINAL;
+ }
+ }
+}
+
+//*****************************************************************************
+//
+// This function handles the write final state of the I2C master state machine.
+//
+//*****************************************************************************
+static void
+I2CMStateWriteFinal(tI2CMInstance *psInst, tI2CMCommand *pCommand)
+{
+ //
+ // See if the write batch has been sent.
+ //
+ if(psInst->ui16Index == pCommand->ui16WriteBatchSize)
+ {
+ //
+ // Move to the write pause state.
+ //
+ psInst->ui8State = STATE_WRITE_PAUSE;
+
+ //
+ // Call the callback function.
+ //
+ if(pCommand->pfnCallback)
+ {
+ pCommand->pfnCallback(pCommand->pvCallbackData,
+ I2CM_STATUS_BATCH_DONE);
+ }
+ }
+ else
+ {
+ //
+ // Write the final byte to the data register.
+ //
+ MAP_I2CMasterDataPut(psInst->ui32Base,
+ pCommand->pui8WriteData[psInst->ui16Index]);
+
+ //
+ // See if there is data to be read after this byte is written.
+ //
+ if(pCommand->ui16ReadCount == 0)
+ {
+ //
+ // Finish the burst write.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base,
+ I2C_MASTER_CMD_BURST_SEND_FINISH);
+
+ //
+ // The next state is the callback state.
+ //
+ psInst->ui8State = STATE_CALLBACK;
+ }
+ else
+ {
+ //
+ // Finish the burst write.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base,
+ I2C_MASTER_CMD_BURST_SEND_CONT);
+
+ //
+ // Set the next state of the interrupt state machine based on the
+ // number of bytes to read.
+ //
+ psInst->ui8State = ((pCommand->ui16ReadCount == 1) ?
+ STATE_READ_ONE : STATE_READ_FIRST);
+ }
+ }
+}
+
+//*****************************************************************************
+//
+// This function handles the write pause state of the I2C master state machine.
+//
+//*****************************************************************************
+static void
+I2CMStateWritePause(tI2CMInstance *psInst, tI2CMCommand *pCommand)
+{
+ //
+ // Decrement the write count by the batch size.
+ //
+ pCommand->ui16WriteCount -= pCommand->ui16WriteBatchSize;
+
+ //
+ // Write the next byte to the data register.
+ //
+ MAP_I2CMasterDataPut(psInst->ui32Base, pCommand->pui8WriteData[0]);
+
+ //
+ // Set the index to indicate that the first byte has been transmitted.
+ //
+ psInst->ui16Index = 1;
+
+ //
+ // See if there is more than one byte left to be written.
+ //
+ if((pCommand->ui16WriteCount - psInst->ui16Index) == 0)
+ {
+ //
+ // See if there is data to be read after this byte is written.
+ //
+ if(pCommand->ui16ReadCount == 0)
+ {
+ //
+ // Finish the burst write.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base,
+ I2C_MASTER_CMD_BURST_SEND_FINISH);
+
+ //
+ // The next state is the callback state.
+ //
+ psInst->ui8State = STATE_CALLBACK;
+ }
+ else
+ {
+ //
+ // Finish the burst write.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base,
+ I2C_MASTER_CMD_BURST_SEND_CONT);
+
+ //
+ // Set the next state of the interrupt state machine based on the
+ // number of bytes to read.
+ //
+ psInst->ui8State = ((pCommand->ui16ReadCount == 1) ?
+ STATE_READ_ONE : STATE_READ_FIRST);
+ }
+ }
+ else
+ {
+ //
+ // Continue the burst write.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base, I2C_MASTER_CMD_BURST_SEND_CONT);
+
+ //
+ // The next state is the write next state.
+ //
+ if((pCommand->ui16WriteCount - psInst->ui16Index) == 1)
+ {
+ psInst->ui8State = STATE_WRITE_FINAL;
+ }
+ else
+ {
+ psInst->ui8State = STATE_WRITE_NEXT;
+ }
+ }
+}
+
+//*****************************************************************************
+//
+// This function handles the read one state of the I2C master state machine.
+//
+//*****************************************************************************
+static void
+I2CMStateReadOne(tI2CMInstance *psInst, tI2CMCommand *pCommand)
+{
+ //
+ // Put the I2C master into receive mode.
+ //
+ MAP_I2CMasterSlaveAddrSet(psInst->ui32Base, pCommand->ui8Addr, true);
+
+ //
+ // Perform a single byte read.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base, I2C_MASTER_CMD_SINGLE_RECEIVE);
+
+ //
+ // Set the index to indicate that the first byte is being read.
+ //
+ psInst->ui16Index = 0;
+
+ //
+ // The next state is the wait for final read state.
+ //
+ psInst->ui8State = STATE_READ_WAIT;
+}
+
+//*****************************************************************************
+//
+// This function handles the read first state of the I2C master state machine.
+//
+//*****************************************************************************
+static void
+I2CMStateReadFirst(tI2CMInstance *psInst, tI2CMCommand *pCommand)
+{
+ //
+ // Put the I2C master into receive mode.
+ //
+ MAP_I2CMasterSlaveAddrSet(psInst->ui32Base, pCommand->ui8Addr, true);
+
+ //
+ // Start the burst receive.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base, I2C_MASTER_CMD_BURST_RECEIVE_START);
+
+ //
+ // Set the index to indicate that the first byte is being read.
+ //
+ psInst->ui16Index = 0;
+
+ //
+ // Set the next state appropriately. If the count is greater than two it
+ // is the middle of the burst read. If exactly two, the next state must
+ // finish the transaction.
+ //
+ psInst->ui8State = ((pCommand->ui16ReadCount == 2) ?
+ STATE_READ_FINAL : STATE_READ_NEXT);
+}
+
+//*****************************************************************************
+//
+// This function handles the read next state of the I2C master state machine.
+//
+//*****************************************************************************
+static void
+I2CMStateReadNext(tI2CMInstance *psInst, tI2CMCommand *pCommand)
+{
+ //
+ // Read the received character.
+ //
+ pCommand->pui8ReadData[psInst->ui16Index] =
+ MAP_I2CMasterDataGet(psInst->ui32Base);
+ psInst->ui16Index++;
+
+ //
+ // See if the read batch has been filled.
+ //
+ if(psInst->ui16Index == pCommand->ui16ReadBatchSize)
+ {
+ //
+ // Move to the read pause state.
+ //
+ psInst->ui8State = STATE_READ_PAUSE;
+
+ //
+ // Call the callback function.
+ //
+ if(pCommand->pfnCallback)
+ {
+ pCommand->pfnCallback(pCommand->pvCallbackData,
+ I2CM_STATUS_BATCH_READY);
+ }
+ }
+ else
+ {
+ //
+ // Continue the burst read.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base,
+ I2C_MASTER_CMD_BURST_RECEIVE_CONT);
+
+ //
+ // If there are two characters left to be read, make the next state be
+ // the end of burst read state.
+ //
+ if((pCommand->ui16ReadCount - psInst->ui16Index) == 2)
+ {
+ psInst->ui8State = STATE_READ_FINAL;
+ }
+ }
+}
+
+//*****************************************************************************
+//
+// This function handles the read final state of the I2C master state machine.
+//
+//*****************************************************************************
+static void
+I2CMStateReadFinal(tI2CMInstance *psInst, tI2CMCommand *pCommand)
+{
+ //
+ // Read the received character.
+ //
+ pCommand->pui8ReadData[psInst->ui16Index] =
+ MAP_I2CMasterDataGet(psInst->ui32Base);
+ psInst->ui16Index++;
+
+ //
+ // See if the read batch has been filled.
+ //
+ if(psInst->ui16Index == pCommand->ui16ReadBatchSize)
+ {
+ //
+ // Move to the read pause state.
+ //
+ psInst->ui8State = STATE_READ_PAUSE;
+
+ //
+ // Call the callback function.
+ //
+ if(pCommand->pfnCallback)
+ {
+ pCommand->pfnCallback(pCommand->pvCallbackData,
+ I2CM_STATUS_BATCH_READY);
+ }
+ }
+ else
+ {
+ //
+ // Finish the burst read.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base,
+ I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
+
+ //
+ // The next state is the wait for final read state.
+ //
+ psInst->ui8State = STATE_READ_WAIT;
+ }
+}
+
+//*****************************************************************************
+//
+// This function handles the read pause state of the I2C master state machine.
+//
+//*****************************************************************************
+static void
+I2CMStateReadPause(tI2CMInstance *psInst, tI2CMCommand *pCommand)
+{
+ //
+ // Decrement the read count by the batch size.
+ //
+ pCommand->ui16ReadCount -= pCommand->ui16ReadBatchSize;
+
+ //
+ // Reset the read index.
+ //
+ psInst->ui16Index = 0;
+
+ //
+ // See if there is more than one byte left to be read.
+ //
+ if((pCommand->ui16ReadCount - psInst->ui16Index) == 1)
+ {
+ //
+ // Finish the burst read.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base,
+ I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
+
+ //
+ // The next state is the wait for final read state.
+ //
+ psInst->ui8State = STATE_READ_WAIT;
+ }
+ else
+ {
+ //
+ // Continue the burst read.
+ //
+ MAP_I2CMasterControl(psInst->ui32Base,
+ I2C_MASTER_CMD_BURST_RECEIVE_CONT);
+
+ //
+ // Determine the next state based on the number of bytes left to read.
+ //
+ if((pCommand->ui16ReadCount - psInst->ui16Index) == 2)
+ {
+ psInst->ui8State = STATE_READ_FINAL;
+ }
+ else
+ {
+ psInst->ui8State = STATE_READ_NEXT;
+ }
+ }
+}
+
+//*****************************************************************************
+//
+// This function handles the read wait state of the I2C master state machine.
+//
+//*****************************************************************************
+static void
+I2CMStateReadWait(tI2CMInstance *psInst, tI2CMCommand *pCommand)
+{
+ //
+ // Read the received character.
+ //
+ pCommand->pui8ReadData[psInst->ui16Index] =
+ MAP_I2CMasterDataGet(psInst->ui32Base);
+
+ //
+ // The state machine is now in the callback state.
+ //
+ psInst->ui8State = STATE_CALLBACK;
+}
+
+//*****************************************************************************
+//
+// This function handles the callback state of the I2C master state machine.
+//
+//*****************************************************************************
+static void
+I2CMStateCallback(tI2CMInstance *psInst, tI2CMCommand *pCommand,
+ uint32_t ui32Status)
+{
+ tSensorCallback *pfnCallback;
+ void *pvCallbackData;
+
+ //
+ // Save the callback information.
+ //
+ pfnCallback = pCommand->pfnCallback;
+ pvCallbackData = pCommand->pvCallbackData;
+
+ //
+ // This command has been completed, so increment the read pointer.
+ //
+ psInst->ui8ReadPtr++;
+ if(psInst->ui8ReadPtr == NUM_I2CM_COMMANDS)
+ {
+ psInst->ui8ReadPtr = 0;
+ }
+
+ //
+ // If there is a callback function then call it now.
+ //
+ if(pfnCallback)
+ {
+ //
+ // Convert the status from the I2C driver into the I2C master
+ // driver status.
+ //
+ if((ui32Status & (I2C_MCS_ARBLST | I2C_MCS_ERROR)) == 0)
+ {
+ ui32Status = I2CM_STATUS_SUCCESS;
+ }
+ else if(ui32Status & I2C_MCS_ARBLST)
+ {
+ ui32Status = I2CM_STATUS_ARB_LOST;
+ }
+ else if(ui32Status & I2C_MCS_ADRACK)
+ {
+ ui32Status = I2CM_STATUS_ADDR_NACK;
+ }
+ else if(ui32Status & I2C_MCS_DATACK)
+ {
+ ui32Status = I2CM_STATUS_DATA_NACK;
+ }
+ else
+ {
+ ui32Status = I2CM_STATUS_ERROR;
+ }
+
+ //
+ // Call the callback function.
+ //
+ pfnCallback(pvCallbackData, ui32Status);
+ }
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = STATE_IDLE;
+}
+
+//*****************************************************************************
+//
+//! Handles I2C master interrupts.
+//!
+//! \param psInst is a pointer to the I2C master instance data.
+//!
+//! This function performs the processing required in response to an I2C
+//! interrupt. The application-supplied interrupt handler should call this
+//! function with the correct instance data in response to the I2C interrupt.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+I2CMIntHandler(tI2CMInstance *psInst)
+{
+ tI2CMCommand *pCommand;
+ uint32_t ui32Status;
+
+ //
+ // Clear the I2C interrupt.
+ //
+ MAP_I2CMasterIntClear(psInst->ui32Base);
+ ui32Status = HWREG(psInst->ui32Base + I2C_O_MCS);
+
+ //
+ // Get a pointer to the current command.
+ //
+ pCommand = &(psInst->pCommands[psInst->ui8ReadPtr]);
+
+ //
+ // See if an error occurred during the last transaction.
+ //
+ if((ui32Status & (I2C_MCS_ERROR | I2C_MCS_ARBLST)) &&
+ (psInst->ui8State != STATE_IDLE))
+ {
+ //
+ // An error occurred, so halt the I2C transaction. The error stop
+ // command for send and receive is identical, so it does not matter
+ // which one is used here. Only issue the stop if the bus is busy.
+ //
+ if(ui32Status & I2C_MCS_BUSBSY)
+ {
+ MAP_I2CMasterControl(psInst->ui32Base,
+ I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
+ }
+
+ //
+ // Move to the callback state.
+ //
+ psInst->ui8State = STATE_CALLBACK;
+ }
+
+ //
+ // Loop forever. Most states will return when they have completed their
+ // action. However, a few states require multi-state processing, so those
+ // states will break and this loop repeated.
+ //
+ while(1)
+ {
+ //
+ // Determine what to do based on the current state.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // The idle state.
+ //
+ case STATE_IDLE:
+ {
+ //
+ // Handle the idle state.
+ //
+ I2CMStateIdle(psInst, pCommand);
+
+ //
+ // This state is done and the next state should be handled at
+ // the next interrupt.
+ //
+ return;
+ }
+
+ //
+ // The state for the middle of a burst write.
+ //
+ case STATE_WRITE_NEXT:
+ {
+ //
+ // Handle the write next state.
+ //
+ I2CMStateWriteNext(psInst, pCommand);
+
+ //
+ // This state is done and the next state should be handled at
+ // the next interrupt.
+ //
+ return;
+ }
+
+ //
+ // The state for the final write of a burst sequence.
+ //
+ case STATE_WRITE_FINAL:
+ {
+ //
+ // Handle the write final state.
+ //
+ I2CMStateWriteFinal(psInst, pCommand);
+
+ //
+ // This state is done and the next state should be handled at
+ // the next interrupt.
+ //
+ return;
+ }
+
+ //
+ // The state for a paused write.
+ //
+ case STATE_WRITE_PAUSE:
+ {
+ //
+ // Handle the write pause state.
+ //
+ I2CMStateWritePause(psInst, pCommand);
+
+ //
+ // This state is done and the next state should be handled at
+ // the next interrupt.
+ //
+ return;
+ }
+
+ //
+ // The state for a single byte read.
+ //
+ case STATE_READ_ONE:
+ {
+ //
+ // Handle the read one state.
+ //
+ I2CMStateReadOne(psInst, pCommand);
+
+ //
+ // This state is done and the next state should be handled at
+ // the next interrupt.
+ //
+ return;
+ }
+
+ //
+ // The state for the start of a burst read.
+ //
+ case STATE_READ_FIRST:
+ {
+ //
+ // Handle the read first state.
+ //
+ I2CMStateReadFirst(psInst, pCommand);
+
+ //
+ // This state is done and the next state should be handled at
+ // the next interrupt.
+ //
+ return;
+ }
+
+ //
+ // The state for the middle of a burst read.
+ //
+ case STATE_READ_NEXT:
+ {
+ //
+ // Handle the read next state.
+ //
+ I2CMStateReadNext(psInst, pCommand);
+
+ //
+ // This state is done and the next state should be handled at
+ // the next interrupt.
+ //
+ return;
+ }
+
+ //
+ // The state for the end of a burst read.
+ //
+ case STATE_READ_FINAL:
+ {
+ //
+ // Handle the read final state.
+ //
+ I2CMStateReadFinal(psInst, pCommand);
+
+ //
+ // This state is done and the next state should be handled at
+ // the next interrupt.
+ //
+ return;
+ }
+
+ //
+ // The state for a paused read.
+ //
+ case STATE_READ_PAUSE:
+ {
+ //
+ // Handle the read pause state.
+ //
+ I2CMStateReadPause(psInst, pCommand);
+
+ //
+ // This state is done and the next state should be handled at
+ // the next interrupt.
+ //
+ return;
+ }
+
+ //
+ // This state is for the final read of a single or burst read.
+ //
+ case STATE_READ_WAIT:
+ {
+ //
+ // Handle the read wait state.
+ //
+ I2CMStateReadWait(psInst, pCommand);
+
+ //
+ // This state is done and the next state needs to be handled
+ // immediately.
+ //
+ break;
+ }
+
+ //
+ // This state is for providing the transaction complete callback.
+ //
+ case STATE_CALLBACK:
+ {
+ //
+ // Handle the callback state.
+ //
+ I2CMStateCallback(psInst, pCommand, ui32Status);
+
+ //
+ // If an error occurred, this state is done. The completion of
+ // the error handling stop condition above, if issued, will
+ // cause the next state to be processed.
+ //
+ if((ui32Status & (I2C_MCS_ERROR | I2C_MCS_ARBLST)) &&
+ (ui32Status & I2C_MCS_BUSBSY))
+ {
+ return;
+ }
+
+ //
+ // Update the pointer to the current command.
+ //
+ pCommand = &(psInst->pCommands[psInst->ui8ReadPtr]);
+
+ //
+ // This state is done and the next state needs to be handled
+ // immediately.
+ //
+ break;
+ }
+ }
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the I2C master driver.
+//!
+//! \param psInst is a pointer to the I2C master instance data.
+//! \param ui32Base is the base address of the I2C module.
+//! \param ui8Int is the interrupt number for the I2C module.
+//! \param ui8TxDMA is the uDMA channel number used for transmitting data to
+//! the I2C module.
+//! \param ui8RxDMA is the uDMA channel number used for receiving data from
+//! the I2C module.
+//! \param ui32Clock is the clock frequency of the input clock to the I2C
+//! module.
+//!
+//! This function prepares both the I2C master module and driver for operation,
+//! and must be the first I2C master driver function called for each I2C master
+//! instance. It is assumed that the application has enabled the I2C module,
+//! configured the I2C pins, and provided an I2C interrupt handler that calls
+//! I2CMIntHandler().
+//!
+//! The uDMA module cannot be used at present to transmit/receive data, so the
+//! \e ui8TxDMA and \e ui8RxDMA parameters are unused. They are reserved for
+//! future use and should be set to 0xff in order to ensure future
+//! compatibility.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+I2CMInit(tI2CMInstance *psInst, uint32_t ui32Base, uint_fast8_t ui8Int,
+ uint_fast8_t ui8TxDMA, uint_fast8_t ui8RxDMA, uint32_t ui32Clock)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(psInst);
+ ASSERT((ui32Base == I2C0_BASE) || (ui32Base == I2C1_BASE) ||
+ (ui32Base == I2C2_BASE) || (ui32Base == I2C3_BASE) ||
+ (ui32Base == I2C4_BASE) || (ui32Base == I2C5_BASE) ||
+ (ui32Base == I2C6_BASE) || (ui32Base == I2C7_BASE) ||
+ (ui32Base == I2C8_BASE) || (ui32Base == I2C9_BASE));
+ ASSERT(ui8Int);
+ ASSERT(ui32Clock);
+
+ //
+ // Initialize the state structure.
+ //
+ psInst->ui32Base = ui32Base;
+ psInst->ui8Int = ui8Int;
+ psInst->ui8TxDMA = ui8TxDMA;
+ psInst->ui8RxDMA = ui8RxDMA;
+ psInst->ui8State = STATE_IDLE;
+ psInst->ui8ReadPtr = 0;
+ psInst->ui8WritePtr = 0;
+
+ //
+ // Initialize the I2C master module.
+ //
+ MAP_I2CMasterInitExpClk(ui32Base, ui32Clock, true);
+
+ //
+ // Enable the I2C interrupt.
+ //
+ MAP_IntEnable(ui8Int);
+ MAP_I2CMasterIntEnableEx(ui32Base, I2C_MASTER_INT_DATA);
+}
+
+//*****************************************************************************
+//
+//! Sends a command to an I2C device.
+//!
+//! \param psInst is a pointer to the I2C master instance data.
+//! \param ui8Addr is the address of the I2C device to access.
+//! \param pui8WriteData is a pointer to the data buffer to be written.
+//! \param ui16WriteCount is the number of bytes to be written.
+//! \param ui16WriteBatchSize is the number of bytes in each write batch.
+//! \param pui8ReadData is a pointer to the buffer to be filled with the read
+//! data.
+//! \param ui16ReadCount is the number of bytes to be read.
+//! \param ui16ReadBatchSize is the number of bytes to be read in each batch.
+//! \param pfnCallback is the function to be called when the transfer has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function adds an I2C command to the queue of commands to be sent. If
+//! successful, the I2C command is then transferred in the background using the
+//! interrupt handler. When the transfer is complete, the callback function,
+//! if provided, is called in the context of the I2C master interrupt handler.
+//!
+//! The first byte of \e pui8WriteData contains the I2C address of the device
+//! to access, the next \e ui16WriteCount bytes contains the data to be written
+//! to the device. The data read from the device is written into the first
+//! \e ui16ReadCount bytes of \e pui8ReadData. The \e ui16WriteCount or
+//! \e ui16ReadCount parameters can be zero if there are no bytes to be read or
+//! written. The write bytes are sent to the device first, and then the read
+//! bytes are read from the device afterward.
+//!
+//! If \e ui16WriteBatchSize is less than \e ui16WriteCount, the write portion
+//! of the transfer is broken up into as many \e ui16WriteBatchSize batches as
+//! required to write \e ui16WriteCount bytes. After each batch, the callback
+//! function is called with an \b I2CM_STATUS_BATCH_DONE status, and the
+//! transfer is paused (with the I2C bus held). The transfer is resumed when
+//! I2CMTransferResume() is called. This procedure can be used to perform very
+//! large writes without requiring all the data be available at once, at the
+//! expense of tying up the I2C bus for the extended duration of the transfer.
+//!
+//! If \e ui16ReadBatchSize is less than \e ui16ReadCount, the read portion of
+//! the transfer is broken up into as many \e ui16ReadBatchSize batches as
+//! required to read \e ui16ReadCount bytes. After each batch, the callback
+//! function is called with an \b I2CM_STATUS_BATCH_READY status, and the
+//! transfer is paused (with the I2C bus held). The transfer is resumed when
+//! I2CMTransferResume() is called. This procedure can be used to perform very
+//! large reads without requiring a large SRAM buffer, at the expense of tying
+//! up the I2C bus for the extended duration of the transfer.
+//!
+//! \return Returns 1 if the command was successfully added to the queue and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+I2CMCommand(tI2CMInstance *psInst, uint_fast8_t ui8Addr,
+ const uint8_t *pui8WriteData, uint_fast16_t ui16WriteCount,
+ uint_fast16_t ui16WriteBatchSize, uint8_t *pui8ReadData,
+ uint_fast16_t ui16ReadCount, uint_fast16_t ui16ReadBatchSize,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ uint_fast8_t ui8Next, ui8Enabled;
+ tI2CMCommand *pCommand;
+
+ //
+ // Check the arguments.
+ //
+ ASSERT(psInst);
+ ASSERT(pui8WriteData || !ui16WriteCount);
+ ASSERT(!ui16WriteCount || (ui16WriteBatchSize > 0));
+ ASSERT(pui8ReadData || !ui16ReadCount);
+ ASSERT(!ui16ReadCount || (ui16ReadBatchSize > 0));
+
+ //
+ // Disable the I2C interrupt.
+ //
+ if(MAP_IntIsEnabled(psInst->ui8Int))
+ {
+ ui8Enabled = 1;
+ MAP_IntDisable(psInst->ui8Int);
+ }
+ else
+ {
+ ui8Enabled = 0;
+ }
+
+ //
+ // Compute the new value of the write pointer (after this command is added
+ // to the queue).
+ //
+ ui8Next = psInst->ui8WritePtr + 1;
+ if(ui8Next == NUM_I2CM_COMMANDS)
+ {
+ ui8Next = 0;
+ }
+
+ //
+ // Return a failure if the command queue is full.
+ //
+ if(psInst->ui8ReadPtr == ui8Next)
+ {
+ if(ui8Enabled)
+ {
+ MAP_IntEnable(psInst->ui8Int);
+ }
+ return(0);
+ }
+
+ //
+ // Get a pointer to the command structure.
+ //
+ pCommand = &(psInst->pCommands[psInst->ui8WritePtr]);
+
+ //
+ // Fill in the command structure with the details of this command.
+ //
+ pCommand->ui8Addr = ui8Addr;
+ pCommand->pui8WriteData = pui8WriteData;
+ pCommand->ui16WriteCount = ui16WriteCount;
+ pCommand->ui16WriteBatchSize = ui16WriteBatchSize;
+ pCommand->pui8ReadData = pui8ReadData;
+ pCommand->ui16ReadCount = ui16ReadCount;
+ pCommand->ui16ReadBatchSize = ui16ReadBatchSize;
+ pCommand->pfnCallback = pfnCallback;
+ pCommand->pvCallbackData = pvCallbackData;
+
+ //
+ // Update the write pointer.
+ //
+ psInst->ui8WritePtr = ui8Next;
+
+ //
+ // See if the state machine is idle.
+ //
+ if(psInst->ui8State == STATE_IDLE)
+ {
+ //
+ // Generate a fake I2C interrupt, which will commence the I2C transfer.
+ //
+ IntTrigger(psInst->ui8Int);
+ }
+
+ //
+ // Re-enable the I2C master interrupt.
+ //
+ if(ui8Enabled)
+ {
+ MAP_IntEnable(psInst->ui8Int);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Resumes an I2C transfer.
+//!
+//! \param psInst is a pointer to the I2C master instance data.
+//! \param pui8Data is a pointer to the buffer to be used for the next batch of
+//! data.
+//!
+//! This function resumes an I2C transfer that has been paused via the use of
+//! the write or read batch size capability.
+//!
+//! \return Returns 1 if the transfer was resumed and 0 if there was not a
+//! paused transfer to resume.
+//
+//*****************************************************************************
+uint_fast8_t
+I2CMTransferResume(tI2CMInstance *psInst, uint8_t *pui8Data)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(psInst);
+ ASSERT(pui8Data);
+
+ //
+ // Return an error if there is not a paused transfer.
+ //
+ if((psInst->ui8State != STATE_WRITE_PAUSE) &&
+ (psInst->ui8State != STATE_READ_PAUSE))
+ {
+ return(0);
+ }
+
+ //
+ // Save the pointer for the next buffer.
+ //
+ if(psInst->ui8State == STATE_WRITE_PAUSE)
+ {
+ psInst->pCommands[psInst->ui8ReadPtr].pui8WriteData = pui8Data;
+ }
+ else
+ {
+ psInst->pCommands[psInst->ui8ReadPtr].pui8ReadData = pui8Data;
+ }
+
+ //
+ // Trigger the I2C interrupt, resuming the transfer.
+ //
+ IntTrigger(psInst->ui8Int);
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transactions as part of of a
+// read-modify-write operation of 8 bits of data have completed.
+//
+//*****************************************************************************
+static void
+I2CMReadModifyWrite8Callback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tI2CMReadModifyWrite8 *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tI2CMReadModifyWrite8
+ // structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result ina callback to propagate the
+ // error).
+ //
+ if(ui8Status != I2CM_STATUS_SUCCESS)
+ {
+ psInst->ui8State = I2CM_RMW_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the I2C master read-modify-write state
+ // machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // The read portion of the read-modify-write has completed.
+ //
+ case I2CM_RMW_STATE_READ:
+ {
+ //
+ // Modify the register data that was just read.
+ //
+ psInst->pui8Buffer[1] = ((psInst->pui8Buffer[1] &
+ psInst->ui8Mask) | psInst->ui8Value);
+
+ //
+ // Write the data back to the device.
+ //
+ I2CMWrite(psInst->psI2CInst, psInst->ui8Addr, psInst->pui8Buffer,
+ 2, I2CMReadModifyWrite8Callback, psInst);
+
+ //
+ // Move to the wait for write state.
+ //
+ psInst->ui8State = I2CM_RMW_STATE_WRITE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // The write portion of the read-modify-write has completed.
+ //
+ case I2CM_RMW_STATE_WRITE:
+ {
+ //
+ // Move to the idle state.
+ //
+ psInst->ui8State = I2CM_RMW_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == I2CM_RMW_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of 8 bits of data in an I2C device.
+//!
+//! \param psInst is a pointer to the read-modify-write instance data.
+//! \param psI2CInst is a pointer to the I2C master instance data.
+//! \param ui8Addr is the address of the I2C device to access.
+//! \param ui8Reg is the register in the I2C device to access.
+//! \param ui8Mask is the mask indicating the register bits that should be
+//! maintained.
+//! \param ui8Value is the value indicating the new value for the register bits
+//! that are not maintained.
+//! \param pfnCallback is the function to be called when the write has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read-modify-write transaction of 8 bits of data
+//! in an I2C device. The modify portion of the operation is performed by
+//! AND-ing the register value with \e ui8Mask and then OR-ing the result with
+//! \e ui8Value. When the read-modify-write is complete, the callback
+//! function, if provided, is called in the context of the I2C master interrupt
+//! handler.
+//!
+//! If the mask (in \e ui8Mask) is zero, then none of the bits in the current
+//! register value are maintained. In this case, the read portion of the
+//! read-modify-write is bypassed, and the new register value (in \e ui8Value)
+//! is directly written to the I2C device.
+//!
+//! \return Returns 1 if the command was successfully added to the queue and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+I2CMReadModifyWrite8(tI2CMReadModifyWrite8 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8Addr, uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask, uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(psInst);
+ ASSERT(psI2CInst);
+
+ //
+ // Fill in the read-modify-write structure with the details of this
+ // request.
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8Addr;
+ psInst->ui8Mask = ui8Mask;
+ psInst->ui8Value = ui8Value;
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Construct the I2C command to access the requested register.
+ //
+ psInst->pui8Buffer[0] = ui8Reg;
+
+ //
+ // See if this is a write or a read-modify-write.
+ //
+ if(ui8Mask == 0)
+ {
+ //
+ // Set the state to waiting for the write portion of the
+ // read-modify-write.
+ //
+ psInst->ui8State = I2CM_RMW_STATE_WRITE;
+
+ //
+ // Set the new register value in the command buffer.
+ //
+ psInst->pui8Buffer[1] = ui8Value;
+
+ //
+ // Add the write command to the I2C master queue.
+ //
+ if(I2CMWrite(psI2CInst, ui8Addr, psInst->pui8Buffer, 2,
+ I2CMReadModifyWrite8Callback, psInst) == 0)
+ {
+ return(0);
+ }
+ }
+ else
+ {
+ //
+ // Set the state to waiting for the read portion of the
+ // read-modify-write.
+ //
+ psInst->ui8State = I2CM_RMW_STATE_READ;
+
+ //
+ // Add the read command to the I2C master queue.
+ //
+ if(I2CMRead(psI2CInst, ui8Addr, psInst->pui8Buffer, 1,
+ psInst->pui8Buffer + 1, 1, I2CMReadModifyWrite8Callback,
+ psInst) == 0)
+ {
+ return(0);
+ }
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transactions as part of a
+// read-modify-write operation of 16 bits of little-endian data have completed.
+//
+//*****************************************************************************
+static void
+I2CMReadModifyWrite16LECallback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tI2CMReadModifyWrite16 *psInst;
+ uint16_t ui16Value;
+
+ //
+ // Convert the instance data into a pointer to a tI2CMReadModifyWrite16
+ // structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result ina callback to propagate the
+ // error).
+ //
+ if(ui8Status != I2CM_STATUS_SUCCESS)
+ {
+ psInst->ui8State = I2CM_RMW_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the I2C master read-modify-write state
+ // machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // The read portion of the read-modify-write has completed.
+ //
+ case I2CM_RMW_STATE_READ:
+ {
+ //
+ // Modify the register data that was just read.
+ //
+ ui16Value = (psInst->pui8Buffer[2] << 8) | psInst->pui8Buffer[1];
+ ui16Value = (ui16Value & psInst->ui16Mask) | psInst->ui16Value;
+ psInst->pui8Buffer[1] = ui16Value & 0xff;
+ psInst->pui8Buffer[2] = (ui16Value >> 8) & 0xff;
+
+ //
+ // Write the data back to the device.
+ //
+ I2CMWrite(psInst->psI2CInst, psInst->ui8Addr, psInst->pui8Buffer,
+ 3, I2CMReadModifyWrite16LECallback, psInst);
+
+ //
+ // Move to the wait for write state.
+ //
+ psInst->ui8State = I2CM_RMW_STATE_WRITE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // The write portion of the read-modify-write has completed.
+ //
+ case I2CM_RMW_STATE_WRITE:
+ {
+ //
+ // Move to the idle state.
+ //
+ psInst->ui8State = I2CM_RMW_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == I2CM_RMW_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of 16 bits of little-endian data in an I2C
+//! device.
+//!
+//! \param psInst is a pointer to the read-modify-write instance data.
+//! \param psI2CInst is a pointer to the I2C master instance data.
+//! \param ui8Addr is the address of the I2C device to access.
+//! \param ui8Reg is the register in the I2C device to access.
+//! \param ui16Mask is the mask indicating the register bits that should be
+//! maintained.
+//! \param ui16Value is the value indicating the new value for the register
+//! bits that are not maintained.
+//! \param pfnCallback is the function to be called when the write has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read-modify-write transaction of 16 bits of
+//! little-endian data in an I2C device. The modify portion of the operation
+//! is performed by AND-ing the register value with \e ui16Mask and then OR-ing
+//! the result with \e ui16Value. When the read-modify-write is complete, the
+//! callback function, if provided, is called in the context of the I2C master
+//! interrupt handler.
+//!
+//! If the mask (in \e ui16Mask) is zero, then none of the bits in the current
+//! register value are maintained. In this case, the read portion of the
+//! read-modify-write is bypassed, and the new register value (in \e ui16Value)
+//! is directly written to the I2C device.
+//!
+//! \return Returns 1 if the command was successfully added to the queue and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+I2CMReadModifyWrite16LE(tI2CMReadModifyWrite16 *psInst,
+ tI2CMInstance *psI2CInst, uint_fast8_t ui8Addr,
+ uint_fast8_t ui8Reg, uint_fast16_t ui16Mask,
+ uint_fast16_t ui16Value, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(psInst);
+ ASSERT(psI2CInst);
+
+ //
+ // Fill in the read-modify-write structure with the details of this
+ // request.
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8Addr;
+ psInst->ui16Mask = ui16Mask;
+ psInst->ui16Value = ui16Value;
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Construct the I2C command to access the requested register.
+ //
+ psInst->pui8Buffer[0] = ui8Reg;
+
+ //
+ // See if this is a write or a read-modify-write.
+ //
+ if(ui16Mask == 0)
+ {
+ //
+ // Set the state to waiting for the write portion of the
+ // read-modify-write.
+ //
+ psInst->ui8State = I2CM_RMW_STATE_WRITE;
+
+ //
+ // Set the new register value in the command buffer.
+ //
+ psInst->pui8Buffer[1] = ui16Value & 0xff;
+ psInst->pui8Buffer[2] = (ui16Value >> 8) & 0xff;
+
+ //
+ // Add the write command to the I2C master queue.
+ //
+ if(I2CMWrite(psI2CInst, ui8Addr, psInst->pui8Buffer, 3,
+ I2CMReadModifyWrite16LECallback, psInst) == 0)
+ {
+ return(0);
+ }
+ }
+ else
+ {
+ //
+ // Set the state to waiting for the read portion of the
+ // read-modify-write.
+ //
+ psInst->ui8State = I2CM_RMW_STATE_READ;
+
+ //
+ // Add the read command to the I2C master queue.
+ //
+ if(I2CMRead(psI2CInst, ui8Addr, psInst->pui8Buffer, 1,
+ psInst->pui8Buffer + 1, 2, I2CMReadModifyWrite16LECallback,
+ psInst) == 0)
+ {
+ return(0);
+ }
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transactions as part of a
+// write operation of 8-bit data have completed.
+//
+//*****************************************************************************
+static void
+I2CMWrite8Callback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tI2CMWrite8 *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tI2CMWrite8 structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // See if the current batch is done and more data is needed.
+ //
+ if(ui8Status == I2CM_STATUS_BATCH_DONE)
+ {
+ //
+ // Place the next two bytes into the write buffer.
+ //
+ psInst->pui8Buffer[0] = psInst->pui8Data[0];
+ if(psInst->ui16Count > 1)
+ {
+ psInst->pui8Buffer[1] = psInst->pui8Data[1];
+ }
+
+ //
+ // Advance past the next two bytes of the input buffer.
+ //
+ psInst->pui8Data += 2;
+ psInst->ui16Count -= 2;
+
+ //
+ // Resume the batched write.
+ //
+ I2CMTransferResume(psInst->psI2CInst, psInst->pui8Buffer);
+ }
+
+ //
+ // The transfer has completed, or an error has occurred. In both cases,
+ // see if there is a callback function.
+ //
+ else if(psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Performs a write of 8-bit data to an I2C device.
+//!
+//! \param psInst is a pointer to the 8-bit write instance data.
+//! \param psI2CInst is a pointer to the I2C master instance data.
+//! \param ui8Addr is the address of the I2C device to access.
+//! \param ui8Reg is the register in the I2C device to access.
+//! \param pui8Data is a pointer to the register data to be written.
+//! \param ui16Count is the number of register values to be written.
+//! \param pfnCallback is the function to be called when the write has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a write transaction of 8-bit data to an I2C device.
+//!
+//! \return Returns 1 if the command was successfully added to the queue and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+I2CMWrite8(tI2CMWrite8 *psInst, tI2CMInstance *psI2CInst, uint_fast8_t ui8Addr,
+ uint_fast8_t ui8Reg, const uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(psInst);
+ ASSERT(psI2CInst);
+
+ //
+ // Fill in the write structure with the details of this request.
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->pui8Data = pui8Data + 1;
+ psInst->ui16Count = ui16Count - 1;
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Initiate the I2C write to this device.
+ //
+ psInst->pui8Buffer[0] = ui8Reg;
+ psInst->pui8Buffer[1] = pui8Data[0];
+ if(I2CMWriteBatched(psI2CInst, ui8Addr, psInst->pui8Buffer, ui16Count + 1,
+ 2, I2CMWrite8Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so return a failure.
+ //
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transactions as part of a read
+// operation of 16-bit big-endian data have completed.
+//
+//*****************************************************************************
+static void
+I2CMRead16BECallback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tI2CMRead16BE *psInst;
+ uint8_t ui8Temp;
+
+ //
+ // Convert the instance data into a pointer to a tI2CMRead16BE structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // See if the transaction completed successfully.
+ //
+ if(ui8Status == I2CM_STATUS_SUCCESS)
+ {
+ //
+ // Loop through the 16-bit values read from the I2C device.
+ //
+ while(psInst->ui16Count--)
+ {
+ //
+ // Byte swap this value.
+ //
+ ui8Temp = psInst->pui8Data[0];
+ psInst->pui8Data[0] = psInst->pui8Data[1];
+ psInst->pui8Data[1] = ui8Temp;
+
+ //
+ // Skip to the next value.
+ //
+ psInst->pui8Data += 2;
+ }
+ }
+
+ //
+ // See if there is a callback function.
+ //
+ if(psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Performs a read of 16-bit big-endian data from an I2C device.
+//!
+//! \param psInst is a pointer to the 16-bit big-endian read instance data.
+//! \param psI2CInst is a pointer to the I2C master instance data.
+//! \param ui8Addr is the address of the I2C device to access.
+//! \param ui8Reg is the register in the I2C device to access.
+//! \param pui16Data is a pointer to the buffer to be filled with the register
+//! data.
+//! \param ui16Count is the number of 16-bit register values to be read.
+//! \param pfnCallback is the function to be called when the read has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read transaction of 16-bit big-endian data from
+//! an I2C device. The data is provided by the device in big-endian format and
+//! is byte-swapped as it is read from the I2C device, returning the data in
+//! little-endian format.
+//!
+//! \return Returns 1 if the command was successfully added to the queue and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+I2CMRead16BE(tI2CMRead16BE *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8Addr, uint_fast8_t ui8Reg,
+ uint16_t *pui16Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(psInst);
+ ASSERT(psI2CInst);
+
+ //
+ // Fill in the read structure with the details of this request.
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->pui8Data = (uint8_t *)pui16Data;
+ psInst->ui16Count = ui16Count;
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Initiate the I2C write to this device.
+ //
+ psInst->pui8Data[0] = ui8Reg;
+ if(I2CMRead(psI2CInst, ui8Addr, psInst->pui8Data, 1, psInst->pui8Data,
+ ui16Count * 2, I2CMRead16BECallback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so return a failure.
+ //
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transactions as part of a
+// write operation of 16-bit big-endian data have completed.
+//
+//*****************************************************************************
+static void
+I2CMWrite16BECallback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tI2CMWrite16BE *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tI2CMWrite16BE structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // See if the current batch is done and more data is needed.
+ //
+ if(ui8Status == I2CM_STATUS_BATCH_DONE)
+ {
+ //
+ // Place the next two bytes into the write buffer.
+ //
+ psInst->pui8Buffer[0] = psInst->pui8Data[0];
+ if(psInst->ui16Count > 1)
+ {
+ psInst->pui8Buffer[1] = psInst->pui8Data[3];
+ }
+
+ //
+ // Advance past the next two bytes of the input buffer.
+ //
+ psInst->pui8Data += 2;
+ psInst->ui16Count--;
+
+ //
+ // Resume the batched write.
+ //
+ I2CMTransferResume(psInst->psI2CInst, psInst->pui8Buffer);
+ }
+
+ //
+ // The transfer has completed, or an error has occurred. In both cases,
+ // see if there is a callback function.
+ //
+ else if(psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Performs a write of 16-bit big-endian data to an I2C device.
+//!
+//! \param psInst is a pointer to the 16-bit big-endian write instance data.
+//! \param psI2CInst is a pointer to the I2C master instance data.
+//! \param ui8Addr is the address of the I2C device to access.
+//! \param ui8Reg is the register in the I2C device to access.
+//! \param pui16Data is a pointer to the register data to be written.
+//! \param ui16Count is the number of 16-bit register values to be written.
+//! \param pfnCallback is the function to be called when the write has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a write transaction of 16-bit big-endian data to an
+//! I2C device. The data in the buffer is provided in little-endian format and
+//! is byte-swapped as it is being written to the I2C device.
+//!
+//! \return Returns 1 if the command was successfully added to the queue and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+I2CMWrite16BE(tI2CMWrite16BE *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8Addr, uint_fast8_t ui8Reg,
+ const uint16_t *pui16Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Check the arguments.
+ //
+ ASSERT(psInst);
+ ASSERT(psI2CInst);
+
+ //
+ // Fill in the write structure with the details of this request.
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->pui8Data = (const uint8_t *)pui16Data;
+ psInst->ui16Count = ui16Count;
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Initiate the I2C write to this device.
+ //
+ psInst->pui8Buffer[0] = ui8Reg;
+ psInst->pui8Buffer[1] = psInst->pui8Data[1];
+ if(I2CMWriteBatched(psI2CInst, ui8Addr, psInst->pui8Buffer,
+ (ui16Count * 2) + 1, 2, I2CMWrite16BECallback,
+ psInst) == 0)
+ {
+ //
+ // The I2C write failed, so return a failure.
+ //
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/i2cm_drv.h b/sensorlib/i2cm_drv.h new file mode 100644 index 0000000..397c04d --- /dev/null +++ b/sensorlib/i2cm_drv.h @@ -0,0 +1,544 @@ +//*****************************************************************************
+//
+// i2cm_drv.h - Prototypes for the interrupt-driven I2C master driver.
+//
+// Copyright (c) 2012-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_I2CM_DRV_H__
+#define __SENSORLIB_I2CM_DRV_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// A prototype for the callback function used by the I2C master driver.
+//
+//*****************************************************************************
+typedef void (tSensorCallback)(void *pvData, uint_fast8_t ui8Status);
+
+//*****************************************************************************
+//
+// The possible status values that can be returned by the I2C command callback.
+//
+//*****************************************************************************
+#define I2CM_STATUS_SUCCESS 0
+#define I2CM_STATUS_ADDR_NACK 1
+#define I2CM_STATUS_DATA_NACK 2
+#define I2CM_STATUS_ARB_LOST 3
+#define I2CM_STATUS_ERROR 4
+#define I2CM_STATUS_BATCH_DONE 5
+#define I2CM_STATUS_BATCH_READY 6
+
+//*****************************************************************************
+//
+// The maximum number of outstanding commands for each I2C master instance.
+//
+//*****************************************************************************
+#define NUM_I2CM_COMMANDS 10
+
+//*****************************************************************************
+//
+// The structure that defines an I2C master command.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The I2C address of the device being accessed.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The data buffer containing the data to be written.
+ //
+ const uint8_t *pui8WriteData;
+
+ //
+ // The total number of bytes to be written by the command.
+ //
+ uint16_t ui16WriteCount;
+
+ //
+ // The number of bytes to be written in each batch.
+ //
+ uint16_t ui16WriteBatchSize;
+
+ //
+ // The data buffer to store data that has been read.
+ //
+ uint8_t *pui8ReadData;
+
+ //
+ // The total number of bytes to be read by the command.
+ //
+ uint16_t ui16ReadCount;
+
+ //
+ // The number of bytes to be read in each chuck.
+ //
+ uint16_t ui16ReadBatchSize;
+
+ //
+ // The function that is called when this command has been transferred.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The pointer provided to the callback function.
+ //
+ void *pvCallbackData;
+}
+tI2CMCommand;
+
+//*****************************************************************************
+//
+// The structure that contains the state of an I2C master instance.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The base address of the I2C module.
+ //
+ uint32_t ui32Base;
+
+ //
+ // The interrupt number associated with the I2C module.
+ //
+ uint8_t ui8Int;
+
+ //
+ // The uDMA channel used to write data to the I2C module.
+ //
+ uint8_t ui8TxDMA;
+
+ //
+ // The uDMA channel used to read data from the I2C module.
+ //
+ uint8_t ui8RxDMA;
+
+ //
+ // The current state of the I2C master driver.
+ //
+ uint8_t ui8State;
+
+ //
+ // The offset of the next command to be read. The buffer is empty when
+ // this value is equal to the write pointer.
+ //
+ uint8_t ui8ReadPtr;
+
+ //
+ // The offset of the next space in the buffer to write a command. The
+ // buffer is full if this value is one less than the read pointer.
+ //
+ uint8_t ui8WritePtr;
+
+ //
+ // The index into the data buffer of the next byte to be transferred.
+ //
+ uint16_t ui16Index;
+
+ //
+ // An array of commands queued up to be sent via the I2C module.
+ //
+ tI2CMCommand pCommands[NUM_I2CM_COMMANDS];
+}
+tI2CMInstance;
+
+//*****************************************************************************
+//
+// The structure that contains the state of an I2C read-modify-write request of
+// 8 bits of data.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // A pointer to the I2C master interface instance used for the
+ // read-modify-write request.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The buffer used for the I2C transfers.
+ //
+ uint8_t pui8Buffer[4];
+
+ //
+ // The current state of the I2C read-modify-write state machine.
+ //
+ uint8_t ui8State;
+
+ //
+ // The I2C address of the device being accessed.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The value to AND with the I2C register data.
+ //
+ uint8_t ui8Mask;
+
+ //
+ // The value to OR with the I2C register data.
+ //
+ uint8_t ui8Value;
+
+ //
+ // The function that is called when the read-modify-write has been
+ // completed.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The pointer provided to the callback function.
+ //
+ void *pvCallbackData;
+}
+tI2CMReadModifyWrite8;
+
+//*****************************************************************************
+//
+// The structure that contains the state of an I2C read-modify-write request of
+// 16 bits of data.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // A pointer to the I2C master interface instance used for the
+ // read-modify-write request.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The buffer used for the I2C transfers.
+ //
+ uint8_t pui8Buffer[4];
+
+ //
+ // The current state of the I2C read-modify-write state machine.
+ //
+ uint8_t ui8State;
+
+ //
+ // The I2C address of the device being accessed.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The value to AND with the I2C register data.
+ //
+ uint16_t ui16Mask;
+
+ //
+ // The value to OR with the I2C register data.
+ //
+ uint16_t ui16Value;
+
+ //
+ // The function that is called when the read-modify-write has been
+ // completed.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The pointer provided to the callback function.
+ //
+ void *pvCallbackData;
+}
+tI2CMReadModifyWrite16;
+
+//*****************************************************************************
+//
+// The structure that contains the state of an I2C write request of 8-bit data.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // A pointer to the I2C master interface instance used for the write
+ // request.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The buffer used for the I2C transfers.
+ //
+ uint8_t pui8Buffer[2];
+
+ //
+ // The number of values to write to the I2C device.
+ //
+ uint16_t ui16Count;
+
+ //
+ // A pointer to the buffer containing the data to write to the I2C device.
+ //
+ const uint8_t *pui8Data;
+
+ //
+ // The function that is called when the write has been completed.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The pointer provided to the callback function.
+ //
+ void *pvCallbackData;
+}
+tI2CMWrite8;
+
+//*****************************************************************************
+//
+// The structure that contains the state of an I2C read request of 16-bit data
+// from a big-endian device.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // A pointer to the I2C master interface instance used for the read
+ // request.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // A pointer to the buffer containing the data read from the I2C device.
+ //
+ uint8_t *pui8Data;
+
+ //
+ // The number of 16-bit values to read from the I2C device.
+ //
+ uint16_t ui16Count;
+
+ //
+ // The function that is called when the read has been completed.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The pointer provided to the callback function.
+ //
+ void *pvCallbackData;
+}
+tI2CMRead16BE;
+
+//*****************************************************************************
+//
+// The structure that contains the state of an I2C write request of 16-bit data
+// to a big-endian device.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // A pointer to the I2C master interface instance used for the write
+ // request.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The buffer used for the I2C transfers.
+ //
+ uint8_t pui8Buffer[2];
+
+ //
+ // The number of 16-bit values to write to the I2C device.
+ //
+ uint16_t ui16Count;
+
+ //
+ // A pointer to the buffer containing the data to write to the I2C device.
+ //
+ const uint8_t *pui8Data;
+
+ //
+ // The function that is called when the write has been completed.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The pointer provided to the callback function.
+ //
+ void *pvCallbackData;
+}
+tI2CMWrite16BE;
+
+//*****************************************************************************
+//
+// Prototypes.
+//
+//*****************************************************************************
+extern void I2CMIntHandler(tI2CMInstance *psInst);
+extern void I2CMInit(tI2CMInstance *psInst, uint32_t ui32Base,
+ uint_fast8_t ui8Int, uint_fast8_t ui8TxDMA,
+ uint_fast8_t ui8RxDMA, uint32_t ui32Clock);
+extern uint_fast8_t I2CMCommand(tI2CMInstance *psInst, uint_fast8_t ui8Addr,
+ const uint8_t *pui8WriteData,
+ uint_fast16_t ui16WriteCount,
+ uint_fast16_t ui16WriteBatchSize,
+ uint8_t *pui8ReadData,
+ uint_fast16_t ui16ReadCount,
+ uint_fast16_t ui16ReadBatchSize,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t I2CMTransferResume(tI2CMInstance *psInst,
+ uint8_t *pui8Data);
+extern uint_fast8_t I2CMReadModifyWrite8(tI2CMReadModifyWrite8 *psInst,
+ tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8Addr,
+ uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask,
+ uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t I2CMReadModifyWrite16LE(tI2CMReadModifyWrite16 *psInst,
+ tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8Addr,
+ uint_fast8_t ui8Reg,
+ uint_fast16_t ui16Mask,
+ uint_fast16_t ui16Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t I2CMWrite8(tI2CMWrite8 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8Addr, uint_fast8_t ui8Reg,
+ const uint8_t *pui8Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t I2CMRead16BE(tI2CMRead16BE *psInst,
+ tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8Addr, uint_fast8_t ui8Reg,
+ uint16_t *pui16Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t I2CMWrite16BE(tI2CMWrite16BE *psInst,
+ tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8Addr, uint_fast8_t ui8Reg,
+ const uint16_t *pui16Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+
+//*****************************************************************************
+//
+// A convenience wrapper around I2CMCommand to perform a write.
+//
+//*****************************************************************************
+inline uint_fast8_t
+I2CMWrite(tI2CMInstance *psInst, uint_fast8_t ui8Addr, const uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ return(I2CMCommand(psInst, ui8Addr, pui8Data, ui16Count, ui16Count, 0, 0,
+ 0, pfnCallback, pvCallbackData));
+}
+
+//*****************************************************************************
+//
+// A convenience wrapper around I2CMCommand to perform a read.
+//
+//*****************************************************************************
+inline uint_fast8_t
+I2CMRead(tI2CMInstance *psInst, uint_fast8_t ui8Addr,
+ const uint8_t *pui8WriteData, uint_fast16_t ui16WriteCount,
+ uint8_t *pui8ReadData, uint_fast16_t ui16ReadCount,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ return(I2CMCommand(psInst, ui8Addr, pui8WriteData, ui16WriteCount,
+ ui16WriteCount, pui8ReadData, ui16ReadCount,
+ ui16ReadCount, pfnCallback, pvCallbackData));
+}
+
+//*****************************************************************************
+//
+// A convenience wrapper around I2CMCommand to perform a batched write.
+//
+//*****************************************************************************
+inline uint_fast8_t
+I2CMWriteBatched(tI2CMInstance *psInst, uint_fast8_t ui8Addr,
+ const uint8_t *pui8Data, uint_fast16_t ui16Count,
+ uint_fast16_t ui16BatchSize, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ return(I2CMCommand(psInst, ui8Addr, pui8Data, ui16Count, ui16BatchSize, 0,
+ 0, 0, pfnCallback, pvCallbackData));
+}
+
+//*****************************************************************************
+//
+// A convenience wrapper around I2CMCommand to perform a batched read.
+//
+//*****************************************************************************
+inline uint_fast8_t
+I2CMReadBatched(tI2CMInstance *psInst, uint_fast8_t ui8Addr,
+ const uint8_t *pui8WriteData, uint_fast16_t ui16WriteCount,
+ uint_fast16_t ui16WriteBatchSize, uint8_t *pui8ReadData,
+ uint_fast16_t ui16ReadCount, uint_fast16_t ui16ReadBatchSize,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ return(I2CMCommand(psInst, ui8Addr, pui8WriteData, ui16WriteCount,
+ ui16WriteBatchSize, pui8ReadData, ui16ReadCount,
+ ui16ReadBatchSize, pfnCallback, pvCallbackData));
+}
+
+//*****************************************************************************
+//
+// A 16-bit big-endian read-modify-write in terms of the little-endian version.
+//
+//*****************************************************************************
+inline uint_fast8_t
+I2CMReadModifyWrite16BE(tI2CMReadModifyWrite16 *psInst,
+ tI2CMInstance *psI2CInst, uint_fast8_t ui8Addr,
+ uint_fast8_t ui8Reg, uint_fast16_t ui16Mask,
+ uint_fast16_t ui16Value, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ return(I2CMReadModifyWrite16LE(psInst, psI2CInst, ui8Addr, ui8Reg,
+ (((ui16Mask & 0xff00) >> 8) |
+ ((ui16Mask & 0x00ff) << 8)),
+ (((ui16Value & 0xff00) >> 8) |
+ ((ui16Value & 0x00ff) << 8)),
+ pfnCallback, pvCallbackData));
+}
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_I2CM_DRV_H__
diff --git a/sensorlib/isl29023.c b/sensorlib/isl29023.c new file mode 100644 index 0000000..313ced9 --- /dev/null +++ b/sensorlib/isl29023.c @@ -0,0 +1,668 @@ +//*****************************************************************************
+//
+// isl29023.c - Driver for the ISL29023 Light Sensor
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sensorlib/hw_isl29023.h"
+#include "sensorlib/i2cm_drv.h"
+#include "sensorlib/isl29023.h"
+
+//*****************************************************************************
+//
+//! \addtogroup isl29023_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// Range setting to floating point range value lookup table
+//
+//*****************************************************************************
+const float g_fRangeLookup[4] =
+{
+ 1000.0,
+ 4000.0,
+ 16000.0,
+ 64000.0
+};
+
+//*****************************************************************************
+//
+// Resolution setting to floating point resolution value lookup table
+//
+//*****************************************************************************
+const float g_fResolutionLookup[4] =
+{
+ 65536.0,
+ 4096.0,
+ 256.0,
+ 16.0
+};
+
+//*****************************************************************************
+//
+// Beta value lookup based on datasheet typical values for DATA_IR1, DATA_IR2,
+// DATA_IR3, DATA_IR4. These should be reasonable for 16 bit conversions.
+// However, Beta changes with resolution and background IR conditions.
+//
+//*****************************************************************************
+const float g_fBetaLookup[4] =
+{
+ 95.238,
+ 23.810,
+ 5.952,
+ 1.486
+};
+
+//*****************************************************************************
+//
+// The states of the ISL29023 state machine.
+//
+//*****************************************************************************
+#define ISL29023_STATE_IDLE 0
+#define ISL29023_STATE_INIT 1
+#define ISL29023_STATE_READ 2
+#define ISL29023_STATE_WRITE 3
+#define ISL29023_STATE_RMW 4
+#define ISL29023_STATE_READ_DATA 5
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transations to/from the
+// ISL29023 have completed.
+//
+//*****************************************************************************
+static void
+ISL29023Callback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tISL29023 *psInst;
+ uint8_t *pui8Data;
+
+ //
+ // Convert the instance data into a pointer to a tBMA180 structure.
+ //
+ psInst = (tISL29023 *)pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result in a callback to propagate the
+ // error).
+ //
+ if(ui8Status != I2CM_STATUS_SUCCESS)
+ {
+ psInst->ui8State = ISL29023_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the ISL29023 state machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // All states that trivially transition to IDLE, and all unknown
+ // states.
+ //
+ case ISL29023_STATE_INIT:
+ case ISL29023_STATE_READ:
+ case ISL29023_STATE_READ_DATA:
+ default:
+ {
+ //
+ // A register operation is complete. Return to IDLE state
+ // the value read from the register is in the pui8Data buffer and
+ // can be accessed directly by the calling application after
+ // receiving the callback.
+ //
+ psInst->ui8State = ISL29023_STATE_IDLE;
+ break;
+ }
+
+ //
+ // A write to the ISL29023 control and config registers is complete.
+ //
+ case ISL29023_STATE_WRITE:
+ {
+ //
+ // Set the range and resolution to the new values. If the register
+ // was not modified, the values will be the same so this has no
+ // effect.
+ //
+ psInst->ui8Range = psInst->ui8NewRange;
+ psInst->ui8Resolution = psInst->ui8NewResolution;
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = ISL29023_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // A read modify write operation has just completed.
+ //
+ case ISL29023_STATE_RMW:
+ {
+ //
+ // Check if the register that was written contained the range or
+ // resolution data that we need to track.
+ //
+ pui8Data = psInst->uCommand.sReadModifyWriteState.pui8Buffer;
+ if((pui8Data[0] == ISL29023_O_CMD_II) &&
+ (ui8Status == I2CM_STATUS_SUCCESS))
+ {
+ //
+ // Store the latest range and resolution settings
+ //
+ psInst->ui8Range = ((pui8Data[1] & ISL29023_CMD_II_RANGE_M) >>
+ ISL29023_CMD_II_RANGE_S);
+ psInst->ui8Resolution = ((pui8Data[1] &
+ ISL29023_CMD_II_ADC_RES_M) >>
+ ISL29023_CMD_II_ADC_RES_S);
+ }
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = ISL29023_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == ISL29023_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the ISL29023 driver.
+//!
+//! \param psInst is a pointer to the ISL29023 instance data.
+//! \param psI2CInst is a pointer to the I2C driver instance data.
+//! \param ui8I2CAddr is the I2C address of the ISL29023 device.
+//! \param pfnCallback is the function to be called when the initialization has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initializes the ISL29023 driver, preparing it for operation.
+//! This function also asserts a reset signal to the ISL29023 to clear any
+//! previous configuration data.
+//!
+//! \return Returns 1 if the ISL29023 driver was successfully initialized and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+ISL29023Init(tISL29023 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Initialize the ISL29023 instance structure
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8I2CAddr;
+ psInst->ui8State = ISL29023_STATE_INIT;
+ psInst->ui8Range = ISL29023_CMD_II_RANGE_1K >> ISL29023_CMD_II_RANGE_S;
+ psInst->ui8NewRange = ISL29023_CMD_II_RANGE_1K >> ISL29023_CMD_II_RANGE_S;
+ psInst->ui8Resolution = (ISL29023_CMD_II_ADC_RES_16 >>
+ ISL29023_CMD_II_ADC_RES_S);
+ psInst->ui8NewResolution = (ISL29023_CMD_II_ADC_RES_16 >>
+ ISL29023_CMD_II_ADC_RES_S);
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Put the device into power down mode.
+ //
+ psInst->pui8Data[0] = ISL29023_O_CMD_I;
+ psInst->pui8Data[1] = ISL29023_CMD_I_OP_MODE_POWER_DOWN;
+ if(I2CMWrite(psInst->psI2CInst, psInst->ui8Addr, psInst->pui8Data, 2,
+ ISL29023Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = ISL29023_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads data from ISL29023 registers.
+//!
+//! \param psInst is a pointer to the ISL29023 instance data.
+//! \param ui8Reg is the first register to read.
+//! \param pui8Data is a pointer to the location to store the data that is
+//! read.
+//! \param ui16Count is the number of data bytes to read.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function reads a sequence of data values from consecutive registers in
+//! the ISL29023.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+ISL29023Read(tISL29023 *psInst, uint_fast8_t ui8Reg, uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the ISL29023 driver is not idle (in other words,
+ // there is already an outstanding request to the ISL29023).
+ //
+ if(psInst->ui8State != ISL29023_STATE_IDLE)
+ {
+ return(0);
+ }
+ //
+ // Store the Callback information
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // set ISL29023 state
+ //
+ psInst->ui8State = ISL29023_STATE_READ;
+
+ //
+ // Load the command buffer with the appropriate register information
+ //
+ psInst->uCommand.pui8Buffer[0] = ui8Reg;
+
+ //
+ // Start the I2CM read and return indication.
+ //
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, pui8Data, ui16Count,
+ ISL29023Callback, psInst) == 0)
+ {
+ psInst->ui8State = ISL29023_STATE_IDLE;
+ return(0);
+ }
+
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Write register data to the ISL29023.
+//!
+//! \param psInst is a pointer to the ISL29023 instance data.
+//! \param ui8Reg is the first register to write.
+//! \param pui8Data is a pointer to the data to write.
+//! \param ui16Count is the number of data bytes to write.
+//! \param pfnCallback is the function to be called when the data has been
+//! written (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function writes a sequence of data values to consecutive registers in
+//! the ISL29023. The first byte of the \e pui8Data buffer contains the value
+//! to be written into the \e ui8Reg register, the second value contains the
+//! data to be written into the next register, and so on.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+ISL29023Write(tISL29023 *psInst, uint_fast8_t ui8Reg, uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the ISL29023 driver is not idle (in other words,
+ // there is already an outstanding request to the ISL29023).
+ //
+ if(psInst->ui8State != ISL29023_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // See if the CMD_II register is being written.
+ //
+ if((ui8Reg <= ISL29023_O_CMD_II) &&
+ ((ui8Reg + ui16Count) > ISL29023_O_CMD_II))
+ {
+ //
+ // Extract the range and resolution from the CMD_II register value.
+ //
+ psInst->ui8NewRange = ((pui8Data[ui8Reg - ISL29023_O_CMD_II] &
+ ISL29023_CMD_II_RANGE_M) >>
+ ISL29023_CMD_II_RANGE_S);
+ psInst->ui8NewResolution = ((pui8Data[ui8Reg - ISL29023_O_CMD_II] &
+ ISL29023_CMD_II_ADC_RES_M) >>
+ ISL29023_CMD_II_ADC_RES_S);
+ }
+
+ //
+ // Move state machine to the write state
+ //
+ psInst->ui8State = ISL29023_STATE_WRITE;
+
+ //
+ // Add the i2c address and the register offset to the data buffer.
+ //
+ if(I2CMWrite8(&(psInst->uCommand.sWriteState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui8Data, ui16Count,
+ ISL29023Callback, psInst) == 0)
+ {
+ //
+ // I2C write failed, move to idle state and return the failure.
+ //
+ psInst->ui8State = ISL29023_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of an ISL29023 register.
+//!
+//! \param psInst is a pointer to the ISL29023 instance data.
+//! \param ui8Reg is the register to modify.
+//! \param ui8Mask is the bit mask that is ANDed with the current register
+//! value.
+//! \param ui8Value is the bit mask that is ORed with the result of the AND
+//! operation.
+//! \param pfnCallback is the function to be called when the data has been
+//! changed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function changes the value of a register in the ISL29023 via a
+//! read-modify-write operation, allowing one of the fields to be changed
+//! without disturbing the other fields. The \e ui8Reg register is read, ANDed
+//! with \e ui8Mask, ORed with \e ui8Value, and then written back to the
+//! ISL29023.
+//!
+//! \return Returns 1 if the read-modify-write was successfully started and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+ISL29023ReadModifyWrite(tISL29023 *psInst, uint_fast8_t ui8Reg,
+ uint8_t ui8Mask, uint8_t ui8Value,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the ISL29023 driver is not in the idle state.
+ //
+ if(psInst->ui8State != ISL29023_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // set ISL29023 state
+ //
+ psInst->ui8State = ISL29023_STATE_RMW;
+
+ //
+ // Submit the read-modify-write request to the ISL29023.
+ //
+ if(I2CMReadModifyWrite8(&(psInst->uCommand.sReadModifyWriteState),
+ psInst->psI2CInst, psInst->ui8Addr, ui8Reg,
+ ui8Mask, ui8Value, ISL29023Callback, psInst) == 0)
+ {
+ //
+ // The I2C read-modify-write failed, so move to the idle state and
+ // return a failure.
+ //
+ psInst->ui8State = ISL29023_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads the light data from the ISL29023.
+//!
+//! \param psInst is a pointer to the ISL29023 instance data.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read of the ISL29023 data registers. When the
+//! read has completed (as indicated by calling the callback function), the new
+//! readings can be obtained via:
+//!
+//! - ISL29023DataLightVisibleGetRaw()
+//! - ISL29023DataLightVisibleGetFloat()
+//! - ISL29023DataLightIRGetRaw()
+//! - ISL29023DataLightIRGetFloat()
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+ISL29023DataRead(tISL29023 *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the ISL29023 driver is not idle (in other words,
+ // there is already an outstanding request to the ISL29023).
+ //
+ if(psInst->ui8State != ISL29023_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Store the Callback information
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // set ISL29023 state
+ //
+ psInst->ui8State = ISL29023_STATE_READ_DATA;
+
+ psInst->uCommand.pui8Buffer[0] = ISL29023_O_DATA_OUT_LSB;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 2,
+ ISL29023Callback, psInst) == 0)
+ {
+ //
+ // The I2C read failed, so move to the idle state and return a failure.
+ //
+ psInst->ui8State = ISL29023_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Gets the raw measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the ISL29023 instance data.
+//! \param pui16Visible is a pointer to the value into which the raw light data
+//! is stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+ISL29023DataLightVisibleGetRaw(tISL29023 *psInst, uint16_t *pui16Visible)
+{
+ //
+ // Return the raw light value.
+ //
+ *pui16Visible = (psInst->pui8Data[1] << 8) | psInst->pui8Data[0];
+}
+
+//*****************************************************************************
+//
+//! Gets the measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the ISL29023 instance data.
+//! \param pfVisibleLight is a pointer to the value into which the light data
+//! is stored as floating point lux.
+//!
+//! This function returns the light data from the most recent data read,
+//! converted into lux.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+ISL29023DataLightVisibleGetFloat(tISL29023 *psInst, float *pfVisibleLight)
+{
+ uint16_t ui16Light;
+ float fRange, fResolution;
+
+ //
+ // Get the raw light data from the instance structure
+ //
+ ISL29023DataLightVisibleGetRaw(psInst, &ui16Light);
+
+ //
+ // Get the floating point values for range and resolution from the lookup.
+ //
+ fRange = g_fRangeLookup[psInst->ui8Range];
+ fResolution = g_fResolutionLookup[psInst->ui8Resolution];
+
+ //
+ // Calculate light reading in lux.
+ //
+ *pfVisibleLight = ((float)ui16Light) * (fRange / fResolution);
+}
+
+//*****************************************************************************
+//
+//! Gets the raw measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the ISL29023 instance data.
+//! \param pui16IR is a pointer to the value into which the raw IR data is
+//! stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+ISL29023DataLightIRGetRaw(tISL29023 *psInst, uint16_t *pui16IR)
+{
+ //
+ // Return the raw light value.
+ //
+ *pui16IR = (psInst->pui8Data[1] << 8) | psInst->pui8Data[0];
+}
+
+//*****************************************************************************
+//
+//! Gets the measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the ISL29023 instance data.
+//! \param pfIR is a pointer to the value into which the IR data is stored as
+//! floating point lux.
+//!
+//! This function returns the IR data from the most recent data read, converted
+//! into lux.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+ISL29023DataLightIRGetFloat(tISL29023 *psInst, float *pfIR)
+{
+ uint16_t i16IR;
+
+ ISL29023DataLightIRGetRaw(psInst, &i16IR);
+
+ *pfIR = ((float) i16IR) / g_fBetaLookup[psInst->ui8Range];
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/isl29023.h b/sensorlib/isl29023.h new file mode 100644 index 0000000..184c702 --- /dev/null +++ b/sensorlib/isl29023.h @@ -0,0 +1,166 @@ +//*****************************************************************************
+//
+// isl29023.h - Prototypes for the ISL29023 light sensor driver.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_ISL29023_H__
+#define __SENSORLIB_ISL29023_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the ISL29023 driver.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The pointer to the I2C master interface instance used to communicate
+ // with the ISL29023.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The I2C address of the ISL29023.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The state of the state machine used while accessing the ISL29023.
+ //
+ uint8_t ui8State;
+
+ //
+ // The data buffer used for sending/receiving data to/from the ISL29023.
+ //
+ uint8_t pui8Data[4];
+
+ //
+ // Instance copy of the range setting. Used in GetFloat functions
+ //
+ uint8_t ui8Range;
+
+ //
+ // The new range, which is used when a register write succeeds.
+ //
+ uint8_t ui8NewRange;
+
+ //
+ // Instance copy of the resolution setting. Used in GetFloat function.
+ //
+ uint8_t ui8Resolution;
+
+ //
+ // The new resolution, which is used when a register write succeeds.
+ //
+ uint8_t ui8NewResolution;
+
+ //
+ // The function that is called when the current request has completed
+ // processing.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The pointer provided to the callback function.
+ //
+ void *pvCallbackData;
+
+ //
+ // A union of structures that are used for read, write and
+ // read-modify-write operations. Since only one operation can be active at
+ // a time, it is safe to re-use the memory in this manner.
+ //
+ union
+ {
+ //
+ // A buffer used to store the write portion of a register read.
+ //
+ uint8_t pui8Buffer[3];
+
+ //
+ // The write state used to write register values.
+ //
+ tI2CMWrite8 sWriteState;
+
+ //
+ // The read-modify-write state used to modify register values.
+ //
+ tI2CMReadModifyWrite8 sReadModifyWriteState;
+ }
+ uCommand;
+}
+tISL29023;
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern uint_fast8_t ISL29023Init(tISL29023 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t ISL29023Read(tISL29023 *psInst, uint_fast8_t ui8Reg,
+ uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t ISL29023Write(tISL29023 *psInst, uint_fast8_t ui8Reg,
+ uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t ISL29023ReadModifyWrite(tISL29023 *psInst,
+ uint_fast8_t ui8Reg,
+ uint8_t ui8Mask, uint8_t ui8Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t ISL29023DataRead(tISL29023 *psInst,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern void ISL29023DataLightVisibleGetRaw(tISL29023 *psInst,
+ uint16_t *pui16Visible);
+extern void ISL29023DataLightVisibleGetFloat(tISL29023 *psInst,
+ float *pfVisible);
+extern void ISL29023DataLightIRGetRaw(tISL29023 *psInst, uint16_t *pui16IR);
+extern void ISL29023DataLightIRGetFloat(tISL29023 *psInst, float *pfIR);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_ISL29023_H__
+
diff --git a/sensorlib/kxti9.c b/sensorlib/kxti9.c new file mode 100644 index 0000000..38de17b --- /dev/null +++ b/sensorlib/kxti9.c @@ -0,0 +1,777 @@ +//*****************************************************************************
+//
+// kxti9.c - Driver for the KXTI9 accelerometer.
+//
+// Copyright (c) 2012-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <stdint.h>
+#include "sensorlib/hw_kxti9.h"
+#include "sensorlib/i2cm_drv.h"
+#include "sensorlib/kxti9.h"
+
+//*****************************************************************************
+//
+//! \addtogroup kxti9_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The states of the KXTI9 state machine.
+//
+//*****************************************************************************
+#define KXTI9_STATE_IDLE 0 // State machine is idle
+#define KXTI9_STATE_INIT_RES 1 // Waiting for intialization
+#define KXTI9_STATE_INIT_WAIT 2 // Waiting for reset to complete
+#define KXTI9_STATE_LAST 3 // Last state of init
+#define KXTI9_STATE_READ 4 // Waiting for read
+#define KXTI9_STATE_WRITE 5 // Waiting for write
+#define KXTI9_STATE_RMW 6 // Waiting for read-modify-write
+
+//*****************************************************************************
+//
+// The factors used to convert the 8-bit acceleration readings from the KXTI9
+// into floating point values in m/s^2.
+//
+//*****************************************************************************
+static const float g_fAccelFactors8[] =
+{
+ (2.0 * 9.81) / 128.0,
+ (4.0 * 9.81) / 128.0,
+ (8.0 * 9.81) / 128.0
+};
+
+//*****************************************************************************
+//
+// The factors used to convert the 12-bit acceleration readings from the KXTI9
+// into floating point values in m/s^2.
+//
+//*****************************************************************************
+static const float g_fAccelFactors12[] =
+{
+ (2.0 * 9.81) / 2048.0,
+ (4.0 * 9.81) / 2048.0,
+ (8.0 * 9.81) / 2048.0
+};
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transations to/from the KXTI9
+// have completed.
+//
+//*****************************************************************************
+static void
+KXTI9Callback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tKXTI9 *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tKXTI9 structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result in a callback to propagate the
+ // error).
+ //
+ if((ui8Status != I2CM_STATUS_SUCCESS) &&
+ (psInst->ui8State != KXTI9_STATE_INIT_WAIT))
+ {
+ psInst->ui8State = KXTI9_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the KXTI9 state machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // All states that trivially transition to IDLE, and all unknown
+ // states.
+ //
+ case KXTI9_STATE_LAST:
+ case KXTI9_STATE_READ:
+ default:
+ {
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = KXTI9_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ case KXTI9_STATE_INIT_RES:
+ {
+ //
+ // Try to read back to determine if reset is done. We expect to see
+ // a NAK.
+ //
+ psInst->uCommand.pui8Buffer[0] = KXTI9_O_CTRL3;
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 1,
+ KXTI9Callback, psInst);
+
+ psInst->ui8State = KXTI9_STATE_INIT_WAIT;
+ break;
+ }
+
+ case KXTI9_STATE_INIT_WAIT:
+ {
+ //
+ // Check to see if there was finally an ACK.
+ //
+ if(ui8Status != I2CM_STATUS_SUCCESS)
+ {
+ //
+ // Read again.
+ //
+ psInst->uCommand.pui8Buffer[0] = KXTI9_O_CTRL3;
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 1,
+ KXTI9Callback, psInst);
+ }
+ else
+ {
+ //
+ // Check the read data to make sure it jibes.
+ //
+ if(psInst->pui8Data[0] == 0x4d)
+ {
+ //
+ // Device is out of reset, enable the device.
+ //
+ psInst->uCommand.pui8Buffer[0] = KXTI9_O_CTRL1;
+ psInst->uCommand.pui8Buffer[1] = KXTI9_CTRL1_PC1;
+ I2CMWrite(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 2, KXTI9Callback,
+ psInst);
+ }
+ else
+ {
+ ui8Status = I2CM_STATUS_ERROR;
+ }
+
+ //
+ // This is the last init write.
+ //
+ psInst->ui8State = KXTI9_STATE_LAST;
+ }
+ break;
+ }
+
+ case KXTI9_STATE_WRITE:
+ {
+ //
+ // Set the accelerometer range and resolution to the new value.
+ // If the register was not modified, the values will be the same so
+ // this has no effect.
+ //
+ psInst->ui8Resolution = psInst->ui8NewResolution;
+ psInst->ui8Range = psInst->ui8NewRange;
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = KXTI9_STATE_IDLE;
+ break;
+ }
+
+ case KXTI9_STATE_RMW:
+ {
+ //
+ // See if the CTRL3 register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ KXTI9_O_CTRL3)
+ {
+ //
+ // See if a soft reset has been issued.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ KXTI9_CTRL3_SRST)
+ {
+ //
+ // Default range setting is +/- 2 g
+ //
+ psInst->ui8Range = 0;
+ psInst->ui8NewRange = 0;
+
+ //
+ // Default resolution is 8-bit.
+ //
+ psInst->ui8Resolution = 0;
+ psInst->ui8NewResolution = 0;
+ }
+ }
+
+ //
+ // See if the CTRL1 register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ KXTI9_O_CTRL1)
+ {
+ //
+ // Extract the range and resolution from the register value.
+ //
+ psInst->ui8Range =
+ ((psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ KXTI9_CTRL1_GSEL_M) >> KXTI9_CTRL1_GSEL_S);
+ psInst->ui8Resolution =
+ ((psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ KXTI9_CTRL1_RES) >> 6);
+ }
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = KXTI9_STATE_IDLE;
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == KXTI9_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //s
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the KXTI9 driver.
+//!
+//! \param psInst is a pointer to the KXTI9 instance data.
+//! \param psI2CInst is a pointer to the I2C master driver instance data.
+//! \param ui8I2CAddr is the I2C address of the KXTI9 device.
+//! \param pfnCallback is the function to be called when the initialization has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initializes the KXTI9 driver, preparing it for operation.
+//!
+//! \return Returns 1 if the KXTI9 driver was successfully initialized and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+KXTI9Init(tKXTI9 *psInst, tI2CMInstance *psI2CInst, uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Initialize the KXTI9 instance structure.
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8I2CAddr;
+ psInst->ui8State = KXTI9_STATE_INIT_RES;
+ psInst->ui8Resolution = 0;
+ psInst->ui8NewResolution = 0;
+ psInst->ui8Range = KXTI9_CTRL1_GSEL_2G >> KXTI9_CTRL1_GSEL_S;
+ psInst->ui8NewRange = KXTI9_CTRL1_GSEL_2G >> KXTI9_CTRL1_GSEL_S;
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Write the EE_W bit of CTRL_REG0 (allowing the configuration registers to
+ // be modified).
+ //
+ psInst->pui8Data[0] = KXTI9_O_CTRL3;
+ psInst->pui8Data[1] = KXTI9_CTRL3_SRST;
+ if(I2CMWrite(psInst->psI2CInst, ui8I2CAddr, psInst->pui8Data, 2,
+ KXTI9Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = KXTI9_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads data from KXTI9 registers.
+//!
+//! \param psInst is a pointer to the KXTI9 instance data.
+//! \param ui8Reg is the first register to read.
+//! \param pui8Data is a pointer to the location to store the data that is
+//! read.
+//! \param ui16Count is the number of data bytes to read.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function reads a sequence of data values from consecutive registers in
+//! the KXTI9.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+KXTI9Read(tKXTI9 *psInst, uint_fast8_t ui8Reg, uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the KXTI9 driver is not idle (in other words, there
+ // is already an outstanding request to the KXTI9).
+ //
+ if(psInst->ui8State != KXTI9_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read state.
+ //
+ psInst->ui8State = KXTI9_STATE_READ;
+
+ //
+ // Read the requested registers from the KXTI9.
+ //
+ psInst->uCommand.pui8Buffer[0] = ui8Reg;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, pui8Data, ui16Count,
+ KXTI9Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = KXTI9_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Writes data to KXTI9 registers.
+//!
+//! \param psInst is a pointer to the KXTI9 instance data.
+//! \param ui8Reg is the first register to write.
+//! \param pui8Data is a pointer to the data to write.
+//! \param ui16Count is the number of data bytes to write.
+//! \param pfnCallback is the function to be called when the data has been
+//! written (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function writes a sequence of data values to consecutive registers in
+//! the KXTI9. The first byte of the \e pui8Data buffer contains the value to
+//! be written into the \e ui8Reg register, the second value contains the data
+//! to be written into the next register, and so on.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+KXTI9Write(tKXTI9 *psInst, uint_fast8_t ui8Reg, uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the KXTI9 driver is not idle (in other words, there
+ // is already an outstanding request to the KXTI9).
+ //
+ if(psInst->ui8State != KXTI9_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ psInst->ui8NewRange = psInst->ui8Range;
+ psInst->ui8NewResolution = psInst->ui8Resolution;
+
+ //
+ // See if the CTRL3 register is being written.
+ //
+ if((ui8Reg <= KXTI9_O_CTRL3) &&
+ ((ui8Reg + ui16Count) > KXTI9_O_CTRL3))
+ {
+ //
+ // See if a soft reset is being requested.
+ //
+ if(pui8Data[ui8Reg - KXTI9_O_CTRL3] & KXTI9_CTRL3_SRST)
+ {
+ //
+ // Default range setting is +/- 2 g.
+ //
+ psInst->ui8NewRange = 0;
+
+ //
+ // Default resolution is 8-bit.
+ //
+ psInst->ui8NewResolution = 0;
+ }
+ }
+
+ //
+ // See if the CTRL1 register is being written.
+ //
+ if((ui8Reg <= KXTI9_O_CTRL1) &&
+ ((ui8Reg + ui16Count) > KXTI9_O_CTRL1))
+ {
+ //
+ // Extract the range and resolution the register value.
+ //
+ psInst->ui8NewRange =
+ ((pui8Data[ui8Reg - KXTI9_O_CTRL1] & KXTI9_CTRL1_GSEL_M)
+ >> KXTI9_CTRL1_GSEL_S);
+ psInst->ui8NewResolution =
+ ((pui8Data[ui8Reg - KXTI9_O_CTRL1] & KXTI9_CTRL1_RES) >> 6);
+ }
+
+ //
+ // Save the details of this write.
+ //
+ psInst->uCommand.sWriteState.pui8Data = pui8Data;
+ psInst->uCommand.sWriteState.ui16Count = ui16Count;
+
+ //
+ // Move the state machine to the wait for write state.
+ //
+ psInst->ui8State = KXTI9_STATE_WRITE;
+
+ //
+ // Write the requested registers to the KXTI9.
+ //
+ pui8Data[0] = ui8Reg;
+ if(I2CMWrite(psInst->psI2CInst, psInst->ui8Addr, pui8Data, ui16Count + 1,
+ KXTI9Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = KXTI9_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of a KXTI9 register.
+//!
+//! \param psInst is a pointer to the KXTI9 instance data.
+//! \param ui8Reg is the register to modify.
+//! \param ui8Mask is the bit mask that is ANDed with the current register
+//! value.
+//! \param ui8Value is the bit mask that is ORed with the result of the AND
+//! operation.
+//! \param pfnCallback is the function to be called when the data has been
+//! changed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function changes the value of a register in the KXTI9 via a
+//! read-modify-write operation, allowing one of the fields to be changed
+//! without disturbing the other fields. The \e ui8Reg register is read, ANDed
+//! with \e ui8Mask, ORed with \e ui8Value, and then written back to the
+//! KXTI9.
+//!
+//! \return Returns 1 if the read-modify-write was successfully started and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+KXTI9ReadModifyWrite(tKXTI9 *psInst, uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask, uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the KXTI9 driver is not idle (in other words, there
+ // is already an outstanding request to the KXTI9).
+ //
+ if(psInst->ui8State != KXTI9_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read-modify-write state.
+ //
+ psInst->ui8State = KXTI9_STATE_RMW;
+
+ //
+ // Submit the read-modify-write request to the KXTI9.
+ //
+ if(I2CMReadModifyWrite8(&(psInst->uCommand.sReadModifyWriteState),
+ psInst->psI2CInst, psInst->ui8Addr, ui8Reg,
+ ui8Mask, ui8Value, KXTI9Callback, psInst) == 0)
+ {
+ //
+ // The I2C read-modify-write failed, so move to the idle state and
+ // return a failure.
+ //
+ psInst->ui8State = KXTI9_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads the acceleration and temperature data from the KXTI9.
+//!
+//! \param psInst is a pointer to the KXTI9 instance data.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read of the KXTI9 data registers. When the read
+//! has completed (as indicated by calling the callback function), the new
+//! readings can be obtained via:
+//!
+//! - KXTI9DataAccelGetRaw()
+//! - KXTI9DataAccelGetFloat()
+//! - KXTI9DataTemperatureGetRaw()
+//! - KXTI9DataTemperatureGetFloat()
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+KXTI9DataRead(tKXTI9 *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the KXTI9 driver is not idle (in other words, there
+ // is already an outstanding request to the KXTI9).
+ //
+ if(psInst->ui8State != KXTI9_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for data read state.
+ //
+ psInst->ui8State = KXTI9_STATE_READ;
+
+ //
+ // Read the data registers from the KXTI9.
+ //
+ psInst->pui8Data[0] = KXTI9_O_XOUT_L;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr, psInst->pui8Data, 1,
+ psInst->pui8Data, 6, KXTI9Callback, psInst) == 0)
+ {
+ //
+ // The I2C read failed, so move to the idle state and return a failure.
+ //
+ psInst->ui8State = KXTI9_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Gets the raw acceleration data from the most recent data read.
+//!
+//! \param psInst is a pointer to the KXTI9 instance data.
+//! \param pui16AccelX is a pointer to the value into which the raw X-axis
+//! acceleration data is stored.
+//! \param pui16AccelY is a pointer to the value into which the raw Y-axis
+//! acceleration data is stored.
+//! \param pui16AccelZ is a pointer to the value into which the raw Z-axis
+//! acceleration data is stored.
+//!
+//! This function returns the raw acceleration data from the most recent data
+//! read. The data is not manipulated in any way by the driver. If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+KXTI9DataAccelGetRaw(tKXTI9 *psInst, uint_fast16_t *pui16AccelX,
+ uint_fast16_t *pui16AccelY, uint_fast16_t *pui16AccelZ)
+{
+ //
+ // Return the raw acceleration values.
+ //
+ if(pui16AccelX)
+ {
+ *pui16AccelX = ((psInst->pui8Data[1] << 4) |
+ (psInst->pui8Data[0] >> 4));
+ }
+ if(pui16AccelY)
+ {
+ *pui16AccelY = ((psInst->pui8Data[3] << 4) |
+ (psInst->pui8Data[2] >> 4));
+ }
+ if(pui16AccelZ)
+ {
+ *pui16AccelZ = ((psInst->pui8Data[5] << 4) |
+ (psInst->pui8Data[4] >> 4));
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the acceleration data from the most recent data read.
+//!
+//! \param psInst is a pointer to the KXTI9 instance data.
+//! \param pfAccelX is a pointer to the value into which the X-axis
+//! acceleration data is stored.
+//! \param pfAccelY is a pointer to the value into which the Y-axis
+//! acceleration data is stored.
+//! \param pfAccelZ is a pointer to the value into which the Z-axis
+//! acceleration data is stored.
+//!
+//! This function returns the acceleration data from the most recent data read,
+//! converted into g. If any of the output data pointers are \b NULL, the
+//! corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+KXTI9DataAccelGetFloat(tKXTI9 *psInst, float *pfAccelX, float *pfAccelY,
+ float *pfAccelZ)
+{
+ float fFactor;
+ int16_t iX, iY, iZ;
+
+ //
+ // Get the acceleration conversion factor for the current range.
+ //
+ fFactor = (psInst->ui8Resolution == 0) ? g_fAccelFactors8[psInst->ui8Range] :
+ g_fAccelFactors12[psInst->ui8Range];
+
+ if(psInst->ui8Resolution)
+ {
+ //
+ // Get conversion data and store in temporary variables.
+ //
+ iX = (int16_t)((psInst->pui8Data[1] << 4) | (psInst->pui8Data[0] >> 4));
+ iY = (int16_t)((psInst->pui8Data[3] << 4) | (psInst->pui8Data[2] >> 4));
+ iZ = (int16_t)((psInst->pui8Data[5] << 4) | (psInst->pui8Data[4] >> 4));
+
+ //
+ // Sign extend 12-bit data.
+ //
+ iX |= (iX & 0x800) ? 0xf000 : 0;
+ iY |= (iY & 0x800) ? 0xf000 : 0;
+ iZ |= (iZ & 0x800) ? 0xf000 : 0;
+ }
+ else
+ {
+ //
+ // Chop off the lower 4 bits of the data. 8-bit mode only returns 8
+ // valid bits, but can have garbage in the lower 4.
+ //
+ iX = (int16_t)(psInst->pui8Data[1]);
+ iY = (int16_t)(psInst->pui8Data[3]);
+ iZ = (int16_t)(psInst->pui8Data[5]);
+
+ //
+ // Sign extend 8-bit data.
+ //
+ iX |= (iX & 0x80) ? 0xff00 : 0;
+ iY |= (iY & 0x80) ? 0xff00 : 0;
+ iZ |= (iZ & 0x80) ? 0xff00 : 0;
+ }
+
+ //
+ // Convert the acceleration values into floating-point g values.
+ //
+ if(pfAccelX)
+ {
+ *pfAccelX = (float)(iX) * fFactor;
+ }
+ if(pfAccelY)
+ {
+ *pfAccelY = (float)(iY) * fFactor;
+ }
+ if(pfAccelZ)
+ {
+ *pfAccelZ = (float)(iZ) * fFactor;
+ }
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/kxti9.h b/sensorlib/kxti9.h new file mode 100644 index 0000000..1c8e7fc --- /dev/null +++ b/sensorlib/kxti9.h @@ -0,0 +1,170 @@ +//*****************************************************************************
+//
+// KXTI9.h - Prototypes for the KXTI9 accelerometer driver.
+//
+// Copyright (c) 2012-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_KXTI9_H__
+#define __SENSORLIB_KXTI9_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the KXTI9 driver.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The pointer to the I2C master interface instance used to communicate
+ // with the KXTI9.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The I2C address of the KXTI9.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The state of the state machine used while accessing the KXTI9.
+ //
+ uint8_t ui8State;
+
+ //
+ // The ADC resolution of the KXTI9.
+ //
+ uint8_t ui8Resolution;
+
+ uint8_t ui8NewResolution;
+
+ //
+ // The current operating range (g force) of the KXTI9.
+ //
+ uint8_t ui8Range;
+
+ uint8_t ui8NewRange;
+
+ //
+ // The data buffer used for sending/receiving data to/from the KXTI9.
+ //
+ uint8_t pui8Data[7];
+
+ //
+ // The function that is called when the current request has completed
+ // processing.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The pointer provided to the callback function.
+ //
+ void *pvCallbackData;
+
+ //
+ // A union of structures that are used for read, write and
+ // read-modify-write operations. Since only one operation can be active at
+ // a time, it is safe to re-use the memory in this manner.
+ //
+ union
+ {
+ //
+ // A buffer used to store the write portion of a register read.
+ //
+ uint8_t pui8Buffer[2];
+
+ //
+ // The write state used to write register values.
+ //
+ struct
+ {
+ //
+ // The buffer that is being written to the KXTI9.
+ //
+ uint8_t *pui8Data;
+
+ //
+ // The number of bytes being written to the KXTI9.
+ //
+ uint16_t ui16Count;
+ }
+ sWriteState;
+
+ //
+ // The read-modify-write state used to modify register values.
+ //
+ tI2CMReadModifyWrite8 sReadModifyWriteState;
+ }
+ uCommand;
+}
+tKXTI9;
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern uint_fast8_t KXTI9Init(tKXTI9 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t KXTI9Read(tKXTI9 *psInst, uint_fast8_t ui8Reg,
+ uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t KXTI9Write(tKXTI9 *psInst, uint_fast8_t ui8Reg,
+ uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t KXTI9ReadModifyWrite(tKXTI9 *psInst, uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask,
+ uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t KXTI9DataRead(tKXTI9 *psInst,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern void KXTI9DataAccelGetRaw(tKXTI9 *psInst, uint_fast16_t *pui16AccelX,
+ uint_fast16_t *pui16AccelY,
+ uint_fast16_t *pui16AccelZ);
+extern void KXTI9DataAccelGetFloat(tKXTI9 *psInst, float *pfAccelX,
+ float *pfAccelY, float *pfAccelZ);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_KXTI9_H__
diff --git a/sensorlib/l3gd20h.c b/sensorlib/l3gd20h.c new file mode 100644 index 0000000..6694660 --- /dev/null +++ b/sensorlib/l3gd20h.c @@ -0,0 +1,722 @@ +//*****************************************************************************
+//
+// l3gd20h.c - Driver for the ST L3GD20H gyroscope.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <stdint.h>
+#include "sensorlib/hw_l3gd20h.h"
+#include "sensorlib/i2cm_drv.h"
+#include "sensorlib/l3gd20h.h"
+
+//*****************************************************************************
+//
+//! \addtogroup l3gd20h_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The states of the L3GD20H state machine.
+//
+//*****************************************************************************
+#define L3GD20H_STATE_IDLE 0 // State machine is idle
+#define L3GD20H_STATE_INIT_RES 1 // Waiting for initialization
+#define L3GD20H_STATE_INIT_WAIT 2 // Waiting for reset to complete
+#define L3GD20H_STATE_READ 3 // Waiting for read
+#define L3GD20H_STATE_WRITE 4 // Waiting for write
+#define L3GD20H_STATE_RMW 5 // Waiting for read-modify-write
+
+//*****************************************************************************
+//
+// The factors used to convert the gyroscope readings from the L3GD20H into
+// floating point values in radians per second.
+//
+// Per the data-sheet, the sensitivity is 8.75, 17.50, and 70.00 mdps/digit for
+// for 245, 500, and 2000 DPS scales respectively.
+//
+// mdeg 1 deg PI rad
+// 8.75 ---- * ---- * --- = 1.5271630955e-4f rad/sec per digit
+// sec 1000 mdeg 180 deg
+//
+// Values are obtained by taking the degree per second conversion factors
+// from the data sheet and then converting to radians per sec (1 degree =
+// 0.0174532925 radians).
+//
+//*****************************************************************************
+static const float g_pfL3GD20HGyroFactors[] =
+{
+ 1.5271631e-5f, // Range = +/- 245 dps
+ 3.0543262e-4f, // Range = +/- 500 dps
+ 1.2217305e-3f, // Range = +/- 2000 dps
+ 1.2217305e-3f // Range = +/- 2000 dps
+};
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transations to/from the
+// L3GD20H have completed.
+//
+//*****************************************************************************
+static void
+L3GD20HCallback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tL3GD20H *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tL3GD20H structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result in a callback to propagate the
+ // error).
+ //
+ if(ui8Status != I2CM_STATUS_SUCCESS)
+ {
+ psInst->ui8State = L3GD20H_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the L3GD20H state machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // All states that trivially transition to IDLE, and all unknown
+ // states.
+ //
+ case L3GD20H_STATE_READ:
+ default:
+ {
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = L3GD20H_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // L3GD20H Device reset was issued
+ //
+ case L3GD20H_STATE_INIT_RES:
+ {
+ //
+ // Issue a read of the status register to confirm reset is done.
+ //
+ psInst->uCommand.pui8Buffer[0] = L3GD20H_O_LOW_ODR;
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 1,
+ L3GD20HCallback, psInst);
+
+ psInst->ui8State = L3GD20H_STATE_INIT_WAIT;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // Status register was read, check if reset is done before proceeding.
+ //
+ case L3GD20H_STATE_INIT_WAIT:
+ {
+ //
+ // Check the value read back from status to determine if device
+ // is still in reset or if it is ready.
+ //
+ if(psInst->pui8Data[0] & L3GD20H_LOW_ODR_SWRESET_M)
+ {
+ //
+ // Device still in reset so begin polling this register.
+ //
+ psInst->uCommand.pui8Buffer[0] = L3GD20H_O_LOW_ODR;
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 1,
+ L3GD20HCallback, psInst);
+ }
+ else
+ {
+ //
+ // Device is out of reset, move to the idle state.
+ //
+ psInst->ui8State = L3GD20H_STATE_IDLE;
+ }
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // A write just completed
+ //
+ case L3GD20H_STATE_WRITE:
+ {
+ //
+ // Set the gyroscope ranges to the new values. If the register was
+ // not modified, the values will be the same so this has no effect.
+ //
+ psInst->ui8GyroFsSel = psInst->ui8NewGyroFsSel;
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = L3GD20H_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // A read-modify-write just completed
+ //
+ case L3GD20H_STATE_RMW:
+ {
+ //
+ // See if the PWR_MGMT_1 register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ L3GD20H_O_LOW_ODR)
+ {
+ //
+ // See if a soft reset has been issued.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ L3GD20H_LOW_ODR_SWRESET_M)
+ {
+ //
+ // Default range setting is +/- 245 degrees/s
+ //
+ psInst->ui8GyroFsSel = 0;
+ psInst->ui8NewGyroFsSel = 0;
+ }
+ }
+
+ //
+ // See if the GYRO_CONFIG register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ L3GD20H_O_CTRL4)
+ {
+ //
+ // Extract the FS_SEL from the GYRO_CONFIG register value.
+ //
+ psInst->ui8GyroFsSel =
+ ((psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ L3GD20H_CTRL4_FS_M) >>
+ L3GD20H_CTRL4_FS_S);
+ }
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = L3GD20H_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == L3GD20H_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the L3GD20H driver.
+//!
+//! \param psInst is a pointer to the L3GD20H instance data.
+//! \param psI2CInst is a pointer to the I2C master driver instance data.
+//! \param ui8I2CAddr is the I2C address of the L3GD20H device.
+//! \param pfnCallback is the function to be called when the initialization has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initializes the L3GD20H driver, preparing it for operation.
+//!
+//! \return Returns 1 if the L3GD20H driver was successfully initialized and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+L3GD20HInit(tL3GD20H *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Initialize the L3GD20H instance structure.
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8I2CAddr;
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Default range setting is +/- 245 degrees/s
+ //
+ psInst->ui8GyroFsSel =
+ (L3GD20H_CTRL4_FS_245DPS & L3GD20H_CTRL4_FS_M) >> L3GD20H_CTRL4_FS_S;
+ psInst->ui8NewGyroFsSel =
+ (L3GD20H_CTRL4_FS_245DPS & L3GD20H_CTRL4_FS_M) >> L3GD20H_CTRL4_FS_S;
+
+ //
+ // Set the state to show we are initiating a reset.
+ //
+ psInst->ui8State = L3GD20H_STATE_INIT_RES;
+
+ //
+ // Load the buffer with command to perform device reset
+ //
+ psInst->pui8Data[0] = L3GD20H_O_LOW_ODR;
+ psInst->pui8Data[1] = L3GD20H_LOW_ODR_SWRESET_RESET;
+ if(I2CMWrite(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 2, L3GD20HCallback, psInst) == 0)
+ {
+ psInst->ui8State = L3GD20H_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads data from L3GD20H registers.
+//!
+//! \param psInst is a pointer to the L3GD20H instance data.
+//! \param ui8Reg is the first register to read.
+//! \param pui8Data is a pointer to the location to store the data that is
+//! read.
+//! \param ui16Count is the number of data bytes to read.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function reads a sequence of data values from consecutive registers in
+//! the L3GD20H.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+L3GD20HRead(tL3GD20H *psInst, uint_fast8_t ui8Reg, uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the L3GD20H driver is not idle (in other words,
+ // there is already an outstanding request to the L3GD20H).
+ //
+ if(psInst->ui8State != L3GD20H_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read state.
+ //
+ psInst->ui8State = L3GD20H_STATE_READ;
+
+ //
+ // Read the requested registers from the L3GD20H.
+ //
+ psInst->uCommand.pui8Buffer[0] = ui8Reg;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, pui8Data, ui16Count,
+ L3GD20HCallback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = L3GD20H_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Writes data to L3GD20H registers.
+//!
+//! \param psInst is a pointer to the L3GD20H instance data.
+//! \param ui8Reg is the first register to write.
+//! \param pui8Data is a pointer to the data to write.
+//! \param ui16Count is the number of data bytes to write.
+//! \param pfnCallback is the function to be called when the data has been
+//! written (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function writes a sequence of data values to consecutive registers in
+//! the L3GD20H. The first byte of the \e pui8Data buffer contains the value
+//! to be written into the \e ui8Reg register, the second value contains the
+//! data to be written into the next register, and so on.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+L3GD20HWrite(tL3GD20H *psInst, uint_fast8_t ui8Reg, const uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the L3GD20H driver is not idle (in other words,
+ // there is already an outstanding request to the L3GD20H).
+ //
+ if(psInst->ui8State != L3GD20H_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // See if the PWR_MGMT_1 register is being written.
+ //
+ if((ui8Reg <= L3GD20H_O_LOW_ODR) &&
+ ((ui8Reg + ui16Count) > L3GD20H_O_LOW_ODR))
+ {
+ //
+ // See if a soft reset is being requested.
+ //
+ if(pui8Data[ui8Reg - L3GD20H_O_LOW_ODR] & L3GD20H_LOW_ODR_SWRESET_M)
+ {
+ //
+ // Default range setting is +/- 245 degrees/s.
+ //
+ psInst->ui8NewGyroFsSel = 0;
+ }
+ }
+
+ //
+ // See if the GYRO_CONFIG register is being written.
+ //
+ if((ui8Reg <= L3GD20H_O_CTRL4) &&
+ ((ui8Reg + ui16Count) > L3GD20H_O_CTRL4))
+ {
+ //
+ // Extract the FS_SEL from the GYRO_CONFIG register value.
+ //
+ psInst->ui8NewGyroFsSel = ((pui8Data[ui8Reg - L3GD20H_O_CTRL4] &
+ L3GD20H_CTRL4_FS_M) >>
+ L3GD20H_CTRL4_FS_S);
+ }
+
+ //
+ // Move the state machine to the wait for write state.
+ //
+ psInst->ui8State = L3GD20H_STATE_WRITE;
+
+ //
+ // Write the requested registers to the L3GD20H.
+ //
+ if(I2CMWrite8(&(psInst->uCommand.sWriteState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui8Data, ui16Count,
+ L3GD20HCallback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = L3GD20H_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of a L3GD20H register.
+//!
+//! \param psInst is a pointer to the L3GD20H instance data.
+//! \param ui8Reg is the register to modify.
+//! \param ui8Mask is the bit mask that is ANDed with the current register
+//! value.
+//! \param ui8Value is the bit mask that is ORed with the result of the AND
+//! operation.
+//! \param pfnCallback is the function to be called when the data has been
+//! changed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function changes the value of a register in the L3GD20H via a
+//! read-modify-write operation, allowing one of the fields to be changed
+//! without disturbing the other fields. The \e ui8Reg register is read, ANDed
+//! with \e ui8Mask, ORed with \e ui8Value, and then written back to the
+//! L3GD20H.
+//!
+//! \return Returns 1 if the read-modify-write was successfully started and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+L3GD20HReadModifyWrite(tL3GD20H *psInst, uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask, uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the L3GD20H driver is not idle (in other words,
+ // there is already an outstanding request to the L3GD20H).
+ //
+ if(psInst->ui8State != L3GD20H_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read-modify-write state.
+ //
+ psInst->ui8State = L3GD20H_STATE_RMW;
+
+ //
+ // Submit the read-modify-write request to the L3GD20H.
+ //
+ if(I2CMReadModifyWrite8(&(psInst->uCommand.sReadModifyWriteState),
+ psInst->psI2CInst, psInst->ui8Addr, ui8Reg,
+ ui8Mask, ui8Value, L3GD20HCallback, psInst) == 0)
+ {
+ //
+ // The I2C read-modify-write failed, so move to the idle state and
+ // return a failure.
+ //
+ psInst->ui8State = L3GD20H_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads the gyroscope data from the L3GD20H.
+//!
+//! \param psInst is a pointer to the L3GD20H instance data.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read of the L3GD20H data registers. When the
+//! read has completed (as indicated by calling the callback function), the new
+//! readings can be obtained via:
+//!
+//! - L3GD20HDataGyroGetRaw()
+//! - L3GD20HDataGyroGetFloat()
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+L3GD20HDataRead(tL3GD20H *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the L3GD20H driver is not idle (in other words,
+ // there is already an outstanding request to the L3GD20H).
+ //
+ if(psInst->ui8State != L3GD20H_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for data read state.
+ //
+ psInst->ui8State = L3GD20H_STATE_READ;
+
+ //
+ // Read the data registers from the L3GD20H.
+ //
+ psInst->pui8Data[0] = L3GD20H_O_STATUS | 0x80;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr, psInst->pui8Data, 1,
+ psInst->pui8Data, 7, L3GD20HCallback, psInst) == 0)
+ {
+ //
+ // The I2C read failed, so move to the idle state and return a failure.
+ //
+ psInst->ui8State = L3GD20H_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Gets the raw gyroscope data from the most recent data read.
+//!
+//! \param psInst is a pointer to the L3GD20H instance data.
+//! \param pui16GyroX is a pointer to the value into which the raw X-axis
+//! gyroscope data is stored.
+//! \param pui16GyroY is a pointer to the value into which the raw Y-axis
+//! gyroscope data is stored.
+//! \param pui16GyroZ is a pointer to the value into which the raw Z-axis
+//! gyroscope data is stored.
+//!
+//! This function returns the raw gyroscope data from the most recent data
+//! read. The data is not manipulated in any way by the driver. If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+L3GD20HDataGyroGetRaw(tL3GD20H *psInst, uint_fast16_t *pui16GyroX,
+ uint_fast16_t *pui16GyroY, uint_fast16_t *pui16GyroZ)
+{
+ //
+ // Return the raw gyroscope values.
+ //
+ if(pui16GyroX)
+ {
+ *pui16GyroX = (psInst->pui8Data[2] << 8) | psInst->pui8Data[1];
+ }
+ if(pui16GyroY)
+ {
+ *pui16GyroY = (psInst->pui8Data[4] << 8) | psInst->pui8Data[3];
+ }
+ if(pui16GyroZ)
+ {
+ *pui16GyroZ = (psInst->pui8Data[6] << 8) | psInst->pui8Data[5];
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the gyroscope data from the most recent data read.
+//!
+//! \param psInst is a pointer to the L3GD20H instance data.
+//! \param pfGyroX is a pointer to the value into which the X-axis gyroscope
+//! data is stored.
+//! \param pfGyroY is a pointer to the value into which the Y-axis gyroscope
+//! data is stored.
+//! \param pfGyroZ is a pointer to the value into which the Z-axis gyroscope
+//! data is stored.
+//!
+//! This function returns the gyroscope data from the most recent data read,
+//! converted into radians per second. If any of the output data pointers are
+//! \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+L3GD20HDataGyroGetFloat(tL3GD20H *psInst, float *pfGyroX, float *pfGyroY,
+ float *pfGyroZ)
+{
+ float fFactor;
+
+ //
+ // Get the conversion factor for the current data format.
+ //
+ fFactor = g_pfL3GD20HGyroFactors[psInst->ui8GyroFsSel];
+
+ //
+ // Convert the gyroscope values into rad/sec.
+ //
+ if(pfGyroX)
+ {
+ *pfGyroX = ((float)(int16_t)((psInst->pui8Data[2] << 8) |
+ psInst->pui8Data[1]) * fFactor);
+ }
+ if(pfGyroY)
+ {
+ *pfGyroY = ((float)(int16_t)((psInst->pui8Data[4] << 8) |
+ psInst->pui8Data[3]) * fFactor);
+ }
+ if(pfGyroZ)
+ {
+ *pfGyroZ = ((float)(int16_t)((psInst->pui8Data[6] << 8) |
+ psInst->pui8Data[5]) * fFactor);
+ }
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/l3gd20h.h b/sensorlib/l3gd20h.h new file mode 100644 index 0000000..c56bf36 --- /dev/null +++ b/sensorlib/l3gd20h.h @@ -0,0 +1,158 @@ +//*****************************************************************************
+//
+// l3gd20h.c - Driver for the ST L3GD20H gyroscope.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_L3GD20H_H__
+#define __SENSORLIB_L3GD20H_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the L3GD20H driver.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The pointer to the I2C master interface instance used to communicate
+ // with the L3GD20H.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The I2C address of the L3GD20H.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The state of the state machine used while accessing the L3GD20H.
+ //
+ uint8_t ui8State;
+
+ //
+ // The current gyroscope fs_sel setting.
+ //
+ uint8_t ui8GyroFsSel;
+
+ //
+ // The new gyroscope fs_sel setting, which is used when a register write
+ // succeeds.
+ //
+ uint8_t ui8NewGyroFsSel;
+
+ //
+ // The data buffer used for sending/receiving data to/from the L3GD20H.
+ // We need 7 bytes (1 status + 3axis * 2bytes per axis)
+ //
+ uint8_t pui8Data[8];
+
+ //
+ // The function that is called when the current request has completed
+ // processing.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The callback data provided to the callback function.
+ //
+ void *pvCallbackData;
+
+ //
+ // A union of structures that are used for read, write and
+ // read-modify-write operations. Since only one operation can be active at
+ // a time, it is safe to re-use the memory in this manner.
+ //
+ union
+ {
+ //
+ // A buffer used to store the write portion of a register read.
+ //
+ uint8_t pui8Buffer[2];
+
+ //
+ // The write state used to write register values.
+ //
+ tI2CMWrite8 sWriteState;
+
+ //
+ // The read-modify-write state used to modify register values.
+ //
+ tI2CMReadModifyWrite8 sReadModifyWriteState;
+ }
+ uCommand;
+}
+tL3GD20H;
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern uint_fast8_t L3GD20HInit(tL3GD20H *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t L3GD20HRead(tL3GD20H *psInst, uint_fast8_t ui8Reg,
+ uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t L3GD20HWrite(tL3GD20H *psInst, uint_fast8_t ui8Reg,
+ const uint8_t *pui8Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t L3GD20HReadModifyWrite(tL3GD20H *psInst,
+ uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask,
+ uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t L3GD20HDataRead(tL3GD20H *psInst,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern void L3GD20HDataGyroGetRaw(tL3GD20H *psInst, uint_fast16_t *pui16GyroX,
+ uint_fast16_t *pui16GyroY,
+ uint_fast16_t *pui16GyroZ);
+extern void L3GD20HDataGyroGetFloat(tL3GD20H *psInst, float *pfGyroX,
+ float *pfGyroY, float *pfGyroZ);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_L3GD20H_H__
diff --git a/sensorlib/lsm303d.c b/sensorlib/lsm303d.c new file mode 100644 index 0000000..e21a5b8 --- /dev/null +++ b/sensorlib/lsm303d.c @@ -0,0 +1,835 @@ +//*****************************************************************************
+//
+// lsm303d.c - Driver for the ST LSM303D accelerometer/magnetometer.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <stdint.h>
+#include "sensorlib/hw_lsm303d.h"
+#include "sensorlib/i2cm_drv.h"
+#include "sensorlib/lsm303d.h"
+
+//*****************************************************************************
+//
+//! \addtogroup lsm303dlhc_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The states of the LSM303D state machine.
+//
+//*****************************************************************************
+#define LSM303D_STATE_IDLE 0 // State machine is idle
+#define LSM303D_STATE_INIT 1 // Waiting for init
+#define LSM303D_STATE_READ_MAG \
+ 2 // Waiting for mag read
+#define LSM303D_STATE_READ_ACCEL \
+ 3 // Waiting for accel read
+#define LSM303D_STATE_WRITE 4 // Waiting for write
+#define LSM303D_STATE_RMW 5 // Waiting for read-modify-write
+
+//*****************************************************************************
+//
+// The factors used to convert the acceleration readings from the LSM303D
+// into floating point values in meters per second squared.
+//
+// Values are obtained by taking the g conversion factors from the data sheet
+// and multiplying by 9.81 (1 g = 9.81 m/s^2).
+//
+//*****************************************************************************
+static const float g_pfLSM303DAccelFactors[] =
+{
+ 0.00059875, // Range = +/- 2 g (16384 lsb/g)
+ 0.00119751, // Range = +/- 4 g (8192 lsb/g)
+ 0.00239502, // Range = +/- 8 g (4096 lsb/g)
+ 0.00479004 // Range = +/- 16 g (2048 lsb/g)
+};
+static const float g_pfLSM303DMagFactors[] =
+{
+ 8.0e-6f, // Range = +/- 2 (0.080 mgauss/lsb)
+ 1.6e-5f, // Range = +/- 4 (0.160 mgauss/lsb)
+ 3.2e-5f, // Range = +/- 8 (0.320 mgauss/lsb)
+ 4.79e-5f // Range = +/- 12 (0.479 mgauss/lsb)
+};
+//
+// Uninitialized values will default to zero which is what we want. 0x80 is
+// ORed into the register address so the writes auto-increment
+//
+static const uint8_t g_pui8ZeroInit[] =
+{
+ 0x80 | LSM303D_O_MAG_INT_CTRL,
+ 0xE8, // MAG_INT_CTRL
+ 0x0, // int_src (RO)
+ 0x0, // THS_LSB
+ 0x0, // THS_MSB
+ 0x0, // OFFSET_X_LSB
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0, // REF_X
+ 0x0,
+ 0x0,
+ 0x0, // CTRL0
+ 0x7,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x18, // CTRL5
+ 0x20,
+ 0x1,
+ 0x0, // status (RO)
+ 0x0, // out_x_lsb (RO)
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0, // FIFO_CTRL
+ 0x0, // fifo_src (RO)
+ 0x0, // IG_CFG1
+ 0x0, // ig_src1 (RO)
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0, // ig_src2 (RO)
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0, // clk_src (RO)
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0
+};
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transations to/from the
+// LSM303D have completed.
+//
+//*****************************************************************************
+static void
+LSM303DCallback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tLSM303D *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tLSM303D structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result in a callback to propagate the
+ // error).
+ //
+ if(ui8Status != I2CM_STATUS_SUCCESS)
+ {
+ psInst->ui8State = LSM303D_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the LSM303D state machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // All states that trivially transition to IDLE, and all unknown
+ // states.
+ //
+ default:
+ {
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = LSM303D_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ case LSM303D_STATE_READ_MAG:
+ {
+ //
+ // Move the state machine to the wait for accel data read state.
+ //
+ psInst->ui8State = LSM303D_STATE_READ_ACCEL;
+
+ //
+ // Read the accel data registers from the LSM303D.
+ //
+ psInst->pui8DataAccel[0] = LSM303D_O_STATUS | 0x80;
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr, psInst->pui8DataAccel,
+ 1, psInst->pui8DataAccel, 7, LSM303DCallback, psInst);
+
+ //
+ // Done.
+ //
+ break;
+ }
+ case LSM303D_STATE_INIT:
+ {
+ psInst->ui8State = LSM303D_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // A write just completed
+ //
+ case LSM303D_STATE_WRITE:
+ {
+ //
+ // Set the accelerometer ranges to the new values. If the register
+ // was not modified, the values will be the same so this has no
+ // effect.
+ //
+ psInst->ui8AccelFSSel = psInst->ui8NewAccelFSSel;
+ psInst->ui8MagFSSel = psInst->ui8NewMagFSSel;
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = LSM303D_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // A read-modify-write just completed
+ //
+ case LSM303D_STATE_RMW:
+ {
+ //
+ // See if the accel scale register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ LSM303D_O_CTRL2)
+ {
+ //
+ // Extract the FS_SEL from the ACCEL_CONFIG register value.
+ //
+ psInst->ui8AccelFSSel =
+ ((psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ LSM303D_CTRL2_AFS_M) >> LSM303D_CTRL2_AFS_S);
+ }
+
+ //
+ // See if the mag scale register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ LSM303D_O_CTRL6)
+ {
+ //
+ // Extract the FS_SEL from the mag scale register value.
+ //
+ psInst->ui8MagFSSel =
+ ((psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ LSM303D_CTRL6_MFS_M) >> LSM303D_CTRL6_MFS_S);
+
+ }
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = LSM303D_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == LSM303D_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the LSM303D driver.
+//!
+//! \param psInst is a pointer to the LSM303D instance data.
+//! \param psI2CInst is a pointer to the I2C master driver instance data.
+//! \param ui8I2CAddr is the I2C address of the LSM303D device.
+//! \param pfnCallback is the function to be called when the initialization has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initializes the LSM303D driver, preparing it for
+//! operation.
+//!
+//! \return Returns 1 if the LSM303D driver was successfully initialized and
+//! 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+LSM303DInit(tLSM303D *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Initialize the LSM303D instance structure.
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8I2CAddr;
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Default range setting is +/- 2 g
+ //
+ psInst->ui8AccelFSSel = (LSM303D_CTRL2_AFS_2G >> LSM303D_CTRL2_AFS_S);
+ psInst->ui8NewAccelFSSel = (LSM303D_CTRL2_AFS_2G >> LSM303D_CTRL2_AFS_S);
+ psInst->ui8MagFSSel = (LSM303D_CTRL6_MFS_2G >> LSM303D_CTRL6_MFS_S);
+ psInst->ui8NewMagFSSel = (LSM303D_CTRL6_MFS_2G >> LSM303D_CTRL6_MFS_S);
+
+ //
+ // There is no soft reset on the LSM303. Force registers back to their
+ // spec'ed POR defaults.
+ //
+ psInst->ui8State = LSM303D_STATE_INIT;
+ if(I2CMWrite(psInst->psI2CInst, psInst->ui8Addr, g_pui8ZeroInit,
+ sizeof(g_pui8ZeroInit), LSM303DCallback, (void *)psInst) == 0)
+ {
+ psInst->ui8State = LSM303D_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads data from LSM303D registers.
+//!
+//! \param psInst is a pointer to the LSM303D instance data.
+//! \param ui8Reg is the first register to read.
+//! \param pui8Data is a pointer to the location to store the data that is
+//! read.
+//! \param ui16Count is the number of data bytes to read.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function reads a sequence of data values from consecutive registers in
+//! the LSM303D.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+LSM303DRead(tLSM303D *psInst, uint_fast8_t ui8Reg,
+ uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the LSM303D driver is not idle (in other words,
+ // there is already an outstanding request to the LSM303D).
+ //
+ if(psInst->ui8State != LSM303D_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read state.
+ //
+ psInst->ui8State = LSM303D_STATE_READ_MAG;
+
+ //
+ // Read the requested registers from the LSM303D.
+ //
+ psInst->uCommand.pui8Buffer[0] = ui8Reg;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, pui8Data, ui16Count,
+ LSM303DCallback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = LSM303D_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Writes data to LSM303D registers.
+//!
+//! \param psInst is a pointer to the LSM303D instance data.
+//! \param ui8Reg is the first register to write.
+//! \param pui8Data is a pointer to the data to write.
+//! \param ui16Count is the number of data bytes to write.
+//! \param pfnCallback is the function to be called when the data has been
+//! written (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function writes a sequence of data values to consecutive registers in
+//! the LSM303D. The first byte of the \e pui8Data buffer contains the
+//! value to be written into the \e ui8Reg register, the second value contains
+//! the data to be written into the next register, and so on.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+LSM303DWrite(tLSM303D *psInst, uint_fast8_t ui8Reg,
+ const uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the LSM303D driver is not idle (in other words,
+ // there is already an outstanding request to the LSM303D).
+ //
+ if(psInst->ui8State != LSM303D_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // See if the accel full scale select register is being written.
+ //
+ if((ui8Reg <= LSM303D_O_CTRL2) &&
+ ((ui8Reg + ui16Count) > LSM303D_O_CTRL2))
+ {
+ //
+ // Extract the AFS_SEL from the ACCEL_CONFIG register value.
+ //
+ psInst->ui8NewAccelFSSel =
+ ((pui8Data[ui8Reg - LSM303D_O_CTRL2] &
+ LSM303D_CTRL2_AFS_M) >> LSM303D_CTRL2_AFS_S);
+ }
+
+ //
+ // See if the mag full scale select register is being written.
+ //
+ if((ui8Reg <= LSM303D_O_CTRL6) &&
+ ((ui8Reg + ui16Count) > LSM303D_O_CTRL6))
+ {
+ //
+ // Extract the AFS_SEL from the ACCEL_CONFIG register value.
+ //
+ psInst->ui8NewMagFSSel =
+ ((pui8Data[ui8Reg - LSM303D_O_CTRL6] &
+ LSM303D_CTRL6_MFS_M) >> LSM303D_CTRL6_MFS_S);
+ }
+
+ //
+ // Move the state machine to the wait for write state.
+ //
+ psInst->ui8State = LSM303D_STATE_WRITE;
+
+ //
+ // Write the requested registers to the LSM303D.
+ //
+ if(I2CMWrite8(&(psInst->uCommand.sWriteState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui8Data, ui16Count,
+ LSM303DCallback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = LSM303D_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of a LSM303D register.
+//!
+//! \param psInst is a pointer to the LSM303D instance data.
+//! \param ui8Reg is the register to modify.
+//! \param ui8Mask is the bit mask that is ANDed with the current register
+//! value.
+//! \param ui8Value is the bit mask that is ORed with the result of the AND
+//! operation.
+//! \param pfnCallback is the function to be called when the data has been
+//! changed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function changes the value of a register in the LSM303D via a
+//! read-modify-write operation, allowing one of the fields to be changed
+//! without disturbing the other fields. The \e ui8Reg register is read, ANDed
+//! with \e ui8Mask, ORed with \e ui8Value, and then written back to the
+//! LSM303D.
+//!
+//! \return Returns 1 if the read-modify-write was successfully started and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+LSM303DReadModifyWrite(tLSM303D *psInst, uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask, uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the LSM303D driver is not idle (in other words,
+ // there is already an outstanding request to the LSM303D).
+ //
+ if(psInst->ui8State != LSM303D_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read-modify-write state.
+ //
+ psInst->ui8State = LSM303D_STATE_RMW;
+
+ //
+ // Submit the read-modify-write request to the LSM303D.
+ //
+ if(I2CMReadModifyWrite8(&(psInst->uCommand.sReadModifyWriteState),
+ psInst->psI2CInst, psInst->ui8Addr, ui8Reg,
+ ui8Mask, ui8Value, LSM303DCallback,
+ psInst) == 0)
+ {
+ //
+ // The I2C read-modify-write failed, so move to the idle state and
+ // return a failure.
+ //
+ psInst->ui8State = LSM303D_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads the accelerometer data from the LSM303D.
+//!
+//! \param psInst is a pointer to the LSM303D instance data.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read of the LSM303D data registers. When the
+//! read has completed (as indicated by calling the callback function), the new
+//! readings can be obtained via:
+//!
+//! - LSM303DDataAccelGetRaw()
+//! - LSM303DDataAccelGetFloat()
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+LSM303DDataRead(tLSM303D *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the LSM303D driver is not idle (in other words,
+ // there is already an outstanding request to the LSM303D).
+ //
+ if(psInst->ui8State != LSM303D_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for mag data read state.
+ //
+ psInst->ui8State = LSM303D_STATE_READ_MAG;
+
+ //
+ // Read the data registers from the LSM303D.
+ //
+ psInst->pui8DataMag[0] = LSM303D_O_MAG_STATUS | 0x80;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr, psInst->pui8DataMag, 1,
+ psInst->pui8DataMag, 7, LSM303DCallback, psInst) == 0)
+ {
+ //
+ // The I2C read failed, so move to the idle state and return a failure.
+ //
+ psInst->ui8State = LSM303D_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Gets the raw accelerometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the LSM303D instance data.
+//! \param pui16AccelX is a pointer to the value into which the raw X-axis
+//! accelerometer data is stored.
+//! \param pui16AccelY is a pointer to the value into which the raw Y-axis
+//! accelerometer data is stored.
+//! \param pui16AccelZ is a pointer to the value into which the raw Z-axis
+//! accelerometer data is stored.
+//!
+//! This function returns the raw accelerometer data from the most recent data
+//! read. The data is not manipulated in any way by the driver. If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+LSM303DDataAccelGetRaw(tLSM303D *psInst,
+ uint_fast16_t *pui16AccelX,
+ uint_fast16_t *pui16AccelY,
+ uint_fast16_t *pui16AccelZ)
+{
+ //
+ // Return the raw accelerometer values.
+ //
+ if(pui16AccelX)
+ {
+ *pui16AccelX = (psInst->pui8DataAccel[2] << 8) | psInst->pui8DataAccel[1];
+ }
+ if(pui16AccelY)
+ {
+ *pui16AccelY = (psInst->pui8DataAccel[4] << 8) | psInst->pui8DataAccel[3];
+ }
+ if(pui16AccelZ)
+ {
+ *pui16AccelZ = (psInst->pui8DataAccel[6] << 8) | psInst->pui8DataAccel[5];
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the raw accelerometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the LSM303D instance data.
+//! \param pui16AccelX is a pointer to the value into which the raw X-axis
+//! accelerometer data is stored.
+//! \param pui16AccelY is a pointer to the value into which the raw Y-axis
+//! accelerometer data is stored.
+//! \param pui16AccelZ is a pointer to the value into which the raw Z-axis
+//! accelerometer data is stored.
+//!
+//! This function returns the raw accelerometer data from the most recent data
+//! read. The data is not manipulated in any way by the driver. If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+LSM303DDataMagnetoGetRaw(tLSM303D *psInst,
+ uint_fast16_t *pui16AccelX,
+ uint_fast16_t *pui16AccelY,
+ uint_fast16_t *pui16AccelZ)
+{
+ //
+ // Return the raw accelerometer values.
+ //
+ if(pui16AccelX)
+ {
+ *pui16AccelX = (psInst->pui8DataMag[2] << 8) | psInst->pui8DataMag[1];
+ }
+ if(pui16AccelY)
+ {
+ *pui16AccelY = (psInst->pui8DataMag[4] << 8) | psInst->pui8DataMag[3];
+ }
+ if(pui16AccelZ)
+ {
+ *pui16AccelZ = (psInst->pui8DataMag[6] << 8) | psInst->pui8DataMag[5];
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the accelerometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the LSM303D instance data.
+//! \param pfAccelX is a pointer to the value into which the X-axis
+//! accelerometer data is stored.
+//! \param pfAccelY is a pointer to the value into which the Y-axis
+//! accelerometer data is stored.
+//! \param pfAccelZ is a pointer to the value into which the Z-axis
+//! accelerometer data is stored.
+//!
+//! This function returns the accelerometer data from the most recent data
+//! read, converted into meters per second squared (m/s^2). If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+LSM303DDataAccelGetFloat(tLSM303D *psInst, float *pfAccelX,
+ float *pfAccelY, float *pfAccelZ)
+{
+ float fFactor;
+
+ //
+ // Get the acceleration conversion factor for the current data format.
+ //
+ fFactor = g_pfLSM303DAccelFactors[psInst->ui8AccelFSSel];
+
+ //
+ // Convert the Accelerometer values into floating-point gravity values.
+ //
+ if(pfAccelX)
+ {
+ *pfAccelX = (float)(((int16_t)((psInst->pui8DataAccel[2] << 8) |
+ psInst->pui8DataAccel[1])) * fFactor);
+ }
+ if(pfAccelY)
+ {
+ *pfAccelY = (float)(((int16_t)((psInst->pui8DataAccel[4] << 8) |
+ psInst->pui8DataAccel[3])) * fFactor);
+ }
+ if(pfAccelZ)
+ {
+ *pfAccelZ = (float)(((int16_t)((psInst->pui8DataAccel[6] << 8) |
+ psInst->pui8DataAccel[5])) * fFactor);
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the magnetometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the LSM303D instance data.
+//! \param pfMagX is a pointer to the value into which the X-axis
+//! accelerometer data is stored.
+//! \param pfMagY is a pointer to the value into which the Y-axis
+//! accelerometer data is stored.
+//! \param pfMagZ is a pointer to the value into which the Z-axis
+//! accelerometer data is stored.
+//!
+//! This function returns the magnetometer data from the most recent data
+//! read, converted into tesla. If any of the output data pointers are
+//! \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+LSM303DDataMagnetoGetFloat(tLSM303D *psInst, float *pfMagX,
+ float *pfMagY, float *pfMagZ)
+{
+ float fFactor;
+
+ //
+ // Get the magnetometer conversion factor for the current data format.
+ //
+ fFactor = g_pfLSM303DMagFactors[psInst->ui8MagFSSel];
+
+ //
+ // Convert the Accelerometer values into floating-point gravity values.
+ //
+ if(pfMagX)
+ {
+ *pfMagX = (float)(((int16_t)((psInst->pui8DataMag[2] << 8) |
+ psInst->pui8DataMag[1])) * fFactor);
+ }
+ if(pfMagY)
+ {
+ *pfMagY = (float)(((int16_t)((psInst->pui8DataMag[4] << 8) |
+ psInst->pui8DataMag[3])) * fFactor);
+ }
+ if(pfMagZ)
+ {
+ *pfMagZ = (float)(((int16_t)((psInst->pui8DataMag[6] << 8) |
+ psInst->pui8DataMag[5])) * fFactor);
+ }
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/lsm303d.h b/sensorlib/lsm303d.h new file mode 100644 index 0000000..a236e0f --- /dev/null +++ b/sensorlib/lsm303d.h @@ -0,0 +1,186 @@ +//*****************************************************************************
+//
+// lsm303d.h - Driver for the ST LSM303D accelerometer/magnetometer.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_LSM303D_H__
+#define __SENSORLIB_LSM303D_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the LSM303DLHC driver.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The pointer to the I2C master interface instance used to communicate
+ // with the LSM303DLHC.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The I2C address of the LSM303DLHC.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The state of the state machine used while accessing the LSM303DLHC.
+ //
+ uint8_t ui8State;
+
+ //
+ // The current accelerometer afs_sel setting.
+ //
+ uint8_t ui8AccelFSSel;
+
+ //
+ // The new accelerometer afs_sel setting, which is used when a register
+ // write succeeds.
+ //
+ uint8_t ui8NewAccelFSSel;
+
+ //
+ // The current accelerometer afs_sel setting.
+ //
+ uint8_t ui8MagFSSel;
+
+ //
+ // The new accelerometer afs_sel setting, which is used when a register
+ // write succeeds.
+ //
+ uint8_t ui8NewMagFSSel;
+
+ //
+ // The data buffers used for sending/receiving data to/from the LSM303DLHC.
+ //
+ uint8_t pui8DataMag[8];
+
+ //
+ // The data buffers used for sending/receiving data to/from the LSM303DLHC.
+ //
+ uint8_t pui8DataAccel[8];
+
+ //
+ // The function that is called when the current request has completed
+ // processing.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The callback data provided to the callback function.
+ //
+ void *pvCallbackData;
+
+ //
+ // A union of structures that are used for read, write and
+ // read-modify-write operations. Since only one operation can be active at
+ // a time, it is safe to re-use the memory in this manner.
+ //
+ union
+ {
+ //
+ // A buffer used to store the write portion of a register read.
+ //
+ uint8_t pui8Buffer[2];
+
+ //
+ // The write state used to write register values.
+ //
+ tI2CMWrite8 sWriteState;
+
+ //
+ // The read-modify-write state used to modify register values.
+ //
+ tI2CMReadModifyWrite8 sReadModifyWriteState;
+ }
+ uCommand;
+}
+tLSM303D;
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern uint_fast8_t LSM303DInit(tLSM303D *psInst,
+ tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t LSM303DRead(tLSM303D *psInst,
+ uint_fast8_t ui8Reg,
+ uint8_t *pui8Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t LSM303DWrite(tLSM303D *psInst,
+ uint_fast8_t ui8Reg,
+ const uint8_t *pui8Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t LSM303DReadModifyWrite(tLSM303D *psInst,
+ uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask,
+ uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallbak,
+ void *pvCallbackData);
+extern uint_fast8_t LSM303DDataRead(tLSM303D *psInst,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern void LSM303DDataAccelGetRaw(tLSM303D *psInst,
+ uint_fast16_t *pui16AccelX,
+ uint_fast16_t *pui16AccelY,
+ uint_fast16_t *pui16AccelZ);
+extern void LSM303DDataAccelGetFloat(tLSM303D *psInst,
+ float *pfAccelX, float *pfAccelY,
+ float *pfAccelZ);
+extern void LSM303DDataMagnetoGetRaw(tLSM303D *psInst,
+ uint_fast16_t *pui16MagX,
+ uint_fast16_t *pui16MagY,
+ uint_fast16_t *pui16MagZ);
+extern void LSM303DDataMagnetoGetFloat(tLSM303D *psInst,
+ float *pfMagX, float *pfMagY,
+ float *pfMagZ);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_LSM303D_H__
diff --git a/sensorlib/lsm303dlhc_accel.c b/sensorlib/lsm303dlhc_accel.c new file mode 100644 index 0000000..ad46b37 --- /dev/null +++ b/sensorlib/lsm303dlhc_accel.c @@ -0,0 +1,662 @@ +//*****************************************************************************
+//
+// lsm303dlhc.c - Driver for the ST LSM303DLHC accelerometer
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <stdint.h>
+#include "sensorlib/hw_lsm303dlhc.h"
+#include "sensorlib/i2cm_drv.h"
+#include "sensorlib/lsm303dlhc_accel.h"
+
+//*****************************************************************************
+//
+//! \addtogroup lsm303dlhc_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The states of the LSM303DLHC state machine.
+//
+//*****************************************************************************
+#define LSM303DLHC_STATE_IDLE 0 // State machine is idle
+#define LSM303DLHC_STATE_INIT 1 // Waiting for init
+#define LSM303DLHC_STATE_READ 2 // Waiting for read
+#define LSM303DLHC_STATE_WRITE 3 // Waiting for write
+#define LSM303DLHC_STATE_RMW 4 // Waiting for read-modify-write
+
+//*****************************************************************************
+//
+// The factors used to convert the acceleration readings from the LSM303DLHC
+// into floating point values in meters per second squared.
+//
+// Values are obtained by taking the g conversion factors from the data sheet
+// and multiplying by 9.81 (1 g = 9.81 m/s^2).
+//
+//*****************************************************************************
+static const float g_pfLSM303DLHCAccelFactors[] =
+{
+ 0.00059875, // Range = +/- 2 g (16384 lsb/g)
+ 0.00119751, // Range = +/- 4 g (8192 lsb/g)
+ 0.00239502, // Range = +/- 8 g (4096 lsb/g)
+ 0.00479004 // Range = +/- 16 g (2048 lsb/g)
+};
+
+//
+// Uninitialized values will default to zero which is what we want. 0x80 is
+// ORed into the register address so the writes auto-increment
+//
+static const uint8_t g_pui8ZeroCtrl1[8] =
+{
+ 0x80 | LSM303DLHC_O_CTRL1
+};
+static const uint8_t g_pui8ZeroFifoCtl[14] =
+{
+ 0x80 | LSM303DLHC_O_FIFO_CTRL
+};
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transations to/from the
+// LSM303DLHC have completed.
+//
+//*****************************************************************************
+static void
+LSM303DLHCCallback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tLSM303DLHCAccel *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tLSM303DLHC structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result in a callback to propagate the
+ // error).
+ //
+ if(ui8Status != I2CM_STATUS_SUCCESS)
+ {
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the LSM303DLHC state machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // All states that trivially transition to IDLE, and all unknown
+ // states.
+ //
+ case LSM303DLHC_STATE_READ:
+ default:
+ {
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ case LSM303DLHC_STATE_INIT:
+ {
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+ I2CMWrite(psInst->psI2CInst, psInst->ui8Addr, g_pui8ZeroFifoCtl,
+ 14, LSM303DLHCCallback, pvCallbackData);
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // A write just completed
+ //
+ case LSM303DLHC_STATE_WRITE:
+ {
+ //
+ // Set the accelerometer ranges to the new values. If the register
+ // was not modified, the values will be the same so this has no
+ // effect.
+ //
+ psInst->ui8AccelAfsSel = psInst->ui8NewAccelAfsSel;
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // A read-modify-write just completed
+ //
+ case LSM303DLHC_STATE_RMW:
+ {
+ //
+ // See if the ACCEL_CONFIG register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ LSM303DLHC_O_CTRL4)
+ {
+ //
+ // Extract the FS_SEL from the ACCEL_CONFIG register value.
+ //
+ psInst->ui8AccelAfsSel =
+ ((psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ LSM303DLHC_CTRL4_FS_M) >> LSM303DLHC_CTRL4_FS_S);
+ }
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == LSM303DLHC_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the LSM303DLHC driver.
+//!
+//! \param psInst is a pointer to the LSM303DLHC instance data.
+//! \param psI2CInst is a pointer to the I2C master driver instance data.
+//! \param ui8I2CAddr is the I2C address of the LSM303DLHC device.
+//! \param pfnCallback is the function to be called when the initialization has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initializes the LSM303DLHC driver, preparing it for
+//! operation.
+//!
+//! \return Returns 1 if the LSM303DLHC driver was successfully initialized and
+//! 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+LSM303DLHCAccelInit(tLSM303DLHCAccel *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Initialize the LSM303DLHC instance structure.
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8I2CAddr;
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Default range setting is +/- 2 g
+ //
+ psInst->ui8AccelAfsSel = (LSM303DLHC_CTRL4_FS_2G >> LSM303DLHC_CTRL4_FS_S);
+ psInst->ui8NewAccelAfsSel = (LSM303DLHC_CTRL4_FS_2G >> LSM303DLHC_CTRL4_FS_S);
+
+ //
+ // There is no soft reset on the LSM303. Force registers back to their
+ // spec'ed POR defaults.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_INIT;
+ if(I2CMWrite(psInst->psI2CInst, psInst->ui8Addr, g_pui8ZeroCtrl1, 7,
+ LSM303DLHCCallback, (void *)psInst) == 0)
+ {
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads data from LSM303DLHC registers.
+//!
+//! \param psInst is a pointer to the LSM303DLHC instance data.
+//! \param ui8Reg is the first register to read.
+//! \param pui8Data is a pointer to the location to store the data that is
+//! read.
+//! \param ui16Count is the number of data bytes to read.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function reads a sequence of data values from consecutive registers in
+//! the LSM303DLHC.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+LSM303DLHCAccelRead(tLSM303DLHCAccel *psInst, uint_fast8_t ui8Reg,
+ uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the LSM303DLHC driver is not idle (in other words,
+ // there is already an outstanding request to the LSM303DLHC).
+ //
+ if(psInst->ui8State != LSM303DLHC_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read state.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_READ;
+
+ //
+ // Read the requested registers from the LSM303DLHC.
+ //
+ psInst->uCommand.pui8Buffer[0] = ui8Reg;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, pui8Data, ui16Count,
+ LSM303DLHCCallback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Writes data to LSM303DLHC registers.
+//!
+//! \param psInst is a pointer to the LSM303DLHC instance data.
+//! \param ui8Reg is the first register to write.
+//! \param pui8Data is a pointer to the data to write.
+//! \param ui16Count is the number of data bytes to write.
+//! \param pfnCallback is the function to be called when the data has been
+//! written (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function writes a sequence of data values to consecutive registers in
+//! the LSM303DLHC. The first byte of the \e pui8Data buffer contains the
+//! value to be written into the \e ui8Reg register, the second value contains
+//! the data to be written into the next register, and so on.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+LSM303DLHCAccelWrite(tLSM303DLHCAccel *psInst, uint_fast8_t ui8Reg,
+ const uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the LSM303DLHC driver is not idle (in other words,
+ // there is already an outstanding request to the LSM303DLHC).
+ //
+ if(psInst->ui8State != LSM303DLHC_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // See if they're rebooting via CTRL5
+ //
+ if((ui8Reg <= LSM303DLHC_O_CTRL5) &&
+ ((ui8Reg + ui16Count) > LSM303DLHC_O_CTRL5))
+ {
+ //
+ // See if a soft reset is being requested.
+ //
+ if(pui8Data[ui8Reg - LSM303DLHC_O_CTRL5] & LSM303DLHC_CTRL5_REBOOTCTL_M)
+ {
+ //
+ // Default range setting is +/- 2 g.
+ //
+ psInst->ui8NewAccelAfsSel = 0;
+ }
+ }
+
+ //
+ // See if the ACCEL_CONFIG register is being written.
+ //
+ if((ui8Reg <= LSM303DLHC_O_CTRL4) &&
+ ((ui8Reg + ui16Count) > LSM303DLHC_O_CTRL4))
+ {
+ //
+ // Extract the AFS_SEL from the ACCEL_CONFIG register value.
+ //
+ psInst->ui8NewAccelAfsSel =
+ ((pui8Data[ui8Reg - LSM303DLHC_O_CTRL4] &
+ LSM303DLHC_CTRL4_FS_M) >> LSM303DLHC_CTRL4_FS_S);
+ }
+
+ //
+ // Move the state machine to the wait for write state.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_WRITE;
+
+ //
+ // Write the requested registers to the LSM303DLHC.
+ //
+ if(I2CMWrite8(&(psInst->uCommand.sWriteState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui8Data, ui16Count,
+ LSM303DLHCCallback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of a LSM303DLHC register.
+//!
+//! \param psInst is a pointer to the LSM303DLHC instance data.
+//! \param ui8Reg is the register to modify.
+//! \param ui8Mask is the bit mask that is ANDed with the current register
+//! value.
+//! \param ui8Value is the bit mask that is ORed with the result of the AND
+//! operation.
+//! \param pfnCallback is the function to be called when the data has been
+//! changed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function changes the value of a register in the LSM303DLHC via a
+//! read-modify-write operation, allowing one of the fields to be changed
+//! without disturbing the other fields. The \e ui8Reg register is read, ANDed
+//! with \e ui8Mask, ORed with \e ui8Value, and then written back to the
+//! LSM303DLHC.
+//!
+//! \return Returns 1 if the read-modify-write was successfully started and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+LSM303DLHCAccelReadModifyWrite(tLSM303DLHCAccel *psInst, uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask, uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the LSM303DLHC driver is not idle (in other words,
+ // there is already an outstanding request to the LSM303DLHC).
+ //
+ if(psInst->ui8State != LSM303DLHC_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read-modify-write state.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_RMW;
+
+ //
+ // Submit the read-modify-write request to the LSM303DLHC.
+ //
+ if(I2CMReadModifyWrite8(&(psInst->uCommand.sReadModifyWriteState),
+ psInst->psI2CInst, psInst->ui8Addr, ui8Reg,
+ ui8Mask, ui8Value, LSM303DLHCCallback,
+ psInst) == 0)
+ {
+ //
+ // The I2C read-modify-write failed, so move to the idle state and
+ // return a failure.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads the accelerometer data from the LSM303DLHC.
+//!
+//! \param psInst is a pointer to the LSM303DLHC instance data.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read of the LSM303DLHC data registers. When the
+//! read has completed (as indicated by calling the callback function), the new
+//! readings can be obtained via:
+//!
+//! - LSM303DLHCDataAccelGetRaw()
+//! - LSM303DLHCDataAccelGetFloat()
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+LSM303DLHCAccelDataRead(tLSM303DLHCAccel *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the LSM303DLHC driver is not idle (in other words,
+ // there is already an outstanding request to the LSM303DLHC).
+ //
+ if(psInst->ui8State != LSM303DLHC_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for data read state.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_READ;
+
+ //
+ // Read the data registers from the LSM303DLHC.
+ //
+ psInst->pui8Data[0] = LSM303DLHC_O_OUT_X_LSB | 0x80;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr, psInst->pui8Data, 1,
+ psInst->pui8Data, 6, LSM303DLHCCallback, psInst) == 0)
+ {
+ //
+ // The I2C read failed, so move to the idle state and return a failure.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Gets the raw accelerometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the LSM303DLHC instance data.
+//! \param pui16AccelX is a pointer to the value into which the raw X-axis
+//! accelerometer data is stored.
+//! \param pui16AccelY is a pointer to the value into which the raw Y-axis
+//! accelerometer data is stored.
+//! \param pui16AccelZ is a pointer to the value into which the raw Z-axis
+//! accelerometer data is stored.
+//!
+//! This function returns the raw accelerometer data from the most recent data
+//! read. The data is not manipulated in any way by the driver. If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+LSM303DLHCAccelDataAccelGetRaw(tLSM303DLHCAccel *psInst,
+ uint_fast16_t *pui16AccelX,
+ uint_fast16_t *pui16AccelY,
+ uint_fast16_t *pui16AccelZ)
+{
+ //
+ // Return the raw accelerometer values.
+ //
+ if(pui16AccelX)
+ {
+ *pui16AccelX = (psInst->pui8Data[1] << 8) | psInst->pui8Data[0];
+ }
+ if(pui16AccelY)
+ {
+ *pui16AccelY = (psInst->pui8Data[3] << 8) | psInst->pui8Data[2];
+ }
+ if(pui16AccelZ)
+ {
+ *pui16AccelZ = (psInst->pui8Data[5] << 8) | psInst->pui8Data[4];
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the accelerometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the LSM303DLHC instance data.
+//! \param pfAccelX is a pointer to the value into which the X-axis
+//! accelerometer data is stored.
+//! \param pfAccelY is a pointer to the value into which the Y-axis
+//! accelerometer data is stored.
+//! \param pfAccelZ is a pointer to the value into which the Z-axis
+//! accelerometer data is stored.
+//!
+//! This function returns the accelerometer data from the most recent data
+//! read, converted into meters per second squared (m/s^2). If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+LSM303DLHCAccelDataAccelGetFloat(tLSM303DLHCAccel *psInst, float *pfAccelX,
+ float *pfAccelY, float *pfAccelZ)
+{
+ float fFactor;
+
+ //
+ // Get the acceleration conversion factor for the current data format.
+ //
+ fFactor = g_pfLSM303DLHCAccelFactors[psInst->ui8AccelAfsSel];
+
+ //
+ // Convert the Accelerometer values into floating-point gravity values.
+ //
+ if(pfAccelX)
+ {
+ *pfAccelX = (float)(((int16_t)((psInst->pui8Data[1] << 8) |
+ psInst->pui8Data[0])) * fFactor);
+ }
+ if(pfAccelY)
+ {
+ *pfAccelY = (float)(((int16_t)((psInst->pui8Data[3] << 8) |
+ psInst->pui8Data[2])) * fFactor);
+ }
+ if(pfAccelZ)
+ {
+ *pfAccelZ = (float)(((int16_t)((psInst->pui8Data[5] << 8) |
+ psInst->pui8Data[4])) * fFactor);
+ }
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/lsm303dlhc_accel.h b/sensorlib/lsm303dlhc_accel.h new file mode 100644 index 0000000..00d72f7 --- /dev/null +++ b/sensorlib/lsm303dlhc_accel.h @@ -0,0 +1,163 @@ +//*****************************************************************************
+//
+// lsm303dlhc.c - Driver for the ST L3GD20H gyrometer
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_LSM303DLHC_ACCEL_H__
+#define __SENSORLIB_LSM303DLHC_ACCEL_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the LSM303DLHC driver.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The pointer to the I2C master interface instance used to communicate
+ // with the LSM303DLHC.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The I2C address of the LSM303DLHC.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The state of the state machine used while accessing the LSM303DLHC.
+ //
+ uint8_t ui8State;
+
+ //
+ // The current accelerometer afs_sel setting.
+ //
+ uint8_t ui8AccelAfsSel;
+
+ //
+ // The new accelerometer afs_sel setting, which is used when a register
+ // write succeeds.
+ //
+ uint8_t ui8NewAccelAfsSel;
+
+ //
+ // The data buffers used for sending/receiving data to/from the LSM303DLHC.
+ //
+ uint8_t pui8Data[8];
+
+ //
+ // The function that is called when the current request has completed
+ // processing.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The callback data provided to the callback function.
+ //
+ void *pvCallbackData;
+
+ //
+ // A union of structures that are used for read, write and
+ // read-modify-write operations. Since only one operation can be active at
+ // a time, it is safe to re-use the memory in this manner.
+ //
+ union
+ {
+ //
+ // A buffer used to store the write portion of a register read.
+ //
+ uint8_t pui8Buffer[2];
+
+ //
+ // The write state used to write register values.
+ //
+ tI2CMWrite8 sWriteState;
+
+ //
+ // The read-modify-write state used to modify register values.
+ //
+ tI2CMReadModifyWrite8 sReadModifyWriteState;
+ }
+ uCommand;
+}
+tLSM303DLHCAccel;
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern uint_fast8_t LSM303DLHCAccelInit(tLSM303DLHCAccel *psInst,
+ tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t LSM303DLHCAccelRead(tLSM303DLHCAccel *psInst,
+ uint_fast8_t ui8Reg,
+ uint8_t *pui8Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t LSM303DLHCAccelWrite(tLSM303DLHCAccel *psInst,
+ uint_fast8_t ui8Reg,
+ const uint8_t *pui8Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t LSM303DLHCAccelReadModifyWrite(tLSM303DLHCAccel *psInst,
+ uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask,
+ uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallbak,
+ void *pvCallbackData);
+extern uint_fast8_t LSM303DLHCAccelDataRead(tLSM303DLHCAccel *psInst,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern void LSM303DLHCAccelDataAccelGetRaw(tLSM303DLHCAccel *psInst,
+ uint_fast16_t *pui16AccelX,
+ uint_fast16_t *pui16AccelY,
+ uint_fast16_t *pui16AccelZ);
+extern void LSM303DLHCAccelDataAccelGetFloat(tLSM303DLHCAccel *psInst,
+ float *pfAccelX, float *pfAccelY,
+ float *pfAccelZ);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_LSM303DLHC_ACCEL_H__
diff --git a/sensorlib/lsm303dlhc_mag.c b/sensorlib/lsm303dlhc_mag.c new file mode 100644 index 0000000..d8abaa8 --- /dev/null +++ b/sensorlib/lsm303dlhc_mag.c @@ -0,0 +1,615 @@ +//*****************************************************************************
+//
+// lsm303dlhc.c - Driver for the ST LSM303DLHC magnetometer
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <stdint.h>
+#include "sensorlib/hw_lsm303dlhc.h"
+#include "sensorlib/i2cm_drv.h"
+#include "sensorlib/lsm303dlhc_mag.h"
+
+//*****************************************************************************
+//
+//! \addtogroup lsm303dlhc_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The states of the LSM303DLHC state machine.
+//
+//*****************************************************************************
+#define LSM303DLHC_STATE_IDLE 0 // State machine is idle
+#define LSM303DLHC_STATE_READ 1 // Waiting for read
+#define LSM303DLHC_STATE_WRITE 2 // Waiting for write
+#define LSM303DLHC_STATE_RMW 3 // Waiting for read-modify-write
+
+//*****************************************************************************
+//
+// The factors used to convert the magnetometer readings from the LSM303 into
+// floating point values in tesla
+//
+//*****************************************************************************
+static const float g_pfLSM303DLHCMagnetoFactors[] =
+{
+ 0,
+ 9.09E-08f,
+ 1.17E-07f,
+ 1.49E-07f,
+ 2.22E-07f,
+ 2.50E-07f,
+ 3.03E-07f,
+ 4.35E-07f,
+};
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transations to/from the
+// LSM303DLHC have completed.
+//
+//*****************************************************************************
+static void
+LSM303DLHCCallback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tLSM303DLHCMag *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tLSM303DLHC structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result in a callback to propagate the
+ // error).
+ //
+ if(ui8Status != I2CM_STATUS_SUCCESS)
+ {
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the LSM303DLHC state machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // All states that trivially transition to IDLE, and all unknown
+ // states.
+ //
+ case LSM303DLHC_STATE_READ:
+ default:
+ {
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // A write just completed
+ //
+ case LSM303DLHC_STATE_WRITE:
+ {
+ //
+ // Set the magneto ranges to the new values. If the register was
+ // not modified, the values will be the same so this has no effect.
+ //
+ psInst->ui8MagnetoFsSel = psInst->ui8NewMagnetoFsSel;
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // A read-modify-write just completed
+ //
+ case LSM303DLHC_STATE_RMW:
+ {
+ //
+ // See if the MAGNETO_CONFIG register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ LSM303DLHC_O_MAG_CRB)
+ {
+ //
+ // Extract the FS_SEL from the MAGNETO_CONFIG register value.
+ //
+ psInst->ui8MagnetoFsSel =
+ ((psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ LSM303DLHC_MAG_CRB_GAIN_M) >> LSM303DLHC_MAG_CRB_GAIN_S);
+ }
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == LSM303DLHC_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the LSM303DLHC driver.
+//!
+//! \param psInst is a pointer to the LSM303DLHC instance data.
+//! \param psI2CInst is a pointer to the I2C master driver instance data.
+//! \param ui8I2CAddr is the I2C address of the LSM303DLHC device.
+//! \param pfnCallback is the function to be called when the initialization has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initializes the LSM303DLHC driver, preparing it for
+//! operation.
+//!
+//! \return Returns 1 if the LSM303DLHC driver was successfully initialized and
+//! 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+LSM303DLHCMagInit(tLSM303DLHCMag *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Initialize the LSM303DLHC instance structure.
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8I2CAddr;
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Default range setting is +/- 1.3
+ // TODO: double-check default
+ //
+ psInst->ui8MagnetoFsSel = (LSM303DLHC_MAG_CRB_GAIN_1_3GAUSS >>
+ LSM303DLHC_MAG_CRB_GAIN_S);
+ psInst->ui8NewMagnetoFsSel = (LSM303DLHC_MAG_CRB_GAIN_1_3GAUSS >>
+ LSM303DLHC_MAG_CRB_GAIN_S);
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+
+ if(pfnCallback)
+ {
+ pfnCallback(pvCallbackData, I2CM_STATUS_SUCCESS);
+ }
+
+ //
+ // Success
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads data from LSM303DLHC registers.
+//!
+//! \param psInst is a pointer to the LSM303DLHC instance data.
+//! \param ui8Reg is the first register to read.
+//! \param pui8Data is a pointer to the location to store the data that is
+//! read.
+//! \param ui16Count is the number of data bytes to read.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function reads a sequence of data values from consecutive registers in
+//! the LSM303DLHC.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+LSM303DLHCMagRead(tLSM303DLHCMag *psInst, uint_fast8_t ui8Reg,
+ uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the LSM303DLHC driver is not idle (in other words,
+ // there is already an outstanding request to the LSM303DLHC).
+ //
+ if(psInst->ui8State != LSM303DLHC_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read state.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_READ;
+
+ //
+ // Read the requested registers from the LSM303DLHC.
+ //
+ psInst->uCommand.pui8Buffer[0] = ui8Reg;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, pui8Data, ui16Count,
+ LSM303DLHCCallback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Writes data to LSM303DLHC registers.
+//!
+//! \param psInst is a pointer to the LSM303DLHC instance data.
+//! \param ui8Reg is the first register to write.
+//! \param pui8Data is a pointer to the data to write.
+//! \param ui16Count is the number of data bytes to write.
+//! \param pfnCallback is the function to be called when the data has been
+//! written (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function writes a sequence of data values to consecutive registers in
+//! the LSM303DLHC. The first byte of the \e pui8Data buffer contains the
+//! value to be written into the \e ui8Reg register, the second value contains
+//! the data to be written into the next register, and so on.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+LSM303DLHCMagWrite(tLSM303DLHCMag *psInst, uint_fast8_t ui8Reg,
+ const uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the LSM303DLHC driver is not idle (in other words,
+ // there is already an outstanding request to the LSM303DLHC).
+ //
+ if(psInst->ui8State != LSM303DLHC_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // See if the MAGNETO_CONFIG register is being written.
+ //
+ if((ui8Reg <= LSM303DLHC_O_MAG_CRB) &&
+ ((ui8Reg + ui16Count) > LSM303DLHC_O_MAG_CRB))
+ {
+ //
+ // Extract the FS_SEL from the MAGNETO_CONFIG register value.
+ //
+ psInst->ui8NewMagnetoFsSel = ((pui8Data[ui8Reg - LSM303DLHC_O_MAG_CRB] &
+ LSM303DLHC_MAG_CRB_GAIN_M) >>
+ LSM303DLHC_MAG_CRB_GAIN_S);
+ }
+
+ //
+ // Move the state machine to the wait for write state.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_WRITE;
+
+ //
+ // Write the requested registers to the LSM303DLHC.
+ //
+ if(I2CMWrite8(&(psInst->uCommand.sWriteState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui8Data, ui16Count,
+ LSM303DLHCCallback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of a LSM303DLHC register.
+//!
+//! \param psInst is a pointer to the LSM303DLHC instance data.
+//! \param ui8Reg is the register to modify.
+//! \param ui8Mask is the bit mask that is ANDed with the current register
+//! value.
+//! \param ui8Value is the bit mask that is ORed with the result of the AND
+//! operation.
+//! \param pfnCallback is the function to be called when the data has been
+//! changed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function changes the value of a register in the LSM303DLHC via a
+//! read-modify-write operation, allowing one of the fields to be changed
+//! without disturbing the other fields. The \e ui8Reg register is read, ANDed
+//! with \e ui8Mask, ORed with \e ui8Value, and then written back to the
+//! LSM303DLHC.
+//!
+//! \return Returns 1 if the read-modify-write was successfully started and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+LSM303DLHCMagReadModifyWrite(tLSM303DLHCMag *psInst, uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask, uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the LSM303DLHC driver is not idle (in other words,
+ // there is already an outstanding request to the LSM303DLHC).
+ //
+ if(psInst->ui8State != LSM303DLHC_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read-modify-write state.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_RMW;
+
+ //
+ // Submit the read-modify-write request to the LSM303DLHC.
+ //
+ if(I2CMReadModifyWrite8(&(psInst->uCommand.sReadModifyWriteState),
+ psInst->psI2CInst, psInst->ui8Addr, ui8Reg,
+ ui8Mask, ui8Value, LSM303DLHCCallback,
+ psInst) == 0)
+ {
+ //
+ // The I2C read-modify-write failed, so move to the idle state and
+ // return a failure.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads the magneto data from the LSM303DLHC.
+//!
+//! \param psInst is a pointer to the LSM303DLHC instance data.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read of the LSM303DLHC data registers. When the
+//! read has completed (as indicated by calling the callback function), the new
+//! readings can be obtained via:
+//!
+//! - LSM303DLHCDataMagnetoGetRaw()
+//! - LSM303DLHCDataMagnetoGetFloat()
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+LSM303DLHCMagDataRead(tLSM303DLHCMag *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the LSM303DLHC driver is not idle (in other words,
+ // there is already an outstanding request to the LSM303DLHC).
+ //
+ if(psInst->ui8State != LSM303DLHC_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for data read state.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_READ;
+
+ //
+ // Read the data registers from the LSM303DLHC.
+ //
+ psInst->pui8Data[0] = LSM303DLHC_O_MAG_OUT_X_MSB;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr, psInst->pui8Data, 1,
+ psInst->pui8Data, 7, LSM303DLHCCallback, psInst) == 0)
+ {
+ //
+ // The I2C read failed, so move to the idle state and return a failure.
+ //
+ psInst->ui8State = LSM303DLHC_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Gets the raw magneto data from the most recent data read.
+//!
+//! \param psInst is a pointer to the LSM303DLHC instance data.
+//! \param pui16MagnetoX is a pointer to the value into which the raw X-axis
+//! magnetometer data is stored.
+//! \param pui16MagnetoY is a pointer to the value into which the raw Y-axis
+//! magnetometer data is stored.
+//! \param pui16MagnetoZ is a pointer to the value into which the raw Z-axis
+//! magnetometer data is stored.
+//!
+//! This function returns the raw magnetometer data from the most recent data
+//! read. The data is not manipulated in any way by the driver. If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+LSM303DLHCMagDataMagnetoGetRaw(tLSM303DLHCMag *psInst,
+ uint_fast16_t *pui16MagnetoX,
+ uint_fast16_t *pui16MagnetoY,
+ uint_fast16_t *pui16MagnetoZ)
+{
+ //
+ // Return the raw magnetometer values.
+ //
+ if(pui16MagnetoX)
+ {
+ *pui16MagnetoX = (psInst->pui8Data[0] << 8) | psInst->pui8Data[1];
+ }
+ if(pui16MagnetoY)
+ {
+ *pui16MagnetoY = (psInst->pui8Data[2] << 8) | psInst->pui8Data[3];
+ }
+ if(pui16MagnetoZ)
+ {
+ *pui16MagnetoZ = (psInst->pui8Data[4] << 8) | psInst->pui8Data[5];
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the magnetometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the LSM303DLHC instance data.
+//! \param pfMagnetoX is a pointer to the value into which the X-axis
+//! magnetometer data is stored.
+//! \param pfMagnetoY is a pointer to the value into which the Y-axis
+//! magnetometer data is stored.
+//! \param pfMagnetoZ is a pointer to the value into which the Z-axis
+//! magnetometer data is stored.
+//!
+//! This function returns the magnetometer data from the most recent data read,
+//! converted into radians per second. If any of the output data pointers are
+//! \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+LSM303DLHCMagDataMagnetoGetFloat(tLSM303DLHCMag *psInst, float *pfMagnetoX,
+ float *pfMagnetoY, float *pfMagnetoZ)
+{
+ float fFactor;
+
+ //
+ // Get the conversion factor for the current data format.
+ //
+ fFactor = g_pfLSM303DLHCMagnetoFactors[psInst->ui8MagnetoFsSel];
+
+ //
+ // Convert the magnetometer values into rad/sec
+ //
+ if(pfMagnetoX)
+ {
+ *pfMagnetoX = (float)(((int16_t)((psInst->pui8Data[0] << 8) |
+ psInst->pui8Data[1])) * fFactor);
+ }
+ if(pfMagnetoY)
+ {
+ *pfMagnetoY = (float)(((int16_t)((psInst->pui8Data[2] << 8) |
+ psInst->pui8Data[3])) * fFactor);
+ }
+ if(pfMagnetoZ)
+ {
+ *pfMagnetoZ = (float)(((int16_t)((psInst->pui8Data[4] << 8) |
+ psInst->pui8Data[5])) * fFactor);
+ }
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/lsm303dlhc_mag.h b/sensorlib/lsm303dlhc_mag.h new file mode 100644 index 0000000..a7426c3 --- /dev/null +++ b/sensorlib/lsm303dlhc_mag.h @@ -0,0 +1,164 @@ +//*****************************************************************************
+//
+// lsm303dlhc.c - Driver for the ST L3GD20H gyrometer
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_LSM303DLHC_MAG_H__
+#define __SENSORLIB_LSM303DLHC_MAG_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the LSM303DLHC driver.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The pointer to the I2C master interface instance used to communicate
+ // with the LSM303DLHC.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The I2C address of the LSM303DLHC.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The state of the state machine used while accessing the LSM303DLHC.
+ //
+ uint8_t ui8State;
+
+ //
+ // The current gyroscope fs_sel setting.
+ //
+ uint8_t ui8MagnetoFsSel;
+
+ //
+ // The new gyroscope fs_sel setting, which is used when a register write
+ // succeeds.
+ //
+ uint8_t ui8NewMagnetoFsSel;
+
+ //
+ // The data buffers used for sending/receiving data to/from the LSM303DLHC.
+ //
+ uint8_t pui8Data[8];
+
+ //
+ // The function that is called when the current request has completed
+ // processing.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The callback data provided to the callback function.
+ //
+ void *pvCallbackData;
+
+ //
+ // A union of structures that are used for read, write and
+ // read-modify-write operations. Since only one operation can be active at
+ // a time, it is safe to re-use the memory in this manner.
+ //
+ union
+ {
+ //
+ // A buffer used to store the write portion of a register read.
+ //
+ uint8_t pui8Buffer[2];
+
+ //
+ // The write state used to write register values.
+ //
+ tI2CMWrite8 sWriteState;
+
+ //
+ // The read-modify-write state used to modify register values.
+ //
+ tI2CMReadModifyWrite8 sReadModifyWriteState;
+ }
+ uCommand;
+}
+tLSM303DLHCMag;
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern uint_fast8_t LSM303DLHCMagInit(tLSM303DLHCMag *psInst,
+ tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t LSM303DLHCMagRead(tLSM303DLHCMag *psInst,
+ uint_fast8_t ui8Reg,
+ uint8_t *pui8Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t LSM303DLHCMagWrite(tLSM303DLHCMag *psInst,
+ uint_fast8_t ui8Reg,
+ const uint8_t *pui8Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t LSM303DLHCMagReadModifyWrite(tLSM303DLHCMag *psInst,
+ uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask,
+ uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t LSM303DLHCMagDataRead(tLSM303DLHCMag *psInst,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern void LSM303DLHCMagDataMagnetoGetRaw(tLSM303DLHCMag *psInst,
+ uint_fast16_t *pui16MagnetoX,
+ uint_fast16_t *pui16MagnetoY,
+ uint_fast16_t *pui16MagnetoZ);
+extern void LSM303DLHCMagDataMagnetoGetFloat(tLSM303DLHCMag *psInst,
+ float *pfMagnetoX,
+ float *pfMagnetoY,
+ float *pfMagnetoZ);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_LSM303DLHC_MAG_H__
diff --git a/sensorlib/magneto.c b/sensorlib/magneto.c new file mode 100644 index 0000000..b7f7595 --- /dev/null +++ b/sensorlib/magneto.c @@ -0,0 +1,248 @@ +//*****************************************************************************
+//
+// magneto.c - Functions for manipulating magnetometer readings.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <math.h>
+#include "sensorlib/magneto.h"
+
+//*****************************************************************************
+//
+//! \addtogroup magneto_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+//! Initializes the magnetometer hard- and soft-iron compensation state.
+//!
+//! \param psInst is a pointer to the magnetometer compensation state
+//! structure.
+//! \param fXOffset is the hard-iron compensation for the X axis.
+//! \param fYOffset is the hard-iron compensation for the Y axis.
+//! \param fZOffset is the hard-iron compensation for the Z axis.
+//! \param fXYAngle is the amount to rotate around the Z axis prior to scaling
+//! the Y axis reading, in radians.
+//! \param fYRatio is the amount to scale the Y axis reading.
+//! \param fXZAngle is the amount to rotate around the Y axis prior to scaling
+//! the Z axis reading, in radians.
+//! \param fZRatio is the amount to scale the Z axis reading.
+//!
+//! This function initializes the magnetometer compensation state structure
+//! with the values that are used to perform hard- and soft-iron compensation
+//! of magnetometer readings.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+MagnetoCompensateInit(tMagnetoCompensation *psInst, float fXOffset,
+ float fYOffset, float fZOffset, float fXYAngle,
+ float fYRatio, float fXZAngle, float fZRatio)
+{
+ //
+ // Save the hard- and soft-iron compensation values.
+ //
+ psInst->fXOffset = fXOffset;
+ psInst->fYOffset = fYOffset;
+ psInst->fZOffset = fZOffset;
+ psInst->fXYAngle = fXYAngle;
+ psInst->fYRatio = fYRatio;
+ psInst->fXZAngle = fXZAngle;
+ psInst->fZRatio = fZRatio;
+}
+
+//*****************************************************************************
+//
+//! Performs hard- and soft-iron compensation on magnetometer readings.
+//!
+//! \param psInst is a pointer to the magnetometer compensation state
+//! structure.
+//! \param pfMagnetoX is a pointer to the magnetometer X-axis reading.
+//! \param pfMagnetoY is a pointer to the magnetometer Y-axis reading.
+//! \param pfMagnetoZ is a pointer to the magnetometer Z-axis reading.
+//!
+//! This function performs hard- and soft-iron compensation on the given
+//! magnetometer reading. Hard-iron distortions cause a fixed offset in the
+//! reading, regardless of orientation. Hard-iron compensation is performed by
+//! negating this fixed offset.
+//!
+//! Soft-iron distortion is more complicated, causing an offset that varies as
+//! the sensor rotates, which results in the sensor returning an ellipse as it
+//! rotates instead of a circle. Performing soft-iron compensation requires
+//! rotating the sensor reading such that the major axis of the ellipse is
+//! aligned with one of the magnetometer axes, scaling one of the axes, then
+//! rotating the scaled sensor reading back. This operation is performed two
+//! times; once to scale the Y axis to the same scale as the X axis, and once
+//! again to scale the Z axis to the same scale as the X axis.
+//!
+//! Hard-iron compensation is performed prior to soft-iron compensation.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+MagnetoCompensate(tMagnetoCompensation *psInst, float *pfMagnetoX,
+ float *pfMagnetoY, float *pfMagnetoZ)
+{
+ float fSin, fCos, fX, fY, fZ, fTemp;
+
+ //
+ // Get the magnetometer values.
+ //
+ fX = *pfMagnetoX;
+ fY = *pfMagnetoY;
+ fZ = *pfMagnetoZ;
+
+ //
+ // Perform hard-iron distortion compensation.
+ //
+ fX += psInst->fXOffset;
+ fY += psInst->fYOffset;
+ fZ += psInst->fZOffset;
+
+ //
+ // Perform soft-iron distortion compensation on the X-Y plane. Start by
+ // computing the sine and cosine of the rotation angle (which will be used
+ // multiple times below).
+ //
+ fSin = sinf(psInst->fXYAngle);
+ fCos = cosf(psInst->fXYAngle);
+
+ //
+ // Rotate the magnetometer reading around the Z axis.
+ //
+ fTemp = (fCos * fX) - (fSin * fY);
+ fY = (fCos * fY) + (fSin * fX);
+ fX = fTemp;
+
+ //
+ // Scale the Y-axis reading so that it has the same range as the X-axis
+ // reading.
+ //
+ fY *= psInst->fYRatio;
+
+ //
+ // Rotate the magnetometer reading around the Z axis again, this time in
+ // the opposite direction.
+ //
+ fTemp = (fCos * fX) + (fSin * fY);
+ fY = (fCos * fY) - (fSin * fX);
+ fX = fTemp;
+
+ //
+ // Perform soft-iron distortion compensation on the X-Z plane. Start by
+ // computing the sine and cosine of the rotation angle (which will be used
+ // multiple times below).
+ //
+ fSin = sinf(psInst->fXZAngle);
+ fCos = cosf(psInst->fXZAngle);
+
+ //
+ // Rotate the magnetometer reading around the Y axis.
+ //
+ fTemp = (fCos * fZ) - (fSin * fX);
+ fX = (fCos * fX) + (fSin * fZ);
+ fZ = fTemp;
+
+ //
+ // Scale the Z-axis reading so that it has the same range as the X-axis
+ // reading.
+ //
+ fZ *= psInst->fZRatio;
+
+ //
+ // Rotate the magnetometer reading around the Y axis again, this time in
+ // the opposite direction.
+ //
+ fTemp = (fCos * fZ) + (fSin * fX);
+ fX = (fCos * fX) - (fSin * fZ);
+ fZ = fTemp;
+
+ //
+ // Return the compensated magnetometer values.
+ //
+ *pfMagnetoX = fX;
+ *pfMagnetoY = fY;
+ *pfMagnetoZ = fZ;
+}
+
+//*****************************************************************************
+//
+//! Computes the compass heading from magnetometer data and roll/pitch.
+//!
+//! \param fMagnetoX is the X component of the magnetometer reading.
+//! \param fMagnetoY is the Y component of the magnetometer reading.
+//! \param fMagnetoZ is the Z component of the magnetometer reading.
+//! \param fRoll is the roll angle, in radians.
+//! \param fPitch is the pitch angle, in radians.
+//!
+//! This function computes the compass heading by performing tilt compensation
+//! on the magnetometer reading.
+//!
+//! \return Returns the compass heading, in radians.
+//
+//*****************************************************************************
+float
+MagnetoHeadingCompute(float fMagnetoX, float fMagnetoY, float fMagnetoZ,
+ float fRoll, float fPitch)
+{
+ float fSinRoll, fCosRoll, fSinPitch, fCosPitch, fX, fY, fHeading;
+
+ //
+ // Compute the sine and cosine of the roll and pitch angles.
+ //
+ fSinRoll = sinf(fRoll);
+ fCosRoll = cosf(fRoll);
+ fSinPitch = sinf(fPitch);
+ fCosPitch = cosf(fPitch);
+
+ //
+ // Rotate the magnetometer data such that it is level with the ground,
+ // based on the provided roll and pitch.
+ //
+ fX = ((fMagnetoX * fCosPitch) + (fMagnetoY * fSinRoll * fSinPitch) +
+ (fMagnetoZ * fCosRoll * fSinPitch));
+ fY = (fMagnetoY * fCosRoll) - (fMagnetoZ * fSinRoll);
+
+ //
+ // Compute the compass heading and make it positive.
+ //
+ fHeading = atan2f(-fY, fX);
+ if(fHeading < 0)
+ {
+ fHeading += 2 * 3.141592;
+ }
+
+ //
+ // Return the computed compass heading.
+ //
+ return(fHeading);
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/magneto.h b/sensorlib/magneto.h new file mode 100644 index 0000000..811491e --- /dev/null +++ b/sensorlib/magneto.h @@ -0,0 +1,92 @@ +//*****************************************************************************
+//
+// magneto.h - Prototypes for the functions that manipulate magnetometer
+// readings.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_MAGNETO_H__
+#define __SENSORLIB_MAGNETO_H__
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the magnetometer hard and
+// soft iron compensation.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The hard iron induced offset in the X axis of the magnetometer.
+ //
+ float fXOffset;
+
+ //
+ // The hard iron induced offset in the Y axis of the magnetometer.
+ //
+ float fYOffset;
+
+ //
+ // The hard iron induced offset in the Z axis of the magnetometer.
+ //
+ float fZOffset;
+
+ //
+ // The Z axis rotation required to align the major/minor axes of the
+ // ellipse in the X-Y plane with the X-Y axes, specified in radians.
+ //
+ float fXYAngle;
+
+ //
+ // The amount to scale the Y axis in order to turn the X-Y ellipse into a
+ // circle.
+ //
+ float fYRatio;
+
+ //
+ // The Y axis rotation required to align the major/minor axes of the
+ // ellipse in the X-Z plane with X-Z axes, specified in radians.
+ //
+ float fXZAngle;
+
+ //
+ // The amount to scale the Z axis in order to turn the X-Z ellipse into a
+ // circle.
+ //
+ float fZRatio;
+}
+tMagnetoCompensation;
+
+//*****************************************************************************
+//
+// Prototypes.
+//
+//*****************************************************************************
+extern void MagnetoCompensateInit(tMagnetoCompensation *psInst, float fXOffset,
+ float fYOffset, float fZOffset,
+ float fXYAngle, float fYRatio,
+ float fXZAngle, float fZRatio);
+extern void MagnetoCompensate(tMagnetoCompensation *psInst, float *pfMagnetoX,
+ float *pfMagnetoY, float *pfMagnetoZ);
+extern float MagnetoHeadingCompute(float fMagnetoX, float fMagnetoY,
+ float fMagnetoZ, float fRoll, float fPitch);
+
+#endif // __SENSORLIB_MAGNETO_H__
diff --git a/sensorlib/mpu6050.c b/sensorlib/mpu6050.c new file mode 100644 index 0000000..f095e40 --- /dev/null +++ b/sensorlib/mpu6050.c @@ -0,0 +1,879 @@ +//*****************************************************************************
+//
+// mpu6050.c - Driver for the MPU6050 accelerometer and gyroscope.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <stdint.h>
+#include "sensorlib/hw_mpu6050.h"
+#include "sensorlib/i2cm_drv.h"
+#include "sensorlib/mpu6050.h"
+
+//*****************************************************************************
+//
+//! \addtogroup mpu6050_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The states of the MPU6050 state machine.
+//
+//*****************************************************************************
+#define MPU6050_STATE_IDLE 0 // State machine is idle
+#define MPU6050_STATE_INIT_RES 1 // Waiting for initialization
+#define MPU6050_STATE_INIT_WAIT 2 // Waiting for reset to complete
+#define MPU6050_STATE_READ 3 // Waiting for read
+#define MPU6050_STATE_WRITE 4 // Waiting for write
+#define MPU6050_STATE_RMW 5 // Waiting for read-modify-write
+
+//*****************************************************************************
+//
+// The factors used to convert the acceleration readings from the MPU6050 into
+// floating point values in meters per second squared.
+//
+// Values are obtained by taking the g conversion factors from the data sheet
+// and multiplying by 9.81 (1 g = 9.81 m/s^2).
+//
+//*****************************************************************************
+static const float g_fMPU6050AccelFactors[] =
+{
+ 0.00059875, // Range = +/- 2 g (16384 lsb/g)
+ 0.00119751, // Range = +/- 4 g (8192 lsb/g)
+ 0.00239502, // Range = +/- 8 g (4096 lsb/g)
+ 0.00479004 // Range = +/- 16 g (2048 lsb/g)
+};
+
+//*****************************************************************************
+//
+// The factors used to convert the acceleration readings from the MPU6050 into
+// floating point values in radians per second.
+//
+// Values are obtained by taking the degree per second conversion factors
+// from the data sheet and then converting to radians per sec (1 degree =
+// 0.0174532925 radians).
+//
+//*****************************************************************************
+static const float g_fMPU6050GyroFactors[] =
+{
+ 1.3323124e-4f, // Range = +/- 250 dps (131.0 LSBs/DPS)
+ 2.6646248e-4f, // Range = +/- 500 dps (65.5 LSBs/DPS)
+ 5.3211258e-4f, // Range = +/- 1000 dps (32.8 LSBs/DPS)
+ 0.0010642252f // Range = +/- 2000 dps (16.4 LSBs/DPS)
+};
+//*****************************************************************************
+//
+// The callback function that is called when I2C transations to/from the
+// MPU6050 have completed.
+//
+//*****************************************************************************
+static void
+MPU6050Callback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tMPU6050 *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tMPU6050 structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result in a callback to propagate the
+ // error). Except in the case that we are in the reset wait state and the
+ // error is an address NACK. This error is handled by the reset wait
+ // state.
+ //
+ if((ui8Status != I2CM_STATUS_SUCCESS) &&
+ !((ui8Status == I2CM_STATUS_ADDR_NACK) &&
+ (psInst->ui8State == MPU6050_STATE_INIT_WAIT)))
+ {
+ psInst->ui8State = MPU6050_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the MPU6050 state machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // All states that trivially transition to IDLE, and all unknown
+ // states.
+ //
+ case MPU6050_STATE_READ:
+ default:
+ {
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = MPU6050_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // MPU6050 Device reset was issued
+ //
+ case MPU6050_STATE_INIT_RES:
+ {
+ //
+ // Issue a read of the status register to confirm reset is done.
+ //
+ psInst->uCommand.pui8Buffer[0] = MPU6050_O_PWR_MGMT_1;
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 1,
+ MPU6050Callback, psInst);
+
+ psInst->ui8State = MPU6050_STATE_INIT_WAIT;
+ break;
+ }
+
+ //
+ // Status register was read, check if reset is done before proceeding.
+ //
+ case MPU6050_STATE_INIT_WAIT:
+ {
+ //
+ // Check the value read back from status to determine if device
+ // is still in reset or if it is ready. Reset state for this
+ // register is 0x40, which has sleep bit set. Device may also
+ // respond with an address NACK during very early stages of the its
+ // internal reset. Keep polling until we verify device is ready.
+ //
+ //
+ if((psInst->pui8Data[0] != MPU6050_PWR_MGMT_1_SLEEP) ||
+ (ui8Status == I2CM_STATUS_ADDR_NACK))
+ {
+ //
+ // Device still in reset so begin polling this register.
+ //
+ psInst->uCommand.pui8Buffer[0] = MPU6050_O_PWR_MGMT_1;
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 1,
+ MPU6050Callback, psInst);
+
+ //
+ // Intentionally stay in this state to create polling effect.
+ //
+ }
+ else
+ {
+ //
+ // Device is out of reset, move to the idle state.
+ //
+ psInst->ui8State = MPU6050_STATE_IDLE;
+ }
+ break;
+ }
+
+ //
+ // A write just completed
+ //
+ case MPU6050_STATE_WRITE:
+ {
+ //
+ // Set the accelerometer and gyroscope ranges to the new values.
+ // If the register was not modified, the values will be the same so
+ // this has no effect.
+ //
+ psInst->ui8AccelAfsSel = psInst->ui8NewAccelAfsSel;
+ psInst->ui8GyroFsSel = psInst->ui8NewGyroFsSel;
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = MPU6050_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // A read-modify-write just completed
+ //
+ case MPU6050_STATE_RMW:
+ {
+ //
+ // See if the PWR_MGMT_1 register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ MPU6050_O_PWR_MGMT_1)
+ {
+ //
+ // See if a soft reset has been issued.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ MPU6050_PWR_MGMT_1_DEVICE_RESET)
+ {
+ //
+ // Default range setting is +/- 2 g
+ //
+ psInst->ui8AccelAfsSel = 0;
+ psInst->ui8NewAccelAfsSel = 0;
+
+ //
+ // Default range setting is +/- 250 degrees/s
+ //
+ psInst->ui8GyroFsSel = 0;
+ psInst->ui8NewGyroFsSel = 0;
+ }
+ }
+
+ //
+ // See if the GYRO_CONFIG register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ MPU6050_O_GYRO_CONFIG)
+ {
+ //
+ // Extract the FS_SEL from the GYRO_CONFIG register value.
+ //
+ psInst->ui8GyroFsSel =
+ ((psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ MPU6050_GYRO_CONFIG_FS_SEL_M) >>
+ MPU6050_GYRO_CONFIG_FS_SEL_S);
+ }
+
+ //
+ // See if the ACCEL_CONFIG register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ MPU6050_O_ACCEL_CONFIG)
+ {
+ //
+ // Extract the FS_SEL from the ACCEL_CONFIG register value.
+ //
+ psInst->ui8AccelAfsSel =
+ ((psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ MPU6050_ACCEL_CONFIG_AFS_SEL_M) >>
+ MPU6050_ACCEL_CONFIG_AFS_SEL_S);
+ }
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = MPU6050_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == MPU6050_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the MPU6050 driver.
+//!
+//! \param psInst is a pointer to the MPU6050 instance data.
+//! \param psI2CInst is a pointer to the I2C master driver instance data.
+//! \param ui8I2CAddr is the I2C address of the MPU6050 device.
+//! \param pfnCallback is the function to be called when the initialization has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initializes the MPU6050 driver, preparing it for operation.
+//!
+//! \return Returns 1 if the MPU6050 driver was successfully initialized and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+MPU6050Init(tMPU6050 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Initialize the MPU6050 instance structure.
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8I2CAddr;
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Default range setting is +/- 2 g
+ //
+ psInst->ui8AccelAfsSel = (MPU6050_ACCEL_CONFIG_AFS_SEL_2G >>
+ MPU6050_ACCEL_CONFIG_AFS_SEL_S);
+ psInst->ui8NewAccelAfsSel = (MPU6050_ACCEL_CONFIG_AFS_SEL_2G >>
+ MPU6050_ACCEL_CONFIG_AFS_SEL_S);
+
+ //
+ // Default range setting is +/- 250 degrees/s
+ //
+ psInst->ui8GyroFsSel = (MPU6050_GYRO_CONFIG_FS_SEL_250 >>
+ MPU6050_GYRO_CONFIG_FS_SEL_S);
+ psInst->ui8NewGyroFsSel = (MPU6050_GYRO_CONFIG_FS_SEL_250 >>
+ MPU6050_GYRO_CONFIG_FS_SEL_S);
+
+ //
+ // Set the state to show we are initiating a reset.
+ //
+ psInst->ui8State = MPU6050_STATE_INIT_RES;
+
+ //
+ // Load the buffer with command to perform device reset
+ //
+ psInst->uCommand.pui8Buffer[0] = MPU6050_O_PWR_MGMT_1;
+ psInst->uCommand.pui8Buffer[1] = MPU6050_PWR_MGMT_1_DEVICE_RESET;
+ if(I2CMWrite(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 2, MPU6050Callback, psInst) == 0)
+ {
+ psInst->ui8State = MPU6050_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads data from MPU6050 registers.
+//!
+//! \param psInst is a pointer to the MPU6050 instance data.
+//! \param ui8Reg is the first register to read.
+//! \param pui8Data is a pointer to the location to store the data that is
+//! read.
+//! \param ui16Count is the number of data bytes to read.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function reads a sequence of data values from consecutive registers in
+//! the MPU6050.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+MPU6050Read(tMPU6050 *psInst, uint_fast8_t ui8Reg, uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the MPU6050 driver is not idle (in other words,
+ // there is already an outstanding request to the MPU6050).
+ //
+ if(psInst->ui8State != MPU6050_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read state.
+ //
+ psInst->ui8State = MPU6050_STATE_READ;
+
+ //
+ // Read the requested registers from the MPU6050.
+ //
+ psInst->uCommand.pui8Buffer[0] = ui8Reg;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, pui8Data, ui16Count,
+ MPU6050Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = MPU6050_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Writes data to MPU6050 registers.
+//!
+//! \param psInst is a pointer to the MPU6050 instance data.
+//! \param ui8Reg is the first register to write.
+//! \param pui8Data is a pointer to the data to write.
+//! \param ui16Count is the number of data bytes to write.
+//! \param pfnCallback is the function to be called when the data has been
+//! written (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function writes a sequence of data values to consecutive registers in
+//! the MPU6050. The first byte of the \e pui8Data buffer contains the value
+//! to be written into the \e ui8Reg register, the second value contains the
+//! data to be written into the next register, and so on.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+MPU6050Write(tMPU6050 *psInst, uint_fast8_t ui8Reg, const uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the MPU6050 driver is not idle (in other words,
+ // there is already an outstanding request to the MPU6050).
+ //
+ if(psInst->ui8State != MPU6050_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // See if the PWR_MGMT_1 register is being written.
+ //
+ if((ui8Reg <= MPU6050_O_PWR_MGMT_1) &&
+ ((ui8Reg + ui16Count) > MPU6050_O_PWR_MGMT_1))
+ {
+ //
+ // See if a soft reset is being requested.
+ //
+ if(pui8Data[ui8Reg - MPU6050_O_PWR_MGMT_1] &
+ MPU6050_PWR_MGMT_1_DEVICE_RESET)
+ {
+ //
+ // Default range setting is +/- 2 g.
+ //
+ psInst->ui8NewAccelAfsSel = 0;
+
+ //
+ // Default range setting is +/- 250 degrees/s.
+ //
+ psInst->ui8NewGyroFsSel = 0;
+ }
+ }
+
+ //
+ // See if the GYRO_CONFIG register is being written.
+ //
+ if((ui8Reg <= MPU6050_O_GYRO_CONFIG) &&
+ ((ui8Reg + ui16Count) > MPU6050_O_GYRO_CONFIG))
+ {
+ //
+ // Extract the FS_SEL from the GYRO_CONFIG register value.
+ //
+ psInst->ui8NewGyroFsSel = ((pui8Data[ui8Reg - MPU6050_O_GYRO_CONFIG] &
+ MPU6050_GYRO_CONFIG_FS_SEL_M) >>
+ MPU6050_GYRO_CONFIG_FS_SEL_S);
+ }
+
+ //
+ // See if the ACCEL_CONFIG register is being written.
+ //
+ if((ui8Reg <= MPU6050_O_ACCEL_CONFIG) &&
+ ((ui8Reg + ui16Count) > MPU6050_O_ACCEL_CONFIG))
+ {
+ //
+ // Extract the AFS_SEL from the ACCEL_CONFIG register value.
+ //
+ psInst->ui8NewAccelAfsSel =
+ ((pui8Data[ui8Reg - MPU6050_O_ACCEL_CONFIG] &
+ MPU6050_ACCEL_CONFIG_AFS_SEL_M) >>
+ MPU6050_ACCEL_CONFIG_AFS_SEL_S);
+ }
+
+ //
+ // Move the state machine to the wait for write state.
+ //
+ psInst->ui8State = MPU6050_STATE_WRITE;
+
+ //
+ // Write the requested registers to the MPU6050.
+ //
+ if(I2CMWrite8(&(psInst->uCommand.sWriteState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui8Data, ui16Count,
+ MPU6050Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = MPU6050_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of a MPU6050 register.
+//!
+//! \param psInst is a pointer to the MPU6050 instance data.
+//! \param ui8Reg is the register to modify.
+//! \param ui8Mask is the bit mask that is ANDed with the current register
+//! value.
+//! \param ui8Value is the bit mask that is ORed with the result of the AND
+//! operation.
+//! \param pfnCallback is the function to be called when the data has been
+//! changed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function changes the value of a register in the MPU6050 via a
+//! read-modify-write operation, allowing one of the fields to be changed
+//! without disturbing the other fields. The \e ui8Reg register is read, ANDed
+//! with \e ui8Mask, ORed with \e ui8Value, and then written back to the
+//! MPU6050.
+//!
+//! \return Returns 1 if the read-modify-write was successfully started and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+MPU6050ReadModifyWrite(tMPU6050 *psInst, uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask, uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the MPU6050 driver is not idle (in other words,
+ // there is already an outstanding request to the MPU6050).
+ //
+ if(psInst->ui8State != MPU6050_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read-modify-write state.
+ //
+ psInst->ui8State = MPU6050_STATE_RMW;
+
+ //
+ // Submit the read-modify-write request to the MPU6050.
+ //
+ if(I2CMReadModifyWrite8(&(psInst->uCommand.sReadModifyWriteState),
+ psInst->psI2CInst, psInst->ui8Addr, ui8Reg,
+ ui8Mask, ui8Value, MPU6050Callback, psInst) == 0)
+ {
+ //
+ // The I2C read-modify-write failed, so move to the idle state and
+ // return a failure.
+ //
+ psInst->ui8State = MPU6050_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads the accelerometer and gyroscope data from the MPU6050.
+//!
+//! \param psInst is a pointer to the MPU6050 instance data.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read of the MPU6050 data registers. When the
+//! read has completed (as indicated by calling the callback function), the new
+//! readings can be obtained via:
+//!
+//! - MPU6050DataAccelGetRaw()
+//! - MPU6050DataAccelGetFloat()
+//! - MPU6050DataGyroGetRaw()
+//! - MPU6050DataGyroGetFloat()
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+MPU6050DataRead(tMPU6050 *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the MPU6050 driver is not idle (in other words,
+ // there is already an outstanding request to the MPU6050).
+ //
+ if(psInst->ui8State != MPU6050_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for data read state.
+ //
+ psInst->ui8State = MPU6050_STATE_READ;
+
+ //
+ // Read the data registers from the MPU6050.
+ //
+ psInst->pui8Data[0] = MPU6050_O_ACCEL_XOUT_H;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr, psInst->pui8Data, 1,
+ psInst->pui8Data, 14, MPU6050Callback, psInst) == 0)
+ {
+ //
+ // The I2C read failed, so move to the idle state and return a failure.
+ //
+ psInst->ui8State = MPU6050_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Gets the raw accelerometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the MPU6050 instance data.
+//! \param pui16AccelX is a pointer to the value into which the raw X-axis
+//! accelerometer data is stored.
+//! \param pui16AccelY is a pointer to the value into which the raw Y-axis
+//! accelerometer data is stored.
+//! \param pui16AccelZ is a pointer to the value into which the raw Z-axis
+//! accelerometer data is stored.
+//!
+//! This function returns the raw accelerometer data from the most recent data
+//! read. The data is not manipulated in any way by the driver. If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+MPU6050DataAccelGetRaw(tMPU6050 *psInst, uint_fast16_t *pui16AccelX,
+ uint_fast16_t *pui16AccelY, uint_fast16_t *pui16AccelZ)
+{
+ //
+ // Return the raw accelerometer values.
+ //
+ if(pui16AccelX)
+ {
+ *pui16AccelX = (psInst->pui8Data[0] << 8) | psInst->pui8Data[1];
+ }
+ if(pui16AccelY)
+ {
+ *pui16AccelY = (psInst->pui8Data[2] << 8) | psInst->pui8Data[3];
+ }
+ if(pui16AccelZ)
+ {
+ *pui16AccelZ = (psInst->pui8Data[4] << 8) | psInst->pui8Data[5];
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the accelerometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the MPU6050 instance data.
+//! \param pfAccelX is a pointer to the value into which the X-axis
+//! accelerometer data is stored.
+//! \param pfAccelY is a pointer to the value into which the Y-axis
+//! accelerometer data is stored.
+//! \param pfAccelZ is a pointer to the value into which the Z-axis
+//! accelerometer data is stored.
+//!
+//! This function returns the accelerometer data from the most recent data
+//! read, converted into meters per second squared (m/s^2). If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+MPU6050DataAccelGetFloat(tMPU6050 *psInst, float *pfAccelX, float *pfAccelY,
+ float *pfAccelZ)
+{
+ float fFactor;
+
+ //
+ // Get the acceleration conversion factor for the current data format.
+ //
+ fFactor = g_fMPU6050AccelFactors[psInst->ui8AccelAfsSel];
+
+ //
+ // Convert the Accelerometer values into floating-point gravity values.
+ //
+ if(pfAccelX)
+ {
+ *pfAccelX = (float)((int16_t)((psInst->pui8Data[0] << 8) |
+ psInst->pui8Data[1]) * fFactor);
+ }
+ if(pfAccelY)
+ {
+ *pfAccelY = (float)((int16_t)((psInst->pui8Data[2] << 8) |
+ psInst->pui8Data[3]) * fFactor);
+ }
+ if(pfAccelZ)
+ {
+ *pfAccelZ = (float)((int16_t)((psInst->pui8Data[4] << 8) |
+ psInst->pui8Data[5]) * fFactor);
+ }
+}
+//*****************************************************************************
+//
+//! Gets the raw gyroscope data from the most recent data read.
+//!
+//! \param psInst is a pointer to the MPU6050 instance data.
+//! \param pui16GyroX is a pointer to the value into which the raw X-axis
+//! gyroscope data is stored.
+//! \param pui16GyroY is a pointer to the value into which the raw Y-axis
+//! gyroscope data is stored.
+//! \param pui16GyroZ is a pointer to the value into which the raw Z-axis
+//! gyroscope data is stored.
+//!
+//! This function returns the raw gyroscope data from the most recent data
+//! read. The data is not manipulated in any way by the driver. If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+MPU6050DataGyroGetRaw(tMPU6050 *psInst, uint_fast16_t *pui16GyroX,
+ uint_fast16_t *pui16GyroY, uint_fast16_t *pui16GyroZ)
+{
+ //
+ // Return the raw gyroscope values.
+ //
+ if(pui16GyroX)
+ {
+ *pui16GyroX = (psInst->pui8Data[8] << 8) | psInst->pui8Data[9];
+ }
+ if(pui16GyroY)
+ {
+ *pui16GyroY = (psInst->pui8Data[10] << 8) | psInst->pui8Data[11];
+ }
+ if(pui16GyroZ)
+ {
+ *pui16GyroZ = (psInst->pui8Data[12] << 8) | psInst->pui8Data[13];
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the gyroscope data from the most recent data read.
+//!
+//! \param psInst is a pointer to the MPU6050 instance data.
+//! \param pfGyroX is a pointer to the value into which the X-axis
+//! gyroscope data is stored.
+//! \param pfGyroY is a pointer to the value into which the Y-axis
+//! gyroscope data is stored.
+//! \param pfGyroZ is a pointer to the value into which the Z-axis
+//! gyroscope data is stored.
+//!
+//! This function returns the gyroscope data from the most recent data read,
+//! converted into radians per second. If any of the output data pointers are
+//! \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+MPU6050DataGyroGetFloat(tMPU6050 *psInst, float *pfGyroX, float *pfGyroY,
+ float *pfGyroZ)
+{
+ float fFactor;
+
+ //
+ // Get the conversion factor for the current data format.
+ //
+ fFactor = g_fMPU6050GyroFactors[psInst->ui8GyroFsSel];
+
+ //
+ // Convert the gyroscope values into rad/sec
+ //
+ if(pfGyroX)
+ {
+ *pfGyroX = ((float)(int16_t)((psInst->pui8Data[8] << 8) |
+ psInst->pui8Data[9]) * fFactor);
+ }
+ if(pfGyroY)
+ {
+ *pfGyroY = ((float)(int16_t)((psInst->pui8Data[10] << 8) |
+ psInst->pui8Data[11]) * fFactor);
+ }
+ if(pfGyroZ)
+ {
+ *pfGyroZ = ((float)(int16_t)((psInst->pui8Data[12] << 8) |
+ psInst->pui8Data[13]) * fFactor);
+ }
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/mpu6050.h b/sensorlib/mpu6050.h new file mode 100644 index 0000000..ec11ab8 --- /dev/null +++ b/sensorlib/mpu6050.h @@ -0,0 +1,174 @@ +//*****************************************************************************
+//
+// mpu6050.h - Prototypes for the MPU6050 accelerometer and gyroscope driver.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_MPU6050_H__
+#define __SENSORLIB_MPU6050_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the MPU6050 driver.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The pointer to the I2C master interface instance used to communicate
+ // with the MPU6050.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The I2C address of the MPU6050.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The state of the state machine used while accessing the MPU6050.
+ //
+ uint8_t ui8State;
+
+ //
+ // The current accelerometer afs_sel setting.
+ //
+ uint8_t ui8AccelAfsSel;
+
+ //
+ // The new accelerometer afs_sel setting, which is used when a register
+ // write succeeds.
+ //
+ uint8_t ui8NewAccelAfsSel;
+
+ //
+ // The current gyroscope fs_sel setting.
+ //
+ uint8_t ui8GyroFsSel;
+
+ //
+ // The new gyroscope fs_sel setting, which is used when a register write
+ // succeeds.
+ //
+ uint8_t ui8NewGyroFsSel;
+
+ //
+ // The data buffer used for sending/receiving data to/from the MPU6050.
+ //
+ uint8_t pui8Data[16];
+
+ //
+ // The function that is called when the current request has completed
+ // processing.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The callback data provided to the callback function.
+ //
+ void *pvCallbackData;
+
+ //
+ // A union of structures that are used for read, write and
+ // read-modify-write operations. Since only one operation can be active at
+ // a time, it is safe to re-use the memory in this manner.
+ //
+ union
+ {
+ //
+ // A buffer used to store the write portion of a register read.
+ //
+ uint8_t pui8Buffer[2];
+
+ //
+ // The write state used to write register values.
+ //
+ tI2CMWrite8 sWriteState;
+
+ //
+ // The read-modify-write state used to modify register values.
+ //
+ tI2CMReadModifyWrite8 sReadModifyWriteState;
+ }
+ uCommand;
+}
+tMPU6050;
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern uint_fast8_t MPU6050Init(tMPU6050 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t MPU6050Read(tMPU6050 *psInst, uint_fast8_t ui8Reg,
+ uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t MPU6050Write(tMPU6050 *psInst, uint_fast8_t ui8Reg,
+ const uint8_t *pui8Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t MPU6050ReadModifyWrite(tMPU6050 *psInst,
+ uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask,
+ uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t MPU6050DataRead(tMPU6050 *psInst,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern void MPU6050DataAccelGetRaw(tMPU6050 *psInst,
+ uint_fast16_t *pui16AccelX,
+ uint_fast16_t *pui16AccelY,
+ uint_fast16_t *pui16AccelZ);
+extern void MPU6050DataAccelGetFloat(tMPU6050 *psInst, float *pfAccelX,
+ float *pfAccelY, float *pfAccelZ);
+extern void MPU6050DataGyroGetRaw(tMPU6050 *psInst, uint_fast16_t *pui16GyroX,
+ uint_fast16_t *pui16GyroY,
+ uint_fast16_t *pui16GyroZ);
+extern void MPU6050DataGyroGetFloat(tMPU6050 *psInst, float *pfGyroX,
+ float *pfGyroY, float *pfGyroZ);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_MPU6050_H__
diff --git a/sensorlib/mpu9150.c b/sensorlib/mpu9150.c new file mode 100644 index 0000000..a1515e2 --- /dev/null +++ b/sensorlib/mpu9150.c @@ -0,0 +1,1180 @@ +//*****************************************************************************
+//
+// mpu9150.c - Driver for the MPU9150 accelerometer, gyroscope, and
+// magnetometer.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <stdint.h>
+#include "sensorlib/hw_ak8975.h"
+#include "sensorlib/hw_mpu9150.h"
+#include "sensorlib/i2cm_drv.h"
+#include "sensorlib/ak8975.h"
+#include "sensorlib/mpu9150.h"
+
+//*****************************************************************************
+//
+//! \addtogroup mpu9150_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The states of the MPU9150 state machine.
+//
+//*****************************************************************************
+#define MPU9150_STATE_IDLE 0 // State machine is idle
+#define MPU9150_STATE_LAST 1 // Last step in a sequence
+#define MPU9150_STATE_READ 2 // Waiting for read
+#define MPU9150_STATE_WRITE 3 // Waiting for write
+#define MPU9150_STATE_RMW 4 // Waiting for read modify write
+#define MPU9150_STATE_INIT_RESET \
+ 5 // reset request issued.
+#define MPU9150_STATE_INIT_RESET_WAIT \
+ 6 // polling wait for reset complete
+#define MPU9150_STATE_INIT_PWR_MGMT \
+ 7 // wake up the device.
+#define MPU9150_STATE_INIT_USER_CTRL \
+ 8 // init user control
+#define MPU9150_STATE_INIT_SAMPLE_RATE_CFG \
+ 9 // init the sensors and filters
+#define MPU9150_STATE_INIT_I2C_SLAVE_DLY \
+ 10 // set the ak8975 polling delay
+#define MPU9150_STATE_INIT_I2C_SLAVE_0 \
+ 11 // config ak8975 automatic read
+#define MPU9150_STATE_RD_DATA 12 // Waiting for data read
+
+//*****************************************************************************
+//
+// The factors used to convert the acceleration readings from the MPU9150 into
+// floating point values in meters per second squared.
+//
+// Values are obtained by taking the g conversion factors from the data sheet
+// and multiplying by 9.81 (1 g = 9.81 m/s^2).
+//
+//*****************************************************************************
+static const float g_fMPU9150AccelFactors[] =
+{
+ 0.0005985482, // Range = +/- 2 g (16384 lsb/g)
+ 0.0011970964, // Range = +/- 4 g (8192 lsb/g)
+ 0.0023941928, // Range = +/- 8 g (4096 lsb/g)
+ 0.0047883855 // Range = +/- 16 g (2048 lsb/g)
+};
+
+//*****************************************************************************
+//
+// The factors used to convert the acceleration readings from the MPU9150 into
+// floating point values in radians per second.
+//
+// Values are obtained by taking the degree per second conversion factors
+// from the data sheet and then converting to radians per sec (1 degree =
+// 0.0174532925 radians).
+//
+//*****************************************************************************
+static const float g_fMPU9150GyroFactors[] =
+{
+ 1.3323124e-4, // Range = +/- 250 dps (131.0)
+ 2.6646248e-4, // Range = +/- 500 dps (65.5)
+ 5.3211258e-4, // Range = +/- 1000 dps (32.8)
+ 0.0010642252 // Range = +/- 2000 dps (16.4)
+};
+
+//*****************************************************************************
+//
+// Converting sensor data to tesla (0.3 uT per LSB)
+//
+//*****************************************************************************
+#define CONVERT_TO_TESLA 0.0000003
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transations to/from the
+// MPU9150 have completed.
+//
+//*****************************************************************************
+static void
+MPU9150Callback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tMPU9150 *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tMPU9150 structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result in a callback to propagate the
+ // error). Except in the case that we are in the reset wait state and the
+ // error is an address NACK. This error is handled by the reset wait
+ // state.
+ //
+ if((ui8Status != I2CM_STATUS_SUCCESS) &&
+ !((ui8Status == I2CM_STATUS_ADDR_NACK) &&
+ (psInst->ui8State == MPU9150_STATE_INIT_RESET_WAIT)))
+ {
+ psInst->ui8State = MPU9150_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the MPU9150 state machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // All states that trivially transition to IDLE, and all unknown
+ // states.
+ //
+ case MPU9150_STATE_READ:
+ case MPU9150_STATE_LAST:
+ case MPU9150_STATE_RD_DATA:
+ default:
+ {
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = MPU9150_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // MPU9150 Device reset was issued
+ //
+ case MPU9150_STATE_INIT_RESET:
+ {
+ //
+ // Issue a read of the status register to confirm reset is done.
+ //
+ psInst->uCommand.pui8Buffer[0] = MPU9150_O_PWR_MGMT_1;
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 1,
+ MPU9150Callback, psInst);
+
+ psInst->ui8State = MPU9150_STATE_INIT_RESET_WAIT;
+ break;
+ }
+
+ //
+ // Status register was read, check if reset is done before proceeding.
+ //
+ case MPU9150_STATE_INIT_RESET_WAIT:
+ {
+ //
+ // Check the value read back from status to determine if device
+ // is still in reset or if it is ready. Reset state for this
+ // register is 0x40, which has sleep bit set. Device may also
+ // respond with an address NACK during very early stages of the
+ // its internal reset. Keep polling until we verify device is
+ // ready.
+ //
+ if((psInst->pui8Data[0] != MPU9150_PWR_MGMT_1_SLEEP) ||
+ (ui8Status == I2CM_STATUS_ADDR_NACK))
+ {
+ //
+ // Device still in reset so begin polling this register.
+ //
+ psInst->uCommand.pui8Buffer[0] = MPU9150_O_PWR_MGMT_1;
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 1,
+ MPU9150Callback, psInst);
+
+ //
+ // Intentionally stay in this state to create polling effect.
+ //
+ }
+ else
+ {
+ //
+ // Device is out of reset, bring it out of sleep mode.
+ //
+ psInst->uCommand.pui8Buffer[0] = MPU9150_O_PWR_MGMT_1;
+ psInst->uCommand.pui8Buffer[1] = MPU9150_PWR_MGMT_1_CLKSEL_XG;
+ I2CMWrite(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 2, MPU9150Callback,
+ psInst);
+
+ //
+ // Update state to show we are modifing user control and
+ // power management 1 regs.
+ //
+ psInst->ui8State = MPU9150_STATE_INIT_PWR_MGMT;
+ }
+ break;
+ }
+
+ //
+ // Reset complete now take device out of sleep mode.
+ //
+ case MPU9150_STATE_INIT_PWR_MGMT:
+ {
+ psInst->uCommand.pui8Buffer[0] = MPU9150_O_USER_CTRL;
+ psInst->uCommand.pui8Buffer[1] = MPU9150_USER_CTRL_I2C_MST_EN;
+ I2CMWrite(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 2, MPU9150Callback,
+ psInst);
+
+ //
+ // Update state to show we are modifing user control and
+ // power management 1 regs.
+ //
+ psInst->ui8State = MPU9150_STATE_INIT_USER_CTRL;
+
+ break;
+ }
+
+ //
+ // Change to power mode complete, device is ready for configuration.
+ //
+ case MPU9150_STATE_INIT_USER_CTRL:
+ {
+ //
+ // Load index 0 with the sample rate register number.
+ //
+ psInst->uCommand.pui8Buffer[0] = MPU9150_O_SMPLRT_DIV;
+
+ //
+ // Set sample rate to 50 hertz. 1000 hz / (1 + 19)
+ //
+ psInst->uCommand.pui8Buffer[1] = 19;
+
+ I2CMWrite(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 2, MPU9150Callback, psInst);
+
+ //
+ // update state to show are in process of configuring sensors.
+ //
+ psInst->ui8State = MPU9150_STATE_INIT_SAMPLE_RATE_CFG;
+ break;
+ }
+
+ //
+ // Sensor configuration is complete.
+ //
+ case MPU9150_STATE_INIT_SAMPLE_RATE_CFG:
+ {
+ //
+ // Write the I2C Master delay control so we only sample the AK
+ // every 5th time that we sample accel/gyro. Delay Count itself
+ // handled in next state.
+ //
+ psInst->uCommand.pui8Buffer[0] = MPU9150_O_I2C_MST_DELAY_CTRL;
+ psInst->uCommand.pui8Buffer[1] =
+ (MPU9150_I2C_MST_DELAY_CTRL_I2C_SLV0_DLY_EN |
+ MPU9150_I2C_MST_DELAY_CTRL_I2C_SLV4_DLY_EN);
+ I2CMWrite(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 2, MPU9150Callback, psInst);
+
+ //
+ // Update state to show we are configuring i2c slave delay between
+ // slave events. Slave 0 and Slave 4 transaction only occur every
+ // 5th sample cycle.
+ //
+ psInst->ui8State = MPU9150_STATE_INIT_I2C_SLAVE_DLY;
+ break;
+ }
+
+ //
+ // Master slave delay configuration complete.
+ //
+ case MPU9150_STATE_INIT_I2C_SLAVE_DLY:
+ {
+ //
+ // Write the configuration for I2C master control clock 400khz
+ // and wait for external sensor before asserting data ready
+ //
+ psInst->uCommand.pui8Buffer[0] = MPU9150_O_I2C_MST_CTRL;
+ psInst->uCommand.pui8Buffer[1] =
+ (MPU9150_I2C_MST_CTRL_I2C_MST_CLK_400 |
+ MPU9150_I2C_MST_CTRL_WAIT_FOR_ES);
+
+ //
+ // Configure I2C Slave 0 for read of AK8975 (I2C Address 0x0C)
+ // Start at AK8975 register status 1
+ // Read 8 bytes and enable this slave transaction
+ //
+ psInst->uCommand.pui8Buffer[2] = MPU9150_I2C_SLV0_ADDR_RW | 0x0C;
+ psInst->uCommand.pui8Buffer[3] = AK8975_O_ST1;
+ psInst->uCommand.pui8Buffer[4] = MPU9150_I2C_SLV0_CTRL_EN | 0x08;
+ I2CMWrite(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 5, MPU9150Callback, psInst);
+
+ //
+ // Update state. Now in process of configuring slave 0.
+ //
+ psInst->ui8State = MPU9150_STATE_INIT_I2C_SLAVE_0;
+ break;
+ }
+
+ //
+ // I2C slave 0 init complete.
+ //
+ case MPU9150_STATE_INIT_I2C_SLAVE_0:
+ {
+ //
+ // Write the configuration for I2C Slave 4 transaction to AK8975
+ // 0x0c is the AK8975 address on i2c bus.
+ // we want to write the control register with the value for a
+ // starting a single measurement.
+ //
+ psInst->uCommand.pui8Buffer[0] = MPU9150_O_I2C_SLV4_ADDR;
+ psInst->uCommand.pui8Buffer[1] = 0x0C;
+ psInst->uCommand.pui8Buffer[2] = AK8975_O_CNTL;
+ psInst->uCommand.pui8Buffer[3] = AK8975_CNTL_MODE_SINGLE;
+
+ //
+ // Enable the SLV4 transaction and set the master delay to
+ // 0x04 + 1. This means the slave transactions with delay enabled
+ // will run every fifth accel/gyro sample.
+ //
+ psInst->uCommand.pui8Buffer[4] = MPU9150_I2C_SLV4_CTRL_EN | 0x04;
+ I2CMWrite(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 5, MPU9150Callback, psInst);
+
+ //
+ // Update state. Now in the final init state.
+ //
+ psInst->ui8State = MPU9150_STATE_LAST;
+ break;
+ }
+
+ //
+ // A write just completed
+ //
+ case MPU9150_STATE_WRITE:
+ {
+ //
+ // Set the accelerometer and gyroscope ranges to the new values.
+ // If the register was not modified, the values will be the same so
+ // this has no effect.
+ //
+ psInst->ui8AccelAfsSel = psInst->ui8NewAccelAfsSel;
+ psInst->ui8GyroFsSel = psInst->ui8NewGyroFsSel;
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = MPU9150_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // A read-modify-write just completed
+ //
+ case MPU9150_STATE_RMW:
+ {
+ //
+ // See if the PWR_MGMT_1 register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ MPU9150_O_PWR_MGMT_1)
+ {
+ //
+ // See if a soft reset has been issued.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ MPU9150_PWR_MGMT_1_DEVICE_RESET)
+ {
+ //
+ // Default range setting is +/- 2 g
+ //
+ psInst->ui8AccelAfsSel = 0;
+ psInst->ui8NewAccelAfsSel = 0;
+
+ //
+ // Default range setting is +/- 250 degrees/s
+ //
+ psInst->ui8GyroFsSel = 0;
+ psInst->ui8NewGyroFsSel = 0;
+ }
+ }
+
+ //
+ // See if the GYRO_CONFIG register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ MPU9150_O_GYRO_CONFIG)
+ {
+ //
+ // Extract the FS_SEL from the GYRO_CONFIG register value.
+ //
+ psInst->ui8GyroFsSel =
+ ((psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ MPU9150_GYRO_CONFIG_FS_SEL_M) >>
+ MPU9150_GYRO_CONFIG_FS_SEL_S);
+ }
+
+ //
+ // See if the ACCEL_CONFIG register was just modified.
+ //
+ if(psInst->uCommand.sReadModifyWriteState.pui8Buffer[0] ==
+ MPU9150_O_ACCEL_CONFIG)
+ {
+ //
+ // Extract the FS_SEL from the ACCEL_CONFIG register value.
+ //
+ psInst->ui8AccelAfsSel =
+ ((psInst->uCommand.sReadModifyWriteState.pui8Buffer[1] &
+ MPU9150_ACCEL_CONFIG_AFS_SEL_M) >>
+ MPU9150_ACCEL_CONFIG_AFS_SEL_S);
+ }
+
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = MPU9150_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == MPU9150_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the MPU9150 driver.
+//!
+//! \param psInst is a pointer to the MPU9150 instance data.
+//! \param psI2CInst is a pointer to the I2C master driver instance data.
+//! \param ui8I2CAddr is the I2C address of the MPU9150 device.
+//! \param pfnCallback is the function to be called when the initialization has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initializes the MPU9150 driver, preparing it for operation.
+//!
+//! \return Returns 1 if the MPU9150 driver was successfully initialized and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+MPU9150Init(tMPU9150 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Initialize the MPU9150 instance structure.
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8I2CAddr;
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Default range setting is +/- 2 g
+ //
+ psInst->ui8AccelAfsSel = (MPU9150_ACCEL_CONFIG_AFS_SEL_2G >>
+ MPU9150_ACCEL_CONFIG_AFS_SEL_S);
+ psInst->ui8NewAccelAfsSel = (MPU9150_ACCEL_CONFIG_AFS_SEL_2G >>
+ MPU9150_ACCEL_CONFIG_AFS_SEL_S);
+
+ //
+ // Default range setting is +/- 250 degrees/s
+ //
+ psInst->ui8GyroFsSel = (MPU9150_GYRO_CONFIG_FS_SEL_250 >>
+ MPU9150_GYRO_CONFIG_FS_SEL_S);
+ psInst->ui8NewGyroFsSel = (MPU9150_GYRO_CONFIG_FS_SEL_250 >>
+ MPU9150_GYRO_CONFIG_FS_SEL_S);
+
+ //
+ // Set the state to show we are initiating a reset.
+ //
+ psInst->ui8State = MPU9150_STATE_INIT_RESET;
+
+ //
+ // Load the buffer with command to perform device reset
+ //
+ psInst->uCommand.pui8Buffer[0] = MPU9150_O_PWR_MGMT_1;
+ psInst->uCommand.pui8Buffer[1] = MPU9150_PWR_MGMT_1_DEVICE_RESET;
+ if(I2CMWrite(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 2, MPU9150Callback, psInst) == 0)
+ {
+ psInst->ui8State = MPU9150_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Returns the pointer to the tAK8975 object
+//!
+//! \param psInst is a pointer to the MPU9150 instance data.
+//!
+//! The MPU9150 contains in internal AK8975 magnetometer. To access data from
+//! that sensor, application should use this function to get a pointer to the
+//! tAK8975 object, and then use the AK8975 APIs.
+//!
+//! \return Returns the pointer to the tAK8975 object
+//
+//*****************************************************************************
+tAK8975 *
+MPU9150MagnetoInstGet(tMPU9150 *psInst)
+{
+ return(&(psInst->sAK8975Inst));
+}
+
+//*****************************************************************************
+//
+//! Reads data from MPU9150 registers.
+//!
+//! \param psInst is a pointer to the MPU9150 instance data.
+//! \param ui8Reg is the first register to read.
+//! \param pui8Data is a pointer to the location to store the data that is
+//! read.
+//! \param ui16Count is the number of data bytes to read.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function reads a sequence of data values from consecutive registers in
+//! the MPU9150.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+MPU9150Read(tMPU9150 *psInst, uint_fast8_t ui8Reg, uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the MPU9150 driver is not idle (in other words,
+ // there is already an outstanding request to the MPU9150).
+ //
+ if(psInst->ui8State != MPU9150_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read state.
+ //
+ psInst->ui8State = MPU9150_STATE_READ;
+
+ //
+ // Read the requested registers from the MPU9150.
+ //
+ psInst->uCommand.pui8Buffer[0] = ui8Reg;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, pui8Data, ui16Count,
+ MPU9150Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = MPU9150_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Writes data to MPU9150 registers.
+//!
+//! \param psInst is a pointer to the MPU9150 instance data.
+//! \param ui8Reg is the first register to write.
+//! \param pui8Data is a pointer to the data to write.
+//! \param ui16Count is the number of data bytes to write.
+//! \param pfnCallback is the function to be called when the data has been
+//! written (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function writes a sequence of data values to consecutive registers in
+//! the MPU9150. The first byte of the \e pui8Data buffer contains the value
+//! to be written into the \e ui8Reg register, the second value contains the
+//! data to be written into the next register, and so on.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+MPU9150Write(tMPU9150 *psInst, uint_fast8_t ui8Reg, const uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the MPU9150 driver is not idle (in other words,
+ // there is already an outstanding request to the MPU9150).
+ //
+ if(psInst->ui8State != MPU9150_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // See if the PWR_MGMT_1 register is being written.
+ //
+ if((ui8Reg <= MPU9150_O_PWR_MGMT_1) &&
+ ((ui8Reg + ui16Count) > MPU9150_O_PWR_MGMT_1))
+ {
+ //
+ // See if a soft reset is being requested.
+ //
+ if(pui8Data[ui8Reg - MPU9150_O_PWR_MGMT_1] &
+ MPU9150_PWR_MGMT_1_DEVICE_RESET)
+ {
+ //
+ // Default range setting is +/- 2 g.
+ //
+ psInst->ui8NewAccelAfsSel = 0;
+
+ //
+ // Default range setting is +/- 250 degrees/s.
+ //
+ psInst->ui8NewGyroFsSel = 0;
+ }
+ }
+
+ //
+ // See if the GYRO_CONFIG register is being written.
+ //
+ if((ui8Reg <= MPU9150_O_GYRO_CONFIG) &&
+ ((ui8Reg + ui16Count) > MPU9150_O_GYRO_CONFIG))
+ {
+ //
+ // Extract the FS_SEL from the GYRO_CONFIG register value.
+ //
+ psInst->ui8NewGyroFsSel = ((pui8Data[ui8Reg - MPU9150_O_GYRO_CONFIG] &
+ MPU9150_GYRO_CONFIG_FS_SEL_M) >>
+ MPU9150_GYRO_CONFIG_FS_SEL_S);
+ }
+
+ //
+ // See if the ACCEL_CONFIG register is being written.
+ //
+ if((ui8Reg <= MPU9150_O_ACCEL_CONFIG) &&
+ ((ui8Reg + ui16Count) > MPU9150_O_ACCEL_CONFIG))
+ {
+ //
+ // Extract the AFS_SEL from the ACCEL_CONFIG register value.
+ //
+ psInst->ui8NewAccelAfsSel =
+ ((pui8Data[ui8Reg - MPU9150_O_ACCEL_CONFIG] &
+ MPU9150_ACCEL_CONFIG_AFS_SEL_M) >>
+ MPU9150_ACCEL_CONFIG_AFS_SEL_S);
+ }
+
+ //
+ // Move the state machine to the wait for write state.
+ //
+ psInst->ui8State = MPU9150_STATE_WRITE;
+
+ //
+ // Write the requested registers to the MPU9150.
+ //
+ if(I2CMWrite8(&(psInst->uCommand.sWriteState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui8Data, ui16Count,
+ MPU9150Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = MPU9150_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of a MPU9150 register.
+//!
+//! \param psInst is a pointer to the MPU9150 instance data.
+//! \param ui8Reg is the register to modify.
+//! \param ui8Mask is the bit mask that is ANDed with the current register
+//! value.
+//! \param ui8Value is the bit mask that is ORed with the result of the AND
+//! operation.
+//! \param pfnCallback is the function to be called when the data has been
+//! changed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function changes the value of a register in the MPU9150 via a
+//! read-modify-write operation, allowing one of the fields to be changed
+//! without disturbing the other fields. The \e ui8Reg register is read, ANDed
+//! with \e ui8Mask, ORed with \e ui8Value, and then written back to the
+//! MPU9150.
+//!
+//! \return Returns 1 if the read-modify-write was successfully started and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+MPU9150ReadModifyWrite(tMPU9150 *psInst, uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask, uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the MPU9150 driver is not idle (in other words,
+ // there is already an outstanding request to the MPU9150).
+ //
+ if(psInst->ui8State != MPU9150_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read-modify-write state.
+ //
+ psInst->ui8State = MPU9150_STATE_RMW;
+
+ //
+ // Submit the read-modify-write request to the MPU9150.
+ //
+ if(I2CMReadModifyWrite8(&(psInst->uCommand.sReadModifyWriteState),
+ psInst->psI2CInst, psInst->ui8Addr, ui8Reg,
+ ui8Mask, ui8Value, MPU9150Callback, psInst) == 0)
+ {
+ //
+ // The I2C read-modify-write failed, so move to the idle state and
+ // return a failure.
+ //
+ psInst->ui8State = MPU9150_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads the accelerometer and gyroscope data from the MPU9150 and the
+//! magnetometer data from the on-chip aK8975.
+//!
+//! \param psInst is a pointer to the MPU9150 instance data.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read of the MPU9150 data registers. When the
+//! read has completed (as indicated by calling the callback function), the new
+//! readings can be obtained via:
+//!
+//! - MPU9150DataAccelGetRaw()
+//! - MPU9150DataAccelGetFloat()
+//! - MPU9150DataGyroGetRaw()
+//! - MPU9150DataGyroGetFloat()
+//! - MPU9150DataMagnetoGetRaw()
+//! - MPU9150DataMagnetoGetFloat()
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+MPU9150DataRead(tMPU9150 *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the MPU9150 driver is not idle (in other words,
+ // there is already an outstanding request to the MPU9150).
+ //
+ if(psInst->ui8State != MPU9150_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for data read state.
+ //
+ psInst->ui8State = MPU9150_STATE_RD_DATA;
+
+ //
+ // Read the data registers from the MPU9150.
+ //
+ // (ACCEL_XOUT_H(0x3B) -> GYRO_ZOUT_L(0x48) = 14 bytes
+ // Grab Ext Sens Data as well for another 8 bytes. ST1 + Mag Data + ST2
+ //
+ psInst->uCommand.pui8Buffer[0] = MPU9150_O_ACCEL_XOUT_H;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 22,
+ MPU9150Callback, psInst) == 0)
+ {
+ //
+ // The I2C read failed, so move to the idle state and return a failure.
+ //
+ psInst->ui8State = MPU9150_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Gets the raw accelerometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the MPU9150 instance data.
+//! \param pui16AccelX is a pointer to the value into which the raw X-axis
+//! accelerometer data is stored.
+//! \param pui16AccelY is a pointer to the value into which the raw Y-axis
+//! accelerometer data is stored.
+//! \param pui16AccelZ is a pointer to the value into which the raw Z-axis
+//! accelerometer data is stored.
+//!
+//! This function returns the raw accelerometer data from the most recent data
+//! read. The data is not manipulated in any way by the driver. If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+MPU9150DataAccelGetRaw(tMPU9150 *psInst, uint_fast16_t *pui16AccelX,
+ uint_fast16_t *pui16AccelY, uint_fast16_t *pui16AccelZ)
+{
+ //
+ // Return the raw accelerometer values.
+ //
+ if(pui16AccelX)
+ {
+ *pui16AccelX = (psInst->pui8Data[0] << 8) | psInst->pui8Data[1];
+ }
+ if(pui16AccelY)
+ {
+ *pui16AccelY = (psInst->pui8Data[2] << 8) | psInst->pui8Data[3];
+ }
+ if(pui16AccelZ)
+ {
+ *pui16AccelZ = (psInst->pui8Data[4] << 8) | psInst->pui8Data[5];
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the accelerometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the MPU9150 instance data.
+//! \param pfAccelX is a pointer to the value into which the X-axis
+//! accelerometer data is stored.
+//! \param pfAccelY is a pointer to the value into which the Y-axis
+//! accelerometer data is stored.
+//! \param pfAccelZ is a pointer to the value into which the Z-axis
+//! accelerometer data is stored.
+//!
+//! This function returns the accelerometer data from the most recent data
+//! read, converted into meters per second squared (m/s^2). If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+MPU9150DataAccelGetFloat(tMPU9150 *psInst, float *pfAccelX, float *pfAccelY,
+ float *pfAccelZ)
+{
+ float fFactor;
+
+ //
+ // Get the acceleration conversion factor for the current data format.
+ //
+ fFactor = g_fMPU9150AccelFactors[psInst->ui8AccelAfsSel];
+
+ //
+ // Convert the accelerometer values into m/sec^2
+ //
+ if(pfAccelX)
+ {
+ *pfAccelX = ((float)(int16_t)((psInst->pui8Data[0] << 8) |
+ psInst->pui8Data[1]) * fFactor);
+ }
+ if(pfAccelY)
+ {
+ *pfAccelY = ((float)(int16_t)((psInst->pui8Data[2] << 8) |
+ psInst->pui8Data[3]) * fFactor);
+ }
+ if(pfAccelZ)
+ {
+ *pfAccelZ = ((float)(int16_t)((psInst->pui8Data[4] << 8) |
+ psInst->pui8Data[5]) * fFactor);
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the raw gyroscope data from the most recent data read.
+//!
+//! \param psInst is a pointer to the MPU9150 instance data.
+//! \param pui16GyroX is a pointer to the value into which the raw X-axis
+//! gyroscope data is stored.
+//! \param pui16GyroY is a pointer to the value into which the raw Y-axis
+//! gyroscope data is stored.
+//! \param pui16GyroZ is a pointer to the value into which the raw Z-axis
+//! gyroscope data is stored.
+//!
+//! This function returns the raw gyroscope data from the most recent data
+//! read. The data is not manipulated in any way by the driver. If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+MPU9150DataGyroGetRaw(tMPU9150 *psInst, uint_fast16_t *pui16GyroX,
+ uint_fast16_t *pui16GyroY, uint_fast16_t *pui16GyroZ)
+{
+ //
+ // Return the raw gyroscope values.
+ //
+ if(pui16GyroX)
+ {
+ *pui16GyroX = (psInst->pui8Data[8] << 8) | psInst->pui8Data[9];
+ }
+ if(pui16GyroY)
+ {
+ *pui16GyroY = (psInst->pui8Data[10] << 8) | psInst->pui8Data[11];
+ }
+ if(pui16GyroZ)
+ {
+ *pui16GyroZ = (psInst->pui8Data[12] << 8) | psInst->pui8Data[13];
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the gyroscope data from the most recent data read.
+//!
+//! \param psInst is a pointer to the MPU9150 instance data.
+//! \param pfGyroX is a pointer to the value into which the X-axis
+//! gyroscope data is stored.
+//! \param pfGyroY is a pointer to the value into which the Y-axis
+//! gyroscope data is stored.
+//! \param pfGyroZ is a pointer to the value into which the Z-axis
+//! gyroscope data is stored.
+//!
+//! This function returns the gyroscope data from the most recent data read,
+//! converted into radians per second. If any of the output data pointers are
+//! \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+MPU9150DataGyroGetFloat(tMPU9150 *psInst, float *pfGyroX, float *pfGyroY,
+ float *pfGyroZ)
+{
+ float fFactor;
+ int16_t i16Temp;
+
+ //
+ // Get the gyroscope conversion factor for the current data format.
+ //
+ fFactor = g_fMPU9150GyroFactors[psInst->ui8GyroFsSel];
+
+ //
+ // Convert the gyroscope values into rad/sec
+ //
+ if(pfGyroX)
+ {
+ i16Temp = (int16_t)psInst->pui8Data[8];
+ i16Temp <<= 8;
+ i16Temp += psInst->pui8Data[9];
+ *pfGyroX = (float)i16Temp;
+ *pfGyroX *= fFactor;
+ }
+ if(pfGyroY)
+ {
+ i16Temp = (int16_t)psInst->pui8Data[10];
+ i16Temp <<= 8;
+ i16Temp += psInst->pui8Data[11];
+ *pfGyroY = (float)i16Temp;
+ *pfGyroY *= fFactor;
+ }
+ if(pfGyroZ)
+ {
+ i16Temp = (int16_t)psInst->pui8Data[12];
+ i16Temp <<= 8;
+ i16Temp += psInst->pui8Data[13];
+ *pfGyroZ = (float)i16Temp;
+ *pfGyroZ *= fFactor;
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the raw magnetometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the MPU9150 instance data.
+//! \param pui16MagnetoX is a pointer to the value into which the raw X-axis
+//! magnetometer data is stored.
+//! \param pui16MagnetoY is a pointer to the value into which the raw Y-axis
+//! magnetometer data is stored.
+//! \param pui16MagnetoZ is a pointer to the value into which the raw Z-axis
+//! magnetometer data is stored.
+//!
+//! This function returns the raw magnetometer data from the most recent data
+//! read. The data is not manipulated in any way by the driver. If any of the
+//! output data pointers are \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+MPU9150DataMagnetoGetRaw(tMPU9150 *psInst, uint_fast16_t *pui16MagnetoX,
+ uint_fast16_t *pui16MagnetoY,
+ uint_fast16_t *pui16MagnetoZ)
+{
+ uint8_t *pui8ExtSensData;
+
+ pui8ExtSensData = &(psInst->pui8Data[14]);
+
+ //
+ // Return the raw magnetometer values.
+ //
+ if(pui16MagnetoX)
+ {
+ *pui16MagnetoX = (pui8ExtSensData[2] << 8) | pui8ExtSensData[1];
+ }
+ if(pui16MagnetoY)
+ {
+ *pui16MagnetoY = (pui8ExtSensData[4] << 8) | pui8ExtSensData[3];
+ }
+ if(pui16MagnetoZ)
+ {
+ *pui16MagnetoZ = (pui8ExtSensData[6] << 8) | pui8ExtSensData[5];
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the magnetometer data from the most recent data read.
+//!
+//! \param psInst is a pointer to the MPU9150 instance data.
+//! \param pfMagnetoX is a pointer to the value into which the X-axis
+//! magnetometer data is stored.
+//! \param pfMagnetoY is a pointer to the value into which the Y-axis
+//! magnetometer data is stored.
+//! \param pfMagnetoZ is a pointer to the value into which the Z-axis
+//! magnetometer data is stored.
+//!
+//! This function returns the magnetometer data from the most recent data read,
+//! converted into tesla. If any of the output data pointers are
+//! \b NULL, the corresponding data is not provided.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+MPU9150DataMagnetoGetFloat(tMPU9150 *psInst, float *pfMagnetoX,
+ float *pfMagnetoY, float *pfMagnetoZ)
+{
+ int16_t *pi16Data;
+
+ pi16Data = (int16_t *)(psInst->pui8Data + 15);
+
+ //
+ // Convert the magnetometer values into floating-point tesla values.
+ //
+ if(pfMagnetoX)
+ {
+ *pfMagnetoX = (float)pi16Data[0];
+ *pfMagnetoX *= CONVERT_TO_TESLA;
+ }
+ if(pfMagnetoY)
+ {
+ *pfMagnetoY = (float)pi16Data[1];
+ *pfMagnetoY *= CONVERT_TO_TESLA;
+ }
+ if(pfMagnetoZ)
+ {
+ *pfMagnetoZ = (float)pi16Data[2];
+ *pfMagnetoZ *= CONVERT_TO_TESLA;
+ }
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/mpu9150.h b/sensorlib/mpu9150.h new file mode 100644 index 0000000..459d6ca --- /dev/null +++ b/sensorlib/mpu9150.h @@ -0,0 +1,187 @@ +//*****************************************************************************
+//
+// mpu9150.h - Prototypes for the MPU9150 accelerometer, gyroscope, and
+// magnetometer driver.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_MPU9150_H__
+#define __SENSORLIB_MPU9150_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the MPU9150 driver.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The pointer to the I2C master interface instance used to communicate
+ // with the MPU9150.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The AK8975 inst that used to access the on-chip AK8975 magnetometer
+ //
+ tAK8975 sAK8975Inst;
+
+ //
+ // The I2C address of the MPU9150.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The state of the state machine used while accessing the MPU9150.
+ //
+ uint8_t ui8State;
+
+ //
+ // The current accelerometer afs_sel setting
+ //
+ uint8_t ui8AccelAfsSel;
+
+ //
+ // The new accelerometer afs_sel setting, which is used when a register
+ // write succeeds.
+ //
+ uint8_t ui8NewAccelAfsSel;
+
+ //
+ // The current gyroscope fs_sel setting
+ //
+ uint8_t ui8GyroFsSel;
+
+ //
+ // The new gyroscope fs_sel setting, which is used when a register write
+ // succeeds.
+ //
+ uint8_t ui8NewGyroFsSel;
+
+ //
+ // The data buffer used for sending/receiving data to/from the MPU9150.
+ //
+ uint8_t pui8Data[24];
+
+ //
+ // The function that is called when the current request has completed
+ // processing.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The callback data provided to the callback function.
+ //
+ void *pvCallbackData;
+
+ //
+ // A union of structures that are used for read, write and
+ // read-modify-write operations. Since only one operation can be active at
+ // a time, it is safe to re-use the memory in this manner.
+ //
+ union
+ {
+ //
+ // A buffer used to store the write portion of a register read.
+ //
+ uint8_t pui8Buffer[6];
+
+ //
+ // The write state used to write register values.
+ //
+ tI2CMWrite8 sWriteState;
+
+ //
+ // The read-modify-write state used to modify register values.
+ //
+ tI2CMReadModifyWrite8 sReadModifyWriteState;
+ }
+ uCommand;
+}
+tMPU9150;
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern uint_fast8_t MPU9150Init(tMPU9150 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern tAK8975 *MPU9150InstAK8975Get(tMPU9150 *psInst);
+extern uint_fast8_t MPU9150Read(tMPU9150 *psInst, uint_fast8_t ui8Reg,
+ uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t MPU9150Write(tMPU9150 *psInst, uint_fast8_t ui8Reg,
+ const uint8_t *pui8Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t MPU9150ReadModifyWrite(tMPU9150 *psInst,
+ uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask,
+ uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t MPU9150DataRead(tMPU9150 *psInst,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern void MPU9150DataAccelGetRaw(tMPU9150 *psInst,
+ uint_fast16_t *pui16AccelX,
+ uint_fast16_t *pui16AccelY,
+ uint_fast16_t *pui16AccelZ);
+extern void MPU9150DataAccelGetFloat(tMPU9150 *psInst, float *pfAccelX,
+ float *pfAccelY, float *pfAccelZ);
+extern void MPU9150DataGyroGetRaw(tMPU9150 *psInst, uint_fast16_t *pui16GyroX,
+ uint_fast16_t *pui16GyroY,
+ uint_fast16_t *pui16GyroZ);
+extern void MPU9150DataGyroGetFloat(tMPU9150 *psInst, float *pfGyroX,
+ float *pfGyroY, float *pfGyroZ);
+extern void MPU9150DataMagnetoGetRaw(tMPU9150 *psInst,
+ uint_fast16_t *pui16MagnetoX,
+ uint_fast16_t *pui16MagnetoY,
+ uint_fast16_t *pui16MagnetoZ);
+extern void MPU9150DataMagnetoGetFloat(tMPU9150 *psInst, float *pfMagnetoX,
+ float *pfMagnetoY, float *pfMagnetoZ);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_MPU9150_H__
diff --git a/sensorlib/quaternion.c b/sensorlib/quaternion.c new file mode 100644 index 0000000..78296aa --- /dev/null +++ b/sensorlib/quaternion.c @@ -0,0 +1,286 @@ +//*****************************************************************************
+//
+// quaternion.c - Functions for performing quaternion operations.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <math.h>
+#include "sensorlib/quaternion.h"
+
+//*****************************************************************************
+//
+//! \addtogroup quaternion_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// If M_PI has not been defined by the system headers, define it here.
+//
+//*****************************************************************************
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+//*****************************************************************************
+//
+//! Computes a quaternion from a set of eueler angles specified in degrees
+//!
+//! \param pfQOut is the inverted quaternion in W,X,Y,Z form
+//! \param fRollDeg is roll in degrees
+//! \param fPitchDeg is pitch in degrees
+//! \param fYawDeg is yaw in degrees
+//!
+//! This function computes a quaternion from a set of euler angles specified
+//! in degrees
+//!
+//! \return Returns a quaternion representing the provided eulers
+//
+//*****************************************************************************
+void
+QuaternionFromEuler(float pfQOut[4], float fRollDeg, float fPitchDeg,
+ float fYawDeg)
+{
+ float fRoll, fPitch, fYaw;
+ float fCOSY, fCOSP, fCOSR;
+ float fSINY, fSINP, fSINR;
+
+ //
+ // Convert roll, pitch, and yaw from degrees into radians
+ //
+ fRoll = fRollDeg * M_PI / 180.0;
+ fPitch = fPitchDeg * M_PI / 180.0;
+ fYaw = fYawDeg * M_PI / 180.0;
+
+ //
+ // Pre-calculate the cosine of (yaw, pitch, roll divided by 2)
+ //
+ fCOSY = cosf(fYaw / 2.0);
+ fCOSP = cosf(fPitch / 2.0);
+ fCOSR = cosf(fRoll / 2.0);
+
+ //
+ // Pre-calculate the sine of (yaw, pitch, roll divided by 2)
+ //
+ fSINY = sinf(fYaw / 2.0);
+ fSINP = sinf(fPitch / 2.0);
+ fSINR = sinf(fRoll / 2.0);
+
+ //
+ // The W component
+ //
+ pfQOut[Q_W] = fCOSY * fCOSP * fCOSR - fSINY * fSINP * fSINR;
+
+ //
+ // The X component
+ //
+ pfQOut[Q_X] = fSINY * fSINP * fCOSR + fCOSY * fCOSP * fSINR;
+
+ //
+ // The Y component
+ //
+ pfQOut[Q_Y] = fCOSY * fSINP * fCOSR - fSINY * fCOSP * fSINR;
+
+ //
+ // The Z component
+ //
+ pfQOut[Q_Z] = fSINY * fCOSP * fCOSR + fCOSY * fSINP * fSINR;
+}
+
+//*****************************************************************************
+//
+//! Computes the magnitude of a quaternion.
+//!
+//! \param pfQIn is the source quaternion in W,X,Y,Z form
+//!
+//! This function computes the magnitude of a quaternion by summing the square
+//! of each of the quatnerion components.
+//!
+//! \return Returns the scalar magnitude of the quaternion
+//
+//*****************************************************************************
+float
+QuaternionMagnitude(float pfQIn[4])
+{
+ float fSumSq;
+
+ //
+ // Calculate the magnitude of the quaternion by finding the sum of the
+ // squares of each component.
+ //
+ fSumSq = ((pfQIn[Q_W] * pfQIn[Q_W]) + (pfQIn[Q_X] * pfQIn[Q_X]) +
+ (pfQIn[Q_Y] * pfQIn[Q_Y]) + (pfQIn[Q_Z] * pfQIn[Q_Z]));
+
+ return(fSumSq);
+}
+
+//*****************************************************************************
+//
+//! Computes the inverse of a quaternion.
+//!
+//! \param pfQOut is the inverted quaternion in W,X,Y,Z form
+//! \param pfQIn is the source quaternion in W,X,Y,Z form
+//!
+//! This function computes the inverse of a quaternion. The inverse of a
+//! quaternion produces a rotation opposite to the source quaternion. This
+//! can be achieved by simply changing the signs of the imaginary components
+//! of a quaternion when the quatnerion is a unit quaternion.
+//!
+//! \return Returns the inverse of a quaternion.
+//
+//*****************************************************************************
+void
+QuaternionInverse(float pfQOut[4], float pfQIn[4])
+{
+ float fMag;
+
+ //
+ // Find magnitude of the quaternion. This will be used to normalize the
+ // source quaternion if it's not already. If it is a unit quaternion then
+ // the magnitude should be nearly equal to 1.0 and dividing by the
+ // magnitude has no mathemtical effect.
+ //
+ fMag = QuaternionMagnitude(pfQIn);
+
+ //
+ // Normalize the W component
+ //
+ pfQOut[Q_W] = pfQIn[Q_W] / fMag;
+
+ //
+ // Invert and normalize the X component
+ //
+ pfQOut[Q_X] = -pfQIn[Q_X] / fMag;
+
+ //
+ // Invert and normalize the Y component
+ //
+ pfQOut[Q_Y] = -pfQIn[Q_Y] / fMag;
+
+ //
+ // Invert and normalize the Z component
+ //
+ pfQOut[Q_Z] = -pfQIn[Q_Z] / fMag;
+}
+
+//*****************************************************************************
+//
+//! Computes the product of two quaternions.
+//!
+//! \param pfQOut is the product of In1 X In2
+//! \param pfQIn1 is the source quaternion in W,X,Y,Z form
+//! \param pfQIn2 is the source quaternion in W,X,Y,Z form
+//!
+//! This function computes the cross product of two quaternions.
+//!
+//! \return Returns the cross product of the two quaternions.
+//
+//*****************************************************************************
+void
+QuaternionMult(float pfQOut[4], float pfQIn1[4], float pfQIn2[4])
+{
+ //
+ // Let Q1 and Q2 be two quaternions with components w,x,y,z
+ // Let Qp be the cross product Q1 x Q2. The components of Qp can be
+ // calculated as follows:
+ //
+ // Qp.w = (Q1w Q2w) - (Q1x Q2x) - (Q1y Q2y) - (Q1z Q2z)
+ // Qp.x = (Q1w Q2x) + (Q1x Q2w) - (Q1z Q2y) + (Q1y Q2z)
+ // Qp.y = (Q1y Q2w) + (Q1z Q2x) + (Q1w Q2y) - (Q1x Q2z)
+ // Qp.z = (Q1z Q2w) - (Q1y Q2x) + (Q1x Q2y) + (Q1w Q2z)
+ //
+
+ //
+ // Calculate the W term
+ //
+ pfQOut[Q_W] = ((pfQIn2[Q_W] * pfQIn1[Q_W]) - (pfQIn2[Q_X] * pfQIn1[Q_X]) -
+ (pfQIn2[Q_Y] * pfQIn1[Q_Y]) - (pfQIn2[Q_Z] * pfQIn1[Q_Z]));
+
+ //
+ // Calculate the X term
+ //
+ pfQOut[Q_X]= ((pfQIn2[Q_X] * pfQIn1[Q_W]) + (pfQIn2[Q_W] * pfQIn1[Q_X]) -
+ (pfQIn2[Q_Y] * pfQIn1[Q_Z]) + (pfQIn2[Q_Z] * pfQIn1[Q_Y]));
+
+ //
+ // Calculate the Y term
+ //
+ pfQOut[Q_Y]= ((pfQIn2[Q_W] * pfQIn1[Q_Y]) + (pfQIn2[Q_X] * pfQIn1[Q_Z]) -
+ (pfQIn2[Q_Y] * pfQIn1[Q_W]) - (pfQIn2[Q_Z] * pfQIn1[Q_X]));
+
+ //
+ // Calculate the Z term
+ //
+ pfQOut[Q_Z] = ((pfQIn2[Q_W] * pfQIn1[Q_Z]) - (pfQIn2[Q_X] * pfQIn1[Q_Y]) -
+ (pfQIn2[Q_Y] * pfQIn1[Q_X]) + (pfQIn2[Q_Z] * pfQIn1[Q_W]));
+}
+
+//*****************************************************************************
+//
+//! Computes the angle between two quaternions
+//!
+//! \param pfQIn1 is a source quaternion in W,X,Y,Z form
+//! \param pfQIn2 is a source quaternion in W,X,Y,Z form
+//!
+//! This function computes the angle between two quaternions.
+//!
+//! \return Returns the angle, in radians, between the two quaternions.
+//
+//*****************************************************************************
+float
+QuaternionAngle(float pfQIn1[4], float pfQIn2[4])
+{
+ float pfQInv[4];
+ float pfQProd[4];
+
+ //
+ // Let Q1 and Q2 be two quaternions having components w,x,y,z. The angle
+ // between the orientations represented by Q1 and Q2 can be calculated
+ // with:
+ //
+ // angle = arccos( (Q2 * Q1').w ) * 2.0;
+ //
+ // where Q1' is the inverse of Q1
+ //
+
+ //
+ // Calculate the inverse of Q1
+ //
+ QuaternionInverse(pfQInv, pfQIn1);
+
+ //
+ // Find the product of Q2 x Q1`
+ //
+ QuaternionMult(pfQProd, pfQIn2, pfQInv);
+
+ //
+ // calculate the arccos of the w component of the previous product.
+ //
+ return(acosf(pfQProd[Q_W]) * 2.0);
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/quaternion.h b/sensorlib/quaternion.h new file mode 100644 index 0000000..79f9270 --- /dev/null +++ b/sensorlib/quaternion.h @@ -0,0 +1,70 @@ +//*****************************************************************************
+//
+// quaternion.h - Prototypes for the quaternion functions.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_QUATERNION_H__
+#define __SENSORLIB_QUATERNION_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The index of the components in a quaternion vector.
+//
+//*****************************************************************************
+#define Q_W 0
+#define Q_X 1
+#define Q_Y 2
+#define Q_Z 3
+
+//*****************************************************************************
+//
+// Prototypes.
+//
+//*****************************************************************************
+extern void QuaternionFromEuler(float pfQOut[4], float fRollDeg,
+ float fPitchDeg, float fYawDeg);
+extern float QuaternionMagnitude(float pfQIn[4]);
+extern void QuaternionInverse(float pfQOut[4], float pfQIn[4]);
+extern void QuaternionMult(float pfQOut[4], float pfQIn1[4], float pfQIn2[4]);
+extern float QuaternionAngle(float pfQIn1[4], float pfQIn2[4]);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_QUATERNION_H__
diff --git a/sensorlib/readme.txt b/sensorlib/readme.txt new file mode 100644 index 0000000..209ec0c --- /dev/null +++ b/sensorlib/readme.txt @@ -0,0 +1,21 @@ +This project will build the Texas Instruments Sensor Library.
+
+-------------------------------------------------------------------------------
+
+Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+Software License Agreement
+
+Texas Instruments (TI) is supplying this software for use solely and
+exclusively on TI's microcontroller products. The software is owned by
+TI and/or its suppliers, and is protected under applicable copyright
+laws. You may not combine this software with "viral" open-source
+software in order to form a larger program.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, FOR ANY REASON WHATSOEVER.
+
+This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
diff --git a/sensorlib/rvmdk/sensorlib.lib b/sensorlib/rvmdk/sensorlib.lib Binary files differnew file mode 100644 index 0000000..582e01b --- /dev/null +++ b/sensorlib/rvmdk/sensorlib.lib diff --git a/sensorlib/sensorlib.ewp b/sensorlib/sensorlib.ewp new file mode 100644 index 0000000..9504f35 --- /dev/null +++ b/sensorlib/sensorlib.ewp @@ -0,0 +1,833 @@ +<?xml version="1.0" encoding="iso-8859-1"?>
+
+<project>
+ <fileVersion>1</fileVersion>
+ <configuration>
+ <name>Debug</name>
+ <toolchain>
+ <name>ARM</name>
+ </toolchain>
+ <debug>1</debug>
+ <settings>
+ <name>General</name>
+ <archiveVersion>3</archiveVersion>
+ <data>
+ <version>14</version>
+ <wantNonLocal>1</wantNonLocal>
+ <debug>1</debug>
+ <option>
+ <name>ExePath</name>
+ <state>ewarm\Exe</state>
+ </option>
+ <option>
+ <name>ObjPath</name>
+ <state>ewarm\Obj</state>
+ </option>
+ <option>
+ <name>ListPath</name>
+ <state>ewarm\List</state>
+ </option>
+ <option>
+ <name>Variant</name>
+ <version>19</version>
+ <state>39</state>
+ </option>
+ <option>
+ <name>GEndianMode</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>Input variant</name>
+ <version>1</version>
+ <state>0</state>
+ </option>
+ <option>
+ <name>Input description</name>
+ <state>Full formatting.</state>
+ </option>
+ <option>
+ <name>Output variant</name>
+ <version>0</version>
+ <state>0</state>
+ </option>
+ <option>
+ <name>Output description</name>
+ <state>Full formatting.</state>
+ </option>
+ <option>
+ <name>GOutputBinary</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>FPU</name>
+ <version>2</version>
+ <state>5</state>
+ </option>
+ <option>
+ <name>OGCoreOrChip</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>GRuntimeLibSelect</name>
+ <version>0</version>
+ <state>1</state>
+ </option>
+ <option>
+ <name>GRuntimeLibSelectSlave</name>
+ <version>0</version>
+ <state>1</state>
+ </option>
+ <option>
+ <name>RTDescription</name>
+ <state>To be used with the normal configuration of the C/C++ runtime library. No locale interface, C locale, no file descriptor support, no multibytes in printf and scanf, and no hex floats in strtod.</state>
+ </option>
+ <option>
+ <name>RTConfigPath</name>
+ <state>$TOOLKIT_DIR$\INC\DLib_Config_Normal.h</state>
+ </option>
+ <option>
+ <name>OGProductVersion</name>
+ <state>5.11.0.50579</state>
+ </option>
+ <option>
+ <name>OGLastSavedByProductVersion</name>
+ <state>5.11.0.50579</state>
+ </option>
+ <option>
+ <name>GeneralMisraRules</name>
+ <version>0</version>
+ <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
+ </option>
+ <option>
+ <name>GeneralEnableMisra</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>GeneralMisraVerbose</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>OGChipSelectEditMenu</name>
+ <state>TM4C1230C3PM TexasInstruments TM4C1230C3PM</state>
+ </option>
+ <option>
+ <name>GenLowLevelInterface</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>GEndianModeBE</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>OGBufferedTerminalOutput</name>
+ <state>0</state>
+ </option>
+ </data>
+ </settings>
+ <settings>
+ <name>ICCARM</name>
+ <archiveVersion>2</archiveVersion>
+ <data>
+ <version>19</version>
+ <wantNonLocal>1</wantNonLocal>
+ <debug>1</debug>
+ <option>
+ <name>CCDefines</name>
+ <state>ewarm</state>
+ </option>
+ <option>
+ <name>CCPreprocFile</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CCPreprocComments</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CCPreprocLine</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CCListCFile</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CCListCMnemonics</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CCListCMessages</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CCListAssFile</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CCListAssSource</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CCEnableRemarks</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CCDiagSuppress</name>
+ <state>Pa050</state>
+ </option>
+ <option>
+ <name>CCDiagRemark</name>
+ <state></state>
+ </option>
+ <option>
+ <name>CCDiagWarning</name>
+ <state></state>
+ </option>
+ <option>
+ <name>CCDiagError</name>
+ <state></state>
+ </option>
+ <option>
+ <name>CCObjPrefix</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>CCAllowList</name>
+ <version>1</version>
+ <state>1111111</state>
+ </option>
+ <option>
+ <name>CCDebugInfo</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>IEndianMode</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>IProcessor</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>IExtraOptionsCheck</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IExtraOptions</name>
+ <state></state>
+ </option>
+ <option>
+ <name>CCLangConformance</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CCSignedPlainChar</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>CCRequirePrototypes</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CCMultibyteSupport</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CCDiagWarnAreErr</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CCCompilerRuntimeInfo</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IFpuProcessor</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>OutputFile</name>
+ <state>$FILE_BNAME$.o</state>
+ </option>
+ <option>
+ <name>CCLangSelect</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CCLibConfigHeader</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>PreInclude</name>
+ <state></state>
+ </option>
+ <option>
+ <name>CompilerMisraRules</name>
+ <version>0</version>
+ <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
+ </option>
+ <option>
+ <name>CompilerMisraOverride</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CCIncludePath2</name>
+ <state>$PROJ_DIR$\..</state>
+ </option>
+ <option>
+ <name>CCStdIncCheck</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CCStdIncludePath</name>
+ <state>$TOOLKIT_DIR$\INC\</state>
+ </option>
+ <option>
+ <name>CCCodeSection</name>
+ <state>.text</state>
+ </option>
+ <option>
+ <name>IInterwork2</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IProcessorMode2</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>CCOptLevel</name>
+ <state>3</state>
+ </option>
+ <option>
+ <name>CCOptStrategy</name>
+ <version>0</version>
+ <state>1</state>
+ </option>
+ <option>
+ <name>CCOptLevelSlave</name>
+ <state>3</state>
+ </option>
+ </data>
+ </settings>
+ <settings>
+ <name>AARM</name>
+ <archiveVersion>2</archiveVersion>
+ <data>
+ <version>7</version>
+ <wantNonLocal>1</wantNonLocal>
+ <debug>1</debug>
+ <option>
+ <name>AObjPrefix</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>AEndian</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>ACaseSensitivity</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>MacroChars</name>
+ <version>0</version>
+ <state>0</state>
+ </option>
+ <option>
+ <name>AWarnEnable</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>AWarnWhat</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>AWarnOne</name>
+ <state></state>
+ </option>
+ <option>
+ <name>AWarnRange1</name>
+ <state></state>
+ </option>
+ <option>
+ <name>AWarnRange2</name>
+ <state></state>
+ </option>
+ <option>
+ <name>ADebug</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>AltRegisterNames</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>ADefines</name>
+ <state>ewarm</state>
+ </option>
+ <option>
+ <name>AList</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>AListHeader</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>AListing</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>Includes</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>MacDefs</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>MacExps</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>MacExec</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>OnlyAssed</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>MultiLine</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>PageLengthCheck</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>PageLength</name>
+ <state>80</state>
+ </option>
+ <option>
+ <name>TabSpacing</name>
+ <state>8</state>
+ </option>
+ <option>
+ <name>AXRef</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>AXRefDefines</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>AXRefInternal</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>AXRefDual</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>AProcessor</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>AFpuProcessor</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>AOutputFile</name>
+ <state>$FILE_BNAME$.o</state>
+ </option>
+ <option>
+ <name>AMultibyteSupport</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>ALimitErrorsCheck</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>ALimitErrorsEdit</name>
+ <state>100</state>
+ </option>
+ <option>
+ <name>AIgnoreStdInclude</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>AStdIncludes</name>
+ <state>$TOOLKIT_DIR$\INC\</state>
+ </option>
+ <option>
+ <name>AUserIncludes</name>
+ <state></state>
+ </option>
+ <option>
+ <name>AExtraOptionsCheckV2</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>AExtraOptionsV2</name>
+ <state></state>
+ </option>
+ </data>
+ </settings>
+ <settings>
+ <name>OBJCOPY</name>
+ <archiveVersion>0</archiveVersion>
+ <data>
+ <version>1</version>
+ <wantNonLocal>1</wantNonLocal>
+ <debug>1</debug>
+ <option>
+ <name>OOCOutputFormat</name>
+ <version>1</version>
+ <state>0</state>
+ </option>
+ <option>
+ <name>OCOutputOverride</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>OOCOutputFile</name>
+ <state>sensorlib.srec</state>
+ </option>
+ <option>
+ <name>OOCCommandLineProducer</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>OOCObjCopyEnable</name>
+ <state>0</state>
+ </option>
+ </data>
+ </settings>
+ <settings>
+ <name>CUSTOM</name>
+ <archiveVersion>3</archiveVersion>
+ <data>
+ <extensions></extensions>
+ <cmdline></cmdline>
+ </data>
+ </settings>
+ <settings>
+ <name>BICOMP</name>
+ <archiveVersion>0</archiveVersion>
+ <data/>
+ </settings>
+ <settings>
+ <name>BUILDACTION</name>
+ <archiveVersion>1</archiveVersion>
+ <data>
+ <prebuild></prebuild>
+ <postbuild></postbuild>
+ </data>
+ </settings>
+ <settings>
+ <name>ILINK</name>
+ <archiveVersion>0</archiveVersion>
+ <data>
+ <version>5</version>
+ <wantNonLocal>1</wantNonLocal>
+ <debug>1</debug>
+ <option>
+ <name>IlinkLibIOConfig</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>XLinkMisraHandler</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IlinkInputFileSlave</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IlinkOutputFile</name>
+ <state>sensorlib.out</state>
+ </option>
+ <option>
+ <name>IlinkDebugInfoEnable</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>IlinkKeepSymbols</name>
+ <state></state>
+ </option>
+ <option>
+ <name>IlinkRawBinaryFile</name>
+ <state></state>
+ </option>
+ <option>
+ <name>IlinkRawBinarySymbol</name>
+ <state></state>
+ </option>
+ <option>
+ <name>IlinkRawBinarySegment</name>
+ <state></state>
+ </option>
+ <option>
+ <name>IlinkRawBinaryAlign</name>
+ <state></state>
+ </option>
+ <option>
+ <name>IlinkDefines</name>
+ <state></state>
+ </option>
+ <option>
+ <name>IlinkConfigDefines</name>
+ <state></state>
+ </option>
+ <option>
+ <name>IlinkMapFile</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IlinkLogFile</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IlinkLogInitialization</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IlinkLogModule</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IlinkLogSection</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IlinkLogVeneer</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IlinkIcfOverride</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IlinkIcfFile</name>
+ <state>lnk0t.icf</state>
+ </option>
+ <option>
+ <name>IlinkIcfFileSlave</name>
+ <state></state>
+ </option>
+ <option>
+ <name>IlinkEnableRemarks</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IlinkSuppressDiags</name>
+ <state></state>
+ </option>
+ <option>
+ <name>IlinkTreatAsRem</name>
+ <state></state>
+ </option>
+ <option>
+ <name>IlinkTreatAsWarn</name>
+ <state></state>
+ </option>
+ <option>
+ <name>IlinkTreatAsErr</name>
+ <state></state>
+ </option>
+ <option>
+ <name>IlinkWarningsAreErrors</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IlinkUseExtraOptions</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IlinkExtraOptions</name>
+ <state></state>
+ </option>
+ <option>
+ <name>IlinkLowLevelInterfaceSlave</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>IlinkAutoLibEnable</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>IlinkAdditionalLibs</name>
+ <state></state>
+ </option>
+ <option>
+ <name>IlinkOverrideProgramEntryLabel</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IlinkProgramEntryLabelSelect</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IlinkProgramEntryLabel</name>
+ <state></state>
+ </option>
+ <option>
+ <name>IlinkNXPLPCChecksum</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>DoFill</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>FillerByte</name>
+ <state>0xFF</state>
+ </option>
+ <option>
+ <name>FillerStart</name>
+ <state>0x0</state>
+ </option>
+ <option>
+ <name>FillerEnd</name>
+ <state>0x0</state>
+ </option>
+ <option>
+ <name>CrcSize</name>
+ <version>0</version>
+ <state>1</state>
+ </option>
+ <option>
+ <name>CrcAlign</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>CrcAlgo</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>CrcPoly</name>
+ <state>0x11021</state>
+ </option>
+ <option>
+ <name>CrcCompl</name>
+ <version>0</version>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CrcBitOrder</name>
+ <version>0</version>
+ <state>0</state>
+ </option>
+ <option>
+ <name>CrcInitialValue</name>
+ <state>0x0</state>
+ </option>
+ <option>
+ <name>DoCrc</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IlinkBE8Slave</name>
+ <state>1</state>
+ </option>
+ <option>
+ <name>IlinkBufferedTerminalOutput</name>
+ <state>1</state>
+ </option>
+ </data>
+ </settings>
+ <settings>
+ <name>IARCHIVE</name>
+ <archiveVersion>0</archiveVersion>
+ <data>
+ <version>0</version>
+ <wantNonLocal>1</wantNonLocal>
+ <debug>1</debug>
+ <option>
+ <name>IarchiveInputs</name>
+ <state></state>
+ </option>
+ <option>
+ <name>IarchiveOverride</name>
+ <state>0</state>
+ </option>
+ <option>
+ <name>IarchiveOutput</name>
+ <state>$PROJ_DIR$\ewarm\Exe\sensorlib.a</state>
+ </option>
+ </data>
+ </settings>
+ <settings>
+ <name>BILINK</name>
+ <archiveVersion>0</archiveVersion>
+ <data/>
+ </settings>
+ </configuration>
+ <group>
+ <name>Source</name>
+ <file>
+ <name>$PROJ_DIR$\ak8963.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\ak8975.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\bmp180.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\bq27510g3.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\cm3218.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\comp_dcm.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\i2cm_drv.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\isl29023.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\kxti9.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\l3gd20h.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\lsm303d.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\lsm303dlhc_accel.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\lsm303dlhc_mag.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\magneto.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\mpu6050.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\mpu9150.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\quaternion.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\sht21.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\tmp006.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\tmp100.c</name>
+ </file>
+ <file>
+ <name>$PROJ_DIR$\vector.c</name>
+ </file>
+ </group>
+</project>
diff --git a/sensorlib/sensorlib.uvopt b/sensorlib/sensorlib.uvopt new file mode 100644 index 0000000..2d5838b --- /dev/null +++ b/sensorlib/sensorlib.uvopt @@ -0,0 +1,524 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<ProjectOpt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_opt.xsd">
+
+ <SchemaVersion>1.0</SchemaVersion>
+
+ <Header>### uVision Project, (C) Keil Software</Header>
+
+ <Extensions>
+ <cExt>*.c</cExt>
+ <aExt>*.s*; *.src; *.a*</aExt>
+ <oExt>*.obj</oExt>
+ <lExt>*.lib</lExt>
+ <tExt>*.txt; *.h; *.inc</tExt>
+ <pExt>*.plm</pExt>
+ <CppX>*.cpp</CppX>
+ </Extensions>
+
+ <DaveTm>
+ <dwLowDateTime>0</dwLowDateTime>
+ <dwHighDateTime>0</dwHighDateTime>
+ </DaveTm>
+
+ <Target>
+ <TargetName>sensorlib</TargetName>
+ <ToolsetNumber>0x4</ToolsetNumber>
+ <ToolsetName>ARM-ADS</ToolsetName>
+ <TargetOption>
+ <CLKADS>8000000</CLKADS>
+ <OPTTT>
+ <gFlags>1</gFlags>
+ <BeepAtEnd>1</BeepAtEnd>
+ <RunSim>1</RunSim>
+ <RunTarget>0</RunTarget>
+ </OPTTT>
+ <OPTHX>
+ <HexSelection>1</HexSelection>
+ <FlashByte>65535</FlashByte>
+ <HexRangeLowAddress>0</HexRangeLowAddress>
+ <HexRangeHighAddress>0</HexRangeHighAddress>
+ <HexOffset>0</HexOffset>
+ </OPTHX>
+ <OPTLEX>
+ <PageWidth>79</PageWidth>
+ <PageLength>66</PageLength>
+ <TabStop>8</TabStop>
+ <ListingPath>.\rvmdk\</ListingPath>
+ </OPTLEX>
+ <ListingPage>
+ <CreateCListing>1</CreateCListing>
+ <CreateAListing>1</CreateAListing>
+ <CreateLListing>1</CreateLListing>
+ <CreateIListing>0</CreateIListing>
+ <AsmCond>1</AsmCond>
+ <AsmSymb>1</AsmSymb>
+ <AsmXref>0</AsmXref>
+ <CCond>1</CCond>
+ <CCode>0</CCode>
+ <CListInc>0</CListInc>
+ <CSymb>0</CSymb>
+ <LinkerCodeListing>0</LinkerCodeListing>
+ </ListingPage>
+ <OPTXL>
+ <LMap>1</LMap>
+ <LComments>1</LComments>
+ <LGenerateSymbols>1</LGenerateSymbols>
+ <LLibSym>1</LLibSym>
+ <LLines>1</LLines>
+ <LLocSym>1</LLocSym>
+ <LPubSym>1</LPubSym>
+ <LXref>0</LXref>
+ <LExpSel>0</LExpSel>
+ </OPTXL>
+ <OPTFL>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <IsCurrentTarget>1</IsCurrentTarget>
+ </OPTFL>
+ <CpuCode>255</CpuCode>
+ <Books>
+ <Book>
+ <Number>0</Number>
+ <Title>Data Sheet</Title>
+ <Path>DATASHTS\Luminary\TM4C1230C3PM.PDF</Path>
+ </Book>
+ </Books>
+ <DllOpt>
+ <SimDllName>SARMCM3.DLL</SimDllName>
+ <SimDllArguments>-MPU</SimDllArguments>
+ <SimDlgDllName>DCM.DLL</SimDlgDllName>
+ <SimDlgDllArguments>-pCM4</SimDlgDllArguments>
+ <TargetDllName>SARMCM3.DLL</TargetDllName>
+ <TargetDllArguments>-MPU</TargetDllArguments>
+ <TargetDlgDllName>TCM.DLL</TargetDlgDllName>
+ <TargetDlgDllArguments>-pCM4</TargetDlgDllArguments>
+ </DllOpt>
+ <DebugOpt>
+ <uSim>1</uSim>
+ <uTrg>0</uTrg>
+ <sLdApp>1</sLdApp>
+ <sGomain>1</sGomain>
+ <sRbreak>1</sRbreak>
+ <sRwatch>1</sRwatch>
+ <sRmem>1</sRmem>
+ <sRfunc>1</sRfunc>
+ <sRbox>1</sRbox>
+ <tLdApp>1</tLdApp>
+ <tGomain>0</tGomain>
+ <tRbreak>1</tRbreak>
+ <tRwatch>1</tRwatch>
+ <tRmem>1</tRmem>
+ <tRfunc>0</tRfunc>
+ <tRbox>1</tRbox>
+ <sRunDeb>0</sRunDeb>
+ <sLrtime>0</sLrtime>
+ <nTsel>3</nTsel>
+ <sDll></sDll>
+ <sDllPa></sDllPa>
+ <sDlgDll></sDlgDll>
+ <sDlgPa></sDlgPa>
+ <sIfile></sIfile>
+ <tDll></tDll>
+ <tDllPa></tDllPa>
+ <tDlgDll></tDlgDll>
+ <tDlgPa></tDlgPa>
+ <tIfile></tIfile>
+ <pMon>BIN\lmidk-agdi.dll</pMon>
+ </DebugOpt>
+ <TargetDriverDllRegistry>
+ <SetRegEntry>
+ <Number>0</Number>
+ <Key>lmidk-agdi</Key>
+ <Name>-O4622 -S3 -FO29</Name>
+ </SetRegEntry>
+ </TargetDriverDllRegistry>
+ <DebugFlag>
+ <trace>0</trace>
+ <periodic>1</periodic>
+ <aLwin>0</aLwin>
+ <aCover>0</aCover>
+ <aSer1>0</aSer1>
+ <aSer2>0</aSer2>
+ <aPa>0</aPa>
+ <viewmode>0</viewmode>
+ <vrSel>0</vrSel>
+ <aSym>0</aSym>
+ <aTbox>0</aTbox>
+ <AscS1>0</AscS1>
+ <AscS2>0</AscS2>
+ <AscS3>0</AscS3>
+ <aSer3>0</aSer3>
+ <eProf>0</eProf>
+ <aLa>0</aLa>
+ <aPa1>0</aPa1>
+ <AscS4>0</AscS4>
+ <aSer4>0</aSer4>
+ <StkLoc>0</StkLoc>
+ <TrcWin>0</TrcWin>
+ <newCpu>0</newCpu>
+ <uProt>0</uProt>
+ </DebugFlag>
+ <LintExecutable></LintExecutable>
+ <LintConfigFile></LintConfigFile>
+ </TargetOption>
+ </Target>
+
+ <Group>
+ <GroupName>Source</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>1</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\ak8963.c</PathWithFileName>
+ <FilenameWithoutPath>ak8963.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>2</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\ak8975.c</PathWithFileName>
+ <FilenameWithoutPath>ak8975.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>3</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\bmp180.c</PathWithFileName>
+ <FilenameWithoutPath>bmp180.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>4</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\bq27510g3.c</PathWithFileName>
+ <FilenameWithoutPath>bq27510g3.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>5</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\cm3218.c</PathWithFileName>
+ <FilenameWithoutPath>cm3218.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>6</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\comp_dcm.c</PathWithFileName>
+ <FilenameWithoutPath>comp_dcm.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>7</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\i2cm_drv.c</PathWithFileName>
+ <FilenameWithoutPath>i2cm_drv.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>8</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\isl29023.c</PathWithFileName>
+ <FilenameWithoutPath>isl29023.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>9</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\kxti9.c</PathWithFileName>
+ <FilenameWithoutPath>kxti9.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>10</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\l3gd20h.c</PathWithFileName>
+ <FilenameWithoutPath>l3gd20h.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>11</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\lsm303d.c</PathWithFileName>
+ <FilenameWithoutPath>lsm303d.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>12</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\lsm303dlhc_accel.c</PathWithFileName>
+ <FilenameWithoutPath>lsm303dlhc_accel.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>13</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\lsm303dlhc_mag.c</PathWithFileName>
+ <FilenameWithoutPath>lsm303dlhc_mag.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>14</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\magneto.c</PathWithFileName>
+ <FilenameWithoutPath>magneto.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>15</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\mpu6050.c</PathWithFileName>
+ <FilenameWithoutPath>mpu6050.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>16</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\mpu9150.c</PathWithFileName>
+ <FilenameWithoutPath>mpu9150.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>17</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\quaternion.c</PathWithFileName>
+ <FilenameWithoutPath>quaternion.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>18</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\sht21.c</PathWithFileName>
+ <FilenameWithoutPath>sht21.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>19</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\tmp006.c</PathWithFileName>
+ <FilenameWithoutPath>tmp006.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>20</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\tmp100.c</PathWithFileName>
+ <FilenameWithoutPath>tmp100.c</FilenameWithoutPath>
+ </File>
+ <File>
+ <GroupNumber>1</GroupNumber>
+ <FileNumber>21</FileNumber>
+ <FileType>1</FileType>
+ <tvExp>0</tvExp>
+ <Focus>0</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>0</TopLine>
+ <CurrentLine>0</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\vector.c</PathWithFileName>
+ <FilenameWithoutPath>vector.c</FilenameWithoutPath>
+ </File>
+ </Group>
+
+ <Group>
+ <GroupName>Documentation</GroupName>
+ <tvExp>1</tvExp>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <cbSel>0</cbSel>
+ <File>
+ <GroupNumber>2</GroupNumber>
+ <FileNumber>22</FileNumber>
+ <FileType>5</FileType>
+ <tvExp>0</tvExp>
+ <Focus>1</Focus>
+ <ColumnNumber>0</ColumnNumber>
+ <tvExpOptDlg>0</tvExpOptDlg>
+ <TopLine>1</TopLine>
+ <CurrentLine>1</CurrentLine>
+ <bDave2>0</bDave2>
+ <PathWithFileName>.\readme.txt</PathWithFileName>
+ <FilenameWithoutPath>readme.txt</FilenameWithoutPath>
+ <WindowPosition>
+ <length>44</length>
+ <flags>0</flags>
+ <showCmd>1</showCmd>
+ <MinPosition>
+ <xPos>-1</xPos>
+ <yPos>-1</yPos>
+ </MinPosition>
+ <MaxPosition>
+ <xPos>-1</xPos>
+ <yPos>-1</yPos>
+ </MaxPosition>
+ <NormalPosition>
+ <Top>0</Top>
+ <Left>0</Left>
+ <Right>729</Right>
+ <Bottom>300</Bottom>
+ </NormalPosition>
+ </WindowPosition>
+ </File>
+ </Group>
+
+ <MDIGroups>
+ <Orientation>1</Orientation>
+ <ActiveMDIGroup>0</ActiveMDIGroup>
+ <MDIGroup>
+ <Size>100</Size>
+ <ActiveTab>0</ActiveTab>
+ <Documents>
+ <Doc>
+ <Name>.\readme.txt</Name>
+ <ColumnNumber>0</ColumnNumber>
+ <TopLine>1</TopLine>
+ <CurrentLine>1</CurrentLine>
+ </Doc>
+ </Documents>
+ </MDIGroup>
+ </MDIGroups>
+
+</ProjectOpt>
diff --git a/sensorlib/sensorlib.uvproj b/sensorlib/sensorlib.uvproj new file mode 100644 index 0000000..7d88e4c --- /dev/null +++ b/sensorlib/sensorlib.uvproj @@ -0,0 +1,510 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_proj.xsd">
+
+ <SchemaVersion>1.1</SchemaVersion>
+
+ <Header>### uVision Project, (C) Keil Software</Header>
+
+ <Targets>
+ <Target>
+ <TargetName>sensorlib</TargetName>
+ <ToolsetNumber>0x4</ToolsetNumber>
+ <ToolsetName>ARM-ADS</ToolsetName>
+ <TargetOption>
+ <TargetCommonOption>
+ <Device>TM4C1230C3PM</Device>
+ <Vendor>Texas Instruments</Vendor>
+ <Cpu>IRAM(0x20000000-0x20002FFF) IROM(0-0x7FFF) CLOCK(8000000) CPUTYPE("Cortex-M4") FPU2</Cpu>
+ <FlashUtilSpec></FlashUtilSpec>
+ <StartupFile>"STARTUP\Luminary\Startup.s" ("Luminary Startup Code")</StartupFile>
+ <FlashDriverDll>UL2CM3(-O207 -S0 -C0 -FO7 -FD20000000 -FC800 -FN1 -FF0LM4F_32 -FS00 -FL08000)</FlashDriverDll>
+ <DeviceId>5919</DeviceId>
+ <RegisterFile>LM4Fxxxx.H</RegisterFile>
+ <MemoryEnv></MemoryEnv>
+ <Cmp></Cmp>
+ <Asm></Asm>
+ <Linker></Linker>
+ <OHString></OHString>
+ <InfinionOptionDll></InfinionOptionDll>
+ <SLE66CMisc></SLE66CMisc>
+ <SLE66AMisc></SLE66AMisc>
+ <SLE66LinkerMisc></SLE66LinkerMisc>
+ <SFDFile>SFD\Luminary\TM4C1230C3PM.SFR</SFDFile>
+ <UseEnv>0</UseEnv>
+ <BinPath></BinPath>
+ <IncludePath></IncludePath>
+ <LibPath></LibPath>
+ <RegisterFilePath>Luminary\</RegisterFilePath>
+ <DBRegisterFilePath>Luminary\</DBRegisterFilePath>
+ <TargetStatus>
+ <Error>0</Error>
+ <ExitCodeStop>0</ExitCodeStop>
+ <ButtonStop>0</ButtonStop>
+ <NotGenerated>0</NotGenerated>
+ <InvalidFlash>1</InvalidFlash>
+ </TargetStatus>
+ <OutputDirectory>.\rvmdk\</OutputDirectory>
+ <OutputName>sensorlib</OutputName>
+ <CreateExecutable>0</CreateExecutable>
+ <CreateLib>1</CreateLib>
+ <CreateHexFile>0</CreateHexFile>
+ <DebugInformation>1</DebugInformation>
+ <BrowseInformation>1</BrowseInformation>
+ <ListingPath>.\rvmdk\</ListingPath>
+ <HexFormatSelection>1</HexFormatSelection>
+ <Merge32K>0</Merge32K>
+ <CreateBatchFile>0</CreateBatchFile>
+ <BeforeCompile>
+ <RunUserProg1>0</RunUserProg1>
+ <RunUserProg2>0</RunUserProg2>
+ <UserProg1Name></UserProg1Name>
+ <UserProg2Name></UserProg2Name>
+ <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+ <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+ </BeforeCompile>
+ <BeforeMake>
+ <RunUserProg1>0</RunUserProg1>
+ <RunUserProg2>0</RunUserProg2>
+ <UserProg1Name></UserProg1Name>
+ <UserProg2Name></UserProg2Name>
+ <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+ <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+ </BeforeMake>
+ <AfterMake>
+ <RunUserProg1>0</RunUserProg1>
+ <RunUserProg2>0</RunUserProg2>
+ <UserProg1Name></UserProg1Name>
+ <UserProg2Name></UserProg2Name>
+ <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+ <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+ </AfterMake>
+ <SelectedForBatchBuild>0</SelectedForBatchBuild>
+ <SVCSIdString></SVCSIdString>
+ </TargetCommonOption>
+ <CommonProperty>
+ <UseCPPCompiler>0</UseCPPCompiler>
+ <RVCTCodeConst>0</RVCTCodeConst>
+ <RVCTZI>0</RVCTZI>
+ <RVCTOtherData>0</RVCTOtherData>
+ <ModuleSelection>0</ModuleSelection>
+ <IncludeInBuild>1</IncludeInBuild>
+ <AlwaysBuild>0</AlwaysBuild>
+ <GenerateAssemblyFile>0</GenerateAssemblyFile>
+ <AssembleAssemblyFile>0</AssembleAssemblyFile>
+ <PublicsOnly>0</PublicsOnly>
+ <StopOnExitCode>3</StopOnExitCode>
+ <CustomArgument></CustomArgument>
+ <IncludeLibraryModules></IncludeLibraryModules>
+ </CommonProperty>
+ <DllOption>
+ <SimDllName>SARMCM3.DLL</SimDllName>
+ <SimDllArguments>-MPU</SimDllArguments>
+ <SimDlgDll>DCM.DLL</SimDlgDll>
+ <SimDlgDllArguments>-pCM4</SimDlgDllArguments>
+ <TargetDllName>SARMCM3.DLL</TargetDllName>
+ <TargetDllArguments>-MPU</TargetDllArguments>
+ <TargetDlgDll>TCM.DLL</TargetDlgDll>
+ <TargetDlgDllArguments>-pCM4</TargetDlgDllArguments>
+ </DllOption>
+ <DebugOption>
+ <OPTHX>
+ <HexSelection>1</HexSelection>
+ <HexRangeLowAddress>0</HexRangeLowAddress>
+ <HexRangeHighAddress>0</HexRangeHighAddress>
+ <HexOffset>0</HexOffset>
+ <Oh166RecLen>16</Oh166RecLen>
+ </OPTHX>
+ <Simulator>
+ <UseSimulator>1</UseSimulator>
+ <LoadApplicationAtStartup>1</LoadApplicationAtStartup>
+ <RunToMain>1</RunToMain>
+ <RestoreBreakpoints>1</RestoreBreakpoints>
+ <RestoreWatchpoints>1</RestoreWatchpoints>
+ <RestoreMemoryDisplay>1</RestoreMemoryDisplay>
+ <RestoreFunctions>1</RestoreFunctions>
+ <RestoreToolbox>1</RestoreToolbox>
+ <LimitSpeedToRealTime>0</LimitSpeedToRealTime>
+ </Simulator>
+ <Target>
+ <UseTarget>0</UseTarget>
+ <LoadApplicationAtStartup>1</LoadApplicationAtStartup>
+ <RunToMain>0</RunToMain>
+ <RestoreBreakpoints>1</RestoreBreakpoints>
+ <RestoreWatchpoints>1</RestoreWatchpoints>
+ <RestoreMemoryDisplay>1</RestoreMemoryDisplay>
+ <RestoreFunctions>0</RestoreFunctions>
+ <RestoreToolbox>1</RestoreToolbox>
+ </Target>
+ <RunDebugAfterBuild>0</RunDebugAfterBuild>
+ <TargetSelection>3</TargetSelection>
+ <SimDlls>
+ <CpuDll></CpuDll>
+ <CpuDllArguments></CpuDllArguments>
+ <PeripheralDll></PeripheralDll>
+ <PeripheralDllArguments></PeripheralDllArguments>
+ <InitializationFile></InitializationFile>
+ </SimDlls>
+ <TargetDlls>
+ <CpuDll></CpuDll>
+ <CpuDllArguments></CpuDllArguments>
+ <PeripheralDll></PeripheralDll>
+ <PeripheralDllArguments></PeripheralDllArguments>
+ <InitializationFile></InitializationFile>
+ <Driver>BIN\lmidk-agdi.dll</Driver>
+ </TargetDlls>
+ </DebugOption>
+ <Utilities>
+ <Flash1>
+ <UseTargetDll>1</UseTargetDll>
+ <UseExternalTool>0</UseExternalTool>
+ <RunIndependent>0</RunIndependent>
+ <UpdateFlashBeforeDebugging>0</UpdateFlashBeforeDebugging>
+ <Capability>1</Capability>
+ <DriverSelection>4097</DriverSelection>
+ </Flash1>
+ <Flash2>BIN\lmidk-agdi.dll</Flash2>
+ <Flash3></Flash3>
+ <Flash4></Flash4>
+ </Utilities>
+ <TargetArmAds>
+ <ArmAdsMisc>
+ <GenerateListings>0</GenerateListings>
+ <asHll>1</asHll>
+ <asAsm>1</asAsm>
+ <asMacX>1</asMacX>
+ <asSyms>1</asSyms>
+ <asFals>1</asFals>
+ <asDbgD>1</asDbgD>
+ <asForm>1</asForm>
+ <ldLst>0</ldLst>
+ <ldmm>1</ldmm>
+ <ldXref>1</ldXref>
+ <BigEnd>0</BigEnd>
+ <AdsALst>0</AdsALst>
+ <AdsACrf>0</AdsACrf>
+ <AdsANop>0</AdsANop>
+ <AdsANot>0</AdsANot>
+ <AdsLLst>0</AdsLLst>
+ <AdsLmap>0</AdsLmap>
+ <AdsLcgr>0</AdsLcgr>
+ <AdsLsym>0</AdsLsym>
+ <AdsLszi>0</AdsLszi>
+ <AdsLtoi>0</AdsLtoi>
+ <AdsLsun>0</AdsLsun>
+ <AdsLven>0</AdsLven>
+ <AdsLsxf>0</AdsLsxf>
+ <RvctClst>0</RvctClst>
+ <GenPPlst>0</GenPPlst>
+ <AdsCpuType>"Cortex-M4"</AdsCpuType>
+ <RvctDeviceName></RvctDeviceName>
+ <mOS>0</mOS>
+ <uocRom>0</uocRom>
+ <uocRam>0</uocRam>
+ <hadIROM>1</hadIROM>
+ <hadIRAM>1</hadIRAM>
+ <hadXRAM>0</hadXRAM>
+ <uocXRam>0</uocXRam>
+ <RvdsVP>2</RvdsVP>
+ <hadIRAM2>0</hadIRAM2>
+ <hadIROM2>0</hadIROM2>
+ <StupSel>8</StupSel>
+ <useUlib>1</useUlib>
+ <EndSel>0</EndSel>
+ <uLtcg>0</uLtcg>
+ <RoSelD>3</RoSelD>
+ <RwSelD>3</RwSelD>
+ <CodeSel>0</CodeSel>
+ <OptFeed>0</OptFeed>
+ <NoZi1>0</NoZi1>
+ <NoZi2>0</NoZi2>
+ <NoZi3>0</NoZi3>
+ <NoZi4>0</NoZi4>
+ <NoZi5>0</NoZi5>
+ <Ro1Chk>0</Ro1Chk>
+ <Ro2Chk>0</Ro2Chk>
+ <Ro3Chk>0</Ro3Chk>
+ <Ir1Chk>1</Ir1Chk>
+ <Ir2Chk>0</Ir2Chk>
+ <Ra1Chk>0</Ra1Chk>
+ <Ra2Chk>0</Ra2Chk>
+ <Ra3Chk>0</Ra3Chk>
+ <Im1Chk>1</Im1Chk>
+ <Im2Chk>0</Im2Chk>
+ <OnChipMemories>
+ <Ocm1>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </Ocm1>
+ <Ocm2>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </Ocm2>
+ <Ocm3>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </Ocm3>
+ <Ocm4>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </Ocm4>
+ <Ocm5>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </Ocm5>
+ <Ocm6>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </Ocm6>
+ <IRAM>
+ <Type>0</Type>
+ <StartAddress>0x20000000</StartAddress>
+ <Size>0x3000</Size>
+ </IRAM>
+ <IROM>
+ <Type>1</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x8000</Size>
+ </IROM>
+ <XRAM>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </XRAM>
+ <OCR_RVCT1>
+ <Type>1</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </OCR_RVCT1>
+ <OCR_RVCT2>
+ <Type>1</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </OCR_RVCT2>
+ <OCR_RVCT3>
+ <Type>1</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </OCR_RVCT3>
+ <OCR_RVCT4>
+ <Type>1</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x8000</Size>
+ </OCR_RVCT4>
+ <OCR_RVCT5>
+ <Type>1</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </OCR_RVCT5>
+ <OCR_RVCT6>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </OCR_RVCT6>
+ <OCR_RVCT7>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </OCR_RVCT7>
+ <OCR_RVCT8>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </OCR_RVCT8>
+ <OCR_RVCT9>
+ <Type>0</Type>
+ <StartAddress>0x20000000</StartAddress>
+ <Size>0x3000</Size>
+ </OCR_RVCT9>
+ <OCR_RVCT10>
+ <Type>0</Type>
+ <StartAddress>0x0</StartAddress>
+ <Size>0x0</Size>
+ </OCR_RVCT10>
+ </OnChipMemories>
+ <RvctStartVector></RvctStartVector>
+ </ArmAdsMisc>
+ <Cads>
+ <interw>0</interw>
+ <Optim>3</Optim>
+ <oTime>1</oTime>
+ <SplitLS>0</SplitLS>
+ <OneElfS>1</OneElfS>
+ <Strict>0</Strict>
+ <EnumInt>0</EnumInt>
+ <PlainCh>0</PlainCh>
+ <Ropi>0</Ropi>
+ <Rwpi>0</Rwpi>
+ <wLevel>2</wLevel>
+ <uThumb>0</uThumb>
+ <VariousControls>
+ <MiscControls>--c99</MiscControls>
+ <Define>rvmdk </Define>
+ <Undefine></Undefine>
+ <IncludePath>..;</IncludePath>
+ </VariousControls>
+ </Cads>
+ <Aads>
+ <interw>1</interw>
+ <Ropi>0</Ropi>
+ <Rwpi>0</Rwpi>
+ <thumb>0</thumb>
+ <SplitLS>0</SplitLS>
+ <SwStkChk>0</SwStkChk>
+ <NoWarn>0</NoWarn>
+ <VariousControls>
+ <MiscControls></MiscControls>
+ <Define></Define>
+ <Undefine></Undefine>
+ <IncludePath></IncludePath>
+ </VariousControls>
+ </Aads>
+ <LDads>
+ <umfTarg>0</umfTarg>
+ <Ropi>0</Ropi>
+ <Rwpi>0</Rwpi>
+ <noStLib>0</noStLib>
+ <RepFail>1</RepFail>
+ <useFile>0</useFile>
+ <TextAddressRange>0x00000000</TextAddressRange>
+ <DataAddressRange>0x20000000</DataAddressRange>
+ <ScatterFile></ScatterFile>
+ <IncludeLibs></IncludeLibs>
+ <IncludeLibsPath></IncludeLibsPath>
+ <Misc></Misc>
+ <LinkerInputFile></LinkerInputFile>
+ <DisabledWarnings></DisabledWarnings>
+ </LDads>
+ </TargetArmAds>
+ </TargetOption>
+ <Groups>
+ <Group>
+ <GroupName>Source</GroupName>
+ <Files>
+ <File>
+ <FileName>ak8963.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\ak8963.c</FilePath>
+ </File>
+ <File>
+ <FileName>ak8975.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\ak8975.c</FilePath>
+ </File>
+ <File>
+ <FileName>bmp180.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\bmp180.c</FilePath>
+ </File>
+ <File>
+ <FileName>bq27510g3.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\bq27510g3.c</FilePath>
+ </File>
+ <File>
+ <FileName>cm3218.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\cm3218.c</FilePath>
+ </File>
+ <File>
+ <FileName>comp_dcm.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\comp_dcm.c</FilePath>
+ </File>
+ <File>
+ <FileName>i2cm_drv.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\i2cm_drv.c</FilePath>
+ </File>
+ <File>
+ <FileName>isl29023.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\isl29023.c</FilePath>
+ </File>
+ <File>
+ <FileName>kxti9.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\kxti9.c</FilePath>
+ </File>
+ <File>
+ <FileName>l3gd20h.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\l3gd20h.c</FilePath>
+ </File>
+ <File>
+ <FileName>lsm303d.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\lsm303d.c</FilePath>
+ </File>
+ <File>
+ <FileName>lsm303dlhc_accel.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\lsm303dlhc_accel.c</FilePath>
+ </File>
+ <File>
+ <FileName>lsm303dlhc_mag.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\lsm303dlhc_mag.c</FilePath>
+ </File>
+ <File>
+ <FileName>magneto.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\magneto.c</FilePath>
+ </File>
+ <File>
+ <FileName>mpu6050.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\mpu6050.c</FilePath>
+ </File>
+ <File>
+ <FileName>mpu9150.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\mpu9150.c</FilePath>
+ </File>
+ <File>
+ <FileName>quaternion.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\quaternion.c</FilePath>
+ </File>
+ <File>
+ <FileName>sht21.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\sht21.c</FilePath>
+ </File>
+ <File>
+ <FileName>tmp006.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\tmp006.c</FilePath>
+ </File>
+ <File>
+ <FileName>tmp100.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\tmp100.c</FilePath>
+ </File>
+ <File>
+ <FileName>vector.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>.\vector.c</FilePath>
+ </File>
+ </Files>
+ </Group>
+ <Group>
+ <GroupName>Documentation</GroupName>
+ <Files>
+ <File>
+ <FileName>readme.txt</FileName>
+ <FileType>5</FileType>
+ <FilePath>.\readme.txt</FilePath>
+ </File>
+ </Files>
+ </Group>
+ </Groups>
+ </Target>
+ </Targets>
+
+</Project>
diff --git a/sensorlib/sht21.c b/sensorlib/sht21.c new file mode 100644 index 0000000..0698593 --- /dev/null +++ b/sensorlib/sht21.c @@ -0,0 +1,564 @@ +//*****************************************************************************
+//
+// sht21.c - Driver for the SHT21 accelerometer.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <stdint.h>
+#include "sensorlib/hw_sht21.h"
+#include "sensorlib/i2cm_drv.h"
+#include "sensorlib/sht21.h"
+
+//*****************************************************************************
+//
+//! \addtogroup sht21_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The states of the SHT21 state machine.
+//
+//*****************************************************************************
+#define SHT21_STATE_IDLE 0 // State machine is idle
+#define SHT21_STATE_INIT 1 // Waiting for initialization
+#define SHT21_STATE_READ 2 // Waiting for register read
+#define SHT21_STATE_WRITE 3 // Waiting for register write
+#define SHT21_STATE_RMW 4
+#define SHT21_STATE_READ_DATA 5 // Waiting for temperature or
+ // humidity data
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transactions to/from the
+// SHT21 have completed.
+//
+//*****************************************************************************
+static void
+SHT21Callback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tSHT21 *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tSHT221 structure.
+ //
+ psInst = (tSHT21 *)pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result in a callback to propagate the
+ // error).
+ //
+ if(ui8Status != I2CM_STATUS_SUCCESS)
+ {
+ psInst->ui8State = SHT21_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the SHT21 state machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // All states that trivially transition to IDLE, and all unknown
+ // states.
+ //
+ case SHT21_STATE_INIT:
+ case SHT21_STATE_READ:
+ case SHT21_STATE_WRITE:
+ case SHT21_STATE_READ_DATA:
+ case SHT21_STATE_RMW:
+ default:
+ {
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = SHT21_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == SHT21_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the SHT21 driver.
+//!
+//! \param psInst is a pointer to the SHT21 instance data.
+//! \param psI2CInst is a pointer to the I2C driver instance data.
+//! \param ui8I2CAddr is the I2C address of the SHT21 device.
+//! \param pfnCallback is the function to be called when the initialization has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initializes the SHT21 driver, preparing it for operation, and
+//! initiates a reset of the SHT21 device, clearing any previous configuration
+//! data.
+//!
+//! \return Returns 1 if the SHT21 driver was successfully initialized and 0 if
+//! it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+SHT21Init(tSHT21 *psInst, tI2CMInstance *psI2CInst, uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Initialize the SHT21 instance structure.
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8I2CAddr;
+ psInst->ui8State = SHT21_STATE_INIT;
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Perform a soft reset of the SHT21.
+ //
+ psInst->pui8Data[0] = SHT21_CMD_SOFT_RESET;
+ if(I2CMWrite(psInst->psI2CInst, ui8I2CAddr, psInst->pui8Data, 1,
+ SHT21Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = SHT21_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads data from SHT21 registers.
+//!
+//! \param psInst is a pointer to the SHT21 instance data.
+//! \param ui8Reg is the first register to read.
+//! \param pui8Data is a pointer to the location to store the data that is
+//! read.
+//! \param ui16Count the number of data bytes to read.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData pointer that is passed to the callback function.
+//!
+//! This function reads a sequence of data values from consecutive registers in
+//! the SHT21.
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+SHT21Read(tSHT21 *psInst, uint_fast8_t ui8Reg, uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the SHT21 driver is not idle (in other words, there
+ // is already an outstanding request to the SHT21).
+ //
+ if(psInst->ui8State != SHT21_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read state.
+ //
+ psInst->ui8State = SHT21_STATE_READ;
+
+ //
+ // Read the requested registers from the SHT21.
+ //
+ psInst->uCommand.pui8Buffer[0] = ui8Reg;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, pui8Data, ui16Count,
+ SHT21Callback, (void *)psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = SHT21_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Writes data to SHT21 registers.
+//!
+//! \param psInst is a pointer to the SHT21 instance data.
+//! \param ui8Reg is the register offset to be written.
+//! \param pui8Data is the data buffer bytes to write.
+//! \param ui16Count is the number of bytes to write.
+//! \param pfnCallback is the function to be called when the data has been
+//! written (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function writes a sequence of data values to consecutive registers in
+//! the SHT21. The first byte of the \e pui8Data buffer contains the value to
+//! be written into the \e ui8Reg register, the second value contains the data
+//! to be written into the next register, and so on.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+SHT21Write(tSHT21 *psInst, uint_fast8_t ui8Reg, const uint8_t *pui8Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the SHT21 driver is not idle (in other words, there
+ // is already an outstanding request to the SHT21).
+ //
+ if(psInst->ui8State != SHT21_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for write state.
+ //
+ psInst->ui8State = SHT21_STATE_WRITE;
+
+ //
+ // Write the requested registers to the SHT21.
+ //
+ if(I2CMWrite8(&(psInst->uCommand.sWriteState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui8Data, ui16Count, SHT21Callback,
+ psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = SHT21_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of a SHT21 register.
+//!
+//! \param psInst is a pointer to the SHT21 instance data.
+//! \param ui8Reg is the register to modify.
+//! \param ui8Mask is the bit mask that is ANDed with the current register
+//! value.
+//! \param ui8Value is the bit mask that is ORed with the result of the AND
+//! operation.
+//! \param pfnCallback is the function to be called when the data has been
+//! changed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function changes the value of a register in the SHT21 via a
+//! read-modify-write operation, allowing one of the fields to be changed
+//! without disturbing the other fields. The \e ui8Reg register is read, ANDed
+//! with \e ui8Mask, ORed with \e ui8Value, and then written back to the SHT21.
+//!
+//! \return Returns 1 if the read-modify-write was successfully started and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+SHT21ReadModifyWrite(tSHT21 *psInst, uint_fast8_t ui8Reg, uint_fast8_t ui8Mask,
+ uint_fast8_t ui8Value, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the SHT21 driver is not idle (in other words, there
+ // is already an outstanding request to the SHT21).
+ //
+ if(psInst->ui8State != SHT21_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read-modify-write state.
+ //
+ psInst->ui8State = SHT21_STATE_RMW;
+
+ //
+ // Submit the read-modify-write request to the TMP006.
+ //
+ if(I2CMReadModifyWrite8(&(psInst->uCommand.sReadModifyWriteState),
+ psInst->psI2CInst, psInst->ui8Addr, ui8Reg,
+ ui8Mask, ui8Value, SHT21Callback, psInst) == 0)
+ {
+ //
+ // The I2C read-modify-write failed, so move to the idle state and
+ // return a failure.
+ //
+ psInst->ui8State = SHT21_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads the temperature and humidity data from the SHT21.
+//!
+//! \param psInst is a pointer to the SHT21 instance data
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read of the SHT21 data registers. The user must
+//! first initiate a measurement by using the SHT21Write() function configured
+//! to write the command for a humidity or temperature measurement. In the
+//! case of a measurement with I2C bus hold, this function is not needed. When
+//! the read has completed (as indicated by callback function), the new
+//! readings can be obtained via:
+//!
+//! - SHT21DataTemperatureGetRaw()
+//! - SHT21DataTemperatureGetFloat()
+//! - SHT21DataHumidityGetRaw()
+//! - SHT21DataHumidityGetFloat()
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+SHT21DataRead(tSHT21 *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the SHT21 driver is not idle (in other words, there
+ // is already an outstanding request to the SHT21).
+ //
+ if(psInst->ui8State != SHT21_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for data read state.
+ //
+ psInst->ui8State = SHT21_STATE_READ_DATA;
+
+ //
+ // Read the data registers from the SHT21.
+ //
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr, 0, 0, psInst->pui8Data, 2,
+ SHT21Callback, psInst) == 0)
+ {
+ psInst->ui8State = SHT21_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Returns the raw temperature measurement as received from the SHT21.
+//!
+//! \param psInst is a pointer to the SHT21 instance data.
+//! \param pui16Temperature is a pointer to the value into which the raw
+//! temperature data is stored.
+//!
+//! This function returns the raw temperature data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SHT21DataTemperatureGetRaw(tSHT21 *psInst, uint16_t *pui16Temperature)
+{
+ //
+ // Return the raw temperature value.
+ //
+ *pui16Temperature = ((((uint16_t)psInst->pui8Data[0]) << 8) |
+ (uint16_t)psInst->pui8Data[1]);
+}
+
+//*****************************************************************************
+//
+//! Returns the most recent temperature measurement in floating point degrees
+//! Celsius.
+//!
+//! \param psInst is a pointer to the SHT21 instance data.
+//! \param pfTemperature is a pointer to the value into which the temperature
+//! data is stored.
+//!
+//! This function converts the raw temperature measurement data into floating
+//! point degrees Celsius and returns the result. See the SHT21 datasheet
+//! section 6.2 for more information about the conversion formula used.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SHT21DataTemperatureGetFloat(tSHT21 *psInst, float *pfTemperature)
+{
+ uint16_t ui16TemperatureRaw;
+
+ //
+ // Get the raw temperature into a floating point variable
+ //
+ SHT21DataTemperatureGetRaw(psInst, &ui16TemperatureRaw);
+ *pfTemperature = (float)(ui16TemperatureRaw & 0xFFFC);
+
+ //
+ // Equation from SHT21 datasheet for raw to Celsius conversion.
+ //
+ *pfTemperature = -46.85 + 175.72 * (*pfTemperature / 65536.0);
+}
+
+//*****************************************************************************
+//
+//! Returns the raw humidity measurement from the SHT21.
+//!
+//! \param psInst is a pointer to the SHT21 instance data.
+//! \param pui16Humidity is a pointer to the value into which the raw humidity
+//! data is stored.
+//!
+//! This function returns the raw humidity data from the most recent data read.
+//! The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SHT21DataHumidityGetRaw(tSHT21 *psInst, uint16_t *pui16Humidity)
+{
+ //
+ // Return the raw humidity value.
+ //
+ *pui16Humidity = ((((uint16_t)psInst->pui8Data[0]) << 8) |
+ (uint16_t)psInst->pui8Data[1]);
+}
+
+//*****************************************************************************
+//
+//! Returns the relative humidity measurement as a floating point percentage.
+//!
+//! \param psInst pointer to the SHT21 instance data.
+//! \param pfHumidity is a pointer to the value into which the humidity data
+//! is stored.
+//!
+//! This function converts the raw humidity measurement to
+//! floating-point-percentage relative humidity over water. For more
+//! information on the conversion algorithm see the SHT21 datasheet section
+//! 6.1.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SHT21DataHumidityGetFloat(tSHT21 *psInst, float *pfHumidity)
+{
+ uint16_t ui16HumidityRaw;
+
+ //
+ // Convert the raw measure to float for later math.
+ //
+ SHT21DataHumidityGetRaw(psInst, &ui16HumidityRaw);
+ *pfHumidity = (float)(ui16HumidityRaw & 0xFFFC);
+
+ //
+ // Convert from raw measurement to percent relative humidity over water
+ // per the datasheet formula.
+ //
+ *pfHumidity = -6.0 + 125.0 * (*pfHumidity / 65536.0);
+
+ //
+ // Convert to a number from 0 to 1.0 instead of 0 to 100%.
+ //
+ *pfHumidity /= 100.0;
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/sht21.h b/sensorlib/sht21.h new file mode 100644 index 0000000..7956b0e --- /dev/null +++ b/sensorlib/sht21.h @@ -0,0 +1,156 @@ +//*****************************************************************************
+//
+// sht21.h - Prototypes for the SHT21 accelerometer driver.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_SHT21_H__
+#define __SENSORLIB_SHT21_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the SHT21 driver.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The pointer to the I2C master interface instance used to communicate
+ // with the SHT21.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // the I2C address of the SHT21.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // the state of the state machine used while accessing the
+ // SHT21.
+ //
+ uint8_t ui8State;
+
+ //
+ // the data buffer used for sending/receiving data to/from the
+ // SHT21.
+ //
+ uint8_t pui8Data[5];
+
+ //
+ // the 16 bit raw temperature reading
+ //
+ uint16_t ui16Temperature;
+
+ //
+ // the 16 bit raw humidity reading
+ //
+ uint16_t ui16Humidity;
+
+ //
+ // the function that is called when the current request has
+ // completed processing.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // the callback data provided to the callback function.
+ //
+ void *pvCallbackData;
+
+ //
+ // A union of structures that are used for read, write and
+ // read-modify-write operations. Since only one operation can be active at
+ // a time, it is safe to re-use the memory in this manner.
+ //
+ union
+ {
+ //
+ // A buffer used to store the write portion of a register read.
+ //
+ uint8_t pui8Buffer[2];
+
+ //
+ // The write state used to write register values.
+ //
+ tI2CMWrite8 sWriteState;
+
+ //
+ // The read-modify-write state used to modify register values.
+ //
+ tI2CMReadModifyWrite8 sReadModifyWriteState;
+ }
+ uCommand;
+}
+tSHT21;
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern uint_fast8_t SHT21Init(tSHT21 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t SHT21Read(tSHT21 *psInst, uint_fast8_t ui8Reg,
+ uint8_t *pui8Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t SHT21Write(tSHT21 *psInst, uint_fast8_t ui8Reg,
+ const uint8_t *pui8Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t SHT21ReadModifyWrite(tSHT21 *psInst, uint_fast8_t ui8Reg,
+ uint_fast8_t ui8Mask,
+ uint_fast8_t ui8Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t SHT21DataRead(tSHT21 *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern void SHT21DataTemperatureGetRaw(tSHT21 *psInst,
+ uint16_t *pui16Temperature);
+extern void SHT21DataTemperatureGetFloat(tSHT21 *psInst, float *pfTemperature);
+extern void SHT21DataHumidityGetRaw(tSHT21 *psInst, uint16_t *pui16Humidity);
+extern void SHT21DataHumidityGetFloat(tSHT21 *psInst, float *pfHumidity);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_SHT21_H__
diff --git a/sensorlib/tmp006.c b/sensorlib/tmp006.c new file mode 100644 index 0000000..e29900a --- /dev/null +++ b/sensorlib/tmp006.c @@ -0,0 +1,606 @@ +//*****************************************************************************
+//
+// tmp006.c - Driver for the TI TMP006 Temperature Sensor
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <math.h>
+#include <stdint.h>
+#include "sensorlib/hw_tmp006.h"
+#include "sensorlib/i2cm_drv.h"
+#include "sensorlib/tmp006.h"
+
+//*****************************************************************************
+//
+//! \addtogroup tmp006_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The states of the TMP006 state machine.
+//
+//*****************************************************************************
+#define TMP006_STATE_IDLE 0
+#define TMP006_STATE_INIT 1
+#define TMP006_STATE_READ 2
+#define TMP006_STATE_WRITE 3
+#define TMP006_STATE_RMW 4
+#define TMP006_STATE_READ_AMB 5
+#define TMP006_STATE_READ_OBJ 6
+
+//*****************************************************************************
+//
+// The constants used to calculate object temperature.
+//
+//*****************************************************************************
+#define T_REF 298.15
+#define A1 1.75e-03
+#define A2 -1.678e-05
+#define B0 -2.94e-05
+#define B1 -5.70e-07
+#define B2 4.63e-09
+#define C2 13.4
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transations to/from the TMP006
+// have completed.
+//
+//*****************************************************************************
+static void
+TMP006Callback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tTMP006 *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tTMP006 structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result in a callback to propagate the
+ // error).
+ //
+ if(ui8Status != I2CM_STATUS_SUCCESS)
+ {
+ psInst->ui8State = TMP006_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the TMP006 state machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // All states that trivially transition to IDLE, and all unknown
+ // states.
+ //
+ case TMP006_STATE_INIT:
+ case TMP006_STATE_READ:
+ case TMP006_STATE_WRITE:
+ case TMP006_STATE_RMW:
+ case TMP006_STATE_READ_OBJ:
+ default:
+ {
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = TMP006_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+
+ //
+ // The ambient temperature was just read.
+ //
+ case TMP006_STATE_READ_AMB:
+ {
+ //
+ // Move to the read object temperature state.
+ //
+ psInst->ui8State = TMP006_STATE_READ_OBJ;
+
+ //
+ // Start a read of the object temperature now that this read is
+ // complete.
+ //
+ psInst->uCommand.pui8Buffer[0] = TMP006_O_VOBJECT;
+ I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data + 2, 2,
+ TMP006Callback, psInst);
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == TMP006_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the TMP006 driver.
+//!
+//! \param psInst is a pointer to the TMP006 instance data.
+//! \param psI2CInst is a pointer to the I2C driver instance data.
+//! \param ui8I2CAddr is the I2C address of the TMP006 device.
+//! \param pfnCallback is the function to be called when the initialization has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initializes the TMP006 driver, preparing it for operation,
+//! and initiates a reset of the TMP006 device, clearing any previous
+//! configuration data.
+//!
+//! \return Returns 1 if the TMP006 driver was successfully initialized and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+TMP006Init(tTMP006 *psInst, tI2CMInstance *psI2CInst, uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Initialize the TMP006 instance structure
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8I2CAddr;
+ psInst->ui8State = TMP006_STATE_INIT;
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Set the calibration factor to a reasonable estimate, applications
+ // should perform a calibration in their environment and directly overwrite
+ // this value after calling TMP006Init with the system specific value.
+ //
+ psInst->fCalibrationFactor = 6.40e-14;
+
+ //
+ // Load the data buffer to write the reset sequence
+ //
+ psInst->pui8Data[0] = TMP006_O_CONFIG;
+ psInst->pui8Data[1] = (uint8_t)(TMP006_CONFIG_RESET_ASSERT >> 8);
+ psInst->pui8Data[2] = (uint8_t)(TMP006_CONFIG_RESET_ASSERT & 0x00FF);
+
+ //
+ // Write the reset bit and issue a callback when finished.
+ //
+ if(I2CMWrite(psInst->psI2CInst, ui8I2CAddr, psInst->pui8Data, 3,
+ TMP006Callback, psInst) == 0)
+ {
+ //
+ // I2CMWrite failed so reset TMP006 state and return zero to indicate
+ // failure.
+ //
+ psInst->ui8State = TMP006_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads data from TMP006 registers.
+//!
+//! \param psInst is a pointer to the TMP006 instance data.
+//! \param ui8Reg is the first register to read.
+//! \param pui16Data is a pointer to the location to store the data that is
+//! read.
+//! \param ui16Count the number of register values to read.
+//! \param pfnCallback is the function to be called when data read is complete
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function reads a sequence of data values from consecutive registers in
+//! the TMP006.
+//!
+//! \note The TMP006 does not auto-increment the register pointer, so reads of
+//! more than one value returns garbage for the subsequent values.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+TMP006Read(tTMP006 *psInst, uint_fast8_t ui8Reg, uint16_t *pui16Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the TMP006 driver is not idle (in other words, there
+ // is already an outstanding request to the TMP006).
+ //
+ if(psInst->ui8State != TMP006_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read state.
+ //
+ psInst->ui8State = TMP006_STATE_READ;
+
+ //
+ // Read the requested registers from the TMP006.
+ //
+ if(I2CMRead16BE(&(psInst->uCommand.sReadState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui16Data, ui16Count,
+ TMP006Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = TMP006_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Writes data to TMP006 registers.
+//!
+//! \param psInst is a pointer to the TMP006 instance data.
+//! \param ui8Reg is the first register to write.
+//! \param pui16Data is a pointer to the 16-bit register data to write.
+//! \param ui16Count is the number of 16-bit registers to write.
+//! \param pfnCallback is the function to be called when the data has been
+//! written (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function writes a sequence of data values to consecutive registers in
+//! the TMP006. The first value in the \e pui16Data buffer contains the data
+//! to be written into the \e ui8Reg register, the second value contains the
+//! data to be written into the next register, and so on.
+//!
+//! \note The TMP006 does not auto-increment the register pointer, so writes of
+//! more than one register are rejected by the TMP006.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+TMP006Write(tTMP006 *psInst, uint_fast8_t ui8Reg, const uint16_t *pui16Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the TMP006 driver is not idle (in other words, there
+ // is already an outstanding request to the TMP006).
+ //
+ if(psInst->ui8State != TMP006_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for write state.
+ //
+ psInst->ui8State = TMP006_STATE_WRITE;
+
+ //
+ // Write the requested registers to the TMP006.
+ //
+ if(I2CMWrite16BE(&(psInst->uCommand.sWriteState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui16Data, ui16Count,
+ TMP006Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = TMP006_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of a TMP006 register.
+//!
+//! \param psInst is a pointer to the TMP006 instance data.
+//! \param ui8Reg is the register offset to read modify and write
+//! \param ui16Mask is the bit mask that is ANDed with the current register
+//! value.
+//! \param ui16Value is the bit mask that is ORed with the result of the AND
+//! operation.
+//! \param pfnCallback is the function to be called when the data has been
+//! changed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function changes the value of a register in the TMP006 via a
+//! read-modify-write operation, allowing one of the fields to be changed
+//! without disturbing the other fields. The \e ui8Reg register is read, ANDed
+//! with \e ui16Mask, ORed with \e ui16Value, and then written back to the
+//! TMP006.
+//!
+//! \return Returns 1 if the read-modify-write was successfully started and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+TMP006ReadModifyWrite(tTMP006 *psInst, uint_fast8_t ui8Reg,
+ uint_fast16_t ui16Mask, uint_fast16_t ui16Value,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the TMP006 driver is not idle (in other words, there
+ // is already an outstanding request to the TMP006).
+ //
+ if(psInst->ui8State != TMP006_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read-modify-write state.
+ //
+ psInst->ui8State = TMP006_STATE_RMW;
+
+ //
+ // Submit the read-modify-write request to the TMP006.
+ //
+ if(I2CMReadModifyWrite16BE(&(psInst->uCommand.sReadModifyWriteState),
+ psInst->psI2CInst, psInst->ui8Addr, ui8Reg,
+ ui16Mask, ui16Value, TMP006Callback,
+ psInst) == 0)
+ {
+ //
+ // The I2C read-modify-write failed, so move to the idle state and
+ // return a failure.
+ //
+ psInst->ui8State = TMP006_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads the temperature data from the TMP006.
+//!
+//! \param psInst is a pointer to the TMP006 instance data.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read of the TMP006 data registers. When the read
+//! has completed (as indicated by calling the callback function), the new
+//! readings can be obtained via:
+//!
+//! - TMP006DataTemperatureGetRaw()
+//! - TMP006DataTemperatureGetFloat()
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+TMP006DataRead(tTMP006 *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the TMP006 driver is not idle (in other words, there
+ // is already an outstanding request to the TMP006).
+ //
+ if(psInst->ui8State != TMP006_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for ambient data read state.
+ //
+ psInst->ui8State = TMP006_STATE_READ_AMB;
+
+ //
+ // Read the ambient temperature data from the TMP006.
+ //
+ psInst->uCommand.pui8Buffer[0] = TMP006_O_TAMBIENT;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 2,
+ TMP006Callback, psInst) == 0)
+ {
+ //
+ // The I2C read failed, so move to the idle state and return a failure.
+ //
+ psInst->ui8State = TMP006_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Gets the raw measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the TMP006 instance data.
+//! \param pi16Ambient is a pointer to the value into which the raw ambient
+//! temperature data is stored.
+//! \param pi16Object is a pointer to the value into which the raw object
+//! temperature data is stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+TMP006DataTemperatureGetRaw(tTMP006 *psInst, int16_t *pi16Ambient,
+ int16_t *pi16Object)
+{
+ //
+ // Return the raw temperature value.
+ //
+ *pi16Ambient = ((int16_t)psInst->pui8Data[0] << 8) | psInst->pui8Data[1];
+ *pi16Object = ((int16_t)psInst->pui8Data[2] << 8) | psInst->pui8Data[3];
+}
+
+//*****************************************************************************
+//
+//! Gets the measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the TMP006 instance data.
+//! \param pfAmbient is a pointer to the value into which the ambient
+//! temperature data is stored as floating point degrees Celsius.
+//! \param pfObject is a pointer to the value into which the object temperature
+//! data is stored as floating point degrees Celsius.
+//!
+//! This function returns the temperature data from the most recent data read,
+//! converted into Celsius.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+TMP006DataTemperatureGetFloat(tTMP006 *psInst, float *pfAmbient,
+ float *pfObject)
+{
+ float fTdie2, fS, fVo, fVx, fObj;
+ int16_t i16Ambient;
+ int16_t i16Object;
+
+ //
+ // Get the raw readings.
+ //
+ TMP006DataTemperatureGetRaw(psInst, &i16Ambient, &i16Object);
+
+ //
+ // The bottom two bits are not temperature data, so discard them but keep
+ // the sign information.
+ //
+ *pfAmbient = (float)(i16Ambient / 4);
+
+ //
+ // Divide by 32 to get unit scaling correct.
+ //
+ *pfAmbient = *pfAmbient / 32.0;
+
+ //
+ // fTdie2 is measured ambient temperature in degrees Kelvin.
+ //
+ fTdie2 = *pfAmbient + T_REF;
+
+ //
+ // S is the sensitivity.
+ //
+ fS = psInst->fCalibrationFactor * (1.0f + (A1 * (*pfAmbient)) +
+ (A2 * ((*pfAmbient) * (*pfAmbient))));
+
+ //
+ // Vos is the offset voltage.
+ //
+ fVo = B0 + (B1 * (*pfAmbient)) + (B2 * ((*pfAmbient) * (*pfAmbient)));
+
+ //
+ // Vx is the difference between raw object voltage and Vos
+ // 156.25e-9 is nanovolts per least significant bit from the voltage
+ // register.
+ //
+ fVx = (((float) i16Object) * 156.25e-9) - fVo;
+
+ //
+ // fObj is the feedback coefficient.
+ //
+ fObj = fVx + C2 * (fVx * fVx);
+
+ //
+ // Finally calculate the object temperature.
+ //
+ *pfObject = (sqrtf(sqrtf((fTdie2 * fTdie2 * fTdie2 * fTdie2) +
+ (fObj / fS))) - T_REF);
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/tmp006.h b/sensorlib/tmp006.h new file mode 100644 index 0000000..e22e410 --- /dev/null +++ b/sensorlib/tmp006.h @@ -0,0 +1,157 @@ +//*****************************************************************************
+//
+// tmp006.h - Prototypes for the Texas Instruments TMP006 temperature sensor
+// driver.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_TMP006_H__
+#define __SENSORLIB_TMP006_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the TMP006 driver.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The pointer to the I2C master interface instance used to communicate
+ // with the TMP006.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The I2C address of the TMP006.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The state of the state machine used while accessing the TMP006.
+ //
+ uint8_t ui8State;
+
+ //
+ // The data buffer used for sending/receiving data to/from the TMP006.
+ //
+ uint8_t pui8Data[4];
+
+ //
+ // Calibration factor. Left to application to implement calibration
+ // See term S0 in http://www.ti.com/lit/ug/sbou107/sbou107.pdf
+ //
+ float fCalibrationFactor;
+
+ //
+ // The function that is called when the current request has completed
+ // processing.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The pointer provided to the callback function.
+ //
+ void *pvCallbackData;
+
+ //
+ // A union of structures that are used for read, write and
+ // read-modify-write operations. Since only one operation can be active at
+ // a time, it is safe to re-use the memory in this manner.
+ //
+ union
+ {
+ //
+ // A buffer used to store the write portion of a register read.
+ //
+ uint8_t pui8Buffer[2];
+
+ //
+ // The read state used to read register values.
+ //
+ tI2CMRead16BE sReadState;
+
+ //
+ // The write state used to write register values.
+ //
+ tI2CMWrite16BE sWriteState;
+
+ //
+ // The read-modify-write state used to modify register values.
+ //
+ tI2CMReadModifyWrite16 sReadModifyWriteState;
+ }
+ uCommand;
+}
+tTMP006;
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern uint_fast8_t TMP006Init(tTMP006 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t TMP006Read(tTMP006 *psInst, uint_fast8_t ui8Reg,
+ uint16_t *pui16Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t TMP006Write(tTMP006 *psInst, uint_fast8_t ui8Reg,
+ const uint16_t *pui16Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t TMP006ReadModifyWrite(tTMP006 *psInst, uint_fast8_t ui8Reg,
+ uint_fast16_t ui16Mask,
+ uint_fast16_t ui16Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t TMP006DataRead(tTMP006 *psInst,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern void TMP006DataTemperatureGetRaw(tTMP006 *psInst, int16_t *pui16Ambient,
+ int16_t *pui16Object);
+extern void TMP006DataTemperatureGetFloat(tTMP006 *psInst, float *pfAmbient,
+ float *pfObject);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_TMP006_H__
+
diff --git a/sensorlib/tmp100.c b/sensorlib/tmp100.c new file mode 100644 index 0000000..d4cc3a8 --- /dev/null +++ b/sensorlib/tmp100.c @@ -0,0 +1,582 @@ +//*****************************************************************************
+//
+// tmp100.c - Driver for the TI TMP100 Temperature Sensor
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <math.h>
+#include <stdint.h>
+#include "sensorlib/hw_tmp100.h"
+#include "sensorlib/i2cm_drv.h"
+#include "sensorlib/tmp100.h"
+
+//*****************************************************************************
+//
+//! \addtogroup tmp100_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The states of the TMP100 state machine.
+//
+//*****************************************************************************
+#define TMP100_STATE_IDLE 0
+#define TMP100_STATE_INIT 1
+#define TMP100_STATE_READ 2
+#define TMP100_STATE_WRITE 3
+#define TMP100_STATE_RMW 4
+
+//*****************************************************************************
+//
+// The callback function that is called when I2C transations to/from the TMP100
+// have completed.
+//
+//*****************************************************************************
+static void
+TMP100Callback(void *pvCallbackData, uint_fast8_t ui8Status)
+{
+ tTMP100 *psInst;
+
+ //
+ // Convert the instance data into a pointer to a tTMP100 structure.
+ //
+ psInst = pvCallbackData;
+
+ //
+ // If the I2C master driver encountered a failure, force the state machine
+ // to the idle state (which will also result in a callback to propagate the
+ // error).
+ //
+ if(ui8Status != I2CM_STATUS_SUCCESS)
+ {
+ psInst->ui8State = TMP100_STATE_IDLE;
+ }
+
+ //
+ // Determine the current state of the TMP100 state machine.
+ //
+ switch(psInst->ui8State)
+ {
+ //
+ // All states that trivially transition to IDLE, and all unknown
+ // states.
+ //
+ case TMP100_STATE_INIT:
+ case TMP100_STATE_READ:
+ case TMP100_STATE_WRITE:
+ case TMP100_STATE_RMW:
+ default:
+ {
+ //
+ // The state machine is now idle.
+ //
+ psInst->ui8State = TMP100_STATE_IDLE;
+
+ //
+ // Done.
+ //
+ break;
+ }
+ }
+
+ //
+ // See if the state machine is now idle and there is a callback function.
+ //
+ if((psInst->ui8State == TMP100_STATE_IDLE) && psInst->pfnCallback)
+ {
+ //
+ // Call the application-supplied callback function.
+ //
+ psInst->pfnCallback(psInst->pvCallbackData, ui8Status);
+ }
+}
+
+//*****************************************************************************
+//
+//! Initializes the TMP100 driver.
+//!
+//! \param psInst is a pointer to the TMP100 instance data.
+//! \param psI2CInst is a pointer to the I2C driver instance data.
+//! \param ui8I2CAddr is the I2C address of the TMP100 device.
+//! \param pfnCallback is the function to be called when the initialization has
+//! completed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initializes the TMP100 driver, preparing it for operation,
+//! and initiates a reset of the TMP100 device, clearing any previous
+//! configuration data.
+//!
+//! \return Returns 1 if the TMP100 driver was successfully initialized and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+TMP100Init(tTMP100 *psInst, tI2CMInstance *psI2CInst, uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Initialize the TMP100 instance structure
+ //
+ psInst->psI2CInst = psI2CInst;
+ psInst->ui8Addr = ui8I2CAddr;
+ psInst->ui8State = TMP100_STATE_INIT;
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Write the configuration register to its default value.
+ //
+ psInst->pui8Data[0] = TMP100_O_CONFIG;
+ psInst->pui8Data[1] = 0x00;
+
+ //
+ // Write the reset bit and issue a callback when finished.
+ //
+ if(I2CMWrite(psInst->psI2CInst, ui8I2CAddr, psInst->pui8Data, 2,
+ TMP100Callback, psInst) == 0)
+ {
+ //
+ // I2CMWrite failed so reset TMP100 state and return zero to indicate
+ // failure.
+ //
+ psInst->ui8State = TMP100_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads data from TMP100 registers.
+//!
+//! \param psInst is a pointer to the TMP100 instance data.
+//! \param ui8Reg is the first register to read.
+//! \param pui16Data is a pointer to the location to store the data that is
+//! read.
+//! \param ui16Count the number of register values to read.
+//! \param pfnCallback is the function to be called when data read is complete
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function reads a sequence of data values from consecutive registers in
+//! the TMP100.
+//!
+//! \note The TMP100 does not auto-increment the register pointer, so reads of
+//! more than one value returns garbage for the subsequent values.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+TMP100Read(tTMP100 *psInst, uint_fast8_t ui8Reg, uint16_t *pui16Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the TMP100 driver is not idle (in other words, there
+ // is already an outstanding request to the TMP100).
+ //
+ if(psInst->ui8State != TMP100_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read state.
+ //
+ psInst->ui8State = TMP100_STATE_READ;
+
+ //
+ // Read the requested registers from the TMP100.
+ //
+ if(ui8Reg == TMP100_O_CONFIG)
+ {
+ //
+ // The configuration register is only one byte, so only a single byte
+ // read is necessary and no endian swapping is required.
+ //
+ psInst->uCommand.pui8Buffer[0] = ui8Reg;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, (uint8_t *)pui16Data, 1,
+ TMP100Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = TMP100_STATE_IDLE;
+ return(0);
+ }
+ }
+ else
+ {
+ //
+ // This is one of the temperature registers, which are 16-bit
+ // big-endian registers.
+ //
+ if(I2CMRead16BE(&(psInst->uCommand.sReadState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui16Data, ui16Count,
+ TMP100Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = TMP100_STATE_IDLE;
+ return(0);
+ }
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Writes data to TMP100 registers.
+//!
+//! \param psInst is a pointer to the TMP100 instance data.
+//! \param ui8Reg is the first register to write.
+//! \param pui16Data is a pointer to the 16-bit register data to write.
+//! \param ui16Count is the number of 16-bit registers to write.
+//! \param pfnCallback is the function to be called when the data has been
+//! written (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function writes a sequence of data values to consecutive registers in
+//! the TMP100. The first value in the \e pui16Data buffer contains the data
+//! to be written into the \e ui8Reg register, the second value contains the
+//! data to be written into the next register, and so on.
+//!
+//! \note The TMP100 does not auto-increment the register pointer, so writes of
+//! more than one register are rejected by the TMP100.
+//!
+//! \return Returns 1 if the write was successfully started and 0 if it was
+//! not.
+//
+//*****************************************************************************
+uint_fast8_t
+TMP100Write(tTMP100 *psInst, uint_fast8_t ui8Reg, const uint16_t *pui16Data,
+ uint_fast16_t ui16Count, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the TMP100 driver is not idle (in other words, there
+ // is already an outstanding request to the TMP100).
+ //
+ if(psInst->ui8State != TMP100_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for write state.
+ //
+ psInst->ui8State = TMP100_STATE_WRITE;
+
+ //
+ // Write the requested registers to the TMP100.
+ //
+ if(ui8Reg == TMP100_O_CONFIG)
+ {
+ //
+ // The configuration register is only one byte, so only a single byte
+ // write is necessary and no endian swapping is required.
+ //
+ psInst->uCommand.pui8Buffer[0] = ui8Reg;
+ psInst->uCommand.pui8Buffer[1] = *pui16Data & 0xff;
+ if(I2CMWrite(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 2, TMP100Callback,
+ psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = TMP100_STATE_IDLE;
+ return(0);
+ }
+ }
+ else
+ {
+ //
+ // This is one of the temperature registers, which are 16-bit
+ // big-endian registers.
+ //
+ if(I2CMWrite16BE(&(psInst->uCommand.sWriteState), psInst->psI2CInst,
+ psInst->ui8Addr, ui8Reg, pui16Data, ui16Count,
+ TMP100Callback, psInst) == 0)
+ {
+ //
+ // The I2C write failed, so move to the idle state and return a
+ // failure.
+ //
+ psInst->ui8State = TMP100_STATE_IDLE;
+ return(0);
+ }
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Performs a read-modify-write of a TMP100 register.
+//!
+//! \param psInst is a pointer to the TMP100 instance data.
+//! \param ui8Reg is the register offset to read modify and write
+//! \param ui16Mask is the bit mask that is ANDed with the current register
+//! value.
+//! \param ui16Value is the bit mask that is ORed with the result of the AND
+//! operation.
+//! \param pfnCallback is the function to be called when the data has been
+//! changed (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function changes the value of a register in the TMP100 via a
+//! read-modify-write operation, allowing one of the fields to be changed
+//! without disturbing the other fields. The \e ui8Reg register is read, ANDed
+//! with \e ui16Mask, ORed with \e ui16Value, and then written back to the
+//! TMP100.
+//!
+//! \return Returns 1 if the read-modify-write was successfully started and 0
+//! if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+TMP100ReadModifyWrite(tTMP100 *psInst, uint_fast8_t ui8Reg,
+ uint_fast16_t ui16Mask, uint_fast16_t ui16Value,
+ tSensorCallback *pfnCallback, void *pvCallbackData)
+{
+ //
+ // Return a failure if the TMP100 driver is not idle (in other words, there
+ // is already an outstanding request to the TMP100).
+ //
+ if(psInst->ui8State != TMP100_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for read-modify-write state.
+ //
+ psInst->ui8State = TMP100_STATE_RMW;
+
+ //
+ // Submit the read-modify-write request to the TMP100.
+ //
+ if(ui8Reg == TMP100_O_CONFIG)
+ {
+ //
+ // The configuration register is only one byte, so only a single byte
+ // read-modify-write is necessary and no endian swapping is required.
+ //
+ if(I2CMReadModifyWrite8(&(psInst->uCommand.sReadModifyWriteState8),
+ psInst->psI2CInst, psInst->ui8Addr, ui8Reg,
+ ui16Mask & 0xff, ui16Value & 0xff,
+ TMP100Callback, psInst) == 0)
+ {
+ //
+ // The I2C read-modify-write failed, so move to the idle state and
+ // return a failure.
+ //
+ psInst->ui8State = TMP100_STATE_IDLE;
+ return(0);
+ }
+ }
+ else
+ {
+ //
+ // This is one of the temperature registers, which are 16-bit
+ // big-endian registers.
+ //
+ if(I2CMReadModifyWrite16BE(&(psInst->uCommand.sReadModifyWriteState16),
+ psInst->psI2CInst, psInst->ui8Addr, ui8Reg,
+ ui16Mask, ui16Value, TMP100Callback,
+ psInst) == 0)
+ {
+ //
+ // The I2C read-modify-write failed, so move to the idle state and
+ // return a failure.
+ //
+ psInst->ui8State = TMP100_STATE_IDLE;
+ return(0);
+ }
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Reads the temperature data from the TMP100.
+//!
+//! \param psInst is a pointer to the TMP100 instance data.
+//! \param pfnCallback is the function to be called when the data has been read
+//! (can be \b NULL if a callback is not required).
+//! \param pvCallbackData is a pointer that is passed to the callback function.
+//!
+//! This function initiates a read of the TMP100 data registers. When the read
+//! has completed (as indicated by calling the callback function), the new
+//! readings can be obtained via:
+//!
+//! - TMP100DataTemperatureGetRaw()
+//! - TMP100DataTemperatureGetFloat()
+//!
+//! \return Returns 1 if the read was successfully started and 0 if it was not.
+//
+//*****************************************************************************
+uint_fast8_t
+TMP100DataRead(tTMP100 *psInst, tSensorCallback *pfnCallback,
+ void *pvCallbackData)
+{
+ //
+ // Return a failure if the TMP100 driver is not idle (in other words, there
+ // is already an outstanding request to the TMP100).
+ //
+ if(psInst->ui8State != TMP100_STATE_IDLE)
+ {
+ return(0);
+ }
+
+ //
+ // Save the callback information.
+ //
+ psInst->pfnCallback = pfnCallback;
+ psInst->pvCallbackData = pvCallbackData;
+
+ //
+ // Move the state machine to the wait for data read state.
+ //
+ psInst->ui8State = TMP100_STATE_READ;
+
+ //
+ // Read the temperature data from the TMP100.
+ //
+ psInst->uCommand.pui8Buffer[0] = TMP100_O_TEMP;
+ if(I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
+ psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 2,
+ TMP100Callback, psInst) == 0)
+ {
+ //
+ // The I2C read failed, so move to the idle state and return a failure.
+ //
+ psInst->ui8State = TMP100_STATE_IDLE;
+ return(0);
+ }
+
+ //
+ // Success.
+ //
+ return(1);
+}
+
+//*****************************************************************************
+//
+//! Gets the raw measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the TMP100 instance data.
+//! \param pi16Temperature is a pointer to the value into which the raw
+//! temperature data is stored.
+//!
+//! This function returns the raw measurement data from the most recent data
+//! read. The data is not manipulated in any way by the driver.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+TMP100DataTemperatureGetRaw(tTMP100 *psInst, int16_t *pi16Temperature)
+{
+ //
+ // Return the raw temperature value.
+ //
+ *pi16Temperature =
+ ((int16_t)psInst->pui8Data[0] << 8) | psInst->pui8Data[1];
+}
+
+//*****************************************************************************
+//
+//! Gets the measurement data from the most recent data read.
+//!
+//! \param psInst is a pointer to the TMP100 instance data.
+//! \param pfTemperature is a pointer to the value into which the temperature
+//! data is stored as floating point degrees Celsius.
+//!
+//! This function returns the temperature data from the most recent data read,
+//! converted into Celsius.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+TMP100DataTemperatureGetFloat(tTMP100 *psInst, float *pfTemperature)
+{
+ //
+ // Convert the temperature reading into Celcius.
+ //
+ *pfTemperature = ((float)(((int16_t)psInst->pui8Data[0] << 8) |
+ psInst->pui8Data[1]) / 256.0);
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/tmp100.h b/sensorlib/tmp100.h new file mode 100644 index 0000000..bbb923c --- /dev/null +++ b/sensorlib/tmp100.h @@ -0,0 +1,156 @@ +//*****************************************************************************
+//
+// tmp100.h - Prototypes for the Texas Instruments TMP100 temperature sensor
+// driver.
+//
+// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_TMP100_H__
+#define __SENSORLIB_TMP100_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// The structure that defines the internal state of the TMP100 driver.
+//
+//*****************************************************************************
+typedef struct
+{
+ //
+ // The pointer to the I2C master interface instance used to communicate
+ // with the TMP100.
+ //
+ tI2CMInstance *psI2CInst;
+
+ //
+ // The I2C address of the TMP100.
+ //
+ uint8_t ui8Addr;
+
+ //
+ // The state of the state machine used while accessing the TMP100.
+ //
+ uint8_t ui8State;
+
+ //
+ // The data buffer used for sending/receiving data to/from the TMP100.
+ //
+ uint8_t pui8Data[4];
+
+ //
+ // The function that is called when the current request has completed
+ // processing.
+ //
+ tSensorCallback *pfnCallback;
+
+ //
+ // The pointer provided to the callback function.
+ //
+ void *pvCallbackData;
+
+ //
+ // A union of structures that are used for read, write and
+ // read-modify-write operations. Since only one operation can be active at
+ // a time, it is safe to re-use the memory in this manner.
+ //
+ union
+ {
+ //
+ // A buffer used to store the write portion of a register read.
+ //
+ uint8_t pui8Buffer[2];
+
+ //
+ // The read state used to read register values.
+ //
+ tI2CMRead16BE sReadState;
+
+ //
+ // The write state used to write register values.
+ //
+ tI2CMWrite16BE sWriteState;
+
+ //
+ // The read-modify-write state used to modify 8-bit register values.
+ //
+ tI2CMReadModifyWrite8 sReadModifyWriteState8;
+
+ //
+ // The read-modify-write state used to modify 16-bit register values.
+ //
+ tI2CMReadModifyWrite16 sReadModifyWriteState16;
+ }
+ uCommand;
+}
+tTMP100;
+
+//*****************************************************************************
+//
+// Function prototypes.
+//
+//*****************************************************************************
+extern uint_fast8_t TMP100Init(tTMP100 *psInst, tI2CMInstance *psI2CInst,
+ uint_fast8_t ui8I2CAddr,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t TMP100Read(tTMP100 *psInst, uint_fast8_t ui8Reg,
+ uint16_t *pui16Data, uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t TMP100Write(tTMP100 *psInst, uint_fast8_t ui8Reg,
+ const uint16_t *pui16Data,
+ uint_fast16_t ui16Count,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t TMP100ReadModifyWrite(tTMP100 *psInst, uint_fast8_t ui8Reg,
+ uint_fast16_t ui16Mask,
+ uint_fast16_t ui16Value,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern uint_fast8_t TMP100DataRead(tTMP100 *psInst,
+ tSensorCallback *pfnCallback,
+ void *pvCallbackData);
+extern void TMP100DataTemperatureGetRaw(tTMP100 *psInst,
+ int16_t *pui16Temperature);
+extern void TMP100DataTemperatureGetFloat(tTMP100 *psInst,
+ float *pfTemperature);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_TMP100_H__
+
diff --git a/sensorlib/vector.c b/sensorlib/vector.c new file mode 100644 index 0000000..208b671 --- /dev/null +++ b/sensorlib/vector.c @@ -0,0 +1,139 @@ +//*****************************************************************************
+//
+// vector.c - Functions for performing vector operations.
+//
+// Copyright (c) 2012-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include "sensorlib/vector.h"
+
+//*****************************************************************************
+//
+//! \addtogroup vector_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+//! Computes the dot product of two vectors.
+//!
+//! \param pfVectorIn1 is the first vector.
+//! \param pfVectorIn2 is the second vector.
+//!
+//! This function computes the dot product of two 3-dimensional vector.
+//!
+//! \return Returns the dot product of the two vectors.
+//
+//*****************************************************************************
+float
+VectorDotProduct(float pfVectorIn1[3], float pfVectorIn2[3])
+{
+ //
+ // Compute and return the vector dot product.
+ //
+ return((pfVectorIn1[0] * pfVectorIn2[0]) +
+ (pfVectorIn1[1] * pfVectorIn2[1]) +
+ (pfVectorIn1[2] * pfVectorIn2[2]));
+}
+
+//*****************************************************************************
+//
+//! Computes the cross product of two vectors.
+//!
+//! \param pfVectorOut is the output vector.
+//! \param pfVectorIn1 is the first vector.
+//! \param pfVectorIn2 is the second vector.
+//!
+//! This function computes the cross product of two 3-dimensional vectors.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+VectorCrossProduct(float pfVectorOut[3], float pfVectorIn1[3],
+ float pfVectorIn2[3])
+{
+ //
+ // Compute the cross product of the input vectors.
+ //
+ pfVectorOut[0] = ((pfVectorIn1[1] * pfVectorIn2[2]) -
+ (pfVectorIn1[2] * pfVectorIn2[1]));
+ pfVectorOut[1] = ((pfVectorIn1[2] * pfVectorIn2[0]) -
+ (pfVectorIn1[0] * pfVectorIn2[2]));
+ pfVectorOut[2] = ((pfVectorIn1[0] * pfVectorIn2[1]) -
+ (pfVectorIn1[1] * pfVectorIn2[0]));
+}
+
+//*****************************************************************************
+//
+//! Scales a vector.
+//!
+//! \param pfVectorOut is the output vector.
+//! \param pfVectorIn is the input vector.
+//! \param fScale is the scale factor.
+//!
+//! This function scales a 3-dimensional vector by multiplying each of its
+//! components by the scale factor.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+VectorScale(float pfVectorOut[3], float pfVectorIn[3], float fScale)
+{
+ //
+ // Scale each component of the vector by the scale factor.
+ //
+ pfVectorOut[0] = pfVectorIn[0] * fScale;
+ pfVectorOut[1] = pfVectorIn[1] * fScale;
+ pfVectorOut[2] = pfVectorIn[2] * fScale;
+}
+
+//*****************************************************************************
+//
+//! Adds two vectors.
+//!
+//! \param pfVectorOut is the output vector.
+//! \param pfVectorIn1 is the first vector.
+//! \param pfVectorIn2 is the second vector.
+//!
+//! This function adds two 3-dimensional vectors.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+VectorAdd(float pfVectorOut[3], float pfVectorIn1[3], float pfVectorIn2[3])
+{
+ //
+ // Add the components of the two vectors.
+ //
+ pfVectorOut[0] = pfVectorIn1[0] + pfVectorIn2[0];
+ pfVectorOut[1] = pfVectorIn1[1] + pfVectorIn2[1];
+ pfVectorOut[2] = pfVectorIn1[2] + pfVectorIn2[2];
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
diff --git a/sensorlib/vector.h b/sensorlib/vector.h new file mode 100644 index 0000000..d18b1e2 --- /dev/null +++ b/sensorlib/vector.h @@ -0,0 +1,61 @@ +//*****************************************************************************
+//
+// vector.h - Prototypes for the vector functions.
+//
+// Copyright (c) 2012-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#ifndef __SENSORLIB_VECTOR_H__
+#define __SENSORLIB_VECTOR_H__
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//*****************************************************************************
+//
+// Prototypes.
+//
+//*****************************************************************************
+extern float VectorDotProduct(float pfVectorIn1[3], float pfVectorIn2[3]);
+extern void VectorCrossProduct(float pfVectorOut[3], float pfVectorIn1[3],
+ float pfVectorIn2[3]);
+extern void VectorScale(float pfVectorOut[3], float pfVectorIn[3],
+ float fScale);
+extern void VectorAdd(float pfVectorOut[3], float pfVectorIn1[3],
+ float pfVectorIn2[3]);
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __SENSORLIB_VECTOR_H__
|
