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_REG.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 * This library include the register read and bit separation function.
hudakz 0:4b76b1dc05cd 8 * \details Ported to Mbed by Zoltan Hudak 2020-08
hudakz 0:4b76b1dc05cd 9 *
hudakz 0:4b76b1dc05cd 10 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
hudakz 0:4b76b1dc05cd 11 * following conditions are met:
hudakz 0:4b76b1dc05cd 12 *
hudakz 0:4b76b1dc05cd 13 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
hudakz 0:4b76b1dc05cd 14 * disclaimer.
hudakz 0:4b76b1dc05cd 15 *
hudakz 0:4b76b1dc05cd 16 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
hudakz 0:4b76b1dc05cd 17 * disclaimer in the documentation and/or other materials provided with the distribution.
hudakz 0:4b76b1dc05cd 18 *
hudakz 0:4b76b1dc05cd 19 * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
hudakz 0:4b76b1dc05cd 20 * products derived from this software without specific prior written permission.
hudakz 0:4b76b1dc05cd 21 *
hudakz 0:4b76b1dc05cd 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
hudakz 0:4b76b1dc05cd 23 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
hudakz 0:4b76b1dc05cd 24 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
hudakz 0:4b76b1dc05cd 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
hudakz 0:4b76b1dc05cd 26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
hudakz 0:4b76b1dc05cd 27 * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
hudakz 0:4b76b1dc05cd 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
hudakz 0:4b76b1dc05cd 29 *
hudakz 0:4b76b1dc05cd 30 */
hudakz 0:4b76b1dc05cd 31
hudakz 0:4b76b1dc05cd 32 #include "TLE5012B_REG.h"
hudakz 0:4b76b1dc05cd 33
hudakz 0:4b76b1dc05cd 34 errorTypes TLE5012B_REG::readSensorType()
hudakz 0:4b76b1dc05cd 35 {
hudakz 0:4b76b1dc05cd 36 errorTypes status;
hudakz 0:4b76b1dc05cd 37 uint16_t rawData[3] = {0};
hudakz 0:4b76b1dc05cd 38
hudakz 0:4b76b1dc05cd 39 triggerUpdate();
hudakz 0:4b76b1dc05cd 40
hudakz 0:4b76b1dc05cd 41 status = readMoreRegisters(0xE, sensorRegister.registers);
hudakz 0:4b76b1dc05cd 42
hudakz 0:4b76b1dc05cd 43 status = readMoreRegisters(REG_TCO_Y + 0x3, rawData);
hudakz 0:4b76b1dc05cd 44 sensorRegister.registers[15] = rawData[0];
hudakz 0:4b76b1dc05cd 45 sensorRegister.registers[16] = rawData[1];
hudakz 0:4b76b1dc05cd 46 sensorRegister.registers[17] = rawData[2];
hudakz 0:4b76b1dc05cd 47
hudakz 0:4b76b1dc05cd 48 status = readMoreRegisters(REG_D_MAG + 0x2, rawData);
hudakz 0:4b76b1dc05cd 49 sensorRegister.registers[18] = rawData[0];
hudakz 0:4b76b1dc05cd 50 sensorRegister.registers[19] = rawData[1];
hudakz 0:4b76b1dc05cd 51
hudakz 0:4b76b1dc05cd 52 status = readTempIIFCnt(rawData[0]);
hudakz 0:4b76b1dc05cd 53 sensorRegister.registers[20] = rawData[0];
hudakz 0:4b76b1dc05cd 54
hudakz 0:4b76b1dc05cd 55 status = readTempT25(rawData[0]);
hudakz 0:4b76b1dc05cd 56 sensorRegister.registers[21] = rawData[0];
hudakz 0:4b76b1dc05cd 57
hudakz 0:4b76b1dc05cd 58 sensorRegister.stat.reg = sensorRegister.registers[0];
hudakz 0:4b76b1dc05cd 59 sensorRegister.acstat.reg = sensorRegister.registers[1];
hudakz 0:4b76b1dc05cd 60 sensorRegister.aval.reg = sensorRegister.registers[2];
hudakz 0:4b76b1dc05cd 61 sensorRegister.aspd.reg = sensorRegister.registers[3];
hudakz 0:4b76b1dc05cd 62 sensorRegister.arev.reg = sensorRegister.registers[4];
hudakz 0:4b76b1dc05cd 63 sensorRegister.fsync.reg = sensorRegister.registers[5];
hudakz 0:4b76b1dc05cd 64 sensorRegister.mod1.reg = sensorRegister.registers[6];
hudakz 0:4b76b1dc05cd 65 sensorRegister.sil.reg = sensorRegister.registers[7];
hudakz 0:4b76b1dc05cd 66 sensorRegister.mod2.reg = sensorRegister.registers[8];
hudakz 0:4b76b1dc05cd 67 sensorRegister.mod3.reg = sensorRegister.registers[9];
hudakz 0:4b76b1dc05cd 68 sensorRegister.offx.reg = sensorRegister.registers[10];
hudakz 0:4b76b1dc05cd 69 sensorRegister.offy.reg = sensorRegister.registers[11];
hudakz 0:4b76b1dc05cd 70 sensorRegister.synch.reg = sensorRegister.registers[12];
hudakz 0:4b76b1dc05cd 71 sensorRegister.ifab.reg = sensorRegister.registers[13];
hudakz 0:4b76b1dc05cd 72 sensorRegister.mod4.reg = sensorRegister.registers[14];
hudakz 0:4b76b1dc05cd 73 sensorRegister.tcoy.reg = sensorRegister.registers[15];
hudakz 0:4b76b1dc05cd 74 sensorRegister.adc.ADCX = sensorRegister.registers[16];
hudakz 0:4b76b1dc05cd 75 sensorRegister.adc.ADCY = sensorRegister.registers[17];
hudakz 0:4b76b1dc05cd 76 sensorRegister.dmag.reg = sensorRegister.registers[18];
hudakz 0:4b76b1dc05cd 77 sensorRegister.traw.reg = sensorRegister.registers[19];
hudakz 0:4b76b1dc05cd 78 sensorRegister.iifcnt.reg = sensorRegister.registers[20];
hudakz 0:4b76b1dc05cd 79 sensorRegister.t250.reg = sensorRegister.registers[21];
hudakz 0:4b76b1dc05cd 80
hudakz 0:4b76b1dc05cd 81 return (status);
hudakz 0:4b76b1dc05cd 82 }
hudakz 0:4b76b1dc05cd 83
hudakz 0:4b76b1dc05cd 84 errorTypes TLE5012B_REG::identifyInterfaceType()
hudakz 0:4b76b1dc05cd 85 {
hudakz 0:4b76b1dc05cd 86 errorTypes status = readSensorType();
hudakz 0:4b76b1dc05cd 87 if (status != NO_ERROR) {
hudakz 0:4b76b1dc05cd 88 return (status);
hudakz 0:4b76b1dc05cd 89 }
hudakz 0:4b76b1dc05cd 90
hudakz 0:4b76b1dc05cd 91 sensorRegister.stat.fetch_SNR(sensorRegister.stat.reg);
hudakz 0:4b76b1dc05cd 92
hudakz 0:4b76b1dc05cd 93 sensorRegister.mod1.fetch_IIFMOD(sensorRegister.mod1.reg);
hudakz 0:4b76b1dc05cd 94 sensorRegister.mod1.fetch_DSPUHOLD(sensorRegister.mod1.reg);
hudakz 0:4b76b1dc05cd 95 sensorRegister.mod1.fetch_CLKSEL(sensorRegister.mod1.reg);
hudakz 0:4b76b1dc05cd 96 sensorRegister.mod1.fetch_FIRMD(sensorRegister.mod1.reg);
hudakz 0:4b76b1dc05cd 97
hudakz 0:4b76b1dc05cd 98 sensorRegister.mod2.fetch_AUTOCAL(sensorRegister.mod2.reg);
hudakz 0:4b76b1dc05cd 99 sensorRegister.mod2.fetch_PREDICT(sensorRegister.mod2.reg);
hudakz 0:4b76b1dc05cd 100 sensorRegister.mod2.fetch_ANGDIR(sensorRegister.mod2.reg);
hudakz 0:4b76b1dc05cd 101 sensorRegister.mod2.fetch_ANGRANGE(sensorRegister.mod2.reg);
hudakz 0:4b76b1dc05cd 102
hudakz 0:4b76b1dc05cd 103 sensorRegister.mod3.fetch_PADDRV(sensorRegister.mod3.reg);
hudakz 0:4b76b1dc05cd 104 sensorRegister.mod3.fetch_SSCOD(sensorRegister.mod3.reg);
hudakz 0:4b76b1dc05cd 105 sensorRegister.mod3.fetch_SPIKEF(sensorRegister.mod3.reg);
hudakz 0:4b76b1dc05cd 106
hudakz 0:4b76b1dc05cd 107 sensorRegister.ifab.fetch_IFADHYST(sensorRegister.ifab.reg);
hudakz 0:4b76b1dc05cd 108 sensorRegister.ifab.fetch_IFABOD(sensorRegister.ifab.reg);
hudakz 0:4b76b1dc05cd 109 sensorRegister.ifab.fetch_FIRUDR(sensorRegister.ifab.reg);
hudakz 0:4b76b1dc05cd 110
hudakz 0:4b76b1dc05cd 111 sensorRegister.tcoy.fetch_SBIST(sensorRegister.tcoy.reg);
hudakz 0:4b76b1dc05cd 112
hudakz 0:4b76b1dc05cd 113 sensorRegister.mod4.fetch_IFMD(sensorRegister.mod4.reg);
hudakz 0:4b76b1dc05cd 114 sensorRegister.mod4.fetch_IFABRES(sensorRegister.mod4.reg);
hudakz 0:4b76b1dc05cd 115 sensorRegister.mod4.fetch_HSMPLP(sensorRegister.mod4.reg);
hudakz 0:4b76b1dc05cd 116
hudakz 0:4b76b1dc05cd 117 _identify();
hudakz 0:4b76b1dc05cd 118
hudakz 0:4b76b1dc05cd 119 return (status);
hudakz 0:4b76b1dc05cd 120 }
hudakz 0:4b76b1dc05cd 121
hudakz 0:4b76b1dc05cd 122 void TLE5012B_REG::_identify(){
hudakz 0:4b76b1dc05cd 123
hudakz 0:4b76b1dc05cd 124 switch (sensorRegister.mod4.IFMD)
hudakz 0:4b76b1dc05cd 125 {
hudakz 0:4b76b1dc05cd 126 case IIF:
hudakz 0:4b76b1dc05cd 127 sensorRegister.interface = IIF;
hudakz 0:4b76b1dc05cd 128 strcpy(sensorRegister.interfaceName, "IIF");
hudakz 0:4b76b1dc05cd 129 sensorRegister.sensorBoard = TLE5012B_E1000;
hudakz 0:4b76b1dc05cd 130 strcpy(sensorRegister.sensorName, "TLE5012B_E1000");
hudakz 0:4b76b1dc05cd 131 break;
hudakz 0:4b76b1dc05cd 132 case PWM:
hudakz 0:4b76b1dc05cd 133 sensorRegister.interface = PWM;
hudakz 0:4b76b1dc05cd 134 strcpy(sensorRegister.interfaceName, "PWM");
hudakz 0:4b76b1dc05cd 135 if (sensorRegister.ifab.FIRUDR == 0x0 && sensorRegister.ifab.IFABOD == 0x0 )
hudakz 0:4b76b1dc05cd 136 {
hudakz 0:4b76b1dc05cd 137 sensorRegister.sensorBoard = TLE5012B_E5000;
hudakz 0:4b76b1dc05cd 138 strcpy(sensorRegister.sensorName, "TLE5012B_E5000");
hudakz 0:4b76b1dc05cd 139 }else{
hudakz 0:4b76b1dc05cd 140 sensorRegister.sensorBoard = TLE5012B_E5020;
hudakz 0:4b76b1dc05cd 141 strcpy(sensorRegister.sensorName, "TLE5012B_E5020");
hudakz 0:4b76b1dc05cd 142 }
hudakz 0:4b76b1dc05cd 143 break;
hudakz 0:4b76b1dc05cd 144 case HSM:
hudakz 0:4b76b1dc05cd 145 strcpy(sensorRegister.interfaceName, "HSM");
hudakz 0:4b76b1dc05cd 146 sensorRegister.interface = HSM;
hudakz 0:4b76b1dc05cd 147 sensorRegister.sensorBoard = TLE5012B_E3005;
hudakz 0:4b76b1dc05cd 148 strcpy(sensorRegister.sensorName, "TLE5012B_E3005");
hudakz 0:4b76b1dc05cd 149 break;
hudakz 0:4b76b1dc05cd 150 case SPC:
hudakz 0:4b76b1dc05cd 151 strcpy(sensorRegister.interfaceName, "SPC");
hudakz 0:4b76b1dc05cd 152 sensorRegister.interface = SPC;
hudakz 0:4b76b1dc05cd 153 sensorRegister.sensorBoard = TLE5012B_E9000;
hudakz 0:4b76b1dc05cd 154 strcpy(sensorRegister.sensorName, "TLE5012B_E9000");
hudakz 0:4b76b1dc05cd 155 break;
hudakz 0:4b76b1dc05cd 156 }
hudakz 0:4b76b1dc05cd 157 }
hudakz 0:4b76b1dc05cd 158
hudakz 0:4b76b1dc05cd 159 errorTypes TLE5012B_REG::writeInterfaceType(interfaceType iface)
hudakz 0:4b76b1dc05cd 160 {
hudakz 0:4b76b1dc05cd 161 uint16_t rawData = 0;
hudakz 0:4b76b1dc05cd 162
hudakz 0:4b76b1dc05cd 163 errorTypes status = readIntMode4(rawData);
hudakz 0:4b76b1dc05cd 164 if (status != NO_ERROR) {
hudakz 0:4b76b1dc05cd 165 return (status);
hudakz 0:4b76b1dc05cd 166 }
hudakz 0:4b76b1dc05cd 167
hudakz 0:4b76b1dc05cd 168 rawData &= ~(1UL << 0);
hudakz 0:4b76b1dc05cd 169 rawData &= ~(1UL << 1);
hudakz 0:4b76b1dc05cd 170 rawData = rawData | iface;
hudakz 0:4b76b1dc05cd 171 status = writeIntMode4(rawData);
hudakz 0:4b76b1dc05cd 172
hudakz 0:4b76b1dc05cd 173 return (status);
hudakz 0:4b76b1dc05cd 174 }
hudakz 0:4b76b1dc05cd 175
hudakz 0:4b76b1dc05cd 176 errorTypes TLE5012B_REG::resetFirmware()
hudakz 0:4b76b1dc05cd 177 {
hudakz 0:4b76b1dc05cd 178 uint16_t rawData = 0x401;
hudakz 0:4b76b1dc05cd 179 errorTypes status = writeActivationStatus(rawData);
hudakz 0:4b76b1dc05cd 180 return (status);
hudakz 0:4b76b1dc05cd 181 }
hudakz 0:4b76b1dc05cd 182
hudakz 0:4b76b1dc05cd 183 errorTypes TLE5012B_REG::setCalibration(calibrationMode calMode)
hudakz 0:4b76b1dc05cd 184 {
hudakz 0:4b76b1dc05cd 185 uint16_t rawData = 0;
hudakz 0:4b76b1dc05cd 186
hudakz 0:4b76b1dc05cd 187 errorTypes status = readIntMode2(rawData);
hudakz 0:4b76b1dc05cd 188 if (status != NO_ERROR) {
hudakz 0:4b76b1dc05cd 189 return (status);
hudakz 0:4b76b1dc05cd 190 }
hudakz 0:4b76b1dc05cd 191
hudakz 0:4b76b1dc05cd 192 rawData &= ~(1UL << 0);
hudakz 0:4b76b1dc05cd 193 rawData &= ~(1UL << 1);
hudakz 0:4b76b1dc05cd 194 rawData = rawData | calMode;
hudakz 0:4b76b1dc05cd 195 status = writeIntMode2(rawData);
hudakz 0:4b76b1dc05cd 196
hudakz 0:4b76b1dc05cd 197 return (status);
hudakz 0:4b76b1dc05cd 198 }
hudakz 0:4b76b1dc05cd 199