Library for PMT9123 for Nordic nRF51
Fork of Pixart_OTS_PMT9123 by
OTC.cpp
00001 #include "mbed.h" 00002 #include "PMT9123Set.h" 00003 #include "OTC.h" 00004 00005 00006 00007 #define PMT9123_ADDR (0x66) //PMT9123 address shift 1-bit 00008 #define I2C_ADDR PMT9123_ADDR 00009 #define PXI_PID 0x41 00010 #define DebounceT 300 //debounce time, unit:ms 00011 00012 // Structure for motion data 00013 union 00014 { 00015 unsigned char d[10]; 00016 struct 00017 { 00018 unsigned char motion; 00019 unsigned char deltaX; 00020 unsigned char deltaY; 00021 unsigned char deltaXY; 00022 unsigned char squal; 00023 //unsigned short shutter; 00024 unsigned char shutterH; 00025 unsigned char shutterL; 00026 unsigned char pix_max; 00027 unsigned char pix_avg; 00028 unsigned char pix_min; 00029 } m; 00030 } MotionData; 00031 00032 00033 Pixart_OTS::Pixart_OTS(I2C *i2c, int Period,OTSCallback callback,bool &Result) 00034 { 00035 m_i2c = i2c; 00036 m_OTSCallback = callback; 00037 //m_pc = pc; 00038 m_Period = Period; 00039 m_Address = 0x00; // Default address to PID 00040 00041 Result=PMT9123_init(); 00042 } 00043 00044 00045 00046 bool Pixart_OTS::PMT9123_init() 00047 { 00048 uint8_t v; 00049 00050 // Power up sequence 00051 // Drive NRESET low for 20us 00052 //digitalWrite(PIN_NRESET_NCS,LOW); 00053 //delayMicroseconds(20); 00054 //digitalWrite(PIN_NRESET_NCS,HIGH); 00055 // wait for 1.5ms 00056 //delayMicroseconds(1500); 00057 00058 // Enable register write 00059 writeRegister(0x41, 0xba); 00060 m_WriteEnable = true; // set to true for the write below to not repeat turning on 00061 wait_us(300); 00062 // Write 0x00 to register 0x1D 00063 Register_Write(0x1D, 0x00); 00064 wait_ms(10); 00065 v = Register_Read(0x1D); 00066 // Check if the bit 0 to 4 is set or not 00067 /*if (!IS_BIT_SET(v, 0x1F)) 00068 { 00069 // Error handling 00070 return false; 00071 }*/ 00072 Register_Write(0x48, 0x10); // Default resolution set to 2000 cpi 00073 00074 // Write in peformance optimization registers 00075 for(v = 0; v < INIT_PMT9123_REG_ARRAY_SIZE; v++) 00076 Register_Write(init_PMT9123_register_array[v][0], init_PMT9123_register_array[v][1]); 00077 00078 // Disable register write 00079 writeRegister(0x41, 0xb5); 00080 m_WriteEnable = false; // set to false for subsequent write to enable and disable it when writing register 00081 // Soft reset 00082 writeRegister(0x3a, 0x96); 00083 00084 wait_ms(50); 00085 00086 00087 m_ticker.attach_us(this,&Pixart_OTS::periodicCallback, m_Period*1000); 00088 00089 //m_pc->printf("\n\r~~~Start Real-time Gesture Demo~~~ \n\r"); 00090 00091 return true; 00092 } 00093 00094 void Pixart_OTS::periodicCallback(void) 00095 { 00096 PMT9123_ReadMotion(); 00097 } 00098 00099 void Pixart_OTS::PMT9123_ReadMotion(void) 00100 { 00101 int16_t temp_deltaXH, temp_deltaYH, deltaX16bit, deltaY16bit; 00102 int i = 0; 00103 00104 // Normal motion reading 00105 for (i = 0; i < 10; i++) 00106 { 00107 MotionData.d[i] = readRegister((0x02+i)); // using the single read version as motion cannot be double read and not affected 00108 } 00109 00110 temp_deltaXH = (MotionData.m.deltaXY<<4) & 0xF00; 00111 if(temp_deltaXH & 0x800) // -ve value spotted convert to 16-bit 00112 { 00113 temp_deltaXH |= 0xf000; 00114 } 00115 temp_deltaYH = (MotionData.m.deltaXY<<8) & 0xF00; 00116 if(temp_deltaYH & 0x800) // -ve value spotted convert to 16-bit 00117 { 00118 temp_deltaYH |= 0xf000; 00119 } 00120 00121 // Delta X is the vertical axis of the chip, only used if the ring can move up and down 00122 deltaX16bit = MotionData.m.deltaX | temp_deltaXH; 00123 // Delta Y is the value that it tracks on when turning the ring 00124 deltaY16bit = MotionData.m.deltaY | temp_deltaYH; 00125 00126 if (deltaY16bit != 0) 00127 m_OTSCallback(deltaY16bit); 00128 } 00129 00130 uint8_t Pixart_OTS::Register_Write(uint8_t addr, uint8_t data) 00131 { 00132 uint8_t result; 00133 unsigned char i = 1; 00134 00135 switch (addr) 00136 { 00137 // if WO registers, just bail out with value 0 00138 case 0x3A: 00139 case 0x3B: 00140 case 0x41: 00141 i = 0; // flag it 00142 break; 00143 default: 00144 if (!m_WriteEnable) 00145 { 00146 // For others, we need to enale register write first 00147 writeRegister(0x41, 0xba); 00148 wait_us(300); 00149 } 00150 break; 00151 } 00152 writeRegister(addr, data); 00153 if (i == 0) 00154 return 0; 00155 00156 // read back to confirm matching the write value, if not write again to maximum 3 times 00157 while ((result = Register_Read(addr)) != data) 00158 { 00159 if (i++ >= 3) 00160 break; 00161 writeRegister(addr, data); 00162 } 00163 if (!m_WriteEnable) 00164 writeRegister(0x41, 0xb5); 00165 return result; 00166 } 00167 00168 void Pixart_OTS::writeRegister(uint8_t addr, uint8_t data) 00169 { 00170 char data_write[2]; 00171 00172 data_write[0] = addr; 00173 data_write[1] = data; 00174 m_i2c->write(I2C_ADDR, data_write, 2, 0); 00175 } 00176 00177 uint8_t Pixart_OTS::Register_Read(uint8_t addr) 00178 { 00179 readRegister(addr); 00180 return readRegister(addr); // only take second read as valid return value 00181 } 00182 00183 uint8_t Pixart_OTS::readRegister(uint8_t addr) 00184 { 00185 char data_write[2]; 00186 char data_read[2]; 00187 00188 data_write[0] = addr; 00189 m_i2c->write(I2C_ADDR, data_write, 1, 0); 00190 m_i2c->read(I2C_ADDR, data_read, 1, 0); 00191 return data_read[0]; 00192 }
Generated on Sat Jul 16 2022 08:14:45 by 1.7.2