Initial Release of Library for PAT9125 OTS on L476RG Platform
Dependencies: mbed
Revision 0:411244c71423, committed 2017-10-03
- Comitter:
- pixus_mbed
- Date:
- Tue Oct 03 07:26:38 2017 +0000
- Child:
- 1:73967d37f487
- Commit message:
- 1st version : OTS, LCM and Serial output are work.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Tue Oct 03 07:26:38 2017 +0000
@@ -0,0 +1,95 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mbed.h"
+#include "pixart_lcm.h"
+#include "pat9125_i2c.h"
+#include "pat9125_mbed.h"
+
+pat9125_mbed_state_s g_pat9125_mbed_state ;
+pat9125_mbed *gp_pat9125_mbed ;
+pixart_lcm *gp_pixart_lcm ;
+
+
+Serial pc(USBTX, USBRX);
+//DigitalIn sdaDummy(I2C_SDA0, PullUp);
+//DigitalIn sclDummy(I2C_SCL0, PullUp);
+pat9125_i2c *gp_pat9125_i2c;//(I2C_SDA0, I2C_SCL0);
+SPI spi(SPI_PSELMOSI0, NC, SPI_PSELSCK0);
+
+DigitalOut PIN_LCM_CSB(SPI_PSELSS0);
+DigitalOut PIN_LCM_RSTB(p20);
+DigitalOut PIN_LCM_RS(p23);
+
+InterruptIn PIN_SEN_MOTION(p15);
+DigitalIn motionDummy(p15, PullUp);
+DigitalIn PIN_BTN_L(p1);
+DigitalIn PIN_BTN_R(p2);
+
+DigitalOut PIN_GLED(p14);
+DigitalOut PIN_RLED(p17);
+#define I2C_ADDRESS 0x73
+
+//-----------------------------------------------------------------------
+int main(void)
+{
+ char addr = 0;
+ char data ;
+ pc.set_flow_control(SerialBase::Disabled) ;
+ pc.baud(115200);
+ pc.printf("---------- Pixart PAT9125 Demo\n");
+
+ // +++++++ LCM Initialization +++++++ //
+ // Chip must be deselected
+ PIN_LCM_CSB = 1 ;
+
+ // Setup the spi for 8 bit data, high steady state clock,
+ // second edge capture, with a 1MHz clock rate
+ spi.format(8,3);
+ spi.frequency(1000000);
+ gp_pixart_lcm = new pixart_lcm(&spi, &PIN_LCM_CSB, &PIN_LCM_RSTB, &PIN_LCM_RS) ;
+ // ------- LCM Initialization ------- //
+
+ // +++++++ PAT9125 Initialization +++++++ //
+ gp_pat9125_i2c = new pat9125_i2c();
+ gp_pat9125_i2c->frequency(400000);
+ g_pat9125_mbed_state.p_i2c = gp_pat9125_i2c;
+ g_pat9125_mbed_state.p_pc = &pc;
+ g_pat9125_mbed_state.pBTN_L = &PIN_BTN_L ;
+ g_pat9125_mbed_state.pBTN_R = &PIN_BTN_R ;
+ g_pat9125_mbed_state.pINT = &PIN_SEN_MOTION;
+ g_pat9125_mbed_state.pRLED = &PIN_RLED;
+ g_pat9125_mbed_state.pGLED = &PIN_GLED;
+ g_pat9125_mbed_state.pLCM = gp_pixart_lcm;
+ g_pat9125_mbed_state.slave_id = (I2C_ADDRESS << 1);
+ g_pat9125_mbed_state.sen_status = 0;
+
+ gp_pat9125_mbed = new pat9125_mbed(&g_pat9125_mbed_state) ;
+ gp_pixart_lcm->LCM_DisplayString_Boot(g_pat9125_mbed_state.sen_status);
+
+ if(g_pat9125_mbed_state.sen_status == true)
+ {
+ pc.printf("Initial Sensor ... Done\n");
+ }
+ else
+ {
+ pc.printf("Initial Sensor ... Fail\n");
+ }
+ while(true)
+ {
+ gp_pat9125_mbed->task();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Oct 03 07:26:38 2017 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/675da3299148 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pat9125_mbed/pat9125_i2c.cpp Tue Oct 03 07:26:38 2017 +0000
@@ -0,0 +1,20 @@
+#include "pat9125_i2c.h"
+
+static pat9125_i2c *_self ;
+static PinName _sda ;
+static PinName _scl ;
+
+
+pat9125_i2c::pat9125_i2c(PinName sda, PinName scl) : I2C(sda, scl)
+{
+ _self = this ;
+ _sda = sda ,
+ _scl = scl ;
+}
+
+pat9125_i2c* pat9125_i2c::reset()
+{
+ delete _self ;
+ _self = new pat9125_i2c(_sda, _scl);
+ return _self ;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pat9125_mbed/pat9125_i2c.h Tue Oct 03 07:26:38 2017 +0000
@@ -0,0 +1,13 @@
+#ifndef PAT9125_I2C_H
+#define PAT9125_I2C_H
+#include "stdint.h"
+#include "mbed.h"
+
+class pat9125_i2c : public I2C
+{
+ public:
+ pat9125_i2c(PinName sda = I2C_SDA0, PinName scl = I2C_SCL0);
+ static pat9125_i2c * reset() ;
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pat9125_mbed/pat9125_mbed.cpp Tue Oct 03 07:26:38 2017 +0000
@@ -0,0 +1,336 @@
+
+#include "pat9125_mbed.h"
+#define delay(ms) wait_ms(ms)
+
+//define OTS state - X
+#define OTS_ROT_NO_CHANGE 0x00
+#define OTS_ROT_UP 0x01
+#define OTS_ROT_DOWN 0x02
+
+//define downscale factor for rotation of shaft
+#define EXPECTED_COUNT_PER_ROUND 360
+#define REAL_AVG_COUNT_PER_ROUND 446 //base on: sensor Reg0x0d=0x65, shaft diameter=2mm, sensor-to-shaft distance=2mm
+
+//define OTS state - Y
+#define OTS_BTN_NO_CHANGE 0x00
+#define OTS_BTN_RELEASE 0x01
+#define OTS_BTN_PRESS 0x02
+
+#define LOW 0
+#define HIGH 1
+#define digitalRead(pin) *pin
+
+static pat9125_mbed_state_s *gp_state ;
+
+#define PIN_BTN_L gp_state->pBTN_L
+#define PIN_BTN_R gp_state->pBTN_R
+#define PIN_SEN_MOTION gp_state->pINT
+
+#define PIN_RLED gp_state->pRLED
+#define PIN_GLED gp_state->pGLED
+#define digitalWrite(pin,level) *pin = level
+#define LED_RED_ON digitalWrite(PIN_RLED,LOW)
+#define LED_RED_OFF digitalWrite(PIN_RLED,HIGH)
+#define LED_GREEN_ON digitalWrite(PIN_GLED,LOW)
+#define LED_GREEN_OFF digitalWrite(PIN_GLED,HIGH)
+#define attachInterrupt(pin,b,c) //pin->enable_irq()
+#define digitalPinToInterrupt(pin) pin
+#define detachInterrupt(pin) //pin->disable_irq()
+#define LCM_DisplayString_Reset gp_state->pLCM->LCM_DisplayString_Reset
+#define LCM_DisplayDecimal(a,b,c,d) gp_state->pLCM->LCM_DisplayDecimal(a,b,c,d)
+#define LCM_DisplayString(a,b,c) gp_state->pLCM->LCM_DisplayString(a,b,c)
+
+#define I2C_RESET gp_state->p_i2c = gp_state->p_i2c->reset(); //workaround for nRF51 mbed
+
+//for OTS
+signed int deltaX16;
+signed int deltaY16;
+unsigned char OTS_ROT_Status;
+unsigned char OTS_BTN_Status;
+
+signed long x_sum=0;
+signed long ds_x_sum=0;
+signed long pre_dsCountX=0;
+unsigned int OTS_BTN_Press_Cnt=0;
+
+volatile unsigned char MotionPinEventTriggered=0;
+
+// Register write function
+void OTS_Write_Reg(unsigned char address, unsigned char value)
+{
+ int ret ;
+ char data_write[2];
+
+ data_write[0] = address;
+ data_write[1] = value;
+ ret = gp_state->p_i2c->write(gp_state->slave_id, data_write, 2, 0);
+}
+
+// Register Read function
+unsigned char OTS_Read_Reg(unsigned char address)
+{
+ unsigned char rdata = 0;
+ gp_state->p_i2c->write(gp_state->slave_id, (char *)&address, 1, 0);
+ gp_state->p_i2c->read(gp_state->slave_id, (char *)&rdata, 1, 0);
+
+ return(rdata);
+}
+
+// Register write & read back check function
+void OTS_WriteRead_Reg(unsigned char address, unsigned char wdata)
+{
+ unsigned char rdata;
+ do
+ {
+ OTS_Write_Reg(address, wdata); // Write data to specified address
+ rdata = OTS_Read_Reg(address); // Read back previous written data
+ } while(rdata != wdata); // Check if the data is correctly written
+
+}
+
+boolean OTS_Sensor_Init(void)
+{
+ unsigned char sensor_pid=0;
+ boolean read_id_ok=false;
+
+ // Read sensor_pid in address 0x00 to check if the serial link is valid, PID should be 0x31
+ sensor_pid = OTS_Read_Reg(0x00);
+ if(sensor_pid == 0x31)
+ {
+ read_id_ok = true;
+
+ //PAT9125 sensor recommended settings as below:
+ OTS_Write_Reg(0x7F, 0x00); // switch to bank0, not allowed to perform OTS_WriteRead_Reg
+ OTS_Write_Reg(0x06, 0x97); // Software Reset (i.e. set bit7 to 1), then it will reset to 0 automatically
+
+ I2C_RESET;
+
+ delay(1); // delay 1ms
+ OTS_Write_Reg(0x06, 0x17); // ensure the sensor has left the reset state.
+
+ OTS_WriteRead_Reg(0x09, 0x5A); // disable write protect
+ OTS_WriteRead_Reg(0x0D, 0x65); // set X-axis resolution (depends on application)
+ OTS_WriteRead_Reg(0x0E, 0xFF); // set Y-axis resolution (depends on application)
+ OTS_WriteRead_Reg(0x19, 0x04); // set 12-bit X/Y data format (depends on application)
+ //OTS_WriteRead_Reg(0x4B, 0x04); // ONLY for VDD=VDDA=1.7~1.9V: for power saving
+
+ if(OTS_Read_Reg(0x5E) == 0x04)
+ {
+ OTS_WriteRead_Reg(0x5E, 0x08);
+ if(OTS_Read_Reg(0x5D) == 0x10)
+ OTS_WriteRead_Reg(0x5D, 0x19);
+ }
+
+ OTS_WriteRead_Reg(0x09, 0x00); // enable write protect
+ }
+
+ return read_id_ok;
+}
+
+// Read motion
+void OTS_Read_Motion(signed int *dx16, signed int *dy16)
+{
+ int shift = (sizeof(signed int) << 3) - 12 ;
+ signed int deltaX_l=0, deltaY_l=0, deltaXY_h=0;
+ signed int deltaX_h=0, deltaY_h=0;
+ char motion = OTS_Read_Reg(0x02) ;
+ if(motion & 0x80) //check motion bit in bit7
+ {
+ deltaX_l = OTS_Read_Reg(0x03);
+ deltaY_l = OTS_Read_Reg(0x04);
+ deltaXY_h = OTS_Read_Reg(0x12);
+
+ deltaX_h = (deltaXY_h<<4) & 0xF00;
+ deltaX_h = (deltaX_h << shift) >> shift ;
+ //if(deltaX_h & 0x800) deltaX_h |= 0xfffff000; // 12-bit data convert to 16-bit
+
+ deltaY_h = (deltaXY_h<<8) & 0xF00;
+ //if(deltaY_h & 0x800) deltaY_h |= 0xfffff000; // 12-bit data convert to 16-bit
+ deltaY_h = (deltaY_h << shift) >> shift ;
+
+ }
+ *dx16 = -(deltaX_h | deltaX_l); //inverse the data (depends on sensor's orientation and application)
+ *dy16 = -(deltaY_h | deltaY_l); //inverse the data (depends on sensor's orientation and application)
+}
+
+void OTS_Reset_Variables(void)
+{
+ //reset variables
+ x_sum=0;
+ ds_x_sum=0;
+ pre_dsCountX=0;
+
+ OTS_BTN_Press_Cnt=0;
+ LCM_DisplayString_Reset();
+}
+
+unsigned char Detect_Rotation(signed long dsCountX)
+{
+ #define EVENT_NUM_PER_ROUND 360//10
+ #define EVENT_COUNT_TH (EXPECTED_COUNT_PER_ROUND / EVENT_NUM_PER_ROUND) //360/10=36 //360/360=1
+
+ signed long diff_count = 0;
+ unsigned char OutRotState = OTS_ROT_NO_CHANGE;
+
+ diff_count = dsCountX - pre_dsCountX;
+ if( diff_count >= EVENT_COUNT_TH )
+ {
+ pre_dsCountX = dsCountX;
+ OutRotState = OTS_ROT_UP;
+ }
+ else if( diff_count <= (-EVENT_COUNT_TH) )
+ {
+ pre_dsCountX = dsCountX;
+ OutRotState = OTS_ROT_DOWN;
+ }
+
+ return OutRotState;
+}
+
+signed long OTS_Resolution_Downscale(signed int delta_count)
+{
+ x_sum += delta_count;
+ return (x_sum * EXPECTED_COUNT_PER_ROUND / REAL_AVG_COUNT_PER_ROUND);
+}
+
+unsigned char OTS_Detect_Rotation(signed int dx16, signed int dy16)
+{
+ ds_x_sum = OTS_Resolution_Downscale(dx16);
+ LCM_DisplayDecimal(1,12,ds_x_sum,4);//show downscale value
+
+ return Detect_Rotation(ds_x_sum);
+}
+
+unsigned char OTS_Detect_Pressing(signed int dx16, signed int dy16)
+{
+ #define PRESS 1
+ #define RELEASE 0
+
+ #define DX_ROTATE_TH 2
+ #define DY_VALID_TH 1
+ #define ACCY_PRESS_TH 5
+ #define DY_RELEASE_TH (-2)
+
+ unsigned char OutBtnState = OTS_BTN_NO_CHANGE;
+ static signed long AccY = 0;
+ static unsigned char State = RELEASE; //0:release, 1:press
+
+ if((dx16 >= DX_ROTATE_TH)||(dx16 <= (-DX_ROTATE_TH)))
+ {
+ AccY = 0;
+ }
+ else
+ {
+ if(State == PRESS)
+ {
+ if(dy16 <= DY_RELEASE_TH)
+ {
+ State = RELEASE;
+ OutBtnState = OTS_BTN_RELEASE;
+ }
+ }
+ else
+ {
+ if(dy16 < DY_VALID_TH)
+ {
+ AccY = 0;
+ }
+ else
+ {
+ AccY += dy16;
+ if(AccY >= ACCY_PRESS_TH)
+ {
+ AccY = 0;
+ State = PRESS;
+ OutBtnState = OTS_BTN_PRESS;
+ }
+ }
+ }
+ }
+
+ return OutBtnState;
+}
+
+//-----------------------------------------------------------------------
+void OTS_MotionPin_ISR(void)
+{
+ detachInterrupt(digitalPinToInterrupt(PIN_SEN_MOTION));
+ MotionPinEventTriggered=1;
+}
+
+//-----------------------------------------------------------------------
+void loop()
+{
+
+ if(digitalRead(PIN_BTN_L) == LOW)//or reset whenever idle_timer timeout
+ {
+ OTS_Reset_Variables();
+ }
+
+ if(MotionPinEventTriggered==1)
+ {
+ MotionPinEventTriggered=0;//clear flag after read 'Motion Status and Data'
+ OTS_Read_Motion(&deltaX16,&deltaY16);
+
+ if(deltaX16 || deltaY16)
+ {
+ OTS_ROT_Status = OTS_Detect_Rotation(deltaX16,deltaY16);
+ OTS_BTN_Status = OTS_Detect_Pressing(deltaX16,deltaY16);
+
+ if(OTS_ROT_Status == OTS_ROT_UP)
+ {
+ LED_RED_ON;
+ LCM_DisplayString(1,8,"Up ");
+ }
+ else if(OTS_ROT_Status == OTS_ROT_DOWN)
+ {
+ LED_GREEN_ON;
+ LCM_DisplayString(1,8,"Dn ");
+ }
+
+ if(OTS_BTN_Status == OTS_BTN_PRESS)
+ {
+ OTS_BTN_Press_Cnt++;
+ if(OTS_BTN_Press_Cnt > 999)
+ {
+ OTS_BTN_Press_Cnt=0;
+ }
+ LCM_DisplayString(2,8,"Pre");
+ LCM_DisplayDecimal(2,12,OTS_BTN_Press_Cnt,4);
+ }
+ else if(OTS_BTN_Status == OTS_BTN_RELEASE)
+ {
+ LCM_DisplayString(2,8,"Rel");
+ }
+ }
+
+ //re-enable interrupt for MOTION pin
+ attachInterrupt(digitalPinToInterrupt(PIN_SEN_MOTION), OTS_MotionPin_ISR, LOW);
+
+ }
+
+ if(digitalRead(PIN_SEN_MOTION) == HIGH)
+ {
+ LED_GREEN_OFF;
+ LED_RED_OFF;
+ }
+
+}
+pat9125_mbed::pat9125_mbed(pat9125_mbed_state_s *state)
+{
+ gp_state = state ;
+ //gp_state->p_pc->printf("PAT9125 ADDR0 %x\n", OTS_Read_Reg(0));
+ gp_state->sen_status = OTS_Sensor_Init();
+ gp_state->p_pc->printf("OTS_Sensor_Init\n");
+ gp_state->pINT->fall(&OTS_MotionPin_ISR); //interrupt at low state
+}
+
+void pat9125_mbed::task()
+{
+ if(digitalRead(PIN_SEN_MOTION) == LOW)
+ {
+ //gp_state->p_pc->printf("Motion Low\n");
+ MotionPinEventTriggered = 1 ;
+ }
+ loop();
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pat9125_mbed/pat9125_mbed.h Tue Oct 03 07:26:38 2017 +0000
@@ -0,0 +1,30 @@
+#ifndef PAT9125_MBED_H
+#define PAT9125_MBED_H
+#include "stdint.h"
+#include "mbed.h"
+#include "pat9125_i2c.h"
+#include "pixart_lcm.h"
+
+typedef uint8_t boolean;
+typedef struct
+{
+ pat9125_i2c *p_i2c;
+ Serial *p_pc ;
+ DigitalIn *pBTN_L ;
+ DigitalIn *pBTN_R ;
+ InterruptIn *pINT ;
+ DigitalOut *pRLED ;
+ DigitalOut *pGLED ;
+ pixart_lcm *pLCM ;
+ uint8_t slave_id ;
+ boolean sen_status ;
+} pat9125_mbed_state_s;
+
+class pat9125_mbed
+{
+ public:
+ pat9125_mbed(pat9125_mbed_state_s *state) ;
+ void task() ;
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pixart_lcm/pixart_lcm.cpp Tue Oct 03 07:26:38 2017 +0000
@@ -0,0 +1,231 @@
+#include "pixart_lcm.h"
+
+
+
+typedef struct
+{
+ SPI *pSPI ;
+ DigitalOut *pCSB;
+ DigitalOut *pRSTB;
+ DigitalOut *pRS;
+} pixart_lcm_state_s;
+
+static pixart_lcm_state_s g_state ;
+
+
+#define LOW 0
+#define HIGH 1
+#define PIN_LCM_RS g_state.pRS
+#define PIN_LCM_RSTB g_state.pRSTB
+#define PIN_LCM_CSB g_state.pCSB
+#define digitalWrite(pin,level) *pin = level
+#define LCM_RS_LO digitalWrite(PIN_LCM_RS,LOW)
+#define LCM_RS_HI digitalWrite(PIN_LCM_RS,HIGH)
+#define LCM_RSTB_LO digitalWrite(PIN_LCM_RSTB,LOW)
+#define LCM_RSTB_HI digitalWrite(PIN_LCM_RSTB,HIGH)
+#define LCM_CSB_LO digitalWrite(PIN_LCM_CSB,LOW)
+#define LCM_CSB_HI digitalWrite(PIN_LCM_CSB,HIGH)
+
+#define I2C_ADDRESS (0x73 << 1)
+#define delayMicroseconds(us) wait_us(us)
+#define delay(ms) wait_ms(ms)
+
+//-----------------------------------------------------------------------
+unsigned char hex2dec_nibble(unsigned char hex_nibble)
+{
+ unsigned char dec;
+
+ switch(hex_nibble)
+ {
+ case 0xA: dec=10; break;
+ case 0xB: dec=11; break;
+ case 0xC: dec=12; break;
+ case 0xD: dec=13; break;
+ case 0xE: dec=14; break;
+ case 0xF: dec=15; break;
+ default: dec=hex_nibble; break;
+ }
+
+ return (dec);
+}
+
+unsigned int hex2dec_word(unsigned int hex_word)
+{
+ unsigned char dec_nb[4];
+ unsigned char nibble3=(hex_word>>12)&0x000f;
+ unsigned char nibble2=(hex_word>>8)&0x000f;
+ unsigned char nibble1=(hex_word>>4)&0x000f;
+ unsigned char nibble0=hex_word&0x000f;
+
+ dec_nb[3]=hex2dec_nibble(nibble3);
+ dec_nb[2]=hex2dec_nibble(nibble2);
+ dec_nb[1]=hex2dec_nibble(nibble1);
+ dec_nb[0]=hex2dec_nibble(nibble0);
+ return ((dec_nb[3]<<12)+(dec_nb[2]<<8)+(dec_nb[1]<<4)+dec_nb[0]);
+}
+
+void LCM_WriteCom(unsigned char Command)
+{
+ LCM_CSB_LO;
+ LCM_RS_LO;
+ //SPI.transfer(Command);
+ g_state.pSPI->write(Command);
+ LCM_CSB_HI;
+
+ delayMicroseconds(30);
+}
+
+void LCM_WriteData(unsigned char Ascii)
+{
+ LCM_CSB_LO;
+ LCM_RS_HI;
+ //SPI.transfer(Ascii);
+ g_state.pSPI->write(Ascii);
+ LCM_CSB_HI;
+
+ delayMicroseconds(30);
+}
+
+void LCM_Init(void)
+{
+ LCM_RSTB_LO;
+ delay(3);
+ LCM_RSTB_HI;
+ delay(20);
+ LCM_WriteCom(0x30); //wake up
+ delay(3);
+ LCM_WriteCom(0x30); //wake up
+ LCM_WriteCom(0x30); //wake up
+ LCM_WriteCom(0x39); //function set
+ LCM_WriteCom(0x14); //internal osc frequency
+ LCM_WriteCom(0x56); //Contrast set
+ LCM_WriteCom(0x6D); //follower control
+ LCM_WriteCom(0x75); //contrast//
+ LCM_WriteCom(0x0C); //display on
+ LCM_WriteCom(0x06); //entry mode
+ LCM_WriteCom(0x01); //clear
+
+ delay(10);
+}
+
+void LCM_Clear(void)
+{
+ LCM_WriteCom(0x01);
+
+ delay(2);
+}
+
+void LCM_SetPosition(unsigned char line, unsigned char position)//line=1 or 2; position=1~16
+{
+ unsigned char address;
+
+ address = ((line-1) * 0x40) + (position-1);
+ address = 0x80 + (address & 0x7F);
+
+ LCM_WriteCom(address);
+}
+
+void LCM_DisplayString(unsigned char line, unsigned char position, const char *ptr)
+{
+ LCM_SetPosition(line,position);
+
+ while (*ptr)
+ {
+ LCM_WriteData(*ptr++);
+ }
+}
+
+void LCM_DisplayDecimal(unsigned char line, unsigned char position, unsigned int hex_word, unsigned char digits)
+{
+ unsigned char sign;//0:positive, 1:negative
+ unsigned int dec_num;
+ unsigned char digit[5];
+ signed char ii;
+
+ if(hex_word & 0x8000)
+ sign=1;
+ else
+ sign=0;
+
+ if(sign==1)
+ hex_word=~hex_word+1;
+
+ dec_num=hex2dec_word(hex_word);
+ digit[4]=dec_num/10000;
+ digit[3]=(dec_num%10000)/1000;
+ digit[2]=(dec_num%1000)/100;
+ digit[1]=(dec_num%100)/10;
+ digit[0]=dec_num%10;
+
+ LCM_SetPosition(line,position);
+
+ if(sign==1)
+ LCM_WriteData('-');
+ else
+ LCM_WriteData('+');
+
+ for(ii=(digits-1);ii>=0;ii--)
+ {
+ LCM_WriteData(digit[ii] | 0x30);//decimal to ascii
+ }
+
+}
+
+void LCM_ClearLine(unsigned char line)// line: 1 or 2
+{
+ LCM_DisplayString(line,1," ");
+}
+
+void LCM_DisplayString_Reset(void)
+{
+ LCM_DisplayString(1,1,"SHAFT"); LCM_DisplayString(1,8,"U/D");LCM_DisplayDecimal(1,12,0x000,4);
+ LCM_DisplayString(2,1,"SPRING");LCM_DisplayString(2,8,"P/R");LCM_DisplayDecimal(2,12,0x000,4);
+}
+
+void LCM_DisplayString_Boot(boolean sen_status)
+{
+ LCM_DisplayString(1,1,"PixArt Shaft EVK");
+ LCM_DisplayString(2,1,"PAT9125 FW V2.30");
+ delay(2000);
+
+ LCM_ClearLine(1);
+ LCM_ClearLine(2);
+
+ if(sen_status == true)
+ {
+ LCM_DisplayString_Reset();
+ }
+ else
+ {
+ LCM_DisplayString(2,1,"Read Sensor Fail");
+ }
+}
+
+//-----------------------------------------------------------------------
+
+pixart_lcm::pixart_lcm(SPI *pSPI, DigitalOut *pCSB, DigitalOut *pRSTB, DigitalOut *pRS)
+{
+ g_state.pSPI = pSPI;
+ g_state.pCSB = pCSB;
+ g_state.pRSTB = pRSTB;
+ g_state.pRS = pRS;
+ *g_state.pRS = 1;
+ LCM_Init();
+}
+
+void pixart_lcm::LCM_DisplayString(unsigned char line, unsigned char position, const char *ptr)
+{
+ ::LCM_DisplayString(line, position, ptr);
+}
+void pixart_lcm::LCM_DisplayDecimal(unsigned char line, unsigned char position, unsigned int hex_word, unsigned char digits)
+{
+ ::LCM_DisplayDecimal(line, position, hex_word, digits);
+}
+void pixart_lcm::LCM_DisplayString_Reset(void)
+{
+ ::LCM_DisplayString_Reset();
+}
+void pixart_lcm::LCM_DisplayString_Boot(boolean sen_status)
+{
+ ::LCM_DisplayString_Boot(sen_status);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pixart_lcm/pixart_lcm.h Tue Oct 03 07:26:38 2017 +0000
@@ -0,0 +1,20 @@
+#ifndef PIXART_LCM_H
+#define PIXART_LCM_H
+
+#include "stdint.h"
+#include "mbed.h"
+
+typedef uint8_t boolean ;
+
+class pixart_lcm
+{
+ public:
+
+ pixart_lcm(SPI *pSPI, DigitalOut *pCSB, DigitalOut *pRSTB, DigitalOut *pRS) ;
+ void LCM_DisplayString(unsigned char line, unsigned char position, const char *ptr) ;
+ void LCM_DisplayDecimal(unsigned char line, unsigned char position, unsigned int hex_word, unsigned char digits) ;
+ void LCM_DisplayString_Reset(void);
+ void LCM_DisplayString_Boot(boolean sen_status);
+
+};
+#endif
PAT9125EL - Miniature Optical Navigation for Surface Tracking