PS/2 Keyboard

Dependents:   Hangman

Committer:
pprasad7
Date:
Thu Oct 11 20:15:09 2012 +0000
Revision:
0:62b62530a82f
PS/2 Input;

Who changed what in which revision?

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