Zoltan Hudak / TLE5012B

Dependents:   TLE5012B_Hello

Revision:
0:4b76b1dc05cd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TLE5012B.cpp	Sat Sep 19 18:01:49 2020 +0000
@@ -0,0 +1,935 @@
+/*!
+ * \name        TLE5012B.h - Mbed port of Arduino library for the TLE5012B angle sensor.
+ * \author      Infineon Technologies AG (Dr.Olaf Filies)
+ * \copyright   Infineon Technologies AG
+ * \version     2.0.1
+ * \brief       GMR-based angle sensor for angular position sensing in automotive applications
+ * \details     Ported to Mbed by Zoltan Hudak 2020-08
+ *
+ * The TLE5012B is a 360° angle sensor that detects the orientation of a magnetic field.
+ * This is achieved by measuring sine and cosine angle components with monolithic integrated
+ * Giant Magneto Resistance (iGMR) elements. These raw signals (sine and cosine) are digitally
+ * processed internally to calculate the angle orientation of the magnetic field (magnet).
+ * The TLE5012B is a pre-calibrated sensor. The calibration parameters are stored in laser fuses.
+ * At start-up the values of the fuses are written into flip-flops, where these values can be changed
+ * by the application-specific parameters. Further precision of the angle measurement over a wide
+ * temperature range and a long lifetime can be improved by enabling an optional internal autocalibration
+ * algorithm. Data communications are accomplished with a bi-directional Synchronous Serial Communication (SSC)
+ * that is SPI-compatible. The sensor configuration is stored in registers, which are accessible by the
+ * SSC interface. Additionally four other interfaces are available with the TLE5012B: Pulse-Width-Modulation (PWM)
+ * Protocol, Short-PWM-Code (SPC) Protocol, Hall Switch Mode (HSM) and Incremental Interface (IIF). These interfaces
+ * can be used in parallel with SSC or alone. Pre-configured sensor derivates with different interface settings are available.
+ * Online diagnostic functions are provided to ensure reliable operation.
+ *
+ * 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 "TLE5012B.h"
+
+//-----------------------------------------------------------------------------
+
+using namespace TLE5012;
+
+// none_class functions
+
+/*!
+ * Gets the first byte of a 2 byte word
+ * @param twoByteWord insert word of two bytes long
+ * @return returns the first byte
+ */
+uint8_t getFirstByte(uint16_t twoByteWord)
+{
+    return((uint8_t) (twoByteWord >> 8));
+}
+
+/*!
+ * Gets the second byte of the 2 byte word
+ * @param twoByteWord insert word of two bytes long
+ * @return returns the second byte
+ */
+uint8_t getSecondByte(uint16_t twoByteWord)
+{
+    return((uint8_t) twoByteWord);
+}
+
+/*!
+ * Function for calculation the CRC.
+ * @param data byte long data for CRC check
+ * @param length length of data
+ * @return returns 8bit CRC
+ */
+uint8_t crc8(uint8_t* data, uint8_t length)
+{
+    uint32_t    crc;
+    int16_t     i, bit;
+
+    crc = CRC_SEED;
+    for (i = 0; i < length; i++) {
+        crc ^= data[i];
+        for (bit = 0; bit < 8; bit++) {
+            if ((crc & 0x80) != 0) {
+                crc <<= 1;
+                crc ^= CRC_POLYNOMIAL;
+            }
+            else {
+                crc <<= 1;
+            }
+        }
+    }
+
+    return((~crc) & CRC_SEED);
+}
+
+/*!
+ * Function for calculation of the CRC
+ * @param crcData byte long data for CRC check
+ * @param length length of data
+ * @return runs crc8 calculation and returns CRC
+ */
+uint8_t crcCalc(uint8_t* crcData, uint8_t length)
+{
+    return(crc8(crcData, length));
+}
+
+/*!
+ * Calculate the angle speed
+ * @param angRange set angular range value
+ * @param rawAngleSpeed raw speed value from read function
+ * @param firMD
+ * @param predictionVal
+ * @return calculated angular speed
+ */
+double calculateAngleSpeed(double angRange, int16_t rawAngleSpeed, uint16_t firMD, uint16_t predictionVal)
+{
+    double  finalAngleSpeed;
+    double  microsecToSec = 0.000001;
+    double  firMDVal;
+
+
+    if (firMD == 1) {
+        firMDVal = 42.7;
+    }
+    else
+    if (firMD == 0) {
+        firMDVal = 21.3;
+    }
+    else
+    if (firMD == 2) {
+        firMDVal = 85.3;
+    }
+    else
+    if (firMD == 3) {
+        firMDVal = 170.6;
+    }
+    else {
+        firMDVal = 0;
+    }
+
+    finalAngleSpeed = ((angRange / POW_2_15) * ((double)rawAngleSpeed)) / (((double)predictionVal) * firMDVal * microsecToSec);
+    return(finalAngleSpeed);
+}
+
+// end none class functions
+
+//-----------------------------------------------------------------------------
+errorTypes TLE5012B::begin(slaveNum slave)
+{
+    _spiConnection->begin(&_cs);
+    _slave = slave;
+    writeSlaveNumber(_slave);
+    return(readBlockCRC());
+
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void TLE5012B::triggerUpdate()
+{
+    _spiConnection->triggerUpdate();
+    _cs = 0;
+    wait_us(5); //grace period for register snapshot
+    _cs = 1;
+}
+
+//-----------------------------------------------------------------------------
+
+// begin generic data transfer functions
+errorTypes TLE5012B::readFromSensor(uint16_t command, uint16_t& data, updTypes upd, safetyTypes safe)
+{
+    errorTypes  checkError = NO_ERROR;
+
+    _command[0] = READ_SENSOR | command | upd | safe;
+
+    uint16_t    _received[MAX_REGISTER_MEM] = { 0 };
+
+    _spiConnection->sendReceiveSpi(&_cs, _command, 1, _received, 2);
+    data = _received[0];
+    if (safe == SAFE_HIGH) {
+        checkError = checkSafety(_received[1], _command[0], &_received[0], 1);
+        if (checkError != NO_ERROR) {
+            data = 0;
+        }
+    }
+
+    return(checkError);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readMoreRegisters(uint16_t command, uint16_t data[], updTypes upd, safetyTypes safe)
+{
+    errorTypes  checkError = NO_ERROR;
+
+    _command[0] = READ_SENSOR | command | upd | safe;
+
+    uint16_t    _received[MAX_REGISTER_MEM] = { 0 };
+    uint16_t    _recDataLength = (_command[0] & (0x000F));  // Number of registers to read
+
+    _spiConnection->sendReceiveSpi(&_cs, _command, 1, _received, _recDataLength + safe);
+    memcpy(data, _received, (_recDataLength) * sizeof(uint16_t));
+    if (safe == SAFE_HIGH) {
+        checkError = checkSafety(_received[_recDataLength], _command[0], _received, _recDataLength);
+        if (checkError != NO_ERROR) {
+            data = 0;
+        }
+    }
+
+    return(checkError);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::writeToSensor(uint16_t command, uint16_t dataToWrite, bool changeCRC)
+{
+    uint16_t    safety = 0;
+    _command[0] = WRITE_SENSOR | command | SAFE_HIGH;
+    _command[1] = dataToWrite;
+    _spiConnection->sendReceiveSpi(&_cs, _command, 2, &safety, 1);
+
+    errorTypes  checkError = checkSafety(safety, _command[0], &_command[1], 1);
+
+    //if we write to a register, which changes the CRC.
+
+    if (changeCRC) {
+
+        //Serial.println("h45");
+        checkError = regularCrcUpdate();
+    }
+
+    return(checkError);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::writeTempCoeffUpdate(uint16_t dataToWrite)
+{
+    uint16_t    safety = 0;
+    uint16_t    readreg = 0;
+
+    triggerUpdate();
+    _command[0] = WRITE_SENSOR | REG_TCO_Y | SAFE_HIGH;
+    _command[1] = dataToWrite;
+    _spiConnection->sendReceiveSpi(&_cs, _command, 2, &safety, 1);
+
+    errorTypes  checkError = checkSafety(safety, _command[0], &_command[1], 1);
+    //
+
+    checkError = readStatus(readreg);
+    if (readreg & 0x0008) {
+        checkError = regularCrcUpdate();
+    }
+
+    return(checkError);
+}
+
+// end generic data transfer functions
+//-----------------------------------------------------------------------------
+
+// begin CRC functions
+errorTypes TLE5012B::checkSafety(uint16_t safety, uint16_t command, uint16_t* readreg, uint16_t length)
+{
+    volatile errorTypes  errorCheck = NO_ERROR;
+    _safetyWord = safety;
+
+    if (!(_safetyWord & SYSTEM_ERROR_MASK)) {
+        errorCheck = SYSTEM_ERROR;
+
+        //resetSafety();
+    }
+    else
+    if (!(_safetyWord & INTERFACE_ERROR_MASK)) {
+        errorCheck = INTERFACE_ACCESS_ERROR;
+
+        //resetSafety();
+    }
+    else
+    if (!(_safetyWord & INV_ANGLE_ERROR_MASK)) {
+        errorCheck = INVALID_ANGLE_ERROR;
+
+        //resetSafety();
+    }
+    else {
+
+        //resetSafety();
+        uint16_t    lengthOfTemp = length * 2 + 2;
+        uint8_t*    temp = new uint8_t[lengthOfTemp];
+
+        temp[0] = getFirstByte(command);
+        temp[1] = getSecondByte(command);
+
+        for (uint16_t i = 0; i < length; i++) {
+            temp[2 + 2 * i] = getFirstByte(readreg[i]);
+            temp[2 + 2 * i + 1] = getSecondByte(readreg[i]);
+        }
+
+        uint8_t crcReceivedFinal = getSecondByte(safety);
+        uint8_t crc = crcCalc(temp, lengthOfTemp);
+
+        if (crc == crcReceivedFinal) {
+            errorCheck = NO_ERROR;
+        }
+        else {
+            errorCheck = CRC_ERROR;
+            resetSafety();
+        }
+
+        delete[] temp;
+    }
+
+    return(errorCheck);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void TLE5012B::resetSafety()
+{
+    uint16_t    command = READ_SENSOR + SAFE_HIGH;
+    uint16_t    receive[4];
+
+    triggerUpdate();
+    _spiConnection->sendReceiveSpi(&_cs, &command, 1, receive, 3);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::regularCrcUpdate()
+{
+    readBlockCRC();
+
+    uint8_t temp[16];
+
+    for (uint8_t i = 0; i < CRC_NUM_REGISTERS; i++) {
+        temp[2 * i] = getFirstByte(_registers[i]);
+        temp[(2 * i) + 1] = getSecondByte(_registers[i]);
+    }
+
+    uint8_t     crc = crcCalc(temp, 15);
+    uint16_t    firstTempByte = (uint16_t) temp[14];
+    uint16_t    secondTempByte = (uint16_t) crc;
+    uint16_t    valToSend = (firstTempByte << 8) | secondTempByte;
+
+    _registers[7] = valToSend;
+
+    return(writeTempCoeffUpdate(valToSend));
+}
+
+// end CRC functions
+//-----------------------------------------------------------------------------
+
+// begin read functions
+errorTypes TLE5012B::readBlockCRC()
+{
+    _command[0] = READ_BLOCK_CRC;
+
+    uint16_t    _registers[CRC_NUM_REGISTERS + 1] = { 0 };  // Number of CRC Registers + 1 Register for Safety word
+    //memset(_registers, 0, sizeof(_registers));
+
+    _spiConnection->sendReceiveSpi(&_cs, _command, 1, _registers, CRC_NUM_REGISTERS + 1);
+
+    errorTypes  checkError = checkSafety(_registers[8], READ_BLOCK_CRC, _registers, 8);
+    resetSafety();
+    return(checkError);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readStatus(uint16_t& data, updTypes upd, safetyTypes safe)
+{
+    return(readFromSensor(REG_STAT, data, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readActivationStatus(uint16_t& data, updTypes upd, safetyTypes safe)
+{
+    return(readFromSensor(REG_ACSTAT, data, upd, safe));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readSIL(uint16_t& data)
+{
+    return(readFromSensor(REG_SIL, data, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readIntMode1(uint16_t& data)
+{
+    return(readFromSensor(REG_MOD_1, data, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readIntMode2(uint16_t& data)
+{
+    return(readFromSensor(REG_MOD_2, data, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readIntMode3(uint16_t& data)
+{
+    return(readFromSensor(REG_MOD_3, data, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readIntMode4(uint16_t& data)
+{
+    return(readFromSensor(REG_MOD_4, data, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readOffsetX(uint16_t& data)
+{
+    return(readFromSensor(REG_OFFX, data, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readOffsetY(uint16_t& data)
+{
+    return(readFromSensor(REG_OFFY, data, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readSynch(uint16_t& data)
+{
+    return(readFromSensor(REG_SYNCH, data, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readIFAB(uint16_t& data)
+{
+    return(readFromSensor(REG_IFAB, data, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readTempCoeff(uint16_t& data)
+{
+    return(readFromSensor(REG_TCO_Y, data, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readTempDMag(uint16_t& data)
+{
+    return(readFromSensor(REG_D_MAG, data, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readTempIIFCnt(uint16_t& data)
+{
+    return(readFromSensor(REG_IIF_CNT, data, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readTempRaw(uint16_t& data)
+{
+    return(readFromSensor(REG_T_RAW, data, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readTempT25(uint16_t& data)
+{
+    return(readFromSensor(REG_T25O, data, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readRawX(int16_t& data)
+{
+    uint16_t    rawData = 0;
+    errorTypes  status = readFromSensor(REG_ADC_X, rawData);
+
+    if (status != NO_ERROR) {
+        return(status);
+    }
+
+    data = rawData;
+    return(status);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::readRawY(int16_t& data)
+{
+    uint16_t    rawData = 0;
+    errorTypes  status = readFromSensor(REG_ADC_Y, rawData);
+
+    if (status != NO_ERROR) {
+        return(status);
+    }
+
+    data = rawData;
+    return(status);
+}
+
+// end read functions
+//-----------------------------------------------------------------------------
+
+// begin get functions
+errorTypes TLE5012B::getAngleValue(double& angleValue)
+{
+    int16_t rawAnglevalue = 0;
+
+    return(getAngleValue(angleValue, rawAnglevalue, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::getAngleValue(double& angleValue, int16_t& rawAnglevalue, updTypes upd, safetyTypes safe)
+{
+    uint16_t    rawData = 0;
+    errorTypes  status = readFromSensor(REG_AVAL, rawData, upd, safe);
+
+    if (status != NO_ERROR) {
+        return(status);
+    }
+
+    rawData = (rawData & (DELETE_BIT_15));
+
+    //check if the value received is positive or negative
+    if (rawData & CHECK_BIT_14) {
+        rawData = rawData - CHANGE_UINT_TO_INT_15;
+    }
+
+    rawAnglevalue = rawData;
+    angleValue = (ANGLE_360_VAL / POW_2_15) * ((double)rawAnglevalue);
+    return(status);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::getTemperature(double& temperature)
+{
+    int16_t rawTemp = 0;
+
+    return(getTemperature(temperature, rawTemp, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::getTemperature(double& temperature, int16_t& rawTemp, updTypes upd, safetyTypes safe)
+{
+    uint16_t    rawData = 0;
+    errorTypes  status = readFromSensor(REG_FSYNC, rawData, upd, safe);
+
+    if (status != NO_ERROR) {
+        return(status);
+    }
+
+    rawData = (rawData & (DELETE_7BITS));
+
+    //check if the value received is positive or negative
+    if (rawData & CHECK_BIT_9) {
+        rawData = rawData - CHANGE_UNIT_TO_INT_9;
+    }
+
+    rawTemp = rawData;
+    temperature = (rawTemp + TEMP_OFFSET) / (TEMP_DIV);
+    return(status);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::getNumRevolutions(int16_t& numRev, updTypes upd, safetyTypes safe)
+{
+    uint16_t    rawData = 0;
+    errorTypes  status = readFromSensor(REG_AREV, rawData, upd, safe);
+
+    if (status != NO_ERROR) {
+        return(status);
+    }
+
+    rawData = (rawData & (DELETE_7BITS));
+
+    //	//check if the value received is positive or negative
+    if (rawData & CHECK_BIT_9) {
+        rawData = rawData - CHANGE_UNIT_TO_INT_9;
+    }
+
+    numRev = rawData;
+    return(status);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::getAngleSpeed(double& finalAngleSpeed)
+{
+    int16_t rawSpeed = 0;
+
+    return(getAngleSpeed(finalAngleSpeed, rawSpeed, UPD_LOW, SAFE_HIGH));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::getAngleSpeed(double& finalAngleSpeed, int16_t& rawSpeed, updTypes upd, safetyTypes safe)
+{
+    int8_t      numOfData = 0x5;
+    uint16_t*   rawData = new uint16_t[numOfData];
+    errorTypes  status = readMoreRegisters(REG_ASPD + numOfData, rawData, upd, safe);
+
+    if (status != NO_ERROR) {
+        return(status);
+    }
+
+    // Prepare raw speed
+    rawSpeed = rawData[0];
+    rawSpeed = (rawSpeed & (DELETE_BIT_15));
+
+    //check if the value received is positive or negative
+    if (rawSpeed & CHECK_BIT_14) {
+        rawSpeed = rawSpeed - CHANGE_UINT_TO_INT_15;
+    }
+
+    // Prepare firMDVal
+    uint16_t    firMDVal = rawData[3];
+
+    firMDVal >>= 14;
+
+    // Prepare intMode2Prediction
+    uint16_t    intMode2Prediction = rawData[5];
+
+    if (intMode2Prediction & 0x0004) {
+        intMode2Prediction = 3;
+    }
+    else {
+        intMode2Prediction = 2;
+    }
+
+    // Prepare angle range
+    uint16_t    rawAngleRange = rawData[5];
+
+    rawAngleRange &= GET_BIT_14_4;
+    rawAngleRange >>= 4;
+
+    double  angleRange = ANGLE_360_VAL * (POW_2_7 / (double)(rawAngleRange));
+
+    //checks the value of fir_MD according to which the value in the calculation of the speed will be determined
+
+    //according to if prediction is enabled then, the formula for speed changes
+    finalAngleSpeed = calculateAngleSpeed(angleRange, rawSpeed, firMDVal, intMode2Prediction);
+    delete[] rawData;
+    return(status);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::getAngleRange(double& angleRange)
+{
+    uint16_t    rawData = 0;
+    errorTypes  status = readIntMode2(rawData);
+
+    if (status != NO_ERROR) {
+        return(status);
+    }
+
+    //Angle Range is stored in bytes 14 - 4, so you have to do this bit shifting to get the right value
+    rawData &= GET_BIT_14_4;
+    rawData >>= 4;
+    angleRange = ANGLE_360_VAL * (POW_2_7 / (double)(rawData));
+    return(status);
+}
+
+// end get functions
+//-----------------------------------------------------------------------------
+
+// begin write functions
+errorTypes TLE5012B::writeIntMode2(uint16_t dataToWrite)
+{
+    return(writeToSensor(REG_MOD_2, dataToWrite, true));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::writeIntMode3(uint16_t dataToWrite)
+{
+    return(writeToSensor(REG_MOD_3, dataToWrite, true));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::writeOffsetX(uint16_t dataToWrite)
+{
+    return(writeToSensor(REG_OFFX, dataToWrite, true));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::writeOffsetY(uint16_t dataToWrite)
+{
+    return(writeToSensor(REG_OFFY, dataToWrite, true));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::writeSynch(uint16_t dataToWrite)
+{
+    return(writeToSensor(REG_SYNCH, dataToWrite, true));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::writeIFAB(uint16_t dataToWrite)
+{
+    return(writeToSensor(REG_IFAB, dataToWrite, true));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::writeIntMode4(uint16_t dataToWrite)
+{
+    return(writeToSensor(REG_MOD_4, dataToWrite, true));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::writeTempCoeff(uint16_t dataToWrite)
+{
+    return(writeToSensor(REG_TCO_Y, dataToWrite, true));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::writeActivationStatus(uint16_t dataToWrite)
+{
+    return(writeToSensor(REG_ACSTAT, dataToWrite, false));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::writeIntMode1(uint16_t dataToWrite)
+{
+    return(writeToSensor(REG_MOD_1, dataToWrite, false));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::writeSIL(uint16_t dataToWrite)
+{
+    return(writeToSensor(REG_SIL, dataToWrite, false));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+errorTypes TLE5012B::writeSlaveNumber(uint16_t dataToWrite)
+{
+    return(writeToSensor(WRITE_SENSOR, dataToWrite, false));
+}
+
+// end write functions