PixArt Optical Track Sensor, OTS, library initial release v1.0. Supports PAT9125, PAT9126, PAT9130, PAA5101. Future to support PAT9150.

Fork of Pixart_OTS by Hill Chen

Committer:
PixArtHC
Date:
Tue Mar 26 22:32:06 2019 +0000
Revision:
1:95917b856631
Parent:
0:2a85075b8467
* V1.1 library changes:;  * Add support to 5101 LD/LED switching.;  * Add support to PAT9150.;  * Fixed bug on loading initialization setting.;  * Optimized register read timing.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
PixArtHC 0:2a85075b8467 1 /* PixArt Optical Finger Navigation, OFN, sensor driver.
PixArtHC 0:2a85075b8467 2 * By PixArt Imaging Inc.
PixArtHC 0:2a85075b8467 3 * Primary Engineer: Hill Chen (PixArt USA)
PixArtHC 0:2a85075b8467 4 *
PixArtHC 0:2a85075b8467 5 * License: Apache-2.0; http://www.apache.org/licenses/LICENSE-2.0
PixArtHC 0:2a85075b8467 6 */
PixArtHC 0:2a85075b8467 7
PixArtHC 0:2a85075b8467 8 #include "Pixart_OTS.h"
PixArtHC 0:2a85075b8467 9
PixArtHC 0:2a85075b8467 10 #ifdef DEBUG
PixArtHC 0:2a85075b8467 11 #define DEBUG_PRINT(...) m_pc.printf(__VA_ARGS__)
PixArtHC 0:2a85075b8467 12 #else
PixArtHC 0:2a85075b8467 13 #define DEBUG_PRINT(...) {}
PixArtHC 0:2a85075b8467 14 #endif
PixArtHC 0:2a85075b8467 15
PixArtHC 1:95917b856631 16 #define ARRAY_REG_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
PixArtHC 0:2a85075b8467 17
PixArtHC 0:2a85075b8467 18 #define I2C_ADDR (0x75 << 1) //I2C address @ID_SEL=Low (apply to 9125/26/50)
PixArtHC 0:2a85075b8467 19 #define PXI_WMI 0x31
PixArtHC 0:2a85075b8467 20
PixArtHC 1:95917b856631 21 class Pixart_OTS_ComPort : public Pixart_ComPort
PixArtHC 1:95917b856631 22 {
PixArtHC 1:95917b856631 23 public:
PixArtHC 1:95917b856631 24 Pixart_OTS_ComPort(Pixart_ComPort *comPort)
PixArtHC 1:95917b856631 25 : m_comPort(comPort)
PixArtHC 1:95917b856631 26 {
PixArtHC 1:95917b856631 27 }
PixArtHC 1:95917b856631 28
PixArtHC 1:95917b856631 29 virtual void writeRegister(uint8_t addr, uint8_t data)
PixArtHC 1:95917b856631 30 {
PixArtHC 1:95917b856631 31 if (addr == 0x7F || addr == 0x06 || addr == 0x03 || addr == 0x2A) {
PixArtHC 1:95917b856631 32 m_comPort->writeRegister(addr, data);
PixArtHC 1:95917b856631 33 }
PixArtHC 1:95917b856631 34
PixArtHC 1:95917b856631 35 else {
PixArtHC 1:95917b856631 36 uint8_t read_value;
PixArtHC 1:95917b856631 37 do
PixArtHC 1:95917b856631 38 {
PixArtHC 1:95917b856631 39 m_comPort->writeRegister(addr, data);
PixArtHC 1:95917b856631 40 read_value = m_comPort->readRegister(addr);
PixArtHC 1:95917b856631 41 } while (read_value != data);
PixArtHC 1:95917b856631 42 }
PixArtHC 1:95917b856631 43 }
PixArtHC 1:95917b856631 44
PixArtHC 1:95917b856631 45 virtual uint8_t readRegister(uint8_t addr)
PixArtHC 1:95917b856631 46 {
PixArtHC 1:95917b856631 47 return m_comPort->readRegister(addr);
PixArtHC 1:95917b856631 48 }
PixArtHC 1:95917b856631 49
PixArtHC 1:95917b856631 50 private:
PixArtHC 1:95917b856631 51 Pixart_ComPort *m_comPort;
PixArtHC 1:95917b856631 52 };
PixArtHC 1:95917b856631 53
PixArtHC 0:2a85075b8467 54 static std::vector<Pixart_OTS_Register> create_registers(const uint8_t setting[][2], size_t setting_len);
PixArtHC 0:2a85075b8467 55
PixArtHC 1:95917b856631 56 Pixart_OTS::Pixart_OTS(Serial &pc, Pixart_ComPort *comPort, Pixart_OTS_GrabData *grabData, Pixart_OTS_Task *task, const std::vector<Pixart_OTS_Register> &initRegisters, const std::string &model, const std::string &HwVer)
PixArtHC 0:2a85075b8467 57 : m_pc(pc)
PixArtHC 1:95917b856631 58 , m_comPort(new Pixart_OTS_ComPort(comPort))
PixArtHC 0:2a85075b8467 59 , m_grabData(grabData)
PixArtHC 1:95917b856631 60 , m_task(task)
PixArtHC 0:2a85075b8467 61 , m_initRegisters(initRegisters)
PixArtHC 0:2a85075b8467 62 , m_model(model)
PixArtHC 0:2a85075b8467 63 , m_HwVer(HwVer)
PixArtHC 0:2a85075b8467 64 {
PixArtHC 0:2a85075b8467 65 wait_ms(500);
PixArtHC 0:2a85075b8467 66 print_build_info();
PixArtHC 0:2a85075b8467 67 }
PixArtHC 0:2a85075b8467 68
PixArtHC 0:2a85075b8467 69 bool Pixart_OTS::sensor_init()
PixArtHC 0:2a85075b8467 70 {
PixArtHC 1:95917b856631 71 m_task->reset_task(*m_comPort);
PixArtHC 1:95917b856631 72 wait_ms(10);
PixArtHC 0:2a85075b8467 73 if (m_comPort->readRegister(0x00) != PXI_WMI)
PixArtHC 0:2a85075b8467 74 {
PixArtHC 0:2a85075b8467 75 DEBUG_PRINT("\r\n << Sensor_Init (Fail), ID = %2X", m_comPort->readRegister(0x00));
PixArtHC 0:2a85075b8467 76 return false;
PixArtHC 0:2a85075b8467 77 }
PixArtHC 0:2a85075b8467 78
PixArtHC 0:2a85075b8467 79 m_totalX = 0;
PixArtHC 0:2a85075b8467 80 m_totalY = 0;
PixArtHC 0:2a85075b8467 81
PixArtHC 0:2a85075b8467 82 for (size_t i = 0; i < m_initRegisters.size(); ++i)
PixArtHC 0:2a85075b8467 83 {
PixArtHC 0:2a85075b8467 84 m_comPort->writeRegister(m_initRegisters[i].addr, m_initRegisters[i].value);
PixArtHC 0:2a85075b8467 85 }
PixArtHC 1:95917b856631 86
PixArtHC 1:95917b856631 87 m_task->pre_task(*m_comPort);
PixArtHC 0:2a85075b8467 88
PixArtHC 0:2a85075b8467 89 return true;
PixArtHC 0:2a85075b8467 90 }
PixArtHC 0:2a85075b8467 91
PixArtHC 0:2a85075b8467 92 void Pixart_OTS::periodic_callback()
PixArtHC 0:2a85075b8467 93 {
PixArtHC 1:95917b856631 94 m_task->periodic_task(*m_comPort);
PixArtHC 1:95917b856631 95
PixArtHC 0:2a85075b8467 96 if (m_comPort->readRegister(0x02) & 0x80)
PixArtHC 0:2a85075b8467 97 {
PixArtHC 0:2a85075b8467 98 Pixart_OTS_OtsData otsData = m_grabData->grab(*m_comPort);
PixArtHC 0:2a85075b8467 99
PixArtHC 0:2a85075b8467 100 if ((otsData.x != 0) || (otsData.y != 0))
PixArtHC 0:2a85075b8467 101 {
PixArtHC 0:2a85075b8467 102 m_totalX += otsData.x;
PixArtHC 0:2a85075b8467 103 m_totalY += otsData.y;
PixArtHC 0:2a85075b8467 104
PixArtHC 0:2a85075b8467 105 DEBUG_PRINT("deltaX: %d\t\t\tdeltaY: %d\n\r", otsData.x, otsData.y);
PixArtHC 0:2a85075b8467 106 DEBUG_PRINT("X-axis Counts: %d\t\tY-axis Counts: %d\n\r", m_totalX, m_totalY);
PixArtHC 0:2a85075b8467 107 }
PixArtHC 0:2a85075b8467 108 }
PixArtHC 0:2a85075b8467 109 }
PixArtHC 0:2a85075b8467 110
PixArtHC 0:2a85075b8467 111 int Pixart_OTS::get_default_i2c_slave_address()
PixArtHC 0:2a85075b8467 112 {
PixArtHC 0:2a85075b8467 113 return I2C_ADDR;
PixArtHC 0:2a85075b8467 114 }
PixArtHC 0:2a85075b8467 115
PixArtHC 0:2a85075b8467 116 std::string Pixart_OTS::get_model() const
PixArtHC 0:2a85075b8467 117 {
PixArtHC 0:2a85075b8467 118 return m_model;
PixArtHC 0:2a85075b8467 119 }
PixArtHC 0:2a85075b8467 120
PixArtHC 0:2a85075b8467 121 std::string Pixart_OTS::get_HwVer() const
PixArtHC 0:2a85075b8467 122 {
PixArtHC 0:2a85075b8467 123 return m_HwVer;
PixArtHC 0:2a85075b8467 124 }
PixArtHC 0:2a85075b8467 125
PixArtHC 0:2a85075b8467 126 void Pixart_OTS::print_build_info()
PixArtHC 0:2a85075b8467 127 {
PixArtHC 0:2a85075b8467 128 DEBUG_PRINT("\r\n\n PixArt Mbed eval code, %s, %s", PRODUCT, get_model().c_str());
PixArtHC 0:2a85075b8467 129 DEBUG_PRINT("\r\n Fw version: %s, Hw version: %s, mbed version: %d", FW_VERSION, get_HwVer().c_str(), MBED_VERSION);
PixArtHC 0:2a85075b8467 130 DEBUG_PRINT("\r\n Build time: %s %s\r\n", __TIME__, __DATE__);
PixArtHC 0:2a85075b8467 131 }
PixArtHC 0:2a85075b8467 132
PixArtHC 0:2a85075b8467 133 Pixart_OTS* create_pixart_ots(Pixart_OTS_Model model, Serial &pc, I2C &i2c)
PixArtHC 0:2a85075b8467 134 {
PixArtHC 0:2a85075b8467 135 Pixart_ComPort *com_port = NULL;
PixArtHC 0:2a85075b8467 136 Pixart_OTS_GrabData *grabData = NULL;
PixArtHC 1:95917b856631 137 Pixart_OTS_Task *task = NULL;
PixArtHC 0:2a85075b8467 138 std::vector<Pixart_OTS_Register> initRegisters;
PixArtHC 0:2a85075b8467 139 std::string modelName;
PixArtHC 0:2a85075b8467 140 std::string HwVer;
PixArtHC 0:2a85075b8467 141
PixArtHC 0:2a85075b8467 142 switch (model)
PixArtHC 0:2a85075b8467 143 {
PixArtHC 0:2a85075b8467 144 case PIXART_OTS_MODEL_9125:
PixArtHC 0:2a85075b8467 145 {
PixArtHC 0:2a85075b8467 146 com_port = new Pixart_I2cComPort(i2c, Pixart_OTS::get_default_i2c_slave_address());
PixArtHC 0:2a85075b8467 147 grabData = new Pixart_OTS_GrabData_12bitXy();
PixArtHC 1:95917b856631 148 task = new Pixart_OTS_Task();
PixArtHC 1:95917b856631 149 initRegisters = create_registers(Pixart_OTS_9125_InitSetting, ARRAY_REG_SIZE(Pixart_OTS_9125_InitSetting));
PixArtHC 0:2a85075b8467 150 modelName = "P9125";
PixArtHC 0:2a85075b8467 151 HwVer = "PIX1484-v5.0";
PixArtHC 0:2a85075b8467 152 }
PixArtHC 0:2a85075b8467 153 break;
PixArtHC 0:2a85075b8467 154
PixArtHC 0:2a85075b8467 155 case PIXART_OTS_MODEL_9126:
PixArtHC 0:2a85075b8467 156 {
PixArtHC 0:2a85075b8467 157 com_port = new Pixart_I2cComPort(i2c, Pixart_OTS::get_default_i2c_slave_address());
PixArtHC 0:2a85075b8467 158 grabData = new Pixart_OTS_GrabData_12bitXy();
PixArtHC 1:95917b856631 159 task = new Pixart_OTS_Task();
PixArtHC 1:95917b856631 160 initRegisters = create_registers(Pixart_OTS_9126_InitSetting, ARRAY_REG_SIZE(Pixart_OTS_9126_InitSetting));
PixArtHC 0:2a85075b8467 161 modelName = "P9126";
PixArtHC 0:2a85075b8467 162 HwVer = "PIX1484-v6.0";
PixArtHC 0:2a85075b8467 163 }
PixArtHC 0:2a85075b8467 164 break;
PixArtHC 0:2a85075b8467 165
PixArtHC 0:2a85075b8467 166 case PIXART_OTS_MODEL_9150:
PixArtHC 0:2a85075b8467 167 {
PixArtHC 0:2a85075b8467 168 com_port = new Pixart_I2cComPort(i2c, Pixart_OTS::get_default_i2c_slave_address());
PixArtHC 0:2a85075b8467 169 grabData = new Pixart_OTS_GrabData_16bitXOnly();
PixArtHC 1:95917b856631 170 task = new Pixart_OTS_Task();
PixArtHC 1:95917b856631 171 initRegisters = create_registers(Pixart_OTS_9150_InitSetting, ARRAY_REG_SIZE(Pixart_OTS_9150_InitSetting));
PixArtHC 0:2a85075b8467 172 modelName = "P9150";
PixArtHC 0:2a85075b8467 173 HwVer = "PIX1xxx-vx.0";
PixArtHC 0:2a85075b8467 174 }
PixArtHC 0:2a85075b8467 175 break;
PixArtHC 0:2a85075b8467 176
PixArtHC 0:2a85075b8467 177 default:
PixArtHC 0:2a85075b8467 178 return NULL;
PixArtHC 0:2a85075b8467 179 }
PixArtHC 0:2a85075b8467 180
PixArtHC 1:95917b856631 181 return new Pixart_OTS(pc, com_port, grabData, task, initRegisters, modelName, HwVer);
PixArtHC 0:2a85075b8467 182 }
PixArtHC 0:2a85075b8467 183
PixArtHC 0:2a85075b8467 184 Pixart_OTS* create_pixart_ots(Pixart_OTS_Model model, Serial &pc, SPI &spi, DigitalOut &cs)
PixArtHC 0:2a85075b8467 185 {
PixArtHC 0:2a85075b8467 186 Pixart_ComPort *com_port = NULL;
PixArtHC 0:2a85075b8467 187 Pixart_OTS_GrabData *grabData = NULL;
PixArtHC 1:95917b856631 188 Pixart_OTS_Task *task = NULL;
PixArtHC 0:2a85075b8467 189 std::vector<Pixart_OTS_Register> initRegisters;
PixArtHC 0:2a85075b8467 190 std::string modelName;
PixArtHC 0:2a85075b8467 191 std::string HwVer;
PixArtHC 0:2a85075b8467 192
PixArtHC 0:2a85075b8467 193 switch (model)
PixArtHC 0:2a85075b8467 194 {
PixArtHC 0:2a85075b8467 195 case PIXART_OTS_MODEL_9125:
PixArtHC 0:2a85075b8467 196 {
PixArtHC 0:2a85075b8467 197 com_port = new Pixart_SpiComPort(spi, cs);
PixArtHC 0:2a85075b8467 198 grabData = new Pixart_OTS_GrabData_12bitXy();
PixArtHC 1:95917b856631 199 task = new Pixart_OTS_Task();
PixArtHC 1:95917b856631 200 initRegisters = create_registers(Pixart_OTS_9125_InitSetting, ARRAY_REG_SIZE(Pixart_OTS_9125_InitSetting));
PixArtHC 0:2a85075b8467 201 modelName = "P9125";
PixArtHC 0:2a85075b8467 202 HwVer = "PIX1484-v5.0";
PixArtHC 0:2a85075b8467 203 }
PixArtHC 0:2a85075b8467 204 break;
PixArtHC 0:2a85075b8467 205
PixArtHC 0:2a85075b8467 206 case PIXART_OTS_MODEL_9130:
PixArtHC 0:2a85075b8467 207 {
PixArtHC 0:2a85075b8467 208 com_port = new Pixart_SpiComPort(spi, cs);
PixArtHC 0:2a85075b8467 209 grabData = new Pixart_OTS_GrabData_16bitXy();
PixArtHC 1:95917b856631 210 task = new Pixart_OTS_Task();
PixArtHC 1:95917b856631 211 initRegisters = create_registers(Pixart_OTS_9130_InitSetting, ARRAY_REG_SIZE(Pixart_OTS_9130_InitSetting));
PixArtHC 0:2a85075b8467 212 modelName = "P9130";
PixArtHC 0:2a85075b8467 213 HwVer = "PIX1621-v3.0";
PixArtHC 0:2a85075b8467 214 }
PixArtHC 0:2a85075b8467 215 break;
PixArtHC 0:2a85075b8467 216
PixArtHC 0:2a85075b8467 217 case PIXART_OTS_MODEL_5101:
PixArtHC 0:2a85075b8467 218 {
PixArtHC 0:2a85075b8467 219 com_port = new Pixart_SpiComPort(spi, cs);
PixArtHC 0:2a85075b8467 220 grabData = new Pixart_OTS_GrabData_16bitXy();
PixArtHC 1:95917b856631 221 task = new Pixart_OTS_Task();
PixArtHC 1:95917b856631 222 initRegisters = create_registers(Pixart_OTS_5101_InitSetting, ARRAY_REG_SIZE(Pixart_OTS_5101_InitSetting));
PixArtHC 0:2a85075b8467 223 modelName = "P5101";
PixArtHC 0:2a85075b8467 224 HwVer = "PIX1889-v1.0";
PixArtHC 0:2a85075b8467 225 }
PixArtHC 0:2a85075b8467 226 break;
PixArtHC 0:2a85075b8467 227
PixArtHC 0:2a85075b8467 228 default:
PixArtHC 0:2a85075b8467 229 return NULL;
PixArtHC 0:2a85075b8467 230 }
PixArtHC 0:2a85075b8467 231
PixArtHC 1:95917b856631 232 return new Pixart_OTS(pc, com_port, grabData, task, initRegisters, modelName, HwVer);
PixArtHC 1:95917b856631 233 }
PixArtHC 1:95917b856631 234
PixArtHC 1:95917b856631 235 Pixart_OTS* create_pixart_ots(Pixart_OTS_Model model, Serial &pc, SPI &spi, DigitalOut &cs, DigitalOut &ldp_enl_pin)
PixArtHC 1:95917b856631 236 {
PixArtHC 1:95917b856631 237 Pixart_ComPort *com_port = NULL;
PixArtHC 1:95917b856631 238 Pixart_OTS_GrabData *grabData = NULL;
PixArtHC 1:95917b856631 239 Pixart_OTS_Task *task = NULL;
PixArtHC 1:95917b856631 240 std::vector<Pixart_OTS_Register> initRegisters;
PixArtHC 1:95917b856631 241 std::string modelName;
PixArtHC 1:95917b856631 242 std::string HwVer;
PixArtHC 1:95917b856631 243
PixArtHC 1:95917b856631 244 switch (model)
PixArtHC 1:95917b856631 245 {
PixArtHC 1:95917b856631 246 case PIXART_OTS_MODEL_5101:
PixArtHC 1:95917b856631 247 {
PixArtHC 1:95917b856631 248 com_port = new Pixart_SpiComPort(spi, cs);
PixArtHC 1:95917b856631 249 grabData = new Pixart_OTS_GrabData_16bitXy();
PixArtHC 1:95917b856631 250 task = new Pixart_OTS_Task_5101(ldp_enl_pin);
PixArtHC 1:95917b856631 251 initRegisters = create_registers(Pixart_OTS_5101_InitSetting, ARRAY_REG_SIZE(Pixart_OTS_5101_InitSetting));
PixArtHC 1:95917b856631 252 modelName = "P5101";
PixArtHC 1:95917b856631 253 HwVer = "PIX1889-v1.0";
PixArtHC 1:95917b856631 254 }
PixArtHC 1:95917b856631 255 break;
PixArtHC 1:95917b856631 256
PixArtHC 1:95917b856631 257 default:
PixArtHC 1:95917b856631 258 return NULL;
PixArtHC 1:95917b856631 259 }
PixArtHC 1:95917b856631 260
PixArtHC 1:95917b856631 261 return new Pixart_OTS(pc, com_port, grabData, task, initRegisters, modelName, HwVer);
PixArtHC 0:2a85075b8467 262 }
PixArtHC 0:2a85075b8467 263
PixArtHC 0:2a85075b8467 264 static std::vector<Pixart_OTS_Register> create_registers(const uint8_t setting[][2], size_t setting_len)
PixArtHC 0:2a85075b8467 265 {
PixArtHC 0:2a85075b8467 266 std::vector<Pixart_OTS_Register> registers;
PixArtHC 0:2a85075b8467 267
PixArtHC 1:95917b856631 268 for (int i = 0; i < setting_len; ++i)
PixArtHC 0:2a85075b8467 269 {
PixArtHC 0:2a85075b8467 270 Pixart_OTS_Register reg;
PixArtHC 0:2a85075b8467 271 reg.addr = setting[i][0];
PixArtHC 0:2a85075b8467 272 reg.value = setting[i][1];
PixArtHC 0:2a85075b8467 273 registers.push_back(reg);
PixArtHC 0:2a85075b8467 274 }
PixArtHC 0:2a85075b8467 275
PixArtHC 0:2a85075b8467 276 return registers;
PixArtHC 0:2a85075b8467 277 }