From a48627b3e5189837d7f183270c88c2b7494ab8c5 Mon Sep 17 00:00:00 2001 From: Thibaut VIARD <thibaut.viard@atmel.com> Date: Mon, 12 May 2014 20:09:09 +0200 Subject: [PATCH] Bringing USB files in name of JcB --- cores/arduino/USB/CDC.cpp | 39 +- cores/arduino/USB/HID.cpp | 15 +- cores/arduino/USB/USBAPI.h | 20 +- cores/arduino/USB/USBCore.cpp | 403 ++++------ cores/arduino/USB/USBCore.h | 8 +- cores/arduino/USB/USBDesc.h | 2 +- cores/arduino/USB/USB_device.h | 412 ++++++++++ cores/arduino/USB/USB_host.h | 78 ++ cores/arduino/USB/samd21_device.c | 713 ++++++++++++++++++ cores/arduino/USB/samd21_device.h | 622 +++++++++++++++ cores/arduino/USB/samd21_host.c | 489 ++++++++++++ cores/arduino/USB/samd21_host.h | 399 ++++++++++ .../build_as6/test.atsln | 20 + .../build_as6/test.atsuo | Bin 0 -> 39424 bytes .../build_as6/test.cppproj | 498 ++++++++++++ .../validation_usb_device/build_gcc/Makefile | 31 +- .../validation_usb_device/build_gcc/debug.mk | 4 +- .../validation_usb_device/build_gcc/gcc.mk | 54 +- .../build_gcc/test_usb_device.mk | 208 ++--- .../validation_usb_device/test_usb_device.cpp | 51 +- 20 files changed, 3653 insertions(+), 413 deletions(-) create mode 100644 cores/arduino/USB/USB_device.h create mode 100644 cores/arduino/USB/USB_host.h create mode 100644 cores/arduino/USB/samd21_device.c create mode 100644 cores/arduino/USB/samd21_device.h create mode 100644 cores/arduino/USB/samd21_host.c create mode 100644 cores/arduino/USB/samd21_host.h create mode 100644 cores/arduino/validation_usb_device/build_as6/test.atsln create mode 100644 cores/arduino/validation_usb_device/build_as6/test.atsuo create mode 100644 cores/arduino/validation_usb_device/build_as6/test.cppproj diff --git a/cores/arduino/USB/CDC.cpp b/cores/arduino/USB/CDC.cpp index 84a4e913..fd93a5e0 100644 --- a/cores/arduino/USB/CDC.cpp +++ b/cores/arduino/USB/CDC.cpp @@ -14,10 +14,22 @@ ** SOFTWARE. */ -#include "Arduino.h" +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> + +// Include Atmel headers +#include "sam.h" +#include "wiring_constants.h" +#include "USBCore.h" +#include "USB_device.h" +#include "USBDesc.h" #include "USBAPI.h" +//#include "samd21_device.h" + #include "Reset.h" + #ifdef CDC_ENABLED #define CDC_SERIAL_BUFFER_SIZE 512 @@ -159,15 +171,15 @@ void Serial_::end(void) void Serial_::accept(void) { - static uint32_t guard = 0; +// static uint32_t guard = 0; // synchronized access to guard - do { - if (__LDREXW(&guard) != 0) { - __CLREX(); - return; // busy - } - } while (__STREXW(1, &guard) != 0); // retry until write succeed +//JCB do { +// if (__LDREXW(&guard) != 0) { +// __CLREX(); +// return; // busy +// } +// } while (__STREXW(1, &guard) != 0); // retry until write succeed ring_buffer *buffer = &cdc_rx_buffer; uint32_t i = (uint32_t)(buffer->head+1) % CDC_SERIAL_BUFFER_SIZE; @@ -179,7 +191,8 @@ void Serial_::accept(void) while (i != buffer->tail) { uint32_t c; if (!USBD_Available(CDC_RX)) { - udd_ack_fifocon(CDC_RX); + UDD_ReleaseRX(CDC_RX); + //JCB udd_ack_fifocon(CDC_RX); break; } c = USBD_Recv(CDC_RX); @@ -191,7 +204,7 @@ void Serial_::accept(void) } // release the guard - guard = 0; +// guard = 0; } int Serial_::available(void) @@ -280,8 +293,8 @@ size_t Serial_::write(uint8_t c) { Serial_::operator bool() { // this is here to avoid spurious opening after upload - if (millis() < 500) - return false; +// if (millis() < 500) +// return false; bool result = false; @@ -290,7 +303,7 @@ Serial_::operator bool() result = true; } - delay(10); +// delay(10); return result; } diff --git a/cores/arduino/USB/HID.cpp b/cores/arduino/USB/HID.cpp index c243f495..6994c14b 100644 --- a/cores/arduino/USB/HID.cpp +++ b/cores/arduino/USB/HID.cpp @@ -14,11 +14,19 @@ ** SOFTWARE. */ -#include "Arduino.h" - #ifdef HID_ENABLED +#include "USBAPI.h" +#include "Reset.h" +#include "USBCore.h" +#include "USBDesc.h" +#include "sam.h" +#include "USB_device.h" + //#define RAWHID_ENABLED +#ifdef __cplusplus +extern "C"{ +#endif // __cplusplus // Singletons for mouse and keyboard @@ -196,6 +204,9 @@ bool WEAK HID_Setup(Setup& setup) } return false; } +#ifdef __cplusplus +} +#endif //================================================================================ //================================================================================ diff --git a/cores/arduino/USB/USBAPI.h b/cores/arduino/USB/USBAPI.h index 3cf601e9..7fa8b471 100644 --- a/cores/arduino/USB/USBAPI.h +++ b/cores/arduino/USB/USBAPI.h @@ -19,8 +19,20 @@ #ifndef __USBAPI__ #define __USBAPI__ + +/* Define attribute */ +#if defined ( __CC_ARM ) /* Keil uVision 4 */ + #define WEAK (__attribute__ ((weak))) +#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */ + #define WEAK __weak +#elif defined ( __GNUC__ ) /* GCC CS */ + #define WEAK __attribute__ ((weak)) +#endif + + #if defined __cplusplus +#include "Stream.h" #include "RingBuffer.h" //================================================================================ @@ -49,7 +61,7 @@ private: RingBuffer *_cdc_rx_buffer; public: void begin(uint32_t baud_count); - void begin(uint32_t baud_count, uint8_t config); + void begin(unsigned long, uint8_t); void end(void); virtual int available(void); @@ -189,7 +201,7 @@ bool MSC_Data(uint8_t rx,uint8_t tx); //================================================================================ //================================================================================ -// CSC 'Driver' +// CDC 'Driver' int CDC_GetInterface(uint8_t* interfaceNum); int CDC_GetOtherInterface(uint8_t* interfaceNum); @@ -217,5 +229,5 @@ uint32_t USBD_Recv(uint32_t ep); // non-blocking void USBD_Flush(uint32_t ep); uint32_t USBD_Connected(void); -#endif -#endif +#endif // __cplusplus +#endif // __USBAPI__ diff --git a/cores/arduino/USB/USBCore.cpp b/cores/arduino/USB/USBCore.cpp index 7876762b..807462fb 100644 --- a/cores/arduino/USB/USBCore.cpp +++ b/cores/arduino/USB/USBCore.cpp @@ -13,16 +13,40 @@ ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ** SOFTWARE. */ - -#include "Arduino.h" -#include "USBAPI.h" -#include "Reset.h" +#include <stdlib.h> #include <stdio.h> +#include <stdint.h> +// Include Atmel headers +#include "sam.h" +#include "wiring_constants.h" +#include "USBCore.h" +#include "USB_device.h" // needed for USB PID define +#include "USBDesc.h" +#include "USBAPI.h" + +#define TRACE_CORE(x) x +//#define TRACE_CORE(x) + +// USB Device +#define USB_VID 0x2341 // arduino LLC vid +#define USB_PID_LEONARDO 0x0034 +#define USB_PID_MICRO 0x0035 +#define USB_PID_DUE 0x003E +#define USB_PID_ZERO 0x004D + + +#define EP_TYPE_CONTROL 0 +#ifdef CDC_ENABLED +#define EP_TYPE_INTERRUPT_IN 1 // CDC_ENDPOINT_ACM +#define EP_TYPE_BULK_OUT 2 // CDC_ENDPOINT_OUT +#define EP_TYPE_BULK_IN 3 // CDC_ENDPOINT_IN +#endif +#ifdef HID_ENABLED +#define EP_TYPE_INTERRUPT_IN_HID 4 // HID_ENDPOINT_INT +#endif -//#define TRACE_CORE(x) x -#define TRACE_CORE(x) -static const uint32_t EndPoints[] = +static const uint8_t EndPoints[] = { EP_TYPE_CONTROL, @@ -90,18 +114,18 @@ const DeviceDescriptor USB_DeviceDescriptor = const DeviceDescriptor USB_DeviceDescriptorA = D_DEVICE(DEVICE_CLASS,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1); -const DeviceDescriptor USB_DeviceQualifier = - D_QUALIFIER(0x00,0x00,0x00,64,1); - -//! 7.1.20 Test Mode Support -static const unsigned char test_packet_buffer[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // JKJKJKJK * 9 - 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, // JJKKJJKK * 8 - 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, // JJJJKKKK * 8 - 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // JJJJJJJKKKKKKK * 8 - 0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD, // JJJJJJJK * 8 - 0xFC,0x7E,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0x7E // {JKKKKKKK * 10}, JK -}; +//const DeviceDescriptor USB_DeviceQualifier = +// D_QUALIFIER(0x00,0x00,0x00,64,1); +// +////! 7.1.20 Test Mode Support +//static const unsigned char test_packet_buffer[] = { +// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // JKJKJKJK * 9 +// 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, // JJKKJJKK * 8 +// 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, // JJJJKKKK * 8 +// 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // JJJJJJJKKKKKKK * 8 +// 0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD, // JJJJJJJK * 8 +// 0xFC,0x7E,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0x7E // {JKKKKKKK * 10}, JK +//}; //================================================================== //================================================================== @@ -115,23 +139,23 @@ uint32_t _cdcComposite = 0; //================================================================== #define USB_RECV_TIMEOUT -class LockEP -{ - irqflags_t flags; -public: - LockEP(uint32_t ep) : flags(cpu_irq_save()) - { - } - ~LockEP() - { - cpu_irq_restore(flags); - } -}; +//class LockEP +//{ +// irqflags_t flags; +//public: +// LockEP(uint32_t ep) : flags(cpu_irq_save()) +// { +// } +// ~LockEP() +// { +// cpu_irq_restore(flags); +// } +//}; // Number of bytes, assumes a rx endpoint uint32_t USBD_Available(uint32_t ep) { - LockEP lock(ep); +// LockEP lock(ep); return UDD_FifoByteCount(ep & 0xF); } @@ -142,7 +166,7 @@ uint32_t USBD_Recv(uint32_t ep, void* d, uint32_t len) if (!_usbConfiguration || len < 0) return -1; - LockEP lock(ep); +// LockEP lock(ep); uint32_t n = UDD_FifoByteCount(ep & 0xF); len = min(n,len); n = len; @@ -263,7 +287,7 @@ static bool USB_SendStringDescriptor(const uint8_t *string, int wLength) { // TODO int USBD_RecvControl(void* d, uint32_t len) { - UDD_WaitOUT(); +// UDD_WaitOUT(); UDD_Recv(EP0, (uint8_t*)d, len); UDD_ClearOUT(); @@ -312,23 +336,23 @@ int USBD_SendInterfaces(void) return interfaces; } -int USBD_SendOtherInterfaces(void) -{ - int total = 0; - uint8_t interfaces = 0; - -#ifdef CDC_ENABLED - total = CDC_GetOtherInterface(&interfaces); -#endif - -#ifdef HID_ENABLED - total += HID_GetInterface(&interfaces); -#endif - - total = total; // Get rid of compiler warning - TRACE_CORE(printf("=> USBD_SendInterfaces, total=%d interfaces=%d\r\n", total, interfaces);) - return interfaces; -} +//int USBD_SendOtherInterfaces(void) +//{ +// int total = 0; +// uint8_t interfaces = 0; +// +//#ifdef CDC_ENABLED +// total = CDC_GetOtherInterface(&interfaces); +//#endif +// +//#ifdef HID_ENABLED +// total += HID_GetInterface(&interfaces); +//#endif +// +// total = total; // Get rid of compiler warning +// TRACE_CORE(printf("=> USBD_SendInterfaces, total=%d interfaces=%d\r\n", total, interfaces);) +// return interfaces; +//} // Construct a dynamic configuration descriptor // This really needs dynamic endpoint allocation etc @@ -342,9 +366,9 @@ static bool USBD_SendConfiguration(int maxlen) //TRACE_CORE(printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark);) //TRACE_CORE(printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor));) -_Pragma("pack(1)") - ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces); -_Pragma("pack()") +//JCB _Pragma("pack(1)") + ConfigDescriptor config = D_CONFIG((uint16_t)(_cmark + sizeof(ConfigDescriptor)),(uint8_t)interfaces); +//JCB _Pragma("pack()") //TRACE_CORE(printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen);) //TRACE_CORE(printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen);) @@ -356,28 +380,28 @@ _Pragma("pack()") return true; } -static bool USBD_SendOtherConfiguration(int maxlen) -{ - // Count and measure interfaces - USBD_InitControl(0); - //TRACE_CORE(printf("=> USBD_SendConfiguration _cmark1=%d\r\n", _cmark);) - int interfaces = USBD_SendOtherInterfaces(); - //TRACE_CORE(printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark);) - //TRACE_CORE(printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor));) - -_Pragma("pack(1)") - ConfigDescriptor config = D_OTHERCONFIG(_cmark + sizeof(ConfigDescriptor),interfaces); -_Pragma("pack()") - //TRACE_CORE(printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen);) - - //TRACE_CORE(printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen);) - - // Now send them - USBD_InitControl(maxlen); - USBD_SendControl(0,&config,sizeof(ConfigDescriptor)); - USBD_SendOtherInterfaces(); - return true; -} +//static bool USBD_SendOtherConfiguration(int maxlen) +//{ +// // Count and measure interfaces +// USBD_InitControl(0); +// //TRACE_CORE(printf("=> USBD_SendConfiguration _cmark1=%d\r\n", _cmark);) +// int interfaces = USBD_SendOtherInterfaces(); +// //TRACE_CORE(printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark);) +// //TRACE_CORE(printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor));) +// +//_Pragma("pack(1)") +// ConfigDescriptor config = D_OTHERCONFIG(_cmark + sizeof(ConfigDescriptor),interfaces); +//_Pragma("pack()") +// //TRACE_CORE(printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen);) +// +// //TRACE_CORE(printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen);) +// +// // Now send them +// USBD_InitControl(maxlen); +// USBD_SendControl(0,&config,sizeof(ConfigDescriptor)); +// USBD_SendOtherInterfaces(); +// return true; +//} static bool USBD_SendDescriptor(Setup& setup) { @@ -431,22 +455,22 @@ static bool USBD_SendDescriptor(Setup& setup) desc_length = setup.wLength; } } - else if (USB_DEVICE_QUALIFIER == t) - { - // Device qualifier descriptor requested - desc_addr = (const uint8_t*)&USB_DeviceQualifier; - if( *desc_addr > setup.wLength ) { - desc_length = setup.wLength; - } - } - else if (USB_OTHER_SPEED_CONFIGURATION == t) - { - // Other configuration descriptor requested - return USBD_SendOtherConfiguration(setup.wLength); - } +// else if (USB_DEVICE_QUALIFIER == t) +// { +// // Device qualifier descriptor requested +// desc_addr = (const uint8_t*)&USB_DeviceQualifier; +// if( *desc_addr > setup.wLength ) { +// desc_length = setup.wLength; +// } +// } +// else if (USB_OTHER_SPEED_CONFIGURATION == t) +// { +// // Other configuration descriptor requested +// return USBD_SendOtherConfiguration(setup.wLength); +// } else { - //printf("Device ERROR"); + TRACE_CORE(printf("Device ERROR");) } if (desc_addr == 0) @@ -466,131 +490,26 @@ static bool USBD_SendDescriptor(Setup& setup) } -static void USB_SendZlp( void ) -{ - while( UOTGHS_DEVEPTISR_TXINI != (UOTGHS->UOTGHS_DEVEPTISR[0] & UOTGHS_DEVEPTISR_TXINI ) ) - { - if((UOTGHS->UOTGHS_DEVISR & UOTGHS_DEVISR_SUSP) == UOTGHS_DEVISR_SUSP) - { - return; - } - } - UOTGHS->UOTGHS_DEVEPTICR[0] = UOTGHS_DEVEPTICR_TXINIC; -} - - -static void Test_Mode_Support( uint8_t wIndex ) -{ - uint8_t i; - uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(2); - - switch( wIndex ) - { - case 4: - //Test mode Test_Packet: - //Upon command, a port must repetitively transmit the following test packet until - //the exit action is taken. This enables the testing of rise and fall times, eye - //patterns, jitter, and any other dynamic waveform specifications. - //The test packet is made up by concatenating the following strings. - //(Note: For J/K NRZI data, and for NRZ data, the bit on the left is the first one - //transmitted. "S" indicates that a bit stuff occurs, which inserts an "extra" NRZI data bit. - //"* N" is used to indicate N occurrences of a string of bits or symbols.) - //A port in Test_Packet mode must send this packet repetitively. The inter-packet timing - //must be no less than the minimum allowable inter-packet gap as defined in Section 7.1.18 and - //no greater than 125 us. - - // Send ZLP - USB_SendZlp(); - - UOTGHS->UOTGHS_DEVDMA[0].UOTGHS_DEVDMACONTROL = 0; // raz - UOTGHS->UOTGHS_DEVDMA[1].UOTGHS_DEVDMACONTROL = 0; // raz - - // Configure endpoint 2, 64 bytes, direction IN, type BULK, 1 bank - UOTGHS->UOTGHS_DEVEPTCFG[2] = UOTGHS_DEVEPTCFG_EPSIZE_64_BYTE - | UOTGHS_DEVEPTCFG_EPDIR_IN - | UOTGHS_DEVEPTCFG_EPTYPE_BLK - | UOTGHS_DEVEPTCFG_EPBK_1_BANK; - // Check if the configuration is ok - UOTGHS->UOTGHS_DEVEPTCFG[2] |= UOTGHS_DEVEPTCFG_ALLOC; - while((UOTGHS->UOTGHS_DEVEPTISR[2]&UOTGHS_DEVEPTISR_CFGOK)==0) {} - UOTGHS->UOTGHS_DEVEPT |= UOTGHS_DEVEPT_EPEN2; - // Write FIFO - for( i=0; i<sizeof(test_packet_buffer); i++) - { - ptr_dest[i] = test_packet_buffer[i];; - } - // Tst PACKET - UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTPCKT; - // Send packet - UOTGHS->UOTGHS_DEVEPTICR[2] = UOTGHS_DEVEPTICR_TXINIC; - UOTGHS->UOTGHS_DEVEPTIDR[2] = UOTGHS_DEVEPTIDR_FIFOCONC; - for(;;); -// break; - - case 1: - //Test mode Test_J: - //Upon command, a port's transceiver must enter the high-speed J state and remain in that - //state until the exit action is taken. This enables the testing of the high output drive - //level on the D+ line. - // Send a ZLP - USB_SendZlp(); - UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTJ; - for(;;); -// break; - - case 2: - //Test mode Test_K: - //Upon command, a port's transceiver must enter the high-speed K state and remain in - //that state until the exit action is taken. This enables the testing of the high output drive - //level on the D- line. - // Send a ZLP - USB_SendZlp(); - UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTK; - for(;;); -// break; - - case 3: - //Test mode Test_SE0_NAK: - //Upon command, a port's transceiver must enter the high-speed receive mode - //and remain in that mode until the exit action is taken. This enables the testing - //of output impedance, low level output voltage, and loading characteristics. - //In addition, while in this mode, upstream facing ports (and only upstream facing ports) - //must respond to any IN token packet with a NAK handshake (only if the packet CRC is - //determined to be correct) within the normal allowed device response time. This enables testing of - //the device squelch level circuitry and, additionally, provides a general purpose stimulus/response - //test for basic functional testing. - - // Send a ZLP - USB_SendZlp(); - UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_SUSPEC - | UOTGHS_DEVIDR_MSOFEC - | UOTGHS_DEVIDR_SOFEC - | UOTGHS_DEVIDR_EORSTEC - | UOTGHS_DEVIDR_WAKEUPEC - | UOTGHS_DEVIDR_EORSMEC - | UOTGHS_DEVIDR_UPRSMEC - | UOTGHS_DEVIDR_PEP_0 - | UOTGHS_DEVIDR_PEP_1 - | UOTGHS_DEVIDR_PEP_2 - | UOTGHS_DEVIDR_PEP_3 - | UOTGHS_DEVIDR_PEP_4 - | UOTGHS_DEVIDR_PEP_5 - | UOTGHS_DEVIDR_PEP_6 - | UOTGHS_DEVIDR_DMA_1 - | UOTGHS_DEVIDR_DMA_2 - | UOTGHS_DEVIDR_DMA_3 - | UOTGHS_DEVIDR_DMA_4 - | UOTGHS_DEVIDR_DMA_5 - | UOTGHS_DEVIDR_DMA_6; - for(;;); -// break; - } -} +//static void USB_SendZlp( void ) +//{ +// //while( UOTGHS_DEVEPTISR_TXINI != (UOTGHS->UOTGHS_DEVEPTISR[0] & UOTGHS_DEVEPTISR_TXINI ) ) +// while (!(USB->DEVICE.DeviceEndpoint[EP0].EPSTATUS.reg & USB_DEVICE_EPSTATUSCLR_BK1RDY)) +// { +// //if((UOTGHS->UOTGHS_DEVISR & UOTGHS_DEVISR_SUSP) == UOTGHS_DEVISR_SUSP) +// if((USB->DEVICE.INTFLAG.reg & USB_DEVICE_INTFLAG_SUSPEND) == USB_DEVICE_INTFLAG_SUSPEND) +// { +// return; +// } +// } +// //UOTGHS->UOTGHS_DEVEPTICR[0] = UOTGHS_DEVEPTICR_TXINIC; +// USB->DEVICE.DeviceEndpoint[EP0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY; +//} +// //unsigned int iii=0; // Endpoint 0 interrupt -static void USB_ISR(void) +void USB_Handler(void) { // printf("ISR=0x%X\n\r", UOTGHS->UOTGHS_DEVISR); // jcb // if( iii++ > 1500 ) while(1); // jcb @@ -601,12 +520,12 @@ static void USB_ISR(void) // Reset USB address to 0 udd_configure_address(0); - udd_enable_address(); + //udd_enable_address(); // Configure EP 0 UDD_InitEP(0, EP_TYPE_CONTROL); udd_enable_setup_received_interrupt(0); - udd_enable_endpoint_interrupt(0); + // udd_enable_endpoint_interrupt(0); _usbConfiguration = 0; udd_ack_reset(); @@ -645,7 +564,7 @@ static void USB_ISR(void) if (requestType & REQUEST_DEVICETOHOST) { TRACE_CORE(puts(">>> EP0 Int: IN Request\r\n");) - UDD_WaitIN(); +//JCB UDD_WaitIN(); } else { @@ -719,26 +638,26 @@ static void USB_ISR(void) //USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest)); UDD_Send8(EP0, 0); } - if( setup.wValueL == 2) // TEST_MODE - { - // 7.1.20 Test Mode Support, 9.4.9 SetFeature - if( (setup.bmRequestType == 0 /*USBGenericRequest_DEVICE*/) && - ((setup.wIndex & 0x000F) == 0) ) - { - // the lower byte of wIndex must be zero - // the most significant byte of wIndex is used to specify the specific test mode - - UOTGHS->UOTGHS_DEVIDR &= ~UOTGHS_DEVIDR_SUSPEC; - UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_SPDCONF_HIGH_SPEED; // remove suspend ? - - Test_Mode_Support( (setup.wIndex & 0xFF00)>>8 ); - } - } +// if( setup.wValueL == 2) // TEST_MODE +// { +// // 7.1.20 Test Mode Support, 9.4.9 SetFeature +// if( (setup.bmRequestType == 0 /*USBGenericRequest_DEVICE*/) && +// ((setup.wIndex & 0x000F) == 0) ) +// { +// // the lower byte of wIndex must be zero +// // the most significant byte of wIndex is used to specify the specific test mode +// +// UOTGHS->UOTGHS_DEVIDR &= ~UOTGHS_DEVIDR_SUSPEC; +// UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_SPDCONF_HIGH_SPEED; // remove suspend ? +// +// Test_Mode_Support( (setup.wIndex & 0xFF00)>>8 ); +// } +// } } else if (SET_ADDRESS == r) { TRACE_CORE(puts(">>> EP0 Int: SET_ADDRESS\r\n");) - UDD_WaitIN(); +//JCB UDD_WaitIN(); UDD_SetAddress(setup.wValueL); } else if (GET_DESCRIPTOR == r) @@ -768,7 +687,7 @@ static void USB_ISR(void) #ifdef CDC_ENABLED // Enable interrupt for CDC reception from host (OUT packet) udd_enable_out_received_interrupt(CDC_RX); - udd_enable_endpoint_interrupt(CDC_RX); + // udd_enable_endpoint_interrupt(CDC_RX); #endif } else @@ -792,7 +711,7 @@ static void USB_ISR(void) { TRACE_CORE(puts(">>> EP0 Int: ClassInterfaceRequest\r\n");) - UDD_WaitIN(); // Workaround: need tempo here, else CDC serial won't open correctly +//JCB UDD_WaitIN(); // Workaround: need tempo here, else CDC serial won't open correctly USBD_InitControl(setup.wLength); // Max length of transfer ok = USBD_ClassInterfaceRequest(setup); @@ -806,7 +725,7 @@ static void USB_ISR(void) else { TRACE_CORE(puts(">>> EP0 Int: Stall\r\n");) - UDD_Stall(); + UDD_Stall(0); } } } @@ -823,7 +742,7 @@ uint32_t USBD_Connected(void) { uint8_t f = UDD_GetFrameNumber(); - delay(3); +//delay(3); //JCB return f != UDD_GetFrameNumber(); } @@ -836,12 +755,14 @@ USBDevice_ USBDevice; USBDevice_::USBDevice_() { - UDD_SetStack(&USB_ISR); - - if (UDD_Init() == 0UL) - { - _usbInitialized=1UL; - } + //UDD_SetStack(&USB_ISR); + +// if (UDD_Init() == 0UL) +// { +// _usbInitialized=1UL; +// } + UDD_Init(); + _usbInitialized=1UL; } bool USBDevice_::attach(void) @@ -858,7 +779,7 @@ bool USBDevice_::attach(void) } } -bool USBDevice_::detach(void) +bool USBDevice_::detach() { if (_usbInitialized != 0UL) { diff --git a/cores/arduino/USB/USBCore.h b/cores/arduino/USB/USBCore.h index b01d7576..8d1bfd52 100644 --- a/cores/arduino/USB/USBCore.h +++ b/cores/arduino/USB/USBCore.h @@ -287,8 +287,8 @@ _Pragma("pack()") #define D_CONFIG(_totalLength,_interfaces) \ { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_SELF_POWERED, USB_CONFIG_POWER_MA(500) } -#define D_OTHERCONFIG(_totalLength,_interfaces) \ - { 9, 7, _totalLength,_interfaces, 1, 0, USB_CONFIG_SELF_POWERED, USB_CONFIG_POWER_MA(500) } +//#define D_OTHERCONFIG(_totalLength,_interfaces) +// { 9, 7, _totalLength,_interfaces, 1, 0, USB_CONFIG_SELF_POWERED, USB_CONFIG_POWER_MA(500) } #define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \ { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 } @@ -296,8 +296,8 @@ _Pragma("pack()") #define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \ { 7, 5, _addr,_attr,_packetSize, _interval } -#define D_QUALIFIER(_class,_subClass,_proto,_packetSize0,_configs) \ - { 10, 6, 0x200, _class,_subClass,_proto,_packetSize0,_configs } +//#define D_QUALIFIER(_class,_subClass,_proto,_packetSize0,_configs) +// { 10, 6, 0x200, _class,_subClass,_proto,_packetSize0,_configs } #define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \ { 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 } diff --git a/cores/arduino/USB/USBDesc.h b/cores/arduino/USB/USBDesc.h index 878095e2..49b85115 100644 --- a/cores/arduino/USB/USBDesc.h +++ b/cores/arduino/USB/USBDesc.h @@ -18,7 +18,7 @@ #define __USBDESC_H__ #define CDC_ENABLED -#define HID_ENABLED +//#define HID_ENABLED #ifdef CDC_ENABLED #define CDC_INTERFACE_COUNT 2 diff --git a/cores/arduino/USB/USB_device.h b/cores/arduino/USB/USB_device.h new file mode 100644 index 00000000..db909352 --- /dev/null +++ b/cores/arduino/USB/USB_device.h @@ -0,0 +1,412 @@ +/* ---------------------------------------------------------------------------- + * SAM Software Package License + * ---------------------------------------------------------------------------- + * Copyright (c) 2011-2012, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following condition is met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +#ifndef USB_DEVICE_H_INCLUDED +#define USB_DEVICE_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include "samd21_device.h" + +extern void UDD_WaitIN(void); +//extern void UDD_WaitOUT(void); +extern void UDD_ClearIN(void); +extern void UDD_ClearOUT(void); +extern uint32_t UDD_WaitForINOrOUT(void); +extern void UDD_ClearRxFlag(unsigned char bEndpoint); +extern uint32_t UDD_ReceivedSetupInt(void); +extern void UDD_ClearSetupInt(void); +//extern uint32_t UDD_ReadWriteAllowed(uint32_t ep); +extern uint32_t UDD_FifoByteCount(uint32_t ep); +extern uint8_t UDD_FifoFree(void); +extern void UDD_ReleaseRX(uint32_t ep); +extern void UDD_ReleaseTX(uint32_t ep); +extern uint8_t UDD_FrameNumber(void); +extern uint8_t UDD_GetConfiguration(void); + +extern uint32_t UDD_Send(uint32_t ep, const void* data, uint32_t len); +extern void UDD_Send8(uint32_t ep, uint8_t data ); +extern uint8_t UDD_Recv8(uint32_t ep); +extern void UDD_Recv(uint32_t ep, uint8_t* data, uint32_t len); + +extern void UDD_InitEndpoints(const uint8_t* eps_table, const uint8_t ul_eps_table_size); +extern void UDD_InitControl(int end); +extern uint32_t UDD_Init(void); +extern void UDD_InitEP( uint32_t ul_ep, uint32_t ul_ep_cfg ); + +extern void UDD_Attach(void); +extern void UDD_Detach(void); + +//extern void UDD_SetStack(void (*pf_isr)(void)); +extern void UDD_SetAddress(uint32_t addr); +extern void UDD_Stall(uint32_t ep); +extern uint32_t UDD_GetFrameNumber(void); + +/*! \name Usual Types + */ + +//! @{ + +typedef unsigned char Bool; //!< Boolean. +#ifndef __cplusplus +#if !defined(__bool_true_false_are_defined) +typedef unsigned char bool; //!< Boolean. +#endif +#endif +typedef int8_t S8; //!< 8-bit signed integer. +typedef uint8_t U8; //!< 8-bit unsigned integer. +typedef int16_t S16; //!< 16-bit signed integer. +typedef uint16_t U16; //!< 16-bit unsigned integer. +typedef uint16_t le16_t; +typedef uint16_t be16_t; +typedef int32_t S32; //!< 32-bit signed integer. +typedef uint32_t U32; //!< 32-bit unsigned integer. +typedef uint32_t le32_t; +typedef uint32_t be32_t; +typedef int64_t S64; //!< 64-bit signed integer. +typedef uint64_t U64; //!< 64-bit unsigned integer. +typedef float F32; //!< 32-bit floating-point number. +typedef double F64; //!< 64-bit floating-point number. +typedef uint32_t iram_size_t; + +//! @} + +/*! \name Bit-Field Handling + */ +//! @{ + +/*! \brief Reads the bits of a value specified by a given bit-mask. + * + * \param value Value to read bits from. + * \param mask Bit-mask indicating bits to read. + * + * \return Read bits. + */ +#define Rd_bits( value, mask) ((value) & (mask)) + +/*! \brief Writes the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue to write bits to. + * \param mask Bit-mask indicating bits to write. + * \param bits Bits to write. + * + * \return Resulting value with written bits. + */ +#define Wr_bits(lvalue, mask, bits) ((lvalue) = ((lvalue) & ~(mask)) |\ + ((bits ) & (mask))) + +/*! \brief Tests the bits of a value specified by a given bit-mask. + * + * \param value Value of which to test bits. + * \param mask Bit-mask indicating bits to test. + * + * \return \c 1 if at least one of the tested bits is set, else \c 0. + */ +#define Tst_bits( value, mask) (Rd_bits(value, mask) != 0) + +/*! \brief Clears the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to clear bits. + * \param mask Bit-mask indicating bits to clear. + * + * \return Resulting value with cleared bits. + */ +#define Clr_bits(lvalue, mask) ((lvalue) &= ~(mask)) + +/*! \brief Sets the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to set bits. + * \param mask Bit-mask indicating bits to set. + * + * \return Resulting value with set bits. + */ +#define Set_bits(lvalue, mask) ((lvalue) |= (mask)) + +/*! \brief Toggles the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to toggle bits. + * \param mask Bit-mask indicating bits to toggle. + * + * \return Resulting value with toggled bits. + */ +#define Tgl_bits(lvalue, mask) ((lvalue) ^= (mask)) + +/*! \brief Reads the bit-field of a value specified by a given bit-mask. + * + * \param value Value to read a bit-field from. + * \param mask Bit-mask indicating the bit-field to read. + * + * \return Read bit-field. + */ +#define Rd_bitfield( value, mask) (Rd_bits( value, mask) >> ctz(mask)) + +/*! \brief Writes the bit-field of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue to write a bit-field to. + * \param mask Bit-mask indicating the bit-field to write. + * \param bitfield Bit-field to write. + * + * \return Resulting value with written bit-field. + */ +#define Wr_bitfield(lvalue, mask, bitfield) (Wr_bits(lvalue, mask, (U32)(bitfield) << ctz(mask))) + +//! @} + +/*! \name Token Paste + * + * Paste N preprocessing tokens together, these tokens being allowed to be \#defined. + * + * May be used only within macros with the tokens passed as arguments if the tokens are \#defined. + * + * For example, writing TPASTE2(U, WIDTH) within a macro \#defined by + * UTYPE(WIDTH) and invoked as UTYPE(UL_WIDTH) with UL_WIDTH \#defined as 32 is + * equivalent to writing U32. + */ + +//! @{ + +#define TPASTE2( a, b) a##b +#define TPASTE3( a, b, c) a##b##c +#define TPASTE4( a, b, c, d) a##b##c##d +#define TPASTE5( a, b, c, d, e) a##b##c##d##e +#define TPASTE6( a, b, c, d, e, f) a##b##c##d##e##f +#define TPASTE7( a, b, c, d, e, f, g) a##b##c##d##e##f##g +#define TPASTE8( a, b, c, d, e, f, g, h) a##b##c##d##e##f##g##h +#define TPASTE9( a, b, c, d, e, f, g, h, i) a##b##c##d##e##f##g##h##i +#define TPASTE10(a, b, c, d, e, f, g, h, i, j) a##b##c##d##e##f##g##h##i##j + +//! @} + +/*! \name Absolute Token Paste + * + * Paste N preprocessing tokens together, these tokens being allowed to be \#defined. + * + * No restriction of use if the tokens are \#defined. + * + * For example, writing ATPASTE2(U, UL_WIDTH) anywhere with UL_WIDTH \#defined + * as 32 is equivalent to writing U32. + */ + +//! @{ + +#define ATPASTE2( a, b) TPASTE2( a, b) +#define ATPASTE3( a, b, c) TPASTE3( a, b, c) +#define ATPASTE4( a, b, c, d) TPASTE4( a, b, c, d) +#define ATPASTE5( a, b, c, d, e) TPASTE5( a, b, c, d, e) +#define ATPASTE6( a, b, c, d, e, f) TPASTE6( a, b, c, d, e, f) +#define ATPASTE7( a, b, c, d, e, f, g) TPASTE7( a, b, c, d, e, f, g) +#define ATPASTE8( a, b, c, d, e, f, g, h) TPASTE8( a, b, c, d, e, f, g, h) +#define ATPASTE9( a, b, c, d, e, f, g, h, i) TPASTE9( a, b, c, d, e, f, g, h, i) +#define ATPASTE10(a, b, c, d, e, f, g, h, i, j) TPASTE10(a, b, c, d, e, f, g, h, i, j) + +//! @} + +/*! \brief Counts the trailing zero bits of the given value considered as a 32-bit integer. + * + * \param u Value of which to count the trailing zero bits. + * + * \return The count of trailing zero bits in \a u. + */ +#if (defined __GNUC__) || (defined __CC_ARM) +# define ctz(u) __builtin_ctz(u) +#else +# define ctz(u) ((u) & (1ul << 0) ? 0 : \ + (u) & (1ul << 1) ? 1 : \ + (u) & (1ul << 2) ? 2 : \ + (u) & (1ul << 3) ? 3 : \ + (u) & (1ul << 4) ? 4 : \ + (u) & (1ul << 5) ? 5 : \ + (u) & (1ul << 6) ? 6 : \ + (u) & (1ul << 7) ? 7 : \ + (u) & (1ul << 8) ? 8 : \ + (u) & (1ul << 9) ? 9 : \ + (u) & (1ul << 10) ? 10 : \ + (u) & (1ul << 11) ? 11 : \ + (u) & (1ul << 12) ? 12 : \ + (u) & (1ul << 13) ? 13 : \ + (u) & (1ul << 14) ? 14 : \ + (u) & (1ul << 15) ? 15 : \ + (u) & (1ul << 16) ? 16 : \ + (u) & (1ul << 17) ? 17 : \ + (u) & (1ul << 18) ? 18 : \ + (u) & (1ul << 19) ? 19 : \ + (u) & (1ul << 20) ? 20 : \ + (u) & (1ul << 21) ? 21 : \ + (u) & (1ul << 22) ? 22 : \ + (u) & (1ul << 23) ? 23 : \ + (u) & (1ul << 24) ? 24 : \ + (u) & (1ul << 25) ? 25 : \ + (u) & (1ul << 26) ? 26 : \ + (u) & (1ul << 27) ? 27 : \ + (u) & (1ul << 28) ? 28 : \ + (u) & (1ul << 29) ? 29 : \ + (u) & (1ul << 30) ? 30 : \ + (u) & (1ul << 31) ? 31 : \ + 32) +#endif + +/*! \name Zero-Bit Counting + * + * Under GCC, __builtin_clz and __builtin_ctz behave like macros when + * applied to constant expressions (values known at compile time), so they are + * more optimized than the use of the corresponding assembly instructions and + * they can be used as constant expressions e.g. to initialize objects having + * static storage duration, and like the corresponding assembly instructions + * when applied to non-constant expressions (values unknown at compile time), so + * they are more optimized than an assembly periphrasis. Hence, clz and ctz + * ensure a possible and optimized behavior for both constant and non-constant + * expressions. + */ +//! @{ + +/*! \brief Counts the leading zero bits of the given value considered as a 32-bit integer. + * + * \param u Value of which to count the leading zero bits. + * + * \return The count of leading zero bits in \a u. + */ +#if (defined __GNUC__) || (defined __CC_ARM) +# define clz(u) __builtin_clz(u) +#elif (defined __ICCARM__) +# define clz(u) __CLZ(u) +#else +# define clz(u) (((u) == 0) ? 32 : \ + ((u) & (1ul << 31)) ? 0 : \ + ((u) & (1ul << 30)) ? 1 : \ + ((u) & (1ul << 29)) ? 2 : \ + ((u) & (1ul << 28)) ? 3 : \ + ((u) & (1ul << 27)) ? 4 : \ + ((u) & (1ul << 26)) ? 5 : \ + ((u) & (1ul << 25)) ? 6 : \ + ((u) & (1ul << 24)) ? 7 : \ + ((u) & (1ul << 23)) ? 8 : \ + ((u) & (1ul << 22)) ? 9 : \ + ((u) & (1ul << 21)) ? 10 : \ + ((u) & (1ul << 20)) ? 11 : \ + ((u) & (1ul << 19)) ? 12 : \ + ((u) & (1ul << 18)) ? 13 : \ + ((u) & (1ul << 17)) ? 14 : \ + ((u) & (1ul << 16)) ? 15 : \ + ((u) & (1ul << 15)) ? 16 : \ + ((u) & (1ul << 14)) ? 17 : \ + ((u) & (1ul << 13)) ? 18 : \ + ((u) & (1ul << 12)) ? 19 : \ + ((u) & (1ul << 11)) ? 20 : \ + ((u) & (1ul << 10)) ? 21 : \ + ((u) & (1ul << 9)) ? 22 : \ + ((u) & (1ul << 8)) ? 23 : \ + ((u) & (1ul << 7)) ? 24 : \ + ((u) & (1ul << 6)) ? 25 : \ + ((u) & (1ul << 5)) ? 26 : \ + ((u) & (1ul << 4)) ? 27 : \ + ((u) & (1ul << 3)) ? 28 : \ + ((u) & (1ul << 2)) ? 29 : \ + ((u) & (1ul << 1)) ? 30 : \ + 31) +#endif + +/*! \name Mathematics + * + * The same considerations as for clz and ctz apply here but GCC does not + * provide built-in functions to access the assembly instructions abs, min and + * max and it does not produce them by itself in most cases, so two sets of + * macros are defined here: + * - Abs, Min and Max to apply to constant expressions (values known at + * compile time); + * - abs, min and max to apply to non-constant expressions (values unknown at + * compile time), abs is found in stdlib.h. + */ +//! @{ + +///*! \brief Takes the absolute value of \a a. +// * +// * \param a Input value. +// * +// * \return Absolute value of \a a. +// * +// * \note More optimized if only used with values known at compile time. +// */ +//#define Abs(a) (((a) < 0 ) ? -(a) : (a)) +// +///*! \brief Takes the minimal value of \a a and \a b. +// * +// * \param a Input value. +// * \param b Input value. +// * +// * \return Minimal value of \a a and \a b. +// * +// * \note More optimized if only used with values known at compile time. +// */ +//#define Min(a, b) (((a) < (b)) ? (a) : (b)) +// +///*! \brief Takes the maximal value of \a a and \a b. +// * +// * \param a Input value. +// * \param b Input value. +// * +// * \return Maximal value of \a a and \a b. +// * +// * \note More optimized if only used with values known at compile time. +// */ +//#define Max(a, b) (((a) > (b)) ? (a) : (b)) +// +//// abs() is already defined by stdlib.h +// +///*! \brief Takes the minimal value of \a a and \a b. +// * +// * \param a Input value. +// * \param b Input value. +// * +// * \return Minimal value of \a a and \a b. +// * +// * \note More optimized if only used with values unknown at compile time. +// */ +//#define min(a, b) Min(a, b) +// +///*! \brief Takes the maximal value of \a a and \a b. +// * +// * \param a Input value. +// * \param b Input value. +// * +// * \return Maximal value of \a a and \a b. +// * +// * \note More optimized if only used with values unknown at compile time. +// */ +//#define max(a, b) Max(a, b) +// +////! @} + +#ifdef __cplusplus +} +#endif + +#endif /* USB_DEVICE_H_INCLUDED */ diff --git a/cores/arduino/USB/USB_host.h b/cores/arduino/USB/USB_host.h new file mode 100644 index 00000000..73221c46 --- /dev/null +++ b/cores/arduino/USB/USB_host.h @@ -0,0 +1,78 @@ +/* ---------------------------------------------------------------------------- + * SAM Software Package License + * ---------------------------------------------------------------------------- + * Copyright (c) 2011-2012, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following condition is met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +#ifndef USB_HOST_H_INCLUDED +#define USB_HOST_H_INCLUDED + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define tokSETUP UOTGHS_HSTPIPCFG_PTOKEN_SETUP +#define tokIN UOTGHS_HSTPIPCFG_PTOKEN_IN +#define tokOUT UOTGHS_HSTPIPCFG_PTOKEN_OUT +#define tokINHS UOTGHS_HSTPIPCFG_PTOKEN_IN +#define tokOUTHS UOTGHS_HSTPIPCFG_PTOKEN_OUT + +//! \brief Device speed +/*typedef enum { + UHD_SPEED_LOW = 0, + UHD_SPEED_FULL = 1, + UHD_SPEED_HIGH = 2, +} uhd_speed_t;*/ + +//! States of USBB interface +typedef enum { + UHD_STATE_NO_VBUS = 0, + UHD_STATE_DISCONNECTED = 1, + UHD_STATE_CONNECTED = 2, + UHD_STATE_ERROR = 3, +} uhd_vbus_state_t; + +//extern uhd_speed_t uhd_get_speed(void); + +extern void UHD_SetStack(void (*pf_isr)(void)); +extern void UHD_Init(void); +extern void UHD_BusReset(void); +extern uhd_vbus_state_t UHD_GetVBUSState(void); +extern uint32_t UHD_Pipe0_Alloc(uint32_t ul_add, uint32_t ul_ep_size); +extern uint32_t UHD_Pipe_Alloc(uint32_t ul_dev_addr, uint32_t ul_dev_ep, uint32_t ul_type, uint32_t ul_dir, uint32_t ul_maxsize, uint32_t ul_interval, uint32_t ul_nb_bank); +extern void UHD_Pipe_Free(uint32_t ul_pipe); +extern uint32_t UHD_Pipe_Read(uint32_t ul_pipe, uint32_t ul_size, uint8_t* data); +extern void UHD_Pipe_Write(uint32_t ul_pipe, uint32_t ul_size, uint8_t* data); +extern void UHD_Pipe_Send(uint32_t ul_pipe, uint32_t ul_token_type); +extern uint32_t UHD_Pipe_Is_Transfer_Complete(uint32_t ul_pipe, uint32_t ul_token_type); + +#ifdef __cplusplus +} +#endif + +#endif /* USB_HOST_H_INCLUDED */ diff --git a/cores/arduino/USB/samd21_device.c b/cores/arduino/USB/samd21_device.c new file mode 100644 index 00000000..65fb503f --- /dev/null +++ b/cores/arduino/USB/samd21_device.c @@ -0,0 +1,713 @@ +/* ---------------------------------------------------------------------------- + * SAM Software Package License + * ---------------------------------------------------------------------------- + * Copyright (c) 2011-2012, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following condition is met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +#include <stdio.h> +#include <stdint.h> + +#include "variant.h" +#include "USB_device.h" +#include "samd21_device.h" +#include "sam.h" + +#ifdef __cplusplus +extern "C"{ +#endif // __cplusplus + +#ifdef SAMD_SERIES +extern uint8_t usb_device_endpoint_is_configured(uint8_t ep); + +#define TRACE_DEVICE(x) x +//#define TRACE_DEVICE(x) + +// Endpoint transfer direction is IN +#define USB_EP_DIR_IN 0x80 +// Endpoint transfer direction is OUT +#define USB_EP_DIR_OUT 0x00 + +extern void (*gpf_isr)(void); + +static volatile uint32_t ul_send_fifo_ptr[USB_EPT_NUM]; +static volatile uint32_t ul_recv_fifo_ptr[USB_EPT_NUM]; + +/** + * USB SRAM data containing pipe descriptor table + * The content of the USB SRAM can be : + * - modified by USB hardware interface to update pipe status. + * Thereby, it is read by software. + * - modified by USB software to control pipe. + * Thereby, it is read by hardware. + * This data section is volatile. + */ + +#if (defined __GNUC__) || defined(__CC_ARM) +#define COMPILER_WORD_ALIGNED __attribute__((__aligned__(4))) +#elif (defined __ICCARM__) +#define COMPILER_WORD_ALIGNED _Pragma("data_alignment = 4") +#endif + +#ifdef __ICCARM__ +_Pragma("pack(4)") +#else +COMPILER_WORD_ALIGNED +#endif +union { + UsbDeviceDescriptor usb_endpoint_table[USB_EPT_NUM]; + UsbHostDescriptor usb_pipe_table[USB_PIPE_NUM]; +} usb_descriptor_table; +_Pragma("pack()") + + +//void (*gpf_isr)(void) = (0UL); +// +//void UOTGHS_Handler( void ) +//{ +// if (gpf_isr) +// gpf_isr(); +//} +//void UDD_SetStack(void (*pf_isr)(void)) +//{ +// gpf_isr = pf_isr; +//} + +// NVM Software Calibration Area Mapping +// USB TRANSN calibration value. Should be written to the USB PADCAL register. +#define NVM_USB_PAD_TRANSN_POS 45 +#define NVM_USB_PAD_TRANSN_SIZE 5 +// USB TRANSP calibration value. Should be written to the USB PADCAL register. +#define NVM_USB_PAD_TRANSP_POS 50 +#define NVM_USB_PAD_TRANSP_SIZE 5 +// USB TRIM calibration value. Should be written to the USB PADCAL register. +#define NVM_USB_PAD_TRIM_POS 55 +#define NVM_USB_PAD_TRIM_SIZE 3 + +uint32_t UDD_Init(void) +{ + uint32_t i; + uint32_t pad_transn; + uint32_t pad_transp; + uint32_t pad_trim; +// struct system_pinmux_config pin_config; +// struct system_gclk_chan_config gclk_chan_config; +// +// /* Turn on the digital interface clock */ +// system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBB, PM_APBBMASK_USB); +// +// /* Set up the USB DP/DN pins */ +// system_pinmux_get_config_defaults(&pin_config); +// pin_config.mux_position = MUX_PA24G_USB_DM; +// system_pinmux_pin_set_config(PIN_PA24G_USB_DM, &pin_config); +// pin_config.mux_position = MUX_PA25G_USB_DP; +// system_pinmux_pin_set_config(PIN_PA25G_USB_DP, &pin_config); +// +// /* Setup clock for module */ +// system_gclk_chan_get_config_defaults(&gclk_chan_config); +// gclk_chan_config.source_generator = module_config->source_generator; +// system_gclk_chan_set_config(USB_GCLK_ID, &gclk_chan_config); +// system_gclk_chan_enable(USB_GCLK_ID); +// pin_config.mux_position = MUX_PB14H_GCLK_IO0; +// pin_config.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT; +// system_pinmux_pin_set_config(PIN_PB14H_GCLK_IO0, &pin_config); + + /* Reset */ + USB->DEVICE.CTRLA.bit.SWRST = 1; + while (USB->DEVICE.SYNCBUSY.bit.SWRST) { + /* Sync wait */ + } + + /* Load Pad Calibration */ + pad_transn =( *((uint32_t *)(NVMCTRL_OTP4) // Non-Volatile Memory Controller + + (NVM_USB_PAD_TRANSN_POS / 32)) + >> (NVM_USB_PAD_TRANSN_POS % 32)) + & ((1 << NVM_USB_PAD_TRANSN_SIZE) - 1); + + if (pad_transn == 0x1F) { // maximum value (31) + pad_transn = 5; + } + + USB->DEVICE.PADCAL.bit.TRANSN = pad_transn; + + pad_transp =( *((uint32_t *)(NVMCTRL_OTP4) + + (NVM_USB_PAD_TRANSP_POS / 32)) + >> (NVM_USB_PAD_TRANSP_POS % 32)) + & ((1 << NVM_USB_PAD_TRANSP_SIZE) - 1); + + if (pad_transp == 0x1F) { // maximum value (31) + pad_transp = 29; + } + + USB->DEVICE.PADCAL.bit.TRANSP = pad_transp; + + pad_trim =( *((uint32_t *)(NVMCTRL_OTP4) + + (NVM_USB_PAD_TRIM_POS / 32)) + >> (NVM_USB_PAD_TRIM_POS % 32)) + & ((1 << NVM_USB_PAD_TRIM_SIZE) - 1); + + if (pad_trim == 0x7) { // maximum value (7) + pad_trim = 3; + } + + USB->DEVICE.PADCAL.bit.TRIM = pad_trim; + + /* Set the configuration */ + udd_force_device_mode(); + udd_device_run_in_standby(); + // Set address of USB SRAM + USB->DEVICE.DESCADD.reg = (uint32_t)(&usb_descriptor_table.usb_endpoint_table[0]); + // For USB_SPEED_FULL + udd_force_full_speed(); + // For USB_LOW_FULL + //udd_force_low_speed(); + + // Clear USB RAM +// memset((uint8_t *)(&usb_descriptor_table.usb_endpoint_table[0]), 0, +// sizeof(usb_descriptor_table.usb_endpoint_table)); + + for (i = 0; i < sizeof(usb_descriptor_table.usb_endpoint_table); i++) { + (*(uint32_t *)(&usb_descriptor_table.usb_endpoint_table[0]+i)) = 0; + } + + +// /* device callback related */ +// for (i = 0; i < USB_DEVICE_CALLBACK_N; i++) { +// module_inst->device_callback[i] = NULL; +// } +// for (i = 0; i < USB_EPT_NUM; i++) { +// for(j = 0; j < USB_DEVICE_EP_CALLBACK_N; j++) { +// module_inst->device_endpoint_callback[i][j] = NULL; +// } +// } +// module_inst->device_registered_callback_mask = 0; +// module_inst->device_enabled_callback_mask = 0; +// for (j = 0; j < USB_EPT_NUM; j++) { +// module_inst->device_endpoint_registered_callback_mask[j] = 0; +// module_inst->device_endpoint_enabled_callback_mask[j] = 0; +// } + + /* Enable interrupts for this USB module */ +// system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_USB); + // Configure interrupts + NVIC_SetPriority((IRQn_Type) USB_IRQn, 0UL); + NVIC_EnableIRQ((IRQn_Type) USB_IRQn); + +// uint32_t i; +// +// for (i = 0; i < USB_EPT_NUM; ++i) +// { +// ul_send_fifo_ptr[i] = 0; +// ul_recv_fifo_ptr[i] = 0; +// } +// +// // Enables the USB Clock +// pmc_enable_periph_clk(ID_USB); +// pmc_enable_upll_clock(); +// pmc_switch_udpck_to_upllck(0); // div=0+1 +// pmc_enable_udpck(); +// +// // Configure interrupts +// NVIC_SetPriority((IRQn_Type) USB_IRQn, 0UL); +// NVIC_EnableIRQ((IRQn_Type) USB_IRQn); +// +// // 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); +// +// // ID pin not used then force device mode +//// otg_disable_id_pin(); +// udd_force_device_mode(); +// +// // Enable USB hardware +// +// // The Pad Calibration values must be loaded from the NVM Software Calibration Area into the USB Pad Calibration +// // register by software, before enabling the USB, to achieve the specified accuracy. Refer to “NVM Software Calibration +// // Area Mapping” on page 21 for further details. +// JCB TODO; +// +// // otg_disable_pad(); +//// otg_enable_pad(); +// udd_enable(); +//// otg_unfreeze_clock(); +// +// // Check USB clock +// //while (!Is_otg_clock_usable()) +// // ; +// +// // Force full Speed +// udd_force_full_speed(); +// +// //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(); +// + return 0UL ; +} + +void UDD_Attach(void) +{ +// irqflags_t flags = cpu_irq_save(); + + TRACE_DEVICE(printf("=> UDD_Attach\r\n");) + + // Authorize attach if Vbus is present + udd_attach_device(); + + // Enable USB line events + udd_enable_reset_interrupt(); + + // usefull for debug + udd_enable_sof_interrupt(); + +// cpu_irq_restore(flags); +} + +void UDD_Detach(void) +{ + TRACE_DEVICE(printf("=> UDD_Detach\r\n");) + udd_detach_device(); +} + + +/** + * \brief Check if current endpoint is configured + * + * \param module_inst Pointer to USB software instance struct + * \param ep Endpoint address (direction & number) + * + * \return \c true if endpoint is configured and ready to use + */ +uint8_t usb_device_endpoint_is_configured(uint8_t ep) +{ + uint8_t ep_num = ep & 0xF; + uint8_t flag; + + if (ep & USB_EP_DIR_IN) { + flag = USB->DEVICE.DeviceEndpoint[ep_num].EPCFG.bit.EPTYPE1; + } else { + flag = USB->DEVICE.DeviceEndpoint[ep_num].EPCFG.bit.EPTYPE0; + } + return( flag != 0 ); // JCB to be checked +} + + + + +//// CONTROL configuration: +//enum status_code usb_device_endpoint_set_config(struct usb_module *module_inst, + //struct usb_device_endpoint_config *ep_config) +void UDD_InitEP( uint32_t ul_ep_nb, uint32_t ul_ep_cfg ) +{ + /* Sanity check arguments */ +// Assert(module_inst); +// Assert(ep_config); + + TRACE_DEVICE(printf("=> UDD_InitEP : init EP %lu\r\n", (unsigned long)ul_ep_nb);) + + if ((USB->DEVICE.DeviceEndpoint[ul_ep_nb].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE0_Msk) == 0 && \ + (USB->DEVICE.DeviceEndpoint[ul_ep_nb].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE1_Msk) == 0) { + + USB->DEVICE.DeviceEndpoint[ul_ep_nb].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(1) | USB_DEVICE_EPCFG_EPTYPE1(1); + USB->DEVICE.DeviceEndpoint[ul_ep_nb].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY; + USB->DEVICE.DeviceEndpoint[ul_ep_nb].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; + } else { + TRACE_DEVICE(printf("=> UDD_InitEP : ERROR ALREADY INITIALIZED EP %lu\r\n", (unsigned long)ul_ep_nb);) + while(1); + } + + usb_descriptor_table.usb_endpoint_table[ul_ep_nb].DeviceDescBank[0].PCKSIZE.reg &= ~USB_DEVICE_PCKSIZE_AUTO_ZLP; + usb_descriptor_table.usb_endpoint_table[ul_ep_nb].DeviceDescBank[1].PCKSIZE.reg &= ~USB_DEVICE_PCKSIZE_AUTO_ZLP; + + usb_descriptor_table.usb_endpoint_table[ul_ep_nb].DeviceDescBank[0].PCKSIZE.bit.SIZE = 0x3; // for 64 bytes + usb_descriptor_table.usb_endpoint_table[ul_ep_nb].DeviceDescBank[1].PCKSIZE.bit.SIZE = 0x3; // for 64 bytes +} + + + + +void UDD_InitEndpoints(const uint8_t* eps_table, const uint8_t ul_eps_table_size) +{ + uint8_t ul_ep_nb; + uint8_t ep_bank; + + for (ul_ep_nb = 1; ul_ep_nb < ul_eps_table_size; ul_ep_nb++) + { +// // Configure EP +// UOTGHS->UOTGHS_DEVEPTCFG[ul_ep_nb] = eps_table[ul_ep_nb]; +// // Enable EP +// udd_enable_endpoint(ul_ep_nb); +// +// if (!Is_udd_endpoint_configured(ul_ep_nb)) { +// TRACE_DEVICE(printf("=> UDD_InitEP : ERROR FAILED TO INIT EP %lu\r\n", ul_ep_nb);) +// while(1); +// } + + TRACE_DEVICE(printf("=> UDD_InitEndpoints : init EP %lu\r\n", (unsigned long)ul_ep_nb);) + + USB->DEVICE.DeviceEndpoint[ul_ep_nb].EPCFG.reg = eps_table[ul_ep_nb]& 0xEF; + ep_bank = eps_table[ul_ep_nb] >> 7; + USB->DEVICE.DeviceEndpoint[ul_ep_nb].EPSTATUSCLR.reg = ep_bank; + // JCB only 1 bank ???? + + usb_descriptor_table.usb_endpoint_table[ul_ep_nb].DeviceDescBank[ep_bank].PCKSIZE.bit.SIZE = 0x06; // for 512 + +// if (true == ep_config->auto_zlp) { + usb_descriptor_table.usb_endpoint_table[ul_ep_nb].DeviceDescBank[ep_bank].PCKSIZE.reg |= USB_DEVICE_PCKSIZE_AUTO_ZLP; +// } else { +// usb_descriptor_table.usb_endpoint_table[ul_ep_nb].DeviceDescBank[ep_bank].PCKSIZE.reg &= ~USB_DEVICE_PCKSIZE_AUTO_ZLP; +// } + } +} + +//// Wait until ready to accept IN packet. +//void UDD_WaitIN(void) +//{ +// while (!(UOTGHS->UOTGHS_DEVEPTISR[EP0] & UOTGHS_DEVEPTISR_TXINI)) +// ; +//} +// +//void UDD_WaitOUT(void) +//{ +// while (!(UOTGHS->UOTGHS_DEVEPTISR[EP0] & UOTGHS_DEVEPTISR_RXOUTI)) +// ; +//} + +// Send packet. +void UDD_ClearIN(void) +{ + TRACE_DEVICE(printf("=> UDD_ClearIN: sent %lu bytes\r\n", (unsigned long)ul_send_fifo_ptr[EP0]);) + + //UOTGHS->UOTGHS_DEVEPTICR[EP0] = UOTGHS_DEVEPTICR_TXINIC; + USB->DEVICE.DeviceEndpoint[EP0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY; + ul_send_fifo_ptr[EP0] = 0; +} + +void UDD_ClearOUT(void) +{ + //UOTGHS->UOTGHS_DEVEPTICR[EP0] = UOTGHS_DEVEPTICR_RXOUTIC; + USB->DEVICE.DeviceEndpoint[EP0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; + + ul_recv_fifo_ptr[EP0] = 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 (!(USB->DEVICE.DeviceEndpoint[EP0].EPSTATUS.reg & (USB_DEVICE_EPSTATUSCLR_BK0RDY | USB_DEVICE_EPSTATUSCLR_BK1RDY))) + ; +// while (!(UOTGHS->UOTGHS_DEVEPTISR[EP0] & (UOTGHS_DEVEPTISR_TXINI | UOTGHS_DEVEPTISR_RXOUTI))) +// ; +// return ((UOTGHS->UOTGHS_DEVEPTISR[EP0] & UOTGHS_DEVEPTISR_RXOUTI) == 0); + + return ((USB->DEVICE.DeviceEndpoint[EP0].EPSTATUS.reg & USB_DEVICE_EPSTATUSCLR_BK0RDY)); +} + + +/** + * \brief Start setup packet read job on a endpoint + * + * \param module_inst Pointer to USB device module instance + * \param pbuf Pointer to buffer + * + * \return Status of procedure + * \retval STATUS_OK Job started successfully + * \retval STATUS_ERR_DENIED Endpoint is not ready + */ +//enum status_code usb_device_endpoint_setup_buffer_job(struct usb_module *module_inst, +// uint8_t* pbuf) +//{ +// /* Sanity check arguments */ +// Assert(module_inst); +// Assert(module_inst->hw); +// +// +// return STATUS_OK; +//} +uint8_t udd_ctrl_buffer[64]; + + +uint32_t UDD_ReceivedSetupInt(void) +{ + /* get endpoint configuration from setting register */ + usb_descriptor_table.usb_endpoint_table[0].DeviceDescBank[0].ADDR.reg = (uint32_t)udd_ctrl_buffer; + usb_descriptor_table.usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 8; + usb_descriptor_table.usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; + USB->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; + +// return UOTGHS->UOTGHS_DEVEPTISR[EP0] & UOTGHS_DEVEPTISR_RXSTPI; + return (USB->DEVICE.DeviceEndpoint[0].EPSTATUS.reg & USB_DEVICE_EPSTATUSCLR_BK0RDY); +} + +void UDD_ClearSetupInt(void) +{ + //UOTGHS->UOTGHS_DEVEPTICR[EP0] = (UOTGHS_DEVEPTICR_RXSTPIC); + USB->DEVICE.DeviceEndpoint[EP0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY; +} + +uint32_t UDD_Send(uint32_t ep, const void* data, uint32_t len) +{ + const uint8_t *ptr_src = data; +// uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ep); + uint32_t i; + + TRACE_DEVICE(printf("=> UDD_Send (1): ep=%lu ul_send_fifo_ptr=%lu len=%lu\r\n", (unsigned long)ep, (unsigned long)ul_send_fifo_ptr[ep], (unsigned long)len);) + +// while( UOTGHS_DEVEPTISR_TXINI != (UOTGHS->UOTGHS_DEVEPTISR[ep] & UOTGHS_DEVEPTISR_TXINI )) {} + while (!(USB->DEVICE.DeviceEndpoint[ep].EPSTATUS.reg & USB_DEVICE_EPSTATUSCLR_BK1RDY)) + ; + + usb_descriptor_table.usb_endpoint_table[0].DeviceDescBank[0].ADDR.reg = (uint32_t)&ul_send_fifo_ptr[ep]; + + if (ep == EP0) + { + if (ul_send_fifo_ptr[ep] + len > EP0_SIZE) + len = EP0_SIZE - ul_send_fifo_ptr[ep]; + } + else + { + ul_send_fifo_ptr[ep] = 0; + } +// for (i = 0, ptr_dest += ul_send_fifo_ptr[ep]; i < len; ++i) +// *ptr_dest++ = *ptr_src++; + + ul_send_fifo_ptr[ep] += len;//i; + + if (ep == EP0) + { + TRACE_DEVICE(printf("=> UDD_Send (2): ep=%lu ptr_dest=%lu maxlen=%d\r\n", (unsigned long)ep, (unsigned long)ul_send_fifo_ptr[ep], EP0_SIZE);) + if (ul_send_fifo_ptr[ep] == EP0_SIZE) + { + UDD_ClearIN(); // Fifo is full, release this packet + } + } + else + { + //UOTGHS->UOTGHS_DEVEPTICR[ep] = UOTGHS_DEVEPTICR_TXINIC; + USB->DEVICE.DeviceEndpoint[EP0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY; + //UOTGHS->UOTGHS_DEVEPTIDR[ep] = UOTGHS_DEVEPTIDR_FIFOCONC; + } + return len; +} + +void UDD_Send8(uint32_t ep, uint8_t data ) +{ +// uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ep); +// +// TRACE_DEVICE(printf("=> UDD_Send8 : ul_send_fifo_ptr=%lu data=0x%x\r\n", ul_send_fifo_ptr[ep], data);) +// +// ptr_dest[ul_send_fifo_ptr[ep]] = data; +// ul_send_fifo_ptr[ep] += 1; + + uint8_t flag; + flag = (uint8_t)(USB->DEVICE.DeviceEndpoint[ep].EPCFG.bit.EPTYPE1); + if (flag == 0) { // Bank1 is disabled + return; + }; + + /* get endpoint configuration from setting register */ + usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[1].ADDR.reg = (uint32_t)&data; + usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[1].PCKSIZE.bit.MULTI_PACKET_SIZE = 0; + usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = 8; + USB->DEVICE.DeviceEndpoint[ep].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY; +} + +uint8_t UDD_Recv8(uint32_t ep) +{ +// uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ep); +// uint8_t data = ptr_dest[ul_recv_fifo_ptr[ep]]; + + TRACE_DEVICE(printf("=> UDD_Recv8 : ep=%d\r\n", (char)ep);) + +// ul_recv_fifo_ptr[ep] += 1; +// return data; + + + volatile uint8_t data; + + usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[0].ADDR.reg = (uint32_t)&data; + usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 8; + usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; + USB->DEVICE.DeviceEndpoint[ep].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; + + TRACE_DEVICE(printf("=> UDD_Recv8 : data=%lu\r\n", (unsigned long)data);) + + return data; +} + +void UDD_Recv(uint32_t ep, uint8_t* data, uint32_t len) +{ +// uint8_t *ptr_src = (uint8_t *) &udd_get_endpoint_fifo_access8(ep); +// uint8_t *ptr_dest = data; +// uint32_t i; +// +// for (i = 0, ptr_src += ul_recv_fifo_ptr[ep]; i < len; ++i) +// *ptr_dest++ = *ptr_src++; +// +// ul_recv_fifo_ptr[ep] += i; + + TRACE_DEVICE(printf("=> UDD_Recv : data=%lu, len=%d\r\n", data[0], (char)len);) + + usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[0].ADDR.reg = (uint32_t)data; + usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = len; + usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; + USB->DEVICE.DeviceEndpoint[ep].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; +} + +void UDD_Stall(uint32_t ep) +{ +// UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPEN0 << EP0); +// UOTGHS->UOTGHS_DEVEPTIER[EP0] = UOTGHS_DEVEPTIER_STALLRQS; + uint8_t ep_num = ep & 0xF; + + // Stall endpoint + if (ep & USB_EP_DIR_IN) { + USB->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1; + } else { + USB->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0; + } +} +// if (ep & USB_EP_DIR_IN) { +// module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_STALL1; +// } else { +// module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_STALL0; +// } +// if (ep & USB_EP_DIR_IN) { +// module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_STALL1; +// } else { +// module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_STALL0; +// } +// if (ep & USB_EP_DIR_IN) { +// return (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ1); +// } else { +// return (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ0); +// } +// // Stall endpoint +// if (ep & USB_EP_DIR_IN) { +// module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1; +// } else { +// module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0; +// } +// +// if (ep & USB_EP_DIR_IN) { +// if (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ1) { +// // Remove stall request +// module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1; +// if (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_STALL1) { +// module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL1; +// // The Stall has occurred, then reset data toggle +// module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLIN; +// } +// } +// } else { +// if (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ0) { +// // Remove stall request +// module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0; +// if (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_STALL0) { +// module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL0; +// // The Stall has occurred, then reset data toggle +// module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLOUT; +// } +// } +// } +// // endpoint transfer stall interrupt +// if (flags & USB_DEVICE_EPINTFLAG_STALL_Msk) { +// if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_STALL1) { +// _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL1; +// ep_callback_para.endpoint_address = USB_EP_DIR_IN | i; +// } else if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_STALL0) { +// _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL0; +// ep_callback_para.endpoint_address = USB_EP_DIR_OUT | i; +// } +// +// if (flags_run & USB_DEVICE_EPINTFLAG_STALL_Msk) { +// (_usb_instances->device_endpoint_callback[i][USB_DEVICE_ENDPOINT_CALLBACK_STALL])(_usb_instances,&ep_callback_para); +// } +// return; +// } + +uint32_t UDD_FifoByteCount(uint32_t ep) +{ + uint8_t ep_num = ep & 0xF; + + //return ((UOTGHS->UOTGHS_DEVEPTISR[ep] & UOTGHS_DEVEPTISR_BYCT_Msk) >> UOTGHS_DEVEPTISR_BYCT_Pos); + //return (USB->DEVICE.PCKSIZE.reg & USB_DEVICE_PCKSIZE_BYTE_COUNT_Msk); + return ((uint16_t)(usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT)); +} + +void UDD_ReleaseRX(uint32_t ep) +{ + TRACE_DEVICE(puts("=> UDD_ReleaseRX\r\n");) +// UOTGHS->UOTGHS_DEVEPTICR[ep] = (UOTGHS_DEVEPTICR_NAKOUTIC | UOTGHS_DEVEPTICR_RXOUTIC); + //UOTGHS->UOTGHS_DEVEPTICR[ep] = UOTGHS_DEVEPTICR_RXOUTIC; + USB->DEVICE.DeviceEndpoint[ep].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; + USB->DEVICE.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT0; + //UOTGHS->UOTGHS_DEVEPTIDR[ep] = UOTGHS_DEVEPTIDR_FIFOCONC; + ul_recv_fifo_ptr[ep] = 0; +} + +void UDD_ReleaseTX(uint32_t ep) +{ + TRACE_DEVICE(printf("=> UDD_ReleaseTX ep=%lu\r\n", (unsigned long)ep);) +// UOTGHS->UOTGHS_DEVEPTICR[ep] = (UOTGHS_DEVEPTICR_NAKINIC | UOTGHS_DEVEPTICR_RXOUTIC | UOTGHS_DEVEPTICR_TXINIC); + //UOTGHS->UOTGHS_DEVEPTICR[ep] = UOTGHS_DEVEPTICR_TXINIC; + USB->DEVICE.DeviceEndpoint[ep].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY; + USB->DEVICE.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT1; + //UOTGHS->UOTGHS_DEVEPTIDR[ep] = UOTGHS_DEVEPTIDR_FIFOCONC; + ul_send_fifo_ptr[ep] = 0; +} + +// Return true if the current bank is not full. +//uint32_t UDD_ReadWriteAllowed(uint32_t ep) +//{ +// //return (UOTGHS->UOTGHS_DEVEPTISR[ep] & UOTGHS_DEVEPTISR_RWALL); +// return 1; +//} + +void UDD_SetAddress(uint32_t addr) +{ + TRACE_DEVICE(printf("=> UDD_SetAddress : setting address to %lu\r\n", (unsigned long)addr);) + + udd_configure_address(addr); + //udd_enable_address(); +} + +uint32_t UDD_GetFrameNumber(void) +{ + return udd_frame_number(); +} + +#ifdef __cplusplus +} +#endif + +#endif /* SAMD_SERIES */ + diff --git a/cores/arduino/USB/samd21_device.h b/cores/arduino/USB/samd21_device.h new file mode 100644 index 00000000..c92140cd --- /dev/null +++ b/cores/arduino/USB/samd21_device.h @@ -0,0 +1,622 @@ +/* ---------------------------------------------------------------------------- + * SAM Software Package License + * ---------------------------------------------------------------------------- + * Copyright (c) 2011-2012, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following condition is met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +#ifndef SAMD21_DEVICE_H_INCLUDED +#define SAMD21_DEVICE_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define EP0 0 +#define EP0_SIZE 64 +#define EPX_SIZE 512 // 512 for Full Speed, EPT size max is 1024 + +#define EP_SINGLE_64 (0x32UL) // EP0 +#define EP_DOUBLE_64 (0x36UL) // Other endpoints + + + +#define USB_REGWRITEPROTECT() PAC0->WPCLR.reg = (1<<5) + + +/* +// Control Endpoint +#define EP_TYPE_CONTROL (USB_DEVICE_EPCFG_EPTYPE0(1) | USB_DEVICE_EPCFG_EPTYPE1(1)) + +// CDC Endpoints +#define EP_TYPE_BULK_IN (USB_DEVICE_EPCFG_EPTYPE1(3) | USB_DEVICE_EPSTATUSCLR_BK1RDY) + +#define EP_TYPE_BULK_OUT (USB_DEVICE_EPCFG_EPTYPE0(3) | USB_DEVICE_EPSTATUSCLR_BK0RDY) + +#define EP_TYPE_INTERRUPT_IN (USB_DEVICE_EPCFG_EPTYPE1(4) | USB_DEVICE_EPSTATUSCLR_BK1RDY) + +// HID Endpoints +#define EP_TYPE_INTERRUPT_IN_HID (USB_DEVICE_EPCFG_EPTYPE1(4) | USB_DEVICE_EPSTATUSCLR_BK1RDY) + +// Various definitions +#define EP_TYPE_INTERRUPT_OUT (USB_DEVICE_EPCFG_EPTYPE0(4) | USB_DEVICE_EPSTATUSCLR_BK0RDY) + + +*/ +//! \ingroup usb_device_group +//! \defgroup udd_group USB Device Driver (UDD) +//! UOTGHS low-level driver for USB device mode +//! +//! @{ + +/*#ifndef UOTGHS_DEVEPTCFG_EPDIR_Pos*/ +/*// Bit pos is not defined in SAM header file but we need it.*/ +/*# define UOTGHS_DEVEPTCFG_EPDIR_Pos 8*/ +/*#endif*/ + +//! @name UOTGHS Device IP properties +//! These macros give access to IP properties +//! @{ + //! Get maximal number of endpoints +#define udd_get_endpoint_max_nbr() (7) +#define UDD_MAX_PEP_NB (udd_get_endpoint_max_nbr() + 1) + //! Get maximal number of banks of endpoints +#define udd_get_endpoint_bank_max_nbr(ep) ((ep == 0) ? 1 : 2) + //! Get maximal size of endpoint (3X, 1024/64) +#define udd_get_endpoint_size_max(ep) (64) // for bulk full speed + //! Get DMA support of endpoints +#define Is_udd_endpoint_dma_supported(ep) (((ep) >= 1) ? true : false) + //! Get High Band Width support of endpoints +#define Is_udd_endpoint_high_bw_supported(ep) (((ep) >= 1) ? true : false) +//! @} + +//! @name USB Device speeds management +//! @{ +// Force device low speed mode +#define udd_force_low_speed() USB_REGWRITEPROTECT(); USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_SPDCONF_Msk; USB->DEVICE.CTRLB.reg |= USB_DEVICE_CTRLB_SPDCONF_1_Val +// Force full speed mode +#define udd_force_full_speed() USB_REGWRITEPROTECT(); USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_SPDCONF_Msk + + + +/* +//! @name UOTGHS Device vbus management +//! @{ +#define udd_enable_vbus_interrupt() (USB->UOTGHS_CTRL |= UOTGHS_CTRL_VBUSTE) +#define udd_disable_vbus_interrupt() (Clr_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE)) +#define Is_udd_vbus_interrupt_enabled() (Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE)) +#define Is_udd_vbus_high() (Tst_bits(USB->UOTGHS_SR, UOTGHS_SR_VBUS)) +#define Is_udd_vbus_low() (!Is_udd_vbus_high()) +#define udd_ack_vbus_transition() (USB->UOTGHS_SCR = UOTGHS_SCR_VBUSTIC) +#define udd_raise_vbus_transition() (USB->UOTGHS_SFR = UOTGHS_SFR_VBUSTIS) +#define Is_udd_vbus_transition() (Tst_bits(USB->UOTGHS_SR, UOTGHS_SR_VBUSTI)) +//! @} +*/ + + +// Attaches to USB bus +#define udd_attach_device() USB_REGWRITEPROTECT(); USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_DETACH +#define udd_detach_device() USB_REGWRITEPROTECT(); USB->DEVICE.CTRLB.reg |= USB_DEVICE_CTRLB_DETACH + +//! @name UOTGHS device bus events control +//! These macros manage the UOTGHS Device bus events. +//! @{ + +//! Initiates a remote wake-up event +//! @{ +//#define udd_initiate_remote_wake_up() (USB->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_RMWKUP) +//#define Is_udd_pending_remote_wake_up() (Tst_bits(USB->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_RMWKUP)) +//! @} + +//! Manage upstream resume event (=remote wakeup) +//! The USB driver sends a resume signal called "Upstream Resume" +//! @{ +#define udd_enable_remote_wake_up_interrupt() (USB->UOTGHS_DEVIER = UOTGHS_DEVIER_UPRSMES) +#define udd_disable_remote_wake_up_interrupt() (USB->UOTGHS_DEVIDR = UOTGHS_DEVIDR_UPRSMEC) +#define Is_udd_remote_wake_up_interrupt_enabled() (Tst_bits(USB->UOTGHS_DEVIMR, UOTGHS_DEVIMR_UPRSME)) +#define udd_ack_remote_wake_up_start() (USB->UOTGHS_DEVICR = UOTGHS_DEVICR_UPRSMC) +#define udd_raise_remote_wake_up_start() (USB->UOTGHS_DEVIFR = UOTGHS_DEVIFR_UPRSMS) +#define Is_udd_remote_wake_up_start() (Tst_bits(USB->UOTGHS_DEVISR, UOTGHS_DEVISR_UPRSM)) +//! @} + +//! Manage downstream resume event (=remote wakeup from host) +//! The USB controller detects a valid "End of Resume" signal initiated by the host +//! @{ +#define udd_enable_resume_interrupt() (USB->UOTGHS_DEVIER = UOTGHS_DEVIER_EORSMES) +#define udd_disable_resume_interrupt() (USB->UOTGHS_DEVIDR = UOTGHS_DEVIDR_EORSMEC) +#define Is_udd_resume_interrupt_enabled() (Tst_bits(USB->UOTGHS_DEVIMR, UOTGHS_DEVIMR_EORSME)) +#define udd_ack_resume() (USB->UOTGHS_DEVICR = UOTGHS_DEVICR_EORSMC) +#define udd_raise_resume() (USB->UOTGHS_DEVIFR = UOTGHS_DEVIFR_EORSMS) +#define Is_udd_resume() (Tst_bits(USB->UOTGHS_DEVISR, UOTGHS_DEVISR_EORSM)) +//! @} + +//! Manage wake-up event (=usb line activity) +//! The USB controller is reactivated by a filtered non-idle signal from the lines +//! @{ +#define udd_enable_wake_up_interrupt() (USB->UOTGHS_DEVIER = UOTGHS_DEVIER_WAKEUPES) +#define udd_disable_wake_up_interrupt() (USB->UOTGHS_DEVIDR = UOTGHS_DEVIDR_WAKEUPEC) +#define Is_udd_wake_up_interrupt_enabled() (Tst_bits(USB->UOTGHS_DEVIMR, UOTGHS_DEVIMR_WAKEUPE)) +#define udd_ack_wake_up() (USB->UOTGHS_DEVICR = UOTGHS_DEVICR_WAKEUPC) +#define udd_raise_wake_up() (USB->UOTGHS_DEVIFR = UOTGHS_DEVIFR_WAKEUPS) +#define Is_udd_wake_up() (Tst_bits(USB->UOTGHS_DEVISR, UOTGHS_DEVISR_WAKEUP)) +//! @} + +//! Manage reset event +//! Set when a USB "End of Reset" has been detected +//! @{ +#define udd_enable_reset_interrupt() USB->DEVICE.INTENSET.reg = USB_DEVICE_INTENSET_EORST +#define udd_disable_reset_interrupt() (USB->UOTGHS_DEVIDR = UOTGHS_DEVIDR_EORSTEC) +#define Is_udd_reset_interrupt_enabled() (Tst_bits(USB->UOTGHS_DEVIMR, UOTGHS_DEVIMR_EORSTE)) +#define udd_ack_reset() USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_EORST //(USB->UOTGHS_DEVICR = UOTGHS_DEVICR_EORSTC) +#define udd_raise_reset() (USB->UOTGHS_DEVIFR = UOTGHS_DEVIFR_EORSTS) +//#define Is_udd_reset() (Tst_bits(USB->UOTGHS_DEVISR, UOTGHS_DEVISR_EORST)) +#define Is_udd_reset() USB->DEVICE.INTFLAG.reg & USB_DEVICE_INTFLAG_EORST +//! @} + +//! Manage start of frame (SOF) event +//! @{ +#define udd_enable_sof_interrupt() USB->DEVICE.INTENSET.reg = USB_DEVICE_INTENSET_SOF +#define udd_disable_sof_interrupt() (USB->UOTGHS_DEVIDR = UOTGHS_DEVIDR_SOFEC) +#define Is_udd_sof_interrupt_enabled() (Tst_bits(USB->UOTGHS_DEVIMR, UOTGHS_DEVIMR_SOFE)) +#define udd_ack_sof() USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_SOF //(USB->UOTGHS_DEVICR = UOTGHS_DEVICR_SOFC) +#define udd_raise_sof() (USB->UOTGHS_DEVIFR = UOTGHS_DEVIFR_SOFS) +#define Is_udd_sof() (USB->DEVICE.INTENSET.reg & USB_DEVICE_INTENSET_SOF) //(Tst_bits(USB->UOTGHS_DEVISR, UOTGHS_DEVISR_SOF)) +#define udd_frame_number() ((USB->DEVICE.FNUM.reg & USB_DEVICE_FNUM_FNUM_Msk) >> USB_DEVICE_FNUM_FNUM_Pos) +#define Is_udd_frame_number_crc_error() (Tst_bits(USB->UOTGHS_DEVFNUM, UOTGHS_DEVFNUM_FNCERR)) +//! @} + + +//! Manage suspend event +//! @{ +#define udd_enable_suspend_interrupt() (USB->UOTGHS_DEVIER = UOTGHS_DEVIER_SUSPES) +#define udd_disable_suspend_interrupt() (USB->UOTGHS_DEVIDR = UOTGHS_DEVIDR_SUSPEC) +#define Is_udd_suspend_interrupt_enabled() (Tst_bits(USB->UOTGHS_DEVIMR, UOTGHS_DEVIMR_SUSPE)) +#define udd_ack_suspend() (USB->UOTGHS_DEVICR = UOTGHS_DEVICR_SUSPC) +#define udd_raise_suspend() (USB->UOTGHS_DEVIFR = UOTGHS_DEVIFR_SUSPS) +#define Is_udd_suspend() (Tst_bits(USB->UOTGHS_DEVISR, UOTGHS_DEVISR_SUSP)) +//! @} + +//! @} + +//! @name UOTGHS device address control +//! These macros manage the UOTGHS Device address. +//! @{ + //! enables USB device address +#define udd_enable_address() (USB->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_ADDEN) + //! disables USB device address +#define udd_disable_address() (Clr_bits(USB->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_ADDEN)) +#define Is_udd_address_enabled() (Tst_bits(USB->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_ADDEN)) + //! configures the USB device address and enable it. +#define udd_configure_address(address) USB->DEVICE.DADD.reg = USB_DEVICE_DADD_ADDEN | address + //! gets the currently configured USB device address +#define udd_get_configured_address() (Rd_bitfield(USB->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_UADD_Msk)) +//! @} + + +//! @name UOTGHS Device endpoint drivers +//! These macros manage the common features of the endpoints. +//! @{ + +//! Generic macro for UOTGHS registers that can be arrayed +//! @{ +//#define UOTGHS_ARRAY(reg,index) ((&(USB->reg))[(index)]) +//! @} + +//! @name UOTGHS Device endpoint configuration +//! @{ + //! enables the selected endpoint +//#define udd_enable_endpoint(ep) (USB->UOTGHS_DEVEPT |= UOTGHS_DEVEPT_EPEN0 << (ep)) + //! disables the selected endpoint +//#define udd_disable_endpoint(ep) (Clr_bits(USB->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPEN0 << (ep))) + //! tests if the selected endpoint is enabled +//#define Is_udd_endpoint_enabled(ep) (Tst_bits(USB->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPEN0 << (ep))) + //! resets the selected endpoint +#define udd_reset_endpoint(ep) \ + do { \ + Set_bits(USB->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPRST0 << (ep)); \ + Clr_bits(USB->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPRST0 << (ep)); \ + } while (0) + //! Tests if the selected endpoint is being reset +#define Is_udd_resetting_endpoint(ep) (Tst_bits(USB->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPRST0 << (ep))) + + //! Configures the selected endpoint type +#define udd_configure_endpoint_type(ep, type) (Wr_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPTYPE_Msk, type)) + //! Gets the configured selected endpoint type +#define udd_get_endpoint_type(ep) (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPTYPE_Msk)) + //! Enables the bank autoswitch for the selected endpoint +#define udd_enable_endpoint_bank_autoswitch(ep) (Set_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_AUTOSW)) + //! Disables the bank autoswitch for the selected endpoint +#define udd_disable_endpoint_bank_autoswitch(ep) (Clr_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_AUTOSW)) +#define Is_udd_endpoint_bank_autoswitch_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_AUTOSW)) + //! Configures the selected endpoint direction +#define udd_configure_endpoint_direction(ep, dir) (Wr_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPDIR, dir)) + //! Gets the configured selected endpoint direction +#define udd_get_endpoint_direction(ep) (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPDIR)) +#define Is_udd_endpoint_in(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPDIR)) + //! Bounds given integer size to allowed range and rounds it up to the nearest + //! available greater size, then applies register format of UOTGHS controller + //! for endpoint size bit-field. +#define udd_format_endpoint_size(size) (32 - clz(((uint32_t)min(max(size, 8), 1024) << 1) - 1) - 1 - 3) + //! Configures the selected endpoint size +#define udd_configure_endpoint_size(ep, size) (Wr_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPSIZE_Msk, udd_format_endpoint_size(size))) + //! Gets the configured selected endpoint size +#define udd_get_endpoint_size(ep) (8 << Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPSIZE_Msk)) + //! Configures the selected endpoint number of banks +#define udd_configure_endpoint_bank(ep, bank) (Wr_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPBK_Msk, bank)) + //! Gets the configured selected endpoint number of banks +#define udd_get_endpoint_bank(ep) (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPBK_Msk)+1) + //! Allocates the configuration selected endpoint in DPRAM memory +#define udd_allocate_memory(ep) (Set_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_ALLOC)) + //! un-allocates the configuration selected endpoint in DPRAM memory +#define udd_unallocate_memory(ep) (Clr_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_ALLOC)) +#define Is_udd_memory_allocated(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_ALLOC)) + + //! Configures selected endpoint in one step +#define udd_configure_endpoint(ep, type, dir, size, bank) (\ + Wr_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPTYPE_Msk |\ + UOTGHS_DEVEPTCFG_EPDIR |\ + UOTGHS_DEVEPTCFG_EPSIZE_Msk |\ + UOTGHS_DEVEPTCFG_EPBK_Msk , \ + (((uint32_t)(type) << UOTGHS_DEVEPTCFG_EPTYPE_Pos) & UOTGHS_DEVEPTCFG_EPTYPE_Msk) |\ + (((uint32_t)(dir ) << UOTGHS_DEVEPTCFG_EPDIR_Pos ) & UOTGHS_DEVEPTCFG_EPDIR) |\ + ( (uint32_t)udd_format_endpoint_size(size) << UOTGHS_DEVEPTCFG_EPSIZE_Pos) |\ + (((uint32_t)(bank) << UOTGHS_DEVEPTCFG_EPBK_Pos) & UOTGHS_DEVEPTCFG_EPBK_Msk))\ +) + //! Tests if current endpoint is configured +#define Is_udd_endpoint_configured(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_CFGOK)) + //! Returns the control direction +#define udd_control_direction() (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], EP_CONTROL), UOTGHS_DEVEPTISR_CTRLDIR)) + + //! Resets the data toggle sequence +#define udd_reset_data_toggle(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_RSTDTS) + //! Tests if the data toggle sequence is being reset +#define Is_udd_data_toggle_reset(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_RSTDT)) + //! Returns data toggle +#define udd_data_toggle(ep) (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_DTSEQ_Msk)) +//! @} + + +//! @name UOTGHS Device control endpoint +//! These macros control the endpoints. +//! @{ + +//! @name UOTGHS Device control endpoint interrupts +//! These macros control the endpoints interrupts. +//! @{ + //! Enables the selected endpoint interrupt +#define udd_enable_endpoint_interrupt(ep) (USB->UOTGHS_DEVIER = UOTGHS_DEVIER_PEP_0 << (ep)) + //! Disables the selected endpoint interrupt +#define udd_disable_endpoint_interrupt(ep) (USB->UOTGHS_DEVIDR = UOTGHS_DEVIDR_PEP_0 << (ep)) + //! Tests if the selected endpoint interrupt is enabled +//#define Is_udd_endpoint_interrupt_enabled(ep) (Tst_bits(USB->UOTGHS_DEVIMR, UOTGHS_DEVIMR_PEP_0 << (ep))) + //! Tests if an interrupt is triggered by the selected endpoint +#define Is_udd_endpoint_interrupt(ep) ((USB->DEVICE.EPINTSMRY.reg & (1<<ep)) != 0 ) + //! Returns the lowest endpoint number generating an endpoint interrupt or MAX_PEP_NB if none +#define udd_get_interrupt_endpoint_number() (ctz(((USB->UOTGHS_DEVISR >> UOTGHS_DEVISR_PEP_Pos) & \ + (USB->UOTGHS_DEVIMR >> UOTGHS_DEVIMR_PEP_Pos)) | \ + (1 << MAX_PEP_NB))) +#define UOTGHS_DEVISR_PEP_Pos 12 +#define UOTGHS_DEVIMR_PEP_Pos 12 +//! @} + +//! @name UOTGHS Device control endpoint errors +//! These macros control the endpoint errors. +//! @{ + //! Enables the STALL handshake +#define udd_enable_stall_handshake(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_STALLRQS) + //! Disables the STALL handshake +#define udd_disable_stall_handshake(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_STALLRQC) + //! Tests if STALL handshake request is running +#define Is_udd_endpoint_stall_requested(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_STALLRQ)) + //! Tests if STALL sent +#define Is_udd_stall(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_STALLEDI)) + //! ACKs STALL sent +#define udd_ack_stall(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_STALLEDIC) + //! Raises STALL sent +#define udd_raise_stall(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_STALLEDIS) + //! Enables STALL sent interrupt +#define udd_enable_stall_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_STALLEDES) + //! Disables STALL sent interrupt +#define udd_disable_stall_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_STALLEDEC) + //! Tests if STALL sent interrupt is enabled +#define Is_udd_stall_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_STALLEDE)) + + //! Tests if NAK OUT received +#define Is_udd_nak_out(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_NAKOUTI)) + //! ACKs NAK OUT received +#define udd_ack_nak_out(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_NAKOUTIC) + //! Raises NAK OUT received +#define udd_raise_nak_out(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_NAKOUTIS) + //! Enables NAK OUT interrupt +#define udd_enable_nak_out_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_NAKOUTES) + //! Disables NAK OUT interrupt +#define udd_disable_nak_out_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_NAKOUTEC) + //! Tests if NAK OUT interrupt is enabled +#define Is_udd_nak_out_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_NAKOUTE)) + + //! Tests if NAK IN received +#define Is_udd_nak_in(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_NAKINI)) + //! ACKs NAK IN received +#define udd_ack_nak_in(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_NAKINIC) + //! Raises NAK IN received +#define udd_raise_nak_in(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_NAKINIS) + //! Enables NAK IN interrupt +#define udd_enable_nak_in_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_NAKINES) + //! Disables NAK IN interrupt +#define udd_disable_nak_in_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_NAKINEC) + //! Tests if NAK IN interrupt is enabled +#define Is_udd_nak_in_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_NAKINE)) + + //! ACKs endpoint isochronous overflow interrupt +#define udd_ack_overflow_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_OVERFIC) + //! Raises endpoint isochronous overflow interrupt +#define udd_raise_overflow_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_OVERFIS) + //! Tests if an overflow occurs +#define Is_udd_overflow(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_OVERFI)) + //! Enables overflow interrupt +#define udd_enable_overflow_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_OVERFES) + //! Disables overflow interrupt +#define udd_disable_overflow_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_OVERFEC) + //! Tests if overflow interrupt is enabled +#define Is_udd_overflow_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_OVERFE)) + + //! ACKs endpoint isochronous underflow interrupt +#define udd_ack_underflow_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_UNDERFIC) + //! Raises endpoint isochronous underflow interrupt +#define udd_raise_underflow_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_UNDERFIS) + //! Tests if an underflow occurs +#define Is_udd_underflow(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_UNDERFI)) + //! Enables underflow interrupt +#define udd_enable_underflow_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_UNDERFES) + //! Disables underflow interrupt +#define udd_disable_underflow_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_UNDERFEC) + //! Tests if underflow interrupt is enabled +#define Is_udd_underflow_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_UNDERFE)) + + //! Tests if CRC ERROR ISO OUT detected +#define Is_udd_crc_error(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_CRCERRI)) + //! ACKs CRC ERROR ISO OUT detected +#define udd_ack_crc_error(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_CRCERRIC) + //! Raises CRC ERROR ISO OUT detected +#define udd_raise_crc_error(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_CRCERRIS) + //! Enables CRC ERROR ISO OUT detected interrupt +#define udd_enable_crc_error_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_CRCERRES) + //! Disables CRC ERROR ISO OUT detected interrupt +#define udd_disable_crc_error_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_CRCERREC) + //! Tests if CRC ERROR ISO OUT detected interrupt is enabled +#define Is_udd_crc_error_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_CRCERRE)) +//! @} + +//! @name UOTGHS Device control endpoint transfer +//! These macros control the endpoint transfer. +//! @{ + + //! Tests if endpoint read allowed +#define Is_udd_read_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_RWALL)) + //! Tests if endpoint write allowed +#define Is_udd_write_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_RWALL)) + + //! Returns the byte count +#define udd_byte_count(ep) (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_BYCT_Msk)) + //! Clears FIFOCON bit +#define udd_ack_fifocon(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_FIFOCONC) + //! Tests if FIFOCON bit set +#define Is_udd_fifocon(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_FIFOCON)) + + //! Returns the number of busy banks +#define udd_nb_busy_bank(ep) (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_NBUSYBK_Msk)) + //! Returns the number of the current bank +#define udd_current_bank(ep) (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_CURRBK_Msk)) + //! Kills last bank +#define udd_kill_last_in_bank(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_KILLBKS) +#define Is_udd_kill_last(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_KILLBK)) + //! Tests if last bank killed +#define Is_udd_last_in_bank_killed(ep) (!Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_KILLBK)) + //! Forces all banks full (OUT) or free (IN) interrupt +#define udd_force_bank_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_NBUSYBKS) + //! Unforces all banks full (OUT) or free (IN) interrupt +#define udd_unforce_bank_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_NBUSYBKS) + //! Enables all banks full (OUT) or free (IN) interrupt +#define udd_enable_bank_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_NBUSYBKES) + //! Disables all banks full (OUT) or free (IN) interrupt +#define udd_disable_bank_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_NBUSYBKEC) + //! Tests if all banks full (OUT) or free (IN) interrupt enabled +#define Is_udd_bank_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_NBUSYBKE)) + + //! Tests if SHORT PACKET received +#define Is_udd_short_packet(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_SHORTPACKET)) + //! ACKs SHORT PACKET received +#define udd_ack_short_packet(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_SHORTPACKETC) + //! Raises SHORT PACKET received +#define udd_raise_short_packet(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_SHORTPACKETS) + //! Enables SHORT PACKET received interrupt +#define udd_enable_short_packet_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_SHORTPACKETES) + //! Disables SHORT PACKET received interrupt +#define udd_disable_short_packet_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_SHORTPACKETEC) + //! Tests if SHORT PACKET received interrupt is enabled +#define Is_udd_short_packet_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_SHORTPACKETE)) + + //! Tests if SETUP received +#define Is_udd_setup_received(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_RXSTPI)) + //! ACKs SETUP received +#define udd_ack_setup_received(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_RXSTPIC) + //! Raises SETUP received +#define udd_raise_setup_received(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_RXSTPIS) + //! Enables SETUP received interrupt +//#define udd_enable_setup_received_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_RXSTPES) +#define udd_enable_setup_received_interrupt(ep) USB->DEVICE.DeviceEndpoint[ep].EPINTENCLR.reg = USB_DEVICE_EPINTFLAG_RXSTP + //! Disables SETUP received interrupt +#define udd_disable_setup_received_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_RXSTPEC) + //! Tests if SETUP received interrupt is enabled +#define Is_udd_setup_received_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_RXSTPE)) + + //! Tests if OUT received +#define Is_udd_out_received(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_RXOUTI)) + //! ACKs OUT received +#define udd_ack_out_received(ep) USB->DEVICE.DeviceEndpoint[ep].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; //(UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_RXOUTIC) + //! Raises OUT received +#define udd_raise_out_received(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_RXOUTIS) + //! Enables OUT received interrupt +#define udd_enable_out_received_interrupt(ep) USB->DEVICE.DeviceEndpoint[ep].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY; //(UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_RXOUTES) + //! Disables OUT received interrupt +#define udd_disable_out_received_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_RXOUTEC) + //! Tests if OUT received interrupt is enabled +#define Is_udd_out_received_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_RXOUTE)) + + //! Tests if IN sending +#define Is_udd_in_send(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_TXINI)) + //! ACKs IN sending +#define udd_ack_in_send(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_TXINIC) + //! Raises IN sending +#define udd_raise_in_send(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_TXINIS) + //! Enables IN sending interrupt +#define udd_enable_in_send_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_TXINES) + //! Disables IN sending interrupt +#define udd_disable_in_send_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_TXINEC) + //! Tests if IN sending interrupt is enabled +#define Is_udd_in_send_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_TXINE)) + + + //! 8-bit access to FIFO data register of selected endpoint. + //! @param ep Endpoint of which to access FIFO data register + //! @return Volatile 8-bit data pointer to FIFO data register + //! @warning It is up to the user of this macro to make sure that all accesses + //! are aligned with their natural boundaries + //! @warning It is up to the user of this macro to make sure that used HSB + //! addresses are identical to the DPRAM internal pointer modulo 32 bits. +#define udd_get_endpoint_fifo_access8(ep) \ + (((volatile uint8_t (*)[0x8000])UOTGHS_RAM_ADDR)[(ep)]) + +//! @} + +/*********************************************************************************************************************/ + +//! @name UOTGHS IP properties +//! These macros give access to IP properties (not defined in 3X) +//! @{ + //! Get IP name part 1 or 2 +#define otg_get_ip_name() +#define otg_data_memory_barrier() + //! Get IP version +#define otg_get_ip_version() + //! Get DPRAM size (FIFO maximal size) in bytes +#define otg_get_dpram_size() + //! Get size of USBB PB address space +#define otg_get_ip_paddress_size() +//! @} + +//! @name UOTGHS OTG ID pin management +//! The ID pin come from the USB OTG connector (A and B receptable) and +//! allows to select the USB mode host or device. +//! The USBB hardware can manage it automaticaly. This feature is optional. +//! When otg_ID_PIN equals true in conf_usb_host.h, the USB_ID must be defined in board.h. +//! +//! @{ + //! PIO, PIO ID and MASK for USB_ID according to configuration from OTG_ID +#define OTG_ID_PIN USB_ID_GPIO +#define OTG_ID_FUNCTION USB_ID_FLAGS + //! Input USB_ID from its pin +#define otg_input_id_pin() do { \ + pio_configure_pin(OTG_ID_PIN, OTG_ID_FUNCTION); \ +} while (0) + + //! Enable external OTG_ID pin (listened to by USB) +#define otg_enable_id_pin() (Set_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_UIDE)) + //! Disable external OTG_ID pin (ignored by USB) +#define otg_disable_id_pin() (Clr_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_UIDE)) + //! Test if external OTG_ID pin enabled (listened to by USB) +#define Is_otg_id_pin_enabled() (Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_UIDE)) +// Force device mode +#define udd_force_device_mode() (USB->DEVICE.CTRLA.reg &= ~USB_CTRLA_MODE) +// Run in Standby +#define udd_device_run_in_standby() (USB->DEVICE.CTRLA.reg |= USB_CTRLA_RUNSTDBY) + //! Test if device mode is forced +//#define Is_otg_device_mode_forced() (!Is_otg_id_pin_enabled() && Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_UIMOD)) +// Force host mode +#define otg_force_host_mode() (USB->DEVICE.CTRLA.reg |= USB_CTRLA_MODE) + //! Test if host mode is forced +#define Is_otg_host_mode_forced() (!Is_otg_id_pin_enabled() && !Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_UIMOD)) + +//! @name UOTGHS OTG ID pin interrupt management +//! These macros manage the ID pin interrupt +//! @{ +#define otg_enable_id_interrupt() (Set_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_IDTE)) +#define otg_disable_id_interrupt() (Clr_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_IDTE)) +#define Is_otg_id_interrupt_enabled() (Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_IDTE)) +#define Is_otg_id_device() (Tst_bits(USB->UOTGHS_SR, UOTGHS_SR_ID)) +#define Is_otg_id_host() (!Is_otg_id_device()) +#define otg_ack_id_transition() (USB->UOTGHS_SCR = UOTGHS_SCR_IDTIC) +#define otg_raise_id_transition() (USB->UOTGHS_SFR = UOTGHS_SFR_IDTIS) +#define Is_otg_id_transition() (Tst_bits(USB->UOTGHS_SR, UOTGHS_SR_IDTI)) +//! @} + + +//! @name USBB OTG Vbus management +//! @{ +#define otg_enable_vbus_interrupt() (Set_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE)) +//#define otg_disable_vbus_interrupt() (Clr_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE)) +//#define Is_otg_vbus_interrupt_enabled() (Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE)) +//#define Is_otg_vbus_high() ((USB->CTRLB & USB_CTRLB_VBUSOK) == USB_CTRLB_VBUSOK) +#define is_usb_vbus_high() port_pin_get_input_level(USB_VBUS_PIN) + +//#define Is_otg_vbus_low() (!Is_otg_vbus_high()) +#define otg_ack_vbus_transition() (USB->UOTGHS_SCR = UOTGHS_SCR_VBUSTIC) +#define otg_raise_vbus_transition() (USB->UOTGHS_SFR = UOTGHS_SFR_VBUSTIS) +#define Is_otg_vbus_transition() (Tst_bits(USB->UOTGHS_SR, UOTGHS_SR_VBUSTI)) +//! @} + +//! @name UOTGHS OTG main management +//! These macros allows to enable/disable pad and UOTGHS hardware +//! @{ + //! Enable USB macro +#define udd_enable() (USB->DEVICE.CTRLA.reg |= USB_CTRLA_ENABLE) +//(Set_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_USBE)) + //! Disable USB macro +#define udd_disable() (USB->DEVICE.CTRLA.reg &= ~USB_CTRLA_ENABLE) +//#define Is_otg_enabled() (Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_USBE)) + + //! Enable OTG pad +//#define otg_enable_pad() (Set_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_OTGPADE)) + //! Disable OTG pad +//#define otg_disable_pad() (Clr_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_OTGPADE)) +//#define Is_otg_pad_enabled() (Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_OTGPADE)) + + //! Check Clock Usable + //! For parts with HS feature, this one corresponding at UTMI clock +//#define Is_otg_clock_usable() (Tst_bits(USB->UOTGHS_SR, UOTGHS_SR_CLKUSABLE)) + + //! Stop (freeze) internal USB clock +//#define otg_freeze_clock() (Set_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_FRZCLK)) +//#define otg_unfreeze_clock() (Clr_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_FRZCLK)) +//#define Is_otg_clock_frozen() (Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_FRZCLK)) + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* SAMD21_DEVICE_H_INCLUDED */ + diff --git a/cores/arduino/USB/samd21_host.c b/cores/arduino/USB/samd21_host.c new file mode 100644 index 00000000..26262ee3 --- /dev/null +++ b/cores/arduino/USB/samd21_host.c @@ -0,0 +1,489 @@ +/* ---------------------------------------------------------------------------- + * SAM Software Package License + * ---------------------------------------------------------------------------- + * Copyright (c) 2011-2012, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following condition is met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +#include <stdio.h> + +#if SAM3XA_SERIES + +//#define TRACE_UOTGHS_HOST(x) x +#define TRACE_UOTGHS_HOST(x) + +extern void (*gpf_isr)(void); + +// Handle UOTGHS Host driver state +static uhd_vbus_state_t uhd_state = UHD_STATE_NO_VBUS; + +/** + * \brief Interrupt sub routine for USB Host state machine management. + */ +static void UHD_ISR(void) +{ + // Manage dis/connection event + if (Is_uhd_disconnection() && Is_uhd_disconnection_int_enabled()) { + TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Disconnection INT\r\n");) + uhd_ack_disconnection(); + uhd_disable_disconnection_int(); + // Stop reset signal, in case of disconnection during reset + uhd_stop_reset(); + // Disable wakeup/resumes interrupts, + // in case of disconnection during suspend mode + //UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_HWUPIEC + // | UOTGHS_HSTIDR_RSMEDIEC + // | UOTGHS_HSTIDR_RXRSMIEC; + uhd_ack_connection(); + uhd_enable_connection_int(); + uhd_state = UHD_STATE_DISCONNECTED; + return; + } + if (Is_uhd_connection() && Is_uhd_connection_int_enabled()) { + TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Connection INT\r\n");) + uhd_ack_connection(); + uhd_disable_connection_int(); + uhd_ack_disconnection(); + uhd_enable_disconnection_int(); + //uhd_enable_sof(); + uhd_state = UHD_STATE_CONNECTED; + return; + } + + // Manage Vbus error + if (Is_uhd_vbus_error_interrupt()) + { + TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : VBUS error INT\r\n");) + uhd_ack_vbus_error_interrupt(); + uhd_state = UHD_STATE_DISCONNECTED; //UHD_STATE_ERROR; + return; + } + + // Check USB clock ready after asynchronous interrupt + while (!Is_otg_clock_usable()) + ; + otg_unfreeze_clock(); + + // Manage Vbus state change + if (Is_otg_vbus_transition()) + { + otg_ack_vbus_transition(); + if (Is_otg_vbus_high()) + { + TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : VBUS transition INT : UHD_STATE_DISCONNECT\r\n");) + uhd_state = UHD_STATE_DISCONNECTED; + } + else + { + TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : VBUS transition INT : UHD_STATE_NO_VBUS\r\n");) + otg_freeze_clock(); + uhd_state = UHD_STATE_NO_VBUS; + } + TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : VBUS transition INT : done.\r\n");) + return; + } + + // Other errors + if (Is_uhd_errors_interrupt()) + { + TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Other error INT\r\n");) + uhd_ack_errors_interrupt(); + return; + } +} + +/** + * \brief Set the interrupt sub routines callback for USB interrupts. + * + * \param pf_isr the ISR address. + */ +void UHD_SetStack(void (*pf_isr)(void)) +{ + gpf_isr = pf_isr; +} + +/** + * \brief Initialize the UOTGHS host driver. + */ +void UHD_Init(void) +{ + irqflags_t flags; + + // To avoid USB interrupt before end of initialization + flags = cpu_irq_save(); + + // Setup USB Host interrupt callback + UHD_SetStack(&UHD_ISR); + + // Enables the USB Clock + pmc_enable_upll_clock(); + pmc_switch_udpck_to_upllck(0); // div=0+1 + pmc_enable_udpck(); + pmc_enable_periph_clk(ID_UOTGHS); + + // Always authorize asynchronous USB interrupts to exit of sleep mode + // For SAM3 USB wake up device except BACKUP mode + NVIC_SetPriority((IRQn_Type) ID_UOTGHS, 0); + NVIC_EnableIRQ((IRQn_Type) ID_UOTGHS); + + // ID pin not used then force host mode + otg_disable_id_pin(); + otg_force_host_mode(); + + // Signal is active low (because all SAM3X Pins are high after startup) + // Hence VBOF must be low after connection request to power up the remote device + // uhd_set_vbof_active_low(); + + // According to the Arduino Due circuit the VBOF must be active high to power up the remote device + uhd_set_vbof_active_high(); + + otg_enable_pad(); + otg_enable(); + + otg_unfreeze_clock(); + + // Check USB clock + while (!Is_otg_clock_usable()) + ; + + // Clear all interrupts that may have been set by a previous host mode + UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_DCONNIC | UOTGHS_HSTICR_DDISCIC + | UOTGHS_HSTICR_HSOFIC | UOTGHS_HSTICR_HWUPIC + | UOTGHS_HSTICR_RSMEDIC | UOTGHS_HSTICR_RSTIC + | UOTGHS_HSTICR_RXRSMIC; + + otg_ack_vbus_transition(); + + // Enable Vbus change and error interrupts + // Disable automatic Vbus control after Vbus error + Set_bits(UOTGHS->UOTGHS_CTRL, + UOTGHS_CTRL_VBUSHWC | UOTGHS_CTRL_VBUSTE | UOTGHS_CTRL_VBERRE); + + uhd_enable_vbus(); + + // Force Vbus interrupt when Vbus is always high + // This is possible due to a short timing between a Host mode stop/start. + if (Is_otg_vbus_high()) + { + otg_raise_vbus_transition(); + } + + // Enable main control interrupt + // Connection, SOF and reset + UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTICR_DCONNIC; + + otg_freeze_clock(); + + uhd_state = UHD_STATE_NO_VBUS; + + cpu_irq_restore(flags); +} + +/** + * \brief Trigger a USB bus reset. + */ +void UHD_BusReset(void) +{ + uhd_start_reset(); +} + +/** + * \brief Get VBUS state. + * + * \return VBUS status. + */ +uhd_vbus_state_t UHD_GetVBUSState(void) +{ + return uhd_state; +} + +/*uhd_speed_t uhd_get_speed(void) +{ + switch (uhd_get_speed_mode()) + { + case UOTGHS_SR_SPEED_HIGH_SPEED: + return UHD_SPEED_HIGH; + + case UOTGHS_SR_SPEED_FULL_SPEED: + return UHD_SPEED_FULL; + + case UOTGHS_SR_SPEED_LOW_SPEED: + return UHD_SPEED_LOW; + + default: + return UHD_SPEED_LOW; + } +}*/ + +/** + * \brief Allocate FIFO for pipe 0. + * + * \param ul_add Address of remote device for pipe 0. + * \param ul_ep_size Actual size of the FIFO in bytes. + * + * \retval 0 success. + * \retval 1 error. + */ +uint32_t UHD_Pipe0_Alloc(uint32_t ul_add, uint32_t ul_ep_size) +{ + if (ul_ep_size < 8) + { + TRACE_UOTGHS_HOST(printf("/!\\ UHD_EP0_Alloc : incorrect pipe size!\r\n");) + return 1; + } + + if (Is_uhd_pipe_enabled(0)) + { + // Pipe is already allocated + return 0; + } + + uhd_enable_pipe(0); + uhd_configure_pipe(0, // Pipe 0 + 0, // No frequency + 0, // Enpoint 0 + UOTGHS_HSTPIPCFG_PTYPE_CTRL, + UOTGHS_HSTPIPCFG_PTOKEN_SETUP, + ul_ep_size, + UOTGHS_HSTPIPCFG_PBK_1_BANK, 0); + + uhd_allocate_memory(0); + + if (!Is_uhd_pipe_configured(0)) + { + TRACE_UOTGHS_HOST(printf("/!\\ UHD_EP0_Alloc : incorrect pipe settings!\r\n");) + uhd_disable_pipe(0); + return 1; + } + + uhd_configure_address(0, ul_add); + + return 0; +} + +/** + * \brief Allocate a new pipe. + * + * \note UOTGHS maximum pipe number is limited to 10, meaning that only a limited + * amount of devices can be connected. Unfortunately, using only one pipe shared accross + * various endpoints and devices is not possible because the UOTGHS IP does not allow to + * change the data toggle value through register interface. + * + * \param ul_dev_addr Address of remote device. + * \param ul_dev_ep Targeted endpoint of remote device. + * \param ul_type Pipe type. + * \param ul_dir Pipe direction. + * \param ul_maxsize Pipe size. + * \param ul_interval Polling interval (if applicable to pipe type). + * \param ul_nb_bank Number of banks associated with this pipe. + * + * \return the newly allocated pipe number on success, 0 otherwise. + */ +uint32_t UHD_Pipe_Alloc(uint32_t ul_dev_addr, uint32_t ul_dev_ep, uint32_t ul_type, uint32_t ul_dir, uint32_t ul_maxsize, uint32_t ul_interval, uint32_t ul_nb_bank) +{ + uint32_t ul_pipe = 1; + + for (ul_pipe = 1; ul_pipe < UOTGHS_EPT_NUM; ++ul_pipe) + { + if (Is_uhd_pipe_enabled(ul_pipe)) + { + continue; + } + + uhd_enable_pipe(ul_pipe); + + uhd_configure_pipe(ul_pipe, ul_interval, ul_dev_ep, ul_type, ul_dir, + ul_maxsize, ul_nb_bank, UOTGHS_HSTPIPCFG_AUTOSW); + + uhd_allocate_memory(ul_pipe); + + if (!Is_uhd_pipe_configured(ul_pipe)) + { + uhd_disable_pipe(ul_pipe); + return 0; + } + + uhd_configure_address(ul_pipe, ul_dev_addr); + + // Pipe is configured and allocated successfully + return ul_pipe; + } + + return 0; +} + +/** + * \brief Free a pipe. + * + * \param ul_pipe Pipe number to free. + */ +void UHD_Pipe_Free(uint32_t ul_pipe) +{ + // Unalloc pipe + uhd_disable_pipe(ul_pipe); + uhd_unallocate_memory(ul_pipe); + uhd_reset_pipe(ul_pipe); +} + +/** + * \brief Read from a pipe. + * + * \param ul_pipe Pipe number. + * \param ul_size Maximum number of data to read. + * \param data Buffer to store the data. + * + * \return number of data read. + */ +uint32_t UHD_Pipe_Read(uint32_t ul_pipe, uint32_t ul_size, uint8_t* data) +{ + uint8_t *ptr_ep_data = 0; + uint8_t nb_byte_received = 0; + uint32_t ul_nb_trans = 0; + + // Get information to read data + nb_byte_received = uhd_byte_count(ul_pipe); + + ptr_ep_data = (uint8_t *) & uhd_get_pipe_fifo_access(ul_pipe, 8); + + // Copy data from pipe to payload buffer + while (ul_size && nb_byte_received) { + *data++ = *ptr_ep_data++; + ul_nb_trans++; + ul_size--; + nb_byte_received--; + } + + return ul_nb_trans; +} + +/** + * \brief Write into a pipe. + * + * \param ul_pipe Pipe number. + * \param ul_size Maximum number of data to read. + * \param data Buffer containing data to write. + */ +void UHD_Pipe_Write(uint32_t ul_pipe, uint32_t ul_size, uint8_t* data) +{ + volatile uint8_t *ptr_ep_data = 0; + uint32_t i = 0; + + // Check pipe + if (!Is_uhd_pipe_enabled(ul_pipe)) + { + // Endpoint not valid + TRACE_UOTGHS_HOST(printf("/!\\ UHD_EP_Send : pipe is not enabled!\r\n");) + return; + } + + ptr_ep_data = (volatile uint8_t *)&uhd_get_pipe_fifo_access(ul_pipe, 8); + for (i = 0; i < ul_size; ++i) + *ptr_ep_data++ = *data++; +} + +/** + * \brief Send a pipe content. + * + * \param ul_pipe Pipe number. + * \param ul_token_type Token type. + */ +void UHD_Pipe_Send(uint32_t ul_pipe, uint32_t ul_token_type) +{ + // Check pipe + if (!Is_uhd_pipe_enabled(ul_pipe)) + { + // Endpoint not valid + TRACE_UOTGHS_HOST(printf("/!\\ UHD_EP_Send : pipe %lu is not enabled!\r\n", ul_pipe);) + return; + } + + // Set token type for zero length packet + // When actually using the FIFO, pipe token MUST be configured first + uhd_configure_pipe_token(ul_pipe, ul_token_type); + + // Clear interrupt flags + uhd_ack_setup_ready(ul_pipe); + uhd_ack_in_received(ul_pipe); + uhd_ack_out_ready(ul_pipe); + uhd_ack_short_packet(ul_pipe); + uhd_ack_nak_received(ul_pipe); + + // Send actual packet + uhd_ack_fifocon(ul_pipe); + uhd_unfreeze_pipe(ul_pipe); +} + +/** + * \brief Check for pipe transfer completion. + * + * \param ul_pipe Pipe number. + * \param ul_token_type Token type. + * + * \retval 0 transfer is not complete. + * \retval 1 transfer is complete. + */ +uint32_t UHD_Pipe_Is_Transfer_Complete(uint32_t ul_pipe, uint32_t ul_token_type) +{ + // Check for transfer completion depending on token type + switch (ul_token_type) + { + case UOTGHS_HSTPIPCFG_PTOKEN_SETUP: + if (Is_uhd_setup_ready(ul_pipe)) + { + uhd_freeze_pipe(ul_pipe); + uhd_ack_setup_ready(ul_pipe); + return 1; + } + + case UOTGHS_HSTPIPCFG_PTOKEN_IN: + if (Is_uhd_in_received(ul_pipe)) + { + // In case of low USB speed and with a high CPU frequency, + // a ACK from host can be always running on USB line + // then wait end of ACK on IN pipe. + while(!Is_uhd_pipe_frozen(ul_pipe)) + ; + + // IN packet received + uhd_ack_in_received(ul_pipe); + + return 1; + } + + case UOTGHS_HSTPIPCFG_PTOKEN_OUT: + if (Is_uhd_out_ready(ul_pipe)) + { + // OUT packet sent + uhd_freeze_pipe(ul_pipe); + uhd_ack_out_ready(ul_pipe); + + return 1; + } + } + + return 0; +} + +#endif /* SAM3XA_SERIES */ diff --git a/cores/arduino/USB/samd21_host.h b/cores/arduino/USB/samd21_host.h new file mode 100644 index 00000000..c3b2186f --- /dev/null +++ b/cores/arduino/USB/samd21_host.h @@ -0,0 +1,399 @@ +/* ---------------------------------------------------------------------------- + * SAM Software Package License + * ---------------------------------------------------------------------------- + * Copyright (c) 2011-2012, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following condition is met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +#ifndef UOTGHS_HOST_H_INCLUDED +#define UOTGHS_HOST_H_INCLUDED + + +#ifdef __cplusplus +extern "C" { +#endif + +//! \ingroup usb_host_group +//! \defgroup uhd_group USB Host Driver (UHD) +//! UOTGHS low-level driver for USB host mode +//! +//! @{ + +//! @name UOTGHS Host IP properties +//! +//! @{ +//! Get maximal number of endpoints +#define uhd_get_pipe_max_nbr() (9) +#define UOTGHS_EPT_NUM (uhd_get_pipe_max_nbr()+1) +//! @} + +//! @name Host Vbus line control +//! +//! VBOF is an optional output pin which allows to enable or disable +//! the external VBus generator. +//! +//! @{ +//! Enables hardware control of USB_VBOF output pin when a Vbus error occur +#define uhd_enable_vbus_error_hw_control() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSHWC)) +//! Disables hardware control of USB_VBOF output pin when a Vbus error occur +#define uhd_disable_vbus_error_hw_control() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSHWC)) + +//! Pin and function for USB_VBOF according to configuration from USB_VBOF +#define USB_VBOF_PIN USB_VBOF_GPIO +#define USB_VBOF_FUNCTION USB_VBOF_FLAGS +//! Output USB_VBOF onto its pin +#define uhd_output_vbof_pin() do {\ + pio_configure_pin(USB_VBOF_PIN, USB_VBOF_FUNCTION); \ +} while (0) + +//! Set USB_VBOF output pin polarity +#define uhd_set_vbof_active_high() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSPO)) +#define uhd_set_vbof_active_low() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSPO)) +//! Requests VBus activation +#define uhd_enable_vbus() (Set_bits(UOTGHS->UOTGHS_SFR, UOTGHS_SR_VBUSRQ)) +//! Requests VBus deactivation +#define uhd_disable_vbus() (Set_bits(UOTGHS->UOTGHS_SCR, UOTGHS_SR_VBUSRQ)) +//! Tests if VBus activation has been requested +#define Is_uhd_vbus_enabled() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_VBUSRQ)) +//! @} + +//! @name Host Vbus line monitoring +//! +//! The VBus level is always checked by USBC hardware. +//! +//! @{ +#define uhd_enable_vbus_error_interrupt() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBERRE)) +#define uhd_disable_vbus_error_interrupt() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBERRE)) +#define Is_uhd_vbus_error_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBERRE)) +#define uhd_ack_vbus_error_interrupt() (Set_bits(UOTGHS->UOTGHS_SCR, UOTGHS_SCR_VBERRIC)) +#define Is_uhd_vbus_error_interrupt() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_VBERRI)) +//! @} + +#define uhd_ack_errors_interrupt() (UOTGHS->UOTGHS_SCR = (UOTGHS_SCR_VBERRIC|UOTGHS_SCR_BCERRIC|UOTGHS_SCR_HNPERRIC|UOTGHS_SCR_STOIC)) +#define Is_uhd_errors_interrupt() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBERRE|UOTGHS_CTRL_BCERRE|UOTGHS_CTRL_HNPERRE|UOTGHS_CTRL_STOE)) +#define uhd_enable_suspend_error_interrupt() +#define uhd_enable_hnp_error_interrupt() +#define uhd_enable_bconn_error_interrupt() + +//! @name USB device connection/disconnection monitoring +//! @{ +#define uhd_enable_connection_int() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_DCONNIES) +#define uhd_disable_connection_int() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_DCONNIEC) +#define Is_uhd_connection_int_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_DCONNIE)) +#define uhd_ack_connection() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_DCONNIC) +#define Is_uhd_connection() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_DCONNI)) + +#define uhd_enable_disconnection_int() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_DDISCIES) +#define uhd_disable_disconnection_int() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_DDISCIEC) +#define Is_uhd_disconnection_int_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_DDISCIE)) +#define uhd_ack_disconnection() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_DDISCIC) +#define Is_uhd_disconnection() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_DDISCI)) +//! @} + +//! @name USB device speed control +//! @{ +#define uhd_get_speed_mode() (Rd_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_SPEED_Msk)) +#define Is_uhd_low_speed_mode() (uhd_get_speed_mode() == UOTGHS_SR_SPEED_LOW_SPEED) +#define Is_uhd_full_speed_mode() (uhd_get_speed_mode() == UOTGHS_SR_SPEED_FULL_SPEED) +#define Is_uhd_high_speed_mode() (uhd_get_speed_mode() == UOTGHS_SR_SPEED_HIGH_SPEED) +//! Enable high speed mode +# define uhd_enable_high_speed_mode() (Wr_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SPDCONF_Msk, UOTGHS_HSTCTRL_SPDCONF_HIGH_SPEED)) +//! Disable high speed mode +# define uhd_disable_high_speed_mode() (Wr_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SPDCONF_Msk, UOTGHS_HSTCTRL_SPDCONF_FORCED_FS)) +//! @} + +//! @name Bus events control +//! These macros manage the bus events: reset, SOF, resume, wakeup. +//! @{ + +//! Initiates a reset event +//! @{ +#define uhd_start_reset() (Set_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESET)) +#define Is_uhd_starting_reset() (Tst_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESET)) +#define uhd_stop_reset() (Clr_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESET)) + +#define uhd_enable_reset_sent_interrupt() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_RSTIES) +#define uhd_disable_reset_sent_interrupt() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_RSTIEC) +#define Is_uhd_reset_sent_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_RSTIE)) +#define uhd_ack_reset_sent() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_RSTIC) +#define Is_uhd_reset_sent() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_RSTI)) +//! @} + +//! Initiates a SOF events +//! @{ +#define uhd_enable_sof() (Set_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SOFE)) +#define uhd_disable_sof() (Clr_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SOFE)) +#define Is_uhd_sof_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SOFE)) +#define uhd_get_sof_number() ((UOTGHS->UOTGHS_HSTFNUM&UOTGHS_HSTFNUM_FNUM_Msk)>>UOTGHS_HSTFNUM_FNUM_Pos) +#define uhd_get_microsof_number() ((UOTGHS->UOTGHS_HSTFNUM&UOTGHS_HSTFNUM_MFNUM_Msk)>>UOTGHS_HSTFNUM_MFNUM_Pos) +#define uhd_get_frame_position() (Rd_bits(UOTGHS->UOTGHS_HSTFNUM, UOTGHS_HSTFNUM_FLENHIGH_Msk)) +#define uhd_enable_sof_interrupt() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_HSOFIES) +#define uhd_disable_sof_interrupt() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_HSOFIEC) +#define Is_uhd_sof_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_HSOFIE)) +#define uhd_ack_sof() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_HSOFIC) +#define Is_uhd_sof() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_HSOFI)) +//! @} + +//! Initiates a resume event +//! It is called downstream resume event. +//! @{ +#define uhd_send_resume() (Set_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESUME)) +#define Is_uhd_sending_resume() (Tst_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESUME)) + +#define uhd_enable_downstream_resume_interrupt() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_RSMEDIES) +#define uhd_disable_downstream_resume_interrupt() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_RSMEDIEC) +#define Is_uhd_downstream_resume_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_RSMEDIE)) +#define uhd_ack_downstream_resume() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_RSMEDIC) +#define Is_uhd_downstream_resume() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_RSMEDI)) +//! @} + +//! Detection of a wake-up event +//! A wake-up event is received when the host controller is in the suspend mode: +//! - and an upstream resume from the peripheral is detected. +//! - and a peripheral disconnection is detected. +//! @{ +#define uhd_enable_wakeup_interrupt() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_HWUPIES) +#define uhd_disable_wakeup_interrupt() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_HWUPIEC) +#define Is_uhd_wakeup_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_HWUPIE)) +#define uhd_ack_wakeup() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_HWUPIC) +#define Is_uhd_wakeup() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_HWUPI)) + +#define uhd_enable_upstream_resume_interrupt() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_RXRSMIES) +#define uhd_disable_upstream_resume_interrupt() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_RXRSMIEC) +#define Is_uhd_upstream_resume_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_RXRSMIE)) +#define uhd_ack_upstream_resume() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_RXRSMIC) +#define Is_uhd_upstream_resume() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_RXRSMI)) +//! @} +//! @} + + +//! @name Pipes management +//! @{ + +//! USB address of pipes +//! @{ +#define uhd_configure_address(p, addr) \ + (Wr_bitfield((&UOTGHS->UOTGHS_HSTADDR1)[(p)>>2], \ + UOTGHS_HSTADDR1_HSTADDRP0_Msk << (((p)&0x03)<<3), addr)) +#define uhd_get_configured_address(p) \ + (Rd_bitfield((&UOTGHS->UOTGHS_HSTADDR1)[(p)>>2], \ + UOTGHS_HSTADDR1_HSTADDRP0_Msk << (((p)&0x03)<<3))) +//! @} + +//! Pipe enable +//! Enable, disable, reset, freeze +//! @{ +#define uhd_enable_pipe(p) \ + (Set_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p))) +#define uhd_disable_pipe(p) \ + (Clr_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p))) +#define Is_uhd_pipe_enabled(p) \ + (Tst_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p))) +#define uhd_reset_pipe(p) \ + (Set_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p))); \ + (Clr_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p))) +#define Is_uhd_resetting_pipe(p) \ + (Tst_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p))) +#define uhd_freeze_pipe(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_PFREEZES) +#define uhd_unfreeze_pipe(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_PFREEZEC) +#define Is_uhd_pipe_frozen(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_PFREEZE)) +#define uhd_reset_data_toggle(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_RSTDTS) +#define Is_uhd_data_toggle_reset(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_RSTDT)) +//! @} + +//! Pipe configuration +//! @{ +#define uhd_configure_pipe_int_req_freq(p,freq) (Wr_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_INTFRQ_Msk, (freq))) +#define uhd_get_pipe_int_req_freq(p) (Rd_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_INTFRQ_Msk)) +#define uhd_configure_pipe_endpoint_number(p,ep) (Wr_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PEPNUM_Msk, (ep))) +#define uhd_get_pipe_endpoint_address(p) \ + (uhd_is_pipe_in(p) ?\ + (uhd_get_pipe_endpoint_number(p) | USB_EP_DIR_IN) :\ + (uhd_get_pipe_endpoint_number(p) | USB_EP_DIR_OUT)) +#define uhd_get_pipe_endpoint_number(p) (Rd_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], (UOTGHS_HSTPIPCFG_PEPNUM_Msk))) +#define uhd_configure_pipe_type(p, type) (Wr_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PTYPE_Msk, type)) +#define uhd_get_pipe_type(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PTYPE_Msk)) +#define uhd_enable_pipe_bank_autoswitch(p) (Set_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_AUTOSW)) +#define uhd_disable_pipe_bank_autoswitch(p) (Clr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_AUTOSW)) +#define Is_uhd_pipe_bank_autoswitch_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_AUTOSW)) +#define uhd_configure_pipe_token(p, token) (Wr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PTOKEN_Msk, token)) +#define uhd_get_pipe_token(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PTOKEN_Msk)) +#define uhd_is_pipe_in(p) (UOTGHS_HSTPIPCFG_PTOKEN_IN==uhd_get_pipe_token(p)) +#define uhd_is_pipe_out(p) (UOTGHS_HSTPIPCFG_PTOKEN_OUT==uhd_get_pipe_token(p)) +//! Bounds given integer size to allowed range and rounds it up to the nearest +//! available greater size, then applies register format of UOTGHS controller +//! for pipe size bit-field. +#define uhd_format_pipe_size(size) \ + (32 - clz(((uint32_t)min(max(size, 8), 1024) << 1) - 1) - 1 - 3) +#define uhd_configure_pipe_size(p,size) \ + (Wr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PSIZE_Msk, uhd_format_pipe_size(size))) +#define uhd_get_pipe_size(p) (8<<((Rd_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], (UOTGHS_HSTPIPCFG_PSIZE_Msk)))>> UOTGHS_HSTPIPCFG_PSIZE_Pos)) +#define uhd_configure_pipe_bank(p,bank) (Wr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PBK_Msk, (bank))) +#define uhd_get_pipe_bank(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PBK_Msk)) +#define uhd_allocate_memory(p) (Set_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_ALLOC)) +#define uhd_unallocate_memory(p) (Clr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_ALLOC)) +#define Is_uhd_memory_allocated(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_ALLOC)) + +//! Enable PING management only available in HS mode +# define uhd_enable_ping(p) (Set_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PINGEN)) +//#endif +#define uhd_configure_pipe(p, freq, ep_num, type, token, size, bank, bank_switch) \ + (UOTGHS->UOTGHS_HSTPIPCFG[p] = \ + (bank)|\ + ((uhd_format_pipe_size(size)<<UOTGHS_HSTPIPCFG_PSIZE_Pos)&UOTGHS_HSTPIPCFG_PSIZE_Msk)|\ + ((token)&UOTGHS_HSTPIPCFG_PTOKEN_Msk)|\ + ((type)&UOTGHS_HSTPIPCFG_PTYPE_Msk)|\ + (((ep_num)<<UOTGHS_HSTPIPCFG_PEPNUM_Pos)&UOTGHS_HSTPIPCFG_PEPNUM_Msk)|\ + bank_switch |\ + (((freq)<<UOTGHS_HSTPIPCFG_INTFRQ_Pos)&UOTGHS_HSTPIPCFG_INTFRQ_Msk)) + +#define Is_uhd_pipe_configured(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_CFGOK)) +//! @} + +//! Pipe main interrupts management +//! @{ +#define uhd_enable_pipe_interrupt(p) (UOTGHS->UOTGHS_HSTIER = (UOTGHS_HSTIER_PEP_0 << (p))) +#define uhd_disable_pipe_interrupt(p) (UOTGHS->UOTGHS_HSTIDR = (UOTGHS_HSTIDR_PEP_0 << (p))) +#define Is_uhd_pipe_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_PEP_0 << (p))) +#define Is_uhd_pipe_interrupt(p) (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_PEP_0 << (p))) +//! returns the lowest pipe number generating a pipe interrupt or UOTGHS_EPT_NUM if none +#define uhd_get_interrupt_pipe_number() \ + (ctz(((UOTGHS->UOTGHS_HSTISR >> 8) & (UOTGHS->UOTGHS_HSTIMR >> 8)) | (1 << UOTGHS_EPT_NUM))) +//! @} + +//! Pipe overflow and underflow for isochronous and interrupt endpoints +//! @{ +#define uhd_enable_overflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_OVERFIES) +#define uhd_disable_overflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_OVERFIEC) +#define Is_uhd_overflow_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_OVERFIE)) +#define uhd_ack_overflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_OVERFIC) +#define Is_uhd_overflow(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_OVERFI)) + +#define uhd_enable_underflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_UNDERFIES) +#define uhd_disable_underflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_UNDERFIEC) +#define Is_uhd_underflow_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_UNDERFIE)) +#define uhd_ack_underflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_UNDERFIC) +#define Is_uhd_underflow(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_UNDERFI)) +//! @} + +//! USB packet errors management +//! @{ +#define uhd_enable_stall_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_RXSTALLDES) +#define uhd_disable_stall_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_RXSTALLDEC) +#define Is_uhd_stall_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_RXSTALLDE)) +#define uhd_ack_stall(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_RXSTALLDIC) +#define Is_uhd_stall(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_RXSTALLDI)) + +#define uhd_enable_pipe_error_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_PERRES) +#define uhd_disable_pipe_error_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_PERREC) +#define Is_uhd_pipe_error_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_PERRE)) +#define uhd_ack_all_errors(p) (UOTGHS->UOTGHS_HSTPIPERR[p] = 0UL) +#define Is_uhd_pipe_error(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_PERRI)) +#define uhd_error_status(p) (UOTGHS->UOTGHS_HSTPIPERR[p]) +#define Is_uhd_bad_data_toggle(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_DATATGL)) +#define Is_uhd_data_pid_error(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_DATAPID)) +#define Is_uhd_pid_error(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_PID)) +#define Is_uhd_timeout_error(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_TIMEOUT)) +#define Is_uhd_crc16_error(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_CRC16)) +#define uhd_get_error_counter(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_COUNTER)) +//! @} + +//! Pipe data management +//! @{ +#define uhd_data_toggle(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_DTSEQ)) + +#define uhd_enable_bank_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_NBUSYBKES) +#define uhd_disable_bank_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_NBUSYBKEC) +#define Is_uhd_bank_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_NBUSYBKE)) +#define uhd_nb_busy_bank(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_NBUSYBK_Msk)) +#define uhd_current_bank(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_CURRBK_Msk )) + +#define uhd_enable_short_packet_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_SHORTPACKETES) +#define uhd_disable_short_packet_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_SHORTPACKETIEC) +#define Is_uhd_short_packet_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_SHORTPACKETIE)) ) +#define uhd_ack_short_packet(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_SHORTPACKETIC) +#define Is_uhd_short_packet(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_SHORTPACKETI)) +#define uhd_byte_count(p) (Rd_bitfield(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_PBYCT_Msk)) + +#define Is_uhd_fifocon(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_FIFOCON)) +#define uhd_ack_fifocon(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_FIFOCONC) + +#define uhd_enable_setup_ready_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_TXSTPES) +#define uhd_disable_setup_ready_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_TXSTPEC) +#define Is_uhd_setup_ready_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_TXSTPE)) +#define uhd_ack_setup_ready(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_TXSTPIC) +#define Is_uhd_setup_ready(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_TXSTPI)) + +#define uhd_enable_in_received_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_RXINES) +#define uhd_disable_in_received_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_RXINEC) +#define Is_uhd_in_received_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_RXINE)) +#define uhd_ack_in_received(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_RXINIC) +#define Is_uhd_in_received(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_RXINI)) + +#define uhd_enable_out_ready_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_TXOUTES) +#define uhd_disable_out_ready_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_TXOUTEC) +#define Is_uhd_out_ready_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_TXOUTE)) +#define uhd_ack_out_ready(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_TXOUTIC) +#define Is_uhd_out_ready(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_TXOUTI)) +#define uhd_raise_out_ready(p) (UOTGHS->UOTGHS_HSTPIPIFR[p] = UOTGHS_HSTPIPIFR_TXOUTIS) + +#define uhd_enable_nak_received_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_NAKEDES) +#define uhd_disable_nak_received_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_NAKEDEC) +#define Is_uhd_nak_received_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_NAKEDE)) +#define uhd_ack_nak_received(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_NAKEDIC) +#define Is_uhd_nak_received(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_NAKEDI)) + +#define Is_uhd_read_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_RWALL)) +#define Is_uhd_write_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_RWALL )) + +#define uhd_enable_continuous_in_mode(p) (Set_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], UOTGHS_HSTPIPINRQ_INMODE)) +#define uhd_disable_continuous_in_mode(p) (Clr_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], UOTGHS_HSTPIPINRQ_INMODE)) +#define Is_uhd_continuous_in_mode_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], UOTGHS_HSTPIPINRQ_INMODE)) + +#define uhd_in_request_number(p, in_num) (Set_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], (in_num)-1)) +#define uhd_get_in_request_number(p) (((Rd_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], UOTGHS_HSTPIPINRQ_INRQ_Msk))>>UOTGHS_HSTPIPINRQ_INRQ_Pos)+1) +//! @} + +//! Maximum transfer size on USB DMA +#define UHD_PIPE_MAX_TRANS 0x8000 + +//! Get 64-, 32-, 16- or 8-bit access to FIFO data register of selected pipe. +//! @param p Target Pipe number +//! @param scale Data scale in bits: 64, 32, 16 or 8 +//! @return Volatile 64-, 32-, 16- or 8-bit data pointer to FIFO data register +//! @warning It is up to the user of this macro to make sure that all accesses +//! are aligned with their natural boundaries except 64-bit accesses which +//! require only 32-bit alignment. +//! @warning It is up to the user of this macro to make sure that used HSB +//! addresses are identical to the DPRAM internal pointer modulo 32 bits. +#define uhd_get_pipe_fifo_access(p, scale) \ + (((volatile TPASTE2(U, scale) (*)[UHD_PIPE_MAX_TRANS / ((scale) / 8)])UOTGHS_RAM_ADDR)[(p)]) + + +#ifdef __cplusplus +} +#endif + +#endif /* UOTGHS_HOST_H_INCLUDED */ diff --git a/cores/arduino/validation_usb_device/build_as6/test.atsln b/cores/arduino/validation_usb_device/build_as6/test.atsln new file mode 100644 index 00000000..749e8031 --- /dev/null +++ b/cores/arduino/validation_usb_device/build_as6/test.atsln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Atmel Studio Solution File, Format Version 11.00 +Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "test", "test.cppproj", "{B3F859AD-E162-4C2F-9684-EAC6932FEC80}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Release|ARM = Release|ARM + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B3F859AD-E162-4C2F-9684-EAC6932FEC80}.Debug|ARM.ActiveCfg = Debug|ARM + {B3F859AD-E162-4C2F-9684-EAC6932FEC80}.Debug|ARM.Build.0 = Debug|ARM + {B3F859AD-E162-4C2F-9684-EAC6932FEC80}.Release|ARM.ActiveCfg = Release|ARM + {B3F859AD-E162-4C2F-9684-EAC6932FEC80}.Release|ARM.Build.0 = Release|ARM + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/cores/arduino/validation_usb_device/build_as6/test.atsuo b/cores/arduino/validation_usb_device/build_as6/test.atsuo new file mode 100644 index 0000000000000000000000000000000000000000..16114ce77c4ab38e10352482fd18769e67ea3cec GIT binary patch literal 39424 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 literal 0 HcmV?d00001 diff --git a/cores/arduino/validation_usb_device/build_as6/test.cppproj b/cores/arduino/validation_usb_device/build_as6/test.cppproj new file mode 100644 index 00000000..75f3f8f4 --- /dev/null +++ b/cores/arduino/validation_usb_device/build_as6/test.cppproj @@ -0,0 +1,498 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <SchemaVersion>2.0</SchemaVersion> + <ProjectVersion>6.2</ProjectVersion> + <ToolchainName>com.Atmel.ARMGCC.CPP</ToolchainName> + <ProjectGuid>{b3f859ad-e162-4c2f-9684-eac6932fec80}</ProjectGuid> + <avrdevice>ATSAMD21G18A</avrdevice> + <avrdeviceseries>none</avrdeviceseries> + <OutputType>Executable</OutputType> + <Language>CPP</Language> + <OutputFileName>$(MSBuildProjectName)</OutputFileName> + <OutputFileExtension>.elf</OutputFileExtension> + <OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory> + <AssemblyName>test</AssemblyName> + <Name>test</Name> + <RootNamespace>test</RootNamespace> + <ToolchainFlavour>Native</ToolchainFlavour> + <KeepTimersRunning>true</KeepTimersRunning> + <OverrideVtor>false</OverrideVtor> + <CacheFlash>false</CacheFlash> + <ProgFlashFromRam>true</ProgFlashFromRam> + <RamSnippetAddress>0x20000000</RamSnippetAddress> + <UncachedRange /> + <OverrideVtorValue>exception_table</OverrideVtorValue> + <BootSegment>2</BootSegment> + <eraseonlaunchrule>1</eraseonlaunchrule> + <AsfFrameworkConfig> + <framework-data xmlns=""> + <options /> + <configurations /> + <files /> + <documentation help="" /> + <offline-documentation help="" /> + <dependencies> + <content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.17.0" /> + </dependencies> + </framework-data> + </AsfFrameworkConfig> + <avrtool>com.atmel.avrdbg.tool.edbg</avrtool> + <avrtoolinterface>SWD</avrtoolinterface> + <com_atmel_avrdbg_tool_samice> + <ToolOptions> + <InterfaceProperties> + </InterfaceProperties> + <InterfaceName>SWD</InterfaceName> + </ToolOptions> + <ToolType>com.atmel.avrdbg.tool.samice</ToolType> + <ToolNumber>28001042</ToolNumber> + <ToolName>SAM-ICE</ToolName> + </com_atmel_avrdbg_tool_samice> + <UseGdb>True</UseGdb> + <com_atmel_avrdbg_tool_edbg> + <ToolOptions> + <InterfaceProperties> + <SwdClock>4000000</SwdClock> + </InterfaceProperties> + <InterfaceName>SWD</InterfaceName> + </ToolOptions> + <ToolType>com.atmel.avrdbg.tool.edbg</ToolType> + <ToolNumber>ATML2320021800000003</ToolNumber> + <ToolName>EDBG</ToolName> + </com_atmel_avrdbg_tool_edbg> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)' == 'Release' "> + <ToolchainSettings> + <ArmGccCpp> + <armgcc.common.outputfiles.hex>True</armgcc.common.outputfiles.hex> + <armgcc.common.outputfiles.lss>True</armgcc.common.outputfiles.lss> + <armgcc.common.outputfiles.eep>True</armgcc.common.outputfiles.eep> + <armgcc.common.outputfiles.bin>True</armgcc.common.outputfiles.bin> + <armgcc.common.outputfiles.srec>True</armgcc.common.outputfiles.srec> + <armgcc.compiler.symbols.DefSymbols> + <ListValues> + <Value>NDEBUG</Value> + </ListValues> + </armgcc.compiler.symbols.DefSymbols> + <armgcc.compiler.directories.IncludePaths> + <ListValues> + <Value>../../../../../../../tools/CMSIS/Device/ATMEL</Value> + <Value>../../../../../../../tools/CMSIS/CMSIS/Include</Value> + <Value>../../..</Value> + <Value>../../../USB</Value> + <Value>../../../../../variants/arduino_zero</Value> + </ListValues> + </armgcc.compiler.directories.IncludePaths> + <armgcc.compiler.optimization.level>Optimize for size (-Os)</armgcc.compiler.optimization.level> + <armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>True</armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection> + <armgcc.compiler.warnings.AllWarnings>True</armgcc.compiler.warnings.AllWarnings> + <armgcccpp.compiler.symbols.DefSymbols> + <ListValues> + <Value>NDEBUG</Value> + </ListValues> + </armgcccpp.compiler.symbols.DefSymbols> + <armgcccpp.compiler.directories.IncludePaths> + <ListValues> + <Value>../../../../../../../tools/CMSIS/Device/ATMEL</Value> + <Value>../../../../../../../tools/CMSIS/CMSIS/Include</Value> + <Value>../../..</Value> + <Value>../../../USB</Value> + <Value>../../../../../variants/arduino_zero</Value> + </ListValues> + </armgcccpp.compiler.directories.IncludePaths> + <armgcccpp.compiler.optimization.level>Optimize for size (-Os)</armgcccpp.compiler.optimization.level> + <armgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection>True</armgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection> + <armgcccpp.compiler.warnings.AllWarnings>True</armgcccpp.compiler.warnings.AllWarnings> + <armgcccpp.linker.libraries.Libraries> + <ListValues> + <Value>libm</Value> + </ListValues> + </armgcccpp.linker.libraries.Libraries> + <armgcccpp.linker.libraries.LibrarySearchPaths> + <ListValues> + <Value>../cmsis/linkerScripts</Value> + </ListValues> + </armgcccpp.linker.libraries.LibrarySearchPaths> + <armgcccpp.linker.optimization.GarbageCollectUnusedSections>True</armgcccpp.linker.optimization.GarbageCollectUnusedSections> + <armgcccpp.linker.miscellaneous.LinkerFlags>-Tsamd21g18a_flash.ld</armgcccpp.linker.miscellaneous.LinkerFlags> + <armgcccpp.preprocessingassembler.general.IncludePaths> + <ListValues> + <Value>../../../../../../../tools/CMSIS/Device/ATMEL</Value> + <Value>../../../../../../../tools/CMSIS/CMSIS/Include</Value> + <Value>../../..</Value> + <Value>../../../USB</Value> + <Value>../../../../../variants/arduino_zero</Value> + </ListValues> + </armgcccpp.preprocessingassembler.general.IncludePaths> + </ArmGccCpp> + </ToolchainSettings> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> + <ToolchainSettings> + <ArmGccCpp> + <armgcc.common.outputfiles.hex>True</armgcc.common.outputfiles.hex> + <armgcc.common.outputfiles.lss>True</armgcc.common.outputfiles.lss> + <armgcc.common.outputfiles.eep>True</armgcc.common.outputfiles.eep> + <armgcc.common.outputfiles.bin>True</armgcc.common.outputfiles.bin> + <armgcc.common.outputfiles.srec>True</armgcc.common.outputfiles.srec> + <armgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</armgcc.compiler.general.ChangeDefaultCharTypeUnsigned> + <armgcc.compiler.symbols.DefSymbols> + <ListValues> + <Value>DEBUG</Value> + </ListValues> + </armgcc.compiler.symbols.DefSymbols> + <armgcc.compiler.directories.DefaultIncludePath>False</armgcc.compiler.directories.DefaultIncludePath> + <armgcc.compiler.directories.IncludePaths> + <ListValues> + <Value>../../../../../../../tools/CMSIS/Device/ATMEL</Value> + <Value>../../../../../../../tools/CMSIS/CMSIS/Include</Value> + <Value>../../..</Value> + <Value>../../../USB</Value> + <Value>../../../../../variants/arduino_zero</Value> + </ListValues> + </armgcc.compiler.directories.IncludePaths> + <armgcc.compiler.optimization.level>Optimize (-O1)</armgcc.compiler.optimization.level> + <armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>True</armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection> + <armgcc.compiler.optimization.PrepareDataForGarbageCollection>True</armgcc.compiler.optimization.PrepareDataForGarbageCollection> + <armgcc.compiler.optimization.DebugLevel>Maximum (-g3)</armgcc.compiler.optimization.DebugLevel> + <armgcc.compiler.warnings.AllWarnings>True</armgcc.compiler.warnings.AllWarnings> + <armgcc.compiler.miscellaneous.OtherFlags>-std=c99</armgcc.compiler.miscellaneous.OtherFlags> + <armgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</armgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned> + <armgcccpp.compiler.symbols.DefSymbols> + <ListValues> + <Value>DEBUG</Value> + <Value>USB_VID=0x2341</Value> + <Value>USB_PID=0x004d</Value> + </ListValues> + </armgcccpp.compiler.symbols.DefSymbols> + <armgcccpp.compiler.directories.DefaultIncludePath>False</armgcccpp.compiler.directories.DefaultIncludePath> + <armgcccpp.compiler.directories.IncludePaths> + <ListValues> + <Value>../../../../../../../tools/CMSIS/Device/ATMEL</Value> + <Value>../../../../../../../tools/CMSIS/CMSIS/Include</Value> + <Value>../../..</Value> + <Value>../../../USB</Value> + <Value>../../../../../variants/arduino_zero</Value> + </ListValues> + </armgcccpp.compiler.directories.IncludePaths> + <armgcccpp.compiler.optimization.level>Optimize (-O1)</armgcccpp.compiler.optimization.level> + <armgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection>True</armgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection> + <armgcccpp.compiler.optimization.PrepareDataForGarbageCollection>True</armgcccpp.compiler.optimization.PrepareDataForGarbageCollection> + <armgcccpp.compiler.optimization.DebugLevel>Maximum (-g3)</armgcccpp.compiler.optimization.DebugLevel> + <armgcccpp.compiler.warnings.AllWarnings>True</armgcccpp.compiler.warnings.AllWarnings> + <armgcccpp.compiler.miscellaneous.OtherFlags>-std=c++98</armgcccpp.compiler.miscellaneous.OtherFlags> + <armgcccpp.linker.general.UseNewlibNano>True</armgcccpp.linker.general.UseNewlibNano> + <armgcccpp.linker.libraries.Libraries> + <ListValues> + <Value>libm</Value> + </ListValues> + </armgcccpp.linker.libraries.Libraries> + <armgcccpp.linker.libraries.LibrarySearchPaths> + <ListValues> + <Value>../../../../../variants/arduino_zero/linker_scripts/gcc</Value> + </ListValues> + </armgcccpp.linker.libraries.LibrarySearchPaths> + <armgcccpp.linker.optimization.GarbageCollectUnusedSections>True</armgcccpp.linker.optimization.GarbageCollectUnusedSections> + <armgcccpp.linker.memorysettings.ExternalRAM /> + <armgcccpp.linker.miscellaneous.LinkerFlags>-Tflash.ld</armgcccpp.linker.miscellaneous.LinkerFlags> + <armgcccpp.assembler.general.IncludePaths> + <ListValues> + <Value>../../..</Value> + </ListValues> + </armgcccpp.assembler.general.IncludePaths> + <armgcccpp.assembler.debugging.DebugLevel>Default (-g)</armgcccpp.assembler.debugging.DebugLevel> + <armgcccpp.preprocessingassembler.general.DefaultIncludePath>False</armgcccpp.preprocessingassembler.general.DefaultIncludePath> + <armgcccpp.preprocessingassembler.general.IncludePaths> + <ListValues> + <Value>../../..</Value> + </ListValues> + </armgcccpp.preprocessingassembler.general.IncludePaths> + <armgcccpp.preprocessingassembler.debugging.DebugLevel>Default (-Wa,-g)</armgcccpp.preprocessingassembler.debugging.DebugLevel> + </ArmGccCpp> + </ToolchainSettings> + </PropertyGroup> + <ItemGroup> + <Folder Include="core" /> + <Folder Include="core\validation_usb_device" /> + <Folder Include="core\USB" /> + <Folder Include="variant" /> + </ItemGroup> + <ItemGroup> + <Compile Include="..\..\..\..\variants\arduino_zero\pins_arduino.h"> + <SubType>compile</SubType> + <Link>variant\pins_arduino.h</Link> + </Compile> + <Compile Include="..\..\..\..\variants\arduino_zero\variant.cpp"> + <SubType>compile</SubType> + <Link>variant\variant.cpp</Link> + </Compile> + <Compile Include="..\..\..\..\variants\arduino_zero\variant.h"> + <SubType>compile</SubType> + <Link>variant\variant.h</Link> + </Compile> + <Compile Include="..\..\Arduino.h"> + <SubType>compile</SubType> + <Link>core\Arduino.h</Link> + </Compile> + <Compile Include="..\..\binary.h"> + <SubType>compile</SubType> + <Link>core\binary.h</Link> + </Compile> + <Compile Include="..\..\Client.h"> + <SubType>compile</SubType> + <Link>core\Client.h</Link> + </Compile> + <Compile Include="..\..\delay.c"> + <SubType>compile</SubType> + <Link>core\delay.c</Link> + </Compile> + <Compile Include="..\..\delay.h"> + <SubType>compile</SubType> + <Link>core\delay.h</Link> + </Compile> + <Compile Include="..\..\HardwareSerial.h"> + <SubType>compile</SubType> + <Link>core\HardwareSerial.h</Link> + </Compile> + <Compile Include="..\..\hooks.c"> + <SubType>compile</SubType> + <Link>core\hooks.c</Link> + </Compile> + <Compile Include="..\..\IPAddress.cpp"> + <SubType>compile</SubType> + <Link>core\IPAddress.cpp</Link> + </Compile> + <Compile Include="..\..\IPAddress.h"> + <SubType>compile</SubType> + <Link>core\IPAddress.h</Link> + </Compile> + <Compile Include="..\..\itoa.c"> + <SubType>compile</SubType> + <Link>core\itoa.c</Link> + </Compile> + <Compile Include="..\..\itoa.h"> + <SubType>compile</SubType> + <Link>core\itoa.h</Link> + </Compile> + <Compile Include="..\..\Print.cpp"> + <SubType>compile</SubType> + <Link>core\Print.cpp</Link> + </Compile> + <Compile Include="..\..\Print.h"> + <SubType>compile</SubType> + <Link>core\Print.h</Link> + </Compile> + <Compile Include="..\..\Printable.h"> + <SubType>compile</SubType> + <Link>core\Printable.h</Link> + </Compile> + <Compile Include="..\..\Reset.cpp"> + <SubType>compile</SubType> + <Link>core\Reset.cpp</Link> + </Compile> + <Compile Include="..\..\Reset.h"> + <SubType>compile</SubType> + <Link>core\Reset.h</Link> + </Compile> + <Compile Include="..\..\RingBuffer.cpp"> + <SubType>compile</SubType> + <Link>core\RingBuffer.cpp</Link> + </Compile> + <Compile Include="..\..\RingBuffer.h"> + <SubType>compile</SubType> + <Link>core\RingBuffer.h</Link> + </Compile> + <Compile Include="..\..\SERCOM.cpp"> + <SubType>compile</SubType> + <Link>core\SERCOM.cpp</Link> + </Compile> + <Compile Include="..\..\SERCOM.h"> + <SubType>compile</SubType> + <Link>core\SERCOM.h</Link> + </Compile> + <Compile Include="..\..\Server.h"> + <SubType>compile</SubType> + <Link>core\Server.h</Link> + </Compile> + <Compile Include="..\..\startup.c"> + <SubType>compile</SubType> + <Link>core\startup.c</Link> + </Compile> + <Compile Include="..\..\Stream.cpp"> + <SubType>compile</SubType> + <Link>core\Stream.cpp</Link> + </Compile> + <Compile Include="..\..\Stream.h"> + <SubType>compile</SubType> + <Link>core\Stream.h</Link> + </Compile> + <Compile Include="..\..\syscalls.c"> + <SubType>compile</SubType> + <Link>core\syscalls.c</Link> + </Compile> + <Compile Include="..\..\syscalls.h"> + <SubType>compile</SubType> + <Link>core\syscalls.h</Link> + </Compile> + <Compile Include="..\..\Tone.h"> + <SubType>compile</SubType> + <Link>core\Tone.h</Link> + </Compile> + <Compile Include="..\..\Udp.h"> + <SubType>compile</SubType> + <Link>core\Udp.h</Link> + </Compile> + <Compile Include="..\..\WCharacter.h"> + <SubType>compile</SubType> + <Link>core\WCharacter.h</Link> + </Compile> + <Compile Include="..\..\WInterrupts.h"> + <SubType>compile</SubType> + <Link>core\WInterrupts.h</Link> + </Compile> + <Compile Include="..\..\wiring.c"> + <SubType>compile</SubType> + <Link>core\wiring.c</Link> + </Compile> + <Compile Include="..\..\wiring.h"> + <SubType>compile</SubType> + <Link>core\wiring.h</Link> + </Compile> + <Compile Include="..\..\wiring_analog.h"> + <SubType>compile</SubType> + <Link>core\wiring_analog.h</Link> + </Compile> + <Compile Include="..\..\wiring_constants.h"> + <SubType>compile</SubType> + <Link>core\wiring_constants.h</Link> + </Compile> + <Compile Include="..\..\wiring_digital.c"> + <SubType>compile</SubType> + <Link>core\wiring_digital.c</Link> + </Compile> + <Compile Include="..\..\wiring_digital.h"> + <SubType>compile</SubType> + <Link>core\wiring_digital.h</Link> + </Compile> + <Compile Include="..\..\wiring_private.h"> + <SubType>compile</SubType> + <Link>core\wiring_private.h</Link> + </Compile> + <Compile Include="..\..\wiring_pulse.h"> + <SubType>compile</SubType> + <Link>core\wiring_pulse.h</Link> + </Compile> + <Compile Include="..\..\wiring_shift.c"> + <SubType>compile</SubType> + <Link>core\wiring_shift.c</Link> + </Compile> + <Compile Include="..\..\wiring_shift.h"> + <SubType>compile</SubType> + <Link>core\wiring_shift.h</Link> + </Compile> + <Compile Include="..\..\WMath.cpp"> + <SubType>compile</SubType> + <Link>core\WMath.cpp</Link> + </Compile> + <Compile Include="..\..\WMath.h"> + <SubType>compile</SubType> + <Link>core\WMath.h</Link> + </Compile> + <Compile Include="..\..\WString.cpp"> + <SubType>compile</SubType> + <Link>core\WString.cpp</Link> + </Compile> + <Compile Include="..\..\WString.h"> + <SubType>compile</SubType> + <Link>core\WString.h</Link> + </Compile> + <Compile Include="..\..\WVariant.h"> + <SubType>compile</SubType> + <Link>core\WVariant.h</Link> + </Compile> + <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\Uart.cpp"> + <SubType>compile</SubType> + <Link>core\Uart.cpp</Link> + </Compile> + <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\Uart.h"> + <SubType>compile</SubType> + <Link>core\Uart.h</Link> + </Compile> + <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\CDC.cpp"> + <SubType>compile</SubType> + <Link>core\USB\CDC.cpp</Link> + </Compile> + <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\HID.cpp"> + <SubType>compile</SubType> + <Link>core\USB\HID.cpp</Link> + </Compile> + <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\samd21_device.c"> + <SubType>compile</SubType> + <Link>core\USB\samd21_device.c</Link> + </Compile> + <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\samd21_device.h"> + <SubType>compile</SubType> + <Link>core\USB\samd21_device.h</Link> + </Compile> + <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\samd21_host.h"> + <SubType>compile</SubType> + <Link>core\USB\samd21_host.h</Link> + </Compile> + <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\USBAPI.h"> + <SubType>compile</SubType> + <Link>core\USB\USBAPI.h</Link> + </Compile> + <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\USBCore.cpp"> + <SubType>compile</SubType> + <Link>core\USB\USBCore.cpp</Link> + </Compile> + <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\USBCore.h"> + <SubType>compile</SubType> + <Link>core\USB\USBCore.h</Link> + </Compile> + <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\USBDesc.h"> + <SubType>compile</SubType> + <Link>core\USB\USBDesc.h</Link> + </Compile> + <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\USB_device.h"> + <SubType>compile</SubType> + <Link>core\USB\USB_device.h</Link> + </Compile> + <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\USB_host.h"> + <SubType>compile</SubType> + <Link>core\USB\USB_host.h</Link> + </Compile> + <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\validation_usb_device\test_usb_device.cpp"> + <SubType>compile</SubType> + <Link>core\validation_usb_device\test_usb_device.cpp</Link> + </Compile> + </ItemGroup> + <ItemGroup> + <None Include="..\..\HOWTO - compiling a project.txt"> + <SubType>compile</SubType> + <Link>core\HOWTO - compiling a project.txt</Link> + </None> + <None Include="..\..\Tone.cpp.disabled"> + <SubType>compile</SubType> + <Link>core\Tone.cpp.disabled</Link> + </None> + <None Include="..\..\WInterrupts.c.disabled"> + <SubType>compile</SubType> + <Link>core\WInterrupts.c.disabled</Link> + </None> + <None Include="..\..\wiring_analog.c.disabled"> + <SubType>compile</SubType> + <Link>core\wiring_analog.c.disabled</Link> + </None> + <None Include="..\..\wiring_digital.c.old"> + <SubType>compile</SubType> + <Link>core\wiring_digital.c.old</Link> + </None> + <None Include="..\..\wiring_pulse.cpp.disabled"> + <SubType>compile</SubType> + <Link>core\wiring_pulse.cpp.disabled</Link> + </None> + </ItemGroup> + <Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" /> +</Project> \ No newline at end of file diff --git a/cores/arduino/validation_usb_device/build_gcc/Makefile b/cores/arduino/validation_usb_device/build_gcc/Makefile index 3f88f26e..852324a9 100644 --- a/cores/arduino/validation_usb_device/build_gcc/Makefile +++ b/cores/arduino/validation_usb_device/build_gcc/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2011 Arduino. All right reserved. +# Copyright (c) 2014 Arduino. All right reserved. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -16,26 +16,37 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # -SUBMAKE_OPTIONS=--no-builtin-rules --no-builtin-variables +SUBMAKE_OPTIONS=--no-builtin-rules --no-builtin-variables --no-print-directory #------------------------------------------------------------------------------- # Rules #------------------------------------------------------------------------------- -all: test_usb_device +all: clean test + +test: test_usb_device + +debug: debug_test_usb_device + +clean: clean_test_usb_device .PHONY: test_usb_device -test: +test_usb_device: + @echo ------------------------------------------------------------------------------------ @echo --- Making test_usb_device - @$(MAKE) DEBUG=1 $(SUBMAKE_OPTIONS) -f test_usb_device.mk + @$(MAKE) DEBUG=1 VARIANT=arduino_zero $(SUBMAKE_OPTIONS) -f test_usb_device.mk test + @echo ------------------------------------------------------------------------------------ .PHONY: clean -clean: +clean_test_usb_device: + @echo ------------------------------------------------------------------------------------ @echo --- Cleaning test_usb_device - @$(MAKE) DEBUG=1 $(SUBMAKE_OPTIONS) -f test_usb_device.mk $@ + @$(MAKE) DEBUG=1 VARIANT=arduino_zero $(SUBMAKE_OPTIONS) -f test_usb_device.mk clean + @echo ------------------------------------------------------------------------------------ .PHONY: debug -debug: +debug_test_usb_device: + @echo ------------------------------------------------------------------------------------ @echo --- Debugging test_usb_device - @$(MAKE) DEBUG=1 $(SUBMAKE_OPTIONS) -f test_usb_device.mk $@ - + @$(MAKE) DEBUG=1 VARIANT=arduino_zero $(SUBMAKE_OPTIONS) -f test_usb_device.mk debug + @echo ------------------------------------------------------------------------------------ diff --git a/cores/arduino/validation_usb_device/build_gcc/debug.mk b/cores/arduino/validation_usb_device/build_gcc/debug.mk index a3cc2337..17cd2107 100644 --- a/cores/arduino/validation_usb_device/build_gcc/debug.mk +++ b/cores/arduino/validation_usb_device/build_gcc/debug.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011 Arduino. All right reserved. +# Copyright (c) 2014 Arduino. All right reserved. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -8,7 +8,7 @@ # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public diff --git a/cores/arduino/validation_usb_device/build_gcc/gcc.mk b/cores/arduino/validation_usb_device/build_gcc/gcc.mk index 36951b46..9b4f7b60 100644 --- a/cores/arduino/validation_usb_device/build_gcc/gcc.mk +++ b/cores/arduino/validation_usb_device/build_gcc/gcc.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011 Arduino. All right reserved. +# Copyright (c) 2014 Arduino. All right reserved. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -8,7 +8,7 @@ # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public @@ -16,26 +16,18 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # -# Tool suffix when cross-compiling -#CROSS_COMPILE = ../../../../tools/CodeSourcery_arm/bin/arm-none-eabi- -#CROSS_COMPILE = C:/CodeSourcery_2011.03-42/bin/arm-none-eabi- -CROSS_COMPILE = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi- - # Compilation tools -AR = $(CROSS_COMPILE)ar -CC = $(CROSS_COMPILE)gcc -CXX = $(CROSS_COMPILE)g++ -AS = $(CROSS_COMPILE)as -GDB = $(CROSS_COMPILE)gdb -SIZE = $(CROSS_COMPILE)size -NM = $(CROSS_COMPILE)nm -OBJCOPY = $(CROSS_COMPILE)objcopy - -ifeq ($(OS),Windows_NT) -RM=cs-rm -Rf -else +AR = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-ar +CC = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-gcc +#CXX = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-g++ +CXX = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-gcc +AS = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-as +GDB = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-gdb +SIZE = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-size +NM = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-nm +OBJCOPY = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-objcopy + RM=rm -Rf -endif SEP=\\ @@ -54,12 +46,14 @@ CFLAGS += -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long CFLAGS += -Wunreachable-code CFLAGS += -Wcast-align -CFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb -mlong-calls -ffunction-sections -nostdlib -std=c99 -CFLAGS += $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D$(VARIANT) +CFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m0plus -mthumb -mlong-calls -ffunction-sections -nostdlib -std=c99 +CFLAGS += $(OPTIMIZATION) $(INCLUDES) -D$(DEVICE) -D$(VARIANT) # To reduce application size use only integer printf function. CFLAGS += -Dprintf=iprintf + + # --------------------------------------------------------------------------------------- # CPP Flags @@ -73,13 +67,23 @@ CPPFLAGS += -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations CPPFLAGS += -Wpacked -Wredundant-decls -Winline -Wlong-long #-fno-rtti -fno-exceptions -CPPFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb -mlong-calls -ffunction-sections -std=c++98 -CPPFLAGS += $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) +CPPFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m0plus -mthumb -mlong-calls -ffunction-sections -fdata-sections -std=c++98 +CPPFLAGS += $(OPTIMIZATION) $(INCLUDES) -D$(DEVICE) -D$(VARIANT) # To reduce application size use only integer printf function. CPPFLAGS += -Dprintf=iprintf + + # --------------------------------------------------------------------------------------- # ASM Flags -ASFLAGS = -mcpu=cortex-m3 -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES) +ASFLAGS = -mcpu=cortex-m0plus -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES) + + + +# --------------------------------------------------------------------------------------- +# LD Flags + +LDFLAGS= -mcpu=cortex-m0plus -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols + diff --git a/cores/arduino/validation_usb_device/build_gcc/test_usb_device.mk b/cores/arduino/validation_usb_device/build_gcc/test_usb_device.mk index 336bbc60..bbcf7978 100644 --- a/cores/arduino/validation_usb_device/build_gcc/test_usb_device.mk +++ b/cores/arduino/validation_usb_device/build_gcc/test_usb_device.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011 Arduino. All right reserved. +# Copyright (c) 2014 Arduino. All right reserved. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -16,69 +16,44 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # -# Makefile for compiling libArduino -.SUFFIXES: .o .a .c .s +# Makefile for compiling usb device +.SUFFIXES: .o .a .c .cpp .s # putting default variant ifeq ("$(VARIANT)", "") -#VARIANT=sam3s_ek -#VARIANT=sam3u_ek -VARIANT=arduino_due_x +VARIANT=arduino_zero endif -ifeq ("$(VARIANT)", "sam3s_ek") -CHIP=__SAM3S4C__ -VARIANT_PATH = ../../../../atmel/sam/variants/$(VARIANT) -else ifeq ("$(VARIANT)", "sam3u_ek") -CHIP=__SAM3U4E__ -VARIANT_PATH = ../../../../atmel/sam/variants/$(VARIANT) -else ifeq ("$(VARIANT)", "sam3x_ek") -CHIP=__SAM3X8H__ -VARIANT_PATH = ../../../../atmel/sam/variants/$(VARIANT) -else ifeq ("$(VARIANT)", "arduino_due_u") -CHIP=__SAM3U4E__ -VARIANT_PATH = ../../../../variants/$(VARIANT) -else ifeq ("$(VARIANT)", "arduino_due_x") -CHIP=__SAM3X8E__ -VARIANT_PATH = ../../../../variants/$(VARIANT) +ifeq ("$(VARIANT)", "arduino_zero") +DEVICE=__SAMD21G18A__ endif -TOOLCHAIN=gcc +ifeq ($(DEVICE), __SAMD21G18A__) +DEVICE_NAME=samd21g18 +DEVICE_SERIE=samd21 +else ifeq ($(DEVICE), __SAMD21J18A__) +DEVICE_NAME=samd21j18 +DEVICE_SERIE=samd21 +endif #------------------------------------------------------------------------------- # Path #------------------------------------------------------------------------------- - -# Libraries -PROJECT_BASE_PATH = ./.. -SYSTEM_PATH = ../../../../system - -ifeq ($(CHIP), __SAM3S4C__) -CHIP_NAME=sam3s4c -CHIP_SERIE=sam3s -else ifeq ($(CHIP), __SAM3U4E__) -CHIP_NAME=sam3u4e -CHIP_SERIE=sam3u -else ifeq ($(CHIP), __SAM3N4C__) -CHIP_NAME=sam3n4c -CHIP_SERIE=sam3n -else ifeq ($(CHIP), __SAM3X8H__) -CHIP_NAME=sam3x8h -CHIP_SERIE=sam3xa -else ifeq ($(CHIP), __SAM3X8E__) -CHIP_NAME=sam3x8e -CHIP_SERIE=sam3xa -else -endif - -CMSIS_ROOT_PATH = $(SYSTEM_PATH)/CMSIS +HARDWARE_PATH=../../../../../.. +ARCH_PATH=$(HARDWARE_PATH)/arduino/samd +ARDUINO_CORE_PATH=$(ARCH_PATH)/cores/arduino +ARDUINO_USB_PATH=$(ARDUINO_CORE_PATH)/USB +VARIANT_PATH = $(ARCH_PATH)/variants/$(VARIANT) +TOOLS_PATH = $(HARDWARE_PATH)/tools +CMSIS_ROOT_PATH=$(TOOLS_PATH)/CMSIS CMSIS_ARM_PATH=$(CMSIS_ROOT_PATH)/CMSIS/Include CMSIS_ATMEL_PATH=$(CMSIS_ROOT_PATH)/Device/ATMEL -CMSIS_CHIP_PATH=$(CMSIS_ROOT_PATH)/Device/ATMEL/$(CHIP_SERIE) +#CMSIS_DEVICE_PATH=$(CMSIS_ROOT_PATH)/Device/ATMEL/$(DEVICE_SERIE) + +PROJECT_BASE_PATH = .. + +TOOLCHAIN=gcc -ARDUINO_CORE_PATH=$(PROJECT_BASE_PATH)/.. -ARDUINO_USB_PATH=$(PROJECT_BASE_PATH)/../USB -ARDUINO_USB_HOST_PATH=$(PROJECT_BASE_PATH)/../../../system/USBHost # Output directories OUTPUT_PATH = debug_$(VARIANT) @@ -87,21 +62,17 @@ OUTPUT_PATH = debug_$(VARIANT) # Files #------------------------------------------------------------------------------- -vpath %.h $(PROJECT_BASE_PATH)/.. $(VARIANT_PATH) $(SYSTEM_PATH) $(CMSIS_ARM_PATH) -vpath %.cpp $(PROJECT_BASE_PATH) +vpath %.cpp $(PROJECT_BASE_PATH) $(ARDUINO_CORE_PATH) $(VARIANT_PATH) $(ARDUINO_USB_PATH) +vpath %.c $(PROJECT_BASE_PATH) $(ARDUINO_CORE_PATH) $(VARIANT_PATH) $(ARDUINO_USB_PATH) -VPATH+=$(PROJECT_BASE_PATH) +#VPATH+=$(PROJECT_BASE_PATH) -INCLUDES = -I$(PROJECT_BASE_PATH)/.. +INCLUDES = -I$(ARDUINO_CORE_PATH) +INCLUDES += -I$(ARDUINO_USB_PATH) INCLUDES += -I$(VARIANT_PATH) -#INCLUDES += -I$(VARIANT_PATH)/.. -#INCLUDES += -I$(SYSTEM_PATH) -INCLUDES += -I$(SYSTEM_PATH)/libsam INCLUDES += -I$(CMSIS_ARM_PATH) INCLUDES += -I$(CMSIS_ATMEL_PATH) -INCLUDES += -I$(CMSIS_CHIP_PATH) -INCLUDES += -I$(ARDUINO_USB_PATH) -INCLUDES += -I$(ARDUINO_USB_HOST_PATH) +#INCLUDES += -I$(CMSIS_DEVICE_PATH) #------------------------------------------------------------------------------- ifdef DEBUG @@ -116,6 +87,9 @@ endif include $(TOOLCHAIN).mk +CFLAGS += -DUSB_VID=0x2341 -DUSB_PID=0x004d +CPPFLAGS += -DUSB_VID=0x2341 -DUSB_PID=0x004d + #------------------------------------------------------------------------------- ifdef DEBUG OUTPUT_OBJ=debug @@ -125,19 +99,44 @@ OUTPUT_OBJ=release LIBS_POSTFIX=rel endif -OUTPUT_BIN=test_$(TOOLCHAIN)_$(LIBS_POSTFIX) -LIBS=-Wl,--start-group -lgcc -lc -lstdc++ -lsam_$(CHIP_NAME)_$(TOOLCHAIN)_$(LIBS_POSTFIX) -larduino_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX) -lvariant_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX) -Wl,--end-group +OUTPUT_BIN=test_usb_device_$(TOOLCHAIN)_$(LIBS_POSTFIX) +LIBS=-Wl,--start-group -lgcc -lc -lstdc++ -Wl,--end-group LIB_PATH =-L$(PROJECT_BASE_PATH)/.. LIB_PATH+=-L=/lib/thumb2 #LIB_PATH+=-L=/../lib/gcc/arm-none-eabi/4.5.2/thumb2 -LDFLAGS= -mcpu=cortex-m3 -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols +#------------------------------------------------------------------------------- +# C source files and objects +#------------------------------------------------------------------------------- +#C_SRC=$(wildcard $(PROJECT_BASE_PATH)/*.c) +#C_SRC+=$(wildcard $(ARDUINO_CORE_PATH)/*.c) +#C_SRC+=$(wildcard $(VARIANT_PATH)/*.c) +#C_SRC=$(wildcard $(ARDUINO_USB_PATH)/*.c) + +C_SRC=$(ARDUINO_USB_PATH)/samd21_device.c +C_SRC+=$(ARDUINO_CORE_PATH)/startup.c +C_SRC+=$(ARDUINO_CORE_PATH)/syscalls.c + +C_OBJ_TEMP = $(patsubst %.c, %.o, $(notdir $(C_SRC))) + +# during development, remove some files +C_OBJ_FILTER= + +C_OBJ=$(filter-out $(C_OBJ_FILTER), $(C_OBJ_TEMP)) #------------------------------------------------------------------------------- # CPP source files and objects #------------------------------------------------------------------------------- CPP_SRC=$(wildcard $(PROJECT_BASE_PATH)/*.cpp) +#CPP_SRC+=$(wildcard $(ARDUINO_CORE_PATH)/*.cpp) +#CPP_SRC+=$(wildcard $(VARIANT_PATH)/*.cpp) +#CPP_SRC+=$(wildcard $(ARDUINO_USB_PATH)/*.cpp) + +CPP_SRC+=$(ARDUINO_USB_PATH)/USBCore.cpp +CPP_SRC+=$(ARDUINO_USB_PATH)/CDC.cpp +CPP_SRC+=$(ARDUINO_USB_PATH)/HID.cpp +#CPP_SRC+=$(VARIANT_PATH)/variant.cpp ##//JCB needed, but not compile CPP_OBJ_TEMP = $(patsubst %.cpp, %.o, $(notdir $(CPP_SRC))) @@ -151,48 +150,72 @@ CPP_OBJ=$(filter-out $(CPP_OBJ_FILTER), $(CPP_OBJ_TEMP)) #------------------------------------------------------------------------------- all: test -test: create_output libsam_$(CHIP_NAME)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a libarduino_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a libvariant_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a $(OUTPUT_BIN) +test: create_output $(OUTPUT_BIN) .PHONY: create_output create_output: + @echo ------------------------------------------------------------------------------------ @echo --- Preparing $(VARIANT) files in $(OUTPUT_PATH) $(OUTPUT_BIN) -# @echo ------------------------- -# @echo *$(INCLUDES) -# @echo ------------------------- -# @echo *$(C_SRC) -# @echo ------------------------- -# @echo *$(C_OBJ) -# @echo ------------------------- -# @echo *$(addprefix $(OUTPUT_PATH)/, $(C_OBJ)) -# @echo ------------------------- -# @echo *$(CPP_SRC) -# @echo ------------------------- -# @echo *$(CPP_OBJ) -# @echo ------------------------- -# @echo *$(addprefix $(OUTPUT_PATH)/, $(CPP_OBJ)) -# @echo ------------------------- -# @echo *$(A_SRC) -# @echo ------------------------- + @echo - + @echo - + @echo INCLUDES ------------------------- + @echo $(INCLUDES) + @echo - + @echo - + @echo C_SRC ------------------------- + @echo $(C_SRC) + @echo - + @echo - + @echo C_OBJ ------------------------- + @echo $(C_OBJ) + @echo - + @echo - + @echo C_OBJ prefix ------------------------- + @echo $(addprefix $(OUTPUT_PATH)/, $(C_OBJ)) + @echo - + @echo - + @echo CPP_SRC ------------------------- + @echo $(CPP_SRC) + @echo - + @echo - + @echo CPP_OBJ ------------------------- + @echo $(CPP_OBJ) + @echo - + @echo - + @echo CPP_OBJ prefix ------------------------- + @echo $(addprefix $(OUTPUT_PATH)/, $(CPP_OBJ)) +# @echo A_SRC ------------------------- +# @echo $(A_SRC) + @echo ------------------------- -@mkdir $(OUTPUT_PATH) 1>NUL 2>&1 + @echo ------------------------------------------------------------------------------------ + +$(addprefix $(OUTPUT_PATH)/,$(C_OBJ)): $(OUTPUT_PATH)/%.o: %.c + @echo Current folder is $(shell cd) - $@ $^ +# @"$(CC)" -c $(CFLAGS) $< -o $@ +# "$(CC)" -v -c $(CFLAGS) $< -o $@ + "$(CC)" -c $(CFLAGS) $< -o $@ $(addprefix $(OUTPUT_PATH)/,$(CPP_OBJ)): $(OUTPUT_PATH)/%.o: %.cpp -# @"$(CC)" -c $(CPPFLAGS) $< -o $@ - @"$(CXX)" -c $(CPPFLAGS) $< -o $@ -# @"$(CXX)" -v -c $(CPPFLAGS) $< -o $@ + @echo Current folder is $(shell cd) - $@ $^ +# @"$(CXX)" -c $(CPPFLAGS) $< -o $@ +# "$(CXX)" -v -c $(CPPFLAGS) $< -o $@ + "$(CXX)" -c $(CPPFLAGS) $< -o $@ $(OUTPUT_BIN): $(addprefix $(OUTPUT_PATH)/, $(C_OBJ)) $(addprefix $(OUTPUT_PATH)/, $(CPP_OBJ)) $(addprefix $(OUTPUT_PATH)/, $(A_OBJ)) @"$(CC)" $(LIB_PATH) $(LDFLAGS) -T"$(VARIANT_PATH)/linker_scripts/gcc/flash.ld" -Wl,-Map,$(OUTPUT_PATH)/$@.map -o $(OUTPUT_PATH)/$@.elf $^ $(LIBS) -# @"$(CC)" $(LIB_PATH) $(LDFLAGS) -T"$(VARIANT_PATH)/linker_scripts/gcc/sram.ld" -Wl,-Map,$(OUTPUT_PATH)/$@.map -o $(OUTPUT_PATH)/$@.elf $^ $(LIBS) @"$(NM)" $(OUTPUT_PATH)/$@.elf >$(OUTPUT_PATH)/$@.elf.txt @"$(OBJCOPY)" -O binary $(OUTPUT_PATH)/$@.elf $(OUTPUT_PATH)/$@.bin $(SIZE) $^ $(OUTPUT_PATH)/$@.elf .PHONY: clean clean: - @echo --- Cleaning test files + @echo ------------------------------------------------------------------------------------ + @echo --- Cleaning test files for $(VARIANT) -@$(RM) $(OUTPUT_PATH) 1>NUL 2>&1 + @echo ------------------------------------------------------------------------------------ # -$(RM) $(OUTPUT_PATH)/test.o # -$(RM) $(OUTPUT_PATH)/$(OUTPUT_BIN).elf @@ -202,17 +225,4 @@ clean: debug: test @"$(GDB)" -x "$(VARIANT_PATH)/debug_scripts/gcc/$(VARIANT)_flash.gdb" -ex "reset" -readnow -se $(OUTPUT_PATH)/$(OUTPUT_BIN).elf -# @"$(GDB)" -w -x "$(VARIANT_PATH)/debug_scripts/gcc/$(VARIANT)_sram.gdb" -ex "reset" -readnow -se $(OUTPUT_PATH)/$(OUTPUT_BIN).elf - -libsam_$(CHIP_NAME)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a: - @echo Building $@ - @$(MAKE) -C $(SYSTEM_PATH)/libsam/build_gcc -f Makefile $@ - -libarduino_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a: - @echo Building $@ - $(MAKE) -C $(ARDUINO_CORE_PATH)/build_gcc -f Makefile $(VARIANT) - -libvariant_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a: - @echo Building $@ - $(MAKE) -C $(VARIANT_PATH)/build_gcc -f Makefile $(VARIANT) diff --git a/cores/arduino/validation_usb_device/test_usb_device.cpp b/cores/arduino/validation_usb_device/test_usb_device.cpp index 8f3f226c..47db951a 100644 --- a/cores/arduino/validation_usb_device/test_usb_device.cpp +++ b/cores/arduino/validation_usb_device/test_usb_device.cpp @@ -16,23 +16,50 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "variant.h" -#include <stdio.h> +#define ARDUINO_MAIN +#include "Arduino.h" -void setup() { - Serial.begin(57600); + + + +void setup(void) { + Serial.begin(115200); + +#ifdef HID_ENABLED Mouse.begin(); +#endif } -void loop() { +void loop(void) { + +#ifdef HID_ENABLED Mouse.move(1, 0, 0); +#endif - if (Serial.available() > 0) - { - char inChar = Serial.read(); - Serial.print(inChar); - Serial1.print(inChar); - } +// if (Serial.available() > 0) +// { +// char inChar = Serial.read(); +// Serial.print(inChar); +// Serial1.print(inChar); +// } - delay(10); +// delay(10); +} + +int main(void) +{ + //JCB init(); not compile at this time + //JCB already in Reset_Handler SystemInit(); + + USBDevice.attach(); + + setup(); + + for (;;) { + loop(); + if (serialEventRun) serialEventRun(); + } + + return 0; } + \ No newline at end of file -- GitLab