PMT9123 OTS on Nucleo (Initial Release)
Fork of Pixart_9123_Nucleo_Library by
Diff: OTC.cpp
- Revision:
- 0:7aefc9ab3301
diff -r 000000000000 -r 7aefc9ab3301 OTC.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/OTC.cpp Thu May 11 17:32:04 2017 +0000
@@ -0,0 +1,192 @@
+#include "mbed.h"
+#include "PMT9123Set.h"
+#include "OTC.h"
+
+
+
+#define PMT9123_ADDR (0x66) //PMT9123 address shift 1-bit
+#define I2C_ADDR PMT9123_ADDR
+#define PXI_PID 0x41
+#define DebounceT 300 //debounce time, unit:ms
+
+// Structure for motion data
+union
+{
+ unsigned char d[10];
+ struct
+ {
+ unsigned char motion;
+ unsigned char deltaX;
+ unsigned char deltaY;
+ unsigned char deltaXY;
+ unsigned char squal;
+ //unsigned short shutter;
+ unsigned char shutterH;
+ unsigned char shutterL;
+ unsigned char pix_max;
+ unsigned char pix_avg;
+ unsigned char pix_min;
+ } m;
+} MotionData;
+
+
+Pixart_OTS::Pixart_OTS(I2C *i2c, int Period,OTSCallback callback,bool &Result)
+{
+ m_i2c = i2c;
+ m_OTSCallback = callback;
+ //m_pc = pc;
+ m_Period = Period;
+ m_Address = 0x00; // Default address to PID
+
+ Result=PMT9123_init();
+}
+
+
+
+bool Pixart_OTS::PMT9123_init()
+{
+ uint8_t v;
+
+ // Power up sequence
+ // Drive NRESET low for 20us
+ //digitalWrite(PIN_NRESET_NCS,LOW);
+ //delayMicroseconds(20);
+ //digitalWrite(PIN_NRESET_NCS,HIGH);
+ // wait for 1.5ms
+ //delayMicroseconds(1500);
+
+ // Enable register write
+ writeRegister(0x41, 0xba);
+ m_WriteEnable = true; // set to true for the write below to not repeat turning on
+ wait_us(300);
+ // Write 0x00 to register 0x1D
+ Register_Write(0x1D, 0x00);
+ wait_ms(10);
+ v = Register_Read(0x1D);
+ // Check if the bit 0 to 4 is set or not
+ /*if (!IS_BIT_SET(v, 0x1F))
+ {
+ // Error handling
+ return false;
+ }*/
+ Register_Write(0x48, 0x10); // Default resolution set to 2000 cpi
+
+ // Write in peformance optimization registers
+ for(v = 0; v < INIT_PMT9123_REG_ARRAY_SIZE; v++)
+ Register_Write(init_PMT9123_register_array[v][0], init_PMT9123_register_array[v][1]);
+
+ // Disable register write
+ writeRegister(0x41, 0xb5);
+ m_WriteEnable = false; // set to false for subsequent write to enable and disable it when writing register
+ // Soft reset
+ writeRegister(0x3a, 0x96);
+
+ wait_ms(50);
+
+
+ m_ticker.attach_us(this,&Pixart_OTS::periodicCallback, m_Period*1000);
+
+ //m_pc->printf("\n\r~~~Start Real-time Gesture Demo~~~ \n\r");
+
+ return true;
+}
+
+void Pixart_OTS::periodicCallback(void)
+{
+ PMT9123_ReadMotion();
+}
+
+void Pixart_OTS::PMT9123_ReadMotion(void)
+{
+ int16_t temp_deltaXH, temp_deltaYH, deltaX16bit, deltaY16bit;
+ int i = 0;
+
+ // Normal motion reading
+ for (i = 0; i < 10; i++)
+ {
+ MotionData.d[i] = readRegister((0x02+i)); // using the single read version as motion cannot be double read and not affected
+ }
+
+ temp_deltaXH = (MotionData.m.deltaXY<<4) & 0xF00;
+ if(temp_deltaXH & 0x800) // -ve value spotted convert to 16-bit
+ {
+ temp_deltaXH |= 0xf000;
+ }
+ temp_deltaYH = (MotionData.m.deltaXY<<8) & 0xF00;
+ if(temp_deltaYH & 0x800) // -ve value spotted convert to 16-bit
+ {
+ temp_deltaYH |= 0xf000;
+ }
+
+ // Delta X is the vertical axis of the chip, only used if the ring can move up and down
+ deltaX16bit = MotionData.m.deltaX | temp_deltaXH;
+ // Delta Y is the value that it tracks on when turning the ring
+ deltaY16bit = MotionData.m.deltaY | temp_deltaYH;
+
+ if (deltaY16bit != 0)
+ m_OTSCallback(deltaY16bit);
+}
+
+uint8_t Pixart_OTS::Register_Write(uint8_t addr, uint8_t data)
+{
+ uint8_t result;
+ unsigned char i = 1;
+
+ switch (addr)
+ {
+ // if WO registers, just bail out with value 0
+ case 0x3A:
+ case 0x3B:
+ case 0x41:
+ i = 0; // flag it
+ break;
+ default:
+ if (!m_WriteEnable)
+ {
+ // For others, we need to enale register write first
+ writeRegister(0x41, 0xba);
+ wait_us(300);
+ }
+ break;
+ }
+ writeRegister(addr, data);
+ if (i == 0)
+ return 0;
+
+ // read back to confirm matching the write value, if not write again to maximum 3 times
+ while ((result = Register_Read(addr)) != data)
+ {
+ if (i++ >= 3)
+ break;
+ writeRegister(addr, data);
+ }
+ if (!m_WriteEnable)
+ writeRegister(0x41, 0xb5);
+ return result;
+}
+
+void Pixart_OTS::writeRegister(uint8_t addr, uint8_t data)
+{
+ char data_write[2];
+
+ data_write[0] = addr;
+ data_write[1] = data;
+ m_i2c->write(I2C_ADDR, data_write, 2, 0);
+}
+
+uint8_t Pixart_OTS::Register_Read(uint8_t addr)
+{
+ readRegister(addr);
+ return readRegister(addr); // only take second read as valid return value
+}
+
+uint8_t Pixart_OTS::readRegister(uint8_t addr)
+{
+ char data_write[2];
+ char data_read[2];
+
+ data_write[0] = addr;
+ m_i2c->write(I2C_ADDR, data_write, 1, 0);
+ m_i2c->read(I2C_ADDR, data_read, 1, 0);
+ return data_read[0];
+}
\ No newline at end of file

Low Power Right Angle Optical Track Sensor PMT9123