Bumbum
27.03.2018, 17:33
Hallo,
ich möchte einen G-Sensor und ein paar Taster auswerten und je nach Auswertung Tastatur-Anschläge an ein Raspberry-Pi senden. Meine erste Idee war eine alte Tastatur zu schlachten und an deren Controller einen AVR zu "häckeln".
Da ich aber eh einen Controller benötigte, dachte ich auch ich kann alles in einem machen. Ich habe mich umgesehen und ein Entwickler-Board mit AT90USB646 gefunden. Hier der Schaltplan: http://wiki.in-circuit.de/images/c/c0/610000163A_AT90USB1287-Evalboard.pdf
Das sieht perfekt aus, also habe ich eines bestellt, einen Standard ISP-Programmier-Stecker angelötet und dann mittels meines STK500 den FLIP-Bootloader gelöscht, sowie eine kleine Test-Anwendung installiert. Das funktioniert.
Dann habe ich versucht aus dem Atmel USB-Keyboard-Beispiel das wichtigste herauszuziehen und alles in eine Bibliothek zu konzentrieren. Den Code hänge ich unten an. Leider funktioniert das nicht. Meine onboard-LED blinkt zwar im passenden Takt, am PC wird die Schaltung über USB aber nicht mal gefunden. Es startet keine Hardware-Erkennung oder sonstwas. Auch beim suchen nach Hardware wird nichts gefunden und im Geräte-Manager tauschen keine Geräte auf. Natürlich habe ich mal ein anderes USB-Kabel getestet.
Dann habe ich das Original Atmel-Beispiel wie es ist auf den Controller geflasht mit gleichem negativen Ergebnis. Ich bin jetzt mit meinem Latein am Ende und habe fast den Verdacht auf meiner gekauften Platine ist ein Fehler.
Kann bitte jemand von euch mal meinen Code prüfen und findet eventuell den Fehler? Vielleicht hat ja jemand einen ähnlichen Controller und kann mal verifizieren, ob das funktioniert?
main.c:
#define AVRGCC
#include <avr/io.h>
#include <compiler.h>
#include <util/delay.h>
#include <USB_keyboard.h>
#define onboard_LED_on PORTD = ~(~PORTD | (1<<PD6))
#define onboard_LED_off PORTD = (PORTD | (1<<PD6))
int main(void)
{
DDRA = 0b00000000;
PORTA = 0b11111111;
DDRB = 0b00000000;
PORTB = 0b11111111;
DDRC = 0b00000000;
PORTC = 0b11111111;
DDRD = 0b01000000;
PORTD = 0b11111111;
DDRE = 0b00000000;
PORTE = 0b11111111;
DDRF = 0b00000000;
PORTF = 0b11111111;
onboard_LED_on;
_delay_ms (1000);
onboard_LED_off;
USB_keyboard_init();
U16 Pause = 0;
while (1)
{
USB_keyboard_task();
Pause++;
if (Pause > 1000)
{
USB_keyboard_sendKey (HID_A);
onboard_LED_on;
Pause = 0;
}
else if (Pause > 100)
onboard_LED_off;
_delay_ms (1);
}
}
USB_keyboard.h:
void USB_keyboard_init (void);
void USB_keyboard_task (void);
bool USB_keyboard_sendKey (U8 keyCode);
#define HID_CLASS 0x03
#define HID_SUB_CLASS_BOOT 0x01 //!< Is used to signal the BIOS BOOT support (0=no no sub class,1=boot interface SubClass)
#define HID_PROTOCOL_KEYBOARD 0x01 //!< Protocol keyboard standard
#define HID_PROTOCOL_MOUSE 0x02 //!< Protocol mouse standard
#define SETUP_HID_GET_REPORT 0x01
#define SETUP_HID_GET_IDLE 0x02
#define SETUP_HID_GET_PROTOCOL 0x03
#define SETUP_HID_SET_REPORT 0x09
#define SETUP_HID_SET_IDLE 0x0A
#define SETUP_HID_SET_PROTOCOL 0x0B
#define DESCRIPTOR_HID 0x21
#define DESCRIPTOR_REPORT 0x22
#define DESCRIPTOR_PHYSICAL 0x23
#define REPORT_TYPE_INPUT 0x01
#define REPORT_TYPE_OUTPUT 0x02
#define REPORT_TYPE_FEATURE 0x03
#define HID_BDC 0x0111 //!< Numeric expression identifying the HID Class Specification release (here V1.11)
#define HID_CLASS_DESC_NB_DEFAULT 0x01 //!< Numeric expression specifying the number of class descriptors (always at least one i.e. Report descriptor.)
#define HID_NO_COUNTRY_CODE 0 // Not Supported
#define HID_COUNTRY_ARABIC 1 // Arabic
#define HID_COUNTRY_BELGIAN 2 // Belgian
#define HID_COUNTRY_CANADIAN_BILINGUAL 3 // Canadian-Bilingual
#define HID_COUNTRY_CANADIAN_FRENCH 4 // Canadian-French
#define HID_COUNTRY_CZECH_REPUBLIC 5 // Czech Republic
#define HID_COUNTRY_DANISH 6 // Danish
#define HID_COUNTRY_FINNISH 7 // Finnish
#define HID_COUNTRY_FRENCH 8 // French
#define HID_COUNTRY_GERMAN 9 // German
#define HID_COUNTRY_GREEK 10 // Greek
#define HID_COUNTRY_HEBREW 11 // Hebrew
#define HID_COUNTRY_HUNGARY 12 // Hungary
#define HID_COUNTRY_INTERNATIONAL_ISO 13 // International (ISO)
#define HID_COUNTRY_ITALIAN 14 // Italian
#define HID_COUNTRY_JAPAN_KATAKANA 15 // Japan (Katakana)
#define HID_COUNTRY_KOREAN 16 // Korean
#define HID_COUNTRY_LATIN_AMERICAN 17 // Latin American
#define HID_COUNTRY_NETHERLANDS_DUTCH 18 // Netherlands/Dutch
#define HID_COUNTRY_NORWEGIAN 19 // Norwegian
#define HID_COUNTRY_PERSIAN_FARSI 20 // Persian (Farsi)
#define HID_COUNTRY_POLAND 21 // Poland
#define HID_COUNTRY_PORTUGUESE 22 // Portuguese
#define HID_COUNTRY_RUSSIA 23 // Russia
#define HID_COUNTRY_SLOVAKIA 24 // Slovakia
#define HID_COUNTRY_SPANISH 25 // Spanish
#define HID_COUNTRY_SWEDISH 26 // Swedish
#define HID_COUNTRY_SWISS_FRENCH 27 // Swiss/French
#define HID_COUNTRY_SWISS_GERMAN 28 // Swiss/German
#define HID_COUNTRY_SWITZERLAND 29 // Switzerland
#define HID_COUNTRY_TAIWAN 30 // Taiwan
#define HID_COUNTRY_TURKISH_Q 31 // Turkish-Q
#define HID_COUNTRY_UK 32 // UK
#define HID_COUNTRY_US 33 // US
#define HID_COUNTRY_YUGOSLAVIA 34 // Yugoslavia
#define HID_COUNTRY_TURKISH_F 35 // Turkish-F
#define HID_A 4
#define HID_B 5
#define HID_C 6
#define HID_D 7
#define HID_E 8
#define HID_F 9
#define HID_G 10
#define HID_H 11
#define HID_I 12
#define HID_J 13
#define HID_K 14
#define HID_L 15
#define HID_M 16
#define HID_N 17
#define HID_O 18
#define HID_P 19
#define HID_Q 20
#define HID_R 21
#define HID_S 22
#define HID_T 23
#define HID_U 24
#define HID_V 25
#define HID_W 26
#define HID_X 27
#define HID_Y 28
#define HID_Z 29
#define HID_1 30
#define HID_2 31
#define HID_3 32
#define HID_4 33
#define HID_5 34
#define HID_6 35
#define HID_7 36
#define HID_8 37
#define HID_9 38
#define HID_0 39
#define HID_ENTER 40
#define HID_ESCAPE 41
#define HID_BACKSPACE 42
#define HID_TAB 43
#define HID_SPACEBAR 44
#define HID_UNDERSCORE 45
#define HID_PLUS 46
/*
#define HID_[ { 47
#define HID_] } 48
*/
#define HID_BACKSLASH 49
/*
#define HID_# ~ 50
#define HID_; : 51
#define HID_‘ " 52
*/
#define HID_TILDE 53
#define HID_COMMA 54
#define HID_DOT 55
#define HID_SLASH 56
#define HID_CAPS LOCK 57
#define HID_F1 58
#define HID_F2 59
#define HID_F3 60
#define HID_F4 61
#define HID_F5 62
#define HID_F6 63
#define HID_F7 64
#define HID_F8 65
#define HID_F9 66
#define HID_F10 67
#define HID_F11 68
#define HID_F12 69
#define HID_PRINTSCREEN 70
#define HID_SCROLL LOCK 71
#define HID_PAUSE 72
#define HID_INSERT 73
#define HID_HOME 74
#define HID_PAGEUP 75
#define HID_DELETE 76
#define HID_END 77
#define HID_PAGEDOWN 78
#define HID_RIGHT 79
#define HID_LEFT 80
#define HID_DOWN 81
#define HID_UP 82
#define HID_KEYPAD_NUM_LOCK 83
#define HID_KEYPAD_DIVIDE 84
#define HID_KEYPAD_AT 85
#define HID_KEYPAD_MULTIPLY 85
#define HID_KEYPAD_MINUS 86
#define HID_KEYPAD_PLUS 87
#define HID_KEYPAD_ENTER 88
#define HID_KEYPAD_1 89
#define HID_KEYPAD_2 90
#define HID_KEYPAD_3 91
#define HID_KEYPAD_4 92
#define HID_KEYPAD_5 93
#define HID_KEYPAD_6 94
#define HID_KEYPAD_7 95
#define HID_KEYPAD_8 96
#define HID_KEYPAD_9 97
#define HID_KEYPAD_0 98
#define HID_MODIFIER_NONE 0x00
#define HID_MODIFIER_LEFT_CTRL 0x01
#define HID_MODIFIER_LEFT_SHIFT 0x02
#define HID_MODIFIER_LEFT_ALT 0x04
#define HID_MODIFIER_LEFT_GUI 0x08
#define HID_MODIFIER_RIGHT_CTRL 0x10
#define HID_MODIFIER_RIGHT_SHIFT 0x20
#define HID_MODIFIER_RIGHT_ALT 0x40
#define HID_MODIFIER_RIGHT_GUI 0x80
#define USE_USB_PADS_REGULATOR ENABLE // Possible values ENABLE or DISABLE
#define EP_CONTROL 0
#define TYPE_CONTROL 0
#define NYET_DISABLED 1
#define DIRECTION_OUT 0
#define SIZE_32 2
#define ONE_BANK 0
#define EP_KBD_IN 1 //! Number of the mouse interrupt IN endpoint
#define EVT_USB_POWERED 1 // USB plugged
#define EVT_USB_UNPOWERED 2 // USB un-plugged
#define EVT_USB_DEVICE_FUNCTION 3 // USB in device
#define EVT_USB_HOST_FUNCTION 4 // USB in host
#define EVT_USB_SUSPEND 5 // USB suspend
#define EVT_USB_WAKE_UP 6 // USB wake up
#define EVT_USB_RESUME 7 // USB resume
#define EVT_USB_RESET 8 // USB reset
#define PLLx03 ( (0<<PLLP2) | (0<<PLLP1) | (1<<PLLP0) )
#define Usb_select_endpoint(ep) (UENUM = (U8)ep )
#define Usb_enable_endpoint() (UECONX |= (1<<EPEN))
#define Is_usb_endpoint_enabled() ((UECONX & (1<<EPEN)) ? TRUE : FALSE)
#define Usb_build_ep_config0(type, dir, nyet) ((type<<6) | (nyet<<1) | (dir))
#define Usb_build_ep_config1(size, bank ) ((size<<4) | (bank<<2) )
#define Usb_allocate_memory() (UECFG1X |= (1<<ALLOC))
#define Is_endpoint_configured() ((UESTA0X & (1<<CFGOK)) ? TRUE : FALSE)
#define Usb_enable() (USBCON |= ((1<<USBE) | (1<<OTGPADE)))
#define Usb_disable() (USBCON &= ~((1<<USBE) | (1<<OTGPADE)))
#define Is_usb_sof() ((UDINT & (1<<SOFI)) ? TRUE : FALSE)
#define Usb_ack_sof() (UDINT = ~(1<<SOFI))
#define Is_sof_interrupt_enabled() ((UDIEN & (1<<SOFE)) ? TRUE : FALSE)
#define Is_usb_suspend() ((UDINT & (1<<SUSPI)) ? TRUE : FALSE)
#define Is_suspend_interrupt_enabled() ((UDIEN & (1<<SUSPE)) ? TRUE : FALSE)
#define Usb_disable_suspend_interrupt() (UDIEN &= ~(1<<SUSPE))
#define Usb_enable_suspend_interrupt() (UDIEN |= (1<<SUSPE))
#define Usb_ack_wake_up() (UDINT = ~(1<<WAKEUPI))
#define Usb_enable_wake_up_interrupt() (UDIEN |= (1<<WAKEUPE))
#define Is_usb_wake_up() ((UDINT & (1<<WAKEUPI)) ? TRUE : FALSE)
#define Is_wake_up_interrupt_enabled() ((UDIEN & (1<<WAKEUPE)) ? TRUE : FALSE)
#define Usb_disable_wake_up_interrupt() (UDIEN &= ~(1<<WAKEUPE))
#define Is_usb_resume() ((UDINT & (1<<EORSMI)) ? TRUE : FALSE)
#define Is_resume_interrupt_enabled() ((UDIEN & (1<<EORSME)) ? TRUE : FALSE)
#define Usb_ack_resume() (UDINT = ~(1<<EORSMI))
#define Usb_enable_resume_interrupt() (UDIEN |= (1<<EORSME))
#define Usb_disable_resume_interrupt() (UDIEN &= ~(1<<EORSME))
#define Usb_enable_reset_interrupt() (UDIEN |= (1<<EORSTE))
#define Usb_disable_reset_interrupt() (UDIEN &= ~(1<<EORSTE))
#define Is_reset_interrupt_enabled() ((UDIEN & (1<<EORSTE)) ? TRUE : FALSE)
#define Usb_ack_reset() (UDINT = ~(1<<EORSTI))
#define Is_usb_reset() ((UDINT & (1<<EORSTI)) ? TRUE : FALSE)
#define Is_usb_enabled() ((USBCON & (1<<USBE)) ? TRUE : FALSE)
#define Usb_engine_enable() (USBCON |= (1<<USBE) )
#define Usb_engine_disable() (USBCON &= ~(1<<USBE))
//#define Usb_enable_regulator() (REGCR &= ~(1<<REGDIS))
#define Usb_enable_regulator() (UHWCON |= (1<<UVREGE))
#define Usb_select_device() (USBCON &= ~(1<<HOST))
#define Is_device_enumerated() ((usb_configuration_nb!=0) ? TRUE : FALSE)
#define Is_device_not_enumerated() ((usb_configuration_nb!=0) ? FALSE : TRUE)
#define Is_usb_write_enabled() (UEINTX&(1<<RWAL))
#define Usb_write_byte(byte) (UEDATX = (U8)byte)
#define Usb_send_in() (UEINTX &= ~(1<<FIFOCON))
#define Usb_detach() (UDCON |= (1<<DETACH))
#define Set_power_down_mode() set_power_down_mode()
#define Enter_power_down_mode() (set_power_down_mode())
#define Setup_power_down_mode() (SMCR=0,SMCR |= (1<<SE)+(1<<SM1))
#define Sleep_instruction() {asm("SLEEP");}
#define Start_pll(clockfactor) (PLLCSR = ( clockfactor | (1<<PLLE) ))
#define Stop_pll() (PLLCSR &= (~(1<<PLLE)),PLLCSR=0 )
#define Is_pll_ready() (PLLCSR & (1<<PLOCK) )
#define Wait_pll_ready() while (!(PLLCSR & (1<<PLOCK)))
#define Pll_start_auto() Start_pll(PLLx03)
#define Usb_freeze_clock() (USBCON |= (1<<FRZCLK))
#define Usb_unfreeze_clock() (USBCON &= ~(1<<FRZCLK))
#define Usb_send_event(x) (g_usb_event |= (1<<x))
#define Usb_ack_event(x) (g_usb_event &= ~(1<<x))
#define Usb_clear_all_event() (g_usb_event = 0)
#define Usb_ack_suspend() (UDINT = ~(1<<SUSPI))
#define usb_configure_endpoint(num, type, dir, size, bank, nyet) \
( Usb_select_endpoint(num), \
usb_config_ep(Usb_build_ep_config0(type, dir, nyet),\
Usb_build_ep_config1(size, bank) ))
#define keyBufferSize 8
U8 usb_config_ep (U8, U8);
U8 transmit_no_key;
volatile bit key_hit;
U8 usb_key;
U8 usb_kbd_state;
U8 usb_configuration_nb;
U8 keyBuffer[keyBufferSize];
U8 keyBufferPointer[2] = {0, 0};
volatile U16 g_usb_event;
U8 usb_init_device (void);
void usb_device_task_init (void);
U8 usb_config_ep (U8 config0, U8 config1);
void usb_keyboard_task (void);
void kbd_test_hit (void);
void vbus_off_action (void);
void suspend_action (void);
void set_power_down_mode (void);
void USB_keyboard_init (void)
{
transmit_no_key = FALSE;
key_hit = FALSE;
usb_kbd_state = 0;
#if (USE_USB_PADS_REGULATOR == ENABLE)
Usb_enable_regulator ();
#endif
usb_device_task_init ();
}
bool USB_keyboard_sendKey (U8 keyCode)
{
U8 oldPointer = keyBufferPointer[1];
keyBufferPointer[1]++;
if (keyBufferPointer[1] > keyBufferSize)
keyBufferPointer[1] = 0;
if (keyBufferPointer[0] != keyBufferPointer[1])
{
keyBuffer[keyBufferPointer[1]] = keyCode;
return (TRUE);
}
else
{
keyBufferPointer[1] = oldPointer;
return (FALSE);
}
}
U8 usb_init_device (void)
{
Usb_select_endpoint (EP_CONTROL);
if (!Is_usb_endpoint_enabled ())
return (usb_configure_endpoint (EP_CONTROL, TYPE_CONTROL, DIRECTION_OUT, SIZE_32, ONE_BANK, NYET_DISABLED));
else
return (FALSE);
}
void usb_device_task_init(void)
{
Enable_interrupt ();
Usb_disable ();
Usb_enable ();
Usb_select_device ();
Enable_interrupt ();
}
U8 usb_config_ep(U8 config0, U8 config1)
{
Usb_enable_endpoint();
UECFG0X = config0;
UECFG1X = (UECFG1X & (1<<ALLOC)) | config1;
Usb_allocate_memory();
return (Is_endpoint_configured());
}
void USB_keyboard_task(void)
{
if (Is_device_enumerated())
{
if (key_hit == FALSE)
kbd_test_hit ();
else
{
Usb_select_endpoint(EP_KBD_IN);
if(Is_usb_write_enabled())
{
if (transmit_no_key == FALSE)
{
transmit_no_key = TRUE;
Usb_write_byte(HID_MODIFIER_NONE); // Byte0: Modifier
Usb_write_byte(0); // Byte1: Reserved
Usb_write_byte(usb_key); // Byte2: Keycode 0
Usb_write_byte(0); // Byte2: Keycode 1
Usb_write_byte(0); // Byte2: Keycode 2
Usb_write_byte(0); // Byte2: Keycode 3
Usb_write_byte(0); // Byte2: Keycode 4
Usb_write_byte(0); // Byte2: Keycode 5
Usb_send_in();
return;
}
else
{
key_hit = FALSE;
transmit_no_key = FALSE;
Usb_write_byte(0);
Usb_write_byte(0);
Usb_write_byte(0);
Usb_write_byte(0);
Usb_write_byte(0);
Usb_write_byte(0);
Usb_write_byte(0);
Usb_write_byte(0);
Usb_send_in();
}
}
}
}
}
void kbd_test_hit(void)
{
switch (usb_kbd_state)
{
case 0: { if (keyBufferPointer[0] != keyBufferPointer[1])
usb_kbd_state = 1;
break;}
case 1: { if (keyBufferPointer[0] != keyBufferPointer[1])
{
if ((key_hit == FALSE) && (transmit_no_key == FALSE))
{
usb_key = keyBuffer[keyBufferPointer[0]];
keyBufferPointer[0]++;
key_hit = TRUE;
}
}
else
usb_kbd_state = 0;
break;}
}
}
void vbus_off_action(void)
{
Usb_detach ();
}
void suspend_action(void)
{
Enable_interrupt ();
Enter_power_down_mode ();
}
void set_power_down_mode(void)
{
Setup_power_down_mode ();
Sleep_instruction ();
}
ISR(USB_GEN_vect)
{
if (Is_usb_sof () && Is_sof_interrupt_enabled ())
{
Usb_ack_sof ();
//Usb_sof_action();
}
if (Is_usb_suspend() && Is_suspend_interrupt_enabled())
{
Usb_ack_wake_up ();
Usb_send_event (EVT_USB_SUSPEND);
Usb_ack_suspend ();
Usb_enable_wake_up_interrupt ();
Usb_freeze_clock ();
Stop_pll ();
suspend_action ();
}
if (Is_usb_wake_up () && Is_wake_up_interrupt_enabled ())
{
if (Is_pll_ready() == FALSE)
{
Pll_start_auto ();
Wait_pll_ready ();
}
Usb_unfreeze_clock ();
Usb_ack_wake_up ();
Usb_disable_wake_up_interrupt ();
Usb_send_event (EVT_USB_WAKE_UP);
Usb_enable_suspend_interrupt ();
}
if (Is_usb_resume () && Is_resume_interrupt_enabled ())
{
Usb_disable_wake_up_interrupt ();
Usb_ack_resume ();
Usb_disable_resume_interrupt ();
Usb_send_event (EVT_USB_RESUME);
}
if (Is_usb_reset() && Is_reset_interrupt_enabled ())
{
Usb_ack_reset ();
usb_init_device ();
Usb_send_event (EVT_USB_RESET);
}
}
Viele Grüße,
Andreas
ich möchte einen G-Sensor und ein paar Taster auswerten und je nach Auswertung Tastatur-Anschläge an ein Raspberry-Pi senden. Meine erste Idee war eine alte Tastatur zu schlachten und an deren Controller einen AVR zu "häckeln".
Da ich aber eh einen Controller benötigte, dachte ich auch ich kann alles in einem machen. Ich habe mich umgesehen und ein Entwickler-Board mit AT90USB646 gefunden. Hier der Schaltplan: http://wiki.in-circuit.de/images/c/c0/610000163A_AT90USB1287-Evalboard.pdf
Das sieht perfekt aus, also habe ich eines bestellt, einen Standard ISP-Programmier-Stecker angelötet und dann mittels meines STK500 den FLIP-Bootloader gelöscht, sowie eine kleine Test-Anwendung installiert. Das funktioniert.
Dann habe ich versucht aus dem Atmel USB-Keyboard-Beispiel das wichtigste herauszuziehen und alles in eine Bibliothek zu konzentrieren. Den Code hänge ich unten an. Leider funktioniert das nicht. Meine onboard-LED blinkt zwar im passenden Takt, am PC wird die Schaltung über USB aber nicht mal gefunden. Es startet keine Hardware-Erkennung oder sonstwas. Auch beim suchen nach Hardware wird nichts gefunden und im Geräte-Manager tauschen keine Geräte auf. Natürlich habe ich mal ein anderes USB-Kabel getestet.
Dann habe ich das Original Atmel-Beispiel wie es ist auf den Controller geflasht mit gleichem negativen Ergebnis. Ich bin jetzt mit meinem Latein am Ende und habe fast den Verdacht auf meiner gekauften Platine ist ein Fehler.
Kann bitte jemand von euch mal meinen Code prüfen und findet eventuell den Fehler? Vielleicht hat ja jemand einen ähnlichen Controller und kann mal verifizieren, ob das funktioniert?
main.c:
#define AVRGCC
#include <avr/io.h>
#include <compiler.h>
#include <util/delay.h>
#include <USB_keyboard.h>
#define onboard_LED_on PORTD = ~(~PORTD | (1<<PD6))
#define onboard_LED_off PORTD = (PORTD | (1<<PD6))
int main(void)
{
DDRA = 0b00000000;
PORTA = 0b11111111;
DDRB = 0b00000000;
PORTB = 0b11111111;
DDRC = 0b00000000;
PORTC = 0b11111111;
DDRD = 0b01000000;
PORTD = 0b11111111;
DDRE = 0b00000000;
PORTE = 0b11111111;
DDRF = 0b00000000;
PORTF = 0b11111111;
onboard_LED_on;
_delay_ms (1000);
onboard_LED_off;
USB_keyboard_init();
U16 Pause = 0;
while (1)
{
USB_keyboard_task();
Pause++;
if (Pause > 1000)
{
USB_keyboard_sendKey (HID_A);
onboard_LED_on;
Pause = 0;
}
else if (Pause > 100)
onboard_LED_off;
_delay_ms (1);
}
}
USB_keyboard.h:
void USB_keyboard_init (void);
void USB_keyboard_task (void);
bool USB_keyboard_sendKey (U8 keyCode);
#define HID_CLASS 0x03
#define HID_SUB_CLASS_BOOT 0x01 //!< Is used to signal the BIOS BOOT support (0=no no sub class,1=boot interface SubClass)
#define HID_PROTOCOL_KEYBOARD 0x01 //!< Protocol keyboard standard
#define HID_PROTOCOL_MOUSE 0x02 //!< Protocol mouse standard
#define SETUP_HID_GET_REPORT 0x01
#define SETUP_HID_GET_IDLE 0x02
#define SETUP_HID_GET_PROTOCOL 0x03
#define SETUP_HID_SET_REPORT 0x09
#define SETUP_HID_SET_IDLE 0x0A
#define SETUP_HID_SET_PROTOCOL 0x0B
#define DESCRIPTOR_HID 0x21
#define DESCRIPTOR_REPORT 0x22
#define DESCRIPTOR_PHYSICAL 0x23
#define REPORT_TYPE_INPUT 0x01
#define REPORT_TYPE_OUTPUT 0x02
#define REPORT_TYPE_FEATURE 0x03
#define HID_BDC 0x0111 //!< Numeric expression identifying the HID Class Specification release (here V1.11)
#define HID_CLASS_DESC_NB_DEFAULT 0x01 //!< Numeric expression specifying the number of class descriptors (always at least one i.e. Report descriptor.)
#define HID_NO_COUNTRY_CODE 0 // Not Supported
#define HID_COUNTRY_ARABIC 1 // Arabic
#define HID_COUNTRY_BELGIAN 2 // Belgian
#define HID_COUNTRY_CANADIAN_BILINGUAL 3 // Canadian-Bilingual
#define HID_COUNTRY_CANADIAN_FRENCH 4 // Canadian-French
#define HID_COUNTRY_CZECH_REPUBLIC 5 // Czech Republic
#define HID_COUNTRY_DANISH 6 // Danish
#define HID_COUNTRY_FINNISH 7 // Finnish
#define HID_COUNTRY_FRENCH 8 // French
#define HID_COUNTRY_GERMAN 9 // German
#define HID_COUNTRY_GREEK 10 // Greek
#define HID_COUNTRY_HEBREW 11 // Hebrew
#define HID_COUNTRY_HUNGARY 12 // Hungary
#define HID_COUNTRY_INTERNATIONAL_ISO 13 // International (ISO)
#define HID_COUNTRY_ITALIAN 14 // Italian
#define HID_COUNTRY_JAPAN_KATAKANA 15 // Japan (Katakana)
#define HID_COUNTRY_KOREAN 16 // Korean
#define HID_COUNTRY_LATIN_AMERICAN 17 // Latin American
#define HID_COUNTRY_NETHERLANDS_DUTCH 18 // Netherlands/Dutch
#define HID_COUNTRY_NORWEGIAN 19 // Norwegian
#define HID_COUNTRY_PERSIAN_FARSI 20 // Persian (Farsi)
#define HID_COUNTRY_POLAND 21 // Poland
#define HID_COUNTRY_PORTUGUESE 22 // Portuguese
#define HID_COUNTRY_RUSSIA 23 // Russia
#define HID_COUNTRY_SLOVAKIA 24 // Slovakia
#define HID_COUNTRY_SPANISH 25 // Spanish
#define HID_COUNTRY_SWEDISH 26 // Swedish
#define HID_COUNTRY_SWISS_FRENCH 27 // Swiss/French
#define HID_COUNTRY_SWISS_GERMAN 28 // Swiss/German
#define HID_COUNTRY_SWITZERLAND 29 // Switzerland
#define HID_COUNTRY_TAIWAN 30 // Taiwan
#define HID_COUNTRY_TURKISH_Q 31 // Turkish-Q
#define HID_COUNTRY_UK 32 // UK
#define HID_COUNTRY_US 33 // US
#define HID_COUNTRY_YUGOSLAVIA 34 // Yugoslavia
#define HID_COUNTRY_TURKISH_F 35 // Turkish-F
#define HID_A 4
#define HID_B 5
#define HID_C 6
#define HID_D 7
#define HID_E 8
#define HID_F 9
#define HID_G 10
#define HID_H 11
#define HID_I 12
#define HID_J 13
#define HID_K 14
#define HID_L 15
#define HID_M 16
#define HID_N 17
#define HID_O 18
#define HID_P 19
#define HID_Q 20
#define HID_R 21
#define HID_S 22
#define HID_T 23
#define HID_U 24
#define HID_V 25
#define HID_W 26
#define HID_X 27
#define HID_Y 28
#define HID_Z 29
#define HID_1 30
#define HID_2 31
#define HID_3 32
#define HID_4 33
#define HID_5 34
#define HID_6 35
#define HID_7 36
#define HID_8 37
#define HID_9 38
#define HID_0 39
#define HID_ENTER 40
#define HID_ESCAPE 41
#define HID_BACKSPACE 42
#define HID_TAB 43
#define HID_SPACEBAR 44
#define HID_UNDERSCORE 45
#define HID_PLUS 46
/*
#define HID_[ { 47
#define HID_] } 48
*/
#define HID_BACKSLASH 49
/*
#define HID_# ~ 50
#define HID_; : 51
#define HID_‘ " 52
*/
#define HID_TILDE 53
#define HID_COMMA 54
#define HID_DOT 55
#define HID_SLASH 56
#define HID_CAPS LOCK 57
#define HID_F1 58
#define HID_F2 59
#define HID_F3 60
#define HID_F4 61
#define HID_F5 62
#define HID_F6 63
#define HID_F7 64
#define HID_F8 65
#define HID_F9 66
#define HID_F10 67
#define HID_F11 68
#define HID_F12 69
#define HID_PRINTSCREEN 70
#define HID_SCROLL LOCK 71
#define HID_PAUSE 72
#define HID_INSERT 73
#define HID_HOME 74
#define HID_PAGEUP 75
#define HID_DELETE 76
#define HID_END 77
#define HID_PAGEDOWN 78
#define HID_RIGHT 79
#define HID_LEFT 80
#define HID_DOWN 81
#define HID_UP 82
#define HID_KEYPAD_NUM_LOCK 83
#define HID_KEYPAD_DIVIDE 84
#define HID_KEYPAD_AT 85
#define HID_KEYPAD_MULTIPLY 85
#define HID_KEYPAD_MINUS 86
#define HID_KEYPAD_PLUS 87
#define HID_KEYPAD_ENTER 88
#define HID_KEYPAD_1 89
#define HID_KEYPAD_2 90
#define HID_KEYPAD_3 91
#define HID_KEYPAD_4 92
#define HID_KEYPAD_5 93
#define HID_KEYPAD_6 94
#define HID_KEYPAD_7 95
#define HID_KEYPAD_8 96
#define HID_KEYPAD_9 97
#define HID_KEYPAD_0 98
#define HID_MODIFIER_NONE 0x00
#define HID_MODIFIER_LEFT_CTRL 0x01
#define HID_MODIFIER_LEFT_SHIFT 0x02
#define HID_MODIFIER_LEFT_ALT 0x04
#define HID_MODIFIER_LEFT_GUI 0x08
#define HID_MODIFIER_RIGHT_CTRL 0x10
#define HID_MODIFIER_RIGHT_SHIFT 0x20
#define HID_MODIFIER_RIGHT_ALT 0x40
#define HID_MODIFIER_RIGHT_GUI 0x80
#define USE_USB_PADS_REGULATOR ENABLE // Possible values ENABLE or DISABLE
#define EP_CONTROL 0
#define TYPE_CONTROL 0
#define NYET_DISABLED 1
#define DIRECTION_OUT 0
#define SIZE_32 2
#define ONE_BANK 0
#define EP_KBD_IN 1 //! Number of the mouse interrupt IN endpoint
#define EVT_USB_POWERED 1 // USB plugged
#define EVT_USB_UNPOWERED 2 // USB un-plugged
#define EVT_USB_DEVICE_FUNCTION 3 // USB in device
#define EVT_USB_HOST_FUNCTION 4 // USB in host
#define EVT_USB_SUSPEND 5 // USB suspend
#define EVT_USB_WAKE_UP 6 // USB wake up
#define EVT_USB_RESUME 7 // USB resume
#define EVT_USB_RESET 8 // USB reset
#define PLLx03 ( (0<<PLLP2) | (0<<PLLP1) | (1<<PLLP0) )
#define Usb_select_endpoint(ep) (UENUM = (U8)ep )
#define Usb_enable_endpoint() (UECONX |= (1<<EPEN))
#define Is_usb_endpoint_enabled() ((UECONX & (1<<EPEN)) ? TRUE : FALSE)
#define Usb_build_ep_config0(type, dir, nyet) ((type<<6) | (nyet<<1) | (dir))
#define Usb_build_ep_config1(size, bank ) ((size<<4) | (bank<<2) )
#define Usb_allocate_memory() (UECFG1X |= (1<<ALLOC))
#define Is_endpoint_configured() ((UESTA0X & (1<<CFGOK)) ? TRUE : FALSE)
#define Usb_enable() (USBCON |= ((1<<USBE) | (1<<OTGPADE)))
#define Usb_disable() (USBCON &= ~((1<<USBE) | (1<<OTGPADE)))
#define Is_usb_sof() ((UDINT & (1<<SOFI)) ? TRUE : FALSE)
#define Usb_ack_sof() (UDINT = ~(1<<SOFI))
#define Is_sof_interrupt_enabled() ((UDIEN & (1<<SOFE)) ? TRUE : FALSE)
#define Is_usb_suspend() ((UDINT & (1<<SUSPI)) ? TRUE : FALSE)
#define Is_suspend_interrupt_enabled() ((UDIEN & (1<<SUSPE)) ? TRUE : FALSE)
#define Usb_disable_suspend_interrupt() (UDIEN &= ~(1<<SUSPE))
#define Usb_enable_suspend_interrupt() (UDIEN |= (1<<SUSPE))
#define Usb_ack_wake_up() (UDINT = ~(1<<WAKEUPI))
#define Usb_enable_wake_up_interrupt() (UDIEN |= (1<<WAKEUPE))
#define Is_usb_wake_up() ((UDINT & (1<<WAKEUPI)) ? TRUE : FALSE)
#define Is_wake_up_interrupt_enabled() ((UDIEN & (1<<WAKEUPE)) ? TRUE : FALSE)
#define Usb_disable_wake_up_interrupt() (UDIEN &= ~(1<<WAKEUPE))
#define Is_usb_resume() ((UDINT & (1<<EORSMI)) ? TRUE : FALSE)
#define Is_resume_interrupt_enabled() ((UDIEN & (1<<EORSME)) ? TRUE : FALSE)
#define Usb_ack_resume() (UDINT = ~(1<<EORSMI))
#define Usb_enable_resume_interrupt() (UDIEN |= (1<<EORSME))
#define Usb_disable_resume_interrupt() (UDIEN &= ~(1<<EORSME))
#define Usb_enable_reset_interrupt() (UDIEN |= (1<<EORSTE))
#define Usb_disable_reset_interrupt() (UDIEN &= ~(1<<EORSTE))
#define Is_reset_interrupt_enabled() ((UDIEN & (1<<EORSTE)) ? TRUE : FALSE)
#define Usb_ack_reset() (UDINT = ~(1<<EORSTI))
#define Is_usb_reset() ((UDINT & (1<<EORSTI)) ? TRUE : FALSE)
#define Is_usb_enabled() ((USBCON & (1<<USBE)) ? TRUE : FALSE)
#define Usb_engine_enable() (USBCON |= (1<<USBE) )
#define Usb_engine_disable() (USBCON &= ~(1<<USBE))
//#define Usb_enable_regulator() (REGCR &= ~(1<<REGDIS))
#define Usb_enable_regulator() (UHWCON |= (1<<UVREGE))
#define Usb_select_device() (USBCON &= ~(1<<HOST))
#define Is_device_enumerated() ((usb_configuration_nb!=0) ? TRUE : FALSE)
#define Is_device_not_enumerated() ((usb_configuration_nb!=0) ? FALSE : TRUE)
#define Is_usb_write_enabled() (UEINTX&(1<<RWAL))
#define Usb_write_byte(byte) (UEDATX = (U8)byte)
#define Usb_send_in() (UEINTX &= ~(1<<FIFOCON))
#define Usb_detach() (UDCON |= (1<<DETACH))
#define Set_power_down_mode() set_power_down_mode()
#define Enter_power_down_mode() (set_power_down_mode())
#define Setup_power_down_mode() (SMCR=0,SMCR |= (1<<SE)+(1<<SM1))
#define Sleep_instruction() {asm("SLEEP");}
#define Start_pll(clockfactor) (PLLCSR = ( clockfactor | (1<<PLLE) ))
#define Stop_pll() (PLLCSR &= (~(1<<PLLE)),PLLCSR=0 )
#define Is_pll_ready() (PLLCSR & (1<<PLOCK) )
#define Wait_pll_ready() while (!(PLLCSR & (1<<PLOCK)))
#define Pll_start_auto() Start_pll(PLLx03)
#define Usb_freeze_clock() (USBCON |= (1<<FRZCLK))
#define Usb_unfreeze_clock() (USBCON &= ~(1<<FRZCLK))
#define Usb_send_event(x) (g_usb_event |= (1<<x))
#define Usb_ack_event(x) (g_usb_event &= ~(1<<x))
#define Usb_clear_all_event() (g_usb_event = 0)
#define Usb_ack_suspend() (UDINT = ~(1<<SUSPI))
#define usb_configure_endpoint(num, type, dir, size, bank, nyet) \
( Usb_select_endpoint(num), \
usb_config_ep(Usb_build_ep_config0(type, dir, nyet),\
Usb_build_ep_config1(size, bank) ))
#define keyBufferSize 8
U8 usb_config_ep (U8, U8);
U8 transmit_no_key;
volatile bit key_hit;
U8 usb_key;
U8 usb_kbd_state;
U8 usb_configuration_nb;
U8 keyBuffer[keyBufferSize];
U8 keyBufferPointer[2] = {0, 0};
volatile U16 g_usb_event;
U8 usb_init_device (void);
void usb_device_task_init (void);
U8 usb_config_ep (U8 config0, U8 config1);
void usb_keyboard_task (void);
void kbd_test_hit (void);
void vbus_off_action (void);
void suspend_action (void);
void set_power_down_mode (void);
void USB_keyboard_init (void)
{
transmit_no_key = FALSE;
key_hit = FALSE;
usb_kbd_state = 0;
#if (USE_USB_PADS_REGULATOR == ENABLE)
Usb_enable_regulator ();
#endif
usb_device_task_init ();
}
bool USB_keyboard_sendKey (U8 keyCode)
{
U8 oldPointer = keyBufferPointer[1];
keyBufferPointer[1]++;
if (keyBufferPointer[1] > keyBufferSize)
keyBufferPointer[1] = 0;
if (keyBufferPointer[0] != keyBufferPointer[1])
{
keyBuffer[keyBufferPointer[1]] = keyCode;
return (TRUE);
}
else
{
keyBufferPointer[1] = oldPointer;
return (FALSE);
}
}
U8 usb_init_device (void)
{
Usb_select_endpoint (EP_CONTROL);
if (!Is_usb_endpoint_enabled ())
return (usb_configure_endpoint (EP_CONTROL, TYPE_CONTROL, DIRECTION_OUT, SIZE_32, ONE_BANK, NYET_DISABLED));
else
return (FALSE);
}
void usb_device_task_init(void)
{
Enable_interrupt ();
Usb_disable ();
Usb_enable ();
Usb_select_device ();
Enable_interrupt ();
}
U8 usb_config_ep(U8 config0, U8 config1)
{
Usb_enable_endpoint();
UECFG0X = config0;
UECFG1X = (UECFG1X & (1<<ALLOC)) | config1;
Usb_allocate_memory();
return (Is_endpoint_configured());
}
void USB_keyboard_task(void)
{
if (Is_device_enumerated())
{
if (key_hit == FALSE)
kbd_test_hit ();
else
{
Usb_select_endpoint(EP_KBD_IN);
if(Is_usb_write_enabled())
{
if (transmit_no_key == FALSE)
{
transmit_no_key = TRUE;
Usb_write_byte(HID_MODIFIER_NONE); // Byte0: Modifier
Usb_write_byte(0); // Byte1: Reserved
Usb_write_byte(usb_key); // Byte2: Keycode 0
Usb_write_byte(0); // Byte2: Keycode 1
Usb_write_byte(0); // Byte2: Keycode 2
Usb_write_byte(0); // Byte2: Keycode 3
Usb_write_byte(0); // Byte2: Keycode 4
Usb_write_byte(0); // Byte2: Keycode 5
Usb_send_in();
return;
}
else
{
key_hit = FALSE;
transmit_no_key = FALSE;
Usb_write_byte(0);
Usb_write_byte(0);
Usb_write_byte(0);
Usb_write_byte(0);
Usb_write_byte(0);
Usb_write_byte(0);
Usb_write_byte(0);
Usb_write_byte(0);
Usb_send_in();
}
}
}
}
}
void kbd_test_hit(void)
{
switch (usb_kbd_state)
{
case 0: { if (keyBufferPointer[0] != keyBufferPointer[1])
usb_kbd_state = 1;
break;}
case 1: { if (keyBufferPointer[0] != keyBufferPointer[1])
{
if ((key_hit == FALSE) && (transmit_no_key == FALSE))
{
usb_key = keyBuffer[keyBufferPointer[0]];
keyBufferPointer[0]++;
key_hit = TRUE;
}
}
else
usb_kbd_state = 0;
break;}
}
}
void vbus_off_action(void)
{
Usb_detach ();
}
void suspend_action(void)
{
Enable_interrupt ();
Enter_power_down_mode ();
}
void set_power_down_mode(void)
{
Setup_power_down_mode ();
Sleep_instruction ();
}
ISR(USB_GEN_vect)
{
if (Is_usb_sof () && Is_sof_interrupt_enabled ())
{
Usb_ack_sof ();
//Usb_sof_action();
}
if (Is_usb_suspend() && Is_suspend_interrupt_enabled())
{
Usb_ack_wake_up ();
Usb_send_event (EVT_USB_SUSPEND);
Usb_ack_suspend ();
Usb_enable_wake_up_interrupt ();
Usb_freeze_clock ();
Stop_pll ();
suspend_action ();
}
if (Is_usb_wake_up () && Is_wake_up_interrupt_enabled ())
{
if (Is_pll_ready() == FALSE)
{
Pll_start_auto ();
Wait_pll_ready ();
}
Usb_unfreeze_clock ();
Usb_ack_wake_up ();
Usb_disable_wake_up_interrupt ();
Usb_send_event (EVT_USB_WAKE_UP);
Usb_enable_suspend_interrupt ();
}
if (Is_usb_resume () && Is_resume_interrupt_enabled ())
{
Usb_disable_wake_up_interrupt ();
Usb_ack_resume ();
Usb_disable_resume_interrupt ();
Usb_send_event (EVT_USB_RESUME);
}
if (Is_usb_reset() && Is_reset_interrupt_enabled ())
{
Usb_ack_reset ();
usb_init_device ();
Usb_send_event (EVT_USB_RESET);
}
}
Viele Grüße,
Andreas