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