Library for PMT9123 for Nordic nRF51
Fork of Pixart_OTS_PMT9123 by
OTC.cpp@0:31779183b108, 2017-05-08 (annotated)
- 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?
User | Revision | Line number | New 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 | } |