Commit f07e7667 authored by Dean Camera's avatar Dean Camera
Browse files

Complete USB XMEGA interrupt control subsystem code in the core USB driver.

Automatically load in the USB calibration bytes from the User Signature Row on start-up.

Create internal SRAM variable for the endpoint control and status register table, used by the XMEGA USB controller hardware.
parent ffa8b430
......@@ -33,11 +33,11 @@
void USB_INT_DisableAllInterrupts(void)
{
AVR32_USBB.USBCON.vbuste = false;
AVR32_USBB.USBCON.idte = false;
AVR32_USBB.USBCON.vbuste = false;
AVR32_USBB.USBCON.idte = false;
AVR32_USBB.uhinteclr = -1;
AVR32_USBB.udinteclr = -1;
AVR32_USBB.uhinteclr = -1;
AVR32_USBB.udinteclr = -1;
}
void USB_INT_ClearAllInterrupts(void)
......@@ -45,8 +45,8 @@ void USB_INT_ClearAllInterrupts(void)
AVR32_USBB.USBSTACLR.vbustic = true;
AVR32_USBB.USBSTACLR.idtic = true;
AVR32_USBB.uhintclr = -1;
AVR32_USBB.udintclr = -1;
AVR32_USBB.uhintclr = -1;
AVR32_USBB.udintclr = -1;
}
ISR(USB_GEN_vect)
......
......@@ -50,6 +50,7 @@
/* Includes: */
#include "../../../../Common/Common.h"
#include "../USBController.h"
#include "../StdDescriptors.h"
#include "../USBInterrupt.h"
#include "../Endpoint.h"
......@@ -103,12 +104,12 @@
/** Length of the device's unique internal serial number, in bits, if present on the selected microcontroller
* model.
*/
#define INTERNAL_SERIAL_LENGTH_BITS 112
#define INTERNAL_SERIAL_LENGTH_BITS (8 * (1 + (offsetof(NVM_PROD_SIGNATURES_t, COORDY1) - offsetof(NVM_PROD_SIGNATURES_t, LOTNUM0))))
/** Start address of the internal serial number, in the appropriate address space, if present on the selected microcontroller
* model.
*/
#define INTERNAL_SERIAL_START_ADDRESS 0x08
#define INTERNAL_SERIAL_START_ADDRESS offsetof(NVM_PROD_SIGNATURES_t, LOTNUM0)
/* Function Prototypes: */
/** Sends a Remote Wakeup request to the host. This signals to the host that the device should
......@@ -139,7 +140,7 @@
static inline uint16_t USB_Device_GetFrameNumber(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
static inline uint16_t USB_Device_GetFrameNumber(void)
{
return 0; // TODO
return (((uint16_t)USB_EndpointTable.FRAMENUMH << 8) | USB_EndpointTable.FRAMENUML);
}
#if !defined(NO_SOF_EVENTS)
......@@ -152,7 +153,7 @@
static inline void USB_Device_EnableSOFEvents(void) ATTR_ALWAYS_INLINE;
static inline void USB_Device_EnableSOFEvents(void)
{
// TODO
USB.INTCTRLA |= USB_SOFIE_bm;
}
/** Disables the device mode Start Of Frame events. When disabled, this stops the firing of the
......@@ -163,7 +164,7 @@
static inline void USB_Device_DisableSOFEvents(void) ATTR_ALWAYS_INLINE;
static inline void USB_Device_DisableSOFEvents(void)
{
// TODO
USB.INTCTRLA &= ~USB_SOFIE_bm;
}
#endif
......@@ -222,8 +223,6 @@
}
SetGlobalInterruptMask(CurrentGlobalInt);
}
#endif
......
......@@ -109,7 +109,7 @@
CheckBytes <<= 1;
}
return (MaskVal << USB_EP_SIZE_gp);
return (MaskVal << USB_EP_BUFSIZE_gp);
}
/* Function Prototypes: */
......
......@@ -40,6 +40,8 @@ volatile uint8_t USB_CurrentMode = USB_MODE_None;
volatile uint8_t USB_Options;
#endif
USB_EP_TABLE_t USB_EndpointTable ATTR_ALIGNED(2);
void USB_Init(
#if defined(USB_CAN_BE_BOTH)
const uint8_t Mode
......@@ -61,6 +63,16 @@ void USB_Init(
#endif
USB_IsInitialized = true;
uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
GlobalInterruptDisable();
NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
USB.CAL0 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL0));
NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
USB.CAL1 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL1));
SetGlobalInterruptMask(CurrentGlobalInt);
USB_ResetInterface();
}
......@@ -79,13 +91,17 @@ void USB_Disable(void)
void USB_ResetInterface(void)
{
if (USB_Options & USB_DEVICE_OPT_LOWSPEED)
CLK.USBCTRL = ((((F_USB / 6000000) - 1) << CLK_USBPSDIV_gp) | CLK_USBSRC_PLL_gc | CLK_USBEN_bm);
CLK.USBCTRL = ((((F_USB / 6000000) - 1) << CLK_USBPSDIV_gp) | CLK_USBSRC_PLL_gc | CLK_USBSEN_bm);
else
CLK.USBCTRL = ((((F_USB / 48000000) - 1) << CLK_USBPSDIV_gp) | CLK_USBSRC_PLL_gc | CLK_USBEN_bm);
CLK.USBCTRL = ((((F_USB / 48000000) - 1) << CLK_USBPSDIV_gp) | CLK_USBSRC_PLL_gc | CLK_USBSEN_bm);
USB_INT_DisableAllInterrupts();
USB_INT_ClearAllInterrupts();
// TODO: Config define for priority
USB.INTCTRLA = (2 << USB_INTLVL_gp);
PMIC.CTRL |= (1 << PMIC_MEDLVLEX_bp);
USB_Controller_Reset();
USB_Init_Device();
}
......@@ -143,6 +159,8 @@ static void USB_Init_Device(void)
ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize,
ENDPOINT_BANK_SINGLE);
USB_INT_Enable(USB_INT_BUSEVENTI);
USB_Attach();
}
#endif
......@@ -55,6 +55,13 @@
#include "../USBTask.h"
#include "../USBInterrupt.h"
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* External Variables: */
extern USB_EP_TABLE_t USB_EndpointTable;
#endif
/* Includes: */
#if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__)
#include "../Device.h"
#include "../Endpoint.h"
......
......@@ -33,13 +33,68 @@
void USB_INT_DisableAllInterrupts(void)
{
// TODO
USB.INTCTRLA = 0;
USB.INTCTRLB = 0;
}
void USB_INT_ClearAllInterrupts(void)
{
// TODO
USB.INTFLAGSACLR = 0xFF;
USB.INTFLAGSBCLR = 0xFF;
}
// TODO: USB ISR
ISR(USB_BUSEVENT_vect)
{
#if !defined(NO_SOF_EVENTS)
if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI))
{
USB_INT_Clear(USB_INT_SOFI);
EVENT_USB_Device_StartOfFrame();
}
#endif
if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Suspend))
{
USB_INT_Clear(USB_INT_BUSEVENTI_Suspend);
#if !defined(NO_LIMITED_CONTROLLER_CONNECT)
USB_DeviceState = DEVICE_STATE_Unattached;
EVENT_USB_Device_Disconnect();
#else
USB_DeviceState = DEVICE_STATE_Suspended;
EVENT_USB_Device_Suspend();
#endif
}
if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Resume))
{
USB_INT_Clear(USB_INT_BUSEVENTI_Resume);
if (USB_Device_ConfigurationNumber)
USB_DeviceState = DEVICE_STATE_Configured;
else
USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;
#if !defined(NO_LIMITED_CONTROLLER_CONNECT)
EVENT_USB_Device_Connect();
#else
EVENT_USB_Device_WakeUp();
#endif
}
if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Reset))
{
USB_INT_Clear(USB_INT_BUSEVENTI_Reset);
USB_DeviceState = DEVICE_STATE_Default;
USB_Device_ConfigurationNumber = 0;
Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,
ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize,
ENDPOINT_BANK_SINGLE);
EVENT_USB_Device_Reset();
}
}
......@@ -59,38 +59,92 @@
/* Enums: */
enum USB_Interrupts_t
{
USB_INT_NONE = 0, // TODO
USB_INT_BUSEVENTI = 1,
USB_INT_BUSEVENTI_Suspend = 2,
USB_INT_BUSEVENTI_Resume = 3,
USB_INT_BUSEVENTI_Reset = 4,
USB_INT_SOFI = 5,
};
/* Inline Functions: */
static inline void USB_INT_Enable(const uint8_t Interrupt) ATTR_ALWAYS_INLINE;
static inline void USB_INT_Enable(const uint8_t Interrupt)
{
// TODO
switch (Interrupt)
{
case USB_INT_BUSEVENTI:
USB.INTCTRLA |= USB_BUSEVIE_bm;
return;
case USB_INT_SOFI:
USB.INTCTRLA |= USB_SOFIE_bm;
return;
}
}
static inline void USB_INT_Disable(const uint8_t Interrupt) ATTR_ALWAYS_INLINE;
static inline void USB_INT_Disable(const uint8_t Interrupt)
{
// TODO
switch (Interrupt)
{
case USB_INT_BUSEVENTI:
USB.INTCTRLA &= ~USB_BUSEVIE_bm;
return;
case USB_INT_SOFI:
USB.INTCTRLA &= ~USB_SOFIE_bm;
return;
}
}
static inline void USB_INT_Clear(const uint8_t Interrupt) ATTR_ALWAYS_INLINE;
static inline void USB_INT_Clear(const uint8_t Interrupt)
{
// TODO
switch (Interrupt)
{
case USB_INT_BUSEVENTI_Suspend:
USB.INTFLAGSACLR = USB_SUSPENDIF_bm;
return;
case USB_INT_BUSEVENTI_Resume:
USB.INTFLAGSACLR = USB_RESUMEIF_bm;
return;
case USB_INT_BUSEVENTI_Reset:
USB.INTFLAGSACLR = USB_RSTIF_bm;
return;
case USB_INT_SOFI:
USB.INTFLAGSACLR = USB_SOFIF_bm;
return;
}
}
static inline bool USB_INT_IsEnabled(const uint8_t Interrupt) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
static inline bool USB_INT_IsEnabled(const uint8_t Interrupt)
{
return false; // TODO
switch (Interrupt)
{
case USB_INT_BUSEVENTI:
return (USB.INTCTRLA & USB_BUSEVIE_bm);
case USB_INT_SOFI:
return (USB.INTCTRLA & USB_SOFIE_bm);
}
return false;
}
static inline bool USB_INT_HasOccurred(const uint8_t Interrupt) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
static inline bool USB_INT_HasOccurred(const uint8_t Interrupt)
{
return false; // TODO
switch (Interrupt)
{
case USB_INT_BUSEVENTI_Suspend:
return (USB.INTFLAGSACLR & USB_SUSPENDIF_bm);
case USB_INT_BUSEVENTI_Resume:
return (USB.INTFLAGSACLR & USB_RESUMEIF_bm);
case USB_INT_BUSEVENTI_Reset:
return (USB.INTFLAGSACLR & USB_RSTIF_bm);
case USB_INT_SOFI:
return (USB.INTFLAGSACLR & USB_SOFIF_bm);
}
return false;
}
/* Includes: */
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment