Library for PMT9123 for Nordic nRF51

Fork of Pixart_OTS_PMT9123 by PixArt Imaging

Committer:
pixus_mbed
Date:
Mon May 08 22:51:47 2017 +0000
Revision:
0:31779183b108
Initial Release for PMT9123 on mbed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pixus_mbed 0:31779183b108 1 #include "mbed.h"
pixus_mbed 0:31779183b108 2 #include "PMT9123Set.h"
pixus_mbed 0:31779183b108 3 #include "OTC.h"
pixus_mbed 0:31779183b108 4
pixus_mbed 0:31779183b108 5
pixus_mbed 0:31779183b108 6
pixus_mbed 0:31779183b108 7 #define PMT9123_ADDR (0x66) //PMT9123 address shift 1-bit
pixus_mbed 0:31779183b108 8 #define I2C_ADDR PMT9123_ADDR
pixus_mbed 0:31779183b108 9 #define PXI_PID 0x41
pixus_mbed 0:31779183b108 10 #define DebounceT 300 //debounce time, unit:ms
pixus_mbed 0:31779183b108 11
pixus_mbed 0:31779183b108 12 // Structure for motion data
pixus_mbed 0:31779183b108 13 union
pixus_mbed 0:31779183b108 14 {
pixus_mbed 0:31779183b108 15 unsigned char d[10];
pixus_mbed 0:31779183b108 16 struct
pixus_mbed 0:31779183b108 17 {
pixus_mbed 0:31779183b108 18 unsigned char motion;
pixus_mbed 0:31779183b108 19 unsigned char deltaX;
pixus_mbed 0:31779183b108 20 unsigned char deltaY;
pixus_mbed 0:31779183b108 21 unsigned char deltaXY;
pixus_mbed 0:31779183b108 22 unsigned char squal;
pixus_mbed 0:31779183b108 23 //unsigned short shutter;
pixus_mbed 0:31779183b108 24 unsigned char shutterH;
pixus_mbed 0:31779183b108 25 unsigned char shutterL;
pixus_mbed 0:31779183b108 26 unsigned char pix_max;
pixus_mbed 0:31779183b108 27 unsigned char pix_avg;
pixus_mbed 0:31779183b108 28 unsigned char pix_min;
pixus_mbed 0:31779183b108 29 } m;
pixus_mbed 0:31779183b108 30 } MotionData;
pixus_mbed 0:31779183b108 31
pixus_mbed 0:31779183b108 32
pixus_mbed 0:31779183b108 33 Pixart_OTS::Pixart_OTS(I2C *i2c, int Period,OTSCallback callback,bool &Result)
pixus_mbed 0:31779183b108 34 {
pixus_mbed 0:31779183b108 35 m_i2c = i2c;
pixus_mbed 0:31779183b108 36 m_OTSCallback = callback;
pixus_mbed 0:31779183b108 37 //m_pc = pc;
pixus_mbed 0:31779183b108 38 m_Period = Period;
pixus_mbed 0:31779183b108 39 m_Address = 0x00; // Default address to PID
pixus_mbed 0:31779183b108 40
pixus_mbed 0:31779183b108 41 Result=PMT9123_init();
pixus_mbed 0:31779183b108 42 }
pixus_mbed 0:31779183b108 43
pixus_mbed 0:31779183b108 44
pixus_mbed 0:31779183b108 45
pixus_mbed 0:31779183b108 46 bool Pixart_OTS::PMT9123_init()
pixus_mbed 0:31779183b108 47 {
pixus_mbed 0:31779183b108 48 uint8_t v;
pixus_mbed 0:31779183b108 49
pixus_mbed 0:31779183b108 50 // Power up sequence
pixus_mbed 0:31779183b108 51 // Drive NRESET low for 20us
pixus_mbed 0:31779183b108 52 //digitalWrite(PIN_NRESET_NCS,LOW);
pixus_mbed 0:31779183b108 53 //delayMicroseconds(20);
pixus_mbed 0:31779183b108 54 //digitalWrite(PIN_NRESET_NCS,HIGH);
pixus_mbed 0:31779183b108 55 // wait for 1.5ms
pixus_mbed 0:31779183b108 56 //delayMicroseconds(1500);
pixus_mbed 0:31779183b108 57
pixus_mbed 0:31779183b108 58 // Enable register write
pixus_mbed 0:31779183b108 59 writeRegister(0x41, 0xba);
pixus_mbed 0:31779183b108 60 m_WriteEnable = true; // set to true for the write below to not repeat turning on
pixus_mbed 0:31779183b108 61 wait_us(300);
pixus_mbed 0:31779183b108 62 // Write 0x00 to register 0x1D
pixus_mbed 0:31779183b108 63 Register_Write(0x1D, 0x00);
pixus_mbed 0:31779183b108 64 wait_ms(10);
pixus_mbed 0:31779183b108 65 v = Register_Read(0x1D);
pixus_mbed 0:31779183b108 66 // Check if the bit 0 to 4 is set or not
pixus_mbed 0:31779183b108 67 /*if (!IS_BIT_SET(v, 0x1F))
pixus_mbed 0:31779183b108 68 {
pixus_mbed 0:31779183b108 69 // Error handling
pixus_mbed 0:31779183b108 70 return false;
pixus_mbed 0:31779183b108 71 }*/
pixus_mbed 0:31779183b108 72 Register_Write(0x48, 0x10); // Default resolution set to 2000 cpi
pixus_mbed 0:31779183b108 73
pixus_mbed 0:31779183b108 74 // Write in peformance optimization registers
pixus_mbed 0:31779183b108 75 for(v = 0; v < INIT_PMT9123_REG_ARRAY_SIZE; v++)
pixus_mbed 0:31779183b108 76 Register_Write(init_PMT9123_register_array[v][0], init_PMT9123_register_array[v][1]);
pixus_mbed 0:31779183b108 77
pixus_mbed 0:31779183b108 78 // Disable register write
pixus_mbed 0:31779183b108 79 writeRegister(0x41, 0xb5);
pixus_mbed 0:31779183b108 80 m_WriteEnable = false; // set to false for subsequent write to enable and disable it when writing register
pixus_mbed 0:31779183b108 81 // Soft reset
pixus_mbed 0:31779183b108 82 writeRegister(0x3a, 0x96);
pixus_mbed 0:31779183b108 83
pixus_mbed 0:31779183b108 84 wait_ms(50);
pixus_mbed 0:31779183b108 85
pixus_mbed 0:31779183b108 86
pixus_mbed 0:31779183b108 87 m_ticker.attach_us(this,&Pixart_OTS::periodicCallback, m_Period*1000);
pixus_mbed 0:31779183b108 88
pixus_mbed 0:31779183b108 89 //m_pc->printf("\n\r~~~Start Real-time Gesture Demo~~~ \n\r");
pixus_mbed 0:31779183b108 90
pixus_mbed 0:31779183b108 91 return true;
pixus_mbed 0:31779183b108 92 }
pixus_mbed 0:31779183b108 93
pixus_mbed 0:31779183b108 94 void Pixart_OTS::periodicCallback(void)
pixus_mbed 0:31779183b108 95 {
pixus_mbed 0:31779183b108 96 PMT9123_ReadMotion();
pixus_mbed 0:31779183b108 97 }
pixus_mbed 0:31779183b108 98
pixus_mbed 0:31779183b108 99 void Pixart_OTS::PMT9123_ReadMotion(void)
pixus_mbed 0:31779183b108 100 {
pixus_mbed 0:31779183b108 101 int16_t temp_deltaXH, temp_deltaYH, deltaX16bit, deltaY16bit;
pixus_mbed 0:31779183b108 102 int i = 0;
pixus_mbed 0:31779183b108 103
pixus_mbed 0:31779183b108 104 // Normal motion reading
pixus_mbed 0:31779183b108 105 for (i = 0; i < 10; i++)
pixus_mbed 0:31779183b108 106 {
pixus_mbed 0:31779183b108 107 MotionData.d[i] = readRegister((0x02+i)); // using the single read version as motion cannot be double read and not affected
pixus_mbed 0:31779183b108 108 }
pixus_mbed 0:31779183b108 109
pixus_mbed 0:31779183b108 110 temp_deltaXH = (MotionData.m.deltaXY<<4) & 0xF00;
pixus_mbed 0:31779183b108 111 if(temp_deltaXH & 0x800) // -ve value spotted convert to 16-bit
pixus_mbed 0:31779183b108 112 {
pixus_mbed 0:31779183b108 113 temp_deltaXH |= 0xf000;
pixus_mbed 0:31779183b108 114 }
pixus_mbed 0:31779183b108 115 temp_deltaYH = (MotionData.m.deltaXY<<8) & 0xF00;
pixus_mbed 0:31779183b108 116 if(temp_deltaYH & 0x800) // -ve value spotted convert to 16-bit
pixus_mbed 0:31779183b108 117 {
pixus_mbed 0:31779183b108 118 temp_deltaYH |= 0xf000;
pixus_mbed 0:31779183b108 119 }
pixus_mbed 0:31779183b108 120
pixus_mbed 0:31779183b108 121 // Delta X is the vertical axis of the chip, only used if the ring can move up and down
pixus_mbed 0:31779183b108 122 deltaX16bit = MotionData.m.deltaX | temp_deltaXH;
pixus_mbed 0:31779183b108 123 // Delta Y is the value that it tracks on when turning the ring
pixus_mbed 0:31779183b108 124 deltaY16bit = MotionData.m.deltaY | temp_deltaYH;
pixus_mbed 0:31779183b108 125
pixus_mbed 0:31779183b108 126 if (deltaY16bit != 0)
pixus_mbed 0:31779183b108 127 m_OTSCallback(deltaY16bit);
pixus_mbed 0:31779183b108 128 }
pixus_mbed 0:31779183b108 129
pixus_mbed 0:31779183b108 130 uint8_t Pixart_OTS::Register_Write(uint8_t addr, uint8_t data)
pixus_mbed 0:31779183b108 131 {
pixus_mbed 0:31779183b108 132 uint8_t result;
pixus_mbed 0:31779183b108 133 unsigned char i = 1;
pixus_mbed 0:31779183b108 134
pixus_mbed 0:31779183b108 135 switch (addr)
pixus_mbed 0:31779183b108 136 {
pixus_mbed 0:31779183b108 137 // if WO registers, just bail out with value 0
pixus_mbed 0:31779183b108 138 case 0x3A:
pixus_mbed 0:31779183b108 139 case 0x3B:
pixus_mbed 0:31779183b108 140 case 0x41:
pixus_mbed 0:31779183b108 141 i = 0; // flag it
pixus_mbed 0:31779183b108 142 break;
pixus_mbed 0:31779183b108 143 default:
pixus_mbed 0:31779183b108 144 if (!m_WriteEnable)
pixus_mbed 0:31779183b108 145 {
pixus_mbed 0:31779183b108 146 // For others, we need to enale register write first
pixus_mbed 0:31779183b108 147 writeRegister(0x41, 0xba);
pixus_mbed 0:31779183b108 148 wait_us(300);
pixus_mbed 0:31779183b108 149 }
pixus_mbed 0:31779183b108 150 break;
pixus_mbed 0:31779183b108 151 }
pixus_mbed 0:31779183b108 152 writeRegister(addr, data);
pixus_mbed 0:31779183b108 153 if (i == 0)
pixus_mbed 0:31779183b108 154 return 0;
pixus_mbed 0:31779183b108 155
pixus_mbed 0:31779183b108 156 // read back to confirm matching the write value, if not write again to maximum 3 times
pixus_mbed 0:31779183b108 157 while ((result = Register_Read(addr)) != data)
pixus_mbed 0:31779183b108 158 {
pixus_mbed 0:31779183b108 159 if (i++ >= 3)
pixus_mbed 0:31779183b108 160 break;
pixus_mbed 0:31779183b108 161 writeRegister(addr, data);
pixus_mbed 0:31779183b108 162 }
pixus_mbed 0:31779183b108 163 if (!m_WriteEnable)
pixus_mbed 0:31779183b108 164 writeRegister(0x41, 0xb5);
pixus_mbed 0:31779183b108 165 return result;
pixus_mbed 0:31779183b108 166 }
pixus_mbed 0:31779183b108 167
pixus_mbed 0:31779183b108 168 void Pixart_OTS::writeRegister(uint8_t addr, uint8_t data)
pixus_mbed 0:31779183b108 169 {
pixus_mbed 0:31779183b108 170 char data_write[2];
pixus_mbed 0:31779183b108 171
pixus_mbed 0:31779183b108 172 data_write[0] = addr;
pixus_mbed 0:31779183b108 173 data_write[1] = data;
pixus_mbed 0:31779183b108 174 m_i2c->write(I2C_ADDR, data_write, 2, 0);
pixus_mbed 0:31779183b108 175 }
pixus_mbed 0:31779183b108 176
pixus_mbed 0:31779183b108 177 uint8_t Pixart_OTS::Register_Read(uint8_t addr)
pixus_mbed 0:31779183b108 178 {
pixus_mbed 0:31779183b108 179 readRegister(addr);
pixus_mbed 0:31779183b108 180 return readRegister(addr); // only take second read as valid return value
pixus_mbed 0:31779183b108 181 }
pixus_mbed 0:31779183b108 182
pixus_mbed 0:31779183b108 183 uint8_t Pixart_OTS::readRegister(uint8_t addr)
pixus_mbed 0:31779183b108 184 {
pixus_mbed 0:31779183b108 185 char data_write[2];
pixus_mbed 0:31779183b108 186 char data_read[2];
pixus_mbed 0:31779183b108 187
pixus_mbed 0:31779183b108 188 data_write[0] = addr;
pixus_mbed 0:31779183b108 189 m_i2c->write(I2C_ADDR, data_write, 1, 0);
pixus_mbed 0:31779183b108 190 m_i2c->read(I2C_ADDR, data_read, 1, 0);
pixus_mbed 0:31779183b108 191 return data_read[0];
pixus_mbed 0:31779183b108 192 }