PS/2
Dependents: Synth Lab3Translator PS2_Keyboard CLI ... more
PS2.cpp@0:7ee6afa15d51, 2010-08-31 (annotated)
- Committer:
- shintamainjp
- Date:
- Tue Aug 31 11:25:34 2010 +0000
- Revision:
- 0:7ee6afa15d51
Who changed what in which revision?
User | Revision | Line number | New 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 | } |