2011/08/08

AVR271: USB Keyboard Demonstration on megaAVR with USB-01

자 키보드 만들어 보자...야무지게



시작은 심히 미약하구나
일단 12X7=84 키 매트릭스를 만들어서 테스트해봤다.

싱글 키 스캔은 완료했다. keyboard_task.c의 kbd_test_hit 함수를 수정하면 싱글 키스캔은 돌아간다.


void kbd_test_hit(void)
{
//20110807 --> added
unsigned char i=0, i_Pre=0, in=0, in_Pre=0;

PORTB = 0xFF;
PORTA = 0xFF;

Key_Scan:
for(i=0;i<12;i++){
if(i < 8)
PORTB = ~(0x01 << i);
else
PORTA = ~(0x01 << (i-8));

_NOP();_NOP();_NOP();_NOP();
in = ~PINC;

PORTB = 0xFF;
PORTA = 0xFF;

if(in){
if(i_Pre == i && in_Pre == in)
goto Key_Value;
else{
i_Pre = i;
in_Pre = in;
goto Key_Scan;
}
}
}

//Key 신호 없음 구간 -->
//키 홀딩, 홀딩 카운트, 연속입력, 키 갱신 신호 초기화.
Key_No:
state_HOLD = 0;
same_Count = 0;
Key_con = 0;
Key_update = 0;
usb_kbd_state = 0;
goto ROUTINE_OUT;
//<-- Key 신호 없음 구간

//Key 위치 판정 구간 -->
Key_Value://Key 위치 판정
if(in & _BV(0)){
if(i == 0)usb_key=HID_F11;
else if(i==1)usb_key=HID_F10;
else if(i==2)usb_key=HID_F9;
else if(i==3)usb_key=HID_F8;
else if(i==4)usb_key=HID_F7;
else if(i==5)usb_key=HID_F6;
else if(i==6)usb_key=HID_F5;
else if(i==7)usb_key=HID_F4;
else if(i==8)usb_key=HID_F3;
else if(i==9)usb_key=HID_F2;
else if(i==10)usb_key=HID_F1;
else if(i==11)usb_key=HID_ESCAPE;
}
else if(in & _BV(1)){
if(i == 0)usb_key=HID_UNDERSCORE;
else if(i==1)usb_key=HID_0;
else if(i==2)usb_key=HID_9;
else if(i==3)usb_key=HID_8;
else if(i==4)usb_key=HID_7;
else if(i==5)usb_key=HID_6;
else if(i==6)usb_key=HID_5;
else if(i==7)usb_key=HID_4;
else if(i==8)usb_key=HID_3;
else if(i==9)usb_key=HID_2;
else if(i==10)usb_key=HID_1;
else if(i==11)usb_key=HID_TILDE;
}
else if(in & _BV(2)){
if(i == 0)usb_key=47;
else if(i==1)usb_key=HID_P;
else if(i==2)usb_key=HID_O;
else if(i==3)usb_key=HID_I;
else if(i==4)usb_key=HID_U;
else if(i==5)usb_key=HID_Y;
else if(i==6)usb_key=HID_T;
else if(i==7)usb_key=HID_R;
else if(i==8)usb_key=HID_E;
else if(i==9)usb_key=HID_W;
else if(i==10)usb_key=HID_Q;
else if(i==11)usb_key=HID_TAB;
}
else if(in & _BV(3)){
if(i == 0)usb_key=52;
else if(i==1)usb_key=51;
else if(i==2)usb_key=HID_L;
else if(i==3)usb_key=HID_K;
else if(i==4)usb_key=HID_J;
else if(i==5)usb_key=HID_H;
else if(i==6)usb_key=HID_G;
else if(i==7)usb_key=HID_F;
else if(i==8)usb_key=HID_D;
else if(i==9)usb_key=HID_S;
else if(i==10)usb_key=HID_A;
else if(i==11)usb_key=HID_MODIFIER_LEFT_CTRL;
}
else if(in & _BV(4)){
if(i == 0)usb_key=HID_MODIFIER_RIGHT_SHIFT;
else if(i==1)usb_key=HID_SLASH;
else if(i==2)usb_key=HID_DOT;
else if(i==3)usb_key=HID_COMMA;
else if(i==4)usb_key=HID_M;
else if(i==5)usb_key=HID_N;
else if(i==6)usb_key=HID_B;
else if(i==7)usb_key=HID_V;
else if(i==8)usb_key=HID_C;
else if(i==9)usb_key=HID_X;
else if(i==10)usb_key=HID_Z;
else if(i==11)usb_key=HID_MODIFIER_LEFT_SHIFT;
}
else if(in & _BV(5)){
if(i == 0)usb_key=HID_F12;
else if(i==1)usb_key=HID_BACKSPACE;
else if(i==2)usb_key=HID_PLUS;
else if(i==3)usb_key=HID_DELETE;
else if(i==4)usb_key=HID_END;
else if(i==5)usb_key=HID_HOME;
else if(i==6)usb_key=HID_MODIFIER_RIGHT_CTRL;
else if(i==7)usb_key=HID_MODIFIER_LEFT_ALT;
else if(i==8)usb_key=HID_SPACEBAR;
else if(i==9)usb_key=HID_MODIFIER_RIGHT_ALT;
else if(i==10)usb_key=HID_MODIFIER_RIGHT_GUI;
else if(i==11)usb_key=HID_CAPSLOCK;
}
else if(in & _BV(6)){
if(i == 0)usb_key=HID_RIGHT;
else if(i==1)usb_key=HID_DOWN;
else if(i==2)usb_key=HID_UP;
else if(i==3)usb_key=HID_LEFT;
else if(i==4)usb_key=HID_ENTER;
}
else{
//중첩키 구간 -->
goto Key_No;
//<-- 중첩키 구간
}

Key_Continuous://Key 입력 상태 판정
if(state_HOLD){//Key Holding state.
if(!Key_con){//<-- 연속 입력 상태 아님
if(same_Count < 10000){//30
same_Count++;
goto ROUTINE_OUT;
}
else{
same_Count = 0;
Key_con = 1;
Key_update = 1;
usb_data_to_send++;
usb_kbd_state = 1;
goto KEY_UPDATE;
}
}
else{//<-- 연속 입력 상태
if(same_Count < 1000){//10
same_Count++;
goto ROUTINE_OUT;
}
else{
same_Count = 0;
Key_update = 1;
usb_data_to_send++;
usb_kbd_state = 1;
goto KEY_UPDATE;
}
}
}
else{//Key First_IN state
state_HOLD = 1;
same_Count = 0;
pre_Key = cur_Key;
Key_con = 0;
Key_update = 1;
usb_data_to_send++;
usb_kbd_state = 1;
goto KEY_UPDATE;
}

KEY_UPDATE:
if(Key_update){
usb_data_to_send --;
key_hit = TRUE;
}
Key_update = 0;

ROUTINE_OUT:
_NOP();
//<-- 20110807
}

다음 할 일은 멀티 키스캔이지...

그리고 HID modifier 사용법도 심도있게 살펴봐야것군.
쉬프트나 컨트롤 쓸라면 이걸 알아야되는거 같애..

아차 한영변환은???

댓글 2개:

  1. USB HID Keyboard 관련 정보를 찾다가 왔어요.

    USB KEYBOARD구현하시려면 LUFA 라이브러리를 이용해보는건 어떠세요?

    http://www.fourwalledcubicle.com/LUFA.php

    DEMO도 있고 USB 관련하여 다양한 예제를 확인할 수 있네요.. 물론 AVR USB칩에 맞춰져 있구요^^

    답글삭제
  2. 넵 USB 소프트 스택도 훌륭하죠.^^

    답글삭제