1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-02-18 12:54:25 +01:00

[sam] first USB with Init/Attach/Detach

This commit is contained in:
Thibaut VIARD 2012-04-28 15:16:13 +02:00
parent 08b614048d
commit 86533a5e8f
7 changed files with 221 additions and 24 deletions

View File

@ -15,8 +15,8 @@ public:
USB_(); USB_();
bool configured(); bool configured();
void attach(); bool attach();
void detach(); // Serial port goes down too... bool detach(); // Serial port goes down too...
void poll(); void poll();
}; };
extern USB_ USB; extern USB_ USB;

View File

@ -94,8 +94,9 @@ const DeviceDescriptor USB_DeviceDescriptorA =
//================================================================== //==================================================================
//================================================================== //==================================================================
volatile uint8_t _usbConfiguration = 0; volatile uint32_t _usbConfiguration = 0;
uint8_t _cdcComposite = 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); n = FifoByteCount(ep);
len = min(n,len); len = min(n,len);
n = len; n = len;
dst = (uint8_t*)d; dst = (uint8_t*)d;
@ -151,16 +152,16 @@ static bool USBD_SendControl(uint8_t d)
{ {
return false; return false;
} }
Send8( d ) ; Send8( d ) ;
if ( !((_cmark + 1) & 0x3F) ) if ( !((_cmark + 1) & 0x3F) )
{ {
ClearIN(); // Fifo is full, release this packet ClearIN(); // Fifo is full, release this packet
} }
} }
_cmark++; _cmark++;
return true ; return true ;
} }
@ -173,7 +174,7 @@ int USBD_SendControl(uint8_t flags, const void* d, int len)
while ( len-- ) while ( len-- )
{ {
uint8_t c = *data++ ; uint8_t c = *data++ ;
if ( !SendControl( c ) ) if ( !SendControl( c ) )
{ {
return -1; return -1;
@ -293,7 +294,7 @@ static bool USBD_SendDescriptor(Setup& setup)
{ {
return false ; return false ;
} }
if ( desc_length == 0 ) if ( desc_length == 0 )
{ {
desc_length = *desc_addr; desc_length = *desc_addr;
@ -308,7 +309,7 @@ static bool USBD_SendDescriptor(Setup& setup)
void USB_ISR() void USB_ISR()
{ {
SetEP(0) ; SetEP(0) ;
if ( !ReceivedSetupInt() ) if ( !ReceivedSetupInt() )
{ {
return; return;
@ -367,7 +368,7 @@ void USB_ISR()
{ {
InitEndpoints(); InitEndpoints();
_usbConfiguration = setup.wValueL; _usbConfiguration = setup.wValueL;
} }
else else
{ {
ok = false; ok = false;
@ -458,17 +459,38 @@ USB_ USB;
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 if ( _usbInitialized != 0UL )
UDPHS->UDPHS_CTRL &= ~UDPHS_CTRL_PULLD_DIS; // Enable Pull Down {
USBD_Detach() ;
return true ;
}
else
{
return false ;
}
} }
// Check for interrupts // Check for interrupts

View File

@ -148,8 +148,6 @@ create_output:
# @echo *$(A_SRC) # @echo *$(A_SRC)
# @echo ------------------------- # @echo -------------------------
# -@mkdir $(subst /,$(SEP),$(OUTPUT_BIN)) 1>NUL 2>&1
-mkdir $(subst /,$(SEP),$(OUTPUT_BIN))
-@mkdir $(OUTPUT_PATH) 1>NUL 2>&1 -@mkdir $(OUTPUT_PATH) 1>NUL 2>&1
$(addprefix $(OUTPUT_PATH)/,$(C_OBJ)): $(OUTPUT_PATH)/%.o: %.c $(addprefix $(OUTPUT_PATH)/,$(C_OBJ)): $(OUTPUT_PATH)/%.o: %.c

View File

@ -148,8 +148,6 @@ create_output:
# @echo *$(A_SRC) # @echo *$(A_SRC)
# @echo ------------------------- # @echo -------------------------
# -@mkdir $(subst /,$(SEP),$(OUTPUT_BIN)) 1>NUL 2>&1
-mkdir $(subst /,$(SEP),$(OUTPUT_BIN))
-@mkdir $(OUTPUT_PATH) 1>NUL 2>&1 -@mkdir $(OUTPUT_PATH) 1>NUL 2>&1
$(addprefix $(OUTPUT_PATH)/,$(C_OBJ)): $(OUTPUT_PATH)/%.o: %.c $(addprefix $(OUTPUT_PATH)/,$(C_OBJ)): $(OUTPUT_PATH)/%.o: %.c

View File

@ -8,7 +8,7 @@
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of 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. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public 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 void USBD_InitControl(int end) ;
extern uint32_t USBD_Init(void) ;
extern void USBD_Attach(void) ; extern void USBD_Attach(void) ;
extern void USBD_Detach(void) ; extern void USBD_Detach(void) ;

View File

@ -8,7 +8,7 @@
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of 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. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
@ -19,4 +19,29 @@
#ifndef UOTGHS_H_INCLUDED #ifndef UOTGHS_H_INCLUDED
#define 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 */ #endif /* UOTGHS_H_INCLUDED */

View File

@ -8,7 +8,7 @@
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of 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. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
@ -20,5 +20,157 @@
#if SAM3XA_SERIES #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 */ #endif /* SAM3XA_SERIES */