Aleksandar Kodzhabashev / Mbed 2 deprecated TrackballQuery

Dependencies:   Servo mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PS2KB_INIT.cpp Source File

PS2KB_INIT.cpp

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