Library for PMT9123 for Nordic nRF51

Fork of Pixart_OTS_PMT9123 by PixArt Imaging

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers OTC.cpp Source File

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 }