From 8dfa9f84592c93ac016344226573de234e176da8 Mon Sep 17 00:00:00 2001 From: Thibault RICHARD Date: Mon, 30 Apr 2012 19:34:27 +0200 Subject: [PATCH 1/2] [SAM] USB device stack updated. Failing at configuration descriptor stage. --- hardware/arduino/sam/cores/sam/USB/CDC.cpp | 10 +- hardware/arduino/sam/cores/sam/USB/HID.cpp | 2 + hardware/arduino/sam/cores/sam/USB/USBAPI.h | 7 +- .../arduino/sam/cores/sam/USB/USBCore.cpp | 108 +++++--- hardware/arduino/sam/cores/sam/USB/USBCore.h | 2 + hardware/arduino/sam/cores/sam/USB/USBDesc.h | 30 +-- hardware/arduino/sam/cores/sam/main.cpp | 4 + .../validation_usb_device/test_usb_device.cpp | 10 +- .../arduino/sam/system/libsam/source/uotghs.c | 233 ++++++++++++++---- .../sam/variants/arduino_due_x/variant.cpp | 2 + 10 files changed, 294 insertions(+), 114 deletions(-) diff --git a/hardware/arduino/sam/cores/sam/USB/CDC.cpp b/hardware/arduino/sam/cores/sam/USB/CDC.cpp index dbd442702..e79f7352f 100644 --- a/hardware/arduino/sam/cores/sam/USB/CDC.cpp +++ b/hardware/arduino/sam/cores/sam/USB/CDC.cpp @@ -25,9 +25,9 @@ struct ring_buffer { - unsigned char buffer[CDC_SERIAL_BUFFER_SIZE]; - volatile int head; - volatile int tail; + uint8_t buffer[CDC_SERIAL_BUFFER_SIZE]; + volatile uint32_t head; + volatile uint32_t tail; }; ring_buffer cdc_rx_buffer = { { 0 }, 0, 0}; @@ -138,8 +138,8 @@ void Serial_::end(void) void Serial_::accept(void) { ring_buffer *buffer = &cdc_rx_buffer; - int c = USBD_Recv(CDC_RX); - int i = (unsigned int)(buffer->head+1) % SERIAL_BUFFER_SIZE; + uint32_t c = USBD_Recv(CDC_RX); + uint32_t i = (uint32_t)(buffer->head+1) % SERIAL_BUFFER_SIZE; // if we should be storing the received character into the location // just before the tail (meaning that the head would advance to the diff --git a/hardware/arduino/sam/cores/sam/USB/HID.cpp b/hardware/arduino/sam/cores/sam/USB/HID.cpp index c0eee1b4f..c50dfab35 100644 --- a/hardware/arduino/sam/cores/sam/USB/HID.cpp +++ b/hardware/arduino/sam/cores/sam/USB/HID.cpp @@ -122,12 +122,14 @@ extern const uint8_t _hidReportDescriptor[] = { #endif }; +_Pragma("pack(1)") extern const HIDDescriptor _hidInterface = { D_INTERFACE(HID_INTERFACE,1,3,0,0), D_HIDREPORT(sizeof(_hidReportDescriptor)), D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01) }; +_Pragma("pack()") //================================================================================ //================================================================================ diff --git a/hardware/arduino/sam/cores/sam/USB/USBAPI.h b/hardware/arduino/sam/cores/sam/USB/USBAPI.h index 46bc6d7a3..078ac0fe6 100644 --- a/hardware/arduino/sam/cores/sam/USB/USBAPI.h +++ b/hardware/arduino/sam/cores/sam/USB/USBAPI.h @@ -204,13 +204,12 @@ int USBD_RecvControl(void* d, uint32_t len); int USBD_SendInterfaces(void); bool USBD_ClassInterfaceRequest(Setup& setup); -uint32_t USBD_Recv(uint32_t ep, void* d, uint32_t len); -uint8_t USBD_Recv8(uint32_t ep); + uint32_t USBD_Available(uint32_t ep); uint32_t USBD_SendSpace(uint32_t ep); uint32_t USBD_Send(uint32_t ep, const void* d, uint32_t len); -int USBD_Recv(uint8_t ep, void* data, uint32_t len); // non-blocking -int USBD_Recv(uint8_t ep); // non-blocking +uint32_t USBD_Recv(uint32_t ep, void* data, uint32_t len); // non-blocking +uint32_t USBD_Recv(uint32_t ep); // non-blocking void USBD_Flush(uint32_t ep); uint32_t USBD_Connected(void); diff --git a/hardware/arduino/sam/cores/sam/USB/USBCore.cpp b/hardware/arduino/sam/cores/sam/USB/USBCore.cpp index fdd585d15..60d9d18be 100644 --- a/hardware/arduino/sam/cores/sam/USB/USBCore.cpp +++ b/hardware/arduino/sam/cores/sam/USB/USBCore.cpp @@ -16,6 +16,7 @@ #include "Arduino.h" #include "USBAPI.h" +#include const uint32_t _initEndpoints[] = { @@ -115,21 +116,6 @@ uint32_t USBD_Available(uint32_t ep) return UDD_FifoByteCount(); } -// Recv 1 byte if ready -/*uint8_t USBD_Recv8(uint32_t ep) -{ - uint8_t c; - - if (USBD_Recv(ep, &c, 1) != 1) - { - return -1; - } - else - { - return c; - } -}*/ - // Non Blocking receive // Return number of bytes read uint32_t USBD_Recv(uint32_t ep, void* d, uint32_t len) @@ -150,6 +136,16 @@ uint32_t USBD_Recv(uint32_t ep, void* d, uint32_t len) return len; } +// Recv 1 byte if ready +uint32_t USBD_Recv(uint32_t ep) +{ + uint8_t c; + if (USBD_Recv(ep, &c, 1) != 1) + return -1; + else + return c; +} + // Space in send EP uint32_t USBD_SendSpace(uint32_t ep) { @@ -223,7 +219,10 @@ static bool USBD_SendControl(uint8_t d) UDD_Send8(d); if (!((_cmark + 1) & 0x3F)) + { + puts("Sent!\r\n"); UDD_ClearIN(); // Fifo is full, release this packet + } } _cmark++; return true; @@ -291,6 +290,7 @@ int USBD_SendInterfaces(void) total += HID_GetInterface(&interfaces) ; #endif + printf("=> USBD_SendInterfaces, total=%d interfaces=%d\r\n", total, interfaces); return interfaces; } @@ -301,8 +301,15 @@ static bool USBD_SendConfiguration(int maxlen) { // Count and measure interfaces USBD_InitControl(0); + printf("=> USBD_SendConfiguration _cmark1=%d\r\n", _cmark); int interfaces = USBD_SendInterfaces(); + printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark); + printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor)); + +_Pragma("pack(1)") ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces); +_Pragma("pack()") + printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen); // Now send them USBD_InitControl(maxlen); @@ -318,28 +325,32 @@ static bool USBD_SendDescriptor(Setup& setup) const uint8_t* desc_addr = 0; if ( USB_CONFIGURATION_DESCRIPTOR_TYPE == t ) - { + { + printf("=> USBD_SendDescriptor : USB_CONFIGURATION_DESCRIPTOR_TYPE length=%d\r\n", setup.wLength); return USBD_SendConfiguration(setup.wLength); - } + } USBD_InitControl(setup.wLength); #ifdef HID_ENABLED if ( HID_REPORT_DESCRIPTOR_TYPE == t ) - { + { + puts("=> USBD_SendDescriptor : HID_REPORT_DESCRIPTOR_TYPE\r\n"); return HID_GetDescriptor( t ) ; - } + } #endif if (USB_DEVICE_DESCRIPTOR_TYPE == t) { + puts("=> USBD_SendDescriptor : USB_DEVICE_DESCRIPTOR_TYPE\r\n"); if ( setup.wLength == 8 ) - { + { _cdcComposite = 1; - } + } desc_addr = _cdcComposite ? (const uint8_t*)&USB_DeviceDescriptorA : (const uint8_t*)&USB_DeviceDescriptor; } else if (USB_STRING_DESCRIPTOR_TYPE == t) { + puts("=> USBD_SendDescriptor : USB_STRING_DESCRIPTOR_TYPE\r\n"); if (setup.wValueL == 0) desc_addr = (const uint8_t*)&STRING_LANGUAGE; else if (setup.wValueL == IPRODUCT) @@ -351,26 +362,33 @@ static bool USBD_SendDescriptor(Setup& setup) } if ( desc_addr == 0 ) - { + { return false ; - } + } if ( desc_length == 0 ) - { + { desc_length = *desc_addr; - } + } + printf("=> USBD_SendDescriptor : desc_addr=%x desc_length=%d\r\n", desc_addr, desc_length); USBD_SendControl(0, desc_addr, desc_length); return true; } +volatile int cpt = 0; + // Endpoint 0 interrupt static void USB_ISR(void) { + while (cpt++ > 100) + ; + // End of Reset if (Is_udd_reset()) { + printf(">>> End of Reset\r\n"); // Reset USB address to 0 udd_configure_address(0); udd_enable_address(); @@ -384,11 +402,15 @@ static void USB_ISR(void) _usbConfiguration = 0; _cmark = 0; _cend = 0; + udd_ack_reset(); /* /!\/!\/!\ TAKEN FROM ASF TO CLEAR ISR /!\/!\/!\ */ + } // Start of Frame - happens every millisecond so we use it for TX and RX LED one-shot timing, too +#if 0 if (Is_udd_sof()) { + printf(">>> Start of Frame\r\n"); #ifdef CDC_ENABLED USBD_Flush(CDC_TX); // Send a tx frame if found #endif @@ -398,11 +420,15 @@ static void USB_ISR(void) TXLED0; if (RxLEDPulse && !(--RxLEDPulse)) RXLED0;*/ + + udd_ack_sof(); /* /!\/!\/!\ TAKEN FROM ASF TO CLEAR ISR /!\/!\/!\ */ } +#endif // EP 0 Interrupt if (Is_udd_endpoint_interrupt(0)) { + printf(">>> EP0 Int: 0x%x\r\n", UOTGHS->UOTGHS_DEVEPTISR[0]); if ( !UDD_ReceivedSetupInt() ) { @@ -413,16 +439,22 @@ static void USB_ISR(void) UDD_Recv((uint8_t*)&setup,8); UDD_ClearSetupInt(); + printf(">>> EP0 Int: AP clear: 0x%x\r\n", UOTGHS->UOTGHS_DEVEPTISR[0]); + uint8_t requestType = setup.bmRequestType; if (requestType & REQUEST_DEVICETOHOST) { + printf(">>> EP0 Int: IN Request\r\n"); UDD_WaitIN(); } else { + printf(">>> EP0 Int: OUT Request\r\n"); UDD_ClearIN(); } + + bool ok = true ; if (REQUEST_STANDARD == (requestType & REQUEST_TYPE)) { @@ -430,6 +462,7 @@ static void USB_ISR(void) uint8_t r = setup.bRequest; if (GET_STATUS == r) { + puts(">>> EP0 Int: GET_STATUS\r\n"); UDD_Send8(0); // TODO UDD_Send8(0); } @@ -441,23 +474,28 @@ static void USB_ISR(void) } else if (SET_ADDRESS == r) { + puts(">>> EP0 Int: SET_ADDRESS\r\n"); UDD_WaitIN(); UDD_SetAddress(setup.wValueL); } else if (GET_DESCRIPTOR == r) { + puts(">>> EP0 Int: GET_DESCRIPTOR\r\n"); ok = USBD_SendDescriptor(setup); } else if (SET_DESCRIPTOR == r) { + puts(">>> EP0 Int: SET_DESCRIPTOR\r\n"); ok = false; } else if (GET_CONFIGURATION == r) { + puts(">>> EP0 Int: GET_CONFIGURATION\r\n"); UDD_Send8(1); } else if (SET_CONFIGURATION == r) { + puts(">>> EP0 Int: SET_CONFIGURATION\r\n"); if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT)) { UDD_InitEndpoints(_initEndpoints); @@ -477,16 +515,19 @@ static void USB_ISR(void) } else { + puts(">>> EP0 Int: ClassInterfaceRequest\r\n"); USBD_InitControl(setup.wLength); // Max length of transfer ok = USBD_ClassInterfaceRequest(setup); } if (ok) { + puts(">>> EP0 Int: Send packet\r\n"); UDD_ClearIN(); } else { + puts(">>> EP0 Int: Stall\r\n"); UDD_Stall(); } } @@ -555,10 +596,10 @@ USB_::USB_() { UDD_SetStack(&USB_ISR); - if ( UDD_Init() == 0UL ) - { - _usbInitialized=1UL ; - } + if ( UDD_Init() == 0UL ) + { + _usbInitialized=1UL ; + } } bool USB_::attach(void) @@ -566,8 +607,8 @@ bool USB_::attach(void) if ( _usbInitialized != 0UL ) { UDD_Attach() ; - - return true ; + _usbConfiguration = 0; + return true; } else { @@ -577,7 +618,8 @@ bool USB_::attach(void) bool USB_::detach(void) { - if ( _usbInitialized != 0UL ) + return true; +/* if ( _usbInitialized != 0UL ) { UDD_Detach() ; @@ -586,7 +628,7 @@ bool USB_::detach(void) else { return false ; - } + }*/ } // Check for interrupts diff --git a/hardware/arduino/sam/cores/sam/USB/USBCore.h b/hardware/arduino/sam/cores/sam/USB/USBCore.h index 7462fb5f4..04b905b0a 100644 --- a/hardware/arduino/sam/cores/sam/USB/USBCore.h +++ b/hardware/arduino/sam/cores/sam/USB/USBCore.h @@ -124,6 +124,7 @@ #define HID_REPORT_DESCRIPTOR_TYPE 0x22 #define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23 +_Pragma("pack(1)") // Device typedef struct { @@ -277,6 +278,7 @@ typedef struct EndpointDescriptor in; } HIDDescriptor; +_Pragma("pack()") #define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \ { 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs } diff --git a/hardware/arduino/sam/cores/sam/USB/USBDesc.h b/hardware/arduino/sam/cores/sam/USB/USBDesc.h index 900713e0f..db912c9ba 100644 --- a/hardware/arduino/sam/cores/sam/USB/USBDesc.h +++ b/hardware/arduino/sam/cores/sam/USB/USBDesc.h @@ -1,22 +1,22 @@ -/* Copyright (c) 2011, Peter Barrett -** -** Permission to use, copy, modify, and/or distribute this software for -** any purpose with or without fee is hereby granted, provided that the -** above copyright notice and this permission notice appear in all copies. -** -** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR -** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES -** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -** SOFTWARE. +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. */ -#define CDC_ENABLED +//#define CDC_ENABLED #define HID_ENABLED diff --git a/hardware/arduino/sam/cores/sam/main.cpp b/hardware/arduino/sam/cores/sam/main.cpp index 4c6b43a0d..b2af23e9b 100644 --- a/hardware/arduino/sam/cores/sam/main.cpp +++ b/hardware/arduino/sam/cores/sam/main.cpp @@ -35,6 +35,10 @@ int main( void ) { init(); +#if defined(USBCON) + USB.attach(); +#endif + setup(); for (;;) diff --git a/hardware/arduino/sam/cores/sam/validation_usb_device/test_usb_device.cpp b/hardware/arduino/sam/cores/sam/validation_usb_device/test_usb_device.cpp index c69bb60fe..d58f8ad79 100644 --- a/hardware/arduino/sam/cores/sam/validation_usb_device/test_usb_device.cpp +++ b/hardware/arduino/sam/cores/sam/validation_usb_device/test_usb_device.cpp @@ -29,7 +29,7 @@ const int mouseButton = 6; int range = 5; // output range of X or Y movement; affects movement speed int responseDelay = 10; // response delay of the mouse, in ms -/* + void setup() { // initialize the buttons' inputs: pinMode(upButton, INPUT); @@ -76,15 +76,15 @@ void loop() { // a delay so the mouse doesn't move too fast: delay(responseDelay); } -*/ -#include "USBAPI.h" + +//#include "USBAPI.h" // Cet exemple fonctionne !!! ;-) -void setup() { +/*void setup() { // initialize the digital pin as an output. // Pin 13 has an LED connected on most Arduino boards: //pinMode(13, OUTPUT); @@ -98,5 +98,5 @@ void loop() { //digitalWrite(13, LOW); // set the LED off delay(1000); // wait for a second printf("loop...\r\n"); -} +}*/ diff --git a/hardware/arduino/sam/system/libsam/source/uotghs.c b/hardware/arduino/sam/system/libsam/source/uotghs.c index 650888813..f395196f4 100644 --- a/hardware/arduino/sam/system/libsam/source/uotghs.c +++ b/hardware/arduino/sam/system/libsam/source/uotghs.c @@ -17,6 +17,7 @@ */ #include "chip.h" +#include #if SAM3XA_SERIES @@ -35,52 +36,6 @@ void UOTGHS_Handler( void ) gpf_isr(); } -void UDD_SetEP( uint32_t ep ) -{ - ul_ep = ep; -} - -void UDD_InitEndpoints(const uint32_t* eps_table) -{ - uint32_t ul_ep_nb ; - - for (ul_ep_nb = 1; ul_ep_nb < sizeof(eps_table); ul_ep_nb++) - { - // Reset Endpoint Fifos - /* UOTGHS->UOTGHS_DEVEPTISR[ul_EP].UDPHS_EPTCLRSTA = UDPHS_EPTCLRSTA_TOGGLESQ | UDPHS_EPTCLRSTA_FRCESTALL; - UOTGHS->UOTGHS_DEVEPT = 1<UDPHS_EPT[ul_EP].UDPHS_EPTCFG = _initEndpoints[ul_EP]; - - while( (signed int)UDPHS_EPTCFG_EPT_MAPD != (signed int)((UOTGHS->UDPHS_EPT[ul_EP].UDPHS_EPTCFG) & (unsigned int)UDPHS_EPTCFG_EPT_MAPD) ) - ; - UOTGHS->UDPHS_EPT[ul_EP].UDPHS_EPTCTLENB = UDPHS_EPTCTLENB_EPT_ENABL; - - // UECFG1X = EP_DOUBLE_64; - }*/ - - // Reset EP - UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPRST0 << ul_ep_nb); - // Configure EP - UOTGHS->UOTGHS_DEVEPTCFG[ul_ep_nb] = eps_table[ul_ep_nb]; - // Enable EP - UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPEN0 << ul_ep_nb); - } - -} - -void UDD_InitEP( uint32_t ul_ep_nb, uint32_t ul_ep_cfg ) -{ - // Reset EP - UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPRST0 << ul_ep_nb); - // Configure EP - UOTGHS->UOTGHS_DEVEPTCFG[ul_ep_nb] = ul_ep_cfg; - // Enable EP - UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPEN0 << ul_ep_nb); -} - uint32_t UDD_Init(void) { uint32_t ul ; @@ -97,10 +52,43 @@ uint32_t UDD_Init(void) // Always authorize asynchrone USB interrupts to exit from sleep mode // for SAM3 USB wake up device except BACKUP mode - pmc_set_fast_startup_input(PMC_FSMR_USBAL); + //pmc_set_fast_startup_input(PMC_FSMR_USBAL); + + + + + // ID pin not used then force device mode + otg_disable_id_pin(); + otg_force_device_mode(); + + // Enable USB hardware + otg_disable_pad(); + otg_enable_pad(); + otg_enable(); + otg_unfreeze_clock(); + // Check USB clock + while (!Is_otg_clock_usable()) + ; + + udd_low_speed_disable(); + udd_high_speed_disable(); + + + //otg_ack_vbus_transition(); + // Force Vbus interrupt in case of Vbus always with a high level + // This is possible with a short timing between a Host mode stop/start. + /*if (Is_otg_vbus_high()) { + otg_raise_vbus_transition(); + } + otg_enable_vbus_interrupt();*/ + otg_freeze_clock(); + + + + // Enable USB - UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_USBE; + /*UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_USBE; // Automatic mode speed for device UOTGHS->UOTGHS_DEVCTRL &= ~UOTGHS_DEVCTRL_SPDCONF_Msk; // Normal mode @@ -215,20 +203,152 @@ uint32_t UDD_Init(void) UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_VBUSTE; UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_WAKEUPES; - +*/ return 0UL ; } void UDD_Attach(void) { - UOTGHS->UOTGHS_DEVCTRL &= ~(unsigned int)UOTGHS_DEVCTRL_DETACH; + //USBCON = ((1< UDD_Attach\r\n"); + + + + + + + + otg_unfreeze_clock(); + + // This section of clock check can be improved with a chek of + // USB clock source via sysclk() + // Check USB clock because the source can be a PLL + while (!Is_otg_clock_usable()); + + // Authorize attach if Vbus is present + udd_attach_device(); + + // Enable USB line events + udd_enable_reset_interrupt(); + //udd_enable_suspend_interrupt(); + //udd_enable_wake_up_interrupt(); + + + //////////////udd_enable_sof_interrupt(); + + + + + // Reset following interupts flag + //udd_ack_reset(); + //udd_ack_sof(); + + + // The first suspend interrupt must be forced + // The first suspend interrupt is not detected else raise it + //udd_raise_suspend(); + + //udd_ack_wake_up(); + //otg_freeze_clock(); + + cpu_irq_restore(flags); + + + + +/* + otg_disable_id_pin(); + otg_force_device_mode(); + + + UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_OTGPADE; + UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_OTGPADE; + UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_USBE; + UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_FRZCLK; + + udd_low_speed_disable(); + udd_high_speed_disable(); + + + UOTGHS->UOTGHS_DEVIER = (UOTGHS_DEVIER_EORSTES | UOTGHS_DEVIER_SOFES); + + otg_ack_vbus_transition(); + // Force Vbus interrupt in case of Vbus always with a high level + // This is possible with a short timing between a Host mode stop/start. + if (Is_otg_vbus_high()) { + otg_raise_vbus_transition(); + } + otg_enable_vbus_interrupt(); + otg_freeze_clock(); +*/ + } void UDD_Detach(void) { - UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_DETACH; + printf("=> UDD_Detach\r\n"); + UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_DETACH; } +void UDD_InitEP( uint32_t ul_ep_nb, uint32_t ul_ep_cfg ) +{ + printf("=> UDD_InitEP\r\n"); + + // Reset EP + UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPRST0 << ul_ep_nb); + // Configure EP + UOTGHS->UOTGHS_DEVEPTCFG[ul_ep_nb] = ul_ep_cfg; + // Enable EP + UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPEN0 << ul_ep_nb); +} + +void UDD_InitEndpoints(const uint32_t* eps_table) +{ + uint32_t ul_ep_nb ; + + printf("=> UDD_InitEndpoints\r\n"); + + for (ul_ep_nb = 1; ul_ep_nb < sizeof(eps_table); ul_ep_nb++) + { + // Reset Endpoint Fifos + /* UOTGHS->UOTGHS_DEVEPTISR[ul_EP].UDPHS_EPTCLRSTA = UDPHS_EPTCLRSTA_TOGGLESQ | UDPHS_EPTCLRSTA_FRCESTALL; + UOTGHS->UOTGHS_DEVEPT = 1<UDPHS_EPT[ul_EP].UDPHS_EPTCFG = _initEndpoints[ul_EP]; + + while( (signed int)UDPHS_EPTCFG_EPT_MAPD != (signed int)((UOTGHS->UDPHS_EPT[ul_EP].UDPHS_EPTCFG) & (unsigned int)UDPHS_EPTCFG_EPT_MAPD) ) + ; + UOTGHS->UDPHS_EPT[ul_EP].UDPHS_EPTCTLENB = UDPHS_EPTCTLENB_EPT_ENABL; + + // UECFG1X = EP_DOUBLE_64; + }*/ + + // Reset EP + UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPRST0 << ul_ep_nb); + // Configure EP + UOTGHS->UOTGHS_DEVEPTCFG[ul_ep_nb] = eps_table[ul_ep_nb]; + // Enable EP + UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPEN0 << ul_ep_nb); + } +} + +void UDD_SetEP( uint32_t ep ) +{ + ul_ep = ep; +} + +// Wait until ready to accept IN packet. void UDD_WaitIN(void) { //while (!(UEINTX & (1< UDD_ClearIN: sent %d bytes\r\n", ul_send_index); // UEINTX = ~(1<UOTGHS_DEVEPTICR[ul_ep] = UOTGHS_DEVEPTICR_TXINIC; ul_send_index = 0; @@ -260,6 +382,8 @@ void UDD_ClearOUT(void) ul_rcv_index = 0; } +// Wait for IN FIFO to be ready to accept data or OUT FIFO to receive data. +// Return true if new IN FIFO buffer available. uint32_t UDD_WaitForINOrOUT(void) { //while (!(UEINTX & ((1<UOTGHS_DEVEPTICR[ul_ep] = (UOTGHS_DEVEPTICR_RXSTPIC | UOTGHS_DEVEPTICR_RXOUTIC | UOTGHS_DEVEPTICR_TXINIC); + //UOTGHS->UOTGHS_DEVEPTICR[ul_ep] = (UOTGHS_DEVEPTICR_RXSTPIC | UOTGHS_DEVEPTICR_RXOUTIC | UOTGHS_DEVEPTICR_TXINIC); + UOTGHS->UOTGHS_DEVEPTICR[ul_ep] = (UOTGHS_DEVEPTICR_RXSTPIC); } void UDD_Send8( uint8_t data ) { uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ul_ep); + printf("=> UDD_Send8 : ul_send_index=%d\r\n", ul_send_index); ptr_dest[ul_send_index++] = data; } @@ -322,6 +448,7 @@ void UDD_ReleaseRX(void) nakouti a clearer rxouti/killbank a clearer*/ + puts("=> UDD_ReleaseRX\r\n"); UOTGHS->UOTGHS_DEVEPTICR[ul_ep] = (UOTGHS_DEVEPTICR_NAKOUTIC | UOTGHS_DEVEPTICR_RXOUTIC); UOTGHS->UOTGHS_DEVEPTIDR[ul_ep] = UOTGHS_DEVEPTIDR_FIFOCONC; } @@ -334,6 +461,7 @@ void UDD_ReleaseTX(void) rxouti/killbank a clearer txini a clearer*/ + puts("=> UDD_ReleaseTX\r\n"); UOTGHS->UOTGHS_DEVEPTICR[ul_ep] = (UOTGHS_DEVEPTICR_NAKINIC | UOTGHS_DEVEPTICR_RXOUTIC | UOTGHS_DEVEPTICR_TXINIC); UOTGHS->UOTGHS_DEVEPTIDR[ul_ep] = UOTGHS_DEVEPTIDR_FIFOCONC; } @@ -345,6 +473,7 @@ uint32_t UDD_ReadWriteAllowed(void) void UDD_SetAddress(uint32_t addr) { + printf("=> UDD_SetAddress : setting address to %d\r\n", addr); udd_configure_address(addr); udd_enable_address(); } diff --git a/hardware/arduino/sam/variants/arduino_due_x/variant.cpp b/hardware/arduino/sam/variants/arduino_due_x/variant.cpp index fbc0f4f0f..9a3318f05 100644 --- a/hardware/arduino/sam/variants/arduino_due_x/variant.cpp +++ b/hardware/arduino/sam/variants/arduino_due_x/variant.cpp @@ -347,6 +347,8 @@ extern void init( void ) g_APinDescription[PINS_UART].ulPin, g_APinDescription[PINS_UART].ulPinConfiguration); + Serial1.begin(115200); + // Initialize Serial ports USART PIO_Configure( g_APinDescription[PINS_USART0].pPort, From 45a1d32e71b6b1ccff4ce7db5299e39867e57f29 Mon Sep 17 00:00:00 2001 From: Thibault RICHARD Date: Mon, 30 Apr 2012 20:17:40 +0200 Subject: [PATCH 2/2] [SAM] enumeration is now okay. Device still not working. --- hardware/arduino/sam/cores/sam/USB/USBCore.cpp | 15 ++++++++------- .../sam/validation_usb_device/test_usb_device.cpp | 10 +++++----- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/hardware/arduino/sam/cores/sam/USB/USBCore.cpp b/hardware/arduino/sam/cores/sam/USB/USBCore.cpp index 60d9d18be..ad83b494d 100644 --- a/hardware/arduino/sam/cores/sam/USB/USBCore.cpp +++ b/hardware/arduino/sam/cores/sam/USB/USBCore.cpp @@ -213,8 +213,9 @@ static bool USBD_SendControl(uint8_t d) { if (_cmark < _cend) { - if (!UDD_WaitForINOrOUT()) - return false; + // /!\ NE DEVRAIT THEORIQUEMENT PAS ETRE COMMENTE... mais ca marche mieux sans... pourquoi?!!! + //if (!UDD_WaitForINOrOUT()) + // return false; UDD_Send8(d); @@ -238,7 +239,10 @@ int USBD_SendControl(uint8_t flags, const void* d, uint32_t len) { uint8_t c = *data++; if (!USBD_SendControl(c)) + { + printf("=> USBD_SendControl : return -1\r\n"); return -1; + } } return sent; } @@ -311,6 +315,8 @@ _Pragma("pack(1)") _Pragma("pack()") printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen); +printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen); + // Now send them USBD_InitControl(maxlen); USBD_SendControl(0,&config,sizeof(ConfigDescriptor)); @@ -382,9 +388,6 @@ volatile int cpt = 0; // Endpoint 0 interrupt static void USB_ISR(void) { - while (cpt++ > 100) - ; - // End of Reset if (Is_udd_reset()) { @@ -407,7 +410,6 @@ static void USB_ISR(void) } // Start of Frame - happens every millisecond so we use it for TX and RX LED one-shot timing, too -#if 0 if (Is_udd_sof()) { printf(">>> Start of Frame\r\n"); @@ -423,7 +425,6 @@ static void USB_ISR(void) udd_ack_sof(); /* /!\/!\/!\ TAKEN FROM ASF TO CLEAR ISR /!\/!\/!\ */ } -#endif // EP 0 Interrupt if (Is_udd_endpoint_interrupt(0)) diff --git a/hardware/arduino/sam/cores/sam/validation_usb_device/test_usb_device.cpp b/hardware/arduino/sam/cores/sam/validation_usb_device/test_usb_device.cpp index d58f8ad79..3b2ffe309 100644 --- a/hardware/arduino/sam/cores/sam/validation_usb_device/test_usb_device.cpp +++ b/hardware/arduino/sam/cores/sam/validation_usb_device/test_usb_device.cpp @@ -32,18 +32,18 @@ int responseDelay = 10; // response delay of the mouse, in ms void setup() { // initialize the buttons' inputs: - pinMode(upButton, INPUT); + /* pinMode(upButton, INPUT); pinMode(downButton, INPUT); pinMode(leftButton, INPUT); pinMode(rightButton, INPUT); - pinMode(mouseButton, INPUT); + pinMode(mouseButton, INPUT);*/ // initialize mouse control: Mouse.begin(); } void loop() { // read the buttons: - int upState = digitalRead(upButton); + /* int upState = digitalRead(upButton); int downState = digitalRead(downButton); int rightState = digitalRead(rightButton); int leftState = digitalRead(leftButton); @@ -71,8 +71,8 @@ void loop() { if (Mouse.isPressed(MOUSE_LEFT)) { Mouse.release(MOUSE_LEFT); } - } - + }*/ +Mouse.move(10, 10, 0); // a delay so the mouse doesn't move too fast: delay(responseDelay); }