Utilities for Pixart gesture recognition sensor PAJ7620U2 with interrupt

Dependents:   MtConnect04S_Gesture_HID

Revision:
0:5ab081158441
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PAJ7620U2.cpp	Fri Dec 30 07:26:01 2016 +0000
@@ -0,0 +1,212 @@
+/* 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
+}