|<><><><><> Original message from Ronald G Minnich <><><><><> |keyboard issues: the following code hangs right now: | |void |pc_keyboard_reset() |{ | volatile unsigned char regval; | /* reset any keyboard interrupts ... */ | (void) inb(0x60);
This flushes any pending output byte (output from the PS/2 controller perspective). Check.
| /* test loop ... delete this when things seem to work ... */ | regval = inb(0x64);
Read the status. check.
| display("regval from kb is "); printint(regval); display("\n"); | regval &= 4; | outb(0xaa, 0x64);
Output the selftest command. Before you do this you should ensure that bit 1 (mask 0x02) is clear, otherwise the write of AA will be ignored.
| while ((inb(0x64) & 1) == 0) | ;
Wait for the response byte. check. But... we need to place a delay between each iteration of the loop. Otherwise the PS/2 controller (an 8048 in disguise) will be to busy updating the status register to complete the selftest. Depends upon the PS/2 controller though.
| display("0x60 has "); printint(inb(0x60)); display("\n");
Print it out. It should be 0x55, otherwise you will need to send the selftest command again.
| outb(0x60, 0x64);
Output WRITE command, we're going to send a command to the PS/2 controller. You need to check bit 1 again before you send this WRITE command otherwise the PS/2 controller may not be ready for it yet.
| /* this test was 2, but it never worked, try 1 */ | while((inb(0x64) & 1) == 0) | ;
Were spining waiting for the PS/2 controller to give us a byte. The PS/2 controller is spining waiting for us to write the command. Deadlock. The test about really should be on '& 2'. If it doesn't complete it is because you didn't spin on '& 2' before outputing the WRITE command.
| outb(0x61 | regval, 0x60); | /* this test was 2, but it never worked, try 1 */
Write the command. I'm not sure what you're attempting to do here. bit 6 will enable PC/XT scan code conversion, otherwise you'll get PC/AT scan codes. You're also enabling PS/2 keyboard interrupts bit 0.
| while((inb(0x64) & 1) == 0) | ;
Wait for the PS/2 controller to have accepted the command. You need to spin on '& 2' though.
General rules for talking to a PS/2 controller. Before writing to either the control or data port spin waiting for bit 1 of the status port to be zero. Before reading the data port. spin waiting for bit 0 of the status port to be one. If you know that you have a PS/2 interrupt you can break the second rule, but you should check the status port to ensure that you don't have a suprious interrupt.
Thomas J. Merritt tjm@codegen.com 1-415-834-9111 - To unsubscribe: send mail to majordomo@freiburg.linux.de with 'unsubscribe openbios' in the body of the message