Interface to access to Avago ADNS-9500 laser mouse sensors.

Fork of ADNS9500 by Chris Majoros

Committer:
aplatanado
Date:
Mon Feb 13 11:39:24 2012 +0000
Revision:
1:fa3052be61b5
Parent:
ADNS9500.cpp@0:782f2061a8f5
Child:
2:ee0c13ef1320
rename files to remove uppercase letters.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
aplatanado 0:782f2061a8f5 1 /*
aplatanado 1:fa3052be61b5 2 * adns9500.hpp - Interface to access to Avago ADNS-9500 laser mouse sensors
aplatanado 0:782f2061a8f5 3 *
aplatanado 0:782f2061a8f5 4 * Copyright 2012 Jesus Torres <jmtorres@ull.es>
aplatanado 0:782f2061a8f5 5 *
aplatanado 0:782f2061a8f5 6 * Licensed under the Apache License, Version 2.0 (the "License");
aplatanado 0:782f2061a8f5 7 * you may not use this file except in compliance with the License.
aplatanado 0:782f2061a8f5 8 * You may obtain a copy of the License at
aplatanado 0:782f2061a8f5 9 *
aplatanado 0:782f2061a8f5 10 * http://www.apache.org/licenses/LICENSE-2.0
aplatanado 0:782f2061a8f5 11 *
aplatanado 0:782f2061a8f5 12 * Unless required by applicable law or agreed to in writing, software
aplatanado 0:782f2061a8f5 13 * distributed under the License is distributed on an "AS IS" BASIS,
aplatanado 0:782f2061a8f5 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
aplatanado 0:782f2061a8f5 15 * See the License for the specific language governing permissions and
aplatanado 0:782f2061a8f5 16 * limitations under the License.
aplatanado 0:782f2061a8f5 17 */
aplatanado 0:782f2061a8f5 18
aplatanado 0:782f2061a8f5 19 #include <fstream>
aplatanado 0:782f2061a8f5 20 #include <math.h>
aplatanado 0:782f2061a8f5 21 #include <mbed.h>
aplatanado 0:782f2061a8f5 22 #include <string>
aplatanado 0:782f2061a8f5 23
aplatanado 1:fa3052be61b5 24 #include <adns9500.hpp>
aplatanado 0:782f2061a8f5 25
aplatanado 0:782f2061a8f5 26 #define WAIT_TSRAD() wait_us(100)
aplatanado 0:782f2061a8f5 27 #define WAIT_TSRWR() wait_us(20)
aplatanado 0:782f2061a8f5 28 #define WAIT_TBEXIT() wait_us(1) // 500ns
aplatanado 0:782f2061a8f5 29 #define WAIT_TNCSSCLK() wait_us(1) // 120ns
aplatanado 0:782f2061a8f5 30 #define WAIT_TSCLKNCS() wait_us(20)
aplatanado 0:782f2061a8f5 31 #define WAIT_TLOAD() wait_us(15)
aplatanado 0:782f2061a8f5 32
aplatanado 0:782f2061a8f5 33 #define DEFAULT_MAX_FPS 1958
aplatanado 0:782f2061a8f5 34 #define DEFAULT_MAX_FRAME_PERIOD ceil(1.0e6 / DEFAULT_MAX_FPS) // in us
aplatanado 0:782f2061a8f5 35 #define DEFAULT_X_CPI 1620
aplatanado 0:782f2061a8f5 36 #define DEFAULT_Y_CPI 1620
aplatanado 0:782f2061a8f5 37 #define CPI_CHANGE_UNIT 90
aplatanado 0:782f2061a8f5 38
aplatanado 0:782f2061a8f5 39 #define SET_BIT(word, mask) (word | mask)
aplatanado 0:782f2061a8f5 40 #define CLEAR_BIT(word, mask) (word & (~mask))
aplatanado 0:782f2061a8f5 41
aplatanado 0:782f2061a8f5 42 namespace adns9500 {
aplatanado 0:782f2061a8f5 43
aplatanado 0:782f2061a8f5 44 ADNS9500::ADNS9500(PinName mosi, PinName miso, PinName sclk, PinName ncs,
aplatanado 0:782f2061a8f5 45 int spi_frequency, PinName motion)
aplatanado 0:782f2061a8f5 46 : spi_(mosi, miso, sclk),
aplatanado 0:782f2061a8f5 47 motion_(motion),
aplatanado 0:782f2061a8f5 48 ncs_(ncs),
aplatanado 0:782f2061a8f5 49 enabled_(false),
aplatanado 0:782f2061a8f5 50 dx_(0), dy_(0),
aplatanado 0:782f2061a8f5 51 xCpi_(DEFAULT_X_CPI), yCpi_(DEFAULT_Y_CPI)
aplatanado 0:782f2061a8f5 52 {
aplatanado 0:782f2061a8f5 53 motion_.fall(this, &ADNS9500::motionTrigger);
aplatanado 0:782f2061a8f5 54 }
aplatanado 0:782f2061a8f5 55
aplatanado 0:782f2061a8f5 56 ADNS9500::~ADNS9500()
aplatanado 0:782f2061a8f5 57 {
aplatanado 0:782f2061a8f5 58 shutdown();
aplatanado 0:782f2061a8f5 59 }
aplatanado 0:782f2061a8f5 60
aplatanado 0:782f2061a8f5 61 void ADNS9500::reset(const char* firmware)
aplatanado 0:782f2061a8f5 62 {
aplatanado 0:782f2061a8f5 63 // SPI port reset
aplatanado 0:782f2061a8f5 64 ncs_.write(1);
aplatanado 0:782f2061a8f5 65 WAIT_TNCSSCLK();
aplatanado 0:782f2061a8f5 66 ncs_.write(0);
aplatanado 0:782f2061a8f5 67 WAIT_TNCSSCLK();
aplatanado 0:782f2061a8f5 68
aplatanado 0:782f2061a8f5 69 // send 0x3a to POWER_UP_RESET and wait for at least 50ms
aplatanado 0:782f2061a8f5 70 spi_.write(POWER_UP_RESET);
aplatanado 0:782f2061a8f5 71 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 72 spi_.write(0x5a);
aplatanado 0:782f2061a8f5 73 wait_ms(50);
aplatanado 0:782f2061a8f5 74
aplatanado 0:782f2061a8f5 75 // clear observation register. Only required to deassert shutdown mode.
aplatanado 0:782f2061a8f5 76 spi_.write(OBSERVATION);
aplatanado 0:782f2061a8f5 77 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 78 spi_.write(0x00);
aplatanado 0:782f2061a8f5 79 wait_us(DEFAULT_MAX_FRAME_PERIOD);
aplatanado 0:782f2061a8f5 80
aplatanado 0:782f2061a8f5 81 // check observation register bits [5:0]
aplatanado 0:782f2061a8f5 82 spi_.write(OBSERVATION);
aplatanado 0:782f2061a8f5 83 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 84 int observation = spi_.write(0x00);
aplatanado 0:782f2061a8f5 85 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 86
aplatanado 0:782f2061a8f5 87 if (! ADNS9500_IF_OBSERVATION_TEST(observation))
aplatanado 0:782f2061a8f5 88 error("ADNS9500::reset : observation register test failed: 0x%x\n", observation);
aplatanado 0:782f2061a8f5 89
aplatanado 0:782f2061a8f5 90 // read motion data
aplatanado 0:782f2061a8f5 91 spi_.write(MOTION);
aplatanado 0:782f2061a8f5 92 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 93 spi_.write(DELTA_X_L);
aplatanado 0:782f2061a8f5 94 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 95 spi_.write(DELTA_X_H);
aplatanado 0:782f2061a8f5 96 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 97 spi_.write(DELTA_Y_L);
aplatanado 0:782f2061a8f5 98 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 99 spi_.write(DELTA_Y_H);
aplatanado 0:782f2061a8f5 100 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 101
aplatanado 0:782f2061a8f5 102 // read product and revision id to test the connection
aplatanado 0:782f2061a8f5 103 spi_.write(PRODUCT_ID);
aplatanado 0:782f2061a8f5 104 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 105 int product_id = spi_.write(REVISION_ID);
aplatanado 0:782f2061a8f5 106 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 107 int revision_id = spi_.write(0x00);
aplatanado 0:782f2061a8f5 108 WAIT_TSCLKNCS();
aplatanado 0:782f2061a8f5 109
aplatanado 0:782f2061a8f5 110 ncs_.write(1);
aplatanado 0:782f2061a8f5 111
aplatanado 0:782f2061a8f5 112 if (product_id != 0x33) {
aplatanado 0:782f2061a8f5 113 error("ADNS9500::reset : bad product ID: 0x%x\n", product_id);
aplatanado 0:782f2061a8f5 114 }
aplatanado 0:782f2061a8f5 115
aplatanado 0:782f2061a8f5 116 if (revision_id != 0x03) {
aplatanado 0:782f2061a8f5 117 error("ADNS9500::reset : bad revision ID: 0x%x\n", revision_id);
aplatanado 0:782f2061a8f5 118 }
aplatanado 0:782f2061a8f5 119
aplatanado 0:782f2061a8f5 120 enabled_ = true;
aplatanado 0:782f2061a8f5 121
aplatanado 0:782f2061a8f5 122 if (firmware) {
aplatanado 0:782f2061a8f5 123 sromDownload(firmware);
aplatanado 0:782f2061a8f5 124 enableLaser();
aplatanado 0:782f2061a8f5 125 }
aplatanado 0:782f2061a8f5 126 }
aplatanado 0:782f2061a8f5 127
aplatanado 0:782f2061a8f5 128 void ADNS9500::shutdown()
aplatanado 0:782f2061a8f5 129 {
aplatanado 0:782f2061a8f5 130 if (! enabled_)
aplatanado 0:782f2061a8f5 131 error("ADNS9500::shutdown : the sensor is not enabled\n");
aplatanado 0:782f2061a8f5 132
aplatanado 0:782f2061a8f5 133 ncs_.write(0);
aplatanado 0:782f2061a8f5 134 WAIT_TNCSSCLK();
aplatanado 0:782f2061a8f5 135
aplatanado 0:782f2061a8f5 136 // send 0x3a to POWER_UP_RESET
aplatanado 0:782f2061a8f5 137 spi_.write(POWER_UP_RESET);
aplatanado 0:782f2061a8f5 138 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 139 spi_.write(0x5a);
aplatanado 0:782f2061a8f5 140 WAIT_TSCLKNCS();
aplatanado 0:782f2061a8f5 141
aplatanado 0:782f2061a8f5 142 ncs_.write(1);
aplatanado 0:782f2061a8f5 143
aplatanado 0:782f2061a8f5 144 enabled_ = false;
aplatanado 0:782f2061a8f5 145 }
aplatanado 0:782f2061a8f5 146
aplatanado 0:782f2061a8f5 147 int ADNS9500::read(Register lregister)
aplatanado 0:782f2061a8f5 148 {
aplatanado 0:782f2061a8f5 149 if (! enabled_)
aplatanado 0:782f2061a8f5 150 error("ADNS9500::read : the sensor is not enabled\n");
aplatanado 0:782f2061a8f5 151
aplatanado 0:782f2061a8f5 152 ncs_.write(0);
aplatanado 0:782f2061a8f5 153 WAIT_TNCSSCLK();
aplatanado 0:782f2061a8f5 154
aplatanado 0:782f2061a8f5 155 // send the command to read the register
aplatanado 0:782f2061a8f5 156 spi_.write(lregister);
aplatanado 0:782f2061a8f5 157 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 158 int value = spi_.write(0x00);
aplatanado 0:782f2061a8f5 159 WAIT_TSCLKNCS();
aplatanado 0:782f2061a8f5 160
aplatanado 0:782f2061a8f5 161 ncs_.write(1);
aplatanado 0:782f2061a8f5 162 return value;
aplatanado 0:782f2061a8f5 163 }
aplatanado 0:782f2061a8f5 164
aplatanado 0:782f2061a8f5 165 int ADNS9500::read(Register uregister, Register lregister)
aplatanado 0:782f2061a8f5 166 {
aplatanado 0:782f2061a8f5 167 if (! enabled_)
aplatanado 0:782f2061a8f5 168 error("ADNS9500::read : the sensor is not enabled\n");
aplatanado 0:782f2061a8f5 169
aplatanado 0:782f2061a8f5 170 ncs_.write(0);
aplatanado 0:782f2061a8f5 171 WAIT_TNCSSCLK();
aplatanado 0:782f2061a8f5 172
aplatanado 0:782f2061a8f5 173 // send the command to read the registers
aplatanado 0:782f2061a8f5 174 spi_.write(lregister);
aplatanado 0:782f2061a8f5 175 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 176 int lvalue = spi_.write(uregister);
aplatanado 0:782f2061a8f5 177 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 178 int uvalue = spi_.write(0x00);
aplatanado 0:782f2061a8f5 179 WAIT_TSCLKNCS();
aplatanado 0:782f2061a8f5 180
aplatanado 0:782f2061a8f5 181 ncs_.write(1);
aplatanado 0:782f2061a8f5 182
aplatanado 0:782f2061a8f5 183 return ADNS9500_UINT16(uvalue, lvalue);
aplatanado 0:782f2061a8f5 184 }
aplatanado 0:782f2061a8f5 185
aplatanado 0:782f2061a8f5 186 int ADNS9500::sromDownload(const char* filename)
aplatanado 0:782f2061a8f5 187 {
aplatanado 0:782f2061a8f5 188 if (! enabled_)
aplatanado 0:782f2061a8f5 189 error("ADNS9500::sromDownload : the sensor is not enabled\n");
aplatanado 0:782f2061a8f5 190
aplatanado 0:782f2061a8f5 191 ncs_.write(0);
aplatanado 0:782f2061a8f5 192 WAIT_TNCSSCLK();
aplatanado 0:782f2061a8f5 193
aplatanado 0:782f2061a8f5 194 // SROM download
aplatanado 0:782f2061a8f5 195 spi_.write(CONFIGURATION_IV);
aplatanado 0:782f2061a8f5 196 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 197 spi_.write(ADNS9500_CONFIGURATION_IV_SROM_SIZE);
aplatanado 0:782f2061a8f5 198 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 199 spi_.write(SROM_ENABLE);
aplatanado 0:782f2061a8f5 200 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 201 spi_.write(0x1d);
aplatanado 0:782f2061a8f5 202 wait_us(DEFAULT_MAX_FRAME_PERIOD);
aplatanado 0:782f2061a8f5 203 spi_.write(SROM_ENABLE);
aplatanado 0:782f2061a8f5 204 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 205 spi_.write(0x18);
aplatanado 0:782f2061a8f5 206 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 207 spi_.write(SROM_LOAD_BURST);
aplatanado 0:782f2061a8f5 208
aplatanado 0:782f2061a8f5 209 // TODO: Comprobar que pasa si el archivo no existe
aplatanado 0:782f2061a8f5 210 ifstream ifs(filename, ifstream::in);
aplatanado 0:782f2061a8f5 211 while(ifs.good()) {
aplatanado 0:782f2061a8f5 212 WAIT_TLOAD();
aplatanado 0:782f2061a8f5 213 spi_.write(ifs.get());
aplatanado 0:782f2061a8f5 214 }
aplatanado 0:782f2061a8f5 215 WAIT_TSCLKNCS();
aplatanado 0:782f2061a8f5 216 ncs_.write(1);
aplatanado 0:782f2061a8f5 217 WAIT_TBEXIT();
aplatanado 0:782f2061a8f5 218
aplatanado 0:782f2061a8f5 219 if (! ifs.eof())
aplatanado 0:782f2061a8f5 220 error("ADNS9500::sromDownload : error reading from file: %s\n", filename);
aplatanado 0:782f2061a8f5 221
aplatanado 0:782f2061a8f5 222 // test if SROM was downloaded successfully
aplatanado 0:782f2061a8f5 223 wait_us(160);
aplatanado 0:782f2061a8f5 224 ncs_.write(0);
aplatanado 0:782f2061a8f5 225 WAIT_TNCSSCLK();
aplatanado 0:782f2061a8f5 226 spi_.write(SROM_ID);
aplatanado 0:782f2061a8f5 227 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 228 int srom_id = spi_.write(0x00);
aplatanado 0:782f2061a8f5 229 WAIT_TSCLKNCS();
aplatanado 0:782f2061a8f5 230 ncs_.write(1);
aplatanado 0:782f2061a8f5 231
aplatanado 0:782f2061a8f5 232 if (! srom_id)
aplatanado 0:782f2061a8f5 233 error("ADNS9500::sromDownload : the firmware was not successful downloaded\n");
aplatanado 0:782f2061a8f5 234
aplatanado 0:782f2061a8f5 235 // test laser fault condition
aplatanado 0:782f2061a8f5 236 ncs_.write(0);
aplatanado 0:782f2061a8f5 237 WAIT_TNCSSCLK();
aplatanado 0:782f2061a8f5 238 spi_.write(MOTION);
aplatanado 0:782f2061a8f5 239 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 240 int motion = spi_.write(0x00);
aplatanado 0:782f2061a8f5 241 WAIT_TSCLKNCS();
aplatanado 0:782f2061a8f5 242 ncs_.write(1);
aplatanado 0:782f2061a8f5 243
aplatanado 0:782f2061a8f5 244 if (ADNS9500_IF_LASER_FAULT(motion))
aplatanado 0:782f2061a8f5 245 error("ADNS9500::sromDownload : laser fault condition detected\n");
aplatanado 0:782f2061a8f5 246
aplatanado 0:782f2061a8f5 247 // return the SROM CRC value
aplatanado 0:782f2061a8f5 248 ncs_.write(0);
aplatanado 0:782f2061a8f5 249 WAIT_TNCSSCLK();
aplatanado 0:782f2061a8f5 250
aplatanado 0:782f2061a8f5 251 spi_.write(SROM_ENABLE);
aplatanado 0:782f2061a8f5 252 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 253 spi_.write(0x15);
aplatanado 0:782f2061a8f5 254 wait_us(10);
aplatanado 0:782f2061a8f5 255 spi_.write(DATA_OUT_LOWER);
aplatanado 0:782f2061a8f5 256 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 257 int lcrc = spi_.write(DATA_OUT_UPPER);
aplatanado 0:782f2061a8f5 258 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 259 int ucrc = spi_.write(0x00);
aplatanado 0:782f2061a8f5 260
aplatanado 0:782f2061a8f5 261 WAIT_TSCLKNCS();
aplatanado 0:782f2061a8f5 262 ncs_.write(1);
aplatanado 0:782f2061a8f5 263
aplatanado 0:782f2061a8f5 264 return ADNS9500_UINT16(ucrc, lcrc);
aplatanado 0:782f2061a8f5 265 }
aplatanado 0:782f2061a8f5 266
aplatanado 0:782f2061a8f5 267 void ADNS9500::enableLaser(bool enable)
aplatanado 0:782f2061a8f5 268 {
aplatanado 0:782f2061a8f5 269 if (! enabled_)
aplatanado 0:782f2061a8f5 270 error("ADNS9500::enableLaser : the sensor is not enabled\n");
aplatanado 0:782f2061a8f5 271
aplatanado 0:782f2061a8f5 272 ncs_.write(0);
aplatanado 0:782f2061a8f5 273 WAIT_TNCSSCLK();
aplatanado 0:782f2061a8f5 274
aplatanado 0:782f2061a8f5 275 spi_.write(LASER_CTRL0);
aplatanado 0:782f2061a8f5 276 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 277 if (enable) {
aplatanado 0:782f2061a8f5 278 int laser_ctrl0 = CLEAR_BIT(0x00, ADNS9500_LASER_CTRL0_FORCE_DISABLED);
aplatanado 0:782f2061a8f5 279 spi_.write(laser_ctrl0);
aplatanado 0:782f2061a8f5 280 }
aplatanado 0:782f2061a8f5 281 else {
aplatanado 0:782f2061a8f5 282 int laser_ctrl0 = SET_BIT(0x00, ADNS9500_LASER_CTRL0_FORCE_DISABLED);
aplatanado 0:782f2061a8f5 283 spi_.write(laser_ctrl0);
aplatanado 0:782f2061a8f5 284 }
aplatanado 0:782f2061a8f5 285
aplatanado 0:782f2061a8f5 286 WAIT_TSCLKNCS();
aplatanado 0:782f2061a8f5 287 ncs_.write(1);
aplatanado 0:782f2061a8f5 288 }
aplatanado 0:782f2061a8f5 289
aplatanado 0:782f2061a8f5 290 bool ADNS9500::getMotionDelta(int& dx, int& dy)
aplatanado 0:782f2061a8f5 291 {
aplatanado 0:782f2061a8f5 292 if (! enabled_)
aplatanado 0:782f2061a8f5 293 error("ADNS9500::getMotionDelta : the sensor is not enabled\n");
aplatanado 0:782f2061a8f5 294
aplatanado 0:782f2061a8f5 295 ncs_.write(0);
aplatanado 0:782f2061a8f5 296 WAIT_TNCSSCLK();
aplatanado 0:782f2061a8f5 297
aplatanado 0:782f2061a8f5 298 spi_.write(MOTION);
aplatanado 0:782f2061a8f5 299 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 300 int motion = spi_.write(DELTA_X_L);
aplatanado 0:782f2061a8f5 301 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 302
aplatanado 0:782f2061a8f5 303 if (ADNS9500_IF_MOTION(motion)) {
aplatanado 0:782f2061a8f5 304 int tmp = spi_.write(DELTA_X_L);
aplatanado 0:782f2061a8f5 305 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 306 dx = ADNS9500_UINT16(spi_.write(DELTA_X_H), tmp);
aplatanado 0:782f2061a8f5 307 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 308 tmp = spi_.write(DELTA_Y_L);
aplatanado 0:782f2061a8f5 309 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 310 dy = ADNS9500_UINT16(spi_.write(DELTA_Y_H), tmp);
aplatanado 0:782f2061a8f5 311
aplatanado 0:782f2061a8f5 312 dx_ = dx;
aplatanado 0:782f2061a8f5 313 dy_ = dy;
aplatanado 0:782f2061a8f5 314 }
aplatanado 0:782f2061a8f5 315 else {
aplatanado 0:782f2061a8f5 316 spi_.write(0x00);
aplatanado 0:782f2061a8f5 317
aplatanado 0:782f2061a8f5 318 dx = dx_;
aplatanado 0:782f2061a8f5 319 dy = dy_;
aplatanado 0:782f2061a8f5 320 }
aplatanado 0:782f2061a8f5 321
aplatanado 0:782f2061a8f5 322 WAIT_TSCLKNCS();
aplatanado 0:782f2061a8f5 323 ncs_.write(1);
aplatanado 0:782f2061a8f5 324
aplatanado 0:782f2061a8f5 325 return ADNS9500_IF_MOTION(motion);
aplatanado 0:782f2061a8f5 326 }
aplatanado 0:782f2061a8f5 327
aplatanado 0:782f2061a8f5 328 bool ADNS9500::getMotionDeltaMM(float& dx, float& dy)
aplatanado 0:782f2061a8f5 329 {
aplatanado 0:782f2061a8f5 330 int rawDx, rawDy;
aplatanado 0:782f2061a8f5 331
aplatanado 0:782f2061a8f5 332 bool motion = getMotionDelta(rawDx, rawDy);
aplatanado 0:782f2061a8f5 333 dx = (float)rawDx / xCpi_ * 25.4;
aplatanado 0:782f2061a8f5 334 dy = (float)rawDy / yCpi_ * 25.4;
aplatanado 0:782f2061a8f5 335
aplatanado 0:782f2061a8f5 336 return motion;
aplatanado 0:782f2061a8f5 337 }
aplatanado 0:782f2061a8f5 338
aplatanado 0:782f2061a8f5 339 bool ADNS9500::getMotionData(MotionData& data)
aplatanado 0:782f2061a8f5 340 {
aplatanado 0:782f2061a8f5 341 if (! enabled_)
aplatanado 0:782f2061a8f5 342 error("ADNS9500::getMotionData : the sensor is not enabled\n");
aplatanado 0:782f2061a8f5 343
aplatanado 0:782f2061a8f5 344 ncs_.write(0);
aplatanado 0:782f2061a8f5 345 WAIT_TNCSSCLK();
aplatanado 0:782f2061a8f5 346
aplatanado 0:782f2061a8f5 347 // activate motion burst mode
aplatanado 0:782f2061a8f5 348 spi_.write(MOTION_BURST);
aplatanado 0:782f2061a8f5 349 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 350 spi_.write(0x50);
aplatanado 0:782f2061a8f5 351
aplatanado 0:782f2061a8f5 352 // if in run mode, wait for 1 frame
aplatanado 0:782f2061a8f5 353 wait_us(DEFAULT_MAX_FRAME_PERIOD);
aplatanado 0:782f2061a8f5 354
aplatanado 0:782f2061a8f5 355 // read motion burst data
aplatanado 0:782f2061a8f5 356 data.motion = spi_.write(0x00);
aplatanado 0:782f2061a8f5 357 data.observation = spi_.write(0x00);
aplatanado 0:782f2061a8f5 358
aplatanado 0:782f2061a8f5 359 int ldx = spi_.write(0x00);
aplatanado 0:782f2061a8f5 360 data.dx = ADNS9500_UINT16(spi_.write(0x00), ldx);
aplatanado 0:782f2061a8f5 361
aplatanado 0:782f2061a8f5 362 int ldy = spi_.write(0x00);
aplatanado 0:782f2061a8f5 363 data.dy = ADNS9500_UINT16(spi_.write(0x00), ldy);
aplatanado 0:782f2061a8f5 364
aplatanado 0:782f2061a8f5 365 data.squal = spi_.write(0x00);
aplatanado 0:782f2061a8f5 366 data.pixelSum = spi_.write(0x00);
aplatanado 0:782f2061a8f5 367 data.maximumPixel = spi_.write(0x00);
aplatanado 0:782f2061a8f5 368 data.minimumPixel = spi_.write(0x00);
aplatanado 0:782f2061a8f5 369
aplatanado 0:782f2061a8f5 370 int ushutter = spi_.write(0x00);
aplatanado 0:782f2061a8f5 371 data.shutter = ADNS9500_UINT16(ushutter, spi_.write(0x00));
aplatanado 0:782f2061a8f5 372
aplatanado 0:782f2061a8f5 373 int uframe_period = spi_.write(0x00);
aplatanado 0:782f2061a8f5 374 data.framePeriod = ADNS9500_UINT16(uframe_period, spi_.write(0x00));
aplatanado 0:782f2061a8f5 375
aplatanado 0:782f2061a8f5 376 WAIT_TSCLKNCS();
aplatanado 0:782f2061a8f5 377 ncs_.write(1);
aplatanado 0:782f2061a8f5 378 WAIT_TBEXIT();
aplatanado 0:782f2061a8f5 379
aplatanado 0:782f2061a8f5 380 return ADNS9500_IF_MOTION(data.motion);
aplatanado 0:782f2061a8f5 381 }
aplatanado 0:782f2061a8f5 382
aplatanado 0:782f2061a8f5 383 void ADNS9500::setResolution(Resolution xy_resolution)
aplatanado 0:782f2061a8f5 384 {
aplatanado 0:782f2061a8f5 385 if (! enabled_)
aplatanado 0:782f2061a8f5 386 error("ADNS9500::setResolution : the sensor is not enabled\n");
aplatanado 0:782f2061a8f5 387
aplatanado 0:782f2061a8f5 388 ncs_.write(0);
aplatanado 0:782f2061a8f5 389 WAIT_TNCSSCLK();
aplatanado 0:782f2061a8f5 390
aplatanado 0:782f2061a8f5 391 // enable XY axes CPI in sync mode
aplatanado 0:782f2061a8f5 392 spi_.write(CONFIGURATION_II);
aplatanado 0:782f2061a8f5 393 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 394 int rpt_mod = spi_.write(0x00);
aplatanado 0:782f2061a8f5 395 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 396 spi_.write(CLEAR_BIT(rpt_mod, ADNS9500_CONFIGURATION_II_RPT_MOD));
aplatanado 0:782f2061a8f5 397 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 398
aplatanado 0:782f2061a8f5 399 // set resolution for X-axis and Y-axis
aplatanado 0:782f2061a8f5 400 spi_.write(CONFIGURATION_I);
aplatanado 0:782f2061a8f5 401 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 402 spi_.write(xy_resolution);
aplatanado 0:782f2061a8f5 403
aplatanado 0:782f2061a8f5 404 WAIT_TSCLKNCS();
aplatanado 0:782f2061a8f5 405 ncs_.write(1);
aplatanado 0:782f2061a8f5 406
aplatanado 0:782f2061a8f5 407 xCpi_ = xy_resolution * CPI_CHANGE_UNIT;
aplatanado 0:782f2061a8f5 408 yCpi_ = xy_resolution * CPI_CHANGE_UNIT;
aplatanado 0:782f2061a8f5 409 }
aplatanado 0:782f2061a8f5 410
aplatanado 0:782f2061a8f5 411 void ADNS9500::setResolution(Resolution x_resolution, Resolution y_resolution)
aplatanado 0:782f2061a8f5 412 {
aplatanado 0:782f2061a8f5 413 if (! enabled_)
aplatanado 0:782f2061a8f5 414 error("ADNS9500::setResolution : the sensor is not enabled\n");
aplatanado 0:782f2061a8f5 415
aplatanado 0:782f2061a8f5 416 ncs_.write(0);
aplatanado 0:782f2061a8f5 417 WAIT_TNCSSCLK();
aplatanado 0:782f2061a8f5 418
aplatanado 0:782f2061a8f5 419 // disable XY axes CPI in sync mode
aplatanado 0:782f2061a8f5 420 spi_.write(CONFIGURATION_II);
aplatanado 0:782f2061a8f5 421 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 422 int rpt_mod = spi_.write(0x00);
aplatanado 0:782f2061a8f5 423 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 424 spi_.write(SET_BIT(rpt_mod, ADNS9500_CONFIGURATION_II_RPT_MOD));
aplatanado 0:782f2061a8f5 425 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 426
aplatanado 0:782f2061a8f5 427 // set resolution for X-axis
aplatanado 0:782f2061a8f5 428 spi_.write(CONFIGURATION_I);
aplatanado 0:782f2061a8f5 429 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 430 spi_.write(x_resolution);
aplatanado 0:782f2061a8f5 431 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 432
aplatanado 0:782f2061a8f5 433 // set resolution for Y-axis
aplatanado 0:782f2061a8f5 434 spi_.write(CONFIGURATION_V);
aplatanado 0:782f2061a8f5 435 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 436 spi_.write(y_resolution);
aplatanado 0:782f2061a8f5 437
aplatanado 0:782f2061a8f5 438 WAIT_TSCLKNCS();
aplatanado 0:782f2061a8f5 439 ncs_.write(1);
aplatanado 0:782f2061a8f5 440
aplatanado 0:782f2061a8f5 441 xCpi_ = x_resolution * CPI_CHANGE_UNIT;
aplatanado 0:782f2061a8f5 442 yCpi_ = y_resolution * CPI_CHANGE_UNIT;
aplatanado 0:782f2061a8f5 443 }
aplatanado 0:782f2061a8f5 444
aplatanado 0:782f2061a8f5 445 void ADNS9500::captureFrame(uint8_t pixels[NUMBER_OF_PIXELS_PER_FRAME])
aplatanado 0:782f2061a8f5 446 {
aplatanado 0:782f2061a8f5 447 if (! enabled_)
aplatanado 0:782f2061a8f5 448 error("ADNS9500::captureFrame : the sensor is not enabled\n");
aplatanado 0:782f2061a8f5 449
aplatanado 0:782f2061a8f5 450 ncs_.write(0);
aplatanado 0:782f2061a8f5 451 WAIT_TNCSSCLK();
aplatanado 0:782f2061a8f5 452
aplatanado 0:782f2061a8f5 453 spi_.write(FRAME_CAPTURE);
aplatanado 0:782f2061a8f5 454 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 455 spi_.write(0x93);
aplatanado 0:782f2061a8f5 456 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 457 spi_.write(FRAME_CAPTURE);
aplatanado 0:782f2061a8f5 458 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 459 spi_.write(0xc5);
aplatanado 0:782f2061a8f5 460 wait_us(DEFAULT_MAX_FRAME_PERIOD);
aplatanado 0:782f2061a8f5 461 wait_us(DEFAULT_MAX_FRAME_PERIOD);
aplatanado 0:782f2061a8f5 462
aplatanado 0:782f2061a8f5 463 // check for first pixel reading motion bit
aplatanado 0:782f2061a8f5 464 spi_.write(MOTION);
aplatanado 0:782f2061a8f5 465 while(true) {
aplatanado 0:782f2061a8f5 466 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 467 int motion = spi_.write(MOTION);
aplatanado 0:782f2061a8f5 468 if (ADNS9500_IF_MOTION(motion))
aplatanado 0:782f2061a8f5 469 break;
aplatanado 0:782f2061a8f5 470 }
aplatanado 0:782f2061a8f5 471
aplatanado 0:782f2061a8f5 472 // read pixel values
aplatanado 0:782f2061a8f5 473 spi_.write(PIXEL_BURST);
aplatanado 0:782f2061a8f5 474 WAIT_TSRAD();
aplatanado 0:782f2061a8f5 475 for (uint8_t* p = pixels; p != pixels + sizeof(pixels); ++p) {
aplatanado 0:782f2061a8f5 476 WAIT_TLOAD();
aplatanado 0:782f2061a8f5 477 *p = spi_.write(PIXEL_BURST);
aplatanado 0:782f2061a8f5 478 }
aplatanado 0:782f2061a8f5 479
aplatanado 0:782f2061a8f5 480 // burst exit
aplatanado 0:782f2061a8f5 481 WAIT_TSCLKNCS();
aplatanado 0:782f2061a8f5 482 ncs_.write(1);
aplatanado 0:782f2061a8f5 483 WAIT_TBEXIT();
aplatanado 0:782f2061a8f5 484 }
aplatanado 0:782f2061a8f5 485 }