/* atkeyb.h AT-Keyboard library Taken from ATMEL Appication Note AVR313 Modified for use with avrgcc 2/2005 Stefan Seegel dahamm@gmx.net 8/2007 Kay (Imperator) */ //----------------------------------------------------------------------------- char str[5]; #define BUFF_SIZE 64 //max. size of keyboard buffer #define KEYB_OUT P2OUT // Port-Pegel #define KEYB_DIR P2DIR // Port-Direction #define KEYB_DATA (1<<5) #define KEYB_IN (P2IN&KEYB_DATA) #define KEYB_CLK (1<<4) #define KEYB_IFG P2IFG // Interrupt-Flag #define KEYB_IES P2IES // Interrupt-Edge #define KEYB_IE P2IE // Interrupt-Enable // Unshifted characters const UBYTE unshifted[][2] = { {0x0d, 9 }, {0x0e,'^'}, {0x15,'q'}, {0x16,'1'}, {0x1a,'y'}, {0x1b,'s'}, {0x1c,'a'}, {0x1d,'w'}, {0x1e,'2'}, {0x21,'c'}, {0x22,'x'}, {0x23,'d'}, {0x24,'e'}, {0x25,'4'}, {0x26,'3'}, {0x29,' '}, {0x2a,'v'}, {0x2b,'f'}, {0x2c,'t'}, {0x2d,'r'}, {0x2e,'5'}, {0x31,'n'}, {0x32,'b'}, {0x33,'h'}, {0x34,'g'}, {0x35,'z'}, {0x36,'6'}, {0x39,','}, {0x3a,'m'}, {0x3b,'j'}, {0x3c,'u'}, {0x3d,'7'}, {0x3e,'8'}, {0x41,','}, {0x42,'k'}, {0x43,'i'}, {0x44,'o'}, {0x45,'0'}, {0x46,'9'}, {0x49,'.'}, {0x4a,'-'}, {0x4b,'l'}, {0x4c,'ö'}, {0x4d,'p'}, {0x4e,'ß'}, {0x52,'ä'}, {0x54,'ü'}, {0x55,'´'}, {0x5a, 13}, {0x5b,'+'}, {0x5d,'#'}, {0x61,'<'}, {0x66, 8}, {0x69,'1'}, {0x6b,'4'}, {0x6c,'7'}, {0x70,'0'}, {0x71,','}, {0x72,'2'}, {0x73,'5'}, {0x74,'6'}, {0x75,'8'}, {0x79,'+'}, {0x7a,'3'}, {0x7b,'%'}, {0x7c,'*'}, {0x7d,'9'}, {0,0}}; // Shifted characters const UBYTE shifted[][2] = { 0x0d,9, 0x0e,'°', 0x15,'Q', 0x16,'!', 0x1a,'Y', 0x1b,'S', 0x1c,'A', 0x1d,'W', 0x1e,'"', 0x21,'C', 0x22,'X', 0x23,'D', 0x24,'E', 0x25,'$', 0x26,'§', 0x29,' ', 0x2a,'V', 0x2b,'F', 0x2c,'T', 0x2d,'R', 0x2e,'%', 0x31,'N', 0x32,'B', 0x33,'H', 0x34,'G', 0x35,'Z', 0x36,'&', 0x39,'L', 0x3a,'M', 0x3b,'J', 0x3c,'U', 0x3d,'/', 0x3e,'(', 0x41,';', 0x42,'K', 0x43,'I', 0x44,'O', 0x45,'=', 0x46,')', 0x49,':', 0x4a,'_', 0x4b,'L', 0x4c,'Ö', 0x4d,'P', 0x4e,'?', 0x52,'Ä', 0x54,'Ü', 0x55,'`', 0x5a,13, 0x5b,'*', 0x5d,'\'', 0x61,'>', 0x66, 8 , 0x69,'1', 0x6b,'4', 0x6c,'7', 0x70,'0', 0x71,',', 0x72,'2', 0x73,'5', 0x74,'6', 0x75,'8', 0x79,'+', 0x7a,'3', 0x7b,'%', 0x7c,'*', 0x7d,'9', 0,0}; UBYTE edge = 0, bitcount = 11;// 0 = neg. 1 = pos. UBYTE kb_buffer[BUFF_SIZE]; UBYTE *inpt, *outpt; volatile UBYTE atkeyb_buffcnt; void put_kbbuff(UBYTE c); void decode(UBYTE sc); void atkeyb_init(void) { inpt = kb_buffer;// Initialize buffer outpt = kb_buffer; atkeyb_buffcnt = 0; KEYB_OUT &= ~(KEYB_CLK|KEYB_DATA);//Data und Clock sind Inputs KEYB_DIR |= KEYB_CLK|KEYB_DATA; // PC-Reset KEYB_DIR &= ~KEYB_DATA; // PC-busy KEYB_DIR &= ~KEYB_CLK; // Input KEYB_IFG = 0x00; // Interrupts loeschen KEYB_IES |= KEYB_CLK; // falling Edge KEYB_DIR &= ~KEYB_CLK; // PC-ready KEYB_IE |= KEYB_CLK; // Interrupt Enable } UBYTE altgr_shift(UBYTE in){ switch(in){ case '2': case '"': return '²'; case '§': case '3': return '³'; case '/': case '7': return '{'; case '(': case '8': return '['; case ')': case '9': return ']'; case '=': case '0': return '}'; case '?': case 'ß': return '\\'; case '*': case '+': return '~'; case 'M': case 'm': return 'µ'; case '<': case '>': return '|'; case 'Q': case 'q': return '@'; case 'E': case 'e': return '€'; default : return in; } } // Interrupt routine #pragma vector = PORT2_VECTOR // Port 2 __interrupt void Interrupt_Port2() { KEYB_IFG &= ~KEYB_CLK; // reset Interrupt-Flag static UBYTE data;// Holds the received scan code if (!edge){ // Routine entered at falling edge if (bitcount < 11 && bitcount > 2)// Bit 3 to 10 is data. Parity bit, { // start and stop bits are ignored. data = (data >> 1); if (KEYB_IN) data = data | 0x80;// Store a '1' } KEYB_IES &= ~KEYB_CLK; // falling Edge edge = 1; } else{ // Routine entered at rising edge KEYB_IES |= KEYB_CLK; // falling Edge edge = 0; if (--bitcount == 0){// All bits received decode(data); bitcount = 11; } } return; } void decode(UBYTE sc) { static UBYTE is_up=0, shift = 0, mode = 0, altgr = 0, special = 0, last_sc; UBYTE i; UBYTE a;//, b; //send(cth(sc));send(" "); if (!is_up){// Last data received was the up-key identifier switch (sc){ case 0xF0 :// The up-key identifier is_up = 1; if(last_sc == 0xE0) special=0; break; case 0x12 :// Left SHIFT shift = 1; break; case 0x59 :// Right SHIFT shift = 1; break; case 0xE0 :// special special = 1;break; case 0x11 :// ALT + Gr if (special) altgr = 1; break; case 0x05 :// F1 if(mode == 0) mode = 1;// Enter scan code mode if(mode == 2) mode = 3;// Leave scan code mode break; default: if(mode == 0 || mode == 3){// If ASCII mode if(!shift)// If shift not pressed, { // do a table look-up i=0; a=unshifted[i][0]; while ((a) && (a!=sc)){ i++; a=unshifted[i][0]; } if (a == sc){ if(altgr){ put_kbbuff(altgr_shift(unshifted[i][1]));} else{ put_kbbuff(unshifted[i][1]);} } } else {// If shift pressed i=0; a=shifted[i][0]; while ((a) && (a!=sc)){ i++; a=shifted[i][0]; } if (a == sc){ if(altgr){ put_kbbuff(altgr_shift(shifted[i][1]));} else{ put_kbbuff(shifted[i][1]);} } } // shift if(altgr){a=altgr_shift(a);} } else{ // Scan code mode //send(cth(sc));send(" "); } } } else{ is_up = 0;// Two 0xF0 in a row not allowed switch (sc) { case 0x12 :// Left SHIFT shift = 0; break; case 0x59 :// Right SHIFT shift = 0; break; case 0xE0 :// special {special = 1;break;} case 0x11 :// ALT + Gr /*if (special)*/ altgr = 0; break; case 0x05 :// F1 if(mode == 1) mode = 2; if(mode == 3) mode = 0; break; case 0x06 :// F2 //clr(); break; } } last_sc=sc; } void put_kbbuff(UBYTE c){ if (atkeyb_buffcnt= kb_buffer + BUFF_SIZE)// Pointer wrapping inpt = kb_buffer; } } BYTE atkeyb_getchar(void) /* returns BYTE from keyboard buffer this function doesn't return until at least 1 BYTE is in buffer Maybe you might check atkeyb_buffcnt to check if data is in buffer! */ { UBYTE byte; while(atkeyb_buffcnt == 0);// Wait for data byte = *outpt;// Get byte outpt++; // Increment pointer if (outpt >= kb_buffer + BUFF_SIZE)// Pointer wrapping outpt = kb_buffer; atkeyb_buffcnt--; // Decrement buffer count return byte; }