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:01:49 2020 +0000
Revision:
0:4b76b1dc05cd
Child:
1:220a2496380e
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_SPI.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, _mosi, 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 #include "TLE5012B_SPI.h"
hudakz 0:4b76b1dc05cd 46
hudakz 0:4b76b1dc05cd 47 /**
hudakz 0:4b76b1dc05cd 48 * @brief Creates an SPI interface for SSC communication with TLE5012B sensor.
hudakz 0:4b76b1dc05cd 49 * @note
hudakz 0:4b76b1dc05cd 50 * @param
hudakz 0:4b76b1dc05cd 51 * @retval
hudakz 0:4b76b1dc05cd 52 */
hudakz 0:4b76b1dc05cd 53 TLE5012B_SPI::TLE5012B_SPI(PinName mosi, PinName miso, PinName sck) :
hudakz 0:4b76b1dc05cd 54 _mosiPin(mosi),
hudakz 0:4b76b1dc05cd 55 _misoPin(miso),
hudakz 0:4b76b1dc05cd 56 _sckPin(sck),
hudakz 0:4b76b1dc05cd 57 _mosi(mosi),
hudakz 0:4b76b1dc05cd 58 _sck(sck),
hudakz 0:4b76b1dc05cd 59 _spi(mosi, miso, sck)
hudakz 0:4b76b1dc05cd 60 { }
hudakz 0:4b76b1dc05cd 61
hudakz 0:4b76b1dc05cd 62 /**
hudakz 0:4b76b1dc05cd 63 * @brief Configures SPI interface for cummunication with TLE5012B chip.
hudakz 0:4b76b1dc05cd 64 * @note
hudakz 0:4b76b1dc05cd 65 * @param
hudakz 0:4b76b1dc05cd 66 * @retval
hudakz 0:4b76b1dc05cd 67 */
hudakz 0:4b76b1dc05cd 68 void TLE5012B_SPI::begin(DigitalOut* cs)
hudakz 0:4b76b1dc05cd 69 {
hudakz 0:4b76b1dc05cd 70 *cs = 1;
hudakz 0:4b76b1dc05cd 71
hudakz 0:4b76b1dc05cd 72 _spi.format(16, 1); // 16 bits, MODE1, MSB first
hudakz 0:4b76b1dc05cd 73 _spi.frequency(8000000); // 8MHz (maximum supported by TLE5012B)
hudakz 0:4b76b1dc05cd 74 }
hudakz 0:4b76b1dc05cd 75
hudakz 0:4b76b1dc05cd 76 /**
hudakz 0:4b76b1dc05cd 77 * @brief Triggers an update.
hudakz 0:4b76b1dc05cd 78 * @note
hudakz 0:4b76b1dc05cd 79 * @param
hudakz 0:4b76b1dc05cd 80 * @retval
hudakz 0:4b76b1dc05cd 81 */
hudakz 0:4b76b1dc05cd 82 void TLE5012B_SPI::triggerUpdate()
hudakz 0:4b76b1dc05cd 83 {
hudakz 0:4b76b1dc05cd 84 _sck = 0;
hudakz 0:4b76b1dc05cd 85 _mosi = 1;
hudakz 0:4b76b1dc05cd 86 }
hudakz 0:4b76b1dc05cd 87
hudakz 0:4b76b1dc05cd 88 /**
hudakz 0:4b76b1dc05cd 89 * @brief Sends command(s) to the TLE5012B sensor and receives data.
hudakz 0:4b76b1dc05cd 90 * @note
hudakz 0:4b76b1dc05cd 91 * @param
hudakz 0:4b76b1dc05cd 92 * @retval
hudakz 0:4b76b1dc05cd 93 */
hudakz 0:4b76b1dc05cd 94 void TLE5012B_SPI::sendReceiveSpi(DigitalOut* cs, uint16_t* tx, uint16_t txLen, uint16_t* rx, uint16_t rxLen)
hudakz 0:4b76b1dc05cd 95 {
hudakz 0:4b76b1dc05cd 96 // Send txData over SPI & receive dummy data
hudakz 0:4b76b1dc05cd 97
hudakz 0:4b76b1dc05cd 98 //_sck = 0;
hudakz 0:4b76b1dc05cd 99 *cs = 0;
hudakz 0:4b76b1dc05cd 100 //_mosi.output();
hudakz 0:4b76b1dc05cd 101 wait_us(1);
hudakz 0:4b76b1dc05cd 102 for (uint16_t i = 0; i < txLen; i++) {
hudakz 0:4b76b1dc05cd 103
hudakz 0:4b76b1dc05cd 104 _spi.write(tx[i]);
hudakz 0:4b76b1dc05cd 105 //write(tx[i]);
hudakz 0:4b76b1dc05cd 106 }
hudakz 0:4b76b1dc05cd 107
hudakz 0:4b76b1dc05cd 108 wait_us(2);
hudakz 0:4b76b1dc05cd 109
hudakz 0:4b76b1dc05cd 110 // Send dummy bytes over SPI & receive data
hudakz 0:4b76b1dc05cd 111 //_mosi.input();
hudakz 0:4b76b1dc05cd 112 wait_us(1);
hudakz 0:4b76b1dc05cd 113 for (uint16_t i = 0; i < rxLen; i++) {
hudakz 0:4b76b1dc05cd 114
hudakz 0:4b76b1dc05cd 115 rx[i] = _spi.write(SPI_FILL_WORD);
hudakz 0:4b76b1dc05cd 116 //rx[i] = read();
hudakz 0:4b76b1dc05cd 117 }
hudakz 0:4b76b1dc05cd 118
hudakz 0:4b76b1dc05cd 119 *cs = 1;
hudakz 0:4b76b1dc05cd 120 //_sck = 0;
hudakz 0:4b76b1dc05cd 121 }
hudakz 0:4b76b1dc05cd 122
hudakz 0:4b76b1dc05cd 123 /**
hudakz 0:4b76b1dc05cd 124 * @brief
hudakz 0:4b76b1dc05cd 125 * @note
hudakz 0:4b76b1dc05cd 126 * @param
hudakz 0:4b76b1dc05cd 127 * @retval
hudakz 0:4b76b1dc05cd 128 */
hudakz 0:4b76b1dc05cd 129 inline void TLE5012B_SPI::writeBit(int value)
hudakz 0:4b76b1dc05cd 130 {
hudakz 0:4b76b1dc05cd 131 _sck = 0;
hudakz 0:4b76b1dc05cd 132 wait_us(1);
hudakz 0:4b76b1dc05cd 133 _sck = 1;
hudakz 0:4b76b1dc05cd 134 wait_us(1);
hudakz 0:4b76b1dc05cd 135 if (value != 0) {
hudakz 0:4b76b1dc05cd 136 _mosi = 1;
hudakz 0:4b76b1dc05cd 137 }
hudakz 0:4b76b1dc05cd 138 else {
hudakz 0:4b76b1dc05cd 139 _mosi = 0;
hudakz 0:4b76b1dc05cd 140 }
hudakz 0:4b76b1dc05cd 141
hudakz 0:4b76b1dc05cd 142 wait_us(1);
hudakz 0:4b76b1dc05cd 143 _sck = 0;
hudakz 0:4b76b1dc05cd 144 }
hudakz 0:4b76b1dc05cd 145
hudakz 0:4b76b1dc05cd 146 /**
hudakz 0:4b76b1dc05cd 147 * @brief
hudakz 0:4b76b1dc05cd 148 * @note
hudakz 0:4b76b1dc05cd 149 * @param
hudakz 0:4b76b1dc05cd 150 * @retval
hudakz 0:4b76b1dc05cd 151 */
hudakz 0:4b76b1dc05cd 152 inline int TLE5012B_SPI::readBit()
hudakz 0:4b76b1dc05cd 153 {
hudakz 0:4b76b1dc05cd 154 int out = 0;
hudakz 0:4b76b1dc05cd 155
hudakz 0:4b76b1dc05cd 156 _sck = 0;
hudakz 0:4b76b1dc05cd 157 wait_us(1);
hudakz 0:4b76b1dc05cd 158 _sck = 1;
hudakz 0:4b76b1dc05cd 159
hudakz 0:4b76b1dc05cd 160 wait_us(1);
hudakz 0:4b76b1dc05cd 161 _sck = 0;
hudakz 0:4b76b1dc05cd 162 if (_mosi.read() != 0) {
hudakz 0:4b76b1dc05cd 163 out = 1;
hudakz 0:4b76b1dc05cd 164 }
hudakz 0:4b76b1dc05cd 165
hudakz 0:4b76b1dc05cd 166 return out;
hudakz 0:4b76b1dc05cd 167 }
hudakz 0:4b76b1dc05cd 168
hudakz 0:4b76b1dc05cd 169 /**
hudakz 0:4b76b1dc05cd 170 * @brief
hudakz 0:4b76b1dc05cd 171 * @note
hudakz 0:4b76b1dc05cd 172 * @param
hudakz 0:4b76b1dc05cd 173 * @retval
hudakz 0:4b76b1dc05cd 174 */
hudakz 0:4b76b1dc05cd 175 void TLE5012B_SPI::write(uint16_t word)
hudakz 0:4b76b1dc05cd 176 {
hudakz 0:4b76b1dc05cd 177 for (int i = 0; i < 16; ++i) {
hudakz 0:4b76b1dc05cd 178 writeBit(word & 0x8000);
hudakz 0:4b76b1dc05cd 179 word <<= 1;
hudakz 0:4b76b1dc05cd 180 }
hudakz 0:4b76b1dc05cd 181 }
hudakz 0:4b76b1dc05cd 182
hudakz 0:4b76b1dc05cd 183 /**
hudakz 0:4b76b1dc05cd 184 * @brief
hudakz 0:4b76b1dc05cd 185 * @note
hudakz 0:4b76b1dc05cd 186 * @param
hudakz 0:4b76b1dc05cd 187 * @retval
hudakz 0:4b76b1dc05cd 188 */
hudakz 0:4b76b1dc05cd 189 uint16_t TLE5012B_SPI::read()
hudakz 0:4b76b1dc05cd 190 {
hudakz 0:4b76b1dc05cd 191 uint16_t word = 0;
hudakz 0:4b76b1dc05cd 192
hudakz 0:4b76b1dc05cd 193 for (int i = 0; i < 16; ++i) {
hudakz 0:4b76b1dc05cd 194 word <<= 1;
hudakz 0:4b76b1dc05cd 195 word |= readBit();
hudakz 0:4b76b1dc05cd 196 }
hudakz 0:4b76b1dc05cd 197
hudakz 0:4b76b1dc05cd 198 return word;
hudakz 0:4b76b1dc05cd 199 }
hudakz 0:4b76b1dc05cd 200
hudakz 0:4b76b1dc05cd 201 /**
hudakz 0:4b76b1dc05cd 202 * @brief
hudakz 0:4b76b1dc05cd 203 * @note
hudakz 0:4b76b1dc05cd 204 * @param
hudakz 0:4b76b1dc05cd 205 * @retval
hudakz 0:4b76b1dc05cd 206 */
hudakz 0:4b76b1dc05cd 207 void TLE5012B_SPI::requestNewData(DigitalOut* cs)
hudakz 0:4b76b1dc05cd 208 {
hudakz 0:4b76b1dc05cd 209 _sck = 0;
hudakz 0:4b76b1dc05cd 210 *cs = 0;
hudakz 0:4b76b1dc05cd 211 wait_us(2);
hudakz 0:4b76b1dc05cd 212 *cs = 1;
hudakz 0:4b76b1dc05cd 213 wait_us(2);
hudakz 0:4b76b1dc05cd 214 }