V-USB on ATMega162/12MHz - Basic Keyboard Functionality
Posted: Mon Mar 22, 2010 11:11 pm
Hello,
I've taken the most basic example of HID Keyboard example from V-USB to frankenstein together the most basic of interface panels.
Think of it as a LCD with function keys around it. The ATMega162 keyscans the user defined buttons and the V-USB soft-core sends USB messaging to a Windows PC who thinks its a keyboard.
The V-USB keyboard functionality works great with messaging being sent and received by the PC. Some of the keys tell the MCU to bit-bang serial data off to the LCD to do things like brightness/contrast and so forth. Inside the for(;;) where the USB stuff resides, there is a keyscan routine that scans rows/colums to determine what buttons you pressed and acts accordingly.
The problem is this, if pressing key 1 returns 0x31 saying ascii '7' V-USB transmits it. If you press a key that has to invoke a function that has to toggle an IO to emulate serial data, its like it gets skipped over completely.
vusb_preenble contains things like the 300ms disconnect, odDebugInit, usbInit(), sei(), DBG1(0x00,0,0) and so on.
A snipped of keypressed is shown below.
The function TogglePD0() can be something simple like blink an LED or use a simple bit-bang example for faking serial data.
It is totally bypassed. The function was tested separately before being included.
Comments welcome!
I've taken the most basic example of HID Keyboard example from V-USB to frankenstein together the most basic of interface panels.
Think of it as a LCD with function keys around it. The ATMega162 keyscans the user defined buttons and the V-USB soft-core sends USB messaging to a Windows PC who thinks its a keyboard.
The V-USB keyboard functionality works great with messaging being sent and received by the PC. Some of the keys tell the MCU to bit-bang serial data off to the LCD to do things like brightness/contrast and so forth. Inside the for(;;) where the USB stuff resides, there is a keyscan routine that scans rows/colums to determine what buttons you pressed and acts accordingly.
The problem is this, if pressing key 1 returns 0x31 saying ascii '7' V-USB transmits it. If you press a key that has to invoke a function that has to toggle an IO to emulate serial data, its like it gets skipped over completely.
Code: Select all
main.c {
vusb_preemble();
for(;;){
wdt_reset();
usbPoll();
//BlinkFault();
key = keyPressed();
if(lastKey != key)
{
lastKey = key;
keyDidChange = 1;
}
if(TIFR & (1<<TOV0))
{ // 22 ms timer
TIFR = 1<<TOV0;
if(idleRate != 0)
{
if(idleCounter > 4)
{
idleCounter -= 5; // 22 ms in units of 4 ms
}
else
{
idleCounter = idleRate;
keyDidChange = 1;
}
}
}
if(keyDidChange && usbInterruptIsReady())
{
keyDidChange = 0;
// use last key and not current key status in order to avoid lost
// changes in key status.
buildReport(lastKey);
usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
} */
}
}
vusb_preenble contains things like the 300ms disconnect, odDebugInit, usbInit(), sei(), DBG1(0x00,0,0) and so on.
A snipped of keypressed is shown below.
Code: Select all
static uchar keyPressed(void)
{
uchar ch = 0;
// First Column
output_low(PORTD, KEYPIN1);
output_high(PORTB, KEYPIN7);
output_high(PORTB, KEYPIN8);
output_high(PORTB, KEYPIN9);
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
if (sw_is_pressed(PIND,KEYPIN2)) { ch = KEY_A; } // SW02: 'TEST'
if (sw_is_pressed(PIND,KEYPIN3)) { ch = KEY_B; } // SW04: '2'
if (sw_is_pressed(PIND,KEYPIN4)) { TogglePD0(); } // SW05: '3'
if (sw_is_pressed(PINB,KEYPIN10)) { ch = KEY_D; } // SW07: '5'
if (sw_is_pressed(PINA,KEYPIN11)) { ch = KEY_E; } // SW08: '6'
if (sw_is_pressed(PINA,KEYPIN12)) { ch = KEY_F; } // SW10: '8'
if (sw_is_pressed(PINA,KEYPIN13)) { ch = KEY_G; } // SW11: '9'
return ch;
}
The function TogglePD0() can be something simple like blink an LED or use a simple bit-bang example for faking serial data.
It is totally bypassed. The function was tested separately before being included.
Comments welcome!