Firmware updates - sensors, calibration, View support, etc (#9)

- Modify TLV493d library to expose frame counter in order to check for lockup, and implement auto-reset in tlv_sensor in case of lockup
 - Implement MT6701 SimpleFOC sensor
 - Make display optional
 - Add optional LED, strain, ALS support
 - Connect ALS to LED and display brightness
 - Hardcoded strain gauge thresholds and haptic feedback
This commit is contained in:
Scott Bezek
2022-03-10 19:05:49 -08:00
committed by GitHub
parent 9e2725f850
commit b47fcf7da4
26 changed files with 2101 additions and 110 deletions

View File

@@ -0,0 +1,369 @@
/**
* Tlv493d.cpp - Library for Arduino to control the TLV493D-A1B6 3D magnetic sensor.
*
* The 3D magnetic sensor TLV493D-A1B6 offers accurate three dimensional sensing with extremely low power consumption
* in a small 6-pin package. With an opportunity to detect the magnetic field in x, y, and z-direction the sensor is
* ideally suited for the measurement of 3D movements, linear movements and rotation movements.
*
* Have a look at the application note/reference manual for more information.
*
* Copyright (c) 2018 Infineon Technologies AG
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
*
* Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Tlv493d.h"
#include "./util/RegMask.h"
#include "./util/BusInterface2.h"
#include <math.h>
Tlv493d::Tlv493d(void)
{
mXdata = 0;
mYdata = 0;
mZdata = 0;
mTempdata = 0;
mExpectedFrameCount = 0x00;
}
Tlv493d::~Tlv493d(void)
{
end();
}
void Tlv493d::begin(void)
{
begin(Wire, TLV493D_ADDRESS1, true);
}
void Tlv493d::begin(TwoWire &bus)
{
begin(bus, TLV493D_ADDRESS1, true);
}
void Tlv493d::begin(TwoWire &bus, Tlv493d_Address_t slaveAddress, bool reset)
{
/**
* Workaround for kit2go vdd enable
*/
#ifdef TLV493D_A1B6_KIT2GO
pinMode(LED2, OUTPUT);
digitalWrite(LED2, HIGH);
delay(50);
#endif
initInterface(&mInterface, &bus, slaveAddress);
delay(TLV493D_STARTUPDELAY);
mInterface.bus->begin();
if(reset == true)
{
resetSensor(mInterface.adress);
}
// get all register data from sensor
tlv493d::readOut(&mInterface);
// copy factory settings to write registers
setRegBits(tlv493d::W_RES1, getRegBits(tlv493d::R_RES1));
setRegBits(tlv493d::W_RES1, getRegBits(tlv493d::R_RES1));
setRegBits(tlv493d::W_RES1, getRegBits(tlv493d::R_RES1));
// enable parity detection
setRegBits(tlv493d::W_PARITY_EN, 1);
// config sensor to lowpower mode
// also contains parity calculation and writeout to sensor
setAccessMode(TLV493D_DEFAULTMODE);
}
void Tlv493d::end(void)
{
disableInterrupt();
setAccessMode(POWERDOWNMODE);
}
bool Tlv493d::setAccessMode(AccessMode_e mode)
{
bool ret = BUS_ERROR;
const tlv493d::AccessMode_t *modeConfig = &(tlv493d::accModes[mode]);
setRegBits(tlv493d::W_FAST, modeConfig->fast);
setRegBits(tlv493d::W_LOWPOWER, modeConfig->lp);
setRegBits(tlv493d::W_LP_PERIOD, modeConfig->lpPeriod);
calcParity();
ret = tlv493d::writeOut(&mInterface);
if ( ret != BUS_ERROR )
{
mMode = mode;
}
return ret;
}
void Tlv493d::enableInterrupt(void)
{
setRegBits(tlv493d::W_INT, 1);
calcParity();
tlv493d::writeOut(&mInterface);
}
void Tlv493d::disableInterrupt(void)
{
setRegBits(tlv493d::W_INT, 0);
calcParity();
tlv493d::writeOut(&mInterface);
}
void Tlv493d::enableTemp(void)
{
setRegBits(tlv493d::W_TEMP_NEN, 0);
calcParity();
tlv493d::writeOut(&mInterface);
}
void Tlv493d::disableTemp(void)
{
setRegBits(tlv493d::W_TEMP_NEN, 1);
calcParity();
tlv493d::writeOut(&mInterface);
}
uint16_t Tlv493d::getMeasurementDelay(void)
{
return tlv493d::accModes[mMode].measurementTime;
}
Tlv493d_Error_t Tlv493d::updateData(void)
{
Tlv493d_Error_t ret = TLV493D_NO_ERROR;
// in POWERDOWNMODE, sensor has to be switched on for one measurement
uint8_t powerdown = 0;
if(mMode == POWERDOWNMODE)
{
if (setAccessMode(MASTERCONTROLLEDMODE) != BUS_OK)
{
ret = TLV493D_BUS_ERROR;
}
delay(getMeasurementDelay());
powerdown = 1;
}
if(ret == TLV493D_NO_ERROR)
{
#ifdef TLV493D_ACCELERATE_READOUT
// just read the most important results in FASTMODE, if this behaviour is desired
if(mMode == FASTMODE)
{
if (readOut(&mInterface, TLV493D_FAST_READOUT) != BUS_OK)
{
ret = TLV493D_BUS_ERROR;
}
}
else
{
if (readOut(&mInterface, TLV493D_MEASUREMENT_READOUT) != BUS_OK)
{
ret = TLV493D_BUS_ERROR;
}
}
#else
if (readOut(&mInterface, TLV493D_MEASUREMENT_READOUT) != BUS_OK)
{
ret = TLV493D_BUS_ERROR;
}
#endif
if (ret == TLV493D_NO_ERROR)
{
// construct results from registers
mXdata = concatResults(getRegBits(tlv493d::R_BX1), getRegBits(tlv493d::R_BX2), true);
mYdata = concatResults(getRegBits(tlv493d::R_BY1), getRegBits(tlv493d::R_BY2), true);
mZdata = concatResults(getRegBits(tlv493d::R_BZ1), getRegBits(tlv493d::R_BZ2), true);
mTempdata = concatResults(getRegBits(tlv493d::R_TEMP1), getRegBits(tlv493d::R_TEMP2), false);
// switch sensor back to POWERDOWNMODE, if it was in POWERDOWNMODE before
if(powerdown)
{
if (setAccessMode(POWERDOWNMODE) != BUS_OK)
{
ret = TLV493D_BUS_ERROR;
}
}
if (ret == TLV493D_NO_ERROR)
{
// if the return value is 0, all results are from the same frame
// otherwise some results may be outdated
if(getRegBits(tlv493d::R_CHANNEL) != 0)
{
ret = TLV493D_FRAME_ERROR;
}
// Todo: removed due to a lot of frame errors
// // if received frame count does not match expected one (frame count from 0 to 3)
// else if( getRegBits(tlv493d::R_FRAMECOUNTER) != (mExpectedFrameCount % 4) )
// {
// ret = TLV493D_FRAME_ERROR;
// }
}
}
}
mExpectedFrameCount = getRegBits(tlv493d::R_FRAMECOUNTER) + 1;
return ret;
}
// SBEZEK
uint8_t Tlv493d::getExpectedFrameCount(void) {
return mExpectedFrameCount;
}
float Tlv493d::getX(void)
{
return static_cast<float>(mXdata) * TLV493D_B_MULT;
}
float Tlv493d::getY(void)
{
return static_cast<float>(mYdata) * TLV493D_B_MULT;
}
float Tlv493d::getZ(void)
{
return static_cast<float>(mZdata) * TLV493D_B_MULT;
}
float Tlv493d::getTemp(void)
{
return static_cast<float>(mTempdata-TLV493D_TEMP_OFFSET) * TLV493D_TEMP_MULT;
}
float Tlv493d::getAmount(void)
{
// sqrt(x^2 + y^2 + z^2)
return TLV493D_B_MULT * sqrt(pow(static_cast<float>(mXdata), 2) + pow(static_cast<float>(mYdata), 2) + pow(static_cast<float>(mZdata), 2));
}
float Tlv493d::getAzimuth(void)
{
// arctan(y/x)
return atan2(static_cast<float>(mYdata), static_cast<float>(mXdata));
}
float Tlv493d::getPolar(void)
{
// arctan(z/(sqrt(x^2+y^2)))
return atan2(static_cast<float>(mZdata), sqrt(pow(static_cast<float>(mXdata), 2) + pow(static_cast<float>(mYdata), 2)));
}
/* internal function called by begin()
* The sensor has a special reset sequence which allows to change its i2c address by setting SDA to high or low during a reset.
* As some i2c peripherals may not cope with this, the simplest way is to use for this very few bytes bitbanging on the SCL/SDA lines.
* Furthermore, as the uC may be stopped during a i2c transmission, a special recovery sequence allows to bring the bus back to
* an operating state.
*/
void Tlv493d::resetSensor(uint8_t adr) // Recovery & Reset - this can be handled by any uC as it uses bitbanging
{
mInterface.bus->beginTransmission(0x00);
if (adr == TLV493D_ADDRESS1) {
// if the sensor shall be initialized with i2c address 0x1F
mInterface.bus->write(0xFF);
} else {
// if the sensor shall be initialized with address 0x5E
mInterface.bus->write((uint8_t)0x00);
}
mInterface.bus->endTransmission(true);
}
void Tlv493d::setRegBits(uint8_t regMaskIndex, uint8_t data)
{
if(regMaskIndex < TLV493D_NUM_OF_REGMASKS)
{
tlv493d::setToRegs(&(tlv493d::regMasks[regMaskIndex]), mInterface.regWriteData, data);
}
}
uint8_t Tlv493d::getRegBits(uint8_t regMaskIndex)
{
if(regMaskIndex < TLV493D_NUM_OF_REGMASKS)
{
const tlv493d::RegMask_t *mask = &(tlv493d::regMasks[regMaskIndex]);
if(mask->rw == REGMASK_READ)
{
return tlv493d::getFromRegs(mask, mInterface.regReadData);
}
else
{
return tlv493d::getFromRegs(mask, mInterface.regWriteData);
}
}
return 0;
}
void Tlv493d::calcParity(void)
{
uint8_t i;
uint8_t y = 0x00;
// set parity bit to 1
// algorithm will calculate an even parity and replace this bit,
// so parity becomes odd
setRegBits(tlv493d::W_PARITY, 1);
// combine array to one byte first
for(i = 0; i < TLV493D_BUSIF_WRITESIZE; i++)
{
y ^= mInterface.regWriteData[i];
}
// combine all bits of this byte
y = y ^ (y >> 1);
y = y ^ (y >> 2);
y = y ^ (y >> 4);
// parity is in the LSB of y
setRegBits(tlv493d::W_PARITY, y&0x01);
}
int16_t Tlv493d::concatResults(uint8_t upperByte, uint8_t lowerByte, bool upperFull)
{
int16_t value=0x0000; //16-bit signed integer for 12-bit values of sensor
if(upperFull)
{
value=upperByte<<8;
value|=(lowerByte&0x0F)<<4;
}
else
{
value=(upperByte&0x0F)<<12;
value|=lowerByte<<4;
}
value>>=4; //shift left so that value is a signed 12 bit integer
return value;
}

View File

@@ -0,0 +1,153 @@
/**
* Tlv493d.h - Library for Arduino to control the TLV493D-A1B6 3D magnetic sensor.
*
* The 3D magnetic sensor TLV493D-A1B6 offers accurate three dimensional sensing with extremely low power consumption
* in a small 6-pin package. With an opportunity to detect the magnetic field in x, y, and z-direction the sensor is
* ideally suited for the measurement of 3D movements, linear movements and rotation movements.
*
* Have a look at the application note/reference manual for more information.
*
* Copyright (c) 2018 Infineon Technologies AG
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
*
* Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TLV493D_H_INCLUDED
#define TLV493D_H_INCLUDED
#include <Arduino.h>
#include <Wire.h>
#include "./util/BusInterface.h"
#include "./util/Tlv493d_conf.h"
typedef enum Tlv493d_Address
{
TLV493D_ADDRESS1 = 0x5E,
TLV493D_ADDRESS2 = 0x1F
}Tlv493d_Address_t;
typedef enum Tlv493d_Error
{
TLV493D_NO_ERROR = 0,
TLV493D_BUS_ERROR = 1,
TLV493D_FRAME_ERROR = 2
}Tlv493d_Error_t;
/*
* TLV493D_ACCELERATE_READOUT lets the controller just read out the first 3 bytes when in fast mode.
* This makes the readout faster (half of usual transfer duration), but there is no way to get
* temperature, current channel or high precision (only 8 instead of 12 bits for x, y, z)
* It is necessary for slow I2C busses to read the last result before the new measurement is completed.
* It only takes effect in FASTMODE, not in other modes.
*
* Feel free to undefine this and increase your I2C bus speed if you need to.
*/
// SBEZEK
// #define TLV493D_ACCELERATE_READOUT
class Tlv493d
{
public:
Tlv493d(void);
~Tlv493d(void);
void begin(void);
void begin(TwoWire &bus);
void begin(TwoWire &bus, Tlv493d_Address_t slaveAddress, bool reset);
void end(void);
// sensor configuration
/* sets the data access mode for TLE493D
* Tle493d is initially in POWERDOWNMODE
* use POWERDOWNMODE for rare and infrequent measurements
* Tle493d will automatically switch to MASTERCONTROLLEDMODE for one measurement if on a readout
* measurements are quite slow in this mode. The power consumption is very low between measurements.
* use MASTERCONTROLLEDMODE for low measurement frequencies where results do not have to be up-to-date
* In this mode a new measurement starts directly after the last result has been read out.
* use LOWPOWERMODE and ULTRALOWPOWERMODE for continuous measurements
* each readout returns the latest measurement results
* use FASTMODE for for continuous measurements on high frequencies
* measurement time might be higher than the time necessary for I2C-readouts in this mode.
* Note: Thus, this mode requires a non-standard 1MHz I2C clock to be used to read the data fast enough.
*/
enum AccessMode_e
{
POWERDOWNMODE = 0,
FASTMODE,
LOWPOWERMODE,
ULTRALOWPOWERMODE,
MASTERCONTROLLEDMODE,
};
bool setAccessMode(AccessMode_e mode);
// interrupt is disabled by default
// it is recommended for FASTMODE, LOWPOWERMODE and ULTRALOWPOWERMODE
// the interrupt is indicated with a short(1.5 us) low pulse on SCL
// you need to capture and react(read the new results) to it by yourself
void enableInterrupt(void);
void disableInterrupt(void);
// temperature measurement is enabled by default
// it can be disabled to reduce power consumption
void enableTemp(void);
void disableTemp(void);
// returns the recommended time between two readouts for the sensor's current configuration
uint16_t getMeasurementDelay(void);
// read measurement results from sensor
Tlv493d_Error_t updateData(void);
// fieldvector in Cartesian coordinates
float getX(void);
float getY(void);
float getZ(void);
// fieldvector in spherical coordinates
float getAmount(void);
float getAzimuth(void);
float getPolar(void);
// temperature
float getTemp(void);
// SBEZEK
uint8_t getExpectedFrameCount(void);
private:
tlv493d::BusInterface_t mInterface;
AccessMode_e mMode;
int16_t mXdata;
int16_t mYdata;
int16_t mZdata;
int16_t mTempdata;
uint8_t mExpectedFrameCount;
void resetSensor(uint8_t adr);
void setRegBits(uint8_t regMaskIndex, uint8_t data);
uint8_t getRegBits(uint8_t regMaskIndex);
void calcParity(void);
int16_t concatResults(uint8_t upperByte, uint8_t lowerByte, bool upperFull);
};
#endif /* TLV493D_H_INCLUDED */

View File

@@ -0,0 +1,97 @@
/**
* BusInterface.cpp - Part of the library for Arduino to control the TLV493D-A1B6 3D magnetic sensor.
*
* The 3D magnetic sensor TLV493D-A1B6 offers accurate three dimensional sensing with extremely low power consumption
* in a small 6-pin package. With an opportunity to detect the magnetic field in x, y, and z-direction the sensor is
* ideally suited for the measurement of 3D movements, linear movements and rotation movements.
*
* Have a look at the application note/reference manual for more information.
*
* Copyright (c) 2018 Infineon Technologies AG
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
*
* Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "BusInterface2.h"
void tlv493d::initInterface(BusInterface_t *interface, TwoWire *bus, uint8_t adress)
{
uint8_t i;
interface->bus = bus;
interface->adress = adress;
for(i = 0; i < TLV493D_BUSIF_READSIZE; i++) {
interface->regReadData[i] = 0x00;;
}
for(i = 0; i < TLV493D_BUSIF_WRITESIZE; i++) {
interface->regWriteData[i] = 0x00;;
}
}
bool tlv493d::readOut(BusInterface_t *interface)
{
return readOut(interface, TLV493D_BUSIF_READSIZE);
}
bool tlv493d::readOut(BusInterface_t *interface, uint8_t count)
{
bool ret = BUS_ERROR;
int i;
if(count > TLV493D_BUSIF_READSIZE)
{
count = TLV493D_BUSIF_READSIZE;
}
uint8_t received_bytes = interface->bus->requestFrom(interface->adress,count);
if (received_bytes == count)
{
for(i = 0; i < count; i++)
{
interface->regReadData[i] = interface->bus->read();
}
ret = BUS_OK;
}
return ret;
}
bool tlv493d::writeOut(BusInterface_t *interface)
{
return writeOut(interface, TLV493D_BUSIF_WRITESIZE);
}
bool tlv493d::writeOut(BusInterface_t *interface, uint8_t count)
{
bool ret = BUS_ERROR;
int i;
if(count > TLV493D_BUSIF_WRITESIZE)
{
count = TLV493D_BUSIF_WRITESIZE;
}
interface->bus->beginTransmission(interface->adress);
for(i = 0; i < count; i++)
{
interface->bus->write(interface->regWriteData[i]);
}
if (interface->bus->endTransmission() == 0)
{
ret = BUS_OK;
}
return ret;
}

View File

@@ -0,0 +1,55 @@
/**
* BusInterface.h - Part of the library for Arduino to control the TLV493D-A1B6 3D magnetic sensor.
*
* The 3D magnetic sensor TLV493D-A1B6 offers accurate three dimensional sensing with extremely low power consumption
* in a small 6-pin package. With an opportunity to detect the magnetic field in x, y, and z-direction the sensor is
* ideally suited for the measurement of 3D movements, linear movements and rotation movements.
*
* Have a look at the application note/reference manual for more information.
*
* Copyright (c) 2018 Infineon Technologies AG
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
*
* Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TLV493D_BUSIF_H_INCLUDED
#define TLV493D_BUSIF_H_INCLUDED
#include <Arduino.h>
#include <Wire.h>
#define TLV493D_BUSIF_READSIZE 10
#define TLV493D_BUSIF_WRITESIZE 4
namespace tlv493d
{
typedef struct
{
TwoWire *bus;
uint8_t adress;
uint8_t regReadData[TLV493D_BUSIF_READSIZE];
uint8_t regWriteData[TLV493D_BUSIF_WRITESIZE];
} BusInterface_t;
}
#endif

View File

@@ -0,0 +1,52 @@
/**
* BusInterface2.h - Part of the library for Arduino to control the TLV493D-A1B6 3D magnetic sensor.
*
* The 3D magnetic sensor TLV493D-A1B6 offers accurate three dimensional sensing with extremely low power consumption
* in a small 6-pin package. With an opportunity to detect the magnetic field in x, y, and z-direction the sensor is
* ideally suited for the measurement of 3D movements, linear movements and rotation movements.
*
* Have a look at the application note/reference manual for more information.
*
* Copyright (c) 2018 Infineon Technologies AG
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
*
* Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TLV493D_BUSIF_2_H_INCLUDED
#define TLV493D_BUSIF_2_H_INCLUDED
#include "BusInterface.h"
#define BUS_ERROR 1
#define BUS_OK 0
namespace tlv493d
{
void initInterface(BusInterface_t *interface, TwoWire *bus, uint8_t adress);
bool readOut(BusInterface_t *interface);
bool readOut(BusInterface_t *interface, uint8_t count);
bool writeOut(BusInterface_t *interface);
bool writeOut(BusInterface_t *interface, uint8_t count);
}
#endif

View File

@@ -0,0 +1,54 @@
/**
* RegMask.cpp - Part of the library for Arduino to control the TLV493D-A1B6 3D magnetic sensor.
*
* The 3D magnetic sensor TLV493D-A1B6 offers accurate three dimensional sensing with extremely low power consumption
* in a small 6-pin package. With an opportunity to detect the magnetic field in x, y, and z-direction the sensor is
* ideally suited for the measurement of 3D movements, linear movements and rotation movements.
*
* Have a look at the application note/reference manual for more information.
*
* Copyright (c) 2018 Infineon Technologies AG
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
*
* Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "RegMask.h"
uint8_t tlv493d::getFromRegs(const RegMask_t *mask, uint8_t *regData)
{
return (regData[mask->byteAdress] & mask->bitMask) >> mask->shift;
}
uint8_t tlv493d::setToRegs(const RegMask_t *mask, uint8_t *regData, uint8_t toWrite)
{
if(mask->rw == REGMASK_WRITE)
{
uint8_t regValue = regData[mask->byteAdress];
regValue &= ~(mask->bitMask);
regValue |= (toWrite << mask->shift) & mask->bitMask;
regData[mask->byteAdress] = regValue;
}
return 0;
}

View File

@@ -0,0 +1,57 @@
/**
* RegMask.h - Part of the library for Arduino to control the TLV493D-A1B6 3D magnetic sensor.
*
* The 3D magnetic sensor TLV493D-A1B6 offers accurate three dimensional sensing with extremely low power consumption
* in a small 6-pin package. With an opportunity to detect the magnetic field in x, y, and z-direction the sensor is
* ideally suited for the measurement of 3D movements, linear movements and rotation movements.
*
* Have a look at the application note/reference manual for more information.
*
* Copyright (c) 2018 Infineon Technologies AG
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
*
* Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TLV493D_REGMASK_H_INCLUDED
#define TLV493D_REGMASK_H_INCLUDED
#include <Arduino.h>
#define REGMASK_READ 0
#define REGMASK_WRITE 1
namespace tlv493d
{
typedef struct
{
uint8_t rw;
uint8_t byteAdress;
uint8_t bitMask;
uint8_t shift;
} RegMask_t;
uint8_t getFromRegs(const RegMask_t *mask, uint8_t *regData);
uint8_t setToRegs(const RegMask_t *mask, uint8_t *regData, uint8_t toWrite);
}
#endif

View File

@@ -0,0 +1,134 @@
/**
* Tlv493d_conf.h - Part of the library for Arduino to control the TLV493D-A1B6 3D magnetic sensor.
*
* The 3D magnetic sensor TLV493D-A1B6 offers accurate three dimensional sensing with extremely low power consumption
* in a small 6-pin package. With an opportunity to detect the magnetic field in x, y, and z-direction the sensor is
* ideally suited for the measurement of 3D movements, linear movements and rotation movements.
*
* Have a look at the application note/reference manual for more information.
*
* Copyright (c) 2018 Infineon Technologies AG
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
*
* Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TLV493D_CONF_H_INCLUDED
#define TLV493D_CONF_H_INCLUDED
#include "RegMask.h"
#include "Tlv493d.h"
#define TLV493D_DEFAULTMODE POWERDOWNMODE
#define TLV493D_STARTUPDELAY 40
#define TLV493D_RESETDELAY 60
#define TLV493D_NUM_OF_REGMASKS 25
#define TLV493D_NUM_OF_ACCMODES 5
#define TLV493D_MEASUREMENT_READOUT 7
#define TLV493D_FAST_READOUT 3
#define TLV493D_B_MULT 0.098
#define TLV493D_TEMP_MULT 1.1
#define TLV493D_TEMP_OFFSET 315
namespace tlv493d
{
typedef struct
{
uint8_t fast;
uint8_t lp;
uint8_t lpPeriod;
uint16_t measurementTime;
} AccessMode_t;
enum Registers_e
{
R_BX1 = 0,
R_BX2,
R_BY1,
R_BY2,
R_BZ1,
R_BZ2,
R_TEMP1,
R_TEMP2,
R_FRAMECOUNTER,
R_CHANNEL,
R_POWERDOWNFLAG,
R_RES1,
R_RES2,
R_RES3,
W_PARITY,
W_ADDR,
W_INT,
W_FAST,
W_LOWPOWER,
W_TEMP_NEN,
W_LP_PERIOD,
W_PARITY_EN,
W_RES1,
W_RES2,
W_RES3
};
const RegMask_t regMasks[] = {
{ REGMASK_READ, 0, 0xFF, 0 }, // R_BX1
{ REGMASK_READ, 4, 0xF0, 4 }, // R_BX2
{ REGMASK_READ, 1, 0xFF, 0 }, // R_BY1
{ REGMASK_READ, 4, 0x0F, 0 }, // R_BY2
{ REGMASK_READ, 2, 0xFF, 0 }, // R_BZ1
{ REGMASK_READ, 5, 0x0F, 0 }, // R_BZ2
{ REGMASK_READ, 3, 0xF0, 4 }, // R_TEMP1
{ REGMASK_READ, 6, 0xFF, 0 }, // R_TEMP2
{ REGMASK_READ, 3, 0x0C, 2 }, // R_FRAMECOUNTER
{ REGMASK_READ, 3, 0x03, 0 }, // R_CHANNEL
{ REGMASK_READ, 5, 0x10, 4 }, // R_POWERDOWNFLAG
{ REGMASK_READ, 7, 0x18, 3 }, // R_RES1
{ REGMASK_READ, 8, 0xFF, 0 }, // R_RES2
{ REGMASK_READ, 9, 0x1F, 0 }, // R_RES3
{ REGMASK_WRITE, 1, 0x80, 7 }, // W_PARITY
{ REGMASK_WRITE, 1, 0x60, 5 }, // W_ADDR
{ REGMASK_WRITE, 1, 0x04, 2 }, // W_INT
{ REGMASK_WRITE, 1, 0x02, 1 }, // W_FAST
{ REGMASK_WRITE, 1, 0x01, 0 }, // W_LOWPOWER
{ REGMASK_WRITE, 3, 0x80, 7 }, // W_TEMP_EN
{ REGMASK_WRITE, 3, 0x40, 6 }, // W_LOWPOWER
{ REGMASK_WRITE, 3, 0x20, 5 }, // W_POWERDOWN
{ REGMASK_WRITE, 1, 0x18, 3 }, // W_RES1
{ REGMASK_WRITE, 2, 0xFF, 0 }, // W_RES2
{ REGMASK_WRITE, 3, 0x1F, 0 } // W_RES3
};
const AccessMode_t accModes[] = {
{ 0, 0, 0, 1000 }, // POWERDOWNMODE
{ 1, 0, 0, 0 }, // FASTMODE
{ 0, 1, 1, 10 }, // LOWPOWERMODE
{ 0, 1, 0, 100 }, // ULTRALOWPOWERMODE
{ 1, 1, 1, 10 } // MASTERCONTROLLEDMODE
};
}
#endif