diff --git a/hardware/arduino/sam/cores/sam/USB/USBAPI.h b/hardware/arduino/sam/cores/sam/USB/USBAPI.h index 8a248ae11..f06380bf0 100644 --- a/hardware/arduino/sam/cores/sam/USB/USBAPI.h +++ b/hardware/arduino/sam/cores/sam/USB/USBAPI.h @@ -15,8 +15,8 @@ public: USB_(); bool configured(); - void attach(); - void detach(); // Serial port goes down too... + bool attach(); + bool detach(); // Serial port goes down too... void poll(); }; extern USB_ USB; diff --git a/hardware/arduino/sam/cores/sam/USB/USBCore.cpp.disabled b/hardware/arduino/sam/cores/sam/USB/USBCore.cpp.disabled index f4587e97f..4b352afa4 100644 --- a/hardware/arduino/sam/cores/sam/USB/USBCore.cpp.disabled +++ b/hardware/arduino/sam/cores/sam/USB/USBCore.cpp.disabled @@ -94,8 +94,9 @@ const DeviceDescriptor USB_DeviceDescriptorA = //================================================================== //================================================================== -volatile uint8_t _usbConfiguration = 0; -uint8_t _cdcComposite = 0; +volatile uint32_t _usbConfiguration = 0; +volatile uint32_t _usbInitialized = 0; +uint32_t _cdcComposite = 0; //================================================================== @@ -129,7 +130,7 @@ int USBD_Recv(uint8_t ep, void* d, int len) } n = FifoByteCount(ep); - + len = min(n,len); n = len; dst = (uint8_t*)d; @@ -151,16 +152,16 @@ static bool USBD_SendControl(uint8_t d) { return false; } - + Send8( d ) ; - + if ( !((_cmark + 1) & 0x3F) ) { ClearIN(); // Fifo is full, release this packet } } _cmark++; - + return true ; } @@ -173,7 +174,7 @@ int USBD_SendControl(uint8_t flags, const void* d, int len) while ( len-- ) { uint8_t c = *data++ ; - + if ( !SendControl( c ) ) { return -1; @@ -293,7 +294,7 @@ static bool USBD_SendDescriptor(Setup& setup) { return false ; } - + if ( desc_length == 0 ) { desc_length = *desc_addr; @@ -308,7 +309,7 @@ static bool USBD_SendDescriptor(Setup& setup) void USB_ISR() { SetEP(0) ; - + if ( !ReceivedSetupInt() ) { return; @@ -367,7 +368,7 @@ void USB_ISR() { InitEndpoints(); _usbConfiguration = setup.wValueL; - } + } else { ok = false; @@ -458,17 +459,38 @@ USB_ USB; USB_::USB_() { + if ( USBD_Init() == 0UL ) + { + _usbInitialized=1UL ; + } } -void USB_::attach(void) +bool USB_::attach(void) { - USBD_Attach() ; + if ( _usbInitialized != 0UL ) + { + USBD_Attach() ; + + return true ; + } + else + { + return false ; + } } -void USB_::detach(void) +bool USB_::detach(void) { - UDPHS->UDPHS_CTRL |= UDPHS_CTRL_DETACH; // detach - UDPHS->UDPHS_CTRL &= ~UDPHS_CTRL_PULLD_DIS; // Enable Pull Down + if ( _usbInitialized != 0UL ) + { + USBD_Detach() ; + + return true ; + } + else + { + return false ; + } } // Check for interrupts diff --git a/hardware/arduino/sam/cores/sam/build_gcc/libarduino_sam3u_ek.mk b/hardware/arduino/sam/cores/sam/build_gcc/libarduino_sam3u_ek.mk index fc312592a..d698e7787 100644 --- a/hardware/arduino/sam/cores/sam/build_gcc/libarduino_sam3u_ek.mk +++ b/hardware/arduino/sam/cores/sam/build_gcc/libarduino_sam3u_ek.mk @@ -148,8 +148,6 @@ create_output: # @echo *$(A_SRC) # @echo ------------------------- -# -@mkdir $(subst /,$(SEP),$(OUTPUT_BIN)) 1>NUL 2>&1 - -mkdir $(subst /,$(SEP),$(OUTPUT_BIN)) -@mkdir $(OUTPUT_PATH) 1>NUL 2>&1 $(addprefix $(OUTPUT_PATH)/,$(C_OBJ)): $(OUTPUT_PATH)/%.o: %.c diff --git a/hardware/arduino/sam/cores/sam/build_gcc/libarduino_sam3x_ek.mk b/hardware/arduino/sam/cores/sam/build_gcc/libarduino_sam3x_ek.mk index a444f7527..7eabc0c37 100644 --- a/hardware/arduino/sam/cores/sam/build_gcc/libarduino_sam3x_ek.mk +++ b/hardware/arduino/sam/cores/sam/build_gcc/libarduino_sam3x_ek.mk @@ -148,8 +148,6 @@ create_output: # @echo *$(A_SRC) # @echo ------------------------- -# -@mkdir $(subst /,$(SEP),$(OUTPUT_BIN)) 1>NUL 2>&1 - -mkdir $(subst /,$(SEP),$(OUTPUT_BIN)) -@mkdir $(OUTPUT_PATH) 1>NUL 2>&1 $(addprefix $(OUTPUT_PATH)/,$(C_OBJ)): $(OUTPUT_PATH)/%.o: %.c diff --git a/hardware/arduino/sam/system/libsam/include/USB_device.h b/hardware/arduino/sam/system/libsam/include/USB_device.h index 6a6950db3..49baf0c04 100644 --- a/hardware/arduino/sam/system/libsam/include/USB_device.h +++ b/hardware/arduino/sam/system/libsam/include/USB_device.h @@ -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 @@ -64,6 +64,8 @@ extern void USBD_InitEndpoints(void) ; extern void USBD_InitControl(int end) ; +extern uint32_t USBD_Init(void) ; + extern void USBD_Attach(void) ; extern void USBD_Detach(void) ; diff --git a/hardware/arduino/sam/system/libsam/include/uotghs.h b/hardware/arduino/sam/system/libsam/include/uotghs.h index 01de19e5f..df5f89958 100644 --- a/hardware/arduino/sam/system/libsam/include/uotghs.h +++ b/hardware/arduino/sam/system/libsam/include/uotghs.h @@ -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 @@ -19,4 +19,29 @@ #ifndef UOTGHS_H_INCLUDED #define UOTGHS_H_INCLUDED +#define EP_SINGLE_64 (0x32UL) // EP0 +#define EP_DOUBLE_64 (0x36UL) // Other endpoints + + +// Control Endpoint +#define EP_TYPE_CONTROL (UOTGHS_DEVEPTCFG_EPSIZE_64_BYTE | UOTGHS_DEVEPTCFG_EPTYPE_CTRL | UOTGHS_DEVEPTCFG_EPBK_1_BANK) + +// CDC Endpoints +#ifdef CDC_ENABLED +#define EP_TYPE_BULK_IN (UOTGHS_DEVEPTCFG_EPSIZE_512_BYTE | UOTGHS_DEVEPTCFG_EPDIR_IN | UOTGHS_DEVEPTCFG_EPTYPE_BLK | UOTGHS_DEVEPTCFG_EPBK_2_BANK) +#define EP_TYPE_BULK_OUT (UOTGHS_DEVEPTCFG_EPSIZE_512_BYTE | UOTGHS_DEVEPTCFG_EPTYPE_BLK | UOTGHS_DEVEPTCFG_EPBK_2_BANK) +#define EP_TYPE_INTERRUPT_IN (UOTGHS_DEVEPTCFG_EPSIZE_64_BYTE | UOTGHS_DEVEPTCFG_EPDIR_IN | UOTGHS_DEVEPTCFG_EPTYPE_INTRPT | UOTGHS_DEVEPTCFG_EPBK_2_BANK) +#endif + +// HID Endpoints +#ifdef HID_ENABLED +#define EP_TYPE_INTERRUPT_IN_HID (UOTGHS_DEVEPTCFG_EPSIZE_64_BYTE | UOTGHS_DEVEPTCFG_EPDIR_IN | UOTGHS_DEVEPTCFG_EPTYPE_INTRPT | UOTGHS_DEVEPTCFG_EPBK_2_BANK) +#endif + +// Various definitions +#define EP_TYPE_INTERRUPT_OUT (UOTGHS_DEVEPTCFG_EPSIZE_64_BYTE | UOTGHS_DEVEPTCFG_EPTYPE_INTRPT | UOTGHS_DEVEPTCFG_EPTYPE_INTRPT | UOTGHS_DEVEPTCFG_EPBK_1_BANK) +#define EP_TYPE_ISOCHRONOUS_IN (UOTGHS_DEVEPTCFG_EPSIZE_1024_BYTE | UOTGHS_DEVEPTCFG_EPDIR_IN | UOTGHS_DEVEPTCFG_EPTYPE_ISO | UOTGHS_DEVEPTCFG_EPBK_3_BANK) +#define EP_TYPE_ISOCHRONOUS_OUT (UOTGHS_DEVEPTCFG_EPSIZE_1024_BYTE | UOTGHS_DEVEPTCFG_EPTYPE_ISO | UOTGHS_DEVEPTCFG_EPBK_3_BANK) + + #endif /* UOTGHS_H_INCLUDED */ diff --git a/hardware/arduino/sam/system/libsam/source/uotghs.c b/hardware/arduino/sam/system/libsam/source/uotghs.c index 5052f0207..ab2b5927a 100644 --- a/hardware/arduino/sam/system/libsam/source/uotghs.c +++ b/hardware/arduino/sam/system/libsam/source/uotghs.c @@ -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 @@ -20,5 +20,157 @@ #if SAM3XA_SERIES +void USBD_InitEndpoints(void) +{ +} + +uint32_t USBD_Init(void) +{ + uint32_t ul ; + + // Enables the USB Clock + pmc_enable_periph_clk(ID_UOTGHS); + pmc_enable_upll_clock(); + pmc_switch_udpck_to_upllck(0); // div=0+1 + pmc_enable_udpck(); + + // Configure interrupts + NVIC_SetPriority((IRQn_Type) ID_UOTGHS, 0UL); + NVIC_EnableIRQ((IRQn_Type) ID_UOTGHS); + + // 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); + + // Enable USB macro + UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_USBE; + + // Automatic mode speed for device + UOTGHS->UOTGHS_DEVCTRL &= ~UOTGHS_DEVCTRL_SPDCONF_Msk; // Normal mode + + UOTGHS->UOTGHS_DEVCTRL &= ~( UOTGHS_DEVCTRL_LS | UOTGHS_DEVCTRL_TSTJ | UOTGHS_DEVCTRL_TSTK | + UOTGHS_DEVCTRL_TSTPCKT | UOTGHS_DEVCTRL_OPMODE2 ); // Normal mode + + UOTGHS->UOTGHS_DEVCTRL = 0; + UOTGHS->UOTGHS_HSTCTRL = 0; + + // Enable OTG pad + UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_OTGPADE; + + // Enable clock OTG pad + UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_FRZCLK; + + // Usb disable + UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_USBE; + UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_OTGPADE; + UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_FRZCLK; + + // Usb enable + UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_USBE; + UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_OTGPADE; + UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_FRZCLK; + + // Usb select_device + UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_UIDE; + UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_UIMOD_Device; + + // Device is in the Attached state +// deviceState = USBD_STATE_SUSPENDED; +// previousDeviceState = USBD_STATE_POWERED; + + // Enable USB macro and clear all other bits + UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_CTRL_USBE; + UOTGHS->UOTGHS_DEVCTRL = UOTGHS_CTRL_USBE; + + // Configure the pull-up on D+ and disconnect it + USBD_Detach(); + + // Clear General IT + UOTGHS->UOTGHS_SCR = (UOTGHS_SCR_IDTIC|UOTGHS_SCR_VBUSTIC|UOTGHS_SCR_SRPIC|UOTGHS_SCR_VBERRIC|UOTGHS_SCR_BCERRIC|UOTGHS_SCR_ROLEEXIC|UOTGHS_SCR_HNPERRIC|UOTGHS_SCR_STOIC|UOTGHS_SCR_VBUSRQC); + + // Clear OTG Device IT + UOTGHS->UOTGHS_DEVICR = (UOTGHS_DEVICR_SUSPC|UOTGHS_DEVICR_MSOFC|UOTGHS_DEVICR_SOFC|UOTGHS_DEVICR_EORSTC|UOTGHS_DEVICR_WAKEUPC|UOTGHS_DEVICR_EORSMC|UOTGHS_DEVICR_UPRSMC); + + // Clear OTG Host IT + UOTGHS->UOTGHS_HSTICR = (UOTGHS_HSTICR_DCONNIC|UOTGHS_HSTICR_DDISCIC|UOTGHS_HSTICR_RSTIC|UOTGHS_HSTICR_RSMEDIC|UOTGHS_HSTICR_RXRSMIC|UOTGHS_HSTICR_HSOFIC|UOTGHS_HSTICR_HWUPIC); + + // Reset all Endpoints Fifos + UOTGHS->UOTGHS_DEVEPT |= (UOTGHS_DEVEPT_EPRST0|UOTGHS_DEVEPT_EPRST1|UOTGHS_DEVEPT_EPRST2|UOTGHS_DEVEPT_EPRST3|UOTGHS_DEVEPT_EPRST4| + UOTGHS_DEVEPT_EPRST5|UOTGHS_DEVEPT_EPRST6|UOTGHS_DEVEPT_EPRST7|UOTGHS_DEVEPT_EPRST8); + UOTGHS->UOTGHS_DEVEPT &= ~(UOTGHS_DEVEPT_EPRST0|UOTGHS_DEVEPT_EPRST1|UOTGHS_DEVEPT_EPRST2|UOTGHS_DEVEPT_EPRST3|UOTGHS_DEVEPT_EPRST4| + UOTGHS_DEVEPT_EPRST5|UOTGHS_DEVEPT_EPRST6|UOTGHS_DEVEPT_EPRST7|UOTGHS_DEVEPT_EPRST8); + + // Disable all endpoints + UOTGHS->UOTGHS_DEVEPT &= ~(UOTGHS_DEVEPT_EPEN0|UOTGHS_DEVEPT_EPEN1|UOTGHS_DEVEPT_EPEN2|UOTGHS_DEVEPT_EPEN3|UOTGHS_DEVEPT_EPEN4| + UOTGHS_DEVEPT_EPEN5|UOTGHS_DEVEPT_EPEN6|UOTGHS_DEVEPT_EPEN7|UOTGHS_DEVEPT_EPEN8); + + // Device is in the Attached state +// deviceState = USBD_STATE_SUSPENDED; +// previousDeviceState = USBD_STATE_POWERED; + + // Automatic mode speed for device + UOTGHS->UOTGHS_DEVCTRL &= ~UOTGHS_DEVCTRL_SPDCONF_Msk; + // Force Full Speed mode for device + //UOTGHS->UOTGHS_DEVCTRL = UOTGHS_DEVCTRL_SPDCONF_FORCED_FS; + // Force High Speed mode for device + //UOTGHS->UOTGHS_DEVCTRL = UOTGHS_DEVCTRL_SPDCONF_HIGH_SPEED; + + UOTGHS->UOTGHS_DEVCTRL &= ~(UOTGHS_DEVCTRL_LS|UOTGHS_DEVCTRL_TSTJ| UOTGHS_DEVCTRL_TSTK|UOTGHS_DEVCTRL_TSTPCKT|UOTGHS_DEVCTRL_OPMODE2) ; + + // Enable USB macro + UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_CTRL_USBE; + + // Enable the UID pin select + UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_CTRL_UIDE; + + // Enable OTG pad + UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_CTRL_OTGPADE; + + // Enable clock OTG pad + UOTGHS->UOTGHS_DEVCTRL &= ~UOTGHS_CTRL_FRZCLK; + + // With OR without DMA !!! + // Initialization of DMA + for( ul=1; ul<= UOTGHSDEVDMA_NUMBER ; ul++ ) + { + // RESET endpoint canal DMA: + // DMA stop channel command + UOTGHS->UOTGHS_DEVDMA[ul].UOTGHS_DEVDMACONTROL = 0; // STOP command + + // Disable endpoint + UOTGHS->UOTGHS_DEVEPTIDR[ul] = (UOTGHS_DEVEPTIDR_TXINEC|UOTGHS_DEVEPTIDR_RXOUTEC|UOTGHS_DEVEPTIDR_RXSTPEC|UOTGHS_DEVEPTIDR_UNDERFEC|UOTGHS_DEVEPTIDR_NAKOUTEC| + UOTGHS_DEVEPTIDR_HBISOINERREC|UOTGHS_DEVEPTIDR_NAKINEC|UOTGHS_DEVEPTIDR_HBISOFLUSHEC|UOTGHS_DEVEPTIDR_OVERFEC|UOTGHS_DEVEPTIDR_STALLEDEC| + UOTGHS_DEVEPTIDR_CRCERREC|UOTGHS_DEVEPTIDR_SHORTPACKETEC|UOTGHS_DEVEPTIDR_MDATEC|UOTGHS_DEVEPTIDR_DATAXEC|UOTGHS_DEVEPTIDR_ERRORTRANSEC| + UOTGHS_DEVEPTIDR_NBUSYBKEC|UOTGHS_DEVEPTIDR_FIFOCONC|UOTGHS_DEVEPTIDR_EPDISHDMAC|UOTGHS_DEVEPTIDR_NYETDISC|UOTGHS_DEVEPTIDR_STALLRQC); + + // Reset endpoint config + UOTGHS->UOTGHS_DEVEPTCFG[ul] = 0UL; + + // Reset DMA channel (Buff count and Control field) + UOTGHS->UOTGHS_DEVDMA[ul].UOTGHS_DEVDMACONTROL = 0x02UL; // NON STOP command + + // Reset DMA channel 0 (STOP) + UOTGHS->UOTGHS_DEVDMA[ul].UOTGHS_DEVDMACONTROL = 0UL; // STOP command + + // Clear DMA channel status (read the register to clear it) + UOTGHS->UOTGHS_DEVDMA[ul].UOTGHS_DEVDMASTATUS = UOTGHS->UOTGHS_DEVDMA[ul].UOTGHS_DEVDMASTATUS; + } + + UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_CTRL_VBUSTE; + UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_WAKEUPES; + + return 0UL ; +} + +void USBD_Attach(void) +{ + UOTGHS->UOTGHS_DEVCTRL &= ~(unsigned int)UOTGHS_DEVCTRL_DETACH; +} + +void USBD_Detach(void) +{ + UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_DETACH; +} + #endif /* SAM3XA_SERIES */