PS/2

Dependents:   Synth Lab3Translator PS2_Keyboard CLI ... more

Committer:
shintamainjp
Date:
Wed Sep 29 14:11:44 2010 +0000
Revision:
1:823c2798e398
Child:
2:a57bbbec16b1

        

Who changed what in which revision?

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