Now with licence header and working for output of DROPSAW project

Committer:
cnckiwi31
Date:
Mon Oct 26 08:26:53 2020 +0000
Revision:
6:1b84babf3042
Parent:
5:9df31d15f3fa
Prepared for documentation with copyright boilerplate added

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cnckiwi31 6:1b84babf3042 1 /* Copyright 2017 Martijn Grootens
cnckiwi31 6:1b84babf3042 2
cnckiwi31 6:1b84babf3042 3 Licensed under the Apache License, Version 2.0 (the "License");
cnckiwi31 6:1b84babf3042 4 you may not use this file except in compliance with the License.
cnckiwi31 6:1b84babf3042 5 You may obtain a copy of the License at
cnckiwi31 6:1b84babf3042 6
cnckiwi31 6:1b84babf3042 7 http://www.apache.org/licenses/LICENSE-2.0
cnckiwi31 6:1b84babf3042 8
cnckiwi31 6:1b84babf3042 9 Unless required by applicable law or agreed to in writing, software
cnckiwi31 6:1b84babf3042 10 distributed under the License is distributed on an "AS IS" BASIS,
cnckiwi31 6:1b84babf3042 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
cnckiwi31 6:1b84babf3042 12 See the License for the specific language governing permissions and
cnckiwi31 6:1b84babf3042 13 limitations under the License.
cnckiwi31 6:1b84babf3042 14 */
cnckiwi31 6:1b84babf3042 15
megrootens 0:723d48642d5c 16 #ifndef _AS5048_H_
megrootens 0:723d48642d5c 17 #define _AS5048_H_
megrootens 0:723d48642d5c 18
megrootens 0:723d48642d5c 19 #include "mbed.h"
megrootens 0:723d48642d5c 20 /**
megrootens 0:723d48642d5c 21 * Interfacing with the AMS AS5048A magnetic rotary sensor using SPI protocol
megrootens 0:723d48642d5c 22 * AS5048 uses 16-bit transfer;
megrootens 0:723d48642d5c 23 * We use two 8-bit transfers for compatibility with 8-bit SPI master devices
megrootens 0:723d48642d5c 24 * SPI protocol:
megrootens 0:723d48642d5c 25 * Mode = 1:
megrootens 0:723d48642d5c 26 * clock polarity = 0 --> clock pulse is high
megrootens 0:723d48642d5c 27 * clock phase = 1 --> sample on falling edge of clock pulse
megrootens 0:723d48642d5c 28 * Code was succesfully tested on the FRDM KL25Z and K22F. The same code fails
megrootens 0:723d48642d5c 29 * on the K64F for some reason. Sampling using a logic analyzer does however
megrootens 0:723d48642d5c 30 * show the same results for al three boards.
megrootens 0:723d48642d5c 31 */
cnckiwi31 6:1b84babf3042 32 class As5048
cnckiwi31 6:1b84babf3042 33 {
cnckiwi31 6:1b84babf3042 34
megrootens 0:723d48642d5c 35 public:
megrootens 0:723d48642d5c 36
megrootens 4:56d59ce73270 37 static const int kNumSensorBits = 14; // 14-bits sensor
megrootens 4:56d59ce73270 38 static const uint16_t kCountsPerRev = 0x4000; // 2**NUM_SENSOR_BITS
megrootens 4:56d59ce73270 39 static const uint16_t kMask = 0x3FFF; // 2**NUM_SENSOR_BITS - 1
megrootens 4:56d59ce73270 40 static const int kParity = 1; // even parity
cnckiwi31 6:1b84babf3042 41
megrootens 4:56d59ce73270 42 static const int kSpiFrequency = 1000000; // AS5048 max 10 MHz
megrootens 4:56d59ce73270 43 static const int kSpiBitsPerTransfer = 8;
megrootens 4:56d59ce73270 44 static const int kSpiMode = 1;
cnckiwi31 6:1b84babf3042 45
megrootens 4:56d59ce73270 46 static const float kDegPerRev = 360.0f; // 360 degrees/rev
megrootens 4:56d59ce73270 47 static const float kRadPerRev = 6.28318530718f; // 2*pi rad/rev
megrootens 4:56d59ce73270 48
megrootens 3:579e12eda4e6 49 // AS5048 flags
megrootens 3:579e12eda4e6 50 typedef enum {
megrootens 3:579e12eda4e6 51 AS_FLAG_PARITY = 0x8000,
megrootens 3:579e12eda4e6 52 AS_FLAG_READ = 0x4000,
megrootens 3:579e12eda4e6 53 } As5048Flag;
cnckiwi31 6:1b84babf3042 54
megrootens 3:579e12eda4e6 55 // AS5048 commands
megrootens 3:579e12eda4e6 56 typedef enum {
megrootens 3:579e12eda4e6 57 AS_CMD_NOP = 0x0000,
megrootens 3:579e12eda4e6 58 AS_CMD_ERROR = 0x0001 | AS_FLAG_READ, // Reads error register of sensor and clear error flags
megrootens 3:579e12eda4e6 59 AS_CMD_DIAGNOSTICS = 0x3FFD | AS_FLAG_READ, // Reads automatic gain control and diagnostics info
megrootens 3:579e12eda4e6 60 AS_CMD_MAGNITUDE = 0x3FFE | AS_FLAG_READ,
megrootens 3:579e12eda4e6 61 AS_CMD_ANGLE = 0x3FFF | AS_FLAG_PARITY | AS_FLAG_READ,
megrootens 3:579e12eda4e6 62 } As5048Command;
cnckiwi31 6:1b84babf3042 63
megrootens 3:579e12eda4e6 64 // AS5048 diagnostics
megrootens 3:579e12eda4e6 65 typedef enum {
megrootens 3:579e12eda4e6 66 AS_DIAG_CORDIC_OVERFLOW = 0x0200,
megrootens 3:579e12eda4e6 67 AS_DIAG_HIGH_MAGNETIC = 0x0400,
megrootens 3:579e12eda4e6 68 AS_DIAG_LOW_MAGNETIC = 0x0800,
megrootens 3:579e12eda4e6 69 } As5048Diagnostics;
megrootens 3:579e12eda4e6 70
megrootens 0:723d48642d5c 71 /**
megrootens 0:723d48642d5c 72 * Creates an object of num_sensors daisy chained AS5048 sensors;
megrootens 0:723d48642d5c 73 * default number of sensors in chain is 1
megrootens 0:723d48642d5c 74 * @param mosi: pinname of the mosi pin of the spi communication
megrootens 0:723d48642d5c 75 * @param miso: pinname of the miso pin of the spi communication
megrootens 0:723d48642d5c 76 * @param sck: pinname of the clock pin of the spi communication
megrootens 0:723d48642d5c 77 * @param cs: pinname of the chip select pin of the spi communication
megrootens 0:723d48642d5c 78 * @param num_sensors = 1: number of sensors in daisy chain
megrootens 0:723d48642d5c 79 */
megrootens 0:723d48642d5c 80 As5048(PinName mosi, PinName miso, PinName sck, PinName cs, int num_sensors = 1):
megrootens 0:723d48642d5c 81 kNumSensors_(num_sensors),
megrootens 0:723d48642d5c 82 chip_(cs),
cnckiwi31 6:1b84babf3042 83 spi_(mosi, miso, sck)
megrootens 0:723d48642d5c 84 {
megrootens 0:723d48642d5c 85 DeselectChip();
cnckiwi31 6:1b84babf3042 86
megrootens 0:723d48642d5c 87 spi_.format(kSpiBitsPerTransfer, kSpiMode);
megrootens 0:723d48642d5c 88 spi_.frequency(kSpiFrequency);
cnckiwi31 6:1b84babf3042 89
megrootens 0:723d48642d5c 90 read_buffer_ = new uint16_t[kNumSensors_];
megrootens 0:723d48642d5c 91 angle_buffer_ = new uint16_t[kNumSensors_];
megrootens 0:723d48642d5c 92 angle_offset_ = new uint16_t[kNumSensors_];
megrootens 1:94b48453d13a 93 directions_ = new bool[kNumSensors_];
cnckiwi31 6:1b84babf3042 94
megrootens 0:723d48642d5c 95 for (int i=0; i<kNumSensors_; ++i) {
megrootens 0:723d48642d5c 96 read_buffer_[i] = 0;
megrootens 0:723d48642d5c 97 angle_buffer_[i] = 0;
megrootens 0:723d48642d5c 98 angle_offset_[i] = 0;
megrootens 1:94b48453d13a 99 directions_[i] = true;
megrootens 0:723d48642d5c 100 }
cnckiwi31 6:1b84babf3042 101
megrootens 0:723d48642d5c 102 last_command_ = AS_CMD_NOP;
megrootens 0:723d48642d5c 103 }
megrootens 0:723d48642d5c 104
cnckiwi31 6:1b84babf3042 105
megrootens 0:723d48642d5c 106 /**
megrootens 0:723d48642d5c 107 * Destructor, memory deallocation
megrootens 0:723d48642d5c 108 */
cnckiwi31 6:1b84babf3042 109 ~As5048()
megrootens 2:111641f7e672 110 {
megrootens 0:723d48642d5c 111 delete [] read_buffer_;
megrootens 0:723d48642d5c 112 delete [] angle_buffer_;
megrootens 0:723d48642d5c 113 delete [] angle_offset_;
megrootens 1:94b48453d13a 114 delete [] directions_;
megrootens 0:723d48642d5c 115 }
cnckiwi31 6:1b84babf3042 116
megrootens 0:723d48642d5c 117 /**
megrootens 0:723d48642d5c 118 * Parity check
megrootens 0:723d48642d5c 119 * @param n: integer to check
megrootens 0:723d48642d5c 120 * @return: true if ok
megrootens 0:723d48642d5c 121 */
cnckiwi31 6:1b84babf3042 122 static bool CheckParity(int n)
megrootens 2:111641f7e672 123 {
megrootens 0:723d48642d5c 124 int parity = n;
megrootens 0:723d48642d5c 125 for(int i=1; i <= kNumSensorBits+1; ++i) {
megrootens 0:723d48642d5c 126 n >>= 1;
megrootens 0:723d48642d5c 127 parity ^= n;
megrootens 0:723d48642d5c 128 }
megrootens 0:723d48642d5c 129 return (parity & kParity) == 0;
megrootens 0:723d48642d5c 130 }
cnckiwi31 6:1b84babf3042 131
megrootens 0:723d48642d5c 132 /**
megrootens 0:723d48642d5c 133 * Update the buffer with angular measurements
megrootens 0:723d48642d5c 134 * NOTE 1:
megrootens 0:723d48642d5c 135 * If the last command sent through Transfer was *not* AS_CMD_ANGLE
megrootens 0:723d48642d5c 136 * then we need an additional Transfer; this takes more time!
megrootens 0:723d48642d5c 137 * This should not occur, since Transfer is not *yet* used elsewhere.
megrootens 0:723d48642d5c 138 * NOTE 2:
cnckiwi31 6:1b84babf3042 139 * We run a parity check on the results from the transfer. We only
megrootens 0:723d48642d5c 140 * update the angle_buffer_ with values that pass the parity check.
megrootens 0:723d48642d5c 141 * Measurement using Timer on K64F for last_command_ == AS_CMD_ANGLE
megrootens 0:723d48642d5c 142 * shows this function takes 87 or 88 us.
megrootens 0:723d48642d5c 143 */
cnckiwi31 6:1b84babf3042 144 void UpdateAngleBuffer()
megrootens 2:111641f7e672 145 {
megrootens 0:723d48642d5c 146 // ensure that the new results indeed will be angles
megrootens 0:723d48642d5c 147 if (last_command_ != AS_CMD_ANGLE) {
megrootens 0:723d48642d5c 148 Transfer(AS_CMD_ANGLE);
megrootens 0:723d48642d5c 149 }
cnckiwi31 6:1b84babf3042 150
megrootens 0:723d48642d5c 151 // update the read buffer
cnckiwi31 6:1b84babf3042 152 Transfer(AS_CMD_ANGLE);
cnckiwi31 6:1b84babf3042 153
megrootens 0:723d48642d5c 154 // update the angle buffer with parity checked values
megrootens 0:723d48642d5c 155 for (int i=0; i<kNumSensors_; ++i) {
megrootens 0:723d48642d5c 156 if (CheckParity(read_buffer_[i])) {
megrootens 0:723d48642d5c 157 // only update angles when parity is correct
megrootens 0:723d48642d5c 158 angle_buffer_[i] = read_buffer_[i];
megrootens 0:723d48642d5c 159 }
megrootens 0:723d48642d5c 160 }
megrootens 0:723d48642d5c 161 }
cnckiwi31 6:1b84babf3042 162
megrootens 0:723d48642d5c 163 /**
megrootens 0:723d48642d5c 164 * @return: pointer to read_buffer_
megrootens 0:723d48642d5c 165 */
cnckiwi31 6:1b84babf3042 166 const uint16_t* get_read_buffer()
cnckiwi31 6:1b84babf3042 167 {
cnckiwi31 6:1b84babf3042 168 return read_buffer_;
cnckiwi31 6:1b84babf3042 169 }
cnckiwi31 6:1b84babf3042 170
megrootens 0:723d48642d5c 171 /**
megrootens 0:723d48642d5c 172 * @return: pointer to angle_buffer_
megrootens 0:723d48642d5c 173 */
cnckiwi31 6:1b84babf3042 174 const uint16_t* get_angle_buffer()
cnckiwi31 6:1b84babf3042 175 {
cnckiwi31 6:1b84babf3042 176 return angle_buffer_;
cnckiwi31 6:1b84babf3042 177 }
cnckiwi31 6:1b84babf3042 178
megrootens 0:723d48642d5c 179 /**
megrootens 0:723d48642d5c 180 * @return: pointer to angle_offet_
megrootens 0:723d48642d5c 181 */
cnckiwi31 6:1b84babf3042 182 const uint16_t* get_angle_offset()
cnckiwi31 6:1b84babf3042 183 {
cnckiwi31 6:1b84babf3042 184 return angle_offset_;
cnckiwi31 6:1b84babf3042 185 }
cnckiwi31 6:1b84babf3042 186
megrootens 0:723d48642d5c 187 /**
megrootens 1:94b48453d13a 188 * @return: pointer to directions_
megrootens 1:94b48453d13a 189 */
cnckiwi31 6:1b84babf3042 190 const bool * get_directions_()
cnckiwi31 6:1b84babf3042 191 {
cnckiwi31 6:1b84babf3042 192 return directions_;
cnckiwi31 6:1b84babf3042 193 }
cnckiwi31 6:1b84babf3042 194
megrootens 1:94b48453d13a 195 /**
megrootens 0:723d48642d5c 196 * You get the angles from two UpdateAngleBuffer() calls before
megrootens 0:723d48642d5c 197 * @return: 14 bits absolute position
megrootens 0:723d48642d5c 198 */
megrootens 2:111641f7e672 199 int getAngle(int i_sensor=0)
cnckiwi31 6:1b84babf3042 200 {
megrootens 1:94b48453d13a 201 int ans = ((int) (angle_buffer_[i_sensor] & kMask)) - angle_offset_[i_sensor];
megrootens 1:94b48453d13a 202 return directions_[i_sensor]?ans:-ans;
megrootens 0:723d48642d5c 203 }
cnckiwi31 6:1b84babf3042 204
megrootens 0:723d48642d5c 205 /**
megrootens 0:723d48642d5c 206 * You get the angles from two UpdateAngleBuffer() calls before
megrootens 0:723d48642d5c 207 * @return: revolution ratio in [0,1]
megrootens 0:723d48642d5c 208 */
cnckiwi31 6:1b84babf3042 209 float getAngleRatio(int i_sensor=0)
cnckiwi31 6:1b84babf3042 210 {
cnckiwi31 6:1b84babf3042 211 return (float) getAngle(i_sensor) / kCountsPerRev;
cnckiwi31 6:1b84babf3042 212 }
cnckiwi31 6:1b84babf3042 213
megrootens 0:723d48642d5c 214 /**
megrootens 0:723d48642d5c 215 * You get the angles from two UpdateAngleBuffer() calls before
megrootens 0:723d48642d5c 216 * @return: angle in degrees
megrootens 0:723d48642d5c 217 */
cnckiwi31 6:1b84babf3042 218 float getAngleDegrees(int i_sensor=0)
cnckiwi31 6:1b84babf3042 219 {
cnckiwi31 6:1b84babf3042 220 return getAngleRatio(i_sensor) * kDegPerRev;
cnckiwi31 6:1b84babf3042 221 }
cnckiwi31 6:1b84babf3042 222
megrootens 0:723d48642d5c 223 /**
megrootens 0:723d48642d5c 224 * You get the angles from two UpdateAngleBuffer() calls before
megrootens 0:723d48642d5c 225 * @return: angle in radians
megrootens 0:723d48642d5c 226 */
cnckiwi31 6:1b84babf3042 227 float getAngleRadians(int i_sensor=0)
cnckiwi31 6:1b84babf3042 228 {
cnckiwi31 6:1b84babf3042 229 return getAngleRatio(i_sensor) * kRadPerRev;
cnckiwi31 6:1b84babf3042 230 }
cnckiwi31 6:1b84babf3042 231
megrootens 0:723d48642d5c 232 /**
megrootens 1:94b48453d13a 233 * Set direction for a sensor
megrootens 1:94b48453d13a 234 * @param i_sensor: id of sensor for which the offset is to be set
megrootens 1:94b48453d13a 235 * @param dir: true positive, false negative
megrootens 1:94b48453d13a 236 * @return: true if i_sensor in [0,kNumSensor_)
megrootens 1:94b48453d13a 237 */
cnckiwi31 6:1b84babf3042 238 bool setDirection(int i_sensor, bool dir)
megrootens 2:111641f7e672 239 {
megrootens 1:94b48453d13a 240 if (i_sensor>-1 and i_sensor<kNumSensors_) {
megrootens 1:94b48453d13a 241 directions_[i_sensor] = dir;
megrootens 1:94b48453d13a 242 return true;
megrootens 1:94b48453d13a 243 }
megrootens 1:94b48453d13a 244 return false;
megrootens 1:94b48453d13a 245 }
cnckiwi31 6:1b84babf3042 246
megrootens 1:94b48453d13a 247 /**
megrootens 1:94b48453d13a 248 * Set direction for the first sensor
megrootens 1:94b48453d13a 249 * @param dir: true positive, false negative
megrootens 1:94b48453d13a 250 * @return: true if i_sensor in [0,kNumSensor_)
megrootens 1:94b48453d13a 251 */
cnckiwi31 6:1b84babf3042 252 bool setDirection(bool dir)
megrootens 2:111641f7e672 253 {
megrootens 1:94b48453d13a 254 return setDirection(0,dir);
megrootens 1:94b48453d13a 255 }
cnckiwi31 6:1b84babf3042 256
cnckiwi31 6:1b84babf3042 257
megrootens 1:94b48453d13a 258 /**
megrootens 0:723d48642d5c 259 * Set offset for a sensor
megrootens 0:723d48642d5c 260 * @param i_sensor: id of sensor for which the offset is to be set
megrootens 0:723d48642d5c 261 * @param offset: offset in counts [0,2**14-1]
megrootens 0:723d48642d5c 262 * @return: true if i_sensor in [0,kNumSensor_)
megrootens 0:723d48642d5c 263 */
cnckiwi31 6:1b84babf3042 264 bool setOffset(int i_sensor, uint16_t offset)
megrootens 2:111641f7e672 265 {
megrootens 0:723d48642d5c 266 if (i_sensor>-1 and i_sensor<kNumSensors_) {
megrootens 0:723d48642d5c 267 angle_offset_[i_sensor] = offset;
megrootens 0:723d48642d5c 268 return true;
megrootens 0:723d48642d5c 269 }
megrootens 0:723d48642d5c 270 return false;
megrootens 0:723d48642d5c 271 }
cnckiwi31 6:1b84babf3042 272
megrootens 0:723d48642d5c 273 /**
megrootens 0:723d48642d5c 274 * Set offset for the first sensor
megrootens 0:723d48642d5c 275 * @param offset: offset in counts [0,2**14-1]
megrootens 0:723d48642d5c 276 * @return: true if i_sensor in [0,kNumSensor_)
megrootens 0:723d48642d5c 277 */
cnckiwi31 6:1b84babf3042 278 bool setOffset(uint16_t offset)
cnckiwi31 6:1b84babf3042 279 {
cnckiwi31 6:1b84babf3042 280 return setOffset(0,offset);
cnckiwi31 6:1b84babf3042 281 }
cnckiwi31 6:1b84babf3042 282
megrootens 0:723d48642d5c 283 /**
megrootens 0:723d48642d5c 284 * Set offset for a sensor
megrootens 0:723d48642d5c 285 * @param i_sensor: id of sensor for which the offset is to be set
megrootens 0:723d48642d5c 286 * @param offset_ratio: offset in ratio in [0,1]
megrootens 0:723d48642d5c 287 * @return: true if i_sensor in [0,kNumSensor_)
megrootens 0:723d48642d5c 288 */
cnckiwi31 6:1b84babf3042 289 bool setOffsetRatio (int i_sensor, float offset_ratio)
megrootens 2:111641f7e672 290 {
megrootens 0:723d48642d5c 291 return setOffset(i_sensor,offset_ratio*kCountsPerRev);
megrootens 0:723d48642d5c 292 }
cnckiwi31 6:1b84babf3042 293
megrootens 0:723d48642d5c 294 /**
megrootens 0:723d48642d5c 295 * Set offset for the first sensor
megrootens 0:723d48642d5c 296 * @param offset_ratio: offset in ratio in [0,1]
megrootens 0:723d48642d5c 297 * @return: true if i_sensor in [0,kNumSensor_)
megrootens 0:723d48642d5c 298 */
cnckiwi31 6:1b84babf3042 299 bool setOffsetRatio(float offset_ratio)
cnckiwi31 6:1b84babf3042 300 {
cnckiwi31 6:1b84babf3042 301 return setOffsetRatio(0,offset_ratio);
megrootens 0:723d48642d5c 302 }
cnckiwi31 6:1b84babf3042 303
megrootens 0:723d48642d5c 304 /**
megrootens 0:723d48642d5c 305 * Set offset for a sensor
megrootens 0:723d48642d5c 306 * @param i_sensor: id of sensor for which the offset is to be set
megrootens 0:723d48642d5c 307 * @param offset_degrees: offset in degrees in [0,360]
megrootens 0:723d48642d5c 308 * @return: true if i_sensor in [0,kNumSensor_)
megrootens 0:723d48642d5c 309 */
cnckiwi31 6:1b84babf3042 310 bool setOffsetDegrees(int i_sensor, float offset_degrees)
megrootens 2:111641f7e672 311 {
megrootens 0:723d48642d5c 312 return setOffsetRatio(i_sensor,offset_degrees / kDegPerRev);
megrootens 0:723d48642d5c 313 }
cnckiwi31 6:1b84babf3042 314
megrootens 0:723d48642d5c 315 /**
megrootens 0:723d48642d5c 316 * Set offset for the first sensor
megrootens 0:723d48642d5c 317 * @param offset_degrees: offset in degrees in [0,360]
megrootens 0:723d48642d5c 318 * @return: true if i_sensor in [0,kNumSensor_)
megrootens 0:723d48642d5c 319 */
cnckiwi31 6:1b84babf3042 320 bool setOffsetDegrees(float offset_degrees)
megrootens 2:111641f7e672 321 {
megrootens 0:723d48642d5c 322 return setOffsetDegrees(0, offset_degrees);
megrootens 0:723d48642d5c 323 }
cnckiwi31 6:1b84babf3042 324
megrootens 0:723d48642d5c 325 /**
megrootens 0:723d48642d5c 326 * Set offset for a sensor
megrootens 0:723d48642d5c 327 * @param i_sensor: id of sensor for which the offset is to be set
megrootens 0:723d48642d5c 328 * @param offset_radians: offset in radians in [0,2*pi]
megrootens 0:723d48642d5c 329 * @return: true if i_sensor in [0,kNumSensor_)
megrootens 0:723d48642d5c 330 */
cnckiwi31 6:1b84babf3042 331 bool setOffsetRadians(int i_sensor, float offset_radians)
megrootens 2:111641f7e672 332 {
megrootens 0:723d48642d5c 333 return setOffsetRatio(i_sensor, offset_radians / kRadPerRev);
megrootens 0:723d48642d5c 334 }
cnckiwi31 6:1b84babf3042 335
megrootens 0:723d48642d5c 336 /**
megrootens 0:723d48642d5c 337 * Set offset for the first sensor
megrootens 0:723d48642d5c 338 * @param offset_radians: offset in radians in [0,2*pi]
megrootens 0:723d48642d5c 339 * @return: true if i_sensor in [0,kNumSensor_)
megrootens 0:723d48642d5c 340 */
cnckiwi31 6:1b84babf3042 341 bool setOffsetRadians(float offset_radians)
megrootens 2:111641f7e672 342 {
megrootens 0:723d48642d5c 343 return setOffsetRadians(0, offset_radians);
megrootens 0:723d48642d5c 344 }
megrootens 0:723d48642d5c 345
megrootens 0:723d48642d5c 346 protected:
megrootens 0:723d48642d5c 347
megrootens 0:723d48642d5c 348 /**
megrootens 0:723d48642d5c 349 * Select (low) chip, and wait 1 us (at least 350 ns)
megrootens 0:723d48642d5c 350 */
cnckiwi31 6:1b84babf3042 351 void SelectChip()
cnckiwi31 6:1b84babf3042 352 {
cnckiwi31 6:1b84babf3042 353 chip_.write(0);
cnckiwi31 6:1b84babf3042 354 wait_us(1);
cnckiwi31 6:1b84babf3042 355 }
cnckiwi31 6:1b84babf3042 356
megrootens 0:723d48642d5c 357 /**
megrootens 0:723d48642d5c 358 * Deselect (high) chip, and wait 1 us (at least 350 ns)
megrootens 0:723d48642d5c 359 */
cnckiwi31 6:1b84babf3042 360 void DeselectChip()
cnckiwi31 6:1b84babf3042 361 {
cnckiwi31 6:1b84babf3042 362 chip_.write(1);
cnckiwi31 6:1b84babf3042 363 wait_us(1);
cnckiwi31 6:1b84babf3042 364 }
megrootens 0:723d48642d5c 365
megrootens 0:723d48642d5c 366 /**
megrootens 0:723d48642d5c 367 * SPI transfer between each of the daisy chained sensors
megrootens 0:723d48642d5c 368 * @param cmd: Command to send
megrootens 0:723d48642d5c 369 */
cnckiwi31 6:1b84babf3042 370 void Transfer(As5048Command cmd)
megrootens 2:111641f7e672 371 {
megrootens 0:723d48642d5c 372 SelectChip();
cnckiwi31 6:1b84babf3042 373 for(int i=0; i<kNumSensors_; ++i) {
megrootens 0:723d48642d5c 374 read_buffer_[i] = spi_.write(cmd>>8) << 8;
megrootens 0:723d48642d5c 375 read_buffer_[i] |= spi_.write(cmd & 0x00FF);
megrootens 0:723d48642d5c 376 }
megrootens 0:723d48642d5c 377 DeselectChip();
megrootens 0:723d48642d5c 378 last_command_ = cmd;
megrootens 0:723d48642d5c 379 }
megrootens 0:723d48642d5c 380
megrootens 0:723d48642d5c 381 const int kNumSensors_; // number of sensors in daisy chain
megrootens 0:723d48642d5c 382 DigitalOut chip_; // chip select port
megrootens 0:723d48642d5c 383 SPI spi_; // mbed spi communiation object
cnckiwi31 6:1b84babf3042 384
megrootens 0:723d48642d5c 385 uint16_t* read_buffer_; // buffer for results from last transfer
megrootens 0:723d48642d5c 386 uint16_t* angle_buffer_; // buffer for angle results from last transfer
megrootens 0:723d48642d5c 387 uint16_t* angle_offset_; // offset array for each sensor
megrootens 1:94b48453d13a 388 bool* directions_; // direction true positive, false negative
cnckiwi31 6:1b84babf3042 389
megrootens 0:723d48642d5c 390 As5048Command last_command_;// command sent during last Transfer
cnckiwi31 6:1b84babf3042 391
megrootens 0:723d48642d5c 392 };
megrootens 0:723d48642d5c 393 #endif