A version of the PS/2 library customized for MbedConsole. Also includes a few things that make it's behavior easier to control and a few bug fixes.
Fork of PS2 by
Diff: PS2KB.cpp
- Revision:
- 1:823c2798e398
- Child:
- 4:fc7f4cc9fbe8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PS2KB.cpp Wed Sep 29 14:11:44 2010 +0000 @@ -0,0 +1,140 @@ +/** + * PS/2 keyboard interface control class (Version 0.0.1) + * + * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) + * http://shinta.main.jp/ + */ + +#include "PS2KB.h" + +/** + * Create. + * + * @param clk_pin Clock pin. + * @param dat_pin Data pin. + */ +PS2KB::PS2KB(PinName clk_pin, PinName dat_pin) + : clk(clk_pin), dat(dat_pin) { + init_work(); + clk.fall(this, &PS2KB::func_fall); + timeout = 1; +} + +/** + * Destory. + */ +PS2KB::~PS2KB() { + wdt.detach(); +} + +/** + * Get a data from a PS/2 device. + * + * @return A data from a PS/2 device. + */ +int PS2KB::getc() { + tot.reset(); + tot.start(); + while (work.cStart == work.cEnd) { + wait_ms(1); + if ((timeout > 0) && (tot.read_ms() > timeout)) { + // printf("Timeout occured.\n"); + return EOF; + } + } + tot.stop(); + + char c = work.buffer[work.cStart++]; + work.cStart = work.cStart % RINGBUFSIZ; + + return c; +} + +/** + * Set timeout. + * + * @param ms Timeout ms. + */ +void PS2KB::setTimeout(int ms) { + timeout = ms; +} + +void PS2KB::func_timeout(void) { + work.bitcnt = 0; +} + +void PS2KB::func_fall(void) { + int oddpar = 0; + /* + */ + switch (work.bitcnt) { + case 0: + /* + * Start bit. + */ + if (dat.read() != 0) { + // printf("Illegal start bit condition.\n"); + } + work.bitcnt++; + break; + case 9: + /* + * Parity bit. + */ + for (int i = 0; i < 8; i++) { + if ((work.buffer[work.cEnd] & (1 << i)) != 0) { + oddpar++; + } + } + if (dat.read() == 1) { + oddpar++; + } + if ((oddpar % 2) != 1) { + // printf("Data parity error.\n"); + } + work.bitcnt++; + break; + case 10: + /* + * Stop bit. + */ + if (dat.read() != 1) { + // printf("Illegal stop bit condition.\n"); + } + if (work.cStart != ((work.cEnd + 1) % RINGBUFSIZ)) { + work.cEnd++; + work.cEnd = work.cEnd % RINGBUFSIZ; + work.bitcnt = 0; + } else { + // printf("Buffer overrun.\n"); + } + break; + default: + if ((1 <= work.bitcnt) && (work.bitcnt <= 8)) { + /* + * data bit. + */ + if (dat.read() == 1) { + work.buffer[work.cEnd] |= (1 << (work.bitcnt - 1)); + } else { + work.buffer[work.cEnd] &= ~(1 << (work.bitcnt - 1)); + } + work.bitcnt++; + } else { + /* + * Illegal internal state. + */ + // printf("Illegal internal state found.\n"); + init_work(); + } + break; + } + wdt.detach(); + wdt.attach_us(this, &PS2KB::func_timeout, 250); +} + +void PS2KB::init_work(void) { + work.bitcnt = 0; + work.cStart = 0; + work.cEnd = 0; +}