Utilities for Pixart gesture recognition sensor PAJ7620U2 with interrupt

Dependents:   MtConnect04S_Gesture_HID

PAJ7620U2.cpp

Committer:
mtmkimi
Date:
2016-12-30
Revision:
0:5ab081158441

File content as of revision 0:5ab081158441:

/* Copyright (c) 2016 MtM Technology Corporation, MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
 * and associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "PAJ7620U2.h"


/* PAJ7620U2 initial registers */
const uint8_t PAJ7620U2_init_regs[][2] = {
    {0xEF,0x00},
    {0x37,0x07},
    {0x38,0x17},
    {0x39,0x06},
    {0x42,0x01},
    {0x46,0x2D},
    {0x47,0x0F},
    {0x48,0x3C},
    {0x49,0x00},
    {0x4A,0x1E},
    {0x4C,0x20},
    {0x51,0x10},
    {0x5E,0x10},
    {0x60,0x27},
    {0x80,0x42},
    {0x81,0x44},
    {0x82,0x04},
    {0x8B,0x01},
    {0x90,0x06},
    //{0x91,0x0A}
    {0x95,0x0A},
    {0x96,0x0C},
    {0x97,0x05},
    {0x9A,0x14},
    {0x9C,0x3F},
    {0xA5,0x19},
    {0xCC,0x19},
    {0xCD,0x0B},
    {0xCE,0x13},
    {0xCF,0x64},
    {0xD0,0x21},
    {0xEF,0x01},
    {0x02,0x0F},
    {0x03,0x10},
    {0x04,0x02},
    {0x25,0x01},
    {0x27,0x39},
    {0x28,0x7F},
    {0x29,0x08},
    {0x3E,0xFF},
    {0x5E,0x3D},
    {0x65,0x96},
    {0x67,0x97},
    {0x69,0xCD},
    {0x6A,0x01},
    {0x6D,0x2C},
    {0x6E,0x01},
    {0x72,0x01},
    {0x73,0x35},
    {0x77,0x01},
    {0xEF,0x00},
};

#if 0
//  {0xEF,0x00},                                              
    {0x41,0xFF},//R_Int_1_En[7:0]                             
//  {0x42,0x01},//R_Int_2_En[7:0]                             
//  {0x46,0x2D},//R_AELedOff_UB[7:0]                          
//  {0x47,0x0F},//R_AELedOff_LB[7:0]                          
//m {0x48,0x70},//R_AE_Exposure_UB[7:0]                       
//  {0x49,0x00},//R_AE_Exposure_UB[15:8]                      
//m {0x4A,0x38},//R_AE_Exposure_LB[7:0]                       
    {0x4B,0x00},//R_AE_Exposure_LB[15:8]                      
//  {0x4C,0x20},//R_AE_Gain_UB[7:0]                           
    {0x4D,0x00},//R_AE_Gain_LB[7:0]                           
//  {0x51,0x10},//R_AE_EnH = 1                                
    {0x5C,0x02},//R_SenClkPrd[5:0]                            
    {0x5E,0x10},//R_SRAM_CLK_manual                           
//  {0x80,0x42},//GPIO setting                                
//  {0x81,0x44},//GPIO setting                                
//m {0x82,0x0C},//Interrupt IO setting                        
    {0x83,0x20},//R_LightThd[7:0]                             
    {0x84,0x20},//R_ObjectSizeStartTh[7:0]                    
    {0x85,0x00},//R_ObjectSizeStartTh[9:8]                    
    {0x86,0x10},//R_ObjectSizeEndTh[7:0]                      
    {0x87,0x00},//R_ObjectSizeEndTh[9:8]                      
//  {0x8B,0x01},//R_Cursor_ObjectSizeTh[7:0]                  
    {0x8D,0x00},//R_TimeDelayNum[7:0]                         
//  {0x90,0x06},//R_NoMotionCountThd[6:0]                     
    {0x91,0x06},//R_NoObjectCountThd[6:0]                     
    {0x93,0x0D},//R_XDirectionThd[4:0]                        
    {0x94,0x0A},//R_YDirectionThd[4:0]                        
//  {0x95,0x0A},//R_ZDirectionThd[4:0]                        
//  {0x96,0x0C},//R_ZDirectionXYThd[4:0]                      
//  {0x97,0x05},//R_ZDirectionAngleThd[3:0]                   
//  {0x9A,0x14},//R_RotateXYThd[4:0]                          
//  {0x9C,0x3F},//Filter setting                              
    {0x9F,0xF9},//R_UseBGModel is enable                      
    {0xA0,0x48},//R_BGUpdateMaxIntensity[7:0]                 
//  {0xA5,0x19},//R_FilterAverage_Mode                        
//  {0xCC,0x19},//R_YtoZSum[5:0]                              
//  {0xCD,0x0B},//R_YtoZFactor[5:0]                           
//  {0xCE,0x13},//bit[2:0] = R_PositionFilterLength[2:0]      
//m {0xCF,0x62},//bit[3:0] = R_WaveCountThd[3:0]              
//  {0xD0,0x21},//R_AbortXYRatio[4:0] & R_AbortLength[6:0]    

//  {0xEF,0x01},                                              
    {0x00,0x1E},//Cmd_HSize[5:0]                              
    {0x01,0x1E},//Cmd_VSize[5:0]                              
//  {0x02,0x0F},//Cmd_HStart[5:0]                             
//m {0x03,0x0F},//Cmd_VStart[5:0]                             
//  {0x04,0x02},//Sensor skip & flip                          
//  {0x25,0x01},//R_LensShadingComp_EnH                       
    {0x26,0x00},//R_OffsetX[6:0]                              
//  {0x27,0x39},//R_OffsetY[6:0]                              
//  {0x28,0x7F},//R_LSC[6:0]                                  
//  {0x29,0x08},//R_LSFT[3:0]                                 
    {0x30,0x03},//R_LED_SoftStart_time[7:0]                   
    {0x32,0x1A},//R_LED1_DAC_UB[4:0]                          
    {0x33,0x1A},//R_LED2_DAC_UB[4:0]                          
//  {0x3E,0xFF},//Cmd_DebugPattern[7:0]                       
//  {0x5E,0x3D},//analog voltage setting                      
//m {0x65,0xAC},//R_IDLE_TIME[7:0] - 120fps  
    {0x66,0x00},//R_IDLE_TIME[15:8]                           
//  {0x67,0x97},//R_IDLE_TIME_SLEEP_1[7:0]                    
    {0x68,0x01},//R_IDLE_TIME_SLEEP_1[15:8]                   
//  {0x69,0xCD},//R_IDLE_TIME_SLEEP_2[7:0]                    
//  {0x6A,0x01},//R_IDLE_TIME_SLEEP_2[15:8]                   
    {0x6B,0xB0},//R_Obj_TIME_1[7:0]                           
    {0x6C,0x04},//R_Obj_TIME_1[15:8]                          
//  {0x6D,0x2C},//R_Obj_TIME_2[7:0]                           
//  {0x6E,0x01},//R_Obj_TIME_2[15:8]                          
//  {0x72,0x01},//R_TG_EnH                                    
//  {0x73,0x35},//Auto Sleep & Wakeup mode                    
    {0x74,0x00},//R_Control_Mode[2:0]                         
//  {0x77,0x01},//R_SRAM_Read_EnH
    {0xEF,0x00}
#endif

#define PAJ7620U2_INIT_REGS_SIZE (sizeof(PAJ7620U2_init_regs)/sizeof(PAJ7620U2_init_regs[0]))


PAJ7620U2::PAJ7620U2(PinName sda, PinName scl, PinName int1) :
_i2c(sda, scl), _int1(int1) {

    /* Check the sensor wake-up has finished */
    while(1){
        char val;
        RegRead(0x00, &val, 1);
        if(val == 0x20) break;
        wait(0.1);
    }

    /* Read sensor PID, VID */
    char id[3];
    RegRead(0x00, id, 3);
    PID = (((uint16_t)id[1]) << 8) + id[0];
    VID = id[2];
  
    /* Initial sensor */
    for(int i=0; i<PAJ7620U2_INIT_REGS_SIZE ;i++){
        RegWrite(PAJ7620U2_init_regs[i][0], PAJ7620U2_init_regs[i][1]);
    }
    wait(0.3); 

    /* Clear interrupt flags */
    char dummy[2];
    RegRead(0x43, dummy, 2);

}

uint16_t PAJ7620U2::ReadIntFlag(void) {
    char val[2];
    RegRead(0x43, val, 2);
    return (((uint16_t)val[1]) << 8) + val[0];
}

void PAJ7620U2::IntEvent(void(*fptr)(void)) {
    _int1.mode(PullNone);   // external pull-up
    _int1.fall(fptr);       // falling edge trigger
}

void PAJ7620U2::RegWrite(char reg, char val) {
    char data[2];
    data[0] = reg;
    data[1] = val;
    _i2c.write(PAJ7620U2_SLAVE_ADDR, data, 2, 0);
}

void PAJ7620U2::RegRead(char reg, char *val, int len) {
    _i2c.write(PAJ7620U2_SLAVE_ADDR, &reg, 1, 0);
    _i2c.read (PAJ7620U2_SLAVE_ADDR, val, len);
}

void PAJ7620U2::RegReadModifyWrite(char reg, char clr_mask, char set_mask) {
    char val;
    RegRead (reg, &val, 1);             // Read
    val = (val & ~clr_mask) | set_mask; // Modify
    RegWrite(reg, val);                 // Write
}