Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 4:47b51250a168, committed 2010-10-13
- Comitter:
- shintamainjp
- Date:
- Wed Oct 13 10:50:55 2010 +0000
- Parent:
- 3:a3ba8d3e3958
- Commit message:
- First version.
Changed in this revision
--- a/PS2.lib Wed Sep 29 22:15:15 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/shintamainjp/code/PS2/#a57bbbec16b1
--- a/TextLCD.lib Wed Sep 29 22:15:15 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/simon/code/TextLCD/#44f34c09bd37
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extlib/TextLCD.lib Wed Oct 13 10:50:55 2010 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/simon/code/TextLCD/#a53b3e2d6f1e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mylib/PS2/PS2.h Wed Oct 13 10:50:55 2010 +0000
@@ -0,0 +1,46 @@
+/**
+ * PS/2 interface control class (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+
+#ifndef _PS2_H_
+#define _PS2_H_
+
+#include "mbed.h"
+
+/**
+ * PS/2 interface control class.
+ */
+class PS2 {
+public:
+ /**
+ * Create.
+ *
+ * @param clk_pin Clock pin.
+ * @param dat_pin Data pin.
+ */
+ PS2(PinName clk_pin, PinName dat_pin);
+
+ /**
+ * Destory.
+ */
+ virtual ~PS2();
+
+ /**
+ * Get a data from a PS/2 device.
+ *
+ * @return A data from a PS/2 device.
+ */
+ virtual int getc(void) = 0;
+
+ /**
+ * Set timeout.
+ *
+ * @param ms Timeout ms.
+ */
+ virtual void setTimeout(int ms) = 0;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mylib/PS2/PS2KB.cpp Wed Oct 13 10:50:55 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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mylib/PS2/PS2KB.h Wed Oct 13 10:50:55 2010 +0000
@@ -0,0 +1,67 @@
+/**
+ * PS/2 keyboard interface control class (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+
+#ifndef _PS2KB_H_
+#define _PS2KB_H_
+
+#include "mbed.h"
+
+/**
+ * PS/2 keyboard interface control class.
+ */
+class PS2KB {
+public:
+ /**
+ * Create.
+ *
+ * @param clk_pin Clock pin.
+ * @param dat_pin Data pin.
+ */
+ PS2KB(PinName clk_pin, PinName dat_pin);
+
+ /**
+ * Destory.
+ */
+ virtual ~PS2KB();
+
+ /**
+ * Get a data from a PS/2 device.
+ *
+ * @return A data from a PS/2 device.
+ */
+ virtual int getc(void);
+
+ /**
+ * Set timeout.
+ *
+ * @param ms Timeout ms.
+ */
+ virtual void setTimeout(int ms);
+
+private:
+ static const int RINGBUFSIZ = 256;
+ InterruptIn clk; /**< Interrupt input for CLK. */
+ DigitalIn dat; /**< Digital input for DAT. */
+ Timeout wdt; /**< Watch dog timer. */
+ Timer tot; /**< Timeout timer. */
+ int timeout; /**< Timeout[ms] for getc(). */
+
+ typedef struct {
+ int bitcnt;
+ int cStart;
+ int cEnd;
+ uint8_t buffer[RINGBUFSIZ];
+ } work_t;
+ work_t work;
+
+ void func_timeout(void);
+ void func_fall(void);
+
+ void init_work(void);
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mylib/PS2/PS2KB_INIT.cpp Wed Oct 13 10:50:55 2010 +0000
@@ -0,0 +1,240 @@
+/**
+ * PS/2 keyboard interface control class (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+#include "PS2KB_INIT.h"
+
+/**
+ * Create.
+ */
+PS2KB_INIT::PS2KB_INIT(PinName clk_pin, PinName dat_pin)
+ : clk(clk_pin), dat(dat_pin) {
+ clk.input();
+ dat.input();
+ clk.write(1);
+ dat.write(1);
+
+ /*
+ * 0xFF: Reset.
+ * 0xED: Set/Reset status indicators.
+ * 0xF2: Read ID.
+ * 0xF3: Set typematic rate/delay.
+ * 0xF4: Enable.
+ */
+ char txdat[12] = "\xFF\xED\x07\xF2\xED\x00\xF3\x20\xF3\x00\xF4";
+ const int n = sizeof(txdat);
+ int txerrcnt = 0;
+ int rxerrcnt = 0;
+ for (int i = 0; i < n; i++) {
+ if (send(txdat[i]) != 0) {
+ txerrcnt++;
+ }
+ if (recv() < 0) {
+ rxerrcnt++;
+ }
+ if (txdat[i] == 0xF2) {
+ if (recv() < 0) {
+ rxerrcnt++;
+ }
+ }
+ }
+
+ if (txerrcnt > 0) {
+ // printf("TX %d errors occured.\n", txerrcnt);
+ }
+ if (rxerrcnt > 0) {
+ // printf("RX %d errors occured.\n", rxerrcnt);
+ }
+}
+
+/**
+ * Destroy.
+ */
+PS2KB_INIT::~PS2KB_INIT() {
+}
+
+/**
+ * Send a byte data.
+ *
+ * @param c a character.
+ *
+ * @return Negative value is a error number.
+ */
+int PS2KB_INIT::send(uint8_t c) {
+ clk.output();
+ dat.output();
+
+ clk.write(0);
+ wait_us(200);
+
+ dat.write(0);
+ wait_us(10);
+ clk.write(1);
+ wait_us(10);
+
+ clk.input();
+ int parcnt = 0;
+ for (int i = 0; i < 10; i++) {
+ if (!waitClockDownEdge()) {
+ return -1;
+ }
+ if ((0 <= i) && (i <= 7)) {
+ /*
+ * Data bit.
+ */
+ if ((c & (1 << i)) == 0) {
+ dat.write(0);
+ } else {
+ dat.write(1);
+ parcnt++;
+ }
+ }
+ if (i == 8) {
+ /*
+ * Parity bit.
+ */
+ if ((parcnt % 2) == 0) {
+ dat.write(1);
+ } else {
+ dat.write(0);
+ }
+ }
+ if (i == 9) {
+ /*
+ * Stop bit.
+ */
+ dat.write(1);
+ }
+ }
+ dat.input();
+
+ /*
+ * Check a ACK.
+ */
+ if (!waitClockDownEdge()) {
+ return -2;
+ }
+ if (dat.read() != 0) {
+ return -3;
+ }
+
+ if (!waitClockUpLevel()) {
+ return -4;
+ }
+
+ return 0;
+}
+
+/**
+ * Receive a byte data.
+ *
+ * @return return a data. Negative value is a error number.
+ */
+int PS2KB_INIT::recv(void) {
+ uint8_t c = 0;
+ clk.input();
+ dat.input();
+ int parcnt = 0;
+ for (int i = 0; i < 11; i++) {
+ if (!waitClockDownEdge()) {
+ return -1;
+ }
+ if (i == 0) {
+ /*
+ * Start bit.
+ */
+ if (dat.read() != 0) {
+ return -2;
+ }
+ }
+ if ((1 <= i) && (i <= 8)) {
+ /*
+ * Data bit.
+ */
+ if (dat.read() == 0) {
+ c &= ~(1 << (i - 1));
+ } else {
+ c |= (1 << (i - 1));
+ parcnt++;
+ }
+ }
+ if (i == 9) {
+ /*
+ * Parity bit.
+ */
+ if (dat.read() == 0) {
+ if ((parcnt % 2) != 1) {
+ return -3;
+ }
+ } else {
+ if ((parcnt % 2) != 0) {
+ return -4;
+ }
+ }
+ }
+ if (i == 10) {
+ /*
+ * Stop bit.
+ */
+ if (dat.read() != 1) {
+ return -5;
+ }
+ }
+ }
+ return (int)c;
+}
+
+/**
+ * Wait a clock down edge.
+ *
+ * @return true if wait done.
+ */
+bool PS2KB_INIT::waitClockDownEdge(void) {
+ int cnt;
+ /*
+ * Wait until clock is low.
+ */
+ cnt = 0;
+ while (clk.read() == 0) {
+ cnt++;
+ if (MAX_RETRY < cnt) {
+ return false;
+ }
+ wait_us(1);
+ }
+ /*
+ * Wait until clock is high.
+ */
+ cnt = 0;
+ while (clk.read() == 1) {
+ cnt++;
+ if (MAX_RETRY < cnt) {
+ return false;
+ }
+ wait_us(1);
+ }
+ return true;
+}
+
+/**
+ * Wait a clock up level.
+ *
+ * @return true if wait done.
+ */
+bool PS2KB_INIT::waitClockUpLevel(void) {
+ int cnt;
+ /*
+ * Wait until clock is low.
+ */
+ cnt = 0;
+ while (clk.read() == 0) {
+ cnt++;
+ if (MAX_RETRY < cnt) {
+ return false;
+ }
+ wait_us(1);
+ }
+ return true;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mylib/PS2/PS2KB_INIT.h Wed Oct 13 10:50:55 2010 +0000
@@ -0,0 +1,64 @@
+/**
+ * PS/2 keyboard interface control class (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+#ifndef _PS2KB_INIT_H_
+#define _PS2KB_INIT_H_
+
+#include "mbed.h"
+
+/**
+ * PS2 keyboard initializer.
+ */
+class PS2KB_INIT {
+public:
+
+ /**
+ * Create.
+ */
+ PS2KB_INIT(PinName clk_pin, PinName dat_pin);
+
+ /**
+ * Destroy.
+ */
+ ~PS2KB_INIT();
+private:
+ DigitalInOut clk;
+ DigitalInOut dat;
+
+ static const int MAX_RETRY = 1000000;
+
+ /**
+ * Send a byte data.
+ *
+ * @param c a character.
+ *
+ * @return Negative value is a error number.
+ */
+ int send(uint8_t c);
+
+ /**
+ * Receive a byte data.
+ *
+ * @return return a data. Negative value is a error number.
+ */
+ int recv(void);
+
+ /**
+ * Wait a clock down edge.
+ *
+ * @return true if wait done.
+ */
+ bool waitClockDownEdge(void);
+
+ /**
+ * Wait a clock up level.
+ *
+ * @return true if wait done.
+ */
+ bool waitClockUpLevel(void);
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mylib/PS2/PS2Keyboard.cpp Wed Oct 13 10:50:55 2010 +0000
@@ -0,0 +1,117 @@
+/**
+ * PS/2 keyboard interface control class (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+#include "PS2Keyboard.h"
+
+PS2Keyboard::PS2Keyboard(PinName clk_pin, PinName dat_pin)
+ : ps2kb_init(clk_pin, dat_pin), ps2kb(clk_pin, dat_pin) {
+}
+
+PS2Keyboard::~PS2Keyboard() {
+}
+
+bool PS2Keyboard::processing(keyboard_event_t *p) {
+ bool emit = false;
+ const int c = ps2kb.getc();
+ if (0 <= c) {
+ scancode[count++] = c;
+ switch (count) {
+ case 1:
+ if ((scancode[0] != 0xE0)
+ && (scancode[0] != 0xE1)
+ && (scancode[0] != 0xF0)) {
+ p->type = KeyMake;
+ p->length = count;
+ memcpy(p->scancode, scancode, sizeof(p->scancode));
+ emit = true;
+ count = 0;
+ }
+ break;
+ case 2:
+ if (scancode[0] == 0xF0) {
+ p->type = KeyBreak;
+ p->length = count;
+ memcpy(p->scancode, scancode, sizeof(p->scancode));
+ emit = true;
+ count = 0;
+ }
+ if ((scancode[0] == 0xE0)
+ && (scancode[1] != 0xF0)
+ && (scancode[1] != 0x12)) {
+ p->type = KeyMake;
+ p->length = count;
+ memcpy(p->scancode, scancode, sizeof(p->scancode));
+ emit = true;
+ count = 0;
+ }
+ break;
+ case 3:
+ if ((scancode[0] == 0xE0)
+ && (scancode[1] == 0xF0)
+ && (scancode[2] != 0x7C)) {
+ p->type = KeyBreak;
+ p->length = count;
+ memcpy(p->scancode, scancode, sizeof(p->scancode));
+ emit = true;
+ count = 0;
+ }
+ break;
+ case 4:
+ if ((scancode[0] == 0xE0)
+ && (scancode[1] == 0x12)
+ && (scancode[2] == 0xE0)
+ && (scancode[3] == 0x7C)) {
+ p->type = KeyMake;
+ p->length = count;
+ memcpy(p->scancode, scancode, sizeof(p->scancode));
+ emit = true;
+ count = 0;
+ }
+ break;
+ case 5:
+ // Do nothing.
+ break;
+ case 6:
+ if ((scancode[0] == 0xE0)
+ && (scancode[1] == 0xF0)
+ && (scancode[2] == 0x7C)
+ && (scancode[3] == 0xE0)
+ && (scancode[4] == 0xF0)
+ && (scancode[5] == 0x12)) {
+ p->type = KeyBreak;
+ p->length = count;
+ memcpy(p->scancode, scancode, sizeof(p->scancode));
+ emit = true;
+ count = 0;
+ }
+ break;
+ case 7:
+ // Do nothing.
+ break;
+ case 8:
+ if ((scancode[0] == 0xE1)
+ && (scancode[1] == 0x14)
+ && (scancode[2] == 0x77)
+ && (scancode[3] == 0xE1)
+ && (scancode[4] == 0xF0)
+ && (scancode[5] == 0x14)
+ && (scancode[6] == 0xF0)
+ && (scancode[7] == 0x77)) {
+ p->type = KeyMake;
+ p->length = count;
+ memcpy(p->scancode, scancode, sizeof(p->scancode));
+ emit = true;
+ count = 0;
+ }
+ break;
+ default:
+ count = 0;
+ break;
+ }
+ count = count % sizeof(scancode);
+ }
+ return emit;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mylib/PS2/PS2Keyboard.h Wed Oct 13 10:50:55 2010 +0000
@@ -0,0 +1,34 @@
+/**
+ * PS/2 keyboard interface control class (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+#ifndef _PS2_KEYBOARD_H_
+#define _PS2_KEYBOARD_H_
+
+#include "PS2KB_INIT.h"
+#include "PS2KB.h"
+
+class PS2Keyboard {
+public:
+ PS2Keyboard(PinName clk_pin, PinName dat_pin);
+ ~PS2Keyboard();
+ typedef enum {
+ KeyMake,
+ KeyBreak
+ } Type;
+ typedef struct {
+ Type type;
+ int length;
+ char scancode[8];
+ } keyboard_event_t;
+ bool processing(keyboard_event_t *p);
+private:
+ PS2KB_INIT ps2kb_init;
+ PS2KB ps2kb;
+ int count;
+ char scancode[8];
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mylib/PS2/PS2MS.cpp Wed Oct 13 10:50:55 2010 +0000
@@ -0,0 +1,135 @@
+/**
+ * PS/2 mouse interface control class (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+
+#include "PS2MS.h"
+
+/**
+ * Create.
+ *
+ * @param clk_pin Clock pin.
+ * @param dat_pin Data pin.
+ */
+PS2MS::PS2MS(PinName clk_pin, PinName dat_pin)
+ : clk(clk_pin), dat(dat_pin) {
+ init_work();
+ clk.fall(this, &PS2MS::func_fall);
+ timeout = 1;
+}
+
+/**
+ * Destory.
+ */
+PS2MS::~PS2MS() {
+ wdt.detach();
+}
+
+int PS2MS::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 PS2MS::setTimeout(int ms) {
+ timeout = ms;
+}
+
+void PS2MS::func_timeout(void) {
+ work.bitcnt = 0;
+}
+
+void PS2MS::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, &PS2MS::func_timeout, 250);
+}
+
+void PS2MS::init_work(void) {
+ work.bitcnt = 0;
+ work.cStart = 0;
+ work.cEnd = 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mylib/PS2/PS2MS.h Wed Oct 13 10:50:55 2010 +0000
@@ -0,0 +1,67 @@
+/**
+ * PS/2 mouse interface control class (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+
+#ifndef _PS2MS_H_
+#define _PS2MS_H_
+
+#include "mbed.h"
+
+/**
+ * PS/2 mouse interface control class.
+ */
+class PS2MS {
+public:
+ /**
+ * Create.
+ *
+ * @param clk_pin Clock pin.
+ * @param dat_pin Data pin.
+ */
+ PS2MS(PinName clk_pin, PinName dat_pin);
+
+ /**
+ * Destory.
+ */
+ virtual ~PS2MS();
+
+ /**
+ * Get a data from a PS/2 device.
+ *
+ * @return A data from a PS/2 device.
+ */
+ virtual int getc(void);
+
+ /**
+ * Set timeout.
+ *
+ * @param ms Timeout ms.
+ */
+ virtual void setTimeout(int ms);
+
+private:
+ static const int RINGBUFSIZ = 1024;
+ InterruptIn clk; /**< Interrupt input for CLK. */
+ DigitalIn dat; /**< Digital input for DAT. */
+ Timeout wdt; /**< Watch dog timer. */
+ Timer tot; /**< Timeout timer. */
+ int timeout; /**< Timeout[ms] for getc(). */
+
+ typedef struct {
+ int bitcnt;
+ int cStart;
+ int cEnd;
+ uint8_t buffer[RINGBUFSIZ];
+ } work_t;
+ work_t work;
+
+ void func_timeout(void);
+ void func_fall(void);
+
+ void init_work(void);
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mylib/PS2/PS2MS_INIT.cpp Wed Oct 13 10:50:55 2010 +0000
@@ -0,0 +1,249 @@
+/**
+ * PS/2 mouse interface control class (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+#include "PS2MS_INIT.h"
+
+/**
+ * Create.
+ */
+PS2MS_INIT::PS2MS_INIT(PinName clk_pin, PinName dat_pin)
+ : clk(clk_pin), dat(dat_pin) {
+ clk.input();
+ dat.input();
+ clk.write(1);
+ dat.write(1);
+
+ /*
+ * 0xFF: Reset command.
+ * 0xF3: Set sample rate.
+ * 0xF2: Read device type.
+ * 0xE8: Set resolution.
+ * 0xE6: Set scaling.
+ * 0xF4: Enable device.
+ */
+ char txdat[17] = "\xFF\xFF\xFF\xF3\xC8\xF3\x64\xF3\x50\xF2\xE8\x03\xE6\xF3\x28\xF4";
+ const int n = sizeof(txdat);
+ int txerrcnt = 0;
+ int rxerrcnt = 0;
+ for (int i = 0; i < n; i++) {
+ if (send(txdat[i]) != 0) {
+ txerrcnt++;
+ }
+ if (recv() < 0) {
+ rxerrcnt++;
+ }
+ if (txdat[i] == 0xF2) {
+ if (recv() < 0) {
+ rxerrcnt++;
+ }
+ }
+ if (txdat[i] == 0xFF) {
+ if (recv() < 0) {
+ rxerrcnt++;
+ }
+ if (recv() < 0) {
+ rxerrcnt++;
+ }
+ }
+ }
+
+ if (txerrcnt > 0) {
+ // printf("TX %d errors occured.\n", txerrcnt);
+ }
+ if (rxerrcnt > 0) {
+ // printf("RX %d errors occured.\n", rxerrcnt);
+ }
+}
+
+/**
+ * Destroy.
+ */
+PS2MS_INIT::~PS2MS_INIT() {
+}
+
+/**
+ * Send a byte data.
+ *
+ * @param c a character.
+ *
+ * @return Negative value is a error number.
+ */
+int PS2MS_INIT::send(uint8_t c) {
+ clk.output();
+ dat.output();
+
+ clk.write(0);
+ wait_us(200);
+
+ dat.write(0);
+ wait_us(10);
+ clk.write(1);
+ wait_us(10);
+
+ clk.input();
+ int parcnt = 0;
+ for (int i = 0; i < 10; i++) {
+ if (!waitClockDownEdge()) {
+ return -1;
+ }
+ if ((0 <= i) && (i <= 7)) {
+ /*
+ * Data bit.
+ */
+ if ((c & (1 << i)) == 0) {
+ dat.write(0);
+ } else {
+ dat.write(1);
+ parcnt++;
+ }
+ }
+ if (i == 8) {
+ /*
+ * Parity bit.
+ */
+ if ((parcnt % 2) == 0) {
+ dat.write(1);
+ } else {
+ dat.write(0);
+ }
+ }
+ if (i == 9) {
+ /*
+ * Stop bit.
+ */
+ dat.write(1);
+ }
+ }
+ dat.input();
+
+ /*
+ * Check a ACK.
+ */
+ if (!waitClockDownEdge()) {
+ return -2;
+ }
+ if (dat.read() != 0) {
+ return -3;
+ }
+
+ if (!waitClockUpLevel()) {
+ return -4;
+ }
+
+ return 0;
+}
+
+/**
+ * Receive a byte data.
+ *
+ * @return return a data. Negative value is a error number.
+ */
+int PS2MS_INIT::recv(void) {
+ uint8_t c = 0;
+ clk.input();
+ dat.input();
+ int parcnt = 0;
+ for (int i = 0; i < 11; i++) {
+ if (!waitClockDownEdge()) {
+ return -1;
+ }
+ if (i == 0) {
+ /*
+ * Start bit.
+ */
+ if (dat.read() != 0) {
+ return -2;
+ }
+ }
+ if ((1 <= i) && (i <= 8)) {
+ /*
+ * Data bit.
+ */
+ if (dat.read() == 0) {
+ c &= ~(1 << (i - 1));
+ } else {
+ c |= (1 << (i - 1));
+ parcnt++;
+ }
+ }
+ if (i == 9) {
+ /*
+ * Parity bit.
+ */
+ if (dat.read() == 0) {
+ if ((parcnt % 2) != 1) {
+ return -3;
+ }
+ } else {
+ if ((parcnt % 2) != 0) {
+ return -4;
+ }
+ }
+ }
+ if (i == 10) {
+ /*
+ * Stop bit.
+ */
+ if (dat.read() != 1) {
+ return -5;
+ }
+ }
+ }
+ return (int)c;
+}
+
+/**
+ * Wait a clock down edge.
+ *
+ * @return true if wait done.
+ */
+bool PS2MS_INIT::waitClockDownEdge(void) {
+ int cnt;
+ /*
+ * Wait until clock is low.
+ */
+ cnt = 0;
+ while (clk.read() == 0) {
+ cnt++;
+ if (MAX_RETRY < cnt) {
+ return false;
+ }
+ wait_us(1);
+ }
+ /*
+ * Wait until clock is high.
+ */
+ cnt = 0;
+ while (clk.read() == 1) {
+ cnt++;
+ if (MAX_RETRY < cnt) {
+ return false;
+ }
+ wait_us(1);
+ }
+ return true;
+}
+
+/**
+ * Wait a clock up level.
+ *
+ * @return true if wait done.
+ */
+bool PS2MS_INIT::waitClockUpLevel(void) {
+ int cnt;
+ /*
+ * Wait until clock is low.
+ */
+ cnt = 0;
+ while (clk.read() == 0) {
+ cnt++;
+ if (MAX_RETRY < cnt) {
+ return false;
+ }
+ wait_us(1);
+ }
+ return true;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mylib/PS2/PS2MS_INIT.h Wed Oct 13 10:50:55 2010 +0000
@@ -0,0 +1,64 @@
+/**
+ * PS/2 mouse interface control class (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+#ifndef _PS2MS_INIT_H_
+#define _PS2MS_INIT_H_
+
+#include "mbed.h"
+
+/**
+ * PS2 mouse initializer.
+ */
+class PS2MS_INIT {
+public:
+
+ /**
+ * Create.
+ */
+ PS2MS_INIT(PinName clk_pin, PinName dat_pin);
+
+ /**
+ * Destroy.
+ */
+ ~PS2MS_INIT();
+private:
+ DigitalInOut clk;
+ DigitalInOut dat;
+
+ static const int MAX_RETRY = 1000000;
+
+ /**
+ * Send a byte data.
+ *
+ * @param c a character.
+ *
+ * @return Negative value is a error number.
+ */
+ int send(uint8_t c);
+
+ /**
+ * Receive a byte data.
+ *
+ * @return return a data. Negative value is a error number.
+ */
+ int recv(void);
+
+ /**
+ * Wait a clock down edge.
+ *
+ * @return true if wait done.
+ */
+ bool waitClockDownEdge(void);
+
+ /**
+ * Wait a clock up level.
+ *
+ * @return true if wait done.
+ */
+ bool waitClockUpLevel(void);
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mylib/PS2/PS2Mouse.cpp Wed Oct 13 10:50:55 2010 +0000
@@ -0,0 +1,58 @@
+/**
+ * PS/2 mouse interface control class (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+#include "PS2Mouse.h"
+
+PS2Mouse::PS2Mouse(PinName clk_pin, PinName dat_pin)
+ : ps2ms_init(clk_pin, dat_pin), ps2ms(clk_pin, dat_pin) {
+ cnt = 0;
+}
+
+PS2Mouse::~PS2Mouse() {
+}
+
+bool PS2Mouse::processing(mouse_event_t *p) {
+ bool emit = false;
+ for (int i = 0; i < 4; i++) {
+ const int c = ps2ms.getc();
+ if (0 <= c) {
+ switch (cnt % 4) {
+ case 0:
+ mi.byte1.byte = c;
+ /*
+ * Check and reset a buffer if state is wrong.
+ */
+ if (mi.byte1.bit.always1 == 0) {
+ cnt = 0;
+ while (0 <= ps2ms.getc()) {
+ }
+ }
+ break;
+ case 1:
+ mi.byte2.byte = c;
+ break;
+ case 2:
+ mi.byte3.byte = c;
+ break;
+ case 3:
+ mi.byte4.byte = c;
+ /*
+ * Store a event data.
+ */
+ p->left = mi.byte1.bit.btnLeft ? true : false;
+ p->center = mi.byte1.bit.btnCenter ? true : false;
+ p->right = mi.byte1.bit.btnRight ? true : false;
+ p->x = mi.byte1.bit.signX ? (-256 + mi.byte2.byte) : mi.byte2.byte;
+ p->y = mi.byte1.bit.signY ? (-256 + mi.byte3.byte) : mi.byte3.byte;
+ p->z = mi.byte4.bit.signZ ? (-128 + mi.byte4.bit.value) : mi.byte4.bit.value;
+ emit = true;
+ break;
+ }
+ cnt++;
+ }
+ }
+ return emit;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mylib/PS2/PS2Mouse.h Wed Oct 13 10:50:55 2010 +0000
@@ -0,0 +1,61 @@
+/**
+ * PS/2 mouse interface control class (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+#ifndef _PS2_MOUSE_H_
+#define _PS2_MOUSE_H_
+
+#include "PS2MS_INIT.h"
+#include "PS2MS.h"
+
+class PS2Mouse {
+public:
+ PS2Mouse(PinName clk_pin, PinName dat_pin);
+ ~PS2Mouse();
+ typedef struct {
+ bool left;
+ bool center;
+ bool right;
+ int x;
+ int y;
+ int z;
+ } mouse_event_t;
+ bool processing(mouse_event_t *p);
+private:
+ PS2MS_INIT ps2ms_init;
+ PS2MS ps2ms;
+ typedef struct {
+ union {
+ uint8_t byte;
+ struct {
+ uint8_t btnLeft:1;
+ uint8_t btnRight:1;
+ uint8_t btnCenter:1;
+ uint8_t always1:1;
+ uint8_t signX:1;
+ uint8_t signY:1;
+ uint8_t overflowX:1;
+ uint8_t overflowY:1;
+ } bit;
+ } byte1;
+ union {
+ uint8_t byte;
+ } byte2;
+ union {
+ uint8_t byte;
+ } byte3;
+ union {
+ uint8_t byte;
+ struct {
+ uint8_t value:7;
+ uint8_t signZ:1;
+ } bit;
+ } byte4;
+ } mouse_info_t;
+ mouse_info_t mi;
+ int cnt;
+};
+
+#endif