PixArt Optical Track Sensor, OTS, library initial release v1.0. Supports PAT9125, PAT9126, PAT9130, PAA5101. Future to support PAT9150.
Fork of Pixart_OTS by
Revision 1:95917b856631, committed 2019-03-26
- Comitter:
- PixArtHC
- Date:
- Tue Mar 26 22:32:06 2019 +0000
- Parent:
- 0:2a85075b8467
- Commit message:
- * 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.
Changed in this revision
diff -r 2a85075b8467 -r 95917b856631 Build_info.h --- a/Build_info.h Wed Mar 06 21:02:39 2019 +0000 +++ b/Build_info.h Tue Mar 26 22:32:06 2019 +0000 @@ -13,6 +13,11 @@ /* Library Revision History * V1.0: March 6, 2019 * First release. Supports PAT9125, PAT9126, PAT9130, PAA5101. Future to support PAT9150. + * V1.1: + * Add support to 5101 LD/LED switching. + * Add support to PAT9150. + * Fixed bug on loading initialization setting. + * Optimized register read timing. */ #pragma once @@ -20,5 +25,5 @@ #define DEBUG //#define USE_CALLBACK -#define FW_VERSION "v1.0" +#define FW_VERSION "v1.1" #define PRODUCT "Optical Track Sensor (OTS)"
diff -r 2a85075b8467 -r 95917b856631 Pixart_ComPort.cpp --- a/Pixart_ComPort.cpp Wed Mar 06 21:02:39 2019 +0000 +++ b/Pixart_ComPort.cpp Tue Mar 26 22:32:06 2019 +0000 @@ -56,7 +56,7 @@ m_cs = 0; addr = addr & 0x7F; m_spi.write(addr); - wait_us(1); + //wait_us(1); uint8_t data_read = m_spi.write(0x00); m_cs = 1;
diff -r 2a85075b8467 -r 95917b856631 Pixart_OTS.cpp --- a/Pixart_OTS.cpp Wed Mar 06 21:02:39 2019 +0000 +++ b/Pixart_OTS.cpp Tue Mar 26 22:32:06 2019 +0000 @@ -6,7 +6,6 @@ */ #include "Pixart_OTS.h" -#include "mbed.h" #ifdef DEBUG #define DEBUG_PRINT(...) m_pc.printf(__VA_ARGS__) @@ -14,17 +13,51 @@ #define DEBUG_PRINT(...) {} #endif -#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) +#define ARRAY_REG_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) #define I2C_ADDR (0x75 << 1) //I2C address @ID_SEL=Low (apply to 9125/26/50) #define PXI_WMI 0x31 +class Pixart_OTS_ComPort : public Pixart_ComPort +{ +public: + Pixart_OTS_ComPort(Pixart_ComPort *comPort) + : m_comPort(comPort) + { + } + + virtual void writeRegister(uint8_t addr, uint8_t data) + { + if (addr == 0x7F || addr == 0x06 || addr == 0x03 || addr == 0x2A) { + m_comPort->writeRegister(addr, data); + } + + else { + uint8_t read_value; + do + { + m_comPort->writeRegister(addr, data); + read_value = m_comPort->readRegister(addr); + } while (read_value != data); + } + } + + virtual uint8_t readRegister(uint8_t addr) + { + return m_comPort->readRegister(addr); + } + +private: + Pixart_ComPort *m_comPort; +}; + static std::vector<Pixart_OTS_Register> create_registers(const uint8_t setting[][2], size_t setting_len); -Pixart_OTS::Pixart_OTS(Serial &pc, Pixart_ComPort *comPort, Pixart_OTS_GrabData *grabData, const std::vector<Pixart_OTS_Register> &initRegisters, const std::string &model, const std::string &HwVer) +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) : m_pc(pc) - , m_comPort(comPort) + , m_comPort(new Pixart_OTS_ComPort(comPort)) , m_grabData(grabData) + , m_task(task) , m_initRegisters(initRegisters) , m_model(model) , m_HwVer(HwVer) @@ -35,8 +68,8 @@ bool Pixart_OTS::sensor_init() { - m_comPort->writeRegister(0x7F, 0x00); - m_comPort->writeRegister(0x06, 0x80); wait_ms(10); + m_task->reset_task(*m_comPort); + wait_ms(10); if (m_comPort->readRegister(0x00) != PXI_WMI) { DEBUG_PRINT("\r\n << Sensor_Init (Fail), ID = %2X", m_comPort->readRegister(0x00)); @@ -50,12 +83,16 @@ { m_comPort->writeRegister(m_initRegisters[i].addr, m_initRegisters[i].value); } + + m_task->pre_task(*m_comPort); return true; } void Pixart_OTS::periodic_callback() { + m_task->periodic_task(*m_comPort); + if (m_comPort->readRegister(0x02) & 0x80) { Pixart_OTS_OtsData otsData = m_grabData->grab(*m_comPort); @@ -97,6 +134,7 @@ { Pixart_ComPort *com_port = NULL; Pixart_OTS_GrabData *grabData = NULL; + Pixart_OTS_Task *task = NULL; std::vector<Pixart_OTS_Register> initRegisters; std::string modelName; std::string HwVer; @@ -107,7 +145,8 @@ { com_port = new Pixart_I2cComPort(i2c, Pixart_OTS::get_default_i2c_slave_address()); grabData = new Pixart_OTS_GrabData_12bitXy(); - initRegisters = create_registers(Pixart_OTS_9125_InitSetting, ARRAY_SIZE(Pixart_OTS_9125_InitSetting)); + task = new Pixart_OTS_Task(); + initRegisters = create_registers(Pixart_OTS_9125_InitSetting, ARRAY_REG_SIZE(Pixart_OTS_9125_InitSetting)); modelName = "P9125"; HwVer = "PIX1484-v5.0"; } @@ -117,7 +156,8 @@ { com_port = new Pixart_I2cComPort(i2c, Pixart_OTS::get_default_i2c_slave_address()); grabData = new Pixart_OTS_GrabData_12bitXy(); - initRegisters = create_registers(Pixart_OTS_9126_InitSetting, ARRAY_SIZE(Pixart_OTS_9126_InitSetting)); + task = new Pixart_OTS_Task(); + initRegisters = create_registers(Pixart_OTS_9126_InitSetting, ARRAY_REG_SIZE(Pixart_OTS_9126_InitSetting)); modelName = "P9126"; HwVer = "PIX1484-v6.0"; } @@ -127,7 +167,8 @@ { com_port = new Pixart_I2cComPort(i2c, Pixart_OTS::get_default_i2c_slave_address()); grabData = new Pixart_OTS_GrabData_16bitXOnly(); - initRegisters = create_registers(Pixart_OTS_9150_InitSetting, ARRAY_SIZE(Pixart_OTS_9150_InitSetting)); + task = new Pixart_OTS_Task(); + initRegisters = create_registers(Pixart_OTS_9150_InitSetting, ARRAY_REG_SIZE(Pixart_OTS_9150_InitSetting)); modelName = "P9150"; HwVer = "PIX1xxx-vx.0"; } @@ -137,13 +178,14 @@ return NULL; } - return new Pixart_OTS(pc, com_port, grabData, initRegisters, modelName, HwVer); + return new Pixart_OTS(pc, com_port, grabData, task, initRegisters, modelName, HwVer); } Pixart_OTS* create_pixart_ots(Pixart_OTS_Model model, Serial &pc, SPI &spi, DigitalOut &cs) { Pixart_ComPort *com_port = NULL; Pixart_OTS_GrabData *grabData = NULL; + Pixart_OTS_Task *task = NULL; std::vector<Pixart_OTS_Register> initRegisters; std::string modelName; std::string HwVer; @@ -154,7 +196,8 @@ { com_port = new Pixart_SpiComPort(spi, cs); grabData = new Pixart_OTS_GrabData_12bitXy(); - initRegisters = create_registers(Pixart_OTS_9125_InitSetting, ARRAY_SIZE(Pixart_OTS_9125_InitSetting)); + task = new Pixart_OTS_Task(); + initRegisters = create_registers(Pixart_OTS_9125_InitSetting, ARRAY_REG_SIZE(Pixart_OTS_9125_InitSetting)); modelName = "P9125"; HwVer = "PIX1484-v5.0"; } @@ -164,7 +207,8 @@ { com_port = new Pixart_SpiComPort(spi, cs); grabData = new Pixart_OTS_GrabData_16bitXy(); - initRegisters = create_registers(Pixart_OTS_9130_InitSetting, ARRAY_SIZE(Pixart_OTS_9130_InitSetting)); + task = new Pixart_OTS_Task(); + initRegisters = create_registers(Pixart_OTS_9130_InitSetting, ARRAY_REG_SIZE(Pixart_OTS_9130_InitSetting)); modelName = "P9130"; HwVer = "PIX1621-v3.0"; } @@ -174,7 +218,8 @@ { com_port = new Pixart_SpiComPort(spi, cs); grabData = new Pixart_OTS_GrabData_16bitXy(); - initRegisters = create_registers(Pixart_OTS_5101_InitSetting, ARRAY_SIZE(Pixart_OTS_5101_InitSetting)); + task = new Pixart_OTS_Task(); + initRegisters = create_registers(Pixart_OTS_5101_InitSetting, ARRAY_REG_SIZE(Pixart_OTS_5101_InitSetting)); modelName = "P5101"; HwVer = "PIX1889-v1.0"; } @@ -184,14 +229,43 @@ return NULL; } - return new Pixart_OTS(pc, com_port, grabData, initRegisters, modelName, HwVer); + return new Pixart_OTS(pc, com_port, grabData, task, initRegisters, modelName, HwVer); +} + +Pixart_OTS* create_pixart_ots(Pixart_OTS_Model model, Serial &pc, SPI &spi, DigitalOut &cs, DigitalOut &ldp_enl_pin) +{ + Pixart_ComPort *com_port = NULL; + Pixart_OTS_GrabData *grabData = NULL; + Pixart_OTS_Task *task = NULL; + std::vector<Pixart_OTS_Register> initRegisters; + std::string modelName; + std::string HwVer; + + switch (model) + { + case PIXART_OTS_MODEL_5101: + { + com_port = new Pixart_SpiComPort(spi, cs); + grabData = new Pixart_OTS_GrabData_16bitXy(); + task = new Pixart_OTS_Task_5101(ldp_enl_pin); + initRegisters = create_registers(Pixart_OTS_5101_InitSetting, ARRAY_REG_SIZE(Pixart_OTS_5101_InitSetting)); + modelName = "P5101"; + HwVer = "PIX1889-v1.0"; + } + break; + + default: + return NULL; + } + + return new Pixart_OTS(pc, com_port, grabData, task, initRegisters, modelName, HwVer); } static std::vector<Pixart_OTS_Register> create_registers(const uint8_t setting[][2], size_t setting_len) { std::vector<Pixart_OTS_Register> registers; - for (int i = 0; i < ARRAY_SIZE(Pixart_OTS_9125_InitSetting); ++i) + for (int i = 0; i < setting_len; ++i) { Pixart_OTS_Register reg; reg.addr = setting[i][0];
diff -r 2a85075b8467 -r 95917b856631 Pixart_OTS.h --- a/Pixart_OTS.h Wed Mar 06 21:02:39 2019 +0000 +++ b/Pixart_OTS.h Tue Mar 26 22:32:06 2019 +0000 @@ -10,6 +10,7 @@ #include "Build_info.h" #include "Pixart_ComPort.h" #include "Pixart_OTS_GrabData.h" +#include "Pixart_OTS_Task.h" #include "Pixart_OTS_InitSetting.h" #include <vector> @@ -34,7 +35,7 @@ class Pixart_OTS { public: - Pixart_OTS(Serial &pc, Pixart_ComPort *comPort, Pixart_OTS_GrabData *grabData, const std::vector<Pixart_OTS_Register> &initRegisters, const std::string &model, const std::string &HwVer); + 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); bool sensor_init(); void periodic_callback(); @@ -46,6 +47,7 @@ Serial &m_pc; Pixart_ComPort *m_comPort; Pixart_OTS_GrabData *m_grabData; + Pixart_OTS_Task *m_task; std::vector<Pixart_OTS_Register> m_initRegisters; std::string m_model; std::string m_HwVer; @@ -58,3 +60,4 @@ Pixart_OTS* create_pixart_ots(Pixart_OTS_Model model, Serial &pc, I2C &i2c); Pixart_OTS* create_pixart_ots(Pixart_OTS_Model model, Serial &pc, SPI &spi, DigitalOut &cs); +Pixart_OTS* create_pixart_ots(Pixart_OTS_Model model, Serial &pc, SPI &spi, DigitalOut &cs, DigitalOut &ldp_enl_pin);
diff -r 2a85075b8467 -r 95917b856631 Pixart_OTS_GrabData.cpp --- a/Pixart_OTS_GrabData.cpp Wed Mar 06 21:02:39 2019 +0000 +++ b/Pixart_OTS_GrabData.cpp Tue Mar 26 22:32:06 2019 +0000 @@ -45,8 +45,12 @@ Pixart_OTS_OtsData Pixart_OTS_GrabData_16bitXOnly::grab(Pixart_ComPort &com_port) { + int16_t deltaX_low = com_port.readRegister(0x03); + int16_t deltaX_high = 0; + deltaX_high = com_port.readRegister(0x04) << 8; + Pixart_OTS_OtsData otsData; - otsData.x = 0; + otsData.x = deltaX_high | deltaX_low; otsData.y = 0; return otsData; }
diff -r 2a85075b8467 -r 95917b856631 Pixart_OTS_GrabData.h --- a/Pixart_OTS_GrabData.h Wed Mar 06 21:02:39 2019 +0000 +++ b/Pixart_OTS_GrabData.h Tue Mar 26 22:32:06 2019 +0000 @@ -5,7 +5,7 @@ * License: Apache-2.0; http://www.apache.org/licenses/LICENSE-2.0 */ -#pragma once +#pragma once #include "Pixart_ComPort.h" struct Pixart_OTS_OtsData
diff -r 2a85075b8467 -r 95917b856631 Pixart_OTS_InitSetting.h --- a/Pixart_OTS_InitSetting.h Wed Mar 06 21:02:39 2019 +0000 +++ b/Pixart_OTS_InitSetting.h Tue Mar 26 22:32:06 2019 +0000 @@ -37,7 +37,7 @@ { { 0x7F, 0x00 }, //Switch to bank0 { 0x09, 0x5A }, //Disables write-protect. - + { 0x0A, 0x0F }, // set X-axis resolution (depends on application) { 0x09, 0x00 }, //Enable write protect }; @@ -141,6 +141,8 @@ static const uint8_t Pixart_OTS_5101_InitSetting[][2] = { + { 0x09,0x5A }, // disable write protect + { 0x51,0x06 }, // To set LD power first, power should be <= 6 { 0x7F,0x00 }, // Bank0, not allowed to perform SPIWriteRead { 0x05,0xA8 }, { 0x07,0xCC },
diff -r 2a85075b8467 -r 95917b856631 Pixart_OTS_Task.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Pixart_OTS_Task.cpp Tue Mar 26 22:32:06 2019 +0000 @@ -0,0 +1,128 @@ +/* PixArt Optical Finger Navigation, OFN, sensor driver. + * By PixArt Imaging Inc. + * Primary Engineer: Hill Chen (PixArt USA) + * + * License: Apache-2.0; http://www.apache.org/licenses/LICENSE-2.0 + */ + +#include "Pixart_OTS_Task.h" + +Pixart_OTS_Task_5101::Pixart_OTS_Task_5101(DigitalOut &ldp_enl_pin) + : LD2LED_TH(0x700) + , LED2LD_TH(0x500) + , FIQ_AVG(0) + , FIQt(0) + , EXTLED_ON(0) + , m_ldp_enl(ldp_enl_pin) +{ + m_ldp_enl = 0; +} + +void Pixart_OTS_Task_5101::reset_task(Pixart_ComPort &com_port) +{ + com_port.writeRegister(0x7F, 0x00); + com_port.writeRegister(0x08, 0x01); +} + +void Pixart_OTS_Task_5101::pre_task(Pixart_ComPort &com_port) +{ + com_port.writeRegister(0x5D, 0x3E); + wait_ms(10); // 10ms delay + com_port.writeRegister(0x5D, 0x3F); + PAA5101_LD_MODE(com_port); // LD mode is default + com_port.writeRegister(0x09, 0x00); // enable write protect +} + +void Pixart_OTS_Task_5101::periodic_task(Pixart_ComPort &com_port) +{ + uint8_t loopi = 0; + FIQ_AVG = 0; + + uint8_t data_msb = com_port.readRegister(0x75); + uint8_t data_lsb = com_port.readRegister(0x76); + FIQ[FIQt] = ((uint16_t)(data_msb))*256 + (uint16_t)data_lsb; + + if(FIQt==7) //every 8 sampling to decide LD/LED mode + { + for(loopi=0;loopi<8;loopi++) + { + FIQ_AVG = FIQ_AVG + FIQ[loopi]; + } + + if(EXTLED_ON == 1 && FIQ_AVG < LED2LD_TH) // Check if change to LD MODE + { + PAA5101_LD_MODE(com_port); + wait_ms(40); // delay for light source change + com_port.writeRegister(0x03,0x00); + } + else if(EXTLED_ON == 0 && FIQ_AVG < LD2LED_TH) // Check if change to external LED MODE + { + PAA5101_EXTLED_MODE(com_port); + wait_ms(40); // delay for light source change + com_port.writeRegister(0x03,0x00); + } + } + FIQt = (FIQt+1) & 0x07; + // LD/LED switch process END +} + +void Pixart_OTS_Task_5101::PAA5101_LD_MODE(Pixart_ComPort &com_port) +{ + EXTLED_ON = 0; // Mode index: LD + + com_port.writeRegister(0x7F, 0x00); // Bank0 + com_port.writeRegister(0x09, 0x5A); // disable write protect + com_port.writeRegister(0x53, 0x01); + com_port.writeRegister(0x07, 0xCC); + com_port.writeRegister(0x0D, 0x05); + com_port.writeRegister(0x0E, 0x05); + com_port.writeRegister(0x19, 0x24); + com_port.writeRegister(0x7F, 0x01); // Bank1 + com_port.writeRegister(0x1D, 0x18); + com_port.writeRegister(0x1F, 0x12); + com_port.writeRegister(0x42, 0x40); + com_port.writeRegister(0x37, 0x60); + com_port.writeRegister(0x43, 0x0A); + com_port.writeRegister(0x7F, 0x04); // Bank4 + com_port.writeRegister(0x06, 0x03); + com_port.writeRegister(0x7F, 0x05); // Bank5 + com_port.writeRegister(0x2E, 0x02); + com_port.writeRegister(0x48, 0x00); + com_port.writeRegister(0x3E, 0x05); + com_port.writeRegister(0x7F, 0x06); // Bank6 + com_port.writeRegister(0x34, 0x01); + com_port.writeRegister(0x7F, 0x00); // Bank0 + com_port.writeRegister(0x09, 0x00); // enable write protect + + m_ldp_enl = 0; // GPIO controls PMOS to low (i.e. turn on LD power) +} + +void Pixart_OTS_Task_5101::PAA5101_EXTLED_MODE(Pixart_ComPort &com_port) +{ + EXTLED_ON = 1; // Mode index: LED + m_ldp_enl = 1; // GPIO controls PMOS to high (i.e. turn off LD power) + + com_port.writeRegister(0x7F, 0x00); // Bank0 + com_port.writeRegister(0x09, 0x5A); // disable write protect + com_port.writeRegister(0x07, 0x55); + com_port.writeRegister(0x0D, 0x7D); + com_port.writeRegister(0x0E, 0x7D); + com_port.writeRegister(0x19, 0x3C); + com_port.writeRegister(0x7F, 0x01); // Bank1 + com_port.writeRegister(0x1D, 0x00); + com_port.writeRegister(0x1F, 0x00); + com_port.writeRegister(0x42, 0x20); + com_port.writeRegister(0x37, 0x18); + com_port.writeRegister(0x43, 0x02); + com_port.writeRegister(0x7F, 0x04); // Bank4 + com_port.writeRegister(0x06, 0x00); + com_port.writeRegister(0x7F, 0x05); // Bank5 + com_port.writeRegister(0x2E, 0x08); + com_port.writeRegister(0x48, 0x02); + com_port.writeRegister(0x3E, 0x85); + com_port.writeRegister(0x7F, 0x06); // Bank6 + com_port.writeRegister(0x34, 0x09); + com_port.writeRegister(0x7F, 0x00); // Bank0 + com_port.writeRegister(0x53, 0x00); + com_port.writeRegister(0x09, 0x00); // enable write protect +}
diff -r 2a85075b8467 -r 95917b856631 Pixart_OTS_Task.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Pixart_OTS_Task.h Tue Mar 26 22:32:06 2019 +0000 @@ -0,0 +1,42 @@ +/* PixArt Optical Finger Navigation, OFN, sensor driver. + * By PixArt Imaging Inc. + * Primary Engineer: Hill Chen (PixArt USA) + * + * License: Apache-2.0; http://www.apache.org/licenses/LICENSE-2.0 + */ + +#pragma once +#include "mbed.h" +#include "Pixart_ComPort.h" + +class Pixart_OTS_Task +{ +public: + virtual void reset_task(Pixart_ComPort &com_port){ + com_port.writeRegister(0x7F, 0x00); + com_port.writeRegister(0x06, 0x80);} + virtual void pre_task(Pixart_ComPort &com_port) {} + virtual void periodic_task(Pixart_ComPort &com_port) {} +}; + +class Pixart_OTS_Task_5101: public Pixart_OTS_Task +{ +private: + uint16_t LD2LED_TH; + uint16_t LED2LD_TH; + uint16_t FIQ[8]; + uint16_t FIQ_AVG; + uint8_t FIQt; + uint8_t EXTLED_ON; // Mode index, 0:LD, 1:LED + DigitalOut &m_ldp_enl; + + void PAA5101_LD_MODE(Pixart_ComPort &com_port); + void PAA5101_EXTLED_MODE(Pixart_ComPort &com_port); + +public: + Pixart_OTS_Task_5101(DigitalOut &ldp_enl_pin); + + virtual void reset_task(Pixart_ComPort &com_port); + virtual void pre_task(Pixart_ComPort &com_port); + virtual void periodic_task(Pixart_ComPort &com_port); +};