PS2 Library

Dependents:   Pong Brickbreaker

Committer:
wjohnsto
Date:
Sun Feb 27 23:34:31 2011 +0000
Revision:
0:ce15490e89e9

        

Who changed what in which revision?

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