Yao Lu / PS2

Dependents:   uVGAII_WebBrowser

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PS2KB.cpp Source File

PS2KB.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 
00008 #include "PS2KB.h"
00009 
00010 /**
00011  * Create.
00012  *
00013  * @param clk_pin Clock pin.
00014  * @param dat_pin Data pin.
00015  */
00016 PS2KB::PS2KB(PinName clk_pin, PinName dat_pin)
00017         : clk(clk_pin), dat(dat_pin) {
00018     init_work();
00019     clk.fall(this, &PS2KB::func_fall);
00020     timeout = 1;
00021 }
00022 
00023 /**
00024  * Destory.
00025  */
00026 PS2KB::~PS2KB() {
00027     wdt.detach();
00028 }
00029 
00030 /**
00031  * Get a data from a PS/2 device.
00032  *
00033  * @return A data from a PS/2 device.
00034  */
00035 int PS2KB::getc() {
00036     tot.reset();
00037     tot.start();
00038     while (work.cStart == work.cEnd) {
00039         wait_ms(1);
00040         if ((timeout > 0) && (tot.read_ms() > timeout)) {
00041             // printf("Timeout occured.\n");
00042             return EOF;
00043         }
00044     }
00045     tot.stop();
00046 
00047     char c = work.buffer[work.cStart++];
00048     work.cStart =  work.cStart % RINGBUFSIZ;
00049 
00050     return c;
00051 }
00052 
00053 /**
00054  * Set timeout.
00055  *
00056  * @param ms Timeout ms.
00057  */
00058 void PS2KB::setTimeout(int ms) {
00059     timeout = ms;
00060 }
00061 
00062 void PS2KB::func_timeout(void) {
00063     work.bitcnt = 0;
00064 }
00065 
00066 void PS2KB::func_fall(void) {
00067     int oddpar = 0;
00068     /*
00069      */
00070     switch (work.bitcnt) {
00071         case 0:
00072             /*
00073              * Start bit.
00074              */
00075             if (dat.read() != 0) {
00076                 // printf("Illegal start bit condition.\n");
00077             }
00078             work.bitcnt++;
00079             break;
00080         case 9:
00081             /*
00082              * Parity bit.
00083              */
00084             for (int i = 0; i < 8; i++) {
00085                 if ((work.buffer[work.cEnd] & (1 << i)) != 0) {
00086                     oddpar++;
00087                 }
00088             }
00089             if (dat.read() == 1) {
00090                 oddpar++;
00091             }
00092             if ((oddpar % 2) != 1) {
00093                 // printf("Data parity error.\n");
00094             }
00095             work.bitcnt++;
00096             break;
00097         case 10:
00098             /*
00099              * Stop bit.
00100              */
00101             if (dat.read() != 1) {
00102                 // printf("Illegal stop bit condition.\n");
00103             }
00104             if (work.cStart != ((work.cEnd + 1) % RINGBUFSIZ)) {
00105                 work.cEnd++;
00106                 work.cEnd = work.cEnd % RINGBUFSIZ;
00107                 work.bitcnt = 0;
00108             } else {
00109                 // printf("Buffer overrun.\n");
00110             }
00111             break;
00112         default:
00113             if ((1 <= work.bitcnt) && (work.bitcnt <= 8)) {
00114                 /*
00115                  * data bit.
00116                  */
00117                 if (dat.read() == 1) {
00118                     work.buffer[work.cEnd] |= (1 << (work.bitcnt - 1));
00119                 } else {
00120                     work.buffer[work.cEnd] &= ~(1 << (work.bitcnt - 1));
00121                 }
00122                 work.bitcnt++;
00123             } else {
00124                 /*
00125                  * Illegal internal state.
00126                  */
00127                 // printf("Illegal internal state found.\n");
00128                 init_work();
00129             }
00130             break;
00131     }
00132     wdt.detach();
00133     wdt.attach_us(this, &PS2KB::func_timeout, 250);
00134 }
00135 
00136 void PS2KB::init_work(void) {
00137     work.bitcnt = 0;
00138     work.cStart = 0;
00139     work.cEnd = 0;
00140 }