|
|
| Author |
Message |
ndudman
Joined: 25 Dec 2008
Posts: 79
|
|
Posted: 17 January 2009, 15:24 PM Post subject: AT keyboard - sometimes loosing track of 11 bits |
|
|
Hi
Ive included a simple broken down part of my project which has an AT serial keyboard connected via INT0 and a data line... the key presses chars are Debug.printed out along with the current bitcounter 0-11...
The problem I have, if keys get pressed really quickly or perhaps uP doing something else... is that the get_kb_bitcount() starts to show that the c code in keyboard.c has lost count (miss-counted) the 1-11 interrupts per key press... once it has lots count then the char codes returned make no sense.
I have to admit and say I dont understand exactly how everything works as the code isnt all mine, although Ive spent a while going through, but I thought of adding some recovery code, perhaps some timer that if a key isnt pressed for a while that we just make sure that the bitcount is 0 and if not ensure its reset.
Im just not sure quite how to do that with the timer interrupts, or if this is the best way... Also wanted to share something in case its useful to others or they can improve and help
Thanks
Neil
ps Perhaps its overkill to have a whole AT PC keyboard connected, but old ones seemed cheap, used only two ports and more or less unlimited amount of keys... and except for the sometimes loosing track seems to work well.
| Description: |
|
 Download |
| Filename: |
keyboardtest.tar.gz |
| Filesize: |
19.43 KB |
| Downloaded: |
2736 Time(s) |
|
|
| Back to top |
|
 |
ndudman
Joined: 25 Dec 2008
Posts: 79
|
|
Posted: 17 January 2009, 16:14 PM Post subject: |
|
|
Hi
Perhaps it was easier then I thought ?
I added
| Code: | | dim gaurdCounterStack(1 to 60) as Byte |
along with a new task in the Main()
| Code: | | callTask gaurdCounter(), gaurdCounterStack |
and the sub also
| Code: | '~ ------------------------------------------------------
'~ Anther task which checks if a non 0 value of the counter
'~ remains for a certain period... indicating that then
'~ keyboard is confused and counter should be reset to 0
'~ ------------------------------------------------------
Declare sub reset_kb_bitcount()
sub gaurdCounter() Attribute(used)
do
Dim bitCount as Byte
Dim bitnextCount as Byte
bitCount = get_kb_bitcount()
Call SetInterval(1.0)
call WaitForInterval(0)
bitnextCount = get_kb_bitcount()
if (bitCount = bitnextCount AND bitCount <> 0) then
call reset_kb_bitcount()
Debug.print "ERR"
else
Debug.print "OK"
end if
call delay(1.0)
loop
end sub |
And also a little function to reset the counter in keyboard.c
| Code: | void reset_kb_bitcount(void) {
_kb_bitcount = 0;
} |
Not sure if I have the timing right... but it seems to work. I really like this development enviroment and am enjoying myself
Thanks
Neil
|
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 17 January 2009, 16:22 PM Post subject: Re: AT keyboard - sometimes loosing track of 11 bits |
|
|
| ndudman wrote: | | except for the sometimes loosing track seems to work well. | I believe that the problem is in int0Task(). The issue is that the subroutine callInt() really needs to run to completion every time it is called and, as written, it is not protected from a task switch or an interrupt. If either of these occurs, callInt will probably miss bits.
The problem can be at least partially fixed by modifying int0Task() as shown below. | Code: | Sub int0Task()
Do
Call WaitForInterrupt(zxPinFallingEdge, WaitInt0)
Atomic
Call callInt()
End Atomic
Loop
End Sub |
Of course, the best way to correct the problem is to have the code in callInt() be run as an ISR. The original C code was intended to run that way.
|
|
| Back to top |
|
 |
ndudman
Joined: 25 Dec 2008
Posts: 79
|
|
Posted: 17 January 2009, 22:22 PM Post subject: |
|
|
Thanks Don
So i went back to the origional c code and changed it back to use ISR directly
and enabled the interrupts with the following, this time reading the Atmega datasheet made more sense then the other times.
| Code: | EICRA=(EICRA&0xFC)|(0x02<<ISC00); // Set falling edge
EIMSK=(EIMSK&0xBF)|(0x01<<INT0); // Enable interrupt |
Ive gone about this the long way... reinventing the wheel... but have learnt much about how it works...thanks the help
Neil
|
|
| Back to top |
|
 |
ndudman
Joined: 25 Dec 2008
Posts: 79
|
|
Posted: 17 January 2009, 22:30 PM Post subject: |
|
|
So Ive much simplified the code... after Id compilated it... but one problem remains
At the keyboard.c _kb_buf_get(void)
I had to add a little delay here, didnt know how to do it except call a zbasic sub.
| Code: | while(_kb_buf_count()==0) {
//~ ~ zf_myprint3(_kb_buf_count());
zf_myDelay();
} |
The origional line was
| Code: | | while(_kb_buf_count()==0) ; |
Which I didnt understand why it wouldnt work, my guess was that it need to yeild or something so that the value could actually change perhaps ? Only a crude guess.
Any pointers ?
Thanks
Neil
|
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 17 January 2009, 23:04 PM Post subject: |
|
|
| ndudman wrote: | | I had to add a little delay here, didnt know how to do it except call a zbasic sub. | The WinAVR include files provide a way to invoke approximate millisecond and microsecond delays but are limited to compile-time constant delays. I see now that I should have included these files among the avr-gcc that are installed with ZBasic. You can add them to your installation by extracting the contents of the attached .zip file (preserving pathnames) to the WinAVR/avr/include subdirectory of the ZBasic installation directory. When you're done you should have a file <ZBasic install directory>/WinAvr/avr/include/util/delay.h.
Once that file is present, you can use the delay functions in C code by adding the two lines below near the top of your .c file. | Code: | #define F_CPU 14745600UL
#include <util/delay.h> |
Then, wherever you need a fixed delay, you can realize it as shown below. | Code: | while(_kb_buf_count()==0)
{
_delay_ms(10); // a 10 mS delay
} |
This issue also revealed that the generated build commands should include the definition of F_CPU so that it doesn't have to be added manually as above.
| Description: |
|
 Download |
| Filename: |
AVR_util.zip |
| Filesize: |
16.64 KB |
| Downloaded: |
2720 Time(s) |
|
|
| Back to top |
|
 |
ndudman
Joined: 25 Dec 2008
Posts: 79
|
|
Posted: 18 January 2009, 1:51 AM Post subject: |
|
|
Don
I applied the zip file and made the changes to my c file... however it dosnt work... only with the zf_myDelay(); can I press and see key presses... Im confused...
Neil
|
|
| Back to top |
|
 |
ndudman
Joined: 25 Dec 2008
Posts: 79
|
|
Posted: 18 January 2009, 2:03 AM Post subject: |
|
|
Don
Back to the origional problem I had of loosing track of the bit count(1-11 or so interrupts per keypress)... Im now using the following kind of definition within the keyboard.c file.
I understand that INT0 cant be interrupted by anything else ? so if its loosing track of the count, which it still is (much better though)... where could I have a look ?
Thanks
Neil
|
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 18 January 2009, 3:00 AM Post subject: |
|
|
| ndudman wrote: | | I applied the zip file and made the changes to my c file... however it dosnt work... | Do you mean that it doesn't compile or that it doesn't receive characters properly? If the latter, I'm afraid that I can't be of much help because I don't know why a delay might be needed.
|
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 18 January 2009, 3:21 AM Post subject: |
|
|
| ndudman wrote: | | so if its loosing track of the count, which it still is (much better though)... where could I have a look ? | How are you connecting the PS/2 keyboard signals to the ZX? The circuit diagram in the attached image shows how it should be done. The pullup resistors are essential but the value is not critical; anything in the 1K to 10K range should be fine. It is also essential that the ground of the PS/2 connector be connected to the same ground as the ZX.
| Description: |
|
| Filesize: |
34.33 KB |
| Viewed: |
8313 Time(s) |

|
|
|
| Back to top |
|
 |
|