Now with licence header and working for output of DROPSAW project
as5048.h@6:1b84babf3042, 2020-10-26 (annotated)
- 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?
User | Revision | Line number | New 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 |