Library for the TLE5012B magnetic 360° angle sensor.

Dependents:   TLE5012B_Hello

This is a Mbed port of the TLE5012B-Angle-Sensor Arduino library.

TLE5012B

200


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.

A bi-directional Synchronous Serial Communication (SSC) Interface (aka 3-wire SPI) is used for the communication. The TLE5012B has a single pin for Data input and and Data output. This pin is connected to the Mbed's SPI MOSI and MISO pins using a series/pull-up resistor as proposed for the 3-wire SPI by Wim Huiskamp.

Wiring of the 8MHz SSC (aka 3-wire SPI) communication:

https://os.mbed.com/media/uploads/hudakz/tle5012b_wiring02.png


Example program:

Import programTLE5012B_Hello

Example program for the TLE5012B magnetic 360° angle sensor.

Committer:
hudakz
Date:
Sat Sep 19 18:49:44 2020 +0000
Revision:
1:220a2496380e
Parent:
0:4b76b1dc05cd
Library for the TLE5012B Giant Magneto Resistance (GMR) based angle sensor.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:4b76b1dc05cd 1 /*!
hudakz 0:4b76b1dc05cd 2 * \name TLE5012B.h - Mbed port of Arduino library for the TLE5012B angle sensor.
hudakz 0:4b76b1dc05cd 3 * \author Infineon Technologies AG (Dr.Olaf Filies)
hudakz 0:4b76b1dc05cd 4 * \copyright 2019 Infineon Technologies AG
hudakz 0:4b76b1dc05cd 5 * \version 2.0.1
hudakz 0:4b76b1dc05cd 6 * \brief GMR-based angle sensor for angular position sensing in automotive applications
hudakz 0:4b76b1dc05cd 7 * \details Ported to Mbed by Zoltan Hudak 2020-08
hudakz 0:4b76b1dc05cd 8 *
hudakz 0:4b76b1dc05cd 9 * The TLE5012B is a 360° angle sensor that detects the orientation of a magnetic field.
hudakz 0:4b76b1dc05cd 10 * This is achieved by measuring sine and cosine angle components with monolithic integrated
hudakz 0:4b76b1dc05cd 11 * Giant Magneto Resistance (iGMR) elements. These raw signals (sine and cosine) are digitally
hudakz 0:4b76b1dc05cd 12 * processed internally to calculate the angle orientation of the magnetic field (magnet).
hudakz 0:4b76b1dc05cd 13 * The TLE5012B is a pre-calibrated sensor. The calibration parameters are stored in laser fuses.
hudakz 0:4b76b1dc05cd 14 * At start-up the values of the fuses are written into flip-flops, where these values can be changed
hudakz 0:4b76b1dc05cd 15 * by the application-specific parameters. Further precision of the angle measurement over a wide
hudakz 0:4b76b1dc05cd 16 * temperature range and a long lifetime can be improved by enabling an optional internal autocalibration
hudakz 0:4b76b1dc05cd 17 * algorithm. Data communications are accomplished with a bi-directional Synchronous Serial Communication (SSC)
hudakz 0:4b76b1dc05cd 18 * that is SPI-compatible. The sensor configuration is stored in registers, which are accessible by the
hudakz 0:4b76b1dc05cd 19 * SSC interface. Additionally four other interfaces are available with the TLE5012B: Pulse-Width-Modulation (PWM)
hudakz 0:4b76b1dc05cd 20 * Protocol, Short-PWM-Code (SPC) Protocol, Hall Switch Mode (HSM) and Incremental Interface (IIF). These interfaces
hudakz 0:4b76b1dc05cd 21 * can be used in parallel with SSC or alone. Pre-configured sensor derivates with different interface settings are available.
hudakz 0:4b76b1dc05cd 22 * Online diagnostic functions are provided to ensure reliable operation.
hudakz 0:4b76b1dc05cd 23 *
hudakz 0:4b76b1dc05cd 24 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
hudakz 0:4b76b1dc05cd 25 * following conditions are met:
hudakz 0:4b76b1dc05cd 26 *
hudakz 0:4b76b1dc05cd 27 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
hudakz 0:4b76b1dc05cd 28 * disclaimer.
hudakz 0:4b76b1dc05cd 29 *
hudakz 0:4b76b1dc05cd 30 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
hudakz 0:4b76b1dc05cd 31 * disclaimer in the documentation and/or other materials provided with the distribution.
hudakz 0:4b76b1dc05cd 32 *
hudakz 0:4b76b1dc05cd 33 * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
hudakz 0:4b76b1dc05cd 34 * products derived from this software without specific prior written permission.
hudakz 0:4b76b1dc05cd 35 *
hudakz 0:4b76b1dc05cd 36 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
hudakz 0:4b76b1dc05cd 37 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
hudakz 0:4b76b1dc05cd 38 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
hudakz 0:4b76b1dc05cd 39 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
hudakz 0:4b76b1dc05cd 40 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
hudakz 0:4b76b1dc05cd 41 * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
hudakz 0:4b76b1dc05cd 42 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
hudakz 0:4b76b1dc05cd 43 *
hudakz 0:4b76b1dc05cd 44 */
hudakz 0:4b76b1dc05cd 45
hudakz 0:4b76b1dc05cd 46 #ifndef TLE5012B_H
hudakz 0:4b76b1dc05cd 47 #define TLE5012B_H
hudakz 0:4b76b1dc05cd 48
hudakz 0:4b76b1dc05cd 49 #include "TLE5012B_SPI.h"
hudakz 0:4b76b1dc05cd 50
hudakz 0:4b76b1dc05cd 51 namespace TLE5012 {
hudakz 0:4b76b1dc05cd 52
hudakz 0:4b76b1dc05cd 53 // Sensor registers
hudakz 0:4b76b1dc05cd 54 #define READ_SENSOR 0x8000 //!< base command for read
hudakz 0:4b76b1dc05cd 55 #define WRITE_SENSOR 0x5000 //!< base command for write
hudakz 0:4b76b1dc05cd 56 #define READ_BLOCK_CRC 0x8088 //!< initialize block CRC check command
hudakz 0:4b76b1dc05cd 57
hudakz 0:4b76b1dc05cd 58 #define REG_STAT 0x0000 //!< STAT status register
hudakz 0:4b76b1dc05cd 59 #define REG_ACSTAT 0x0010 //!< ACSTAT activation status register
hudakz 0:4b76b1dc05cd 60 #define REG_AVAL 0x0020 //!< AVAL angle value register
hudakz 0:4b76b1dc05cd 61 #define REG_ASPD 0x0030 //!< ASPD angle speed register
hudakz 0:4b76b1dc05cd 62 #define REG_AREV 0x0040 //!< AREV angle revolution register
hudakz 0:4b76b1dc05cd 63 #define REG_FSYNC 0x0050 //!< FSYNC frame synchronization register
hudakz 0:4b76b1dc05cd 64 #define REG_MOD_1 0x0060 //!< MOD_1 interface mode1 register
hudakz 0:4b76b1dc05cd 65 #define REG_SIL 0x0070 //!< SIL register
hudakz 0:4b76b1dc05cd 66 #define REG_MOD_2 0x0080 //!< MOD_2 interface mode2 register
hudakz 0:4b76b1dc05cd 67 #define REG_MOD_3 0x0090 //!< MOD_3 interface mode3 register
hudakz 0:4b76b1dc05cd 68 #define REG_OFFX 0x00A0 //!< OFFX offset x
hudakz 0:4b76b1dc05cd 69 #define REG_OFFY 0x00B0 //!< OFFY offset y
hudakz 0:4b76b1dc05cd 70 #define REG_SYNCH 0x00C0 //!< SYNCH synchronicity
hudakz 0:4b76b1dc05cd 71 #define REG_IFAB 0x00D0 //!< IFAB register
hudakz 0:4b76b1dc05cd 72 #define REG_MOD_4 0x00E0 //!< MOD_4 interface mode4 register
hudakz 0:4b76b1dc05cd 73 #define REG_TCO_Y 0x00F0 //!< TCO_Y temperature coefficient register
hudakz 0:4b76b1dc05cd 74 #define REG_ADC_X 0x0100 //!< ADC_X ADC X-raw value
hudakz 0:4b76b1dc05cd 75 #define REG_ADC_Y 0x0110 //!< ADC_Y ADC Y-raw value
hudakz 0:4b76b1dc05cd 76 #define REG_D_MAG 0x0140 //!< D_MAG angle vector magnitude
hudakz 0:4b76b1dc05cd 77 #define REG_T_RAW 0x0150 //!< T_RAW temperature sensor raw-value
hudakz 0:4b76b1dc05cd 78 #define REG_IIF_CNT 0x0200 //!< IIF_CNT IIF counter value
hudakz 0:4b76b1dc05cd 79 #define REG_T25O 0x0300 //!< T25O temperature 25°c offset value
hudakz 0:4b76b1dc05cd 80
hudakz 0:4b76b1dc05cd 81 #define SYSTEM_ERROR_MASK 0x4000 //!< System error masks for safety words
hudakz 0:4b76b1dc05cd 82 #define INTERFACE_ERROR_MASK 0x2000 //!< Interface error masks for safety words
hudakz 0:4b76b1dc05cd 83 #define INV_ANGLE_ERROR_MASK 0x1000 //!< Angle error masks for safety words
hudakz 0:4b76b1dc05cd 84
hudakz 0:4b76b1dc05cd 85 #define CRC_POLYNOMIAL 0x1D //!< values used for calculating the CRC
hudakz 0:4b76b1dc05cd 86 #define CRC_SEED 0xFF
hudakz 0:4b76b1dc05cd 87 #define CRC_NUM_REGISTERS 0x0008 //!< number of CRC relevant registers
hudakz 0:4b76b1dc05cd 88 #define MAX_REGISTER_MEM 0x0030 //!< max readable register values buffer
hudakz 0:4b76b1dc05cd 89
hudakz 0:4b76b1dc05cd 90 #define DELETE_BIT_15 0x7FFF //!< Value used to delete everything except the first 15 bits
hudakz 0:4b76b1dc05cd 91 #define CHANGE_UINT_TO_INT_15 0x8000 //!< Value used to change unsigned 16bit integer into signed
hudakz 0:4b76b1dc05cd 92 #define CHECK_BIT_14 0x4000 //!<
hudakz 0:4b76b1dc05cd 93 #define GET_BIT_14_4 0x7FF0 //!<
hudakz 0:4b76b1dc05cd 94
hudakz 0:4b76b1dc05cd 95 #define DELETE_7BITS 0x01FF //!< values used to calculate 9 bit signed integer sent by the sensor
hudakz 0:4b76b1dc05cd 96 #define CHANGE_UNIT_TO_INT_9 0x0200 //!< Value used to change unsigned 9bit integer into signed
hudakz 0:4b76b1dc05cd 97 #define CHECK_BIT_9 0x0100
hudakz 0:4b76b1dc05cd 98
hudakz 0:4b76b1dc05cd 99 #define POW_2_15 32768.0 //!< values used to for final calculations of angle speed, revolutions, range and value
hudakz 0:4b76b1dc05cd 100 #define POW_2_7 128.0 //!<
hudakz 0:4b76b1dc05cd 101 #define ANGLE_360_VAL 360.0
hudakz 0:4b76b1dc05cd 102
hudakz 0:4b76b1dc05cd 103 #define TEMP_OFFSET 152.0 //!< values used to calculate the temperature
hudakz 0:4b76b1dc05cd 104 #define TEMP_DIV 2.776
hudakz 0:4b76b1dc05cd 105
hudakz 0:4b76b1dc05cd 106 //!< Prints a binary number with leading zeros (Automatic Handling)
hudakz 0:4b76b1dc05cd 107 #define PRINTBIN(Num) for (uint32_t t = (1UL<< (sizeof(Num)*8)-1); t; t >>= 1) Serial.write(Num & t ? '1' : '0');
hudakz 0:4b76b1dc05cd 108 //!< Prints a binary number with leading zeros (Automatic Handling) with space
hudakz 0:4b76b1dc05cd 109 #define PRINTBINS(Num) for (uint32_t t = (1UL<< (sizeof(Num)*8)-1); t; t >>= 1) Serial.write(Num & t ? " 1 " : " 0 ");
hudakz 0:4b76b1dc05cd 110
hudakz 0:4b76b1dc05cd 111 /*!
hudakz 0:4b76b1dc05cd 112 * Error types from safety word
hudakz 0:4b76b1dc05cd 113 */
hudakz 0:4b76b1dc05cd 114 enum errorTypes
hudakz 0:4b76b1dc05cd 115 {
hudakz 0:4b76b1dc05cd 116 NO_ERROR = 0x00, //!< NO_ERROR = Safety word was OK
hudakz 0:4b76b1dc05cd 117 SYSTEM_ERROR = 0x01, //!< SYSTEM_ERROR = over/under voltage, VDD negative, GND off, ROM defect
hudakz 0:4b76b1dc05cd 118 INTERFACE_ACCESS_ERROR = 0x02, //!< INTERFACE_ACCESS_ERROR = wrong address or wrong lock
hudakz 0:4b76b1dc05cd 119 INVALID_ANGLE_ERROR = 0x03, //!< INVALID_ANGLE_ERROR = NO_GMR_A = 1 or NO_GMR_XY = 1
hudakz 0:4b76b1dc05cd 120 ANGLE_SPEED_ERROR = 0x04, //!< ANGLE_SPEED_ERROR = combined error, angular speed calculation wrong
hudakz 0:4b76b1dc05cd 121 CRC_ERROR = 0xFF //!< CRC_ERROR = Cyclic Redundancy Check (CRC), which includes the STAT and RESP bits wrong
hudakz 0:4b76b1dc05cd 122 };
hudakz 0:4b76b1dc05cd 123
hudakz 0:4b76b1dc05cd 124 /*!
hudakz 0:4b76b1dc05cd 125 * Set the UPDate bit high (read from update buffer) or low (read directly)
hudakz 0:4b76b1dc05cd 126 */
hudakz 0:4b76b1dc05cd 127 enum updTypes
hudakz 0:4b76b1dc05cd 128 {
hudakz 0:4b76b1dc05cd 129 UPD_LOW = 0x0000, //!< read normal registers
hudakz 0:4b76b1dc05cd 130 UPD_HIGH = 0x0400, //!< read update buffer registers
hudakz 0:4b76b1dc05cd 131 };
hudakz 0:4b76b1dc05cd 132
hudakz 0:4b76b1dc05cd 133 /*!
hudakz 0:4b76b1dc05cd 134 * Switch on/off safety word generation
hudakz 0:4b76b1dc05cd 135 */
hudakz 0:4b76b1dc05cd 136 enum safetyTypes
hudakz 0:4b76b1dc05cd 137 {
hudakz 0:4b76b1dc05cd 138 SAFE_LOW = 0x0000, //!< switch of safety word generation
hudakz 0:4b76b1dc05cd 139 SAFE_HIGH = 0x0001, //!< switch on safety word generation
hudakz 0:4b76b1dc05cd 140 };
hudakz 0:4b76b1dc05cd 141
hudakz 0:4b76b1dc05cd 142 /*!
hudakz 0:4b76b1dc05cd 143 * Offset for the slave number register to identify the
hudakz 0:4b76b1dc05cd 144 * right selected slave. Max 4 slaves with separated CSQ
hudakz 0:4b76b1dc05cd 145 * lines are possible. If more than one sensor is used on the SPI
hudakz 0:4b76b1dc05cd 146 * interface, than the SNR register must we written with the correct slave number
hudakz 0:4b76b1dc05cd 147 */
hudakz 0:4b76b1dc05cd 148 enum slaveNum
hudakz 0:4b76b1dc05cd 149 {
hudakz 0:4b76b1dc05cd 150 TLE5012B_S0 = 0x0000, //!< TLE5012B_S0 default setting for only one sensor on the SPI
hudakz 0:4b76b1dc05cd 151 TLE5012B_S1 = 0x2000, //!< TLE5012B_S1 second sensor needs also a second CSQ
hudakz 0:4b76b1dc05cd 152 TLE5012B_S2 = 0x4000, //!< TLE5012B_S2 third sensor and dito
hudakz 0:4b76b1dc05cd 153 TLE5012B_S3 = 0x6000 //!< TLE5012B_S3 fourth sensor and dito
hudakz 0:4b76b1dc05cd 154 };
hudakz 0:4b76b1dc05cd 155
hudakz 0:4b76b1dc05cd 156 typedef struct safetyWord {//!< Safety word bit setting
hudakz 0:4b76b1dc05cd 157 bool STAT_RES; //!< bits 15:15 Indication of chip reset or watchdog overflow
hudakz 0:4b76b1dc05cd 158 bool STAT_ERR; //!< bits 14:14 System error
hudakz 0:4b76b1dc05cd 159 bool STAT_ACC; //!< bits 13:13 Interface access error
hudakz 0:4b76b1dc05cd 160 bool STAT_ANG; //!< bits 12:12 Invalid angle value
hudakz 0:4b76b1dc05cd 161 uint8_t RESP; //!< bits 11:8 Sensor number response indicator
hudakz 0:4b76b1dc05cd 162 uint8_t CRC_ADC; //!< bits 7:0 Status ADC Test
hudakz 0:4b76b1dc05cd 163
hudakz 0:4b76b1dc05cd 164 /*!
hudakz 0:4b76b1dc05cd 165 * Returns the safety word slave number to identify the sensor
hudakz 0:4b76b1dc05cd 166 * @return slaveNum setting in safety word
hudakz 0:4b76b1dc05cd 167 */
hudakz 0:4b76b1dc05cd 168 slaveNum responseSlave(){
hudakz 0:4b76b1dc05cd 169 return (RESP == 0x7 ? TLE5012B_S3
hudakz 0:4b76b1dc05cd 170 : (RESP == 0xB ? TLE5012B_S2
hudakz 0:4b76b1dc05cd 171 : (RESP == 0xD ? TLE5012B_S1
hudakz 0:4b76b1dc05cd 172 : TLE5012B_S0)));
hudakz 0:4b76b1dc05cd 173 }
hudakz 0:4b76b1dc05cd 174
hudakz 0:4b76b1dc05cd 175 /*!
hudakz 0:4b76b1dc05cd 176 * Function separates safety word bits
hudakz 0:4b76b1dc05cd 177 * @param [in,out] reg actual safety or last fetched as default
hudakz 0:4b76b1dc05cd 178 * @return safety word
hudakz 0:4b76b1dc05cd 179 */
hudakz 0:4b76b1dc05cd 180 uint16_t fetch_Safety(uint16_t reg)
hudakz 0:4b76b1dc05cd 181 {
hudakz 0:4b76b1dc05cd 182 CRC_ADC = (reg & 0x7F);
hudakz 0:4b76b1dc05cd 183 RESP = (reg & 0xF00) >> 8;
hudakz 0:4b76b1dc05cd 184 STAT_ANG = (reg & 0x1000) >> 12;
hudakz 0:4b76b1dc05cd 185 STAT_ACC = (reg & 0x2000) >> 13;
hudakz 0:4b76b1dc05cd 186 STAT_ERR = (reg & 0x4000) >> 14;
hudakz 0:4b76b1dc05cd 187 STAT_RES = (reg & 0x8000) >> 15;
hudakz 0:4b76b1dc05cd 188 return (reg);
hudakz 0:4b76b1dc05cd 189 }
hudakz 0:4b76b1dc05cd 190 } safetyWord_t;
hudakz 0:4b76b1dc05cd 191
hudakz 0:4b76b1dc05cd 192 /*!
hudakz 0:4b76b1dc05cd 193 * Class TLE5012B
hudakz 0:4b76b1dc05cd 194 */
hudakz 0:4b76b1dc05cd 195 class TLE5012B
hudakz 0:4b76b1dc05cd 196 {
hudakz 0:4b76b1dc05cd 197 public:
hudakz 0:4b76b1dc05cd 198
hudakz 0:4b76b1dc05cd 199 TLE5012B(TLE5012B_SPI* spi, PinName cs) : _spiConnection(spi), _cs(cs), _slave(TLE5012B_S0) { }
hudakz 0:4b76b1dc05cd 200 ~TLE5012B() {}
hudakz 0:4b76b1dc05cd 201
hudakz 0:4b76b1dc05cd 202 /**
hudakz 0:4b76b1dc05cd 203 * All these functions cover the SPI interface and should be implemented
hudakz 0:4b76b1dc05cd 204 * into XMC SPI wrapper.
hudakz 0:4b76b1dc05cd 205 * In 3wire SPI mode miso and mosi are connected together, so read and
hudakz 0:4b76b1dc05cd 206 * write operations are on the same line. In 4wire more read and write are
hudakz 0:4b76b1dc05cd 207 * separated. The system clock SCK and the sensor enable EN line are used
hudakz 0:4b76b1dc05cd 208 * for all slaves whereas the chip select line CS must we set unique for
hudakz 0:4b76b1dc05cd 209 * each slave. A max of four slaves on one SPI interface are possible
hudakz 0:4b76b1dc05cd 210 * @return CRC error type
hudakz 0:4b76b1dc05cd 211 * @param [in] slave slave offset setting for the SNR register, default is TLE5012B_S0
hudakz 0:4b76b1dc05cd 212 */
hudakz 0:4b76b1dc05cd 213 errorTypes begin(slaveNum slave);
hudakz 0:4b76b1dc05cd 214
hudakz 0:4b76b1dc05cd 215 /*!
hudakz 0:4b76b1dc05cd 216 * Triggers an update in the register buffer. This function
hudakz 0:4b76b1dc05cd 217 * should be triggered once before UPD registers where read as
hudakz 0:4b76b1dc05cd 218 * it generates a snapshot of the UPD register values at trigger point
hudakz 0:4b76b1dc05cd 219 */
hudakz 0:4b76b1dc05cd 220 void triggerUpdate();
hudakz 0:4b76b1dc05cd 221
hudakz 0:4b76b1dc05cd 222 /*!
hudakz 0:4b76b1dc05cd 223 * Reads the block of _registers from addresses 08 - 0F in order to figure out the CRC.
hudakz 0:4b76b1dc05cd 224 * ATTENTION: You need a memory chunk of unit16_t * CRC Registers + 1 * uint16_t for the safety word.
hudakz 0:4b76b1dc05cd 225 * @return CRC error type
hudakz 0:4b76b1dc05cd 226 */
hudakz 0:4b76b1dc05cd 227 errorTypes readBlockCRC();
hudakz 0:4b76b1dc05cd 228
hudakz 0:4b76b1dc05cd 229 /*!
hudakz 0:4b76b1dc05cd 230 * General read function for reading _registers from the Tle5012b.
hudakz 0:4b76b1dc05cd 231 *
hudakz 0:4b76b1dc05cd 232 * structure of command word, the numbers represent the bit position of the 2 byte command
hudakz 0:4b76b1dc05cd 233 * 15 - 0 write, 1 read
hudakz 0:4b76b1dc05cd 234 * 14:11 - 0000 for default operational access for addresses between 0x00 - 0x04, 1010 for configuration access for addresses between 0x05 - 0x11
hudakz 0:4b76b1dc05cd 235 * 10 - 0 access to current value, 1 access to value in update buffer
hudakz 0:4b76b1dc05cd 236 * 9:4 - access to 6 bit register address
hudakz 0:4b76b1dc05cd 237 * 3:0 - 4 bit number of data words.
hudakz 0:4b76b1dc05cd 238 *
hudakz 0:4b76b1dc05cd 239 * @param [in] command the command for reading
hudakz 0:4b76b1dc05cd 240 * @param [out] data where the data received from the _registers will be stored
hudakz 0:4b76b1dc05cd 241 * @param [in] upd read from update (UPD_high) register or directly (default, UPD_low)
hudakz 0:4b76b1dc05cd 242 * @param [in] safe generate safety word (default, SAFE_high) or not (SAFE_low)
hudakz 0:4b76b1dc05cd 243 * @return CRC error type
hudakz 0:4b76b1dc05cd 244 */
hudakz 0:4b76b1dc05cd 245 errorTypes readFromSensor(uint16_t command, uint16_t &data, updTypes upd=UPD_LOW, safetyTypes safe=SAFE_HIGH);
hudakz 0:4b76b1dc05cd 246
hudakz 0:4b76b1dc05cd 247 /*!
hudakz 0:4b76b1dc05cd 248 * Can be used to read 1 or more consecutive _registers, and the values
hudakz 0:4b76b1dc05cd 249 * used to read 1 or more than 1 consecutive _registers.
hudakz 0:4b76b1dc05cd 250 * The maximum amount of registers are limited by the bit 3-0 of the command word, which means
hudakz 0:4b76b1dc05cd 251 * you can read max 15 registers and one safety word at once.
hudakz 0:4b76b1dc05cd 252 * @param [in] command the command for reading
hudakz 0:4b76b1dc05cd 253 * @param [out] data where the data received from the _registers will be stored
hudakz 0:4b76b1dc05cd 254 * @param [in] upd read from update (UPD_high) register or directly (default, UPD_low)
hudakz 0:4b76b1dc05cd 255 * @param [in] safe generate safety word (default, SAFE_high) or no (SAFE_low)
hudakz 0:4b76b1dc05cd 256 * @return CRC error type
hudakz 0:4b76b1dc05cd 257 */
hudakz 0:4b76b1dc05cd 258 errorTypes readMoreRegisters(uint16_t command, uint16_t data[], updTypes upd=UPD_LOW, safetyTypes safe=SAFE_HIGH);
hudakz 0:4b76b1dc05cd 259
hudakz 0:4b76b1dc05cd 260 /*!
hudakz 0:4b76b1dc05cd 261 * This functions reads the main status word for the sensor,
hudakz 0:4b76b1dc05cd 262 * mainly for checking with the additional safety word
hudakz 0:4b76b1dc05cd 263 * @param [out] data pointer with the received data word
hudakz 0:4b76b1dc05cd 264 * @param [in] upd read from update (UPD_high) register or directly (default, UPD_low)
hudakz 0:4b76b1dc05cd 265 * @param [in] safe generate safety word (default, SAFE_high) or no (SAFE_low)
hudakz 0:4b76b1dc05cd 266 * @return CRC error type
hudakz 0:4b76b1dc05cd 267 */
hudakz 0:4b76b1dc05cd 268 errorTypes readStatus(uint16_t &data, updTypes upd=UPD_LOW, safetyTypes safe=SAFE_HIGH);
hudakz 0:4b76b1dc05cd 269
hudakz 0:4b76b1dc05cd 270 /*!
hudakz 0:4b76b1dc05cd 271 * This functions reads activation status word for the sensor,
hudakz 0:4b76b1dc05cd 272 * which held on/off information for all optional checks and additional functions
hudakz 0:4b76b1dc05cd 273 * @param [out] data pointer with the received data word
hudakz 0:4b76b1dc05cd 274 * @param [in] upd read from update (UPD_high) register or directly (default, UPD_low)
hudakz 0:4b76b1dc05cd 275 * @param [in] safe generate safety word (default, SAFE_high) or no (SAFE_low)
hudakz 0:4b76b1dc05cd 276 * @return CRC error type
hudakz 0:4b76b1dc05cd 277 */
hudakz 0:4b76b1dc05cd 278 errorTypes readActivationStatus(uint16_t &data, updTypes upd=UPD_LOW, safetyTypes safe=SAFE_HIGH);
hudakz 0:4b76b1dc05cd 279
hudakz 0:4b76b1dc05cd 280 /*!
hudakz 0:4b76b1dc05cd 281 * The next functions are used primarily for storing the parameters and
hudakz 0:4b76b1dc05cd 282 * control of how the sensor works. The values stored in them are used to calculate
hudakz 0:4b76b1dc05cd 283 * the CRC, and their values are stored in the private component of the class, _registers.
hudakz 0:4b76b1dc05cd 284 * @param [out] data where the data received from the _registers will be stored
hudakz 0:4b76b1dc05cd 285 * @return CRC error type
hudakz 0:4b76b1dc05cd 286 */
hudakz 0:4b76b1dc05cd 287 errorTypes readActiveStatus(uint16_t &data); //!< read register offset 0x01
hudakz 0:4b76b1dc05cd 288 errorTypes readIntMode1(uint16_t &data); //!< read register offset 0x06
hudakz 0:4b76b1dc05cd 289 errorTypes readSIL(uint16_t &data); //!< read register offset 0x07
hudakz 0:4b76b1dc05cd 290 errorTypes readIntMode2(uint16_t &data); //!< read register offset 0x08
hudakz 0:4b76b1dc05cd 291 errorTypes readIntMode3(uint16_t &data); //!< read register offset 0x09
hudakz 0:4b76b1dc05cd 292 errorTypes readOffsetX(uint16_t &data); //!< read register offset 0x0A
hudakz 0:4b76b1dc05cd 293 errorTypes readOffsetY(uint16_t &data); //!< read register offset 0x0B
hudakz 0:4b76b1dc05cd 294 errorTypes readSynch(uint16_t &data); //!< read register offset 0x0C
hudakz 0:4b76b1dc05cd 295 errorTypes readIFAB(uint16_t &data); //!< read register offset 0x0D
hudakz 0:4b76b1dc05cd 296 errorTypes readIntMode4(uint16_t &data); //!< read register offset 0x0E
hudakz 0:4b76b1dc05cd 297 errorTypes readTempCoeff(uint16_t &data); //!< read register offset 0x0F
hudakz 0:4b76b1dc05cd 298 errorTypes readTempDMag(uint16_t &data); //!< read register offset 0x14
hudakz 0:4b76b1dc05cd 299 errorTypes readTempRaw(uint16_t &data); //!< read register offset 0x15
hudakz 0:4b76b1dc05cd 300 errorTypes readTempIIFCnt(uint16_t &data); //!< read register offset 0x20
hudakz 0:4b76b1dc05cd 301 errorTypes readTempT25(uint16_t &data); //!< read register offset 0x30
hudakz 0:4b76b1dc05cd 302
hudakz 0:4b76b1dc05cd 303 /*!
hudakz 0:4b76b1dc05cd 304 * The rawX value is signed 16 bit value
hudakz 0:4b76b1dc05cd 305 * @param data pointer to 16bit word
hudakz 0:4b76b1dc05cd 306 * @return CRC error type
hudakz 0:4b76b1dc05cd 307 */
hudakz 0:4b76b1dc05cd 308 errorTypes readRawX(int16_t &data);
hudakz 0:4b76b1dc05cd 309
hudakz 0:4b76b1dc05cd 310 /*!
hudakz 0:4b76b1dc05cd 311 * The rawY value is signed 16 bit value
hudakz 0:4b76b1dc05cd 312 * @param data pointer to 16bit word
hudakz 0:4b76b1dc05cd 313 * @return CRC error type
hudakz 0:4b76b1dc05cd 314 */
hudakz 0:4b76b1dc05cd 315 errorTypes readRawY(int16_t &data);
hudakz 0:4b76b1dc05cd 316
hudakz 0:4b76b1dc05cd 317 /*!
hudakz 0:4b76b1dc05cd 318 * returns the Angle Range
hudakz 0:4b76b1dc05cd 319 * Angle Range is stored in bytes 14 - 4 of MOD_2.
hudakz 0:4b76b1dc05cd 320 * @param angleRange pointer to 16bit double value
hudakz 0:4b76b1dc05cd 321 * @return CRC error type
hudakz 0:4b76b1dc05cd 322 */
hudakz 0:4b76b1dc05cd 323 errorTypes getAngleRange(double &angleRange);
hudakz 0:4b76b1dc05cd 324
hudakz 0:4b76b1dc05cd 325 /*!
hudakz 0:4b76b1dc05cd 326 * Returns the angleValue calculated on the base of a 15 bit signed integer.
hudakz 0:4b76b1dc05cd 327 * However, the register returns 16 bits, so we need to do some bit arithmetic.
hudakz 0:4b76b1dc05cd 328 * @param [in,out] angleValue pointer to 16bit double angle value
hudakz 0:4b76b1dc05cd 329 * @return CRC error type
hudakz 0:4b76b1dc05cd 330 */
hudakz 0:4b76b1dc05cd 331 errorTypes getAngleValue(double &angleValue);
hudakz 0:4b76b1dc05cd 332 /*!
hudakz 0:4b76b1dc05cd 333 * Same function as before but also returns a pointer to the raw data
hudakz 0:4b76b1dc05cd 334 * @param [in,out] angleValue pointer to 16bit double angle value
hudakz 0:4b76b1dc05cd 335 * @param [in,out] rawAnglevalue point to an int16_t raw data value
hudakz 0:4b76b1dc05cd 336 * @param [in] upd read from update (UPD_high) register or directly (default, UPD_low)
hudakz 0:4b76b1dc05cd 337 * @param [in] safe generate safety word (default, SAFE_high) or no (SAFE_low)
hudakz 0:4b76b1dc05cd 338 * @return CRC error type
hudakz 0:4b76b1dc05cd 339 */
hudakz 0:4b76b1dc05cd 340 errorTypes getAngleValue(double &angleValue, int16_t &rawAnglevalue, updTypes upd=UPD_LOW, safetyTypes safe=SAFE_HIGH);
hudakz 0:4b76b1dc05cd 341
hudakz 0:4b76b1dc05cd 342 /*!
hudakz 0:4b76b1dc05cd 343 * Returns the number of revolutions done from the angle value which is a 9 bit signed integer.
hudakz 0:4b76b1dc05cd 344 * However, the register returns 16 bits, so we need to do some bit arithmetic.
hudakz 0:4b76b1dc05cd 345 * Therefore the resulting revolution can b only between -256 < numRev < 256 and
hudakz 0:4b76b1dc05cd 346 * it will switch from positive to negative and vice versa values at the borders.
hudakz 0:4b76b1dc05cd 347 * @param [in,out] numRev pointer to 16bit word for the number of revolutions
hudakz 0:4b76b1dc05cd 348 * @param [in] upd read from update (UPD_high) register or directly (default, UPD_low)
hudakz 0:4b76b1dc05cd 349 * @param [in] safe generate safety word (default, SAFE_high) or no (SAFE_low)
hudakz 0:4b76b1dc05cd 350 * @return CRC error type
hudakz 0:4b76b1dc05cd 351 */
hudakz 0:4b76b1dc05cd 352 errorTypes getNumRevolutions(int16_t &numRev, updTypes upd=UPD_LOW, safetyTypes safe=SAFE_HIGH);
hudakz 0:4b76b1dc05cd 353
hudakz 0:4b76b1dc05cd 354 /*!
hudakz 0:4b76b1dc05cd 355 * Return the temperature.
hudakz 0:4b76b1dc05cd 356 * The temperature value is a 9 bit signed integer.
hudakz 0:4b76b1dc05cd 357 * However, the register returns 16 bits, so we need to do some bit arithmetic.
hudakz 0:4b76b1dc05cd 358 * @param [in,out] temp pointer to 16bit double value of the temperature
hudakz 0:4b76b1dc05cd 359 * @return CRC error type
hudakz 0:4b76b1dc05cd 360 */
hudakz 0:4b76b1dc05cd 361 errorTypes getTemperature(double &temp);
hudakz 0:4b76b1dc05cd 362 /*!
hudakz 0:4b76b1dc05cd 363 * Same as above but also returns a pointer to the raw data
hudakz 0:4b76b1dc05cd 364 * @param [in,out] temp pointer to 16bit double value of the temperature
hudakz 0:4b76b1dc05cd 365 * @param [in,out] rawTemp pointer to int16_t raw value data
hudakz 0:4b76b1dc05cd 366 * @param [in] upd read from update (UPD_high) register or directly (default, UPD_low)
hudakz 0:4b76b1dc05cd 367 * @param [in] safe generate safety word (default, SAFE_high) or no (SAFE_low)
hudakz 0:4b76b1dc05cd 368 * @return CRC error type
hudakz 0:4b76b1dc05cd 369 */
hudakz 0:4b76b1dc05cd 370 errorTypes getTemperature(double &temp, int16_t &rawTemp, updTypes upd=UPD_LOW, safetyTypes safe=SAFE_HIGH);
hudakz 0:4b76b1dc05cd 371
hudakz 0:4b76b1dc05cd 372 /*!
hudakz 0:4b76b1dc05cd 373 * Returns the calculated angle speed.
hudakz 0:4b76b1dc05cd 374 * The angle speed is a 15 bit signed integer,
hudakz 0:4b76b1dc05cd 375 * however, the register returns 16 bits, so we need to do some bit arithmetic.
hudakz 0:4b76b1dc05cd 376 * @param [in,out] angleSpeed pointer to 16bit double value
hudakz 0:4b76b1dc05cd 377 * @return CRC error type
hudakz 0:4b76b1dc05cd 378 */
hudakz 0:4b76b1dc05cd 379 errorTypes getAngleSpeed(double &angleSpeed);
hudakz 0:4b76b1dc05cd 380 /*!
hudakz 0:4b76b1dc05cd 381 * Same as above but also returns a pointer to the raw data
hudakz 0:4b76b1dc05cd 382 * @param [in,out] angleSpeed angleSpeed pointer to 16bit double value
hudakz 0:4b76b1dc05cd 383 * @param [in,out] rawSpeed pointer to int16_t raw value data
hudakz 0:4b76b1dc05cd 384 * @param [in] upd read from update (UPD_high) register or directly (default, UPD_low)
hudakz 0:4b76b1dc05cd 385 * @param [in] safe generate safety word (default, SAFE_high) or no (SAFE_low)
hudakz 0:4b76b1dc05cd 386 * @return CRC error type
hudakz 0:4b76b1dc05cd 387 */
hudakz 0:4b76b1dc05cd 388 errorTypes getAngleSpeed(double &angleSpeed,int16_t &rawSpeed, updTypes upd=UPD_LOW, safetyTypes safe=SAFE_HIGH);
hudakz 0:4b76b1dc05cd 389
hudakz 0:4b76b1dc05cd 390 /*!
hudakz 0:4b76b1dc05cd 391 * Function sets the SNR register with the correct slave number
hudakz 0:4b76b1dc05cd 392 * @param [in] dataToWrite the new data that will be written to the register
hudakz 0:4b76b1dc05cd 393 * @return CRC error type
hudakz 0:4b76b1dc05cd 394 */
hudakz 0:4b76b1dc05cd 395 errorTypes writeSlaveNumber(uint16_t dataToWrite);
hudakz 0:4b76b1dc05cd 396
hudakz 0:4b76b1dc05cd 397 /*!
hudakz 0:4b76b1dc05cd 398 * General write function for writing registers to the Tle5012b. The safety flag will be
hudakz 0:4b76b1dc05cd 399 * set always and only some of all registers are writable. See documentation for further information.
hudakz 0:4b76b1dc05cd 400 * @param [in] command the command to execute the write
hudakz 0:4b76b1dc05cd 401 * @param [in] dataToWrite the new data that will be written to the register
hudakz 0:4b76b1dc05cd 402 * @param [in] changeCRC the registerIndex helps figure out in which register the value changed,
hudakz 0:4b76b1dc05cd 403 * so that we don't need to read all the register again to calculate the CRC
hudakz 0:4b76b1dc05cd 404 * @return CRC error type
hudakz 0:4b76b1dc05cd 405 */
hudakz 0:4b76b1dc05cd 406 errorTypes writeToSensor(uint16_t command, uint16_t dataToWrite, bool changeCRC);
hudakz 0:4b76b1dc05cd 407
hudakz 0:4b76b1dc05cd 408 /*!
hudakz 0:4b76b1dc05cd 409 * This function is used in order to update the CRC in the register 0F(second byte)
hudakz 0:4b76b1dc05cd 410 * @param [in] dataToWrite the new data that will be written to the register
hudakz 0:4b76b1dc05cd 411 * @return CRC error type
hudakz 0:4b76b1dc05cd 412 */
hudakz 0:4b76b1dc05cd 413 errorTypes writeTempCoeffUpdate(uint16_t dataToWrite);
hudakz 0:4b76b1dc05cd 414
hudakz 0:4b76b1dc05cd 415 /*!
hudakz 0:4b76b1dc05cd 416 * Standard function used for updating the CRC
hudakz 0:4b76b1dc05cd 417 * @param [in] dataToWrite the new data that will be written to the register
hudakz 0:4b76b1dc05cd 418 * @return CRC error type
hudakz 0:4b76b1dc05cd 419 */
hudakz 0:4b76b1dc05cd 420 errorTypes writeActivationStatus(uint16_t dataToWrite); //!< write register offset 0x01
hudakz 0:4b76b1dc05cd 421 errorTypes writeIntMode1(uint16_t dataToWrite); //!< write register offset 0x06
hudakz 0:4b76b1dc05cd 422 errorTypes writeSIL(uint16_t dataToWrite); //!< write register offset 0x07
hudakz 0:4b76b1dc05cd 423 errorTypes writeIntMode2(uint16_t dataToWrite); //!< write register offset 0x08
hudakz 0:4b76b1dc05cd 424 errorTypes writeIntMode3(uint16_t dataToWrite); //!< write register offset 0x09
hudakz 0:4b76b1dc05cd 425 errorTypes writeOffsetX(uint16_t dataToWrite); //!< write register offset 0x0A
hudakz 0:4b76b1dc05cd 426 errorTypes writeOffsetY(uint16_t dataToWrite); //!< write register offset 0x0B
hudakz 0:4b76b1dc05cd 427 errorTypes writeSynch(uint16_t dataToWrite); //!< write register offset 0x0C
hudakz 0:4b76b1dc05cd 428 errorTypes writeIFAB(uint16_t dataToWrite); //!< write register offset 0x0D
hudakz 0:4b76b1dc05cd 429 errorTypes writeIntMode4(uint16_t dataToWrite); //!< write register offset 0x0E
hudakz 0:4b76b1dc05cd 430 errorTypes writeTempCoeff(uint16_t dataToWrite); //!< write register offset 0x0F
hudakz 0:4b76b1dc05cd 431
hudakz 0:4b76b1dc05cd 432 private:
hudakz 0:4b76b1dc05cd 433 TLE5012B_SPI* _spiConnection;
hudakz 0:4b76b1dc05cd 434 DigitalOut _cs;
hudakz 0:4b76b1dc05cd 435 slaveNum _slave; //!< actual set slave number
hudakz 0:4b76b1dc05cd 436 safetyWord_t _safetyStatus; //!< actual safety status
hudakz 0:4b76b1dc05cd 437 uint16_t _safetyWord; //!< the last fetched safety word
hudakz 0:4b76b1dc05cd 438 uint16_t _command[2]; //!< command write data [0] = command, [1] = data to write
hudakz 0:4b76b1dc05cd 439 uint16_t _received[MAX_REGISTER_MEM]; //!< fetched data from sensor with last word = safety word
hudakz 0:4b76b1dc05cd 440 uint16_t _registers[CRC_NUM_REGISTERS]; //!< keeps track of the values stored in the 8 _registers, for which the CRC is calculated
hudakz 0:4b76b1dc05cd 441
hudakz 0:4b76b1dc05cd 442 /*!
hudakz 0:4b76b1dc05cd 443 * This function is called each time any register in the
hudakz 0:4b76b1dc05cd 444 * range 08 - 0F(first byte) is changed. It calculates the new CRC
hudakz 0:4b76b1dc05cd 445 * based on the value of all the _registers and then
hudakz 0:4b76b1dc05cd 446 * stores the value in 0F(second byte)
hudakz 0:4b76b1dc05cd 447 * @return CRC error type
hudakz 0:4b76b1dc05cd 448 */
hudakz 0:4b76b1dc05cd 449 errorTypes regularCrcUpdate();
hudakz 0:4b76b1dc05cd 450
hudakz 0:4b76b1dc05cd 451 /*!
hudakz 0:4b76b1dc05cd 452 * checks the safety by looking at the safety word and calculating
hudakz 0:4b76b1dc05cd 453 * the CRC such that the data received is valid
hudakz 0:4b76b1dc05cd 454 * @param safety register with the CRC check data
hudakz 0:4b76b1dc05cd 455 * @param command the command to execute the write
hudakz 0:4b76b1dc05cd 456 * @param readreg pointer to the read data
hudakz 0:4b76b1dc05cd 457 * @param length the length of the data structure
hudakz 0:4b76b1dc05cd 458 * @return CRC error type
hudakz 0:4b76b1dc05cd 459 */
hudakz 0:4b76b1dc05cd 460 errorTypes checkSafety(uint16_t safety, uint16_t command, uint16_t* readreg, uint16_t length);
hudakz 0:4b76b1dc05cd 461
hudakz 0:4b76b1dc05cd 462 /*!
hudakz 0:4b76b1dc05cd 463 * When an error occurs in the safety word, the error bit remains 0(error),
hudakz 0:4b76b1dc05cd 464 * until the status register is read again. Flushes out safety errors,
hudakz 0:4b76b1dc05cd 465 * that might have occurred by reading the register without a safety word.
hudakz 0:4b76b1dc05cd 466 * In case the safety word sends an error, this function is
hudakz 0:4b76b1dc05cd 467 * called so that the error bit is reset to 1.
hudakz 0:4b76b1dc05cd 468 */
hudakz 0:4b76b1dc05cd 469 void resetSafety();
hudakz 0:4b76b1dc05cd 470
hudakz 0:4b76b1dc05cd 471 };
hudakz 0:4b76b1dc05cd 472
hudakz 0:4b76b1dc05cd 473 } // TLE5012 namespace
hudakz 0:4b76b1dc05cd 474
hudakz 0:4b76b1dc05cd 475 #endif