AT keyboard - sometimes loosing track of 11 bits
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.
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.
- Attachments
-
- keyboardtest.tar.gz
- (19.43 KiB) Downloaded 3072 times
Hi
Perhaps it was easier then I thought ?
I added
along with a new task in the Main()
and the sub also
And also a little function to reset the counter in keyboard.c
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
Perhaps it was easier then I thought ?
I added
Code: Select all
dim gaurdCounterStack(1 to 60) as Byte
Code: Select all
callTask gaurdCounter(), gaurdCounterStack
Code: Select all
'~ ------------------------------------------------------
'~ 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
Code: Select all
void reset_kb_bitcount(void) {
_kb_bitcount = 0;
}
Thanks
Neil
Re: AT keyboard - sometimes loosing track of 11 bits
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.ndudman wrote:except for the sometimes loosing track seems to work well.
The problem can be at least partially fixed by modifying int0Task() as shown below.
Code: Select all
Sub int0Task()
Do
Call WaitForInterrupt(zxPinFallingEdge, WaitInt0)
Atomic
Call callInt()
End Atomic
Loop
End Sub
- Don Kinzer
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.
Ive gone about this the long way... reinventing the wheel... but have learnt much about how it works...thanks the help
Neil
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: Select all
EICRA=(EICRA&0xFC)|(0x02<<ISC00); // Set falling edge
EIMSK=(EIMSK&0xBF)|(0x01<<INT0); // Enable interrupt
Neil
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.
The origional line was
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
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: Select all
while(_kb_buf_count()==0) {
//~ ~ zf_myprint3(_kb_buf_count());
zf_myDelay();
}
Code: Select all
while(_kb_buf_count()==0) ;
Any pointers ?
Thanks
Neil
Code: Select all
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.ndudman wrote:I had to add a little delay here, didnt know how to do it except call a zbasic sub.
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: Select all
#define F_CPU 14745600UL
#include <util/delay.h>
Code: Select all
while(_kb_buf_count()==0)
{
_delay_ms(10); // a 10 mS delay
}
- Attachments
-
- AVR_util.zip
- (16.64 KiB) Downloaded 3016 times
- Don Kinzer
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 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.
Code: Select all
ISR(INT0_vect) {
Thanks
Neil
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.ndudman wrote:so if its loosing track of the count, which it still is (much better though)... where could I have a look ?
- Attachments
-
- PS2_Connection.jpg (34.33 KiB) Viewed 10510 times
- Don Kinzer