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:
parent
08b614048d
commit
86533a5e8f
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) ;
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user