Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
PS2KB_INIT.cpp
00001 /** 00002 * PS/2 keyboard interface control class (Version 0.0.1) 00003 * 00004 * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) 00005 * http://shinta.main.jp/ 00006 */ 00007 #include "PS2KB_INIT.h" 00008 00009 /** 00010 * Create. 00011 */ 00012 PS2KB_INIT::PS2KB_INIT(PinName clk_pin, PinName dat_pin) 00013 : clk(clk_pin), dat(dat_pin) { 00014 clk.input(); 00015 dat.input(); 00016 clk.write(1); 00017 dat.write(1); 00018 00019 /* 00020 * 0xFF: Reset. 00021 * 0xED: Set/Reset status indicators. 00022 * 0xF2: Read ID. 00023 * 0xF3: Set typematic rate/delay. 00024 * 0xF4: Enable. 00025 */ 00026 char txdat[12] = "\xFF\xED\x07\xF2\xED\x00\xF3\x20\xF3\x00\xF4"; 00027 const int n = sizeof(txdat); 00028 int txerrcnt = 0; 00029 int rxerrcnt = 0; 00030 for (int i = 0; i < n; i++) { 00031 if (send(txdat[i]) != 0) { 00032 txerrcnt++; 00033 } 00034 if (recv() < 0) { 00035 rxerrcnt++; 00036 } 00037 if (txdat[i] == 0xF2) { 00038 if (recv() < 0) { 00039 rxerrcnt++; 00040 } 00041 } 00042 } 00043 00044 if (txerrcnt > 0) { 00045 // printf("TX %d errors occured.\n", txerrcnt); 00046 } 00047 if (rxerrcnt > 0) { 00048 // printf("RX %d errors occured.\n", rxerrcnt); 00049 } 00050 } 00051 00052 /** 00053 * Destroy. 00054 */ 00055 PS2KB_INIT::~PS2KB_INIT() { 00056 } 00057 00058 /** 00059 * Send a byte data. 00060 * 00061 * @param c a character. 00062 * 00063 * @return Negative value is a error number. 00064 */ 00065 int PS2KB_INIT::send(uint8_t c) { 00066 clk.output(); 00067 dat.output(); 00068 00069 clk.write(0); 00070 wait_us(200); 00071 00072 dat.write(0); 00073 wait_us(10); 00074 clk.write(1); 00075 wait_us(10); 00076 00077 clk.input(); 00078 int parcnt = 0; 00079 for (int i = 0; i < 10; i++) { 00080 if (!waitClockDownEdge()) { 00081 return -1; 00082 } 00083 if ((0 <= i) && (i <= 7)) { 00084 /* 00085 * Data bit. 00086 */ 00087 if ((c & (1 << i)) == 0) { 00088 dat.write(0); 00089 } else { 00090 dat.write(1); 00091 parcnt++; 00092 } 00093 } 00094 if (i == 8) { 00095 /* 00096 * Parity bit. 00097 */ 00098 if ((parcnt % 2) == 0) { 00099 dat.write(1); 00100 } else { 00101 dat.write(0); 00102 } 00103 } 00104 if (i == 9) { 00105 /* 00106 * Stop bit. 00107 */ 00108 dat.write(1); 00109 } 00110 } 00111 dat.input(); 00112 00113 /* 00114 * Check a ACK. 00115 */ 00116 if (!waitClockDownEdge()) { 00117 return -2; 00118 } 00119 if (dat.read() != 0) { 00120 return -3; 00121 } 00122 00123 if (!waitClockUpLevel()) { 00124 return -4; 00125 } 00126 00127 return 0; 00128 } 00129 00130 /** 00131 * Receive a byte data. 00132 * 00133 * @return return a data. Negative value is a error number. 00134 */ 00135 int PS2KB_INIT::recv(void) { 00136 uint8_t c = 0; 00137 clk.input(); 00138 dat.input(); 00139 int parcnt = 0; 00140 for (int i = 0; i < 11; i++) { 00141 if (!waitClockDownEdge()) { 00142 return -1; 00143 } 00144 if (i == 0) { 00145 /* 00146 * Start bit. 00147 */ 00148 if (dat.read() != 0) { 00149 return -2; 00150 } 00151 } 00152 if ((1 <= i) && (i <= 8)) { 00153 /* 00154 * Data bit. 00155 */ 00156 if (dat.read() == 0) { 00157 c &= ~(1 << (i - 1)); 00158 } else { 00159 c |= (1 << (i - 1)); 00160 parcnt++; 00161 } 00162 } 00163 if (i == 9) { 00164 /* 00165 * Parity bit. 00166 */ 00167 if (dat.read() == 0) { 00168 if ((parcnt % 2) != 1) { 00169 return -3; 00170 } 00171 } else { 00172 if ((parcnt % 2) != 0) { 00173 return -4; 00174 } 00175 } 00176 } 00177 if (i == 10) { 00178 /* 00179 * Stop bit. 00180 */ 00181 if (dat.read() != 1) { 00182 return -5; 00183 } 00184 } 00185 } 00186 return (int)c; 00187 } 00188 00189 /** 00190 * Wait a clock down edge. 00191 * 00192 * @return true if wait done. 00193 */ 00194 bool PS2KB_INIT::waitClockDownEdge(void) { 00195 int cnt; 00196 /* 00197 * Wait until clock is low. 00198 */ 00199 cnt = 0; 00200 while (clk.read() == 0) { 00201 cnt++; 00202 if (MAX_RETRY < cnt) { 00203 return false; 00204 } 00205 wait_us(1); 00206 } 00207 /* 00208 * Wait until clock is high. 00209 */ 00210 cnt = 0; 00211 while (clk.read() == 1) { 00212 cnt++; 00213 if (MAX_RETRY < cnt) { 00214 return false; 00215 } 00216 wait_us(1); 00217 } 00218 return true; 00219 } 00220 00221 /** 00222 * Wait a clock up level. 00223 * 00224 * @return true if wait done. 00225 */ 00226 bool PS2KB_INIT::waitClockUpLevel(void) { 00227 int cnt; 00228 /* 00229 * Wait until clock is low. 00230 */ 00231 cnt = 0; 00232 while (clk.read() == 0) { 00233 cnt++; 00234 if (MAX_RETRY < cnt) { 00235 return false; 00236 } 00237 wait_us(1); 00238 } 00239 return true; 00240 }
Generated on Wed Jul 13 2022 15:37:35 by
1.7.2