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/c...-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:

Code:
#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:

Code:
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