Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Keyboard interface code in C

Status
Not open for further replies.

seanthearakh

Member level 1
Joined
Mar 10, 2007
Messages
36
Helped
0
Reputation
0
Reaction score
1
Trophy points
1,286
Activity points
1,481
thanks for your asm, but what i need is in C ,Please help me!:cry:
 

Re: Interface keyboard!

How about this stuff:
Code:
#pragma language=extended 
#include <df0034.h> 
#include "keyboard.h" 
#include "infhotel.h" 
#include "rtc.h" 
#include "lang.h" 
#include "rs232.h" 

uchar keyModifier;  // E0, E1, 
saddr uchar uniKey;       // keystroke converted to pseudo-unicode format (signed 128bit) 
saddr uchar lastUniKey;   // Store previous key in pseudo-unicode format 
bit keyReleased;    // 1 if F0 keystroke received 

saddr uchar kbdbytes;     // number of bytes received from keyboard 
saddr uchar kbdbuffer[KBDBUFFERLEN]; // keyboard buffer 
uchar kbdbits;    // number of received bits (start bit inclusive) 
uchar kbdbyte;    // receiving byte 
uchar kbdto;      // timeout for a keystroke receiving 
bit kbdtx;        // 1 when transmitting to keyboard, 0 when receiving 
bit kbdbit;       // received bit 
bit kbdoddparity; // 1 if odd number of bits before parity 
bit kbderr;       // 1 if any errors 

struct kbd_struct kbd_table; 


                                                                                //  ì   è +  ò   à   ù 
const uchar uni2ascii[UNI2ASCIILEN]=     " abcdefghijklmnopqrstuvwxyz0123456789\\'\x8d\x8a+\x95\x85\x97>,.-.0123456789+-*/ "; 
                                                                                //   é *  ç   °   § 
const uchar shiftuni2ascii[UNI2ASCIILEN]=" ABCDEFGHIJKLMNOPQRSTUVWXYZ=!\"£$%&/()|?^\x82*\x87\xf8\xf5<;:_.0123456789+-*/ "; 
            //                            0   4   8   C   0   4   8   C   0   4    8   C   0   4   8   C   0 

// Map keystrokes to a map similar to unicode. 
uchar const key2uni[132] = { 
  0x00,      K_F9,      0x00,      K_F5,      K_F3,      K_F1,      K_F2,      K_F12, 
  0x00,      K_F10,     K_F8,      K_F6,      K_F4,      K_TAB,     0x25,      0x00, 
//10 
  0x00,      0x00,      0x00,      0x00,      0x00,      0x11,      0x1c,      0x00, 
  0x00,      0x00,      0x1a,      0x13,      0x01,      0x17,      0x1d,      0x00, 
//20 
  0x00,      0x03,      0x18,      0x04,      0x05,      0x1f,      0x1e,      0x00, 
  0x00,      0x40,      0x16,      0x06,      0x14,      0x12,      0x20,      0x00, 
//30 
  0x00,      0x0e,      0x02,      0x08,      0x07,      0x19,      0x21,      0x00, 
  0x00,      0x00,      0x0d,      0x0a,      0x15,      0x22,      0x23,      0x00, 
//40 
  0x00,      0x2e,      0x0b,      0x09,      0x0f,      0x1b,      0x24,      0x00, 
  0x00,      0x2f,      0x30,      0x0c,      0x2a,      0x10,      0x26,      0x00, 
//50 
  0x00,      0x00,      0x2b,      0x00,      0x28,      0x27,      0x00,      0x00, 
  0x00,      0x00,      K_ENTER,   0x29,      0x00,      0x2c,      0x00,      0x00, 
//60 
  0x00,      0x2d,      0x00,      0x00,      0x00,      0x00,      K_BACKSP,  0x00, 
  0x33,      0x1c,      0x00,      0x36,      0x39,      0x00,      0x00,      0x00, 
//70 
  0x32,      0x31,      0x34,      0x37,      0x38,      0x3a,      K_ESC,     0x00, 
  K_F11,     0x3c,      0x35,      0x3d,      0x3e,      0x3b,      0x00,      0x00, 
//80 
  0x00,      0x00,      0x00,      K_F7 
}; 

void getKeyStroke(uchar *ch) { 
  // return the first keystroke in the kbdbuffer[] 
  uchar i; 
  if (kbdbytes) { 
    *ch=*kbdbuffer; 
    kbdbytes--; 
    for (i=0;i<kbdbytes;i++) 
      kbdbuffer[i]=kbdbuffer[i+1]; 
    if (kbdbytes==KBDBUFFERLEN-1) { 
      kbdclk=1;  // release kbdclk to reenable keyboard rx 
      kbdclkm=1; 
    } 
    #ifdef DEBUGKBD 
    rs232putbyte2hex((uchar) *ch,'\n'); 
    #endif 
    return; 
  } else { 
    *ch=0; 
    return; 
  } 
} 

// when new char was received, reinitialize variable (used by kbdGetChar) 
#define kbdNewChar() { keyModifier=0; keyReleased=0; } 

/* Return in uniKey the character read from kbdbuffer, 0 if there are no chars available */ 
void kbdGetChar (void) { 
  uchar ch; 
  // at this point i will read: 
  // a. new complete or partial keystroke 
  // b. completion of previous received partial keystroke 
  // c. another part of previous received partial keystroke 

  if (uniKey) 
    lastUniKey=uniKey; 
  uniKey=0;     // initialize uniKey to ZERO (useful if a "don't care key" was pressed/released) 
  while (1) { 
    getKeyStroke(&ch);  // will store in ch the next part of keystroke 
    if (ch==0)  { 
      // No keystrokes available 
      return; 
    } 
    if (ch==0xF0) { 
      keyReleased=1; 
    } else if (ch==0xE0) { 
      keyModifier=1; 
    } else if (ch==0xE1) { 
      keyModifier=2; 
    } else if (ch==0xAA) { 
      // must reinitialize keyboard 
      kbd_initialize();   // PowerOn: initialize keyboard and empty kbdbuffer[] 
      kbdbytes=0; 
      uniKey=0; 
      kbdNewChar();       // Initialize the variables used by this function (keyRelease, keyModifier, ...) 
      return; 
    } else if (ch<0x84) { 
      if (keyModifier==0) { 
        switch (ch) { 
          case 0x12:  // LEFT SHIFT 
          case 0x59:  // RIGHT SHIFT 
            kbd_table.shift=!keyReleased; break; 
          case 0x14:  //LEFT CONTROL 
            kbd_table.ctrl=!keyReleased; break; 
          case 0x11:  //LEFT ALT 
            kbd_table.alt=!keyReleased; break; 
          case 0x58:  //CAPS LOCK 
            if (keyReleased==1) { 
              kbd_table.capsLock^=1; 
              kbd_initialize(); 
            } break; 
          case 0x77:  // NUM LOCK 
            if (keyReleased==1) { 
              kbd_table.numLock^=1;  //Num lock always active! 
              kbd_initialize(); 
            } break; 
          case 0x7E:  // SCROLL LOCK 
            if (keyReleased==1) { 
              kbd_table.scrollLock^=1; 
              kbd_initialize(); 
            } break; 
          case 0x07:  // F12 
            if (lastUniKey!=K_F12 || keyReleased) { 
              uniKey=K_F12; 
              if (keyReleased) 
                uniKey|=0x80; 
            } 
            break; 
          default: 
            uniKey=key2uni[ch]; 
            if (keyReleased) { 
              uniKey|=0x80; 
            } 
        } 
        kbdNewChar(); 
        return; 
      } else if (keyModifier==1) { 
        switch (ch) { 
          case 0x14:  //RIGHT CONTROL 
            kbd_table.ctrl=1^keyReleased; break; 
          case 0x11:  //RIGHT ALT 
            kbd_table.alt=1^keyReleased; break; 
          case 0x4A:  // KeyPad / 
            uniKey=0x25;break; 
          case 0x5A:  // KeyPad ENTER 
            uniKey=K_ENTER;break; 
          case 0x6B:  //K_LEFT 
            uniKey=K_LEFT; break; 
          case 0x74:  //K_RIGHT 
            uniKey=K_RIGHT; break; 
          case 0x72:  //K_DOWN 
            uniKey=K_DOWN; break; 
          case 0x75:  //K_UP 
            uniKey=K_UP; break; 
          case 0x70:  //K_INSERT 
            uniKey=K_INSERT; break; 
          case 0x71: 
            uniKey=K_DELETE; break; 
          case 0x6c: 
            uniKey=K_HOME; break; 
          case 0x69: 
            uniKey=K_END; break; 
          case 0x7d: 
            uniKey=K_PGUP; break; 
          case 0x7a: 
            uniKey=K_PGDOWN; break; 
          case 0x7c: 
            uniKey=K_SYSRQ;break; 
        } 
        if (keyReleased) { 
          uniKey|=0x80; 
        } 
        kbdNewChar(); 
        return; 
      } else if (keyModifier==2) { 
        if (keyReleased==0) { 
          #ifdef DEBUGKBD 
          rs232putchar('E'); 
          rs232putchar('1'); 
          rs232putchar(' '); 
          rs232putbyte2hex(ch,' '); 
          #endif 
        } 


        return; 
      } 
    } 
  } 
} 


void kbd_sendData(uchar data) { 
  // prepare for the transmission of commands to keyboard, then wait 
  // until ISR finish transmissions, wait for the ack and retransmit the command 
  // if NOACK. 
  uchar i,j,ch; 

  for (i=5;i;i--) { 
    kbdtx=1;            // tell interrupt routine to tx data 
    kbdbyte=data; 
    kbdbits=0; 
    kbdoddparity=0; 
    kbderr=0; 
    kbdto=20;           // keyboard must complete operation within 15ms 
    kbdintmask=1; 
    kbdclk=0;           // pull clock low 
    kbdclkm=0; 
    for (j=0;j<100;j++); // wait for 100uS 
    kbddata=0;          // pull data low, then release clock 
    kbddatam=0; 
    for (j=0;j<10;j++); 
    kbdclk=1; 
    kbdclkm=1; 
    kbdintflag=0; 
    kbdintmask=0; 
    // ok, start bit was transmitted, then interrupt routine will do the rest 

    // wait until data will be TXed 
    for (j=100;j;j--) { 
      unconditionalmsleep(2); 
      if (kbdtx==0) 
        break; 
    } 
    kbdNewChar(); 
    if (j==0) { 
      kbdtx=0; 
      kbddata=1;  // keyboard not connected: set kbd_data as input, then exit 
      kbddatam=1; 
      return; 
    } 
    if (kbderr) { 
      #ifdef DEBUGKBD 
      rs232puts("kbd_sendData: Data TXed, but got NACK\n"); 
      #endif 
      unconditionalmsleep(10); // data transmitted but not acknowledged 
      continue; 
    } 
    for (j=25;j;j--) { 
      // wait for ACK 
      unconditionalmsleep(2); 
      while (getKeyStroke(&ch),ch) { 
        kbdNewChar(); 
        if (ch==0xfa) 
          break; 
      } 
      if (ch==0xfa) { 
        return; 
      } else if (ch) { 
        #ifdef DEBUGKBD 
        rs232puts("kbd_sendData: got answer 0x"); 
        rs232putbyte2hex(ch,'\n'); 
        #endif 
      } 
    } 
  } 
} 



void kbd_initialize(void) { 
  // reset keyboard rate & leds accordingly to kbd_table structure 
  // Must be called after keyboard powerOn (when keyboard send 0xAA data) 
  unconditionalmsleep(20); 
  // Don't alter rate and delay... default is 10.9cps and 500ms 
  //kbd_sendData(KBD_CMD_SET_RATE); 
  //kbd_sendData(0x00); // maximum rate, minimum delay 
  kbd_sendData(KBD_CMD_SET_LEDS); 
  kbd_sendData(kbd_table.scrollLock|(kbd_table.numLock<<1)|(kbd_table.capsLock<<2)); 
  kbdNewChar(); 
  uniKey=0; 
} 

void kbdinit(void) { 
  kbdclk=1;  // kbdclock=output 
  kbdclkm=1; 
  kbdclku=1; 
  kbddata=1; 
  kbddatam=1; 
  kbddatau=1; 
  kbdintegp=0; 
  kbdintegn=1; 
  kbdintflag=0; 
  kbdintmask=0; 
  kbdintprio=1; 
  kbdtx=0; 
  kbdbytes=0; 
  kbdbits=0; 
  kbdbyte=0; 
  kbdbit=0; 
  kbderr=0; 
  kbdoddparity=0; 
  kbdto=0; 
  kbd_table.capsLock=0; 
  kbd_table.scrollLock=0; 
  kbd_table.numLock=1; 
  kbd_table.shift=0; 
  kbd_table.alt=0; 
  kbd_table.ctrl=0; 
  // initialize keyboard only when 0xAA (PowerOn) will be received 
  // kbd_initialize(); 
} 

static interrupt [INTP3_vect] void kbdinterrupt(void) { 
  // called everytime the kbdclk goes low => must latch kbddata 
  if (kbdto==0) { // Control keyboard timeout (2 ms to receive a keystroke 
    kbderr=0; 
    kbdbits=0; 
    kbdoddparity=0; 
    kbdto=3;  // set keyboad time out 
    kbdtx=0; 
    kbddata=1; 
    kbddatam=1; 
  } 
  if (kbdtx) { 
    // transmit to keyboard 
    kbdbits++; 
    if (kbdbits<=8) { 
      if (kbdbyte&1) { 
        kbdoddparity^=1; 
        kbddata=1; 
      } else { 
        kbddata=0; 
      } 
      kbdbyte>>=1; 
    } else if (kbdbits==9) { 
      // transmit parity 
      kbddata=~kbdoddparity; 

    } else if (kbdbits==10) { 
      // transmit stop bit 
      kbddata=1; 
      kbddatam=1; 
    } else if (kbdbits==11) { 
      // get acknowledge 
      kbderr=kbddata; 
      kbdtx=0; 
      kbdto=0; 
    } 
  } else { 
    // receiving from keyboard 
    kbdbit=kbddata; // read data 
    if (kbdbits==0) { 
      if (kbdbit) { 
        // control start bit (must be ZERO!) 
        kbderr=1; 
      } 
    } else if (kbderr==0) { 
      if (kbdbits>=1 && kbdbits<=8) { 
        kbdbyte>>=1; 
        if (kbdbit) { 
          kbdbyte|=0x80; 
          kbdoddparity^=1; 
        } 
      } else if (kbdbits==9) { 
        // parity bit 
        if (kbdbit==kbdoddparity) { 
          kbderr=1; 
        } 
      } else if (kbdbits==10) { 
        // stop bit 
        if (kbdbit==0) { 
          kbderr=1; 
        } 
      } 
    } 
    if ((++kbdbits)==11) { 
      if (kbderr==0) { 
        // no errors => store received byte to kbdbuffer 
        kbdbuffer[kbdbytes]=kbdbyte; 
        if ((++kbdbytes)==KBDBUFFERLEN) { 
          kbdclk=0;  // pulling kbddata low, keyboard communication will be inhibited 

          kbdclkm=0; 
        } 
        kbdtimeout=KBDTIMEOUT; 
      } 
      kbdto=0; 
    } 
  } 
  kbdintflag=0; // reset interrupt flag 
} 

uchar kbdAsciiConv(void) { 
  // read uniKey global variable: return 0 not ascii 
  if (uniKey&0x80 || uniKey==0) 
    return 0; // key released or unknown 
  uniKey&=0x7f; 
  if (uniKey<=26) { 
    if (kbd_table.shift^kbd_table.capsLock) { 
      return shiftuni2ascii[uniKey]; 
    } else { 
      return uni2ascii[uniKey]; 
    } 
  } else if (uniKey<=0x30) { 
    if (kbd_table.shift) { 
      return shiftuni2ascii[uniKey]; 
    } else { 
      return uni2ascii[uniKey]; 
    } 
  } else if (uniKey<UNI2ASCIILEN) { 
    return uni2ascii[uniKey]; 
  } 
  return 0; 
}

Regards,
IanP
 

Re: Interface keyboard!

Hi IanP,

How is kbd_struct defined?
I want to see if I could make this code work for me. I already have functioning keyboard base on Atmel appnote, but it has glitches and no host to keyboard comm. I also like the idea that I could just set the interrupt edge on this code one time instead of flipping the edge every interrupt as it is in the appnote.

TIA
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top