diff options
| author | Priyadi Iman Nurcahyo <priyadi@priyadi.net> | 2016-11-26 14:23:55 +0700 |
|---|---|---|
| committer | Priyadi Iman Nurcahyo <priyadi@priyadi.net> | 2016-11-26 14:23:55 +0700 |
| commit | f837406ace5a3072e98f0bd0e3f4c84704762195 (patch) | |
| tree | 61d4390b50c9aea3a8dd0f6dc2e0f8a1279a697b /readme.md | |
| parent | bf23ac96f62be1cb36d414e76599523af3caf00f (diff) | |
| download | qmk_firmware-f837406ace5a3072e98f0bd0e3f4c84704762195.tar.gz qmk_firmware-f837406ace5a3072e98f0bd0e3f4c84704762195.zip | |
A few addition to PS2 documentation.
Diffstat (limited to 'readme.md')
| -rw-r--r-- | readme.md | 160 |
1 files changed, 125 insertions, 35 deletions
| @@ -1160,41 +1160,131 @@ Please note the USB port can only supply a limited amount of power to the keyboa | |||
| 1160 | ## PS/2 Mouse Support | 1160 | ## PS/2 Mouse Support |
| 1161 | 1161 | ||
| 1162 | Its possible to hook up a PS/2 mouse (for example touchpads or trackpoints) to your keyboard as a composite device. | 1162 | Its possible to hook up a PS/2 mouse (for example touchpads or trackpoints) to your keyboard as a composite device. |
| 1163 | In order to do this you must first enable the option in your Makefile. | 1163 | |
| 1164 | 1164 | Then, decide whether to use USART (best), interrupts (better) or busywait (not recommended), and enable the relevant option. | |
| 1165 | PS2_MOUSE_ENABLE = yes | 1165 | |
| 1166 | 1166 | ### Busywait version | |
| 1167 | Then, decide whether to use interrupts (better if your microcontroller supports them) or busywait, and enable the relevant option. | 1167 | |
| 1168 | 1168 | Note: This is not recommended, you may encounter jerky movement or unsent inputs. Please use interrupt or USART version if possible. | |
| 1169 | PS2_USE_INT = yes | 1169 | |
| 1170 | // PS2_USE_BUSYWAIT = yes | 1170 | In rules.mk: |
| 1171 | 1171 | ||
| 1172 | If you're using a teensy and have hooked up the clock on your PS/2 device to D1 and the data to D0, you're all set. | 1172 | ``` |
| 1173 | Otherwise, you will need to update the following defines in your `config.h`: | 1173 | PS2_MOUSE_ENABLE = yes |
| 1174 | 1174 | PS2_USE_BUSYWAIT = yes | |
| 1175 | #define PS2_CLOCK_PORT PORTD | 1175 | ``` |
| 1176 | #define PS2_CLOCK_PIN PIND | 1176 | |
| 1177 | #define PS2_CLOCK_DDR DDRD | 1177 | In your keyboard config.h: |
| 1178 | #define PS2_CLOCK_BIT 1 | 1178 | |
| 1179 | 1179 | ``` | |
| 1180 | #define PS2_DATA_PORT PORTD | 1180 | #ifdef PS2_USE_BUSYWAIT |
| 1181 | #define PS2_DATA_PIN PIND | 1181 | # define PS2_CLOCK_PORT PORTD |
| 1182 | #define PS2_DATA_DDR DDRD | 1182 | # define PS2_CLOCK_PIN PIND |
| 1183 | #define PS2_DATA_BIT 0 | 1183 | # define PS2_CLOCK_DDR DDRD |
| 1184 | 1184 | # define PS2_CLOCK_BIT 1 | |
| 1185 | And with `PS2_USE_INT` also define these macros: | 1185 | # define PS2_DATA_PORT PORTD |
| 1186 | 1186 | # define PS2_DATA_PIN PIND | |
| 1187 | #define PS2_INT_INIT() do { \ | 1187 | # define PS2_DATA_DDR DDRD |
| 1188 | EICRA |= ((1<<ISC11) | \ | 1188 | # define PS2_DATA_BIT 2 |
| 1189 | (0<<ISC10)); \ | 1189 | #endif |
| 1190 | } while (0) | 1190 | ``` |
| 1191 | #define PS2_INT_ON() do { \ | 1191 | |
| 1192 | EIMSK |= (1<<INT1); \ | 1192 | ### Interrupt version |
| 1193 | } while (0) | 1193 | |
| 1194 | #define PS2_INT_OFF() do { \ | 1194 | The following example uses D2 for clock and D5 for data. You can use any INT or PCINT pin for clock, and any pin for data. |
| 1195 | EIMSK &= ~(1<<INT1); \ | 1195 | |
| 1196 | } while (0) | 1196 | In rules.mk: |
| 1197 | #define PS2_INT_VECT INT1_vect | 1197 | |
| 1198 | ``` | ||
| 1199 | PS2_MOUSE_ENABLE = yes | ||
| 1200 | PS2_USE_INT = yes | ||
| 1201 | ``` | ||
| 1202 | |||
| 1203 | In your keyboard config.h: | ||
| 1204 | |||
| 1205 | ``` | ||
| 1206 | #ifdef PS2_USE_INT | ||
| 1207 | #define PS2_CLOCK_PORT PORTD | ||
| 1208 | #define PS2_CLOCK_PIN PIND | ||
| 1209 | #define PS2_CLOCK_DDR DDRD | ||
| 1210 | #define PS2_CLOCK_BIT 2 | ||
| 1211 | #define PS2_DATA_PORT PORTD | ||
| 1212 | #define PS2_DATA_PIN PIND | ||
| 1213 | #define PS2_DATA_DDR DDRD | ||
| 1214 | #define PS2_DATA_BIT 5 | ||
| 1215 | |||
| 1216 | #define PS2_INT_INIT() do { \ | ||
| 1217 | EICRA |= ((1<<ISC21) | \ | ||
| 1218 | (0<<ISC20)); \ | ||
| 1219 | } while (0) | ||
| 1220 | #define PS2_INT_ON() do { \ | ||
| 1221 | EIMSK |= (1<<INT2); \ | ||
| 1222 | } while (0) | ||
| 1223 | #define PS2_INT_OFF() do { \ | ||
| 1224 | EIMSK &= ~(1<<INT2); \ | ||
| 1225 | } while (0) | ||
| 1226 | #define PS2_INT_VECT INT2_vect | ||
| 1227 | #endif | ||
| 1228 | ``` | ||
| 1229 | |||
| 1230 | ### USART version | ||
| 1231 | |||
| 1232 | To use USART on the ATMega32u4, you have to use PD5 for clock and PD2 for data. If one of those are unavailable, you need to use interrupt version. | ||
| 1233 | |||
| 1234 | In rules.mk: | ||
| 1235 | |||
| 1236 | ``` | ||
| 1237 | PS2_MOUSE_ENABLE = yes | ||
| 1238 | PS2_USE_USART = yes | ||
| 1239 | ``` | ||
| 1240 | |||
| 1241 | In your keyboard config.h: | ||
| 1242 | |||
| 1243 | ``` | ||
| 1244 | #ifdef PS2_USE_USART | ||
| 1245 | #define PS2_CLOCK_PORT PORTD | ||
| 1246 | #define PS2_CLOCK_PIN PIND | ||
| 1247 | #define PS2_CLOCK_DDR DDRD | ||
| 1248 | #define PS2_CLOCK_BIT 5 | ||
| 1249 | #define PS2_DATA_PORT PORTD | ||
| 1250 | #define PS2_DATA_PIN PIND | ||
| 1251 | #define PS2_DATA_DDR DDRD | ||
| 1252 | #define PS2_DATA_BIT 2 | ||
| 1253 | |||
| 1254 | /* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */ | ||
| 1255 | /* set DDR of CLOCK as input to be slave */ | ||
| 1256 | #define PS2_USART_INIT() do { \ | ||
| 1257 | PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT); \ | ||
| 1258 | PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); \ | ||
| 1259 | UCSR1C = ((1 << UMSEL10) | \ | ||
| 1260 | (3 << UPM10) | \ | ||
| 1261 | (0 << USBS1) | \ | ||
| 1262 | (3 << UCSZ10) | \ | ||
| 1263 | (0 << UCPOL1)); \ | ||
| 1264 | UCSR1A = 0; \ | ||
| 1265 | UBRR1H = 0; \ | ||
| 1266 | UBRR1L = 0; \ | ||
| 1267 | } while (0) | ||
| 1268 | #define PS2_USART_RX_INT_ON() do { \ | ||
| 1269 | UCSR1B = ((1 << RXCIE1) | \ | ||
| 1270 | (1 << RXEN1)); \ | ||
| 1271 | } while (0) | ||
| 1272 | #define PS2_USART_RX_POLL_ON() do { \ | ||
| 1273 | UCSR1B = (1 << RXEN1); \ | ||
| 1274 | } while (0) | ||
| 1275 | #define PS2_USART_OFF() do { \ | ||
| 1276 | UCSR1C = 0; \ | ||
| 1277 | UCSR1B &= ~((1 << RXEN1) | \ | ||
| 1278 | (1 << TXEN1)); \ | ||
| 1279 | } while (0) | ||
| 1280 | #define PS2_USART_RX_READY (UCSR1A & (1<<RXC1)) | ||
| 1281 | #define PS2_USART_RX_DATA UDR1 | ||
| 1282 | #define PS2_USART_ERROR (UCSR1A & ((1<<FE1) | (1<<DOR1) | (1<<UPE1))) | ||
| 1283 | #define PS2_USART_RX_VECT USART1_RX_vect | ||
| 1284 | #endif | ||
| 1285 | #endif | ||
| 1286 | #endif | ||
| 1287 | ``` | ||
| 1198 | 1288 | ||
| 1199 | ## Safety Considerations | 1289 | ## Safety Considerations |
| 1200 | 1290 | ||
