1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-03-15 12:29:26 +01:00

[SAM] uotghs first implementation, compilation is okay. Code untested.

This commit is contained in:
Thibault RICHARD 2012-04-30 13:42:04 +02:00
parent 41ef57b963
commit 8c1f9af9f5
11 changed files with 1565 additions and 302 deletions

View File

@ -15,6 +15,7 @@
*/ */
#include "Arduino.h" #include "Arduino.h"
#include "USBAPI.h"
#if defined(USBCON) #if defined(USBCON)
@ -63,7 +64,7 @@ static const CDCDescriptor _cdcInterface =
int WEAK CDC_GetInterface(uint8_t* interfaceNum) int WEAK CDC_GetInterface(uint8_t* interfaceNum)
{ {
interfaceNum[0] += 2; // uses 2 interfaceNum[0] += 2; // uses 2
return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface)); return USBD_SendControl(0,&_cdcInterface,sizeof(_cdcInterface));
} }
bool WEAK CDC_Setup(Setup& setup) bool WEAK CDC_Setup(Setup& setup)
@ -75,7 +76,7 @@ bool WEAK CDC_Setup(Setup& setup)
{ {
if (CDC_GET_LINE_CODING == r) if (CDC_GET_LINE_CODING == r)
{ {
USB_SendControl(0,(void*)&_usbLineInfo,7); USBD_SendControl(0,(void*)&_usbLineInfo,7);
return true; return true;
} }
} }
@ -84,7 +85,7 @@ bool WEAK CDC_Setup(Setup& setup)
{ {
if (CDC_SET_LINE_CODING == r) if (CDC_SET_LINE_CODING == r)
{ {
USB_RecvControl((void*)&_usbLineInfo,7); USBD_RecvControl((void*)&_usbLineInfo,7);
return true; return true;
} }
@ -137,7 +138,7 @@ void Serial_::end(void)
void Serial_::accept(void) void Serial_::accept(void)
{ {
ring_buffer *buffer = &cdc_rx_buffer; ring_buffer *buffer = &cdc_rx_buffer;
int c = USB_Recv(CDC_RX); int c = USBD_Recv(CDC_RX);
int i = (unsigned int)(buffer->head+1) % SERIAL_BUFFER_SIZE; int i = (unsigned int)(buffer->head+1) % SERIAL_BUFFER_SIZE;
// if we should be storing the received character into the location // if we should be storing the received character into the location
@ -181,7 +182,7 @@ int Serial_::read(void)
void Serial_::flush(void) void Serial_::flush(void)
{ {
USB_Flush(CDC_TX); USBD_Flush(CDC_TX);
} }
size_t Serial_::write(uint8_t c) size_t Serial_::write(uint8_t c)
@ -196,7 +197,7 @@ size_t Serial_::write(uint8_t c)
// open connection isn't broken cleanly (cable is yanked out, host dies // open connection isn't broken cleanly (cable is yanked out, host dies
// or locks up, or host virtual serial port hangs) // or locks up, or host virtual serial port hangs)
if (_usbLineInfo.lineState > 0) { if (_usbLineInfo.lineState > 0) {
int r = USB_Send(CDC_TX,&c,1); int r = USBD_Send(CDC_TX,&c,1);
if (r > 0) { if (r > 0) {
return r; return r;
} else { } else {

View File

@ -141,18 +141,18 @@ uint8_t _hid_idle = 1;
int WEAK HID_GetInterface(uint8_t* interfaceNum) int WEAK HID_GetInterface(uint8_t* interfaceNum)
{ {
interfaceNum[0] += 1; // uses 1 interfaceNum[0] += 1; // uses 1
return USB_SendControl(TRANSFER_PGM,&_hidInterface,sizeof(_hidInterface)); return USBD_SendControl(0,&_hidInterface,sizeof(_hidInterface));
} }
int WEAK HID_GetDescriptor(int i) int WEAK HID_GetDescriptor(int i)
{ {
return USB_SendControl(TRANSFER_PGM,_hidReportDescriptor,sizeof(_hidReportDescriptor)); return USBD_SendControl(0,_hidReportDescriptor,sizeof(_hidReportDescriptor));
} }
void WEAK HID_SendReport(uint8_t id, const void* data, int len) void WEAK HID_SendReport(uint8_t id, const void* data, uint32_t len)
{ {
USB_Send(HID_TX, &id, 1); USBD_Send(HID_TX, &id, 1);
USB_Send(HID_TX | TRANSFER_RELEASE,data,len); USBD_Send(HID_TX | TRANSFER_RELEASE,data,len);
} }
bool WEAK HID_Setup(Setup& setup) bool WEAK HID_Setup(Setup& setup)

View File

@ -21,6 +21,8 @@
#if defined __cplusplus && defined USBCON #if defined __cplusplus && defined USBCON
#include "RingBuffer.h"
//================================================================================ //================================================================================
//================================================================================ //================================================================================
// USB // USB
@ -171,7 +173,7 @@ typedef struct
int HID_GetInterface(uint8_t* interfaceNum); int HID_GetInterface(uint8_t* interfaceNum);
int HID_GetDescriptor(int i); int HID_GetDescriptor(int i);
bool HID_Setup(Setup& setup); bool HID_Setup(Setup& setup);
void HID_SendReport(uint8_t id, const void* data, int len); void HID_SendReport(uint8_t id, const void* data, uint32_t len);
//================================================================================ //================================================================================
//================================================================================ //================================================================================
@ -193,18 +195,24 @@ bool CDC_Setup(Setup& setup);
//================================================================================ //================================================================================
//================================================================================ //================================================================================
#define TRANSFER_PGM 0x80
#define TRANSFER_RELEASE 0x40 #define TRANSFER_RELEASE 0x40
#define TRANSFER_ZERO 0x20 #define TRANSFER_ZERO 0x20
int USB_SendControl(uint8_t flags, const void* d, int len); void USBD_InitControl(int end);
int USB_RecvControl(void* d, int len); int USBD_SendControl(uint8_t flags, const void* d, uint32_t len);
int USBD_RecvControl(void* d, uint32_t len);
int USBD_SendInterfaces(void);
bool USBD_ClassInterfaceRequest(Setup& setup);
uint8_t USB_Available(uint8_t ep); uint32_t USBD_Recv(uint32_t ep, void* d, uint32_t len);
int USB_Send(uint8_t ep, const void* data, int len); // blocking uint8_t USBD_Recv8(uint32_t ep);
int USB_Recv(uint8_t ep, void* data, int len); // non-blocking uint32_t USBD_Available(uint32_t ep);
int USB_Recv(uint8_t ep); // non-blocking uint32_t USBD_SendSpace(uint32_t ep);
void USB_Flush(uint8_t ep); uint32_t USBD_Send(uint32_t ep, const void* d, uint32_t len);
int USBD_Recv(uint8_t ep, void* data, uint32_t len); // non-blocking
int USBD_Recv(uint8_t ep); // non-blocking
void USBD_Flush(uint32_t ep);
uint32_t USBD_Connected(void);
#endif #endif

View File

@ -15,6 +15,7 @@
*/ */
#include "Arduino.h" #include "Arduino.h"
#include "USBAPI.h"
const uint32_t _initEndpoints[] = const uint32_t _initEndpoints[] =
{ {
@ -92,96 +93,165 @@ uint32_t _cdcComposite = 0;
//================================================================== //==================================================================
//================================================================== //==================================================================
#define USB_RECV_TIMEOUT
class LockEP
{
irqflags_t flags;
public:
LockEP(uint32_t ep) : flags(cpu_irq_save())
{
UDD_SetEP(ep & 7);
}
~LockEP()
{
cpu_irq_restore(flags);
}
};
// Number of bytes, assumes a rx endpoint
uint32_t USBD_Available(uint32_t ep)
{
LockEP lock(ep);
return UDD_FifoByteCount();
}
// Recv 1 byte if ready // Recv 1 byte if ready
int USBD_Recv(uint8_t ep) /*uint8_t USBD_Recv8(uint32_t ep)
{ {
uint8_t c; uint8_t c;
if (USB_Recv(ep,&c,1) != 1) if (USBD_Recv(ep, &c, 1) != 1)
{ {
return -1; return -1;
} }
else else
{ {
return c; return c;
} }
} }*/
// Non Blocking receive // Non Blocking receive
// Return number of bytes read // Return number of bytes read
int USBD_Recv(uint8_t ep, void* d, int len) uint32_t USBD_Recv(uint32_t ep, void* d, uint32_t len)
{ {
uint8_t n ;
uint8_t* dst ;
if (!_usbConfiguration || len < 0) if (!_usbConfiguration || len < 0)
{
return -1; return -1;
}
n = FifoByteCount(ep);
LockEP lock(ep);
uint32_t n = UDD_FifoByteCount();
len = min(n,len); len = min(n,len);
n = len; n = len;
dst = (uint8_t*)d; uint8_t* dst = (uint8_t*)d;
while (n--) while (n--)
{ *dst++ = UDD_Recv8();
*dst++ = Recv8(ep); if (len && !UDD_FifoByteCount()) // release empty buffer
} UDD_ReleaseRX();
// if (len && !FifoByteCount()) // release empty buffer
// ReleaseRX();
return len; return len;
} }
static bool USBD_SendControl(uint8_t d) // Space in send EP
uint32_t USBD_SendSpace(uint32_t ep)
{ {
if ( _cmark < _cend ) LockEP lock(ep);
{ if (!UDD_ReadWriteAllowed())
if ( !WaitForINOrOUT() ) return 0;
{ return 64 - UDD_FifoByteCount();
return false;
}
Send8( d ) ;
if ( !((_cmark + 1) & 0x3F) )
{
ClearIN(); // Fifo is full, release this packet
}
}
_cmark++;
return true ;
} }
// Blocking Send of data to an endpoint
uint32_t USBD_Send(uint32_t ep, const void* d, uint32_t len)
{
if (!_usbConfiguration)
return -1;
int r = len;
const uint8_t* data = (const uint8_t*)d;
uint8_t timeout = 250; // 250ms timeout on send? TODO
while (len)
{
uint8_t n = USBD_SendSpace(ep);
if (n == 0)
{
if (!(--timeout))
return -1;
delay(1);
continue;
}
if (n > len)
n = len;
len -= n;
{
LockEP lock(ep);
if (ep & TRANSFER_ZERO)
{
while (n--)
UDD_Send8(0);
}
else
{
while (n--)
UDD_Send8(*data++);
}
if (!UDD_ReadWriteAllowed() || ((len == 0) && (ep & TRANSFER_RELEASE))) // Release full buffer
UDD_ReleaseTX();
}
}
//TXLED1; // light the TX LED
//TxLEDPulse = TX_RX_LED_PULSE_MS;
return r;
}
int _cmark;
int _cend;
void USBD_InitControl(int end)
{
UDD_SetEP(0);
_cmark = 0;
_cend = end;
}
static bool USBD_SendControl(uint8_t d)
{
if (_cmark < _cend)
{
if (!UDD_WaitForINOrOUT())
return false;
UDD_Send8(d);
if (!((_cmark + 1) & 0x3F))
UDD_ClearIN(); // Fifo is full, release this packet
}
_cmark++;
return true;
};
// Clipped by _cmark/_cend // Clipped by _cmark/_cend
int USBD_SendControl(uint8_t flags, const void* d, int len) int USBD_SendControl(uint8_t flags, const void* d, uint32_t len)
{ {
int sent = len; int sent = len;
const uint8_t* data = (const uint8_t*)d ; const uint8_t* data = (const uint8_t*)d;
while ( len-- ) while (len--)
{ {
uint8_t c = *data++ ; uint8_t c = *data++;
if (!USBD_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 USBD_RecvControl(void* d, int len) int USBD_RecvControl(void* d, uint32_t len)
{ {
WaitOUT() ; UDD_WaitOUT() ;
Recv( (uint8_t*)d, len ) ; UDD_Recv( (uint8_t*)d, len ) ;
ClearOUT() ; UDD_ClearOUT() ;
return len ; return len ;
} }
@ -230,14 +300,14 @@ int USBD_SendInterfaces(void)
static bool USBD_SendConfiguration(int maxlen) static bool USBD_SendConfiguration(int maxlen)
{ {
// Count and measure interfaces // Count and measure interfaces
InitControl(0); USBD_InitControl(0);
int interfaces = SendInterfaces(); int interfaces = USBD_SendInterfaces();
ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces); ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces);
// Now send them // Now send them
InitControl(maxlen); USBD_InitControl(maxlen);
USB_SendControl(0,&config,sizeof(ConfigDescriptor)); USBD_SendControl(0,&config,sizeof(ConfigDescriptor));
SendInterfaces(); USBD_SendInterfaces();
return true; return true;
} }
@ -249,10 +319,10 @@ static bool USBD_SendDescriptor(Setup& setup)
if ( USB_CONFIGURATION_DESCRIPTOR_TYPE == t ) if ( USB_CONFIGURATION_DESCRIPTOR_TYPE == t )
{ {
return SendConfiguration(setup.wLength); return USBD_SendConfiguration(setup.wLength);
} }
InitControl(setup.wLength); USBD_InitControl(setup.wLength);
#ifdef HID_ENABLED #ifdef HID_ENABLED
if ( HID_REPORT_DESCRIPTOR_TYPE == t ) if ( HID_REPORT_DESCRIPTOR_TYPE == t )
{ {
@ -290,108 +360,143 @@ static bool USBD_SendDescriptor(Setup& setup)
desc_length = *desc_addr; desc_length = *desc_addr;
} }
USB_SendControl(TRANSFER_PGM,desc_addr,desc_length); USBD_SendControl(0, desc_addr, desc_length);
return true; return true;
} }
// Endpoint 0 interrupt // Endpoint 0 interrupt
void USB_ISR() static void USB_ISR(void)
{ {
SetEP(0) ; // End of Reset
if (Is_udd_reset())
{
// Reset USB address to 0
udd_configure_address(0);
udd_enable_address();
if ( !ReceivedSetupInt() ) // Configure EP 0
{ UDD_InitEP(0, EP_TYPE_CONTROL);
return; udd_allocate_memory(0);
} udd_enable_setup_received_interrupt(0);
udd_enable_endpoint_interrupt(0);
Setup setup ; _usbConfiguration = 0;
Recv((uint8_t*)&setup,8); _cmark = 0;
ClearSetupInt(); _cend = 0;
}
uint8_t requestType = setup.bmRequestType; // Start of Frame - happens every millisecond so we use it for TX and RX LED one-shot timing, too
if (requestType & REQUEST_DEVICETOHOST) if (Is_udd_sof())
{ {
WaitIN(); #ifdef CDC_ENABLED
} USBD_Flush(CDC_TX); // Send a tx frame if found
else #endif
{
ClearIN();
}
bool ok = true ; // check whether the one-shot period has elapsed. if so, turn off the LED
if (REQUEST_STANDARD == (requestType & REQUEST_TYPE)) /*if (TxLEDPulse && !(--TxLEDPulse))
TXLED0;
if (RxLEDPulse && !(--RxLEDPulse))
RXLED0;*/
}
// EP 0 Interrupt
if (Is_udd_endpoint_interrupt(0))
{ {
// Standard Requests
uint8_t r = setup.bRequest; if ( !UDD_ReceivedSetupInt() )
if (GET_STATUS == r)
{ {
Send8(0); // TODO return;
Send8(0);
} }
else if (CLEAR_FEATURE == r)
Setup setup ;
UDD_Recv((uint8_t*)&setup,8);
UDD_ClearSetupInt();
uint8_t requestType = setup.bmRequestType;
if (requestType & REQUEST_DEVICETOHOST)
{ {
UDD_WaitIN();
} }
else if (SET_FEATURE == r) else
{ {
UDD_ClearIN();
} }
else if (SET_ADDRESS == r)
bool ok = true ;
if (REQUEST_STANDARD == (requestType & REQUEST_TYPE))
{ {
WaitIN(); // Standard Requests
UDPHS->UDPHS_CTRL |= UDPHS_CTRL_DEV_ADDR(setup.wValueL) | UDPHS_CTRL_FADDR_EN; uint8_t r = setup.bRequest;
} if (GET_STATUS == r)
else if (GET_DESCRIPTOR == r)
{
ok = SendDescriptor(setup);
}
else if (SET_DESCRIPTOR == r)
{
ok = false;
}
else if (GET_CONFIGURATION == r)
{
Send8(1);
}
else if (SET_CONFIGURATION == r)
{
if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT))
{ {
InitEndpoints(_initEndpoints, sizeof(_initEndpoints)/sizeof(_initEndpoints[0])); UDD_Send8(0); // TODO
_usbConfiguration = setup.wValueL; UDD_Send8(0);
} }
else else if (CLEAR_FEATURE == r)
{ {
}
else if (SET_FEATURE == r)
{
}
else if (SET_ADDRESS == r)
{
UDD_WaitIN();
UDD_SetAddress(setup.wValueL);
}
else if (GET_DESCRIPTOR == r)
{
ok = USBD_SendDescriptor(setup);
}
else if (SET_DESCRIPTOR == r)
{
ok = false; ok = false;
} }
else if (GET_CONFIGURATION == r)
{
UDD_Send8(1);
}
else if (SET_CONFIGURATION == r)
{
if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT))
{
UDD_InitEndpoints(_initEndpoints);
_usbConfiguration = setup.wValueL;
}
else
{
ok = false;
}
}
else if (GET_INTERFACE == r)
{
}
else if (SET_INTERFACE == r)
{
}
} }
else if (GET_INTERFACE == r) else
{ {
USBD_InitControl(setup.wLength); // Max length of transfer
ok = USBD_ClassInterfaceRequest(setup);
} }
else if (SET_INTERFACE == r)
{
}
}
else
{
InitControl(setup.wLength); // Max length of transfer
ok = ClassInterfaceRequest(setup);
}
if (ok) if (ok)
{ {
ClearIN(); UDD_ClearIN();
} }
else else
{ {
Stall(); UDD_Stall();
}
} }
} }
void USBD_Flush(uint8_t ep) void USBD_Flush(uint32_t ep)
{ {
SetEP(ep); UDD_SetEP(ep);
// if (FifoByteCount()) if (UDD_FifoByteCount())
// ReleaseTX(); UDD_ReleaseTX();
} }
// General interrupt // General interrupt
@ -427,20 +532,17 @@ ISR(USB_GEN_vect)
RXLED0; RXLED0;
} }
} }
*/ */
// VBUS or counting frames // VBUS or counting frames
// Any frame counting? // Any frame counting?
uint8_t USBD_Connected(void) uint32_t USBD_Connected(void)
{ {
uint8_t f = UDFNUML; uint8_t f = UDD_GetFrameNumber();
delay(3); delay(3);
return f != UDFNUML; return f != UDD_GetFrameNumber();
} }
@ -451,7 +553,9 @@ USB_ USB;
USB_::USB_() USB_::USB_()
{ {
if ( USBD_Init() == 0UL ) UDD_SetStack(&USB_ISR);
if ( UDD_Init() == 0UL )
{ {
_usbInitialized=1UL ; _usbInitialized=1UL ;
} }
@ -461,7 +565,7 @@ bool USB_::attach(void)
{ {
if ( _usbInitialized != 0UL ) if ( _usbInitialized != 0UL )
{ {
USBD_Attach() ; UDD_Attach() ;
return true ; return true ;
} }
@ -475,7 +579,7 @@ bool USB_::detach(void)
{ {
if ( _usbInitialized != 0UL ) if ( _usbInitialized != 0UL )
{ {
USBD_Detach() ; UDD_Detach() ;
return true ; return true ;
} }

View File

@ -42,6 +42,7 @@
* Peripherals * Peripherals
*/ */
#include "include/adc.h" #include "include/adc.h"
#include "include/interrupt_sam_nvic.h"
#include "include/pio.h" #include "include/pio.h"
#include "include/pmc.h" #include "include/pmc.h"
#include "include/pwmc.h" #include "include/pwmc.h"

View File

@ -21,52 +21,384 @@
#include <stdint.h> #include <stdint.h>
extern void USBD_WaitIN(void) ; extern void UDD_WaitIN(void) ;
extern void USBD_WaitOUT(void) ; extern void UDD_WaitOUT(void) ;
extern void USBD_ClearIN(void) ; extern void UDD_ClearIN(void) ;
extern void USBD_ClearOUT(void) ; extern void UDD_ClearOUT(void) ;
extern uint8_t USBD_WaitForINOrOUT(void) ; extern uint32_t UDD_WaitForINOrOUT(void) ;
extern void USBD_ClearRxFlag( unsigned char bEndpoint ) ; extern void UDD_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 uint32_t UDD_ReceivedSetupInt(void);
extern void USBD_InitEndpoints(void) ; extern void UDD_ClearSetupInt(void);
extern void USBD_InitControl(int end) ; extern uint32_t UDD_ReadWriteAllowed(void) ;
extern uint32_t USBD_Init(void) ; extern void UDD_SetEP( uint32_t ep ) ;
extern uint32_t UDD_FifoByteCount(void) ;
extern uint8_t UDD_FifoFree(void) ;
extern void USBD_Attach(void) ; extern void UDD_ReleaseRX(void) ;
extern void USBD_Detach(void) ; extern void UDD_ReleaseTX(void) ;
extern uint8_t UDD_FrameNumber(void) ;
extern uint8_t UDD_GetConfiguration(void) ;
extern void UDD_Send8( uint8_t d ) ;
extern uint8_t UDD_Recv8(void);
extern void UDD_Recv(volatile uint8_t* data, uint32_t count);
extern void UDD_InitEndpoints(const uint32_t* eps);
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(void);
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)
//! @}
#endif /* _USB_DRIVER_*/ #endif /* _USB_DRIVER_*/

View File

@ -43,4 +43,657 @@
#define EP_TYPE_ISOCHRONOUS_IN (UOTGHS_DEVEPTCFG_EPSIZE_1024_BYTE | UOTGHS_DEVEPTCFG_EPDIR_IN | UOTGHS_DEVEPTCFG_EPTYPE_ISO | UOTGHS_DEVEPTCFG_EPBK_3_BANK | UOTGHS_DEVEPTCFG_NBTRANS_3_TRANS) #define EP_TYPE_ISOCHRONOUS_IN (UOTGHS_DEVEPTCFG_EPSIZE_1024_BYTE | UOTGHS_DEVEPTCFG_EPDIR_IN | UOTGHS_DEVEPTCFG_EPTYPE_ISO | UOTGHS_DEVEPTCFG_EPBK_3_BANK | UOTGHS_DEVEPTCFG_NBTRANS_3_TRANS)
#define EP_TYPE_ISOCHRONOUS_OUT (UOTGHS_DEVEPTCFG_EPSIZE_1024_BYTE | UOTGHS_DEVEPTCFG_EPTYPE_ISO | UOTGHS_DEVEPTCFG_EPBK_3_BANK | UOTGHS_DEVEPTCFG_NBTRANS_3_TRANS) #define EP_TYPE_ISOCHRONOUS_OUT (UOTGHS_DEVEPTCFG_EPSIZE_1024_BYTE | UOTGHS_DEVEPTCFG_EPTYPE_ISO | UOTGHS_DEVEPTCFG_EPBK_3_BANK | UOTGHS_DEVEPTCFG_NBTRANS_3_TRANS)
//! \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() (9)
#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 : (( ep <= 2) ? 3 : 2))
//! Get maximal size of endpoint (3X, 1024/64)
#define udd_get_endpoint_size_max(ep) (((ep) == 0) ? 64 : 1024)
//! Get DMA support of endpoints
#define Is_udd_endpoint_dma_supported(ep) ((((ep) >= 1) && ((ep) <= 6)) ? true : false)
//! Get High Band Width support of endpoints
#define Is_udd_endpoint_high_bw_supported(ep) (((ep) >= 2) ? true : false)
//! @}
//! @name UOTGHS Device speeds management
//! @{
//! Enable/disable device low-speed mode
#define udd_low_speed_enable() (Set_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_LS))
#define udd_low_speed_disable() (Clr_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_LS))
//! Test if device low-speed mode is forced
#define Is_udd_low_speed_enable() (Tst_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_LS))
//! Enable high speed mode
#define udd_high_speed_enable() (Wr_bitfield(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_SPDCONF_Msk, 0))
//! Disable high speed mode
#define udd_high_speed_disable() (Wr_bitfield(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_SPDCONF_Msk, 3))
//! Test if controller is in full speed mode
#define Is_udd_full_speed_mode() (Rd_bitfield(UOTGHS->UOTGHS_SR, UOTGHS_SR_SPEED_Msk) == UOTGHS_SR_SPEED_FULL_SPEED)
//! @}
//! @name UOTGHS Device HS test mode management
//! @{
#ifdef UOTGHS_DEVCTRL_SPDCONF_HIGH_SPEED
//! Enable high speed test mode
# define udd_enable_hs_test_mode() (Wr_bitfield(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_SPDCONF_Msk, 2))
# define udd_enable_hs_test_mode_j() (Set_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_TSTJ))
# define udd_enable_hs_test_mode_k() (Set_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_TSTK))
# define udd_enable_hs_test_mode_packet() (Set_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_TSTPCKT))
#endif
//! @}
//! @name UOTGHS Device vbus management
//! @{
#define udd_enable_vbus_interrupt() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE))
#define udd_disable_vbus_interrupt() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE))
#define Is_udd_vbus_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE))
#define Is_udd_vbus_high() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_VBUS))
#define Is_udd_vbus_low() (!Is_udd_vbus_high())
#define udd_ack_vbus_transition() (UOTGHS->UOTGHS_SCR = UOTGHS_SCR_VBUSTIC)
#define udd_raise_vbus_transition() (UOTGHS->UOTGHS_SFR = UOTGHS_SFR_VBUSTIS)
#define Is_udd_vbus_transition() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_VBUSTI))
//! @}
//! @name UOTGHS device attach control
//! These macros manage the UOTGHS Device attach.
//! @{
//! Detaches from USB bus
#define udd_detach_device() (Set_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_DETACH))
//! Attaches to USB bus
#define udd_attach_device() (Clr_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_DETACH))
//! Test if the device is detached
#define Is_udd_detached() (Tst_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_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() (Set_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_RMWKUP))
#define Is_udd_pending_remote_wake_up() (Tst_bits(UOTGHS->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() (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_UPRSMES)
#define udd_disable_remote_wake_up_interrupt() (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_UPRSMEC)
#define Is_udd_remote_wake_up_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_UPRSME))
#define udd_ack_remote_wake_up_start() (UOTGHS->UOTGHS_DEVICR = UOTGHS_DEVICR_UPRSMC)
#define udd_raise_remote_wake_up_start() (UOTGHS->UOTGHS_DEVIFR = UOTGHS_DEVIFR_UPRSMS)
#define Is_udd_remote_wake_up_start() (Tst_bits(UOTGHS->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() (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_EORSMES)
#define udd_disable_resume_interrupt() (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_EORSMEC)
#define Is_udd_resume_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_EORSME))
#define udd_ack_resume() (UOTGHS->UOTGHS_DEVICR = UOTGHS_DEVICR_EORSMC)
#define udd_raise_resume() (UOTGHS->UOTGHS_DEVIFR = UOTGHS_DEVIFR_EORSMS)
#define Is_udd_resume() (Tst_bits(UOTGHS->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() (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_WAKEUPES)
#define udd_disable_wake_up_interrupt() (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_WAKEUPEC)
#define Is_udd_wake_up_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_WAKEUPE))
#define udd_ack_wake_up() (UOTGHS->UOTGHS_DEVICR = UOTGHS_DEVICR_WAKEUPC)
#define udd_raise_wake_up() (UOTGHS->UOTGHS_DEVIFR = UOTGHS_DEVIFR_WAKEUPS)
#define Is_udd_wake_up() (Tst_bits(UOTGHS->UOTGHS_DEVISR, UOTGHS_DEVISR_WAKEUP))
//! @}
//! Manage reset event
//! Set when a USB "End of Reset" has been detected
//! @{
#define udd_enable_reset_interrupt() (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_EORSTES)
#define udd_disable_reset_interrupt() (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_EORSTEC)
#define Is_udd_reset_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_EORSTE))
#define udd_ack_reset() (UOTGHS->UOTGHS_DEVICR = UOTGHS_DEVICR_EORSTC)
#define udd_raise_reset() (UOTGHS->UOTGHS_DEVIFR = UOTGHS_DEVIFR_EORSTS)
#define Is_udd_reset() (Tst_bits(UOTGHS->UOTGHS_DEVISR, UOTGHS_DEVISR_EORST))
//! @}
//! Manage start of frame event
//! @{
#define udd_enable_sof_interrupt() (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_SOFES)
#define udd_disable_sof_interrupt() (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_SOFEC)
#define Is_udd_sof_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_SOFE))
#define udd_ack_sof() (UOTGHS->UOTGHS_DEVICR = UOTGHS_DEVICR_SOFC)
#define udd_raise_sof() (UOTGHS->UOTGHS_DEVIFR = UOTGHS_DEVIFR_SOFS)
#define Is_udd_sof() (Tst_bits(UOTGHS->UOTGHS_DEVISR, UOTGHS_DEVISR_SOF))
#define udd_frame_number() (Rd_bitfield(UOTGHS->UOTGHS_DEVFNUM, UOTGHS_DEVFNUM_FNUM_Msk))
#define Is_udd_frame_number_crc_error() (Tst_bits(UOTGHS->UOTGHS_DEVFNUM, UOTGHS_DEVFNUM_FNCERR))
//! @}
//! Manage Micro start of frame event (High Speed Only)
//! @{
#define udd_enable_msof_interrupt() (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_MSOFES)
#define udd_disable_msof_interrupt() (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_MSOFEC)
#define Is_udd_msof_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_MSOFE))
#define udd_ack_msof() (UOTGHS->UOTGHS_DEVICR = UOTGHS_DEVIMR_MSOFE)
#define udd_raise_msof() (UOTGHS->UOTGHS_DEVIFR = UOTGHS_DEVIFR_MSOFS)
#define Is_udd_msof() (Tst_bits(UOTGHS->UOTGHS_DEVISR, UOTGHS_DEVISR_MSOF))
#define udd_micro_frame_number() \
(Rd_bitfield(UOTGHS->UOTGHS_DEVFNUM, (UOTGHS_DEVFNUM_FNUM_Msk|UOTGHS_DEVFNUM_MFNUM_Msk)))
//! @}
//! Manage suspend event
//! @{
#define udd_enable_suspend_interrupt() (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_SUSPES)
#define udd_disable_suspend_interrupt() (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_SUSPEC)
#define Is_udd_suspend_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_SUSPE))
#define udd_ack_suspend() (UOTGHS->UOTGHS_DEVICR = UOTGHS_DEVICR_SUSPC)
#define udd_raise_suspend() (UOTGHS->UOTGHS_DEVIFR = UOTGHS_DEVIFR_SUSPS)
#define Is_udd_suspend() (Tst_bits(UOTGHS->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() (Set_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_ADDEN))
//! disables USB device address
#define udd_disable_address() (Clr_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_ADDEN))
#define Is_udd_address_enabled() (Tst_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_ADDEN))
//! configures the USB device address
#define udd_configure_address(addr) (Wr_bitfield(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_UADD_Msk, addr))
//! gets the currently configured USB device address
#define udd_get_configured_address() (Rd_bitfield(UOTGHS->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) ((&(UOTGHS->reg))[(index)])
//! @}
//! @name UOTGHS Device endpoint configuration
//! @{
//! enables the selected endpoint
#define udd_enable_endpoint(ep) (Set_bits(UOTGHS->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPEN0 << (ep)))
//! disables the selected endpoint
#define udd_disable_endpoint(ep) (Clr_bits(UOTGHS->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPEN0 << (ep)))
//! tests if the selected endpoint is enabled
#define Is_udd_endpoint_enabled(ep) (Tst_bits(UOTGHS->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPEN0 << (ep)))
//! resets the selected endpoint
#define udd_reset_endpoint(ep) \
do { \
Set_bits(UOTGHS->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPRST0 << (ep)); \
Clr_bits(UOTGHS->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPRST0 << (ep)); \
} while (0)
//! Tests if the selected endpoint is being reset
#define Is_udd_resetting_endpoint(ep) (Tst_bits(UOTGHS->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) (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_PEP_0 << (ep))
//! Disables the selected endpoint interrupt
#define udd_disable_endpoint_interrupt(ep) (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_PEP_0 << (ep))
//! Tests if the selected endpoint interrupt is enabled
#define Is_udd_endpoint_interrupt_enabled(ep) (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_PEP_0 << (ep)))
//! Tests if an interrupt is triggered by the selected endpoint
#define Is_udd_endpoint_interrupt(ep) (Tst_bits(UOTGHS->UOTGHS_DEVISR, UOTGHS_DEVISR_PEP_0 << (ep)))
//! Returns the lowest endpoint number generating an endpoint interrupt or MAX_PEP_NB if none
#define udd_get_interrupt_endpoint_number() (ctz(((UOTGHS->UOTGHS_DEVISR >> UOTGHS_DEVISR_PEP_Pos) & \
(UOTGHS->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)
//! 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) (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) (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(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UIDE))
//! Disable external OTG_ID pin (ignored by USB)
#define otg_disable_id_pin() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UIDE))
//! Test if external OTG_ID pin enabled (listened to by USB)
#define Is_otg_id_pin_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UIDE))
//! Disable external OTG_ID pin and force device mode
#define otg_force_device_mode() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UIMOD), otg_disable_id_pin())
//! Test if device mode is forced
#define Is_otg_device_mode_forced() (!Is_otg_id_pin_enabled() && Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UIMOD))
//! Disable external OTG_ID pin and force host mode
#define otg_force_host_mode() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UIMOD), otg_disable_id_pin())
//! Test if host mode is forced
#define Is_otg_host_mode_forced() (!Is_otg_id_pin_enabled() && !Tst_bits(UOTGHS->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(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_IDTE))
#define otg_disable_id_interrupt() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_IDTE))
#define Is_otg_id_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_IDTE))
#define Is_otg_id_device() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_ID))
#define Is_otg_id_host() (!Is_otg_id_device())
#define otg_ack_id_transition() (UOTGHS->UOTGHS_SCR = UOTGHS_SCR_IDTIC)
#define otg_raise_id_transition() (UOTGHS->UOTGHS_SFR = UOTGHS_SFR_IDTIS)
#define Is_otg_id_transition() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_IDTI))
//! @}
//! @name USBB OTG Vbus management
//! @{
#define otg_enable_vbus_interrupt() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE))
#define otg_disable_vbus_interrupt() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE))
#define Is_otg_vbus_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE))
#define Is_otg_vbus_high() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_VBUS))
#define Is_otg_vbus_low() (!Is_otg_vbus_high())
#define otg_ack_vbus_transition() (UOTGHS->UOTGHS_SCR = UOTGHS_SCR_VBUSTIC)
#define otg_raise_vbus_transition() (UOTGHS->UOTGHS_SFR = UOTGHS_SFR_VBUSTIS)
#define Is_otg_vbus_transition() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_VBUSTI))
//! @}
//! @name UOTGHS OTG main management
//! These macros allows to enable/disable pad and UOTGHS hardware
//! @{
//! Enable USB macro
#define otg_enable() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_USBE))
//! Disable USB macro
#define otg_disable() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_USBE))
#define Is_otg_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_USBE))
//! Enable OTG pad
#define otg_enable_pad() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_OTGPADE))
//! Disable OTG pad
#define otg_disable_pad() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_OTGPADE))
#define Is_otg_pad_enabled() (Tst_bits(UOTGHS->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(UOTGHS->UOTGHS_SR, UOTGHS_SR_CLKUSABLE))
//! Stop (freeze) internal USB clock
#define otg_freeze_clock() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_FRZCLK))
#define otg_unfreeze_clock() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_FRZCLK))
#define Is_otg_clock_frozen() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_FRZCLK))
//! Configure time-out of specified OTG timer
#define otg_configure_timeout(timer, timeout) (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UNLOCK),\
Wr_bitfield(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_TIMPAGE_Msk, timer),\
Wr_bitfield(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_TIMVALUE_Msk, timeout),\
Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UNLOCK))
//! Get configured time-out of specified OTG timer
#define otg_get_timeout(timer) (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UNLOCK),\
Wr_bitfield(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_TIMPAGE_Msk, timer),\
Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UNLOCK),\
Rd_bitfield(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_TIMVALUE_Msk))
//! Get the dual-role device state of the internal USB finite state machine of the UOTGHS controller
#define otg_get_fsm_drd_state() (Rd_bitfield(UOTGHS->UOTGHS_FSM, UOTGHS_FSM_DRDSTATE_Msk))
//! @}
//! @name UOTGHS OTG hardware protocol
//! These macros manages the hardware OTG protocol
//! @{
//! Initiates a Host Negociation Protocol
#define otg_device_initiate_hnp() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_HNPREQ))
//! Accepts a Host Negociation Protocol
#define otg_host_accept_hnp() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_HNPREQ))
//! Rejects a Host Negociation Protocol
#define otg_host_reject_hnp() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_HNPREQ))
//! initiates a Session Request Protocol
#define otg_device_initiate_srp() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_SRPREQ))
//! Selects VBus as SRP method
#define otg_select_vbus_srp_method() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_SRPSEL))
#define Is_otg_vbus_srp_method_selected() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_SRPSEL))
//! Selects data line as SRP method
#define otg_select_data_srp_method() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_SRPSEL))
#define Is_otg_data_srp_method_selected() (!Is_otg_vbus_srp_method_selected())
//! Tests if a HNP occurs
#define Is_otg_hnp() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_HNPREQ))
//! Tests if a SRP from device occurs
#define Is_otg_device_srp() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_SRPREQ))
//! Enables HNP error interrupt
#define otg_enable_hnp_error_interrupt() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_HNPERRE))
//! Disables HNP error interrupt
#define otg_disable_hnp_error_interrupt() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_HNPERRE))
#define Is_otg_hnp_error_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_HNPERRE))
//! ACKs HNP error interrupt
#define otg_ack_hnp_error_interrupt() (UOTGHS->UOTGHS_SCR = UOTGHS_SCR_HNPERRIC)
//! Raises HNP error interrupt
#define otg_raise_hnp_error_interrupt() (UOTGHS->UOTGHS_SFR = UOTGHS_SFR_HNPERRIS)
//! Tests if a HNP error occurs
#define Is_otg_hnp_error_interrupt() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_HNPERRI))
//! Enables role exchange interrupt
#define otg_enable_role_exchange_interrupt() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_ROLEEXE))
//! Disables role exchange interrupt
#define otg_disable_role_exchange_interrupt() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_ROLEEXE))
#define Is_otg_role_exchange_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_ROLEEXE))
//! ACKs role exchange interrupt
#define otg_ack_role_exchange_interrupt() (UOTGHS->UOTGHS_SCR = UOTGHS_SCR_ROLEEXIC)
//! Raises role exchange interrupt
#define otg_raise_role_exchange_interrupt() (UOTGHS->UOTGHS_SFR = UOTGHS_SFR_ROLEEXIS)
//! Tests if a role exchange occurs
#define Is_otg_role_exchange_interrupt() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_ROLEEXI))
//! Eenables SRP interrupt
#define otg_enable_srp_interrupt() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_SRPE))
//! Disables SRP interrupt
#define otg_disable_srp_interrupt() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_SRPE))
#define Is_otg_srp_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_SRPE))
//! ACKs SRP interrupt
#define otg_ack_srp_interrupt() (UOTGHS->UOTGHS_SCR = UOTGHS_SCR_SRPIC)
//! Raises SRP interrupt
#define otg_raise_srp_interrupt() (UOTGHS->UOTGHS_SFR = UOTGHS_SFR_SRPIS)
//! Tests if a SRP occurs
#define Is_otg_srp_interrupt() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_SRPI))
//! @}
//! @}
#endif /* UOTGHS_H_INCLUDED */ #endif /* UOTGHS_H_INCLUDED */

View File

@ -20,14 +20,34 @@
#if SAM3XA_SERIES #if SAM3XA_SERIES
void USBD_InitEndpoints( uint32_t* puc_EndPoints, uint32_t ul_EndPoints ) static void (*gpf_isr)(void)=(0UL);
{
uint32_t ul_EP ;
for (ul_EP = 1; ul_EP < sizeof(_initEndpoints); ul_EP++) uint32_t ul_ep = 0;
void UDD_SetStack(void (*pf_isr)(void))
{
gpf_isr = pf_isr;
}
void UOTGHS_Handler( void )
{
if (gpf_isr)
gpf_isr();
}
void UDD_SetEP( uint32_t ep )
{
ul_ep = ep;
}
void UDD_InitEndpoints(const uint32_t* eps_table)
{
uint32_t ul_ep_nb ;
for (ul_ep_nb = 1; ul_ep_nb < sizeof(eps_table); ul_ep_nb++)
{ {
// Reset Endpoint Fifos // Reset Endpoint Fifos
UOTGHS->UOTGHS_DEVEPTISR[ul_EP].UDPHS_EPTCLRSTA = UDPHS_EPTCLRSTA_TOGGLESQ | UDPHS_EPTCLRSTA_FRCESTALL; /* UOTGHS->UOTGHS_DEVEPTISR[ul_EP].UDPHS_EPTCLRSTA = UDPHS_EPTCLRSTA_TOGGLESQ | UDPHS_EPTCLRSTA_FRCESTALL;
UOTGHS->UOTGHS_DEVEPT = 1<<ul_EP; UOTGHS->UOTGHS_DEVEPT = 1<<ul_EP;
//UECONX = 1; //UECONX = 1;
@ -39,20 +59,39 @@ void USBD_InitEndpoints( uint32_t* puc_EndPoints, uint32_t ul_EndPoints )
UOTGHS->UDPHS_EPT[ul_EP].UDPHS_EPTCTLENB = UDPHS_EPTCTLENB_EPT_ENABL; UOTGHS->UDPHS_EPT[ul_EP].UDPHS_EPTCTLENB = UDPHS_EPTCTLENB_EPT_ENABL;
// UECFG1X = EP_DOUBLE_64; // UECFG1X = EP_DOUBLE_64;
}*/
// Reset EP
UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPRST0 << ul_ep_nb);
// Configure EP
UOTGHS->UOTGHS_DEVEPTCFG[ul_ep_nb] = eps_table[ul_ep_nb];
// Enable EP
UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPEN0 << ul_ep_nb);
} }
} }
uint32_t USBD_Init(void) void UDD_InitEP( uint32_t ul_ep_nb, uint32_t ul_ep_cfg )
{ {
uint32_t ul ; // Reset EP
UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPRST0 << ul_ep_nb);
// Configure EP
UOTGHS->UOTGHS_DEVEPTCFG[ul_ep_nb] = ul_ep_cfg;
// Enable EP
UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPEN0 << ul_ep_nb);
}
// Enables the USB Clock uint32_t UDD_Init(void)
{
uint32_t ul ;
// Enables the USB Clock
pmc_enable_periph_clk(ID_UOTGHS); pmc_enable_periph_clk(ID_UOTGHS);
pmc_enable_upll_clock(); pmc_enable_upll_clock();
pmc_switch_udpck_to_upllck(0); // div=0+1 pmc_switch_udpck_to_upllck(0); // div=0+1
pmc_enable_udpck(); pmc_enable_udpck();
// Configure interrupts // Configure interrupts
NVIC_SetPriority((IRQn_Type) ID_UOTGHS, 0UL); NVIC_SetPriority((IRQn_Type) ID_UOTGHS, 0UL);
NVIC_EnableIRQ((IRQn_Type) ID_UOTGHS); NVIC_EnableIRQ((IRQn_Type) ID_UOTGHS);
@ -60,135 +99,259 @@ uint32_t USBD_Init(void)
// for SAM3 USB wake up device except BACKUP mode // for SAM3 USB wake up device except BACKUP mode
pmc_set_fast_startup_input(PMC_FSMR_USBAL); pmc_set_fast_startup_input(PMC_FSMR_USBAL);
// Enable USB macro // Enable USB
UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_USBE; UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_USBE;
// Automatic mode speed for device // Automatic mode speed for device
UOTGHS->UOTGHS_DEVCTRL &= ~UOTGHS_DEVCTRL_SPDCONF_Msk; // Normal mode UOTGHS->UOTGHS_DEVCTRL &= ~UOTGHS_DEVCTRL_SPDCONF_Msk; // Normal mode
UOTGHS->UOTGHS_DEVCTRL &= ~( UOTGHS_DEVCTRL_LS | UOTGHS_DEVCTRL_TSTJ | UOTGHS_DEVCTRL_TSTK | UOTGHS->UOTGHS_DEVCTRL &= ~( UOTGHS_DEVCTRL_LS | UOTGHS_DEVCTRL_TSTJ | UOTGHS_DEVCTRL_TSTK |
UOTGHS_DEVCTRL_TSTPCKT | UOTGHS_DEVCTRL_OPMODE2 ); // Normal mode UOTGHS_DEVCTRL_TSTPCKT | UOTGHS_DEVCTRL_OPMODE2 ); // Normal mode
UOTGHS->UOTGHS_DEVCTRL = 0; UOTGHS->UOTGHS_DEVCTRL = 0;
UOTGHS->UOTGHS_HSTCTRL = 0; UOTGHS->UOTGHS_HSTCTRL = 0;
// Enable OTG pad // Enable OTG pad
UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_OTGPADE; UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_OTGPADE;
// Enable clock OTG pad // Enable clock OTG pad
UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_FRZCLK; UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_FRZCLK;
// Usb disable // Usb disable
UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_USBE; UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_USBE;
UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_OTGPADE; UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_OTGPADE;
UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_FRZCLK; UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_FRZCLK;
// Usb enable // Usb enable
UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_USBE; UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_USBE;
UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_OTGPADE; UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_OTGPADE;
UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_FRZCLK; UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_FRZCLK;
// Usb select_device // Usb select device mode
UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_UIDE; UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_UIDE;
UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_UIMOD_Device; UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_UIMOD_Device;
// Device is in the Attached state // Device is in the Attached state
// deviceState = USBD_STATE_SUSPENDED; // deviceState = USBD_STATE_SUSPENDED;
// previousDeviceState = USBD_STATE_POWERED; // previousDeviceState = USBD_STATE_POWERED;
// Enable USB macro and clear all other bits // Enable USB and clear all other bits
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_CTRL_USBE; //UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_CTRL_USBE;
UOTGHS->UOTGHS_DEVCTRL = UOTGHS_CTRL_USBE; //UOTGHS->UOTGHS_DEVCTRL = UOTGHS_CTRL_USBE;
// Configure the pull-up on D+ and disconnect it // Configure the pull-up on D+ and disconnect it
USBD_Detach(); UDD_Detach();
// Clear General IT // 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); 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 // 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); 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 // 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); 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 // Reset all Endpoints Fifos
UOTGHS->UOTGHS_DEVEPT |= (UOTGHS_DEVEPT_EPRST0|UOTGHS_DEVEPT_EPRST1|UOTGHS_DEVEPT_EPRST2|UOTGHS_DEVEPT_EPRST3|UOTGHS_DEVEPT_EPRST4| 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_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->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_DEVEPT_EPRST5|UOTGHS_DEVEPT_EPRST6|UOTGHS_DEVEPT_EPRST7|UOTGHS_DEVEPT_EPRST8);
// Disable all endpoints // Disable all endpoints
UOTGHS->UOTGHS_DEVEPT &= ~(UOTGHS_DEVEPT_EPEN0|UOTGHS_DEVEPT_EPEN1|UOTGHS_DEVEPT_EPEN2|UOTGHS_DEVEPT_EPEN3|UOTGHS_DEVEPT_EPEN4| 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); UOTGHS_DEVEPT_EPEN5|UOTGHS_DEVEPT_EPEN6|UOTGHS_DEVEPT_EPEN7|UOTGHS_DEVEPT_EPEN8);
// Device is in the Attached state // Device is in the Attached state
// deviceState = USBD_STATE_SUSPENDED; // deviceState = USBD_STATE_SUSPENDED;
// previousDeviceState = USBD_STATE_POWERED; // previousDeviceState = USBD_STATE_POWERED;
// Automatic mode speed for device // Automatic mode speed for device
UOTGHS->UOTGHS_DEVCTRL &= ~UOTGHS_DEVCTRL_SPDCONF_Msk; UOTGHS->UOTGHS_DEVCTRL &= ~UOTGHS_DEVCTRL_SPDCONF_Msk;
// Force Full Speed mode for device // Force Full Speed mode for device
//UOTGHS->UOTGHS_DEVCTRL = UOTGHS_DEVCTRL_SPDCONF_FORCED_FS; //UOTGHS->UOTGHS_DEVCTRL = UOTGHS_DEVCTRL_SPDCONF_FORCED_FS;
// Force High Speed mode for device // Force High Speed mode for device
//UOTGHS->UOTGHS_DEVCTRL = UOTGHS_DEVCTRL_SPDCONF_HIGH_SPEED; //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) ; UOTGHS->UOTGHS_DEVCTRL &= ~(UOTGHS_DEVCTRL_LS|UOTGHS_DEVCTRL_TSTJ| UOTGHS_DEVCTRL_TSTK|UOTGHS_DEVCTRL_TSTPCKT|UOTGHS_DEVCTRL_OPMODE2) ;
// Enable USB macro // Enable USB macro
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_CTRL_USBE; UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_USBE;
// Enable the UID pin select // Enable the UID pin select
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_CTRL_UIDE; UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_UIDE;
// Enable OTG pad // Enable OTG pad
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_CTRL_OTGPADE; UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_OTGPADE;
// Enable clock OTG pad // Enable clock OTG pad
UOTGHS->UOTGHS_DEVCTRL &= ~UOTGHS_CTRL_FRZCLK; UOTGHS->UOTGHS_CTRL &= ~UOTGHS_CTRL_FRZCLK;
// With OR without DMA !!! // With OR without DMA !!!
// Initialization of DMA // Initialization of DMA
for( ul=1; ul<= UOTGHSDEVDMA_NUMBER ; ul++ ) for( ul=1; ul<= UOTGHSDEVDMA_NUMBER ; ul++ )
{ {
// RESET endpoint canal DMA: // RESET endpoint canal DMA:
// DMA stop channel command // DMA stop channel command
UOTGHS->UOTGHS_DEVDMA[ul].UOTGHS_DEVDMACONTROL = 0; // STOP command UOTGHS->UOTGHS_DEVDMA[ul].UOTGHS_DEVDMACONTROL = 0; // STOP command
// Disable endpoint // Disable endpoint
UOTGHS->UOTGHS_DEVEPTIDR[ul] = (UOTGHS_DEVEPTIDR_TXINEC|UOTGHS_DEVEPTIDR_RXOUTEC|UOTGHS_DEVEPTIDR_RXSTPEC|UOTGHS_DEVEPTIDR_UNDERFEC|UOTGHS_DEVEPTIDR_NAKOUTEC| 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_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_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); UOTGHS_DEVEPTIDR_NBUSYBKEC|UOTGHS_DEVEPTIDR_FIFOCONC|UOTGHS_DEVEPTIDR_EPDISHDMAC|UOTGHS_DEVEPTIDR_NYETDISC|UOTGHS_DEVEPTIDR_STALLRQC);
// Reset endpoint config // Reset endpoint config
UOTGHS->UOTGHS_DEVEPTCFG[ul] = 0UL; UOTGHS->UOTGHS_DEVEPTCFG[ul] = 0UL;
// Reset DMA channel (Buff count and Control field) // Reset DMA channel (Buff count and Control field)
UOTGHS->UOTGHS_DEVDMA[ul].UOTGHS_DEVDMACONTROL = 0x02UL; // NON STOP command UOTGHS->UOTGHS_DEVDMA[ul].UOTGHS_DEVDMACONTROL = 0x02UL; // NON STOP command
// Reset DMA channel 0 (STOP) // Reset DMA channel 0 (STOP)
UOTGHS->UOTGHS_DEVDMA[ul].UOTGHS_DEVDMACONTROL = 0UL; // STOP command UOTGHS->UOTGHS_DEVDMA[ul].UOTGHS_DEVDMACONTROL = 0UL; // STOP command
// Clear DMA channel status (read the register to clear it) // Clear DMA channel status (read the register to clear it)
UOTGHS->UOTGHS_DEVDMA[ul].UOTGHS_DEVDMASTATUS = UOTGHS->UOTGHS_DEVDMA[ul].UOTGHS_DEVDMASTATUS; UOTGHS->UOTGHS_DEVDMA[ul].UOTGHS_DEVDMASTATUS = UOTGHS->UOTGHS_DEVDMA[ul].UOTGHS_DEVDMASTATUS;
} }
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_CTRL_VBUSTE; UOTGHS->UOTGHS_CTRL |= UOTGHS_CTRL_VBUSTE;
UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_WAKEUPES; UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_WAKEUPES;
return 0UL ; return 0UL ;
} }
void USBD_Attach(void) void UDD_Attach(void)
{ {
UOTGHS->UOTGHS_DEVCTRL &= ~(unsigned int)UOTGHS_DEVCTRL_DETACH; UOTGHS->UOTGHS_DEVCTRL &= ~(unsigned int)UOTGHS_DEVCTRL_DETACH;
} }
void USBD_Detach(void) void UDD_Detach(void)
{ {
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_DETACH; UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_DETACH;
} }
void UDD_WaitIN(void)
{
//while (!(UEINTX & (1<<TXINI)));
while (!(UOTGHS->UOTGHS_DEVEPTISR[ul_ep] & UOTGHS_DEVEPTISR_TXINI))
;
}
void UDD_WaitOUT(void)
{
//while (!(UEINTX & (1<<RXOUTI)));
while (!(UOTGHS->UOTGHS_DEVEPTISR[ul_ep] & UOTGHS_DEVEPTISR_RXOUTI))
;
}
uint32_t ul_send_index = 0;
uint32_t ul_rcv_index = 0;
void UDD_ClearIN(void)
{
// UEINTX = ~(1<<TXINI);
UOTGHS->UOTGHS_DEVEPTICR[ul_ep] = UOTGHS_DEVEPTICR_TXINIC;
ul_send_index = 0;
}
void UDD_ClearOUT(void)
{
// UEINTX = ~(1<<RXOUTI);
UOTGHS->UOTGHS_DEVEPTICR[ul_ep] = UOTGHS_DEVEPTICR_RXOUTIC;
ul_rcv_index = 0;
}
uint32_t UDD_WaitForINOrOUT(void)
{
//while (!(UEINTX & ((1<<TXINI)|(1<<RXOUTI))));
//return (UEINTX & (1<<RXOUTI)) == 0;
while (!(UOTGHS->UOTGHS_DEVEPTISR[ul_ep] & (UOTGHS_DEVEPTISR_TXINI | UOTGHS_DEVEPTISR_RXOUTI)))
;
return ((UOTGHS->UOTGHS_DEVEPTISR[ul_ep] & UOTGHS_DEVEPTISR_RXOUTI) == 0);
}
uint32_t UDD_ReceivedSetupInt(void)
{
return UOTGHS->UOTGHS_DEVEPTISR[ul_ep] & UOTGHS_DEVEPTISR_RXSTPI;
}
void UDD_ClearSetupInt(void)
{
//UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
UOTGHS->UOTGHS_DEVEPTICR[ul_ep] = (UOTGHS_DEVEPTICR_RXSTPIC | UOTGHS_DEVEPTICR_RXOUTIC | UOTGHS_DEVEPTICR_TXINIC);
}
void UDD_Send8( uint8_t data )
{
uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ul_ep);
ptr_dest[ul_send_index++] = data;
}
uint8_t UDD_Recv8(void)
{
uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ul_ep);
return ptr_dest[ul_rcv_index++];
}
void UDD_Recv(volatile uint8_t* data, uint32_t count)
{
uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ul_ep);
while (count--)
*data++ = ptr_dest[ul_rcv_index++];
}
void UDD_Stall(void)
{
//UECONX = (1<<STALLRQ) | (1<<EPEN);
UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPEN0 << ul_ep);
UOTGHS->UOTGHS_DEVEPTIER[ul_ep] = UOTGHS_DEVEPTIER_STALLRQS;
}
uint32_t UDD_FifoByteCount(void)
{
return ((UOTGHS->UOTGHS_DEVEPTISR[ul_ep] & UOTGHS_DEVEPTISR_BYCT_Msk) >> UOTGHS_DEVEPTISR_BYCT_Pos);
}
void UDD_ReleaseRX(void)
{
/* UEINTX = 0x6B; // FIFOCON=0 NAKINI=1 RWAL=1 NAKOUTI=0 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=1
clear fifocon = send and switch bank
nakouti a clearer
rxouti/killbank a clearer*/
UOTGHS->UOTGHS_DEVEPTICR[ul_ep] = (UOTGHS_DEVEPTICR_NAKOUTIC | UOTGHS_DEVEPTICR_RXOUTIC);
UOTGHS->UOTGHS_DEVEPTIDR[ul_ep] = UOTGHS_DEVEPTIDR_FIFOCONC;
}
void UDD_ReleaseTX(void)
{
/* UEINTX = 0x3A; // FIFOCON=0 NAKINI=0 RWAL=1 NAKOUTI=1 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=0
clear fifocon = send and switch bank
nakini a clearer
rxouti/killbank a clearer
txini a clearer*/
UOTGHS->UOTGHS_DEVEPTICR[ul_ep] = (UOTGHS_DEVEPTICR_NAKINIC | UOTGHS_DEVEPTICR_RXOUTIC | UOTGHS_DEVEPTICR_TXINIC);
UOTGHS->UOTGHS_DEVEPTIDR[ul_ep] = UOTGHS_DEVEPTIDR_FIFOCONC;
}
uint32_t UDD_ReadWriteAllowed(void)
{
return (UOTGHS->UOTGHS_DEVEPTISR[ul_ep] & UOTGHS_DEVEPTISR_RWALL);
}
void UDD_SetAddress(uint32_t addr)
{
udd_configure_address(addr);
udd_enable_address();
}
uint32_t UDD_GetFrameNumber(void)
{
return udd_frame_number();
}
#endif /* SAM3XA_SERIES */ #endif /* SAM3XA_SERIES */

View File

@ -55,6 +55,7 @@ VPATH+=$(PROJECT_BASE_PATH)
INCLUDES = INCLUDES =
#INCLUDES += -I$(PROJECT_BASE_PATH) #INCLUDES += -I$(PROJECT_BASE_PATH)
INCLUDES += -I$(ARDUINO_PATH) INCLUDES += -I$(ARDUINO_PATH)
INCLUDES += -I$(ARDUINO_PATH)/USB
INCLUDES += -I$(SYSTEM_PATH) INCLUDES += -I$(SYSTEM_PATH)
INCLUDES += -I$(SYSTEM_PATH)/libsam INCLUDES += -I$(SYSTEM_PATH)/libsam
INCLUDES += -I$(VARIANT_BASE_PATH) INCLUDES += -I$(VARIANT_BASE_PATH)