PS2 keyboard

Dependents:   uVGAII_WebBrowser

Committer:
yaolu23
Date:
Wed Mar 12 16:15:14 2014 +0000
Revision:
0:33c8907eb27a
na

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yaolu23 0:33c8907eb27a 1 /**
yaolu23 0:33c8907eb27a 2 * PS/2 keyboard interface control class (Version 0.0.1)
yaolu23 0:33c8907eb27a 3 *
yaolu23 0:33c8907eb27a 4 * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
yaolu23 0:33c8907eb27a 5 * http://shinta.main.jp/
yaolu23 0:33c8907eb27a 6 */
yaolu23 0:33c8907eb27a 7 #include "PS2KB_INIT.h"
yaolu23 0:33c8907eb27a 8
yaolu23 0:33c8907eb27a 9 /**
yaolu23 0:33c8907eb27a 10 * Create.
yaolu23 0:33c8907eb27a 11 */
yaolu23 0:33c8907eb27a 12 PS2KB_INIT::PS2KB_INIT(PinName clk_pin, PinName dat_pin)
yaolu23 0:33c8907eb27a 13 : clk(clk_pin), dat(dat_pin) {
yaolu23 0:33c8907eb27a 14 clk.input();
yaolu23 0:33c8907eb27a 15 dat.input();
yaolu23 0:33c8907eb27a 16 clk.write(1);
yaolu23 0:33c8907eb27a 17 dat.write(1);
yaolu23 0:33c8907eb27a 18
yaolu23 0:33c8907eb27a 19 /*
yaolu23 0:33c8907eb27a 20 * 0xFF: Reset.
yaolu23 0:33c8907eb27a 21 * 0xED: Set/Reset status indicators.
yaolu23 0:33c8907eb27a 22 * 0xF2: Read ID.
yaolu23 0:33c8907eb27a 23 * 0xF3: Set typematic rate/delay.
yaolu23 0:33c8907eb27a 24 * 0xF4: Enable.
yaolu23 0:33c8907eb27a 25 */
yaolu23 0:33c8907eb27a 26 char txdat[12] = "\xFF\xED\x07\xF2\xED\x00\xF3\x20\xF3\x00\xF4";
yaolu23 0:33c8907eb27a 27 const int n = sizeof(txdat);
yaolu23 0:33c8907eb27a 28 int txerrcnt = 0;
yaolu23 0:33c8907eb27a 29 int rxerrcnt = 0;
yaolu23 0:33c8907eb27a 30 for (int i = 0; i < n; i++) {
yaolu23 0:33c8907eb27a 31 if (send(txdat[i]) != 0) {
yaolu23 0:33c8907eb27a 32 txerrcnt++;
yaolu23 0:33c8907eb27a 33 }
yaolu23 0:33c8907eb27a 34 if (recv() < 0) {
yaolu23 0:33c8907eb27a 35 rxerrcnt++;
yaolu23 0:33c8907eb27a 36 }
yaolu23 0:33c8907eb27a 37 if (txdat[i] == 0xF2) {
yaolu23 0:33c8907eb27a 38 if (recv() < 0) {
yaolu23 0:33c8907eb27a 39 rxerrcnt++;
yaolu23 0:33c8907eb27a 40 }
yaolu23 0:33c8907eb27a 41 }
yaolu23 0:33c8907eb27a 42 }
yaolu23 0:33c8907eb27a 43
yaolu23 0:33c8907eb27a 44 if (txerrcnt > 0) {
yaolu23 0:33c8907eb27a 45 // printf("TX %d errors occured.\n", txerrcnt);
yaolu23 0:33c8907eb27a 46 }
yaolu23 0:33c8907eb27a 47 if (rxerrcnt > 0) {
yaolu23 0:33c8907eb27a 48 // printf("RX %d errors occured.\n", rxerrcnt);
yaolu23 0:33c8907eb27a 49 }
yaolu23 0:33c8907eb27a 50 }
yaolu23 0:33c8907eb27a 51
yaolu23 0:33c8907eb27a 52 /**
yaolu23 0:33c8907eb27a 53 * Destroy.
yaolu23 0:33c8907eb27a 54 */
yaolu23 0:33c8907eb27a 55 PS2KB_INIT::~PS2KB_INIT() {
yaolu23 0:33c8907eb27a 56 }
yaolu23 0:33c8907eb27a 57
yaolu23 0:33c8907eb27a 58 /**
yaolu23 0:33c8907eb27a 59 * Send a byte data.
yaolu23 0:33c8907eb27a 60 *
yaolu23 0:33c8907eb27a 61 * @param c a character.
yaolu23 0:33c8907eb27a 62 *
yaolu23 0:33c8907eb27a 63 * @return Negative value is a error number.
yaolu23 0:33c8907eb27a 64 */
yaolu23 0:33c8907eb27a 65 int PS2KB_INIT::send(uint8_t c) {
yaolu23 0:33c8907eb27a 66 clk.output();
yaolu23 0:33c8907eb27a 67 dat.output();
yaolu23 0:33c8907eb27a 68
yaolu23 0:33c8907eb27a 69 clk.write(0);
yaolu23 0:33c8907eb27a 70 wait_us(200);
yaolu23 0:33c8907eb27a 71
yaolu23 0:33c8907eb27a 72 dat.write(0);
yaolu23 0:33c8907eb27a 73 wait_us(10);
yaolu23 0:33c8907eb27a 74 clk.write(1);
yaolu23 0:33c8907eb27a 75 wait_us(10);
yaolu23 0:33c8907eb27a 76
yaolu23 0:33c8907eb27a 77 clk.input();
yaolu23 0:33c8907eb27a 78 int parcnt = 0;
yaolu23 0:33c8907eb27a 79 for (int i = 0; i < 10; i++) {
yaolu23 0:33c8907eb27a 80 if (!waitClockDownEdge()) {
yaolu23 0:33c8907eb27a 81 return -1;
yaolu23 0:33c8907eb27a 82 }
yaolu23 0:33c8907eb27a 83 if ((0 <= i) && (i <= 7)) {
yaolu23 0:33c8907eb27a 84 /*
yaolu23 0:33c8907eb27a 85 * Data bit.
yaolu23 0:33c8907eb27a 86 */
yaolu23 0:33c8907eb27a 87 if ((c & (1 << i)) == 0) {
yaolu23 0:33c8907eb27a 88 dat.write(0);
yaolu23 0:33c8907eb27a 89 } else {
yaolu23 0:33c8907eb27a 90 dat.write(1);
yaolu23 0:33c8907eb27a 91 parcnt++;
yaolu23 0:33c8907eb27a 92 }
yaolu23 0:33c8907eb27a 93 }
yaolu23 0:33c8907eb27a 94 if (i == 8) {
yaolu23 0:33c8907eb27a 95 /*
yaolu23 0:33c8907eb27a 96 * Parity bit.
yaolu23 0:33c8907eb27a 97 */
yaolu23 0:33c8907eb27a 98 if ((parcnt % 2) == 0) {
yaolu23 0:33c8907eb27a 99 dat.write(1);
yaolu23 0:33c8907eb27a 100 } else {
yaolu23 0:33c8907eb27a 101 dat.write(0);
yaolu23 0:33c8907eb27a 102 }
yaolu23 0:33c8907eb27a 103 }
yaolu23 0:33c8907eb27a 104 if (i == 9) {
yaolu23 0:33c8907eb27a 105 /*
yaolu23 0:33c8907eb27a 106 * Stop bit.
yaolu23 0:33c8907eb27a 107 */
yaolu23 0:33c8907eb27a 108 dat.write(1);
yaolu23 0:33c8907eb27a 109 }
yaolu23 0:33c8907eb27a 110 }
yaolu23 0:33c8907eb27a 111 dat.input();
yaolu23 0:33c8907eb27a 112
yaolu23 0:33c8907eb27a 113 /*
yaolu23 0:33c8907eb27a 114 * Check a ACK.
yaolu23 0:33c8907eb27a 115 */
yaolu23 0:33c8907eb27a 116 if (!waitClockDownEdge()) {
yaolu23 0:33c8907eb27a 117 return -2;
yaolu23 0:33c8907eb27a 118 }
yaolu23 0:33c8907eb27a 119 if (dat.read() != 0) {
yaolu23 0:33c8907eb27a 120 return -3;
yaolu23 0:33c8907eb27a 121 }
yaolu23 0:33c8907eb27a 122
yaolu23 0:33c8907eb27a 123 if (!waitClockUpLevel()) {
yaolu23 0:33c8907eb27a 124 return -4;
yaolu23 0:33c8907eb27a 125 }
yaolu23 0:33c8907eb27a 126
yaolu23 0:33c8907eb27a 127 return 0;
yaolu23 0:33c8907eb27a 128 }
yaolu23 0:33c8907eb27a 129
yaolu23 0:33c8907eb27a 130 /**
yaolu23 0:33c8907eb27a 131 * Receive a byte data.
yaolu23 0:33c8907eb27a 132 *
yaolu23 0:33c8907eb27a 133 * @return return a data. Negative value is a error number.
yaolu23 0:33c8907eb27a 134 */
yaolu23 0:33c8907eb27a 135 int PS2KB_INIT::recv(void) {
yaolu23 0:33c8907eb27a 136 uint8_t c = 0;
yaolu23 0:33c8907eb27a 137 clk.input();
yaolu23 0:33c8907eb27a 138 dat.input();
yaolu23 0:33c8907eb27a 139 int parcnt = 0;
yaolu23 0:33c8907eb27a 140 for (int i = 0; i < 11; i++) {
yaolu23 0:33c8907eb27a 141 if (!waitClockDownEdge()) {
yaolu23 0:33c8907eb27a 142 return -1;
yaolu23 0:33c8907eb27a 143 }
yaolu23 0:33c8907eb27a 144 if (i == 0) {
yaolu23 0:33c8907eb27a 145 /*
yaolu23 0:33c8907eb27a 146 * Start bit.
yaolu23 0:33c8907eb27a 147 */
yaolu23 0:33c8907eb27a 148 if (dat.read() != 0) {
yaolu23 0:33c8907eb27a 149 return -2;
yaolu23 0:33c8907eb27a 150 }
yaolu23 0:33c8907eb27a 151 }
yaolu23 0:33c8907eb27a 152 if ((1 <= i) && (i <= 8)) {
yaolu23 0:33c8907eb27a 153 /*
yaolu23 0:33c8907eb27a 154 * Data bit.
yaolu23 0:33c8907eb27a 155 */
yaolu23 0:33c8907eb27a 156 if (dat.read() == 0) {
yaolu23 0:33c8907eb27a 157 c &= ~(1 << (i - 1));
yaolu23 0:33c8907eb27a 158 } else {
yaolu23 0:33c8907eb27a 159 c |= (1 << (i - 1));
yaolu23 0:33c8907eb27a 160 parcnt++;
yaolu23 0:33c8907eb27a 161 }
yaolu23 0:33c8907eb27a 162 }
yaolu23 0:33c8907eb27a 163 if (i == 9) {
yaolu23 0:33c8907eb27a 164 /*
yaolu23 0:33c8907eb27a 165 * Parity bit.
yaolu23 0:33c8907eb27a 166 */
yaolu23 0:33c8907eb27a 167 if (dat.read() == 0) {
yaolu23 0:33c8907eb27a 168 if ((parcnt % 2) != 1) {
yaolu23 0:33c8907eb27a 169 return -3;
yaolu23 0:33c8907eb27a 170 }
yaolu23 0:33c8907eb27a 171 } else {
yaolu23 0:33c8907eb27a 172 if ((parcnt % 2) != 0) {
yaolu23 0:33c8907eb27a 173 return -4;
yaolu23 0:33c8907eb27a 174 }
yaolu23 0:33c8907eb27a 175 }
yaolu23 0:33c8907eb27a 176 }
yaolu23 0:33c8907eb27a 177 if (i == 10) {
yaolu23 0:33c8907eb27a 178 /*
yaolu23 0:33c8907eb27a 179 * Stop bit.
yaolu23 0:33c8907eb27a 180 */
yaolu23 0:33c8907eb27a 181 if (dat.read() != 1) {
yaolu23 0:33c8907eb27a 182 return -5;
yaolu23 0:33c8907eb27a 183 }
yaolu23 0:33c8907eb27a 184 }
yaolu23 0:33c8907eb27a 185 }
yaolu23 0:33c8907eb27a 186 return (int)c;
yaolu23 0:33c8907eb27a 187 }
yaolu23 0:33c8907eb27a 188
yaolu23 0:33c8907eb27a 189 /**
yaolu23 0:33c8907eb27a 190 * Wait a clock down edge.
yaolu23 0:33c8907eb27a 191 *
yaolu23 0:33c8907eb27a 192 * @return true if wait done.
yaolu23 0:33c8907eb27a 193 */
yaolu23 0:33c8907eb27a 194 bool PS2KB_INIT::waitClockDownEdge(void) {
yaolu23 0:33c8907eb27a 195 int cnt;
yaolu23 0:33c8907eb27a 196 /*
yaolu23 0:33c8907eb27a 197 * Wait until clock is low.
yaolu23 0:33c8907eb27a 198 */
yaolu23 0:33c8907eb27a 199 cnt = 0;
yaolu23 0:33c8907eb27a 200 while (clk.read() == 0) {
yaolu23 0:33c8907eb27a 201 cnt++;
yaolu23 0:33c8907eb27a 202 if (MAX_RETRY < cnt) {
yaolu23 0:33c8907eb27a 203 return false;
yaolu23 0:33c8907eb27a 204 }
yaolu23 0:33c8907eb27a 205 wait_us(1);
yaolu23 0:33c8907eb27a 206 }
yaolu23 0:33c8907eb27a 207 /*
yaolu23 0:33c8907eb27a 208 * Wait until clock is high.
yaolu23 0:33c8907eb27a 209 */
yaolu23 0:33c8907eb27a 210 cnt = 0;
yaolu23 0:33c8907eb27a 211 while (clk.read() == 1) {
yaolu23 0:33c8907eb27a 212 cnt++;
yaolu23 0:33c8907eb27a 213 if (MAX_RETRY < cnt) {
yaolu23 0:33c8907eb27a 214 return false;
yaolu23 0:33c8907eb27a 215 }
yaolu23 0:33c8907eb27a 216 wait_us(1);
yaolu23 0:33c8907eb27a 217 }
yaolu23 0:33c8907eb27a 218 return true;
yaolu23 0:33c8907eb27a 219 }
yaolu23 0:33c8907eb27a 220
yaolu23 0:33c8907eb27a 221 /**
yaolu23 0:33c8907eb27a 222 * Wait a clock up level.
yaolu23 0:33c8907eb27a 223 *
yaolu23 0:33c8907eb27a 224 * @return true if wait done.
yaolu23 0:33c8907eb27a 225 */
yaolu23 0:33c8907eb27a 226 bool PS2KB_INIT::waitClockUpLevel(void) {
yaolu23 0:33c8907eb27a 227 int cnt;
yaolu23 0:33c8907eb27a 228 /*
yaolu23 0:33c8907eb27a 229 * Wait until clock is low.
yaolu23 0:33c8907eb27a 230 */
yaolu23 0:33c8907eb27a 231 cnt = 0;
yaolu23 0:33c8907eb27a 232 while (clk.read() == 0) {
yaolu23 0:33c8907eb27a 233 cnt++;
yaolu23 0:33c8907eb27a 234 if (MAX_RETRY < cnt) {
yaolu23 0:33c8907eb27a 235 return false;
yaolu23 0:33c8907eb27a 236 }
yaolu23 0:33c8907eb27a 237 wait_us(1);
yaolu23 0:33c8907eb27a 238 }
yaolu23 0:33c8907eb27a 239 return true;
yaolu23 0:33c8907eb27a 240 }