a500kbd

diff src/main.c @ 2:a4fd9c5a6655

first working version
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 17 Oct 2017 15:25:33 +0300
parents 3228a731d4db
children 31a1f0b53d98
line diff
     1.1 --- a/src/main.c	Sat Oct 14 07:23:47 2017 +0300
     1.2 +++ b/src/main.c	Tue Oct 17 15:25:33 2017 +0300
     1.3 @@ -1,64 +1,50 @@
     1.4 -#define F_CPU	XTAL
     1.5  #include <stdio.h>
     1.6  #include <ctype.h>
     1.7  #include <avr/io.h>
     1.8  #include <avr/interrupt.h>
     1.9  #include <util/delay.h>
    1.10 -#include <util/parity.h>
    1.11  #include "serial.h"
    1.12  #include "scantbl.h"
    1.13 -
    1.14 -/* pin assignments:
    1.15 - * B0	PS/2 data
    1.16 - * D2	PS/2 clock (INT0)
    1.17 - * B1	KBD data
    1.18 - * D3	KBD clock (INT1)
    1.19 - */
    1.20 -
    1.21 -#define BIT_DATA	1
    1.22 -#define BIT_CLK		2
    1.23 -
    1.24 -#define PS2LOW(bit) do { DDRB |= (bit); PORTB &= ~(bit); } while(0)
    1.25 -#define PS2HIGH(bit) do { DDRB |= (bit); PORTB |= (bit); } while(0)
    1.26 -#define PS2REL(bit) do { DDRB &= ~(bit); PORTB &= ~(bit); } while(0)
    1.27 -
    1.28 -void ps2write(unsigned char c);
    1.29 -unsigned char ps2read(void);
    1.30 -int ps2pending(void);
    1.31 -
    1.32 -#define BUF_SZ	16
    1.33 -#define BUF_IDX_MASK	(BUF_SZ - 1)
    1.34 -#define NEXT_IDX(x) (((x) + 1) & BUF_IDX_MASK)
    1.35 -static volatile unsigned char keybuf[BUF_SZ];
    1.36 -static volatile unsigned char key_rd, key_wr;
    1.37 -
    1.38 -static volatile int sending;
    1.39 +#include "ps2kbd.h"
    1.40 +#include "amigakb.h"
    1.41 +#include "defs.h"
    1.42 +#include "timer.h"
    1.43  
    1.44  enum {
    1.45  	KF_BRK = 1,
    1.46  	KF_EXT = 2,
    1.47  	KF_EXT1 = 4,
    1.48 +
    1.49 +	KF_CTRL		= 16,
    1.50 +	KF_LAMIGA	= 32,
    1.51 +	KF_RAMIGA	= 64
    1.52  };
    1.53 +#define KF_TRANSIENT	0x0f
    1.54 +#define KF_STICKY		0xf0
    1.55  
    1.56  int main(void)
    1.57  {
    1.58  	unsigned int keyflags = 0;
    1.59 -	int keycode;
    1.60 +	unsigned char keycode;
    1.61 +	int press;
    1.62  
    1.63 -	DDRB = 0;
    1.64 +	/* disable all pullups globally */
    1.65 +	MCUCR |= 1 << PUD;
    1.66 +
    1.67  	DDRD = 0;
    1.68 -	PORTB = 0;
    1.69  	PORTD = 0;
    1.70  	EIMSK = 0;	/* mask external interrupts */
    1.71  	EICRA = (1 << ISC11) | (1 << ISC01);	/* falling edge interrupts */
    1.72  
    1.73 +	init_timer();
    1.74 +
    1.75  	/* initialize the UART and enable interrupts */
    1.76  	init_serial(9600);
    1.77  	sei();
    1.78  
    1.79  	printf("PS/2 keyboard controller - John Tsiombikas <nuclear@member.fsf.org>\r\n");
    1.80  
    1.81 -	EIMSK = (1 << INT0);	/* enable ps/2 clock interrupt */
    1.82 +	EIMSK = (1 << INT0) | (1 << INT1);	/* enable ps/2 clock interrupt */
    1.83  
    1.84  	for(;;) {
    1.85  		unsigned char c = ps2read();
    1.86 @@ -76,7 +62,9 @@
    1.87  			break;
    1.88  
    1.89  		default:
    1.90 -			keycode = 0;
    1.91 +			press = !(keyflags & KF_BRK);
    1.92 +
    1.93 +			keycode = 0xff;
    1.94  			if(keyflags & KF_EXT) {
    1.95  				printf("ext ");
    1.96  				if(c < KEYMAP_EXT_SIZE) {
    1.97 @@ -90,94 +78,48 @@
    1.98  				}
    1.99  			}
   1.100  
   1.101 -			if(keycode >= 256) {
   1.102 -				/*printf("%s: %s (scancode: %x)\r\n", keyflags & KF_BRK ? "release" : "press", skeystr[keycode - 256], (unsigned int)c);*/
   1.103 -				printf("%s: key %xh (scancode: %x)\r\n", keyflags & KF_BRK ? "release" : "press", keycode, (unsigned int)c);
   1.104 -			} else if(isprint(keycode)) {
   1.105 -				printf("%s: %c (scancode: %x)\r\n", keyflags & KF_BRK ? "release" : "press", (char)keycode, (unsigned int)c);
   1.106 -			} else if(keycode > 0) {
   1.107 -				printf("%s: key %xh (scancode: %x)\r\n", keyflags & KF_BRK ? "release" : "press", keycode, (unsigned int)c);
   1.108 +			switch(keycode) {
   1.109 +			case AMIKEY_CTRL:
   1.110 +				if(press)
   1.111 +					keyflags |= KF_CTRL;
   1.112 +				else
   1.113 +					keyflags &= ~KF_CTRL;
   1.114 +				break;
   1.115 +
   1.116 +			case AMIKEY_LAMI:
   1.117 +				if(press)
   1.118 +					keyflags |= KF_LAMIGA;
   1.119 +				else
   1.120 +					keyflags &= ~KF_LAMIGA;
   1.121 +				break;
   1.122 +
   1.123 +			case AMIKEY_RAMI:
   1.124 +				if(press)
   1.125 +					keyflags |= KF_RAMIGA;
   1.126 +				else
   1.127 +					keyflags &= ~KF_RAMIGA;
   1.128 +				break;
   1.129 +
   1.130 +			default:
   1.131 +				break;
   1.132 +			}
   1.133 +
   1.134 +			if((keyflags & (KF_CTRL | KF_RAMIGA | KF_LAMIGA)) == (KF_CTRL | KF_RAMIGA | KF_LAMIGA)) {
   1.135 +				printf("CTRL - AMIGA - AMIGA!\r\n");
   1.136 +				amikb_reset();
   1.137 +			}
   1.138 +
   1.139 +			printf("scancode %x -> ", (unsigned int)c);
   1.140 +			if(keycode != 0xff) {
   1.141 +				amikb_sendkey(keycode, ~keyflags & KF_BRK);
   1.142 +				printf("[%s] amiga key %xh\r\n", press ? "press" : "release", keycode);
   1.143  			} else {
   1.144 -				printf("%s: %x\r\n", keyflags & KF_BRK ? "release" : "press", (unsigned int)c);
   1.145 +				printf("[%s] no translation\r\n", press ? "press" : "release");
   1.146  			}
   1.147 -			keyflags = 0;
   1.148 +			keyflags &= ~KF_TRANSIENT;
   1.149  		}
   1.150  	}
   1.151  	return 0;
   1.152  }
   1.153  
   1.154 -void ps2write(unsigned char c)
   1.155 -{
   1.156 -	int i;
   1.157 -	unsigned short out = (unsigned short)c | ((unsigned short)(parity_even_bit(c) & 1) << 8);
   1.158  
   1.159 -	/* pull clock low for >60us */
   1.160 -	PS2LOW(BIT_CLK);
   1.161 -	_delay_us(60);
   1.162 -
   1.163 -	/* then pull data low and release clock */
   1.164 -	PS2LOW(BIT_DATA);
   1.165 -	PS2REL(BIT_CLK);
   1.166 -
   1.167 -	for(i=0; i<9; i++) {
   1.168 -		while(PINB & BIT_CLK);	/* wait for kbd to drive the clock low */
   1.169 -		PORTB |= out & 1;
   1.170 -		out >>= 1;
   1.171 -		while(!(PINB & BIT_CLK));	/* wait for kbd to drive the clock high */
   1.172 -	}
   1.173 -
   1.174 -	PS2REL(BIT_DATA);
   1.175 -	/* wait for ack */
   1.176 -	while(PINB & BIT_DATA);
   1.177 -	while(!(PINB & BIT_DATA));
   1.178 -}
   1.179 -
   1.180 -unsigned char ps2read(void)
   1.181 -{
   1.182 -	unsigned char key;
   1.183 -
   1.184 -	while(key_rd == key_wr) {
   1.185 -	}
   1.186 -
   1.187 -	cli();
   1.188 -	key = keybuf[key_rd];
   1.189 -	key_rd = NEXT_IDX(key_rd);
   1.190 -	sei();
   1.191 -
   1.192 -	return key;
   1.193 -}
   1.194 -
   1.195 -int ps2pending(void)
   1.196 -{
   1.197 -	return key_rd != key_wr;
   1.198 -}
   1.199 -
   1.200 -ISR(INT0_vect)
   1.201 -{
   1.202 -	static unsigned char value, valp, parity;
   1.203 -	static int nbits;
   1.204 -
   1.205 -	if(sending) {
   1.206 -	} else {
   1.207 -		if(nbits > 0 && nbits < 9) {
   1.208 -			value >>= 1;
   1.209 -			if(PINB & 1) {
   1.210 -				value |= 0x80;
   1.211 -				parity ^= 1;
   1.212 -			}
   1.213 -		}/* else if(nbits == 9) {
   1.214 -			valp = PINB & 1;
   1.215 -		}*/
   1.216 -		if(++nbits >= 11) {
   1.217 -			nbits = 0;
   1.218 -
   1.219 -			/* check parity */
   1.220 -			/*if((parity & 1) == (valp & 1)) {}*/
   1.221 -			keybuf[key_wr] = (unsigned char)value;
   1.222 -			key_wr = NEXT_IDX(key_wr);
   1.223 -
   1.224 -			value = 0;
   1.225 -			parity = 0;
   1.226 -		}
   1.227 -	}
   1.228 -}