Aleksandar Kodzhabashev / Mbed 2 deprecated TrackballQuery

Dependencies:   Servo mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PS2MS_INIT.cpp Source File

PS2MS_INIT.cpp

00001 /**
00002  * PS/2 mouse interface control class (Version 0.0.1)
00003  *
00004  * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
00005  * http://shinta.main.jp/
00006  */
00007 #include "PS2MS_INIT.h"
00008 
00009 /**
00010  * Create.
00011  */
00012 PS2MS_INIT::PS2MS_INIT(PinName clk_pin, PinName dat_pin)
00013         : clk(clk_pin), dat(dat_pin) {
00014     clk.input();
00015     dat.input();
00016     clk.write(1);
00017     dat.write(1);
00018 
00019     /*
00020      * 0xFF: Reset command.
00021      * 0xF3: Set sample rate.
00022      * 0xF2: Read device type.
00023      * 0xE8: Set resolution.
00024      * 0xE6: Set scaling.
00025      * 0xF4: Enable device.
00026      * 0xF0: Set remote mode
00027      */
00028     //char txdat[17] = "\xFF\xFF\xFF\xF3\xC8\xF3\x64\xF3\x50\xF2\xE8\x03\xE6\xF3\x28\xF4";
00029     //char txdat[11] = "\xFF\xFF\xFF\xF2\xE8\x03\xE6\xF3\xC8\xF4";
00030     char txdat[12] = "\xFF\xFF\xFF\xF2\xE8\x02\xE6\xF3\x28\xF0\xF4";
00031     const int n = sizeof(txdat);
00032     int txerrcnt = 0;
00033     int rxerrcnt = 0;
00034     for (int i = 0; i < n; i++) {
00035         if (send(txdat[i]) != 0) {
00036             txerrcnt++;
00037         }
00038         if (recv() < 0) {
00039             rxerrcnt++;
00040         }
00041         if (txdat[i] == 0xF2) {
00042             if (recv() < 0) {
00043                 rxerrcnt++;
00044             }
00045         }
00046         if (txdat[i] == 0xFF) {
00047             if (recv() < 0) {
00048                 rxerrcnt++;
00049             }
00050             if (recv() < 0) {
00051                 rxerrcnt++;
00052             }
00053         }
00054     }
00055     
00056     if (txerrcnt > 0) {
00057         printf("TX %d errors occured.\n", txerrcnt);
00058     }
00059     if (rxerrcnt > 0) {
00060         printf("RX %d errors occured.\n", rxerrcnt);
00061     }
00062 }
00063 
00064 /**
00065  * Destroy.
00066  */
00067 PS2MS_INIT::~PS2MS_INIT() {
00068 }
00069 
00070 /**
00071  * Send a byte data.
00072  *
00073  * @param c a character.
00074  *
00075  * @return Negative value is a error number.
00076  */
00077 int PS2MS_INIT::send(uint8_t c) {
00078     clk.output();
00079     dat.output();
00080 
00081     clk.write(0);
00082     wait_us(200);
00083 
00084     dat.write(0);
00085     wait_us(10);
00086     clk.write(1);
00087     wait_us(10);
00088 
00089     clk.input();
00090     int parcnt = 0;
00091     for (int i = 0; i < 10; i++) {
00092         if (!waitClockDownEdge()) {
00093             return -1;
00094         }
00095         if ((0 <= i) && (i <= 7)) {
00096             /*
00097              * Data bit.
00098              */
00099             if ((c & (1 << i)) == 0) {
00100                 dat.write(0);
00101             } else {
00102                 dat.write(1);
00103                 parcnt++;
00104             }
00105         }
00106         if (i == 8) {
00107             /*
00108              * Parity bit.
00109              */
00110             if ((parcnt % 2) == 0) {
00111                 dat.write(1);
00112             } else {
00113                 dat.write(0);
00114             }
00115         }
00116         if (i == 9) {
00117             /*
00118              * Stop bit.
00119              */
00120             dat.write(1);
00121         }
00122     }
00123     dat.input();
00124 
00125     /*
00126      * Check a ACK.
00127      */
00128     if (!waitClockDownEdge()) {
00129         return -2;
00130     }
00131     if (dat.read() != 0) {
00132         return -3;
00133     }
00134 
00135     if (!waitClockUpLevel()) {
00136         return -4;
00137     }
00138 
00139     return 0;
00140 }
00141 
00142 /**
00143  * Receive a byte data.
00144  *
00145  * @return return a data. Negative value is a error number.
00146  */
00147 int PS2MS_INIT::recv(void) {
00148     uint8_t c = 0;
00149     clk.input();
00150     dat.input();
00151     int parcnt = 0;
00152     for (int i = 0; i < 11; i++) {
00153         if (!waitClockDownEdge()) {
00154             return -1;
00155         }
00156         if (i == 0) {
00157             /*
00158              * Start bit.
00159              */
00160             if (dat.read() != 0) {
00161                 return -2;
00162             }
00163         }
00164         if ((1 <= i) && (i <= 8)) {
00165             /*
00166              * Data bit.
00167              */
00168             if (dat.read() == 0) {
00169                 c &= ~(1 << (i - 1));
00170             } else {
00171                 c |= (1 << (i - 1));
00172                 parcnt++;
00173             }
00174         }
00175         if (i == 9) {
00176             /*
00177              * Parity bit.
00178              */
00179             if (dat.read() == 0) {
00180                 if ((parcnt % 2) != 1) {
00181                     return -3;
00182                 }
00183             } else {
00184                 if ((parcnt % 2) != 0) {
00185                     return -4;
00186                 }
00187             }
00188         }
00189         if (i == 10) {
00190             /*
00191              * Stop bit.
00192              */
00193             if (dat.read() != 1) {
00194                 return -5;
00195             }
00196         }
00197     }
00198     return (int)c;
00199 }
00200 
00201 /**
00202  * Wait a clock down edge.
00203  *
00204  * @return true if wait done.
00205  */
00206 bool PS2MS_INIT::waitClockDownEdge(void) {
00207     int cnt;
00208     /*
00209      * Wait until clock is low.
00210      */
00211     cnt = 0;
00212     while (clk.read() == 0) {
00213         cnt++;
00214         if (MAX_RETRY < cnt) {
00215             return false;
00216         }
00217         wait_us(1);
00218     }
00219     /*
00220      * Wait until clock is high.
00221      */
00222     cnt = 0;
00223     while (clk.read() == 1) {
00224         cnt++;
00225         if (MAX_RETRY < cnt) {
00226             return false;
00227         }
00228         wait_us(1);
00229     }
00230     return true;
00231 }
00232 
00233 /**
00234  * Wait a clock up level.
00235  *
00236  * @return true if wait done.
00237  */
00238 bool PS2MS_INIT::waitClockUpLevel(void) {
00239     int cnt;
00240     /*
00241      * Wait until clock is low.
00242      */
00243     cnt = 0;
00244     while (clk.read() == 0) {
00245         cnt++;
00246         if (MAX_RETRY < cnt) {
00247             return false;
00248         }
00249         wait_us(1);
00250     }
00251     return true;
00252 }