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

Pixart_OTS.cpp

Committer:
PixArtHC
Date:
2019-03-26
Revision:
1:95917b856631
Parent:
0:2a85075b8467

File content as of revision 1:95917b856631:

/* 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.h"

#ifdef DEBUG
    #define DEBUG_PRINT(...)    m_pc.printf(__VA_ARGS__)
#else
    #define DEBUG_PRINT(...)    {}
#endif

#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, Pixart_OTS_Task *task, const std::vector<Pixart_OTS_Register> &initRegisters, const std::string &model, const std::string &HwVer)
    : m_pc(pc)
    , m_comPort(new Pixart_OTS_ComPort(comPort))
    , m_grabData(grabData)
    , m_task(task)
    , m_initRegisters(initRegisters)
    , m_model(model)
    , m_HwVer(HwVer)
{
    wait_ms(500);
    print_build_info();
}

bool Pixart_OTS::sensor_init()
{
    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));
        return false;
    }

    m_totalX = 0;
    m_totalY = 0;
    
    for (size_t i = 0; i < m_initRegisters.size(); ++i)
    {
        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);
        
        if ((otsData.x != 0) || (otsData.y != 0))
        {
            m_totalX += otsData.x;
            m_totalY += otsData.y;

            DEBUG_PRINT("deltaX: %d\t\t\tdeltaY: %d\n\r", otsData.x, otsData.y);
            DEBUG_PRINT("X-axis Counts: %d\t\tY-axis Counts: %d\n\r", m_totalX, m_totalY);
        }
    }
}

int Pixart_OTS::get_default_i2c_slave_address()
{
    return I2C_ADDR;
}

std::string Pixart_OTS::get_model() const
{
    return m_model;
}

std::string Pixart_OTS::get_HwVer() const
{
    return m_HwVer;
}

void Pixart_OTS::print_build_info()
{
    DEBUG_PRINT("\r\n\n PixArt Mbed eval code, %s, %s", PRODUCT, get_model().c_str());
    DEBUG_PRINT("\r\n Fw version: %s, Hw version: %s, mbed version: %d", FW_VERSION, get_HwVer().c_str(), MBED_VERSION);
    DEBUG_PRINT("\r\n Build time: %s  %s\r\n", __TIME__, __DATE__);
}

Pixart_OTS* create_pixart_ots(Pixart_OTS_Model model, Serial &pc, I2C &i2c)
{   
    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_9125:
            {
                com_port = new Pixart_I2cComPort(i2c, Pixart_OTS::get_default_i2c_slave_address());
                grabData = new Pixart_OTS_GrabData_12bitXy();
                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";
            }
            break;

        case PIXART_OTS_MODEL_9126:
            {
                com_port = new Pixart_I2cComPort(i2c, Pixart_OTS::get_default_i2c_slave_address());
                grabData = new Pixart_OTS_GrabData_12bitXy();
                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";
            }
            break;

        case PIXART_OTS_MODEL_9150:
            {
                com_port = new Pixart_I2cComPort(i2c, Pixart_OTS::get_default_i2c_slave_address());
                grabData = new Pixart_OTS_GrabData_16bitXOnly();
                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";
            }
            break;

        default:
            return NULL;
    }

    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;

    switch (model)
    {
        case PIXART_OTS_MODEL_9125:
            {
                com_port = new Pixart_SpiComPort(spi, cs);
                grabData = new Pixart_OTS_GrabData_12bitXy();
                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";
            }
            break;

        case PIXART_OTS_MODEL_9130:
            {
                com_port = new Pixart_SpiComPort(spi, cs);
                grabData = new Pixart_OTS_GrabData_16bitXy();
                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";
            }
            break;

        case PIXART_OTS_MODEL_5101:
            {
                com_port = new Pixart_SpiComPort(spi, cs);
                grabData = new Pixart_OTS_GrabData_16bitXy();
                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";
            }
            break;

        default:
            return NULL;
    }

    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 < setting_len; ++i)
    {
        Pixart_OTS_Register reg;
        reg.addr = setting[i][0];
        reg.value = setting[i][1];
        registers.push_back(reg);
    }

    return registers;
}