1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-17 22:23:10 +03:00

[sam] prelimanary work on USB Device stack

This commit is contained in:
Thibaut VIARD
2012-03-29 21:11:05 +02:00
parent 29e2e30514
commit f83cd2f3e7
17 changed files with 401 additions and 427 deletions

View File

@ -230,7 +230,7 @@ int USB_Recv(u8 ep, void* d, int len)
n = len; n = len;
u8* dst = (u8*)d; u8* dst = (u8*)d;
while (n--) while (n--)
*dst++ = Recv8(); *dst++ = USBD_Recv8();
if (len && !FifoByteCount()) // release empty buffer if (len && !FifoByteCount()) // release empty buffer
ReleaseRX(); ReleaseRX();

View File

@ -43,10 +43,10 @@ extern Serial_ Serial;
//================================================================================ //================================================================================
// Mouse // Mouse
#define MOUSE_LEFT 1 #define MOUSE_LEFT (1u)
#define MOUSE_RIGHT 2 #define MOUSE_RIGHT (2u)
#define MOUSE_MIDDLE 4 #define MOUSE_MIDDLE (4u)
#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE) #define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)
class Mouse_ class Mouse_
{ {
@ -67,14 +67,14 @@ extern Mouse_ Mouse;
//================================================================================ //================================================================================
// Keyboard // Keyboard
#define KEY_MODIFIER_LEFT_CTRL 0x01 #define KEY_MODIFIER_LEFT_CTRL (0x01u)
#define KEY_MODIFIER_LEFT_SHIFT 0x02 #define KEY_MODIFIER_LEFT_SHIFT (0x02u)
#define KEY_MODIFIER_LEFT_ALT 0x04 #define KEY_MODIFIER_LEFT_ALT (0x04u)
#define KEY_MODIFIER_LEFT_GUI 0x08 #define KEY_MODIFIER_LEFT_GUI (0x08u)
#define KEY_MODIFIER_RIGHT_CTRL 0x010 #define KEY_MODIFIER_RIGHT_CTRL (0x010u)
#define KEY_MODIFIER_RIGHT_SHIFT 0x020 #define KEY_MODIFIER_RIGHT_SHIFT (0x020u)
#define KEY_MODIFIER_RIGHT_ALT 0x040 #define KEY_MODIFIER_RIGHT_ALT (0x040u)
#define KEY_MODIFIER_RIGHT_GUI 0x080 #define KEY_MODIFIER_RIGHT_GUI (0x080u)
// Low level key report: up to 6 keys and shift, ctrl etc at once // Low level key report: up to 6 keys and shift, ctrl etc at once
typedef struct typedef struct
@ -148,10 +148,6 @@ bool CDC_Setup(Setup& setup);
//================================================================================ //================================================================================
//================================================================================ //================================================================================
#define TRANSFER_PGM 0x80
#define TRANSFER_RELEASE 0x40
#define TRANSFER_ZERO 0x20
int USB_SendControl(uint8_t flags, const void* d, int len); int USB_SendControl(uint8_t flags, const void* d, int len);
int USB_RecvControl(void* d, int len); int USB_RecvControl(void* d, int len);

View File

@ -25,10 +25,8 @@
#if defined(USBCON) #if defined(USBCON)
extern const uint8_t _initEndpoints[] ;
const uint8_t _initEndpoints[] =
extern const u8 _initEndpoints[] ;
const u8 _initEndpoints[] =
{ {
0, 0,
@ -45,37 +43,37 @@ const u8 _initEndpoints[] =
/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */ /** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */
#define TX_RX_LED_PULSE_MS 100 #define TX_RX_LED_PULSE_MS 100
volatile u8 TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */ volatile uint8_t TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */
volatile u8 RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */ volatile uint8_t RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
//================================================================== //==================================================================
//================================================================== //==================================================================
extern const u16 STRING_LANGUAGE[] ; extern const uint16_t STRING_LANGUAGE[] ;
extern const u16 STRING_IPRODUCT[] ; extern const uint16_t STRING_IPRODUCT[] ;
extern const u16 STRING_IMANUFACTURER[] ; extern const uint16_t STRING_IMANUFACTURER[] ;
extern const DeviceDescriptor USB_DeviceDescriptor ; extern const DeviceDescriptor USB_DeviceDescriptor ;
extern const DeviceDescriptor USB_DeviceDescriptorA ; extern const DeviceDescriptor USB_DeviceDescriptorA ;
const u16 STRING_LANGUAGE[2] = { const uint16_t STRING_LANGUAGE[2] = {
(3<<8) | (2+2), (3<<8) | (2+2),
0x0409 // English 0x0409 // English
}; };
const u16 STRING_IPRODUCT[17] = { const uint16_t STRING_IPRODUCT[17] = {
(3<<8) | (2+2*16), (3<<8) | (2+2*16),
#if USB_PID == USB_PID_LEONARDO #if USB_PID == USB_PID_LEONARDO
'A','r','d','u','i','n','o',' ','L','e','o','n','a','r','d','o' 'A','r','d','u','i','n','o',' ','L','e','o','n','a','r','d','o'
#elif USB_PID == USB_PID_MICRO #elif USB_PID == USB_PID_MICRO
'A','r','d','u','i','n','o',' ','M','i','c','r','o',' ',' ',' ' 'A','r','d','u','i','n','o',' ','M','i','c','r','o',' ',' ',' '
#elif USB_PID == ARDUINO_MODEL_USB_PID #elif USB_PID == USB_PID_DUE
'A','r','d','u','i','n','o',' ','D','u','e',' ',' ',' ',' ',' ' 'A','r','d','u','i','n','o',' ','D','u','e',' ',' ',' ',' ',' '
#else #else
#error "Need an USB PID" #error "Need an USB PID"
#endif #endif
}; };
const u16 STRING_IMANUFACTURER[12] = { const uint16_t STRING_IMANUFACTURER[12] = {
(3<<8) | (2+2*11), (3<<8) | (2+2*11),
'A','r','d','u','i','n','o',' ','L','L','C' 'A','r','d','u','i','n','o',' ','L','L','C'
}; };
@ -96,63 +94,140 @@ const DeviceDescriptor USB_DeviceDescriptorA =
//================================================================== //==================================================================
//================================================================== //==================================================================
volatile u8 _usbConfiguration = 0; volatile uint8_t _usbConfiguration = 0;
uint8_t _cdcComposite = 0;
//================================================================== //==================================================================
//================================================================== //==================================================================
static // Recv 1 byte if ready
bool SendControl(u8 d) int USBD_Recv(uint8_t ep)
{ {
if (_cmark < _cend) uint8_t c;
if (USB_Recv(ep,&c,1) != 1)
{
return -1;
}
else
{
return c;
}
}
// Non Blocking receive
// Return number of bytes read
int USBD_Recv(uint8_t ep, void* d, int len)
{
uint8_t n ;
uint8_t* dst ;
if (!_usbConfiguration || len < 0)
{
return -1;
}
n = FifoByteCount(ep);
len = min(n,len);
n = len;
dst = (uint8_t*)d;
while (n--)
{
*dst++ = Recv8(ep);
}
// if (len && !FifoByteCount()) // release empty buffer
// ReleaseRX();
return len;
}
static bool USBD_SendControl(uint8_t d)
{
if ( _cmark < _cend )
{ {
if (!WaitForINOrOUT()) if ( !WaitForINOrOUT() )
{
return false; return false;
Send8(d); }
if (!((_cmark + 1) & 0x3F))
Send8( d ) ;
if ( !((_cmark + 1) & 0x3F) )
{
ClearIN(); // Fifo is full, release this packet ClearIN(); // Fifo is full, release this packet
}
} }
_cmark++; _cmark++;
return true;
}; return true ;
}
// Clipped by _cmark/_cend // Clipped by _cmark/_cend
int USB_SendControl(u8 flags, const void* d, int len) int USBD_SendControl(uint8_t flags, const void* d, int len)
{ {
int sent = len; int sent = len;
const u8* data = (const u8*)d; const uint8_t* data = (const uint8_t*)d ;
bool pgm = flags & TRANSFER_PGM;
while (len--) while ( len-- )
{ {
u8 c = pgm ? *data++ : *data++; uint8_t c = *data++ ;
if (!SendControl(c))
if ( !SendControl( c ) )
{
return -1; return -1;
}
} }
return sent; return sent;
} }
// Does not timeout or cross fifo boundaries // Does not timeout or cross fifo boundaries
// Will only work for transfers <= 64 bytes // Will only work for transfers <= 64 bytes
// TODO // TODO
int USB_RecvControl(void* d, int len) int USBD_RecvControl(void* d, int len)
{ {
WaitOUT(); WaitOUT() ;
Recv((u8*)d,len); Recv( (uint8_t*)d, len ) ;
ClearOUT(); ClearOUT() ;
return len;
return len ;
} }
int SendInterfaces() // Handle CLASS_INTERFACE requests
bool USBD_ClassInterfaceRequest(Setup& setup)
{ {
int total = 0; uint8_t i = setup.wIndex;
u8 interfaces = 0;
#ifdef CDC_ENABLED #ifdef CDC_ENABLED
total = CDC_GetInterface(&interfaces); if ( CDC_ACM_INTERFACE == i )
{
return CDC_Setup(setup);
}
#endif #endif
#ifdef HID_ENABLED #ifdef HID_ENABLED
total += HID_GetInterface(&interfaces); if ( HID_INTERFACE == i )
{
return HID_Setup(setup);
}
#endif
return false ;
}
int USBD_SendInterfaces(void)
{
int total = 0;
uint8_t interfaces = 0;
#ifdef CDC_ENABLED
total = CDC_GetInterface(&interfaces) ;
#endif
#ifdef HID_ENABLED
total += HID_GetInterface(&interfaces) ;
#endif #endif
return interfaces; return interfaces;
@ -161,8 +236,7 @@ int SendInterfaces()
// Construct a dynamic configuration descriptor // Construct a dynamic configuration descriptor
// This really needs dynamic endpoint allocation etc // This really needs dynamic endpoint allocation etc
// TODO // TODO
static static bool USBD_SendConfiguration(int maxlen)
bool SendConfiguration(int maxlen)
{ {
// Count and measure interfaces // Count and measure interfaces
InitControl(0); InitControl(0);
@ -176,73 +250,89 @@ bool SendConfiguration(int maxlen)
return true; return true;
} }
u8 _cdcComposite = 0; static bool USBD_SendDescriptor(Setup& setup)
static
bool SendDescriptor(Setup& setup)
{ {
u8 t = setup.wValueH; uint8_t t = setup.wValueH;
if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t) uint8_t desc_length = 0;
const uint8_t* desc_addr = 0;
if ( USB_CONFIGURATION_DESCRIPTOR_TYPE == t )
{
return SendConfiguration(setup.wLength); return SendConfiguration(setup.wLength);
}
InitControl(setup.wLength); InitControl(setup.wLength);
#ifdef HID_ENABLED #ifdef HID_ENABLED
if (HID_REPORT_DESCRIPTOR_TYPE == t) if ( HID_REPORT_DESCRIPTOR_TYPE == t )
return HID_GetDescriptor(t); {
return HID_GetDescriptor( t ) ;
}
#endif #endif
u8 desc_length = 0;
const u8* desc_addr = 0;
if (USB_DEVICE_DESCRIPTOR_TYPE == t) if (USB_DEVICE_DESCRIPTOR_TYPE == t)
{ {
if (setup.wLength == 8) if ( setup.wLength == 8 )
{
_cdcComposite = 1; _cdcComposite = 1;
desc_addr = _cdcComposite ? (const u8*)&USB_DeviceDescriptorA : (const u8*)&USB_DeviceDescriptor; }
desc_addr = _cdcComposite ? (const uint8_t*)&USB_DeviceDescriptorA : (const uint8_t*)&USB_DeviceDescriptor;
} }
else if (USB_STRING_DESCRIPTOR_TYPE == t) else if (USB_STRING_DESCRIPTOR_TYPE == t)
{ {
if (setup.wValueL == 0) if (setup.wValueL == 0)
desc_addr = (const u8*)&STRING_LANGUAGE; desc_addr = (const uint8_t*)&STRING_LANGUAGE;
else if (setup.wValueL == IPRODUCT) else if (setup.wValueL == IPRODUCT)
desc_addr = (const u8*)&STRING_IPRODUCT; desc_addr = (const uint8_t*)&STRING_IPRODUCT;
else if (setup.wValueL == IMANUFACTURER) else if (setup.wValueL == IMANUFACTURER)
desc_addr = (const u8*)&STRING_IMANUFACTURER; desc_addr = (const uint8_t*)&STRING_IMANUFACTURER;
else else
return false; return false;
} }
if (desc_addr == 0) if ( desc_addr == 0 )
return false; {
if (desc_length == 0) return false ;
}
if ( desc_length == 0 )
{
desc_length = *desc_addr; desc_length = *desc_addr;
}
USB_SendControl(TRANSFER_PGM,desc_addr,desc_length); USB_SendControl(TRANSFER_PGM,desc_addr,desc_length);
return true; return true;
} }
// Endpoint 0 interrupt // Endpoint 0 interrupt
//ISR(USB_COM_vect)
void USB_ISR() void USB_ISR()
{ {
SetEP(0); SetEP(0) ;
if (!ReceivedSetupInt())
if ( !ReceivedSetupInt() )
{
return; return;
}
Setup setup; Setup setup ;
Recv((u8*)&setup,8); Recv((uint8_t*)&setup,8);
ClearSetupInt(); ClearSetupInt();
u8 requestType = setup.bmRequestType; uint8_t requestType = setup.bmRequestType;
if (requestType & REQUEST_DEVICETOHOST) if (requestType & REQUEST_DEVICETOHOST)
{
WaitIN(); WaitIN();
}
else else
{
ClearIN(); ClearIN();
}
bool ok = true; bool ok = true ;
if (REQUEST_STANDARD == (requestType & REQUEST_TYPE)) if (REQUEST_STANDARD == (requestType & REQUEST_TYPE))
{ {
// Standard Requests // Standard Requests
u8 r = setup.bRequest; uint8_t r = setup.bRequest;
if (GET_STATUS == r) if (GET_STATUS == r)
{ {
Send8(0); // TODO Send8(0); // TODO
@ -277,8 +367,11 @@ void USB_ISR()
{ {
InitEndpoints(); InitEndpoints();
_usbConfiguration = setup.wValueL; _usbConfiguration = setup.wValueL;
} else }
else
{
ok = false; ok = false;
}
} }
else if (GET_INTERFACE == r) else if (GET_INTERFACE == r)
{ {
@ -294,14 +387,16 @@ void USB_ISR()
} }
if (ok) if (ok)
{
ClearIN(); ClearIN();
}
else else
{ {
Stall(); Stall();
} }
} }
void USB_Flush(u8 ep) void USBD_Flush(uint8_t ep)
{ {
SetEP(ep); SetEP(ep);
// if (FifoByteCount()) // if (FifoByteCount())
@ -316,7 +411,7 @@ void USB_Flush(u8 ep)
// General interrupt // General interrupt
ISR(USB_GEN_vect) ISR(USB_GEN_vect)
{ {
u8 udint = UDINT; uint8_t udint = UDINT;
UDINT = 0; UDINT = 0;
// End of Reset // End of Reset
@ -348,9 +443,9 @@ ISR(USB_GEN_vect)
// VBUS or counting frames // VBUS or counting frames
// Any frame counting? // Any frame counting?
u8 USBConnected() uint8_t USBD_Connected(void)
{ {
u8 f = UDFNUML; uint8_t f = UDFNUML;
delay(3); delay(3);
return f != UDFNUML; return f != UDFNUML;
} }
@ -365,51 +460,12 @@ USB_::USB_()
{ {
} }
void USB_::attach() void USB_::attach(void)
{/* {
_usbConfiguration = 0; USBD_Attach() ;
}
//UHWCON = 0x01; // power internal reg void USB_::detach(void)
//USBCON = (1<<USBE)|(1<<FRZCLK); // clock frozen, usb enabled
//PLLCSR = 0x12; // Need 16 MHz xtal
//while (!(PLLCSR & (1<<PLOCK))) // wait for lock pll
// ;
PMC->PMC_PCER = (1 << ID_UDPHS);
// Enable 480MHZ
//AT91C_BASE_CKGR->CKGR_UCKR |= (AT91C_CKGR_PLLCOUNT & (3 << 20)) | AT91C_CKGR_UPLLEN;
CKGR->CKGR_UCKR |= ((0xf << 20) & (3 << 20)) | AT91C_CKGR_UPLLEN;
// Wait until UTMI PLL is locked
while ((PMC->PMC_SR & PMC_LOCKU) == 0);
// Reset and enable IP UDPHS
UDPHS->UDPHS_CTRL &= ~UDPHS_CTRL_EN_UDPHS;
UDPHS->UDPHS_CTRL |= UDPHS_CTRL_EN_UDPHS;
//USBCON = ((1<<USBE)|(1<<OTGPADE)); // start USB clock
UDPHS->UDPHS_IEN = 0;
UDPHS->UDPHS_CLRINT = UDPHS_CLRINT_UPSTR_RES
| UDPHS_CLRINT_ENDOFRSM
| UDPHS_CLRINT_WAKE_UP
| UDPHS_CLRINT_ENDRESET
| UDPHS_CLRINT_INT_SOF
| UDPHS_CLRINT_MICRO_SOF
| UDPHS_CLRINT_DET_SUSPD;
// Enable interrupts for EOR (End of Reset), wake up and SOF (start of frame)
//UDIEN = (1<<EORSTE)|(1<<SOFE);
UDPHS->UDPHS_IEN = UDPHS_IEN_ENDOFRSM
| UDPHS_IEN_WAKE_UP
| UDPHS_IEN_DET_SUSPD;
// enable attach resistor
//UDCON = 0;
UDPHS->UDPHS_CTRL &= ~UDPHS_CTRL_DETACH; // Pull Up on DP
UDPHS->UDPHS_CTRL |= UDPHS_CTRL_PULLD_DIS; // Disable Pull Down
TX_RX_LED_INIT;
*/}
void USB_::detach()
{ {
UDPHS->UDPHS_CTRL |= UDPHS_CTRL_DETACH; // detach UDPHS->UDPHS_CTRL |= UDPHS_CTRL_DETACH; // detach
UDPHS->UDPHS_CTRL &= ~UDPHS_CTRL_PULLD_DIS; // Enable Pull Down UDPHS->UDPHS_CTRL &= ~UDPHS_CTRL_PULLD_DIS; // Enable Pull Down

View File

@ -58,11 +58,11 @@
#define HID_TX HID_ENDPOINT_INT #define HID_TX HID_ENDPOINT_INT
#endif #endif
#define IMANUFACTURER 1 #define IMANUFACTURER (1u)
#define IPRODUCT 2 #define IPRODUCT (2u)
#define USB_PID_LEONARDO 0x0034 #define USB_PID_LEONARDO (0x0034u)
#define USB_PID_MICRO 0x0035 #define USB_PID_MICRO (0x0035u)
#define ARDUINO_MODEL_USB_PID 0x0036 #define USB_PID_DUE (0x0036u)
#define USB_VID 0x2341 // arduino LLC vid
#define USB_PID ARDUINO_MODEL_USB_PID
#define USB_VID (0x2341u) // Arduino LLC vendor id
#define USB_PID USB_PID_DUE

View File

@ -1,79 +0,0 @@
/*
Copyright (c) 2011 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
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _USB_DRIVER_
#define _USB_DRIVER_
#include <stdint.h>
extern inline void USBD_WaitIN( void ) ;
extern inline void USBD_ClearIN( void ) ;
extern inline void USBD_WaitOUT( void ) ;
extern inline uint8_t USBD_WaitForINOrOUT( void ) ;
extern inline void USBD_ClearOUT(void) ;
extern void USBD_ClearRxFlag( unsigned char bEndpoint ) ;
extern void USBD_Recv( volatile uint8_t* data, uint8_t count ) ;
extern inline uint8_t USBD_Recv8( void ) ;
extern inline void USBD_Send8( uint8_t d ) ;
extern inline void USBD_SetEP( uint8_t ep ) ;
extern inline u16 USBD_FifoByteCount( void ) ;
extern inline uint8_t USBD_ReceivedSetupInt( void ) ;
extern inline void USBD_ClearSetupInt( void ) ;
extern inline void USBD_Stall( void ) ;
extern inline uint8_t USBD_ReadWriteAllowed( void ) ;
extern inline uint8_t USBD_Stalled( void ) ;
extern uint8_t USBD_FifoFree( void ) ;
extern inline void USBD_ReleaseRX( void ) ;
extern inline void USBD_ReleaseTX( void ) ;
extern inline uint8_t USBD_FrameNumber( void ) ;
extern uint8_t USBD_GetConfiguration( void ) ;
// Number of bytes, assumes a rx endpoint
extern uint8_t USBD_Available( uint8_t ep ) ;
// Non Blocking receive
// Return number of bytes read
extern int USBD_Recv(uint8_t ep, void* d, int len) ;
// Recv 1 byte if ready
extern int USBD_Recv(uint8_t ep) ;
// Space in send EP
extern uint8_t USBD_SendSpace(uint8_t ep) ;
// Blocking Send of data to an endpoint
extern int USBD_Send(uint8_t ep, const void* d, int len) ;
extern void USBD_InitEP(uint8_t index, uint8_t type, uint8_t size) ;
extern void USBD_InitEndpoints() ;
// Handle CLASS_INTERFACE requests
extern bool USBD_ClassInterfaceRequest(Setup& setup) ;
extern void USBD_InitControl(int end) ;
extern void UDPHS_Handler( void ) ;
extern void USBD_Attach( void ) ;
extern void USBD_Detach( void ) ;
#endif /* _USB_DRIVER_*/

View File

@ -30,7 +30,13 @@ GDB = $(CROSS_COMPILE)gdb
SIZE = $(CROSS_COMPILE)size SIZE = $(CROSS_COMPILE)size
NM = $(CROSS_COMPILE)nm NM = $(CROSS_COMPILE)nm
OBJCOPY = $(CROSS_COMPILE)objcopy OBJCOPY = $(CROSS_COMPILE)objcopy
ifeq ($(OS),Windows_NT)
RM=cs-rm -Rf RM=cs-rm -Rf
else
RM=rm -Rf
endif
SEP=\\ SEP=\\
# --------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------
@ -48,7 +54,7 @@ CFLAGS += -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long
CFLAGS += -Wunreachable-code CFLAGS += -Wunreachable-code
CFLAGS += -Wcast-align CFLAGS += -Wcast-align
CFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb -mlong-calls -ffunction-sections -nostdlib 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 += $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D$(VARIANT)
# To reduce application size use only integer printf function. # To reduce application size use only integer printf function.
@ -67,7 +73,7 @@ CPPFLAGS += -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations
CPPFLAGS += -Wpacked -Wredundant-decls -Winline -Wlong-long CPPFLAGS += -Wpacked -Wredundant-decls -Winline -Wlong-long
#-fno-rtti -fno-exceptions #-fno-rtti -fno-exceptions
CPPFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb -mlong-calls -ffunction-sections CPPFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb -mlong-calls -ffunction-sections -std=c++98
CPPFLAGS += $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) CPPFLAGS += $(OPTIMIZATION) $(INCLUDES) -D$(CHIP)
# To reduce application size use only integer printf function. # To reduce application size use only integer printf function.

View File

@ -30,8 +30,12 @@ ifeq ("$(VARIANT)", "sam3s_ek")
CHIP=__SAM3S4C__ CHIP=__SAM3S4C__
else ifeq ("$(VARIANT)", "sam3u_ek") else ifeq ("$(VARIANT)", "sam3u_ek")
CHIP=__SAM3U4E__ CHIP=__SAM3U4E__
else ifeq ("$(VARIANT)", "arduino_due") else ifeq ("$(VARIANT)", "sam3x_ek")
CHIP=__SAM3X8H__
else ifeq ("$(VARIANT)", "arduino_due_u")
CHIP=__SAM3U4E__ CHIP=__SAM3U4E__
else ifeq ("$(VARIANT)", "arduino_due_x")
CHIP=__SAM3X8E__
endif endif
TOOLCHAIN=gcc TOOLCHAIN=gcc

View File

@ -68,13 +68,9 @@ typedef struct {
WoReg UDPHS_EPTRST; /**< \brief (Udphs Offset: 0x1C) UDPHS Endpoints Reset Register */ WoReg UDPHS_EPTRST; /**< \brief (Udphs Offset: 0x1C) UDPHS Endpoints Reset Register */
RoReg Reserved2[48]; RoReg Reserved2[48];
RwReg UDPHS_TST; /**< \brief (Udphs Offset: 0xE0) UDPHS Test Register */ RwReg UDPHS_TST; /**< \brief (Udphs Offset: 0xE0) UDPHS Test Register */
RoReg Reserved3[3]; RoReg Reserved3[7];
RoReg UDPHS_IPNAME1; /**< \brief (Udphs Offset: 0xF0) UDPHS Name1 Register */
RoReg UDPHS_IPNAME2; /**< \brief (Udphs Offset: 0xF4) UDPHS Name2 Register */
RoReg UDPHS_IPFEATURES; /**< \brief (Udphs Offset: 0xF8) UDPHS Features Register */
RoReg Reserved4[1];
UdphsEpt UDPHS_EPT[UDPHSEPT_NUMBER]; /**< \brief (Udphs Offset: 0x100) endpoint = 0 .. 6 */ UdphsEpt UDPHS_EPT[UDPHSEPT_NUMBER]; /**< \brief (Udphs Offset: 0x100) endpoint = 0 .. 6 */
RoReg Reserved5[72]; RoReg Reserved4[72];
UdphsDma UDPHS_DMA[UDPHSDMA_NUMBER]; /**< \brief (Udphs Offset: 0x300) channel = 0 .. 5 */ UdphsDma UDPHS_DMA[UDPHSDMA_NUMBER]; /**< \brief (Udphs Offset: 0x300) channel = 0 .. 5 */
} Udphs; } Udphs;
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ #endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
@ -162,39 +158,6 @@ typedef struct {
#define UDPHS_TST_TST_K (0x1u << 3) /**< \brief (UDPHS_TST) Test K Mode */ #define UDPHS_TST_TST_K (0x1u << 3) /**< \brief (UDPHS_TST) Test K Mode */
#define UDPHS_TST_TST_PKT (0x1u << 4) /**< \brief (UDPHS_TST) Test Packet Mode */ #define UDPHS_TST_TST_PKT (0x1u << 4) /**< \brief (UDPHS_TST) Test Packet Mode */
#define UDPHS_TST_OPMODE2 (0x1u << 5) /**< \brief (UDPHS_TST) OpMode2 */ #define UDPHS_TST_OPMODE2 (0x1u << 5) /**< \brief (UDPHS_TST) OpMode2 */
/* -------- UDPHS_IPNAME1 : (UDPHS Offset: 0xF0) UDPHS Name1 Register -------- */
#define UDPHS_IPNAME1_IP_NAME1_Pos 0
#define UDPHS_IPNAME1_IP_NAME1_Msk (0xffffffffu << UDPHS_IPNAME1_IP_NAME1_Pos) /**< \brief (UDPHS_IPNAME1) */
/* -------- UDPHS_IPNAME2 : (UDPHS Offset: 0xF4) UDPHS Name2 Register -------- */
#define UDPHS_IPNAME2_IP_NAME2_Pos 0
#define UDPHS_IPNAME2_IP_NAME2_Msk (0xffffffffu << UDPHS_IPNAME2_IP_NAME2_Pos) /**< \brief (UDPHS_IPNAME2) */
/* -------- UDPHS_IPFEATURES : (UDPHS Offset: 0xF8) UDPHS Features Register -------- */
#define UDPHS_IPFEATURES_EPT_NBR_MAX_Pos 0
#define UDPHS_IPFEATURES_EPT_NBR_MAX_Msk (0xfu << UDPHS_IPFEATURES_EPT_NBR_MAX_Pos) /**< \brief (UDPHS_IPFEATURES) Max Number of Endpoints */
#define UDPHS_IPFEATURES_DMA_CHANNEL_NBR_Pos 4
#define UDPHS_IPFEATURES_DMA_CHANNEL_NBR_Msk (0x7u << UDPHS_IPFEATURES_DMA_CHANNEL_NBR_Pos) /**< \brief (UDPHS_IPFEATURES) Number of DMA Channels */
#define UDPHS_IPFEATURES_DMA_B_SIZ (0x1u << 7) /**< \brief (UDPHS_IPFEATURES) DMA Buffer Size */
#define UDPHS_IPFEATURES_DMA_FIFO_WORD_DEPTH_Pos 8
#define UDPHS_IPFEATURES_DMA_FIFO_WORD_DEPTH_Msk (0xfu << UDPHS_IPFEATURES_DMA_FIFO_WORD_DEPTH_Pos) /**< \brief (UDPHS_IPFEATURES) DMA FIFO Depth in Words */
#define UDPHS_IPFEATURES_FIFO_MAX_SIZE_Pos 12
#define UDPHS_IPFEATURES_FIFO_MAX_SIZE_Msk (0x7u << UDPHS_IPFEATURES_FIFO_MAX_SIZE_Pos) /**< \brief (UDPHS_IPFEATURES) DPRAM Size */
#define UDPHS_IPFEATURES_BW_DPRAM (0x1u << 15) /**< \brief (UDPHS_IPFEATURES) DPRAM Byte Write Capability */
#define UDPHS_IPFEATURES_DATAB16_8 (0x1u << 16) /**< \brief (UDPHS_IPFEATURES) UTMI DataBus16_8 */
#define UDPHS_IPFEATURES_ISO_EPT_1 (0x1u << 17) /**< \brief (UDPHS_IPFEATURES) Endpointx High Bandwidth Isochronous Capability */
#define UDPHS_IPFEATURES_ISO_EPT_2 (0x1u << 18) /**< \brief (UDPHS_IPFEATURES) Endpointx High Bandwidth Isochronous Capability */
#define UDPHS_IPFEATURES_ISO_EPT_3 (0x1u << 19) /**< \brief (UDPHS_IPFEATURES) Endpointx High Bandwidth Isochronous Capability */
#define UDPHS_IPFEATURES_ISO_EPT_4 (0x1u << 20) /**< \brief (UDPHS_IPFEATURES) Endpointx High Bandwidth Isochronous Capability */
#define UDPHS_IPFEATURES_ISO_EPT_5 (0x1u << 21) /**< \brief (UDPHS_IPFEATURES) Endpointx High Bandwidth Isochronous Capability */
#define UDPHS_IPFEATURES_ISO_EPT_6 (0x1u << 22) /**< \brief (UDPHS_IPFEATURES) Endpointx High Bandwidth Isochronous Capability */
#define UDPHS_IPFEATURES_ISO_EPT_7 (0x1u << 23) /**< \brief (UDPHS_IPFEATURES) Endpointx High Bandwidth Isochronous Capability */
#define UDPHS_IPFEATURES_ISO_EPT_8 (0x1u << 24) /**< \brief (UDPHS_IPFEATURES) Endpointx High Bandwidth Isochronous Capability */
#define UDPHS_IPFEATURES_ISO_EPT_9 (0x1u << 25) /**< \brief (UDPHS_IPFEATURES) Endpointx High Bandwidth Isochronous Capability */
#define UDPHS_IPFEATURES_ISO_EPT_10 (0x1u << 26) /**< \brief (UDPHS_IPFEATURES) Endpointx High Bandwidth Isochronous Capability */
#define UDPHS_IPFEATURES_ISO_EPT_11 (0x1u << 27) /**< \brief (UDPHS_IPFEATURES) Endpointx High Bandwidth Isochronous Capability */
#define UDPHS_IPFEATURES_ISO_EPT_12 (0x1u << 28) /**< \brief (UDPHS_IPFEATURES) Endpointx High Bandwidth Isochronous Capability */
#define UDPHS_IPFEATURES_ISO_EPT_13 (0x1u << 29) /**< \brief (UDPHS_IPFEATURES) Endpointx High Bandwidth Isochronous Capability */
#define UDPHS_IPFEATURES_ISO_EPT_14 (0x1u << 30) /**< \brief (UDPHS_IPFEATURES) Endpointx High Bandwidth Isochronous Capability */
#define UDPHS_IPFEATURES_ISO_EPT_15 (0x1u << 31) /**< \brief (UDPHS_IPFEATURES) Endpointx High Bandwidth Isochronous Capability */
/* -------- UDPHS_EPTCFG : (UDPHS Offset: N/A) UDPHS Endpoint Configuration Register -------- */ /* -------- UDPHS_EPTCFG : (UDPHS Offset: N/A) UDPHS Endpoint Configuration Register -------- */
#define UDPHS_EPTCFG_EPT_SIZE_Pos 0 #define UDPHS_EPTCFG_EPT_SIZE_Pos 0
#define UDPHS_EPTCFG_EPT_SIZE_Msk (0x7u << UDPHS_EPTCFG_EPT_SIZE_Pos) /**< \brief (UDPHS_EPTCFG) Endpoint Size */ #define UDPHS_EPTCFG_EPT_SIZE_Msk (0x7u << UDPHS_EPTCFG_EPT_SIZE_Pos) /**< \brief (UDPHS_EPTCFG) Endpoint Size */

View File

@ -0,0 +1,70 @@
/*
Copyright (c) 2011 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
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _USB_DRIVER_
#define _USB_DRIVER_
#include <stdint.h>
extern void USBD_WaitIN(void) ;
extern void USBD_WaitOUT(void) ;
extern void USBD_ClearIN(void) ;
extern void USBD_ClearOUT(void) ;
extern uint8_t USBD_WaitForINOrOUT(void) ;
extern void USBD_ClearRxFlag( unsigned char bEndpoint ) ;
extern void USBD_Stall(void) ;
extern uint8_t USBD_Stalled(void) ;
extern uint8_t USBD_ReceivedSetupInt(void) ;
extern void USBD_ClearSetupInt(void) ;
extern uint8_t USBD_ReadWriteAllowed(void) ;
extern void USBD_SetEP( uint8_t ep ) ;
extern uint16_t USBD_FifoByteCount(void) ;
extern uint8_t USBD_FifoFree(void) ;
extern void USBD_ReleaseRX(void) ;
extern void USBD_ReleaseTX(void) ;
extern uint8_t USBD_FrameNumber(void) ;
extern uint8_t USBD_GetConfiguration(void) ;
extern void USBD_Recv( volatile uint8_t* data, uint8_t count ) ;
extern uint8_t USBD_Recv8(void) ;
extern void USBD_Send8( uint8_t d ) ;
// Blocking Send of data to an endpoint
extern int USBD_Send(uint8_t ep, const void* d, int len) ;
// Space in send EP
extern uint8_t USBD_SendSpace(uint8_t ep) ;
// Number of bytes, assumes a rx endpoint
extern uint8_t USBD_Available(uint8_t ep) ;
extern void USBD_InitEP(uint8_t index, uint8_t type, uint8_t size) ;
extern void USBD_InitEndpoints(void) ;
extern void USBD_InitControl(int end) ;
extern void USBD_Attach(void) ;
extern void USBD_Detach(void) ;
#endif /* _USB_DRIVER_*/

View File

@ -19,8 +19,6 @@
#ifndef UDPHS_H_INCLUDED #ifndef UDPHS_H_INCLUDED
#define UDPHS_H_INCLUDED #define UDPHS_H_INCLUDED
#include "arduino.h"
#define NUM_IT_MAX 3 #define NUM_IT_MAX 3
#define EP_SINGLE_64 0x32 // EP0 #define EP_SINGLE_64 0x32 // EP0

View File

@ -16,7 +16,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "Arduino.h" #include "chip.h"
#if SAM3S_SERIES || SAM4S_SERIES #if SAM3S_SERIES || SAM4S_SERIES

View File

@ -16,7 +16,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "Arduino.h" #include "chip.h"
#if SAM3U_SERIES #if SAM3U_SERIES
@ -24,8 +24,8 @@
#include "udphs.h" #include "udphs.h"
/// Max size of the FMA FIFO /// Max size of the FMA FIFO
#define EPT_VIRTUAL_SIZE 16384 #define EPT_VIRTUAL_SIZE (16384u)
#define SHIFT_INTERUPT 8 #define SHIFT_INTERUPT (8u)
int _cmark; int _cmark;
int _cend; int _cend;
@ -34,146 +34,109 @@ int _cend;
unsigned int NumEndpoint=0; unsigned int NumEndpoint=0;
inline void USBD_WaitIN( void ) void USBD_WaitIN(void)
{ {
// while (!(UEINTX & (1<<TXINI))); // while (!(UEINTX & (1<<TXINI)));
while (!(UDPHS->UDPHS_EPT[0].UDPHS_EPTSTA & UDPHS_EPTSTA_TX_PK_RDY)); while (!(UDPHS->UDPHS_EPT[0].UDPHS_EPTSTA & UDPHS_EPTSTA_TX_PK_RDY));
} }
inline void USBD_ClearIN( void ) void USBD_WaitOUT(void)
{
// UEINTX = ~(1<<TXINI);
UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTCLRSTA = UDPHS_EPTCLRSTA_TX_COMPLT;
}
inline void USBD_WaitOUT( void )
{ {
// while (!(UEINTX & (1<<RXOUTI))) // while (!(UEINTX & (1<<RXOUTI)))
// ; // ;
// Waiting for Status stage // Waiting for Status stage
while (UDPHS_EPTSTA_RX_BK_RDY != (UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTSTA & UDPHS_EPTSTA_RX_BK_RDY)); while (UDPHS_EPTSTA_RX_BK_RDY != (UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTSTA & UDPHS_EPTSTA_RX_BK_RDY));
} }
inline uint8_t USBD_WaitForINOrOUT( void ) void USBD_ClearIN(void)
{
// UEINTX = ~(1<<TXINI);
UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTCLRSTA = UDPHS_EPTCLRSTA_TX_COMPLT;
}
void USBD_ClearOUT(void)
{
// UEINTX = ~(1<<RXOUTI);
UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTCLRSTA = UDPHS_EPTCLRSTA_RX_BK_RDY;
}
uint8_t USBD_WaitForINOrOUT(void)
{ {
// while (!(UEINTX & ((1<<TXINI)|(1<<RXOUTI)))) // while (!(UEINTX & ((1<<TXINI)|(1<<RXOUTI))))
// ; // ;
// return (UEINTX & (1<<RXOUTI)) == 0; // return (UEINTX & (1<<RXOUTI)) == 0;
while (!(UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTSTA & (UDPHS_EPTSTA_RX_BK_RDY | UDPHS_EPTSTA_TX_PK_RDY))); while (!(UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTSTA & (UDPHS_EPTSTA_RX_BK_RDY | UDPHS_EPTSTA_TX_PK_RDY)));
return (UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTSTA & UDPHS_EPTSTA_RX_BK_RDY) == 0; return (UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTSTA & UDPHS_EPTSTA_RX_BK_RDY) == 0;
} }
inline void USBD_ClearOUT(void) void USBD_ClearRxFlag(unsigned char bEndpoint)
{ {
// UEINTX = ~(1<<RXOUTI); UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTCLRSTA = UDPHS_EPTCLRSTA_RX_BK_RDY;
UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTCLRSTA = UDPHS_EPTCLRSTA_RX_BK_RDY;
} }
/* void USBD_Stall(void)
void USBD_ClearRxFlag( unsigned char bEndpoint )
{ {
UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTCLRSTA = UDPHS_EPTCLRSTA_RX_BK_RDY; // UECONX = (1<<STALLRQ) | (1<<EPEN);
UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTSETSTA = UDPHS_EPTSETSTA_FRCESTALL;
} }
*/
void USBD_Recv(volatile uint8_t* data, uint8_t count) uint8_t USBD_Stalled(void)
{ {
uint8_t *pFifo; // return UEINTX & (1<<STALLEDI);
// Check if the data has been STALLed
pFifo = (uint8_t*)((u32 *)UDPHS_EPTFIFO + (EPT_VIRTUAL_SIZE * NumEndpoint)); return ( UDPHS_EPTSTA_FRCESTALL == (UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTSTA & UDPHS_EPTSTA_FRCESTALL));
while (count--)
*data++ = pFifo[0]; // UEDATX;
RXLED1; // light the RX LED
RxLEDPulse = TX_RX_LED_PULSE_MS;
} }
uint8_t USBD_ReceivedSetupInt(void)
inline uint8_t USBD_Recv8( void )
{ {
uint8_t *pFifo; // return UEINTX & (1<<RXSTPI);
return ( UDPHS_EPTSTA_RX_SETUP == (UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTSTA & UDPHS_EPTSTA_RX_SETUP) );
RXLED1; // light the RX LED
RxLEDPulse = TX_RX_LED_PULSE_MS;
pFifo = (uint8_t*)((u32 *)UDPHS_EPTFIFO + (EPT_VIRTUAL_SIZE * NumEndpoint));
// return UEDATX;
return (pFifo[0]);
} }
inline void USBD_Send8(uint8_t d) void USBD_ClearSetupInt(void)
{ {
uint8_t *pFifo; // UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
pFifo = (uint8_t*)((u32 *)UDPHS_EPTFIFO + (EPT_VIRTUAL_SIZE * NumEndpoint)); UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTCLRSTA = UDPHS_EPTSTA_RX_SETUP | UDPHS_EPTCLRSTA_RX_BK_RDY | UDPHS_EPTCLRSTA_TX_COMPLT;
// UEDATX = d;
pFifo[0] =d;
} }
inline void USBD_SetEP(uint8_t ep) uint8_t USBD_ReadWriteAllowed(void)
{
//return UEINTX & (1<<RWAL);
return 1;
}
void USBD_SetEP(uint8_t ep)
{ {
// UENUM = ep; // UENUM = ep;
NumEndpoint = ep & 7; NumEndpoint = ep & 7;
} }
inline u16 USBD_FifoByteCount() uint16_t USBD_FifoByteCount(void)
{ {
// return UEBCLX; // return UEBCLX;
// SAM3X // SAM3X
//return ((UOTGHS->UOTGHS_DEVEPTISR[ep] & UOTGHS_DEVEPTISR_BYCT_Msk) >> UOTGHS_DEVEPTISR_BYCT_Pos); //return ((UOTGHS->UOTGHS_DEVEPTISR[ep] & UOTGHS_DEVEPTISR_BYCT_Msk) >> UOTGHS_DEVEPTISR_BYCT_Pos);
// SAM3U //AT91C_UDPHS_BYTE_COUNT (0x7FF << 20) // SAM3U //AT91C_UDPHS_BYTE_COUNT (0x7FF << 20)
return ((UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTSTA & (0x7FF << 20)) >> 20); return ((UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTSTA & UDPHS_EPTSTA_BYTE_COUNT_Msk) >> UDPHS_EPTSTA_BYTE_COUNT_Pos);
} }
inline uint8_t USBD_ReceivedSetupInt() uint8_t USBD_FifoFree(void)
{
// return UEINTX & (1<<RXSTPI);
return ( UDPHS_EPTSTA_RX_SETUP == (UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTSTA & UDPHS_EPTSTA_RX_SETUP) );
}
inline void USBD_ClearSetupInt()
{
// UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTCLRSTA = UDPHS_EPTSTA_RX_SETUP | UDPHS_EPTCLRSTA_RX_BK_RDY | UDPHS_EPTCLRSTA_TX_COMPLT;
}
inline void USBD_Stall()
{
// UECONX = (1<<STALLRQ) | (1<<EPEN);
UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTSETSTA = UDPHS_EPTSETSTA_FRCESTALL;
}
inline uint8_t USBD_ReadWriteAllowed()
{
//return UEINTX & (1<<RWAL);
return 1;
}
inline uint8_t USBD_Stalled()
{
// return UEINTX & (1<<STALLEDI);
// Check if the data has been STALLed
return ( UDPHS_EPTSTA_FRCESTALL == (UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTSTA & UDPHS_EPTSTA_FRCESTALL));
}
uint8_t USBD_FifoFree()
{ {
// return UEINTX & (1<<FIFOCON); // return UEINTX & (1<<FIFOCON);
return( 0 != (UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTSTA & UDPHS_EPTSTA_TX_PK_RDY )); return( 0 != (UDPHS->UDPHS_EPT[NumEndpoint].UDPHS_EPTSTA & UDPHS_EPTSTA_TX_PK_RDY ));
} }
//inline void USBD_ReleaseRX() void USBD_ReleaseRX(void)
//{ {
// UEINTX = 0x6B; // FIFOCON=0 NAKINI=1 RWAL=1 NAKOUTI=0 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=1 UEINTX = 0x6B; // FIFOCON=0 NAKINI=1 RWAL=1 NAKOUTI=0 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=1
//} }
//inline void USBD_ReleaseTX() void USBD_ReleaseTX()
//{ {
// UEINTX = 0x3A; // FIFOCON=0 NAKINI=0 RWAL=1 NAKOUTI=1 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=0 UEINTX = 0x3A; // FIFOCON=0 NAKINI=0 RWAL=1 NAKOUTI=1 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=0
//} }
inline uint8_t USBD_FrameNumber() uint8_t USBD_FrameNumber(void)
{ {
return UDFNUML; return UDFNUML;
} }
@ -183,49 +146,42 @@ uint8_t USBD_GetConfiguration(void)
return _usbConfiguration; return _usbConfiguration;
} }
// Number of bytes, assumes a rx endpoint
uint8_t USBD_Available(uint8_t ep)
void USBD_Recv(volatile uint8_t* data, uint8_t count)
{ {
SetEP(ep); uint8_t *pFifo;
return FifoByteCount();
pFifo = (uint8_t*)((uint32_t *)UDPHS_RAM_ADDR + (EPT_VIRTUAL_SIZE * NumEndpoint));
while (count--)
{
*data++ = pFifo[0];
}
// RXLED1; // light the RX LED
// RxLEDPulse = TX_RX_LED_PULSE_MS;
} }
// Non Blocking receive uint8_t USBD_Recv8(void)
// Return number of bytes read
int USBD_Recv(uint8_t ep, void* d, int len)
{ {
if (!_usbConfiguration || len < 0) uint8_t *pFifo;
return -1;
SetEP(ep); // RXLED1; // light the RX LED
uint8_t n = FifoByteCount(); // RxLEDPulse = TX_RX_LED_PULSE_MS;
len = min(n,len);
n = len;
uint8_t* dst = (uint8_t*)d;
while (n--)
*dst++ = Recv8();
// if (len && !FifoByteCount()) // release empty buffer
// ReleaseRX();
return len; pFifo = (uint8_t*)((uint32_t *)UDPHS_RAM_ADDR + (EPT_VIRTUAL_SIZE * NumEndpoint));
// return UEDATX;
return (pFifo[0]);
} }
// Recv 1 byte if ready void USBD_Send8(uint8_t d)
int USBD_Recv(uint8_t ep)
{ {
uint8_t c; uint8_t *pFifo;
if (USB_Recv(ep,&c,1) != 1) pFifo = (uint8_t*)((uint32_t *)UDPHS_RAM_ADDR + (EPT_VIRTUAL_SIZE * NumEndpoint));
return -1; // UEDATX = d;
return c; pFifo[0] =d;
}
// Space in send EP
uint8_t USBD_SendSpace(uint8_t ep)
{
SetEP(ep);
if (!ReadWriteAllowed())
return 0;
return 64 - FifoByteCount();
} }
// Blocking Send of data to an endpoint // Blocking Send of data to an endpoint
@ -279,6 +235,26 @@ int USBD_Send(uint8_t ep, const void* d, int len)
} }
// Space in send EP
uint8_t USBD_SendSpace(uint8_t ep)
{
SetEP(ep);
if (!ReadWriteAllowed())
{
return 0;
}
return 64 - FifoByteCount();
}
// Number of bytes, assumes a rx endpoint
uint8_t USBD_Available(uint8_t ep)
{
SetEP(ep);
return FifoByteCount();
}
void USBD_InitEP(uint8_t index, uint8_t type, uint8_t size) void USBD_InitEP(uint8_t index, uint8_t type, uint8_t size)
{ {
UENUM = index; UENUM = index;
@ -288,7 +264,7 @@ void USBD_InitEP(uint8_t index, uint8_t type, uint8_t size)
} }
void USBD_InitEndpoints() void USBD_InitEndpoints(void)
{ {
for (uint8_t i = 1; i < sizeof(_initEndpoints); i++) for (uint8_t i = 1; i < sizeof(_initEndpoints); i++)
{ {
@ -310,33 +286,17 @@ void USBD_InitEndpoints()
///\// UERST = 0; ///\// UERST = 0;
} }
// Handle CLASS_INTERFACE requests
bool USBD_ClassInterfaceRequest(Setup& setup)
{
uint8_t i = setup.wIndex;
#ifdef CDC_ENABLED
if (CDC_ACM_INTERFACE == i)
return CDC_Setup(setup);
#endif
#ifdef HID_ENABLED
if (HID_INTERFACE == i)
return HID_Setup(setup);
#endif
return false;
}
void USBD_InitControl(int end) void USBD_InitControl(int end)
{ {
SetEP(0); SetEP(0);
UDPHS->UDPHS_EPT[0].UDPHS_EPTCFG = _initEndpoints[0]; UDPHS->UDPHS_EPT[0].UDPHS_EPTCFG = _initEndpoints[0];
while( (signed int)UDPHS_EPTCFG_EPT_MAPD != (signed int)((UDPHS->UDPHS_EPT[0].UDPHS_EPTCFG) & (unsigned int)UDPHS_EPTCFG_EPT_MAPD) )
; while( (signed int)UDPHS_EPTCFG_EPT_MAPD != (signed int)((UDPHS->UDPHS_EPT[0].UDPHS_EPTCFG) & (unsigned int)UDPHS_EPTCFG_EPT_MAPD) )
UDPHS->UDPHS_EPT[0].UDPHS_EPTCTLENB = UDPHS_EPTCTLENB_RX_BK_RDY ;
| UDPHS_EPTCTLENB_RX_SETUP
| UDPHS_EPTCTLENB_EPT_ENABL; UDPHS->UDPHS_EPT[0].UDPHS_EPTCTLENB = UDPHS_EPTCTLENB_RX_BK_RDY
| UDPHS_EPTCTLENB_RX_SETUP
| UDPHS_EPTCTLENB_EPT_ENABL;
_cmark = 0; _cmark = 0;
_cend = end; _cend = end;

View File

@ -16,7 +16,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "Arduino.h" #include "chip.h"
#if SAM3XA_SERIES #if SAM3XA_SERIES

View File

@ -266,12 +266,12 @@ extern const PinDescription g_APinDescription[]=
*/ */
RingBuffer rx_buffer1 ; RingBuffer rx_buffer1 ;
UARTClass Serial( UART, UART_IRQn, ID_UART, &rx_buffer1 ) ; UARTClass Serial1( UART, UART_IRQn, ID_UART, &rx_buffer1 ) ;
// IT handlers // IT handlers
void UART_Handler(void) void UART_Handler(void)
{ {
Serial.IrqHandler() ; Serial1.IrqHandler() ;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -162,7 +162,7 @@ static const uint8_t A13 = 67;
#ifdef __cplusplus #ifdef __cplusplus
extern UARTClass Serial ; extern UARTClass Serial1 ;
extern USARTClass Serial2 ; extern USARTClass Serial2 ;
extern USARTClass Serial3 ; extern USARTClass Serial3 ;

View File

@ -272,12 +272,12 @@ extern const PinDescription g_APinDescription[]=
*/ */
RingBuffer rx_buffer1 ; RingBuffer rx_buffer1 ;
UARTClass Serial( UART, UART_IRQn, ID_UART, &rx_buffer1 ) ; UARTClass Serial1( UART, UART_IRQn, ID_UART, &rx_buffer1 ) ;
// IT handlers // IT handlers
void UART_Handler(void) void UART_Handler(void)
{ {
Serial.IrqHandler() ; Serial1.IrqHandler() ;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -162,7 +162,7 @@ static const uint8_t A15 = 69;
#ifdef __cplusplus #ifdef __cplusplus
extern UARTClass Serial ; extern UARTClass Serial1 ;
extern USARTClass Serial2 ; extern USARTClass Serial2 ;
extern USARTClass Serial3 ; extern USARTClass Serial3 ;