• AVR Freaks

Hot!PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine

Page: 12 > Showing page 1 of 2
Author
ishkabum
Starting Member
  • Total Posts : 58
  • Reward points : 0
  • Joined: 2020/09/24 07:42:09
  • Location: Washington DC
  • Status: offline
2020/10/26 10:48:35 (permalink)
0

PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine

I'm using MPLAB X IDE v5.40, XC8 v2.30, and programming with the PICkit 4 ICSP. The device is target powered on a breadboard. There are 0.1 uF capacitors between VDD and VSS as recommended by the datasheet page 8, Note 5. There's a 10 kOhm pull-up resistor from MCLR to VDD as recommended by PICkit user guide page 19 (2.3.2 Target Circuitry). Jumpers are running to LEDs to observe program states. Oscillator is HFINTOSC at 64 MHz. Unused pins are outputs set low.
 
I can see with a simple LED strobe and button-push routine that it's staying in the while(1) but never seems to get a start condition. The intent is it's polling CLOCK_PORT and DATA_PORT to see when it's staying low for a set amount of time, and when conditions for next state arrive it will start incrementing a confidence counter which should exceed a threshold before proceeding. When I bring that confLimit as low as 5, it will go through the routine and I believe all that is noise. Just as high as 10 and it will never exceed.
 
The PS/2 CLK and DATA lines are both expected to be HIGH until a key press occurs. This is confirmed by sending those values to LEDs every time they're polled. They're always showing high. Is there something I'm doing wrong in the logic here? I took my routine into another program where I manually set the DATA & CLK with digital switches. The data-word building process worked as expected, the parity bit check worked as expected, etc. So without an oscillator I'm stumped. Fortunately I've commented very well and hopefully someone can see something obvious where I think something is happening which is not.
 
https://imgur.com/a/u3wG6oX
 
This video shows the wiring arrangement and running state. LED 2 strobes with counter, LED 3 turns on when the button is pushed down, and LEDs 4 & 5 are reading DATA & CLOCK lines remaining high (red). Weak pull-ups are enabled on those 2 inputs, which can be seen connected to pins D0, D1 (lower right). I tried connecting external pull up resistors (3.3kOhm) also but I feel this is unnecessary given the internal pull-up. Green=VDD +5V, Black = GND, and the red and white are No Connection which are grounded.
 
The variables are passed between functions, but it's all in the same c file so I don't think an extern designator is needed, but that didn't stop me from trying it. If there is any other designator that is needed for them to behave as expected I might not have it. I tried making them all static too and that didn't help. The main is included and the others are attached for reference.
 
  
#include "mcc_generated_files/mcc.h"

#define PUSHED 1
#define NOT_PUSHED 0

void strobe(void);
void assignLight(void);
void waitForCLK_HI(void);
void waitForCLK_LO(void);
void checkKeyboard(void);
void checkButtonS2(void);
void clearAndBlink(void);
void checkStartCondition(void);
uint8_t readRoutine(void);
bool dataIsValid = true; 
bool confident = false;
bool startCond = false;
long confidence = 0;
long confLimit = 10;
uint8_t byteBuild = 0x00;
uint8_t zeroBits = 0;
uint8_t scanCode = 0;
uint8_t parityBit = 0;
uint8_t newScan = 0;
uint8_t lastScan = 0;
uint8_t printCt = 0;
uint8_t printCtshift = 4;
uint8_t currClock = 0;
uint8_t currData = 0;
uint8_t wordCount = 0;
uint8_t switch2Flag = 0;
uint8_t btn2State = 0;
long startConf = 0;
long counter = 0;



void main(void)
{
    SYSTEM_Initialize();
    while (1)
    {
        strobe();
        checkButtonS2();
        assignLight();
        checkStartCondition();
    }
}

void checkKeyboard(void) //Print scan-code
{
    newScan = readRoutine(); //Read scan code
    if(newScan != lastScan) //Make sure it's a new key-press
    {
        //if(dataIsValid) //Check if parity is correct
        //{
            //lcdWrite(newScan, DATA); //Print scan-code to LCD (not mapped yet)
        wordCount++; //Track placement of character
        if(newScan == 0xF0) L8_SetHigh(); //Turn on L8
        //}
        //else dataIsValid = true; //Reset dataIsValid and don't print if false.
    }
    lastScan = newScan; //Set lastScan - F0 will have to be ignored (break code)
}

uint8_t readRoutine(void)
{
    waitForCLK_HI();
    waitForCLK_LO();

    for(int i = 0; i<8; i++) //Enter the byteBuilding zone
    {
        __delay_us(15); //Poll halfway thru CLK pulse
        if (DATA_PORT) byteBuild |= 0x01 << i; //Set the bit if DATA=1
        else zeroBits++; //Count the zeros for PARITY
        waitForCLK_HI();
        if (i<7) waitForCLK_LO(); //Wait for CLK to go LOW. After D7, EXIT LOOP
    }
    waitForCLK_LO();
    __delay_us(15); //Poll halfway thru CLK pulse
    parityBit = DATA_PORT; //Take the PARITY bit
    
    //if odd 0s and parityBit=1, or if even 0s and parityBit=0, data is corrupted
    if((zeroBits%2 && parityBit) || (!zeroBits%2 && !parityBit)) dataIsValid=false;
    waitForCLK_HI();
    waitForCLK_LO();
    __delay_us(15); //Poll halfway thru CLK pulse
    if(!DATA_PORT) dataIsValid=false; //STOP bit must be 1
    waitForCLK_HI();
    scanCode = byteBuild; //Store the completed byte
    clearAndBlink(); //Clear variables, blink lights
    return scanCode; //Return the keyboard scanCode
}

void waitForCLK_HI(void)
{
    while (!confident) //Wait for CLK to go HIGH
    {
        if(CLOCK_PORT) //If CLK is HIGH
        {
            confidence++; //Building confidence
            if(confidence>confLimit)
            {
                confidence = 0; //Clear confidence counter
                confident = true; //Set confident to exit loop
            }
        }
        else confidence = 0; //Reset confidence
    } confident = false;
}

void waitForCLK_LO(void)
{
    while (!confident) //Wait for CLK to go LOW
    {
        if(!CLOCK_PORT) //If CLK is LOW
        {
            confidence++;
            if(confidence>confLimit)
            {
                confidence = 0; //Clear confidence counter
                confident = true; //Reset confident
            }
        } else confidence = 0; //Reset confidence
    } confident = false; //Reset confident
}

void clearAndBlink(void)
{
    byteBuild = 0; //Clear the byteBuild tool
    zeroBits = 0; //Clear the zero bits counter
    dataIsValid = true; //Reset dataIsValid for next
    
    L15_SetHigh();
    __delay_ms(250);
    L15_SetLow();
    __delay_ms(250);
    L15_SetHigh();
    __delay_ms(250);
    L15_SetLow();
    /*
    LATB = 0;
    LATC = 0;
    LATD = 0;
    */
}

void strobe(void) //ON RA7, strobe RA5, show program is running
{
    counter++; //increment counter
    if(counter>256000) //manually set to be close to 1 second by stopwatch
    {
        //LED_D5_SetHigh(); //D5 comes on after 1 sec and stays on
        L14_Toggle(); //L14 strobes to show it's running
        counter=0; //reset counter
    }
}

void checkButtonS2(void) //RC3 sets btn2State, switch2Flag
{
    if(btn2State == NOT_PUSHED) //we think the button is not pushed
    {
        if (RC3_GetValue() == LOW) //see if the button is pushed
        {
            __delay_ms(30); //de-bouncing
            if (RC3_GetValue() == LOW) //if the button is still pressed
            {
                btn2State = PUSHED; //switch on button state
                switch2Flag = HIGH; //raise the flag
            }
        }
    }
    else //we think the button is pushed
    {
        if (RC3_GetValue() == HIGH) //if the button is released
        {
            btn2State = NOT_PUSHED; //set the button state
        }
    }
}

void assignLight(void) //L13 on when RC3 pressed down
{
    if (switch2Flag)
    {
        //LED_D2_Toggle(); //flip the LED D2 status
        //printNext(); //write a message
        switch2Flag=LOW; //lower the flag
    }
    if(btn2State == PUSHED) L13_SetHigh();
        else L13_SetLow();
}

void checkStartCondition(void)
{
    if(!CLOCK_PORT) currClock=0;
    else currClock=1; //Check CLOCK
    
    if(!DATA_PORT) currData=0;
    else currData=1; //Check DATA
    
    if(currClock) L12_SetHigh(); //Display CLOCK
    else L12_SetLow();
    
    if(currData) L11_SetHigh(); //Display DATA
    else L11_SetLow();
    
    if(!currClock && !currData) //If CLK&DATA both LOW - Possible START Condition
    {
        startConf++; //Build Start Confidence
        if (startConf > confLimit) //Need to hold condition past confLimit
        {
            startConf = 0; //Reset Start Confidence
            startCond = true; //Set Start Condition
        }
    } else startConf = 0;
    
    if(startCond)
    {
        startCond = false; //Clear startCond
        L0_SetHigh(); //LED 0 INDICATOR
        checkKeyboard(); //Begin when confident of START condition
    }
}

 
Thanks to anyone who can offer any insights.
 
 
post edited by ishkabum - 2020/10/26 10:56:40
#1

25 Replies Related Threads

    KTrenholm
    Super Member
    • Total Posts : 804
    • Reward points : 0
    • Joined: 2012/08/08 14:04:23
    • Location: Connecticut, USA
    • Status: offline
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/26 11:33:49 (permalink)
    +1 (1)
    How are CLOCK_PORT and DATA_PORT defined?
    My first thought is that if your LEDs are not updating, currClock and currData are not setting properly, which leads to the if() statements:

     
        if(!CLOCK_PORT) currClock=0;
        else currClock=1; //Check CLOCK
        
        if(!DATA_PORT) currData=0;
        else currData=1; //Check DATA
     

     
     
    I'd also definitely use the external pull-ups rather than internal for PS/2.  Some PICs can probably handle it, but that PIC has what looks to be equal to about 20k weak pull-ups if I'm reading the datasheet correctly.  That's probably too weak to properly handle PS/2 communication speed (10KHz to 16.7KHz).  5k-10k is around what I'd expect to see for PS/2 (although I've used as low as 2k).  It probably won't matter if you're testing with manual switches for changes in clock/data, but can absolutely become an issue when talking to an actual PS/2 device
    post edited by KTrenholm - 2020/10/26 11:39:57
    #2
    ishkabum
    Starting Member
    • Total Posts : 58
    • Reward points : 0
    • Joined: 2020/09/24 07:42:09
    • Location: Washington DC
    • Status: offline
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/26 11:39:14 (permalink)
    0
    KTrenholm
    How are CLOCK_PORT and DATA_PORT defined?
    My first thought is that if your LEDs are not updating, currClock and currData are not setting properly, which leads to the if() statements:

     
        if(!CLOCK_PORT) currClock=0;
        else currClock=1; //Check CLOCK
        
        if(!DATA_PORT) currData=0;
        else currData=1; //Check DATA
     

     
     
    I'd also definitely use the external pull-ups rather than internal for PS/2. The internal pull-ups on that PIC are almost for sure too weak to properly handle PS/2 communication speed (10KHz to 16.7KHz).  It probably won't matter if you're testing with manual switches for changes in clock/data, but can absolutely become an issue when talking to an actual PS/2 device


    The pins are named CLOCK and DATA in MCC so the pin_manager.h has the following definitions:
     

     
    // get/set DATA aliases
    #define DATA_TRIS TRISDbits.TRISD0
    #define DATA_LAT LATDbits.LATD0
    #define DATA_PORT PORTDbits.RD0
    #define DATA_WPU WPUDbits.WPUD0
    #define DATA_OD ODCONDbits.ODCD0
    #define DATA_ANS ANSELDbits.ANSELD0
    #define DATA_SetHigh() do { LATDbits.LATD0 = 1; } while(0)
    #define DATA_SetLow() do { LATDbits.LATD0 = 0; } while(0)
    #define DATA_Toggle() do { LATDbits.LATD0 = ~LATDbits.LATD0; } while(0)
    #define DATA_GetValue() PORTDbits.RD0
    #define DATA_SetDigitalInput() do { TRISDbits.TRISD0 = 1; } while(0)
    #define DATA_SetDigitalOutput() do { TRISDbits.TRISD0 = 0; } while(0)
    #define DATA_SetPullup() do { WPUDbits.WPUD0 = 1; } while(0)
    #define DATA_ResetPullup() do { WPUDbits.WPUD0 = 0; } while(0)
    #define DATA_SetPushPull() do { ODCONDbits.ODCD0 = 0; } while(0)
    #define DATA_SetOpenDrain() do { ODCONDbits.ODCD0 = 1; } while(0)
    #define DATA_SetAnalogMode() do { ANSELDbits.ANSELD0 = 1; } while(0)
    #define DATA_SetDigitalMode() do { ANSELDbits.ANSELD0 = 0; } while(0)
     
    // get/set CLOCK aliases
    #define CLOCK_TRIS TRISDbits.TRISD1
    #define CLOCK_LAT LATDbits.LATD1
    #define CLOCK_PORT PORTDbits.RD1
    #define CLOCK_WPU WPUDbits.WPUD1
    #define CLOCK_OD ODCONDbits.ODCD1
    #define CLOCK_ANS ANSELDbits.ANSELD1
    #define CLOCK_SetHigh() do { LATDbits.LATD1 = 1; } while(0)
    #define CLOCK_SetLow() do { LATDbits.LATD1 = 0; } while(0)
    #define CLOCK_Toggle() do { LATDbits.LATD1 = ~LATDbits.LATD1; } while(0)
    #define CLOCK_GetValue() PORTDbits.RD1
    #define CLOCK_SetDigitalInput() do { TRISDbits.TRISD1 = 1; } while(0)
    #define CLOCK_SetDigitalOutput() do { TRISDbits.TRISD1 = 0; } while(0)
    #define CLOCK_SetPullup() do { WPUDbits.WPUD1 = 1; } while(0)
    #define CLOCK_ResetPullup() do { WPUDbits.WPUD1 = 0; } while(0)
    #define CLOCK_SetPushPull() do { ODCONDbits.ODCD1 = 0; } while(0)
    #define CLOCK_SetOpenDrain() do { ODCONDbits.ODCD1 = 1; } while(0)
    #define CLOCK_SetAnalogMode() do { ANSELDbits.ANSELD1 = 1; } while(0)
    #define CLOCK_SetDigitalMode() do { ANSELDbits.ANSELD1 = 0; } while(0)
     


    That's good to know about internal vs external; I will try gradually lower from 3.3kOhm. I will disable the WPU in MCC and start with 3.3 and bring it down to 1k. A (seemingly-classic and oft-repeated) resource I found recommended between 1-10kOhm.
     
    When the confidence threshold is set low enough (5 cycles which must be in the nanosecond range I presume) I do see the lights come on indicating that the program enters the readRoutine and the lines came low, but it's almost certainly all noise because it does this when keys are not pressed. The pullup resistors are hopefully the problem here.
    post edited by ishkabum - 2020/10/26 11:40:41
    #3
    ishkabum
    Starting Member
    • Total Posts : 58
    • Reward points : 0
    • Joined: 2020/09/24 07:42:09
    • Location: Washington DC
    • Status: offline
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/26 15:38:24 (permalink)
    0
    KTrenholm 
    I'd also definitely use the external pull-ups rather than internal for PS/2.  Some PICs can probably handle it, but that PIC has what looks to be equal to about 20k weak pull-ups if I'm reading the datasheet correctly.  That's probably too weak to properly handle PS/2 communication speed (10KHz to 16.7KHz).  5k-10k is around what I'd expect to see for PS/2 (although I've used as low as 2k).  It probably won't matter if you're testing with manual switches for changes in clock/data, but can absolutely become an issue when talking to an actual PS/2 device



    Unfortunately going down to 1.1kOhm still presented with the same issue of not entering the loop. If I can get access to a digital oscillator or a UART module to stream back to my computer I'll be able to look at the signal and see if it's behaving properly. Otherwise I'm out of ideas. I may start a new program using interrupts but in theory shouldn't be necessary and still not sure why it's getting stuck.
    #4
    ric
    Super Member
    • Total Posts : 28943
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/26 16:02:22 (permalink)
    +1 (1)
    Where are "true" and "false" defined?
    Be aware, type "bool" uses a whole byte. Use type "__bit" if you want to use just a single bit.
    The only drawbacks of the __bit type is you cannot make arrays of them or create pointers to them.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #5
    KTrenholm
    Super Member
    • Total Posts : 804
    • Reward points : 0
    • Joined: 2012/08/08 14:04:23
    • Location: Connecticut, USA
    • Status: offline
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/27 07:42:34 (permalink)
    +2 (2)
    I'd also be a little wary of why startCond is going true without your input when your debounce threshold is 5 or less.  You are assuming it is noise, but I feel like it's unlikely you're getting 5 lows in a row from just noise.  My gut feeling is there's something else going on here (but my gut feelings have been known to be wrong before mr green: mr green)
     
    Do you have any method to measure your time to get through your main loop to be sure you're catching the start condition?  If you have a way to measure frequency such as a multimeter, you could toggle a pin every time you call checkStartCondition to measure your time between debounce passes.
     
    Bear in mind the minimum cycle time of that PIC is listed at 62.5ns in the datasheet,  The low time of a clock pulse (so the amount of time you have to catch 5 low reads) is 50us max (10KHz) and 30us minimum (16.7KHz).  This would mean you need to make 5 trips through your main loop within that time frame. 
     
    This would mean, at most, you have 800 cycles to hit checkStartCondition 5 times.  That's a budget of 160 cycles per loop through main, assuming minimum instruction time of the PIC, and minimum PS/2 clock frequency.
    800 = 0.000050/0.0000000625
    160 = 800/5
     
    That's at the low end of possible PS/2 clock frequencies.  If we assume we are running at max PS/2 clock frequency of 16.7KHz, that gives you 96 cycles to get loop through main:
    480 = 0.000030/0.0000000625
    96 = 480/5
     
    That time budget just decreases further the more passes you make on the debounce.  Looking at the code you provided, assuming that is all that is being called in main, you should meet this timing spec for 5 debounce passes, but if it were me, I would still measure it to be absolutely sure.
     
    If you manage to get your hands on an oscilloscope, toggling an output each time your counter increments and looking at it next to the PS/2 data/clock you should be able to see exactly where you are sampling the signals when you poll them, as well as how quickly checkStartCondition is being called.
     
     
    #6
    hexreader
    Super Member
    • Total Posts : 1107
    • Reward points : 0
    • Joined: 2008/05/04 03:06:55
    • Location: England
    • Status: online
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/27 08:25:43 (permalink)
    +1 (3)
    I would be willing to debug your project, given all files zipped up into one zip file so that I can compile without having to guess at what is in the undisclosed files.
     
    Need all files - not just snippets -zip up and post the whole project folder
     
    no guarantee of any result, but it will be fun to try
     
    Regards hexreader
    post edited by hexreader - 2020/10/27 08:35:57

    Experienced Hobbyist
    #7
    ishkabum
    Starting Member
    • Total Posts : 58
    • Reward points : 0
    • Joined: 2020/09/24 07:42:09
    • Location: Washington DC
    • Status: offline
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/27 09:00:27 (permalink)
    0
    ric
    Where are "true" and "false" defined?
    Be aware, type "bool" uses a whole byte. Use type "__bit" if you want to use just a single bit.
    The only drawbacks of the __bit type is you cannot make arrays of them or create pointers to them.

    I checked and see that stdbool.h holds the #define true 1 and #define false 0 statements. The intent indeed would be to use 1 bit if possible so I will try to do __bit for binary values and see how that goes. 
     
    KTrenholm
    I'd also be a little wary of why startCond is going true without your input when your debounce threshold is 5 or less.  You are assuming it is noise, but I feel like it's unlikely you're getting 5 lows in a row from just noise.  My gut feeling is there's something else going on here (but my gut feelings have been known to be wrong before mr green: mr green)
     
    Do you have any method to measure your time to get through your main loop to be sure you're catching the start condition?  If you have a way to measure frequency such as a multimeter, you could toggle a pin every time you call checkStartCondition to measure your time between debounce passes.

     
    I see your point, I'm also a little wary. I've tried to get in touch with a local university and see if I can use their digital oscilloscope. I'll keep hounding them... I've been trying to install a CDC driver to use my PICkit USB as Serial port, because the MPLAB Data Visualizer will only stream out to USART or Serial. That hasn't worked yet. I could also use one of the TMRs so I may do that if I'm stalled and try to read an actual time that the loop takes. 
     
    KTrenholm
     
    That's at the low end of possible PS/2 clock frequencies.  If we assume we are running at max PS/2 clock frequency of 16.7KHz, that gives you 96 cycles to get loop through main:
    480 = 0.000030/0.0000000625
    96 = 480/5
     

    Seems right, I should be able to get through it and read at least 5 or 10 before going into the routine. Will try to get use of an oscilloscope and measure to be sure. It's running at 64 MHz so there should be no issue there, all the functions in the main are pretty quick.
     
     
    hexreader
    I would be willing to debug your project, given all files zipped up into one zip file so that I can compile without having to guess at what is in the undisclosed files.
     
    Need all files - not just snippets -zip up and post the whole project folder
     
    no guarantee of any result, but it will be fun to try
     
    Regards hexreader


    That sounds good, here:
     
    https://drive.google.com/file/d/1sIGpVhtOGETX_NadMhbZ6S71mCQ4Akck/view?usp=sharing
     
    The whole folder has been zipped and posted with download permissions. Note again that nothing is really happening with the scan code you'll see. I'm just lighting up one LED (L0) when it detects start condition, it only clears upon Reset, and I'm just setting breakpoints to see where it's getting caught and what parts of the routine it's getting to, etc. So also at this time nothing is being done with the dataIsValid bool reacting to parity check, start/stop bits, etc. Please let me know if there are any questions about the code.
    #8
    hexreader
    Super Member
    • Total Posts : 1107
    • Reward points : 0
    • Joined: 2008/05/04 03:06:55
    • Location: England
    • Status: online
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/27 09:20:37 (permalink)
    +1 (1)
    It is great to see code that is well formatted and well commented.
     
    Might take me a long time to get my head around how the code works. Looks very complex at first look.
     
    Working on it.... but don't feel overly hopeful :(
     
    (thought it best to be honest)
    post edited by hexreader - 2020/10/27 09:22:38

    Experienced Hobbyist
    #9
    ishkabum
    Starting Member
    • Total Posts : 58
    • Reward points : 0
    • Joined: 2020/09/24 07:42:09
    • Location: Washington DC
    • Status: offline
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/27 09:25:39 (permalink)
    0
    hexreader
    It is great to see code that is well formatted and well commented.
     
    Might take me a long time to get my head around how the code works. Looks very complex at first look.
     
    Working on it.... but don't feel overly hopeful :(
     
    (thought it best to be honest)


    Appreciate it. I'm not an especially skilled programmer so I think once you start moving through it and reading it you'll see it's relatively simple, hopefully that is. I only know how to use simple stuff like while, for, if/else, etc. So it should be pretty straight forward. Please feel free to contact me on Telegram at https://t.me/ishkabum
     
    It's just doing the routine to wait for the confidence counter to build and ensure the program of a pin-state transition. Anything else do feel free to contact me with any questions for clarification. I really do appreciate you taking a look.
    #10
    hexreader
    Super Member
    • Total Posts : 1107
    • Reward points : 0
    • Joined: 2008/05/04 03:06:55
    • Location: England
    • Status: online
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/27 09:48:29 (permalink)
    +1 (1)
    First thoughts ......
     
    Not sure that the "confidence" checks are needed. Clock and data signals do not bounce the way that buttons do.
     
    First simplification will be to remove all "confidence" variables and do simple high/low checks.
     
    Still working on it...

    Experienced Hobbyist
    #11
    ishkabum
    Starting Member
    • Total Posts : 58
    • Reward points : 0
    • Joined: 2020/09/24 07:42:09
    • Location: Washington DC
    • Status: offline
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/27 09:51:57 (permalink)
    0
    hexreader
    First thoughts ......
     
    Not sure that the "confidence" checks are needed. Clock and data signals do not bounce the way that buttons do.
     
    First simplification will be to remove all "confidence" variables and do simple high/low checks.
     
    Still working on it...


    OK noted, I think you're right. It may help to explain that I only added this when it didn't work the first time and I wasn't sure yet why, just couldn't think of anything else to do LoL: LoL. Especially if I could see the data stream with oscilloscope that would tell me if it was needed or not...
     
    I will work on reducing the code to remove those checks and save this version for archive.
    #12
    hexreader
    Super Member
    • Total Posts : 1107
    • Reward points : 0
    • Joined: 2008/05/04 03:06:55
    • Location: England
    • Status: online
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/27 10:05:28 (permalink)
    +1 (1)
    No need to reduce code (unless you want to) - I will do it for you :)

    Experienced Hobbyist
    #13
    KTrenholm
    Super Member
    • Total Posts : 804
    • Reward points : 0
    • Joined: 2012/08/08 14:04:23
    • Location: Connecticut, USA
    • Status: offline
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/27 10:08:26 (permalink)
    +1 (1)
    ishkabum
    hexreader
    First thoughts ......
     
    Not sure that the "confidence" checks are needed. Clock and data signals do not bounce the way that buttons do.
     
    First simplification will be to remove all "confidence" variables and do simple high/low checks.
     
    Still working on it...


    OK noted, I think you're right. It may help to explain that I only added this when it didn't work the first time and I wasn't sure yet why, just couldn't think of anything else to do LoL: LoL. Especially if I could see the data stream with oscilloscope that would tell me if it was needed or not...
     
    I will work on reducing the code to remove those checks and save this version for archive.



    The debouncing did probably made it work better when you were testing with a switch though, so there's that.  But he's 100% correct, unless you have a severe noise problem, you should not need debouncing on clock and data.
    #14
    ishkabum
    Starting Member
    • Total Posts : 58
    • Reward points : 0
    • Joined: 2020/09/24 07:42:09
    • Location: Washington DC
    • Status: offline
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/27 10:24:21 (permalink)
    0
    KTrenholm
    The debouncing did probably made it work better when you were testing with a switch though, so there's that.  But he's 100% correct, unless you have a severe noise problem, you should not need debouncing on clock and data.

    That's true, it is needed for the switch check, which  I had to do to make sure that part works as expected.
     
    What I'm replacing the waitForCLK_HI(); function with is:
    while(!CLOCK_PORT);

    waitForCLK_LO(); is replaced with:
    while(CLOCK_PORT);

     
    The intent is it is polling these all the time and it should return zero when low, and remain until it gets a high value. Is this correct? I know PORTXbits.RX# returns a bit so it should be 0 or 1 and break as expected, just want to confirm.
    post edited by ishkabum - 2020/10/27 10:27:05
    #15
    KTrenholm
    Super Member
    • Total Posts : 804
    • Reward points : 0
    • Joined: 2012/08/08 14:04:23
    • Location: Connecticut, USA
    • Status: offline
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/27 10:33:34 (permalink)
    +1 (1)
    ishkabum
    What I'm replacing the waitForCLK_HI(); function with is:
    while(!CLOCK_PORT);

    waitForCLK_LO(); is replaced with:
    while(CLOCK_PORT);

    The intent is it is polling these all the time and it should return zero when low, and remain until it gets a high value. Is this correct?



    Yes that would work. 
    Me personally, I usually like having a macro for things like that, but your preference may differ:

    #define    WAIT_FOR_CLK_HI    while(!CLOCK_PORT)
    #define    WAIT_FOR_CLK_LO    while(CLOCK_PORT)

    #16
    ishkabum
    Starting Member
    • Total Posts : 58
    • Reward points : 0
    • Joined: 2020/09/24 07:42:09
    • Location: Washington DC
    • Status: offline
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/27 10:34:10 (permalink)
    0
    Getting closer... As I remove the confidence checks I am seeing a stream of alternating 0xAA = 0b10101010 from the byteBuild routine. By the way there is no better debugging soundtrack than:
     
    https://www.youtube.com/watch?v=UkXeOMSwdZQ
     
     
    #17
    ishkabum
    Starting Member
    • Total Posts : 58
    • Reward points : 0
    • Joined: 2020/09/24 07:42:09
    • Location: Washington DC
    • Status: offline
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/27 10:37:41 (permalink)
    0
    KTrenholm
    Yes that would work. 
    Me personally, I usually like having a macro for things like that, but your preference may differ:

     
    #define    WAIT_FOR_CLK_HI    while(!CLOCK_PORT)
     
    #define    WAIT_FOR_CLK_LO    while(CLOCK_PORT)


    Thanks, I prefer that too. Will revise.
    #18
    hexreader
    Super Member
    • Total Posts : 1107
    • Reward points : 0
    • Joined: 2008/05/04 03:06:55
    • Location: England
    • Status: online
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/27 15:07:45 (permalink)
    +1 (1)
    Wow ! that is the most complicated code for a simple job that I have ever seen
     
    Here are my questions so far...
     
    1) why are you reading data 15ms after clock goes low? - I would think that data is valid on clock falling edge, not after
    2) what is "start condition" ?   - is it same thing as start bit?
    3) what is the aim of your code? - (the bigger picture)
    4) is it OK if I re-write from scratch?  your code makes my brain hurt

    Experienced Hobbyist
    #19
    ishkabum
    Starting Member
    • Total Posts : 58
    • Reward points : 0
    • Joined: 2020/09/24 07:42:09
    • Location: Washington DC
    • Status: offline
    Re: PIC18F47Q10 - Reading PS/2 signal without interrupts - never enters read routine 2020/10/27 15:45:54 (permalink)
    +1 (1)
    Ha! Yeah... Well a lot of it is writing indicators for me to observe parts. Like strobe, checkButton, assignLight.... All of that is unrelated just to see it's staying in the loop. I do agree that check keyboard, readRoutine, checkStartCondition, three separate for this is probably not necessary and I see how it could make it more confusing than necessary.

    1. No particular reason. Data is valid on CLK low pulse but I wait a portion just to pick it up in the middle of the pulse, like the comment says. Probably not necessary. I just figured it's possible there is some settling in the first nanoseconds that must occur so I'd pick it up partway through the pulse.
    2.Yes, same thing as the start bit. 
    3. It's just to grab the scan code, I will be displaying to LCD which I have that part separately. Does so by sending to other PICs via I2C or serial protocol. It won't need to write to the keyboard to turn on LEDs, only device to host.
    4. Sure! Haha
    post edited by ishkabum - 2020/10/27 16:23:43
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2020 APG vNext Commercial Version 4.5