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

Files at this revision

API Documentation at this revision

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

Build_info.h Show annotated file Show diff for this revision Revisions of this file
Pixart_ComPort.cpp Show annotated file Show diff for this revision Revisions of this file
Pixart_OTS.cpp Show annotated file Show diff for this revision Revisions of this file
Pixart_OTS.h Show annotated file Show diff for this revision Revisions of this file
Pixart_OTS_GrabData.cpp Show annotated file Show diff for this revision Revisions of this file
Pixart_OTS_GrabData.h Show annotated file Show diff for this revision Revisions of this file
Pixart_OTS_InitSetting.h Show annotated file Show diff for this revision Revisions of this file
Pixart_OTS_Task.cpp Show annotated file Show diff for this revision Revisions of this file
Pixart_OTS_Task.h Show annotated file Show diff for this revision Revisions of this file
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);
+};