Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Pixart_9123_Nucleo_Library 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 Mon Jul 18 2022 03:20:59 by
1.7.2

Low Power Right Angle Optical Track Sensor PMT9123