PMT9123 OTS on Nucleo (Initial Release)

Fork of Pixart_9123_Nucleo_Library by PixArt Imaging

Committer:
pixus_mbed
Date:
Thu May 11 17:32:04 2017 +0000
Revision:
0:7aefc9ab3301
PMT9123 OTS on Nucleo (Initial Release)

Who changed what in which revision?

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