CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Need help with PS/2 keyboard code

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
abo_shreek11



Joined: 27 Sep 2008
Posts: 10

View user's profile Send private message Send e-mail

Need help with PS/2 keyboard code
PostPosted: Mon Nov 24, 2008 3:57 pm     Reply with quote

Hi Guys
I used the above code in the following topic with some of my spices
http://www.ccsinfo.com/forum/viewtopic.php?p=107151#107151
Please read my configuration first and at the end you will find my question:

PIC in use: F184550
OSC : 20 Mhz

First, The configuration registers:
Code:

#include <18F4550.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES BROWNOUT_SW              //Brownout controlled by configuration bit in special file register
#FUSES BORV43                   //Brownout reset at 4.3V
#FUSES PUT                      //Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES NOSTVREN                 //Stack full/underflow will not cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES NOFCMEN                  //Fail-safe clock monitor disabled
#FUSES PBADEN                   //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOLPT1OSC                //Timer1 configured for higher power operation
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL1                     //No PLL PreScaler
#FUSES CPUDIV1                  //No System Clock Postscaler
#FUSES NOUSBDIV                 //USB clock source comes from primary oscillator
#FUSES NOVREGEN                 //USB voltage regulator disabled
#FUSES NOICPRT                  //ICPRT disabled

#use delay(clock=20000000)


Then, the LCD driver I used to display the key stroked on keyboard. By the way, I tested the LCD driver and connection before going into the keyboard stuff, and it is working fine, here is the code:
http://www.ccsinfo.com/forum/viewtopic.php?t=24661
Code:

// flex_lcd.c
#define LCD_DB4   PIN_D0
#define LCD_DB5   PIN_D1
#define LCD_DB6   PIN_D2
#define LCD_DB7   PIN_D3

#define LCD_E     PIN_C2
#define LCD_RS    PIN_C0
#define LCD_RW    PIN_C1

// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.

#define USE_LCD_RW   1     



And here is my program, which have to read from keyboard and display on LCD:
Code:

#include "D:\My Documents\PIC Projects\Keyboard Test(2) pic18 by CCS\main.h"

#include "flex_lcd.c"
   

//D0 - Clock
//D1 - Data


// Clock must be the interrupt pin
#define CLOCK PIN_B0
#define DATA  PIN_C4

unsigned char bData[16];
unsigned char idx=0;
unsigned char tmp=0;

unsigned char readByte();
unsigned char processByte();
unsigned char waitKey();
byte keyhit();
unsigned char translate(unsigned char scancode);

volatile byte shiftSet = 0;

byte kbBuffer[16];
byte kbPos = 0;
byte kbSize = 0;
byte capsSet = 0;
volatile byte extFlag = 0;
volatile byte relFlag = 0;
volatile byte key=0;

void sendByte(byte b)
{
    byte a=0;
    byte p = 1;
    byte t = 0;

    return;         // THIS IS NOT FULLY WORKING ON ALL KEYBOARDS
                    // SO IT IS COMMENTED OUT
                    // Some kind of timing issue or something. Whatever, they're just LEDs

    disable_interrupts(GLOBAL);
    output_low(CLOCK);
    delay_us(300);
    output_low(DATA);
    input(CLOCK);

    for(a=0; a<8; a++)
    {
        t = b&(1<<a);
        while(input(CLOCK) == 1); //wait for 0
        output_bit(DATA, t);
        if(t)
            p++;
        while(input(CLOCK) == 0); //wait for 1
    }

    while(input(CLOCK) == 1); //wait for 0
    output_bit(DATA, p&0x01);
    while(input(CLOCK) == 0); //wait for 1

    input(DATA);
    while(input(DATA) == 1); //wait for 0
    while(input(CLOCK) == 1); //wait for 0

    delay_ms(10);

    clear_interrupt(INT_EXT);
    enable_interrupts(GLOBAL);
}


main()
{
    int locx=1;
    unsigned char k=0;
   
    lcd_init();  // Always call this first.
    //printf("READY >");
    lcd_gotoxy(1,1);
    lcd_putc("READY >");

    output_b(0x00);
    input(CLOCK);

    delay_ms(100);

    ext_int_edge(H_to_L);
    enable_interrupts(INT_EXT);
    enable_interrupts(GLOBAL);

    while(1)
    {   
        if (locx>16)
         locx=0;
       
        if(keyhit())
        {
            k = waitKey();
            lcd_putc(k);
       
            locx++;
            lcd_gotoxy(locx,2);
        }
    }
}

byte keyhit()
{
    return kbSize != 0;
}

unsigned char waitKey()
{
    unsigned char k = 0;
    while(kbSize == 0);
    k = kbBuffer[(kbPos - kbSize)&0x0F];
    kbSize--;
    return k;
}

#int_ext
void kbInterrupt()
{
    volatile byte k=0;
    k = processByte();

    if(k != 0)
    {
        kbBuffer[kbPos] = k;
        kbPos = ++kbPos & 0x0F;
        kbSize++;
    }
    return;
}

unsigned char readByte()
{
    int i=0, t=0;
    idx=0;
    tmp=0;

    i=0;
    goto dataread;
   // while(INPUT(CLOCK) != 0);   // Wait for a keypress
            t=0;
       while(INPUT(CLOCK) != 0 && t<255)   // Wait for clock, time out if needed
       {
           delay_us(1);
           t++;
       }
    for(i=0; i<11; i++)
    {
        t=0;
        while(INPUT(CLOCK) != 0 && t<255)   // Wait for clock, time out if needed
        {
            delay_us(1);
            t++;
        }
        dataread:

        bData[idx]=INPUT(DATA);
        idx++;
        if(idx==9)
        {
            for(idx=1; idx<9; idx++)
                if(bData[idx]!=0)
                    tmp|=(1<<(idx-1));

            return tmp;
            idx=0;
            tmp=0;
        }
     //   while(INPUT(CLOCK) == 0);
        t=0;
        while(INPUT(CLOCK) == 0 && t<255)   // Wait for clock, time out if needed
        {
            delay_us(1);
            t++;
        }

    }
}

static const unsigned char scantableAZ[]={
0x1C, 0x32, 0x21, 0x23, 0x24, 0x2B, 0x34, 0x33, 0x43, 0x3B, 0x42, 0x4B, 0x3A, // A-Z
0x31, 0x44, 0x4D, 0x15, 0x2D, 0x1B, 0x2C, 0x3C, 0x2A, 0x1D, 0x22, 0x35, 0x1A};

// Normal numeric scancodes, starting with ',' .
static const unsigned char scantable09n[]=
{
0x41, 0x4E, 0x49, 0x4A, // , - . /
0x45, 0x16, 0x1E, 0x26, 0x25, 0x2E, 0x36, 0x3D, 0x3E, 0x46,     //Digits 0-9
0x00, 0x4C, 0x00, 0x55 // 0 ; 0 =
};

// Shift scancodes, starting at '!'
static const unsigned char scantable09s[]=
{
    0x16, 0x52, 0x26, 0x25, 0x2E, 0x3D, 0x00, 0x46, 0x45, 0x3E, 0x55
};

// Normal misc. scancode map. Scancode, ASCII value
static const unsigned char scanmapn[]=
{0x54, '[', 0x5B, ']', 0x0E, '`', 0x5D, '\\', 0x52, '\''};

// Shifted misc. scancode map. Scancode, ASCII value
static const unsigned char scanmaps[]=
{0x1E, '@', 0x36, '^', 0x4E, '_', 0x54, '{', 0x5B, '}', 0x5D, '|',
0x4C, ':', 0x41, '<', 0x49, '>', 0x4A, '?', 0x0E, '~'};


// Scancode map independent of Shift
static const unsigned char scanmapx[]=
{0x29, ' ', 0x5A, '\r', 0x0D, '\t', 0x76, 27, 0x66, 0x08};

// Extended scancode map
static const unsigned char scanmape[]=
{
0x71, 0x7F
};

unsigned char translate(unsigned char scancode)
{
    int i=0;

    if(extFlag == 0)
    {
        for(i=0; i<10; i+=2)
            if(scanmapx[i] == scancode)
                return scanmapx[i+1];

        for(i=0; i<26; i++)
            if(scantableAZ[i] == scancode)
                if(shiftSet ^ capsSet)
                    return i+65;
                else
                    return i+65 + 32;

        if(shiftSet)
        {
            for(i=0; i<11; i++)
                if(scantable09s[i] == scancode)
                    return i+'!';

            for(i=0; i<22; i+=2)
                if(scanmaps[i] == scancode)
                    return scanmaps[i+1];
        } else
        {
            for(i=0; i<18; i++)
                if(scantable09n[i] == scancode)
                    return i+',';

            for(i=0; i<10; i+=2)
                if(scanmapn[i] == scancode)
                    return scanmapn[i+1];
        }
    } else      // Extended keys
    {
        for(i=0; i<2; i+=2)
            if(scanmape[i] == scancode)
                return scanmape[i+1];
    }
    return '?';
}

unsigned char processByte()
{
    unsigned char i, j;
    i = readByte();

    if(i == 0xF0)       //A key is being released
    {
        relFlag = 1;
        return 0;
    }

    if(i == 0xE0)       // Extended key operation
    {
        extFlag = 1;
        relFlag = 0;    //0xE0 always first in sequence, OK to clear this
        return 0;
    }

    if(relFlag == 0)    // Pressing a key
    {
        if(extFlag == 0)    // Non-extended key pressed
        {
            if(i == 0x12 || i == 0x59)
            {
                shiftSet = 1;
                return 0;
            }

            if(i == 0x58)
            {
                sendByte(0xED);
                if(capsSet == 0)
                {
                    capsSet = 1;
                    sendByte(0x04);
                } else
                {
                    capsSet = 0;
                    sendByte(0x00);
                }
                return 0;
            }


        }
        j = translate(i);
        extFlag = 0;
        return j;
    }

    if(relFlag == 1)    //Releasing a key
    {
        relFlag = 0;    //If a flag was set but not handled, we wouldn't have gotten here
        extFlag = 0;    //OK to clear this here

        if(extFlag == 0)   // Releasing a nonextended key
        {
            if(i == 0x12 || i == 0x59)
            {
                shiftSet = 0;
                return 0;
            }

        }
//        } else              // Releasing an extended key
//        {
//            return 0;
//        }

//        return 0;
    }
    return 0;
}

Now to the important part. When I power up my circuit, the LCD displays the "Ready" line and the keyboard Num Lock and Caps Lock LEDs light up. 1 or 2 seconds later, the LEDs start to blink and the LCD starts to shows " : " character on the second line.

Any suggestion on what is going on ? I doubt the microcontroller inside the keyboard is not well initialized.
Please Contribute
stevenm86



Joined: 11 Jun 2006
Posts: 11

View user's profile Send private message

PostPosted: Mon Nov 24, 2008 10:07 pm     Reply with quote

Wow, it certainly has been a while....

The LEDs on the keyboard blink?

They shouldn't... Are you sure the keyboard is hooked up correctly? Does it go to the right pins on your chip?

The only thing I can think of that would cause the LEDs to blink is if you were somehow sending random LED commands to the keyboard.
abo_shreek11



Joined: 27 Sep 2008
Posts: 10

View user's profile Send private message Send e-mail

PostPosted: Tue Nov 25, 2008 1:50 am     Reply with quote

Hi Steve

I am using "mini-din 6 pins" female connector, and the only connectivty which at least turned the keyboard on is the only on which blinks the led. I have doubt that I damaged the keyboard microcontroller with one of the connection combinations I used Confused, and I don't think I am sending a random command as the code above shows. Do you think configuring portb as analog or digital has something to do with this "interrupt pin" ? In the project configuration wizard, I chose portb to be analog input. What do you think ?
Ttelmah
Guest







PostPosted: Tue Nov 25, 2008 5:26 am     Reply with quote

First, have you got pull-up resistors on the keyboard interface lines?. These are _required_. The bus is an 'open collector' link, and once you switch to 'input' mode at the PIC, there is nothing to drive the lines 'high', unless these resistors are present.
You probably need a slightly longer pause after dropping the clock line, before switching to reading it. When you pull the clock 'low' on boot, it disables the interface to the keyboard, and it does take a moment for the keyboard to respond to this. You are normally meant ot then release the line, wait for the keyboard to respond, and write a two bytes to the command register (at address 0x64), normally 0x60, then 0x8. Unless this is done, the keyboard will be in 'inhibit' mode, and not able to send data to the host. It may be that your keyboard gives an 'error' display if this is not done.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group