Implementation of several key core USB driver functions for the new USB XMEGA devices.

pull/1469/head
Dean Camera 13 years ago
parent 6490d1c443
commit 8629e1918c

@ -98,17 +98,17 @@
* On unsupported devices, this will evaluate to \ref NO_DESCRIPTOR and so will force the host to create a pseudo-serial
* number for the device.
*/
#define USE_INTERNAL_SERIAL NO_DESCRIPTOR
#define USE_INTERNAL_SERIAL 0xDC
/** Length of the device's unique internal serial number, in bits, if present on the selected microcontroller
* model.
*/
#define INTERNAL_SERIAL_LENGTH_BITS 0
#define INTERNAL_SERIAL_LENGTH_BITS 112
/** Start address of the internal serial number, in the appropriate address space, if present on the selected microcontroller
* model.
*/
#define INTERNAL_SERIAL_START_ADDRESS 0
#define INTERNAL_SERIAL_START_ADDRESS 0x08
/* Function Prototypes: */
/** Sends a Remote Wakeup request to the host. This signals to the host that the device should
@ -173,34 +173,58 @@
static inline void USB_Device_SetLowSpeed(void) ATTR_ALWAYS_INLINE;
static inline void USB_Device_SetLowSpeed(void)
{
// TODO
USB.CTRLA &= ~USB_SPEED_bm;
}
static inline void USB_Device_SetFullSpeed(void) ATTR_ALWAYS_INLINE;
static inline void USB_Device_SetFullSpeed(void)
{
// TODO
USB.CTRLA |= USB_SPEED_bm;
}
static inline void USB_Device_SetDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE;
static inline void USB_Device_SetDeviceAddress(const uint8_t Address)
{
// TODO
USB.ADDR = Address;
}
static inline bool USB_Device_IsAddressSet(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
static inline bool USB_Device_IsAddressSet(void)
{
return false; // TODO
return ((USB.ADDR != 0) ? true : false);
}
#if (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString) ATTR_NON_NULL_PTR_ARG(1);
static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString)
{
// TODO
uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
GlobalInterruptDisable();
uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS;
for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++)
{
uint8_t SerialByte;
NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
SerialByte = pgm_read_byte(SigReadAddress);
if (SerialCharNum & 0x01)
{
SerialByte >>= 4;
SigReadAddress++;
}
SerialByte &= 0x0F;
UnicodeString[SerialCharNum] = cpu_to_le16((SerialByte >= 10) ?
(('A' - 10) + SerialByte) : ('0' + SerialByte));
}
SetGlobalInterruptMask(CurrentGlobalInt);
}
#endif
#endif

@ -90,33 +90,10 @@
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define _ENDPOINT_GET_MAXSIZE(EPIndex) _ENDPOINT_GET_MAXSIZE2(ENDPOINT_DETAILS_EP ## EPIndex)
#define _ENDPOINT_GET_MAXSIZE2(EPDetails) _ENDPOINT_GET_MAXSIZE3(EPDetails)
#define _ENDPOINT_GET_MAXSIZE3(MaxSize, Banks) (MaxSize)
#define _ENDPOINT_GET_BANKS(EPIndex) _ENDPOINT_GET_BANKS2(ENDPOINT_DETAILS_EP ## EPIndex)
#define _ENDPOINT_GET_BANKS2(EPDetails) _ENDPOINT_GET_BANKS3(EPDetails)
#define _ENDPOINT_GET_BANKS3(MaxSize, Banks) (Banks)
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
#define ENDPOINT_DETAILS_MAXEP 7
#define ENDPOINT_DETAILS_EP0 64, 1
#define ENDPOINT_DETAILS_EP1 256, 2
#define ENDPOINT_DETAILS_EP2 64, 2
#define ENDPOINT_DETAILS_EP3 64, 2
#define ENDPOINT_DETAILS_EP4 64, 2
#define ENDPOINT_DETAILS_EP5 64, 2
#define ENDPOINT_DETAILS_EP6 64, 2
#else
#define ENDPOINT_DETAILS_MAXEP 5
#define _ENDPOINT_GET_MAXSIZE(EPIndex) 1023
#define _ENDPOINT_GET_BANKS(EPIndex) 2
#define ENDPOINT_DETAILS_EP0 64, 1
#define ENDPOINT_DETAILS_EP1 64, 1
#define ENDPOINT_DETAILS_EP2 64, 1
#define ENDPOINT_DETAILS_EP3 64, 2
#define ENDPOINT_DETAILS_EP4 64, 2
#endif
#define ENDPOINT_DETAILS_MAXEP 16
/* Inline Functions: */
static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST
@ -141,12 +118,12 @@
/** Endpoint data direction mask for \ref Endpoint_ConfigureEndpoint(). This indicates that the endpoint
* should be initialized in the OUT direction - i.e. data flows from host to device.
*/
#define ENDPOINT_DIR_OUT (0 << EPDIR)
#define ENDPOINT_DIR_OUT 0 // TODO
/** Endpoint data direction mask for \ref Endpoint_ConfigureEndpoint(). This indicates that the endpoint
* should be initialized in the IN direction - i.e. data flows from device to host.
*/
#define ENDPOINT_DIR_IN (1 << EPDIR)
#define ENDPOINT_DIR_IN 0 // TODO
//@}
/** \name Endpoint Bank Mode Masks */
@ -156,14 +133,14 @@
* in slower transfers as only one USB device (the AVR or the host) can access the endpoint's
* bank at the one time.
*/
#define ENDPOINT_BANK_SINGLE (0 << EPBK0)
#define ENDPOINT_BANK_SINGLE 0 // TODO
/** Mask for the bank mode selection for the \ref Endpoint_ConfigureEndpoint() macro. This indicates
* that the endpoint should have two banks, which requires more USB FIFO memory but results
* in faster transfers as one USB device (the AVR or the host) can access one bank while the other
* accesses the second bank.
*/
#define ENDPOINT_BANK_DOUBLE (1 << EPBK0)
#define ENDPOINT_BANK_DOUBLE 0 // TODO
//@}
#if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))

@ -56,22 +56,88 @@ void USB_Init(
#endif
)
{
// TODO
#if !defined(USE_STATIC_OPTIONS)
USB_Options = Options;
#endif
USB_IsInitialized = true;
USB_ResetInterface();
}
void USB_Disable(void)
{
// TODO
USB_INT_DisableAllInterrupts();
USB_INT_ClearAllInterrupts();
USB_Detach();
USB_Controller_Disable();
USB_IsInitialized = false;
}
void USB_ResetInterface(void)
{
// TODO
USB_INT_DisableAllInterrupts();
USB_INT_ClearAllInterrupts();
USB_Controller_Reset();
USB_Init_Device();
}
#if defined(USB_CAN_BE_DEVICE)
static void USB_Init_Device(void)
{
// TODO
USB_DeviceState = DEVICE_STATE_Unattached;
USB_Device_ConfigurationNumber = 0;
#if !defined(NO_DEVICE_REMOTE_WAKEUP)
USB_Device_RemoteWakeupEnabled = false;
#endif
#if !defined(NO_DEVICE_SELF_POWER)
USB_Device_CurrentlySelfPowered = false;
#endif
#if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
USB_Descriptor_Device_t* DeviceDescriptorPtr;
#if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
!(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
uint8_t DescriptorAddressSpace;
if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr, &DescriptorAddressSpace) != NO_DESCRIPTOR)
{
if (DescriptorAddressSpace == MEMSPACE_FLASH)
USB_Device_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
USB_Device_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
else
USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
}
#else
if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR)
{
#if defined(USE_RAM_DESCRIPTORS)
USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
#elif defined(USE_EEPROM_DESCRIPTORS)
USB_Device_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
#else
USB_Device_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
#endif
}
#endif
#endif
if (USB_Options & USB_DEVICE_OPT_LOWSPEED)
USB_Device_SetLowSpeed();
else
USB_Device_SetFullSpeed();
Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,
ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize,
ENDPOINT_BANK_SINGLE);
USB_Attach();
}
#endif

@ -78,36 +78,6 @@
/* Public Interface - May be used in end-application: */
/* Macros: */
/** \name USB Controller Option Masks */
//@{
/** Regulator disable option mask for \ref USB_Init(). This indicates that the internal 3.3V USB data pad
* regulator should be disabled and the AVR's VCC level used for the data pads.
*
* \note See USB AVR data sheet for more information on the internal pad regulator.
*/
#define USB_OPT_REG_DISABLED (1 << 1)
/** Regulator enable option mask for \ref USB_Init(). This indicates that the internal 3.3V USB data pad
* regulator should be enabled to regulate the data pin voltages from the VBUS level down to a level within
* the range allowable by the USB standard.
*
* \note See USB AVR data sheet for more information on the internal pad regulator.
*/
#define USB_OPT_REG_ENABLED (0 << 1)
/** Manual PLL control option mask for \ref USB_Init(). This indicates to the library that the user application
* will take full responsibility for controlling the AVR's PLL (used to generate the high frequency clock
* that the USB controller requires) and ensuring that it is locked at the correct frequency for USB operations.
*/
#define USB_OPT_MANUAL_PLL (1 << 2)
/** Automatic PLL control option mask for \ref USB_Init(). This indicates to the library that the library should
* take full responsibility for controlling the AVR's PLL (used to generate the high frequency clock
* that the USB controller requires) and ensuring that it is locked at the correct frequency for USB operations.
*/
#define USB_OPT_AUTO_PLL (0 << 2)
//@}
/** \name Endpoint/Pipe Type Masks */
//@{
/** Mask for a CONTROL type endpoint or pipe.
@ -147,18 +117,6 @@
#endif
/* Inline Functions: */
/** Determines if the VBUS line is currently high (i.e. the USB host is supplying power).
*
* \note This function is not available on some AVR models which do not support hardware VBUS monitoring.
*
* \return Boolean \c true if the VBUS line is currently detecting power from a host, \c false otherwise.
*/
static inline bool USB_VBUS_GetStatus(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool USB_VBUS_GetStatus(void)
{
return 0; // TODO
}
/** Detaches the device from the USB bus. This has the effect of removing the device from any
* attached host, ceasing USB communications. If no host is present, this prevents any host from
* enumerating the device once attached until \ref USB_Attach() is called.
@ -166,7 +124,7 @@
static inline void USB_Detach(void) ATTR_ALWAYS_INLINE;
static inline void USB_Detach(void)
{
// TODO
USB.CTRLB &= ~USB_ATTACH_bm;
}
/** Attaches the device to the USB bus. This announces the device's presence to any attached
@ -180,7 +138,7 @@
static inline void USB_Attach(void) ATTR_ALWAYS_INLINE;
static inline void USB_Attach(void)
{
// TODO
USB.CTRLB |= USB_ATTACH_bm;
}
/* Function Prototypes: */
@ -304,46 +262,23 @@
#endif
/* Inline Functions: */
static inline void USB_REG_On(void) ATTR_ALWAYS_INLINE;
static inline void USB_REG_On(void)
{
// TODO
}
static inline void USB_REG_Off(void) ATTR_ALWAYS_INLINE;
static inline void USB_REG_Off(void)
{
// TODO
}
static inline void USB_CLK_Freeze(void) ATTR_ALWAYS_INLINE;
static inline void USB_CLK_Freeze(void)
{
// TODO
}
static inline void USB_CLK_Unfreeze(void) ATTR_ALWAYS_INLINE;
static inline void USB_CLK_Unfreeze(void)
{
// TODO
}
static inline void USB_Controller_Enable(void) ATTR_ALWAYS_INLINE;
static inline void USB_Controller_Enable(void)
{
// TODO
USB.CTRLA |= (USB_ENABLE_bm | USB_STFRNUM_bm | USB_MAXEP_gm);
}
static inline void USB_Controller_Disable(void) ATTR_ALWAYS_INLINE;
static inline void USB_Controller_Disable(void)
{
// TODO
USB.CTRLA &= ~USB_ENABLE_bm;
}
static inline void USB_Controller_Reset(void) ATTR_ALWAYS_INLINE;
static inline void USB_Controller_Reset(void)
{
// TODO
USB.CTRLA &= ~USB_ENABLE_bm;
USB.CTRLA |= USB_ENABLE_bm;
}
#endif

Loading…
Cancel
Save