PS/2

Dependents:   Synth Lab3Translator PS2_Keyboard CLI ... more

Committer:
shintamainjp
Date:
Tue Aug 31 11:25:34 2010 +0000
Revision:
0:7ee6afa15d51

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shintamainjp 0:7ee6afa15d51 1 /**
shintamainjp 0:7ee6afa15d51 2 * PS/2 interface control class (Version 0.0.1)
shintamainjp 0:7ee6afa15d51 3 *
shintamainjp 0:7ee6afa15d51 4 * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
shintamainjp 0:7ee6afa15d51 5 * http://shinta.main.jp/
shintamainjp 0:7ee6afa15d51 6 */
shintamainjp 0:7ee6afa15d51 7
shintamainjp 0:7ee6afa15d51 8 #include "PS2.h"
shintamainjp 0:7ee6afa15d51 9
shintamainjp 0:7ee6afa15d51 10 #define LOCK() sem.take()
shintamainjp 0:7ee6afa15d51 11 #define UNLOCK() sem.release()
shintamainjp 0:7ee6afa15d51 12
shintamainjp 0:7ee6afa15d51 13 PS2::PS2(PinName clkin_pin, PinName datin_pin, PinName clkout_pin, PinName datout_pin)
shintamainjp 0:7ee6afa15d51 14 :
shintamainjp 0:7ee6afa15d51 15 clkin(clkin_pin), datin(datin_pin),
shintamainjp 0:7ee6afa15d51 16 clkout(clkout_pin), datout(datout_pin),
shintamainjp 0:7ee6afa15d51 17 writepoint(0), readpoint(0) {
shintamainjp 0:7ee6afa15d51 18 init_work();
shintamainjp 0:7ee6afa15d51 19 clkin.mode(PullUp);
shintamainjp 0:7ee6afa15d51 20 datin.mode(PullUp);
shintamainjp 0:7ee6afa15d51 21 clkin.fall(this, &PS2::func_fall);
shintamainjp 0:7ee6afa15d51 22
shintamainjp 0:7ee6afa15d51 23 clkout.write(0);
shintamainjp 0:7ee6afa15d51 24 datout.write(0);
shintamainjp 0:7ee6afa15d51 25 }
shintamainjp 0:7ee6afa15d51 26
shintamainjp 0:7ee6afa15d51 27 PS2::~PS2() {
shintamainjp 0:7ee6afa15d51 28 }
shintamainjp 0:7ee6afa15d51 29
shintamainjp 0:7ee6afa15d51 30 bool PS2::exists(void) {
shintamainjp 0:7ee6afa15d51 31 LOCK();
shintamainjp 0:7ee6afa15d51 32 bool b = (readpoint == writepoint) ? false : true;
shintamainjp 0:7ee6afa15d51 33 UNLOCK();
shintamainjp 0:7ee6afa15d51 34 return b;
shintamainjp 0:7ee6afa15d51 35 }
shintamainjp 0:7ee6afa15d51 36
shintamainjp 0:7ee6afa15d51 37 int PS2::getData(uint8_t *buf, size_t bufsiz) {
shintamainjp 0:7ee6afa15d51 38 LOCK();
shintamainjp 0:7ee6afa15d51 39
shintamainjp 0:7ee6afa15d51 40 /*
shintamainjp 0:7ee6afa15d51 41 * Check a buffer empty.
shintamainjp 0:7ee6afa15d51 42 */
shintamainjp 0:7ee6afa15d51 43 if (readpoint == writepoint) {
shintamainjp 0:7ee6afa15d51 44 UNLOCK();
shintamainjp 0:7ee6afa15d51 45 return -1;
shintamainjp 0:7ee6afa15d51 46 }
shintamainjp 0:7ee6afa15d51 47
shintamainjp 0:7ee6afa15d51 48 /*
shintamainjp 0:7ee6afa15d51 49 * Check a storage buffer size.
shintamainjp 0:7ee6afa15d51 50 */
shintamainjp 0:7ee6afa15d51 51 if (bufsiz < DATABUFSIZ) {
shintamainjp 0:7ee6afa15d51 52 UNLOCK();
shintamainjp 0:7ee6afa15d51 53 return -2;
shintamainjp 0:7ee6afa15d51 54 }
shintamainjp 0:7ee6afa15d51 55
shintamainjp 0:7ee6afa15d51 56 /*
shintamainjp 0:7ee6afa15d51 57 * Copy the data.
shintamainjp 0:7ee6afa15d51 58 */
shintamainjp 0:7ee6afa15d51 59 const int nbytes = ringbuffer[readpoint].bytecnt;
shintamainjp 0:7ee6afa15d51 60 for (int i = 0; i < nbytes; i++) {
shintamainjp 0:7ee6afa15d51 61 buf[i] = ringbuffer[readpoint].buffer[i];
shintamainjp 0:7ee6afa15d51 62 }
shintamainjp 0:7ee6afa15d51 63
shintamainjp 0:7ee6afa15d51 64 /*
shintamainjp 0:7ee6afa15d51 65 * Increment read pointer.
shintamainjp 0:7ee6afa15d51 66 */
shintamainjp 0:7ee6afa15d51 67 readpoint++;
shintamainjp 0:7ee6afa15d51 68 if (RINGBUFSIZ <= readpoint) {
shintamainjp 0:7ee6afa15d51 69 readpoint = 0;
shintamainjp 0:7ee6afa15d51 70 }
shintamainjp 0:7ee6afa15d51 71
shintamainjp 0:7ee6afa15d51 72 UNLOCK();
shintamainjp 0:7ee6afa15d51 73 return nbytes;
shintamainjp 0:7ee6afa15d51 74 }
shintamainjp 0:7ee6afa15d51 75
shintamainjp 0:7ee6afa15d51 76 void PS2::func_timeout(void) {
shintamainjp 0:7ee6afa15d51 77
shintamainjp 0:7ee6afa15d51 78 LOCK();
shintamainjp 0:7ee6afa15d51 79
shintamainjp 0:7ee6afa15d51 80 /*
shintamainjp 0:7ee6afa15d51 81 * Check a buffer full.
shintamainjp 0:7ee6afa15d51 82 */
shintamainjp 0:7ee6afa15d51 83 const int n = ((readpoint - 1) < 0) ? (RINGBUFSIZ - 1) : (readpoint - 1);
shintamainjp 0:7ee6afa15d51 84 if (n == writepoint) {
shintamainjp 0:7ee6afa15d51 85 init_work();
shintamainjp 0:7ee6afa15d51 86 // printf("Buffer full.\n");
shintamainjp 0:7ee6afa15d51 87 UNLOCK();
shintamainjp 0:7ee6afa15d51 88 return;
shintamainjp 0:7ee6afa15d51 89 }
shintamainjp 0:7ee6afa15d51 90
shintamainjp 0:7ee6afa15d51 91 /*
shintamainjp 0:7ee6afa15d51 92 * Check a data size.
shintamainjp 0:7ee6afa15d51 93 */
shintamainjp 0:7ee6afa15d51 94 if (work.bytecnt == 0) {
shintamainjp 0:7ee6afa15d51 95 init_work();
shintamainjp 0:7ee6afa15d51 96 // printf("Empty data detected.\n");
shintamainjp 0:7ee6afa15d51 97 UNLOCK();
shintamainjp 0:7ee6afa15d51 98 return;
shintamainjp 0:7ee6afa15d51 99 }
shintamainjp 0:7ee6afa15d51 100
shintamainjp 0:7ee6afa15d51 101 /*
shintamainjp 0:7ee6afa15d51 102 * Check a error.
shintamainjp 0:7ee6afa15d51 103 */
shintamainjp 0:7ee6afa15d51 104 if (work.errcnt > 0) {
shintamainjp 0:7ee6afa15d51 105 init_work();
shintamainjp 0:7ee6afa15d51 106 // printf("Error detected.\n");
shintamainjp 0:7ee6afa15d51 107 UNLOCK();
shintamainjp 0:7ee6afa15d51 108 return;
shintamainjp 0:7ee6afa15d51 109 }
shintamainjp 0:7ee6afa15d51 110
shintamainjp 0:7ee6afa15d51 111 /*
shintamainjp 0:7ee6afa15d51 112 * Copy the data.
shintamainjp 0:7ee6afa15d51 113 */
shintamainjp 0:7ee6afa15d51 114 ringbuffer[writepoint].bytecnt = work.bytecnt;
shintamainjp 0:7ee6afa15d51 115 for (int i = 0; i < work.bytecnt; i++) {
shintamainjp 0:7ee6afa15d51 116 ringbuffer[writepoint].buffer[i] = work.buffer[i];
shintamainjp 0:7ee6afa15d51 117 }
shintamainjp 0:7ee6afa15d51 118
shintamainjp 0:7ee6afa15d51 119 /*
shintamainjp 0:7ee6afa15d51 120 * Increment write pointer.
shintamainjp 0:7ee6afa15d51 121 */
shintamainjp 0:7ee6afa15d51 122 writepoint++;
shintamainjp 0:7ee6afa15d51 123 if (RINGBUFSIZ <= writepoint) {
shintamainjp 0:7ee6afa15d51 124 writepoint = 0;
shintamainjp 0:7ee6afa15d51 125 }
shintamainjp 0:7ee6afa15d51 126
shintamainjp 0:7ee6afa15d51 127 /*
shintamainjp 0:7ee6afa15d51 128 * Reset variables for work.
shintamainjp 0:7ee6afa15d51 129 */
shintamainjp 0:7ee6afa15d51 130 init_work();
shintamainjp 0:7ee6afa15d51 131
shintamainjp 0:7ee6afa15d51 132 UNLOCK();
shintamainjp 0:7ee6afa15d51 133 }
shintamainjp 0:7ee6afa15d51 134
shintamainjp 0:7ee6afa15d51 135 void PS2::func_fall(void) {
shintamainjp 0:7ee6afa15d51 136
shintamainjp 0:7ee6afa15d51 137 LOCK();
shintamainjp 0:7ee6afa15d51 138
shintamainjp 0:7ee6afa15d51 139 /*
shintamainjp 0:7ee6afa15d51 140 */
shintamainjp 0:7ee6afa15d51 141 switch (work.bitcnt) {
shintamainjp 0:7ee6afa15d51 142 case 0:
shintamainjp 0:7ee6afa15d51 143 // start bit.
shintamainjp 0:7ee6afa15d51 144 /*
shintamainjp 0:7ee6afa15d51 145 */
shintamainjp 0:7ee6afa15d51 146 if (datin.read() != 0) {
shintamainjp 0:7ee6afa15d51 147 // printf("Illegal start bit condition.\n");
shintamainjp 0:7ee6afa15d51 148 work.errcnt++;
shintamainjp 0:7ee6afa15d51 149 }
shintamainjp 0:7ee6afa15d51 150 /*
shintamainjp 0:7ee6afa15d51 151 */
shintamainjp 0:7ee6afa15d51 152 work.bitcnt++;
shintamainjp 0:7ee6afa15d51 153 break;
shintamainjp 0:7ee6afa15d51 154 case 9:
shintamainjp 0:7ee6afa15d51 155 // parity bit.
shintamainjp 0:7ee6afa15d51 156 /*
shintamainjp 0:7ee6afa15d51 157 */
shintamainjp 0:7ee6afa15d51 158 {
shintamainjp 0:7ee6afa15d51 159 int oddpar = 0;
shintamainjp 0:7ee6afa15d51 160 for (int i = 0; i < 8; i++) {
shintamainjp 0:7ee6afa15d51 161 if ((work.buffer[work.bytecnt] & (1 << i)) != 0) {
shintamainjp 0:7ee6afa15d51 162 oddpar++;
shintamainjp 0:7ee6afa15d51 163 }
shintamainjp 0:7ee6afa15d51 164 }
shintamainjp 0:7ee6afa15d51 165 if (datin.read() == 1) {
shintamainjp 0:7ee6afa15d51 166 oddpar++;
shintamainjp 0:7ee6afa15d51 167 }
shintamainjp 0:7ee6afa15d51 168 if ((oddpar % 2) != 1) {
shintamainjp 0:7ee6afa15d51 169 // printf("Data parity error.\n");
shintamainjp 0:7ee6afa15d51 170 work.errcnt++;
shintamainjp 0:7ee6afa15d51 171 }
shintamainjp 0:7ee6afa15d51 172 }
shintamainjp 0:7ee6afa15d51 173 /*
shintamainjp 0:7ee6afa15d51 174 */
shintamainjp 0:7ee6afa15d51 175 work.bitcnt++;
shintamainjp 0:7ee6afa15d51 176 break;
shintamainjp 0:7ee6afa15d51 177 case 10:
shintamainjp 0:7ee6afa15d51 178 // stop bit.
shintamainjp 0:7ee6afa15d51 179 /*
shintamainjp 0:7ee6afa15d51 180 */
shintamainjp 0:7ee6afa15d51 181 if (datin.read() != 1) {
shintamainjp 0:7ee6afa15d51 182 // printf("Illegal stop bit condition.\n");
shintamainjp 0:7ee6afa15d51 183 work.errcnt++;
shintamainjp 0:7ee6afa15d51 184 }
shintamainjp 0:7ee6afa15d51 185 /*
shintamainjp 0:7ee6afa15d51 186 */
shintamainjp 0:7ee6afa15d51 187 work.bytecnt++;
shintamainjp 0:7ee6afa15d51 188 work.bitcnt = 0;
shintamainjp 0:7ee6afa15d51 189 break;
shintamainjp 0:7ee6afa15d51 190 default:
shintamainjp 0:7ee6afa15d51 191 if ((1 <= work.bitcnt) && (work.bitcnt <= 8)) {
shintamainjp 0:7ee6afa15d51 192 /*
shintamainjp 0:7ee6afa15d51 193 * data bit.
shintamainjp 0:7ee6afa15d51 194 */
shintamainjp 0:7ee6afa15d51 195 if (datin.read() == 1) {
shintamainjp 0:7ee6afa15d51 196 work.buffer[work.bytecnt] |= (1 << (work.bitcnt - 1));
shintamainjp 0:7ee6afa15d51 197 } else {
shintamainjp 0:7ee6afa15d51 198 work.buffer[work.bytecnt] &= ~(1 << (work.bitcnt - 1));
shintamainjp 0:7ee6afa15d51 199 }
shintamainjp 0:7ee6afa15d51 200 work.bitcnt++;
shintamainjp 0:7ee6afa15d51 201 } else {
shintamainjp 0:7ee6afa15d51 202 /*
shintamainjp 0:7ee6afa15d51 203 * Illegal internal state.
shintamainjp 0:7ee6afa15d51 204 */
shintamainjp 0:7ee6afa15d51 205 // printf("Illegal internal state found.\n");
shintamainjp 0:7ee6afa15d51 206 init_work();
shintamainjp 0:7ee6afa15d51 207 }
shintamainjp 0:7ee6afa15d51 208 break;
shintamainjp 0:7ee6afa15d51 209 }
shintamainjp 0:7ee6afa15d51 210
shintamainjp 0:7ee6afa15d51 211 UNLOCK();
shintamainjp 0:7ee6afa15d51 212 timeout.attach_us(this, &PS2::func_timeout, TIMEOUT_US);
shintamainjp 0:7ee6afa15d51 213 }
shintamainjp 0:7ee6afa15d51 214
shintamainjp 0:7ee6afa15d51 215 void PS2::init_work(void) {
shintamainjp 0:7ee6afa15d51 216 work.state = Idle;
shintamainjp 0:7ee6afa15d51 217 work.bitcnt = 0;
shintamainjp 0:7ee6afa15d51 218 work.bytecnt = 0;
shintamainjp 0:7ee6afa15d51 219 work.errcnt = 0;
shintamainjp 0:7ee6afa15d51 220 }