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.

Dependents:   MbedConsole

Fork of PS2 by Shinichiro Nakamura

Committer:
earlz
Date:
Fri Sep 28 04:03:35 2012 +0000
Revision:
5:ead90ca02b18
Parent:
2:a57bbbec16b1
Changed interrupt priority and initialization to use keyboard defaults

Who changed what in which revision?

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