Moved all source to the trunk directory.
This commit is contained in:
parent
9991321321
commit
6a10d6b465
88 changed files with 15575 additions and 0 deletions
313
LUFA/Drivers/USB/LowLevel/DevChapter9.c
Normal file
313
LUFA/Drivers/USB/LowLevel/DevChapter9.c
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#include "USBMode.h"
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
|
||||
#define INCLUDE_FROM_DEVCHAPTER9_C
|
||||
#include "DevChapter9.h"
|
||||
|
||||
uint8_t USB_ConfigurationNumber;
|
||||
bool USB_RemoteWakeupEnabled;
|
||||
bool USB_CurrentlySelfPowered;
|
||||
|
||||
void USB_Device_ProcessControlPacket(void)
|
||||
{
|
||||
uint8_t bmRequestType = Endpoint_Read_Byte();
|
||||
uint8_t bRequest = Endpoint_Read_Byte();
|
||||
bool RequestHandled = false;
|
||||
|
||||
switch (bRequest)
|
||||
{
|
||||
case REQ_GetStatus:
|
||||
if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
|
||||
(bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT)))
|
||||
{
|
||||
USB_Device_GetStatus(bmRequestType);
|
||||
RequestHandled = true;
|
||||
}
|
||||
|
||||
break;
|
||||
#if !defined(NO_CLEARSET_FEATURE_REQUEST)
|
||||
case REQ_ClearFeature:
|
||||
case REQ_SetFeature:
|
||||
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT))
|
||||
{
|
||||
USB_Device_ClearSetFeature(bRequest, bmRequestType);
|
||||
RequestHandled = true;
|
||||
}
|
||||
|
||||
break;
|
||||
#endif
|
||||
case REQ_SetAddress:
|
||||
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
|
||||
{
|
||||
USB_Device_SetAddress();
|
||||
RequestHandled = true;
|
||||
}
|
||||
|
||||
break;
|
||||
case REQ_GetDescriptor:
|
||||
if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
|
||||
(bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE)))
|
||||
{
|
||||
USB_Device_GetDescriptor();
|
||||
RequestHandled = true;
|
||||
}
|
||||
|
||||
break;
|
||||
case REQ_GetConfiguration:
|
||||
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE))
|
||||
{
|
||||
USB_Device_GetConfiguration();
|
||||
RequestHandled = true;
|
||||
}
|
||||
|
||||
break;
|
||||
case REQ_SetConfiguration:
|
||||
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
|
||||
{
|
||||
USB_Device_SetConfiguration();
|
||||
RequestHandled = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(RequestHandled))
|
||||
RAISE_EVENT(USB_UnhandledControlPacket, bRequest, bmRequestType);
|
||||
|
||||
if (Endpoint_IsSetupReceived())
|
||||
{
|
||||
Endpoint_StallTransaction();
|
||||
Endpoint_ClearSetupReceived();
|
||||
}
|
||||
}
|
||||
|
||||
static void USB_Device_SetAddress(void)
|
||||
{
|
||||
uint8_t wValue_LSB = Endpoint_Read_Byte();
|
||||
|
||||
Endpoint_ClearSetupReceived();
|
||||
|
||||
while (!(Endpoint_IsSetupINReady()));
|
||||
|
||||
Endpoint_ClearSetupIN();
|
||||
|
||||
while (!(Endpoint_IsSetupINReady()));
|
||||
|
||||
UDADDR = ((1 << ADDEN) | (wValue_LSB & 0x7F));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void USB_Device_SetConfiguration(void)
|
||||
{
|
||||
uint8_t wValue_LSB = Endpoint_Read_Byte();
|
||||
bool AlreadyConfigured = (USB_ConfigurationNumber != 0);
|
||||
|
||||
#if defined(USE_SINGLE_DEVICE_CONFIGURATION)
|
||||
if (wValue_LSB > 1)
|
||||
#else
|
||||
USB_Descriptor_Device_t* DevDescriptorPtr;
|
||||
|
||||
if ((USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr) == NO_DESCRIPTOR) ||
|
||||
#if defined(USE_RAM_DESCRIPTORS)
|
||||
(wValue_LSB > DevDescriptorPtr->NumberOfConfigurations))
|
||||
#elif defined (USE_EEPROM_DESCRIPTORS)
|
||||
(wValue_LSB > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
|
||||
#else
|
||||
(wValue_LSB > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Endpoint_ClearSetupReceived();
|
||||
|
||||
USB_ConfigurationNumber = wValue_LSB;
|
||||
|
||||
Endpoint_ClearSetupIN();
|
||||
|
||||
if (!(AlreadyConfigured) && USB_ConfigurationNumber)
|
||||
RAISE_EVENT(USB_DeviceEnumerationComplete);
|
||||
|
||||
RAISE_EVENT(USB_ConfigurationChanged);
|
||||
}
|
||||
|
||||
void USB_Device_GetConfiguration(void)
|
||||
{
|
||||
Endpoint_ClearSetupReceived();
|
||||
|
||||
Endpoint_Write_Byte(USB_ConfigurationNumber);
|
||||
|
||||
Endpoint_ClearSetupIN();
|
||||
|
||||
while (!(Endpoint_IsSetupOUTReceived()));
|
||||
Endpoint_ClearSetupOUT();
|
||||
}
|
||||
|
||||
static void USB_Device_GetDescriptor(void)
|
||||
{
|
||||
uint16_t wValue = Endpoint_Read_Word_LE();
|
||||
uint16_t wIndex = Endpoint_Read_Word_LE();
|
||||
uint16_t wLength = Endpoint_Read_Word_LE();
|
||||
|
||||
void* DescriptorPointer;
|
||||
uint16_t DescriptorSize;
|
||||
|
||||
bool SendZLP;
|
||||
|
||||
if ((DescriptorSize = USB_GetDescriptor(wValue, wIndex, &DescriptorPointer)) == NO_DESCRIPTOR)
|
||||
return;
|
||||
|
||||
Endpoint_ClearSetupReceived();
|
||||
|
||||
if (wLength > DescriptorSize)
|
||||
wLength = DescriptorSize;
|
||||
|
||||
while (wLength)
|
||||
{
|
||||
while (!(Endpoint_IsSetupINReady()))
|
||||
{
|
||||
if (Endpoint_IsSetupOUTReceived())
|
||||
{
|
||||
Endpoint_ClearSetupOUT();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while (wLength && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
|
||||
{
|
||||
#if defined(USE_RAM_DESCRIPTORS)
|
||||
Endpoint_Write_Byte(*((uint8_t*)DescriptorPointer++));
|
||||
#elif defined (USE_EEPROM_DESCRIPTORS)
|
||||
Endpoint_Write_Byte(eeprom_read_byte(DescriptorPointer++));
|
||||
#else
|
||||
Endpoint_Write_Byte(pgm_read_byte(DescriptorPointer++));
|
||||
#endif
|
||||
|
||||
wLength--;
|
||||
}
|
||||
|
||||
SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
|
||||
Endpoint_ClearSetupIN();
|
||||
}
|
||||
|
||||
if (SendZLP)
|
||||
{
|
||||
while (!(Endpoint_IsSetupINReady()));
|
||||
Endpoint_ClearSetupIN();
|
||||
}
|
||||
|
||||
while (!(Endpoint_IsSetupOUTReceived()));
|
||||
Endpoint_ClearSetupOUT();
|
||||
}
|
||||
|
||||
static void USB_Device_GetStatus(const uint8_t bmRequestType)
|
||||
{
|
||||
uint8_t CurrentStatus = 0;
|
||||
|
||||
Endpoint_Discard_Word();
|
||||
|
||||
uint8_t wIndex_LSB = Endpoint_Read_Byte();
|
||||
|
||||
switch (bmRequestType)
|
||||
{
|
||||
case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
|
||||
if (USB_CurrentlySelfPowered)
|
||||
CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
|
||||
|
||||
if (USB_RemoteWakeupEnabled)
|
||||
CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
|
||||
|
||||
break;
|
||||
case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
|
||||
Endpoint_SelectEndpoint(wIndex_LSB);
|
||||
|
||||
CurrentStatus = Endpoint_IsStalled();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
|
||||
Endpoint_ClearSetupReceived();
|
||||
Endpoint_Write_Word_LE(CurrentStatus);
|
||||
|
||||
Endpoint_ClearSetupIN();
|
||||
|
||||
while (!(Endpoint_IsSetupOUTReceived()));
|
||||
Endpoint_ClearSetupOUT();
|
||||
}
|
||||
|
||||
#if !defined(NO_CLEARSET_FEATURE_REQUEST)
|
||||
static void USB_Device_ClearSetFeature(const uint8_t bRequest, const uint8_t bmRequestType)
|
||||
{
|
||||
uint16_t wValue = Endpoint_Read_Word_LE();
|
||||
uint16_t wIndex = Endpoint_Read_Word_LE();
|
||||
|
||||
switch (bmRequestType & CONTROL_REQTYPE_RECIPIENT)
|
||||
{
|
||||
case REQREC_ENDPOINT:
|
||||
if (wValue == FEATURE_ENDPOINT_HALT)
|
||||
{
|
||||
uint8_t EndpointIndex = (wIndex & ENDPOINT_EPNUM_MASK);
|
||||
|
||||
if (EndpointIndex != ENDPOINT_CONTROLEP)
|
||||
{
|
||||
Endpoint_SelectEndpoint(EndpointIndex);
|
||||
|
||||
if (Endpoint_IsEnabled())
|
||||
{
|
||||
if (bRequest == REQ_ClearFeature)
|
||||
{
|
||||
Endpoint_ClearStall();
|
||||
Endpoint_ResetFIFO(EndpointIndex);
|
||||
Endpoint_ResetDataToggle();
|
||||
}
|
||||
else
|
||||
{
|
||||
Endpoint_StallTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
|
||||
Endpoint_ClearSetupReceived();
|
||||
Endpoint_ClearSetupIN();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
135
LUFA/Drivers/USB/LowLevel/DevChapter9.h
Normal file
135
LUFA/Drivers/USB/LowLevel/DevChapter9.h
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Module for device mode request processing. This module allows for the processing of standard control
|
||||
* requests to the default control endpoint while in device mode.
|
||||
*
|
||||
* \see Chapter 9 of the USB 2.0 specification.
|
||||
*/
|
||||
|
||||
#ifndef __DEVCHAPTER9_H__
|
||||
#define __DEVCHAPTER9_H__
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/eeprom.h>
|
||||
|
||||
#include "../HighLevel/StdDescriptors.h"
|
||||
#include "../HighLevel/Events.h"
|
||||
#include "LowLevel.h"
|
||||
#include "StdRequestType.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Global Variables: */
|
||||
/** Indicates the currently set configuration number of the device. USB devices may have several
|
||||
* different configurations which the host can select between; this indicates the currently selected
|
||||
* value, or 0 if no configuration has been selected.
|
||||
*
|
||||
* If a device has only one single configuration, the token USE_SINGLE_DEVICE_CONFIGURATION may be
|
||||
* defined in the project makefile and passed to the compiler using the -D switch. This optimize for
|
||||
* a single configuration, saving a small amount of space in the resulting compiled binary.
|
||||
*
|
||||
* \note This variable should be treated as read-only in the user application, and never manually
|
||||
* changed in value.
|
||||
*/
|
||||
extern uint8_t USB_ConfigurationNumber;
|
||||
|
||||
/** Indicates if the host is currently allowing the device to issue remote wakeup events. If this
|
||||
* flag is cleared, the device should not issue remote wakeup events to the host.
|
||||
*
|
||||
* \note This variable should be treated as read-only in the user application, and never manually
|
||||
* changed in value.
|
||||
*/
|
||||
extern bool USB_RemoteWakeupEnabled;
|
||||
|
||||
/** Indicates if the device is currently being powered by its own power supply, rather than being
|
||||
* powered by the host's USB supply. This flag should remain cleared if the device does not
|
||||
* support self powered mode, as indicated in the device descriptors.
|
||||
*/
|
||||
extern bool USB_CurrentlySelfPowered;
|
||||
|
||||
/* Throwable Events: */
|
||||
/** This module raises the USB_UnhandledControlPacket event when a request to the default control
|
||||
* endpoint has been received, but the library does not implement an internal handler for it.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_UnhandledControlPacket);
|
||||
|
||||
/** This module raises the USB_ConfigurationChanged event when the host issues a REQ_SetConfiguration
|
||||
* device request, to change the currently selected configuration number.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_ConfigurationChanged);
|
||||
|
||||
/** This module raises the USB_DeviceEnumerationComplete event when the host has completed its
|
||||
* enumeration of the device (i.e. when a REQ_SetConfiguration request changes the current configuration
|
||||
* number from 0 to a non-zero value).
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_DeviceEnumerationComplete);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
#if defined(USE_RAM_DESCRIPTORS) && defined(USE_EEPROM_DESCRIPTORS)
|
||||
#error USE_RAM_DESCRIPTORS and USE_EEPROM_DESCRIPTORS are mutually exclusive.
|
||||
#endif
|
||||
|
||||
/* Function Prototypes: */
|
||||
void USB_Device_ProcessControlPacket(void);
|
||||
|
||||
#if defined(INCLUDE_FROM_DEVCHAPTER9_C)
|
||||
static void USB_Device_SetAddress(void);
|
||||
static void USB_Device_SetConfiguration(void);
|
||||
static void USB_Device_GetConfiguration(void);
|
||||
static void USB_Device_GetDescriptor(void);
|
||||
static void USB_Device_GetStatus(const uint8_t bmRequestType);
|
||||
#if !defined(NO_CLEARSET_FEATURE_REQUEST)
|
||||
static void USB_Device_ClearSetFeature(const uint8_t bRequest, const uint8_t bmRequestType);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
126
LUFA/Drivers/USB/LowLevel/Device.h
Normal file
126
LUFA/Drivers/USB/LowLevel/Device.h
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* USB Device mode related macros and enums. This module contains macros and enums which are used when
|
||||
* the USB controller is initialized in device mode.
|
||||
*/
|
||||
|
||||
#ifndef __USBDEVICE_H__
|
||||
#define __USBDEVICE_H__
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/eeprom.h>
|
||||
|
||||
#include "../../../Common/Common.h"
|
||||
#include "../HighLevel/StdDescriptors.h"
|
||||
#include "Endpoint.h"
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
#if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER) || defined(__DOXYGEN__)
|
||||
/** Mask for the Options parameter of the USB_Init() function. This indicates that the
|
||||
* USB interface should be initialized in low speed (1.5Mb/s) mode.
|
||||
*
|
||||
* \note Low Speed mode is not available on all USB AVR models.
|
||||
*
|
||||
* \note Restrictions apply on the number, size and type of endpoints which can be used
|
||||
* when running in low speed mode -- refer to the USB 2.0 standard.
|
||||
*/
|
||||
#define USB_DEVICE_OPT_LOWSPEED (1 << 0)
|
||||
#endif
|
||||
|
||||
/** Mask for the Options parameter of the USB_Init() function. This indicates that the
|
||||
* USB interface should be initialized in full speed (12Mb/s) mode.
|
||||
*/
|
||||
#define USB_DEVICE_OPT_FULLSPEED (0 << 0)
|
||||
|
||||
/** Sends a Remote Wakeup request to the host. This signals to the host that the device should
|
||||
* be taken out of suspended mode, and communications should resume.
|
||||
*
|
||||
* Typically, this is implemented so that HID devices (mice, keyboards, etc.) can wake up the
|
||||
* host computer when the host has suspended all USB devices to enter a low power state.
|
||||
*
|
||||
* \note This macro should only be used if the device has indicated to the host that it
|
||||
* supports the Remote Wakeup feature in the device descriptors, and should only be
|
||||
* issued if the host is currently allowing remote wakeup events from the device (i.e.,
|
||||
* the USB_RemoteWakeupEnabled flag is set, see DevChapter9.h documentation).
|
||||
*
|
||||
* \see StdDescriptors.h for more information on the RMWAKEUP feature and device descriptors.
|
||||
*/
|
||||
#define USB_Device_SendRemoteWakeup() MACROS{ UDCON |= (1 << RMWKUP); }MACROE
|
||||
|
||||
/** Indicates if a Remote Wakeup request is being sent to the host. This returns true if a
|
||||
* remote wakeup is currently being sent, false otherwise.
|
||||
*
|
||||
* This can be used in conjunction with the USB_Device_IsUSBSuspended() macro to determine if
|
||||
* a sent RMWAKEUP request was accepted or rejected by the host.
|
||||
*
|
||||
* \note This macro should only be used if the device has indicated to the host that it
|
||||
* supports the Remote Wakeup feature in the device descriptors.
|
||||
*
|
||||
* \see StdDescriptors.h for more information on the RMWAKEUP feature and device descriptors.
|
||||
*/
|
||||
#define USB_Device_IsRemoteWakeupSent() ((UDCON & (1 << RMWKUP)) ? false : true)
|
||||
|
||||
/** Indicates if the device is currently suspended by the host. While suspended, the device is
|
||||
* to enter a low power state until resumed by the host. While suspended no USB traffic to or
|
||||
* from the device can ocurr (except for Remote Wakeup requests).
|
||||
*
|
||||
* This macro returns true if the USB communications have been suspended by the host, false
|
||||
* otherwise.
|
||||
*/
|
||||
#define USB_Device_IsUSBSuspended() ((UDINT & (1 << SUSPI)) ? true : false)
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the ErrorCode parameter of the USB_DeviceError event.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
enum USB_Device_ErrorCodes_t
|
||||
{
|
||||
DEVICE_ERROR_GetDescriptorNotHooked = 0, /**< Indicates that the GetDescriptor() method
|
||||
* has not been hooked by the user application.
|
||||
*
|
||||
* \see StdDescriptors.h for more information on
|
||||
* the GetDescriptor() method.
|
||||
*/
|
||||
};
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define USB_Device_SetLowSpeed() MACROS{ UDCON |= (1 << LSM); }MACROE
|
||||
#define USB_Device_SetHighSpeed() MACROS{ UDCON &= ~(1 << LSM); }MACROE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
387
LUFA/Drivers/USB/LowLevel/Endpoint.c
Normal file
387
LUFA/Drivers/USB/LowLevel/Endpoint.c
Normal file
|
|
@ -0,0 +1,387 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#include "USBMode.h"
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
|
||||
#define INCLUDE_FROM_ENDPOINT_C
|
||||
#include "Endpoint.h"
|
||||
|
||||
#if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
|
||||
uint8_t USB_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
|
||||
#endif
|
||||
|
||||
#if !defined(STATIC_ENDPOINT_CONFIGURATION)
|
||||
bool Endpoint_ConfigureEndpoint(const uint8_t Number, const uint8_t Type, const uint8_t Direction,
|
||||
const uint16_t Size, const uint8_t Banks)
|
||||
{
|
||||
Endpoint_SelectEndpoint(Number);
|
||||
Endpoint_EnableEndpoint();
|
||||
|
||||
UECFG1X = 0;
|
||||
|
||||
UECFG0X = ((Type << EPTYPE0) | Direction);
|
||||
UECFG1X = ((1 << ALLOC) | Banks | Endpoint_BytesToEPSizeMask(Size));
|
||||
|
||||
return Endpoint_IsConfigured();
|
||||
}
|
||||
#else
|
||||
bool Endpoint_ConfigureEndpointStatic(const uint8_t Number, const uint8_t UECFG0XData, const uint8_t UECFG1XData)
|
||||
{
|
||||
Endpoint_SelectEndpoint(Number);
|
||||
Endpoint_EnableEndpoint();
|
||||
|
||||
UECFG1X = 0;
|
||||
|
||||
UECFG0X = UECFG0XData;
|
||||
UECFG1X = UECFG1XData;
|
||||
|
||||
return Endpoint_IsConfigured();
|
||||
}
|
||||
#endif
|
||||
|
||||
void Endpoint_ClearEndpoints(void)
|
||||
{
|
||||
UEINT = 0;
|
||||
|
||||
for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
|
||||
{
|
||||
Endpoint_SelectEndpoint(EPNum);
|
||||
UEIENX = 0;
|
||||
UEINTX = 0;
|
||||
Endpoint_DeallocateMemory();
|
||||
Endpoint_DisableEndpoint();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Endpoint_WaitUntilReady(void)
|
||||
{
|
||||
uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
|
||||
|
||||
USB_INT_Clear(USB_INT_SOFI);
|
||||
|
||||
while (!(Endpoint_ReadWriteAllowed()))
|
||||
{
|
||||
if (!(USB_IsConnected))
|
||||
return ENDPOINT_READYWAIT_DeviceDisconnected;
|
||||
else if (Endpoint_IsStalled())
|
||||
return ENDPOINT_READYWAIT_EndpointStalled;
|
||||
|
||||
if (USB_INT_HasOccurred(USB_INT_SOFI))
|
||||
{
|
||||
USB_INT_Clear(USB_INT_SOFI);
|
||||
|
||||
if (!(TimeoutMSRem--))
|
||||
return ENDPOINT_READYWAIT_Timeout;
|
||||
}
|
||||
}
|
||||
|
||||
return ENDPOINT_READYWAIT_NoError;
|
||||
}
|
||||
|
||||
uint8_t Endpoint_Discard_Stream(uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
|
||||
while (Length--)
|
||||
{
|
||||
if (!(Endpoint_ReadWriteAllowed()))
|
||||
{
|
||||
Endpoint_ClearCurrentBank();
|
||||
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
|
||||
return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
|
||||
#endif
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Endpoint_Discard_Byte();
|
||||
}
|
||||
|
||||
return ENDPOINT_RWSTREAM_ERROR_NoError;
|
||||
}
|
||||
|
||||
uint8_t Endpoint_Write_Stream_LE(const void* Buffer, uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
uint8_t* DataStream = (uint8_t*)Buffer;
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
|
||||
while (Length--)
|
||||
{
|
||||
if (!(Endpoint_ReadWriteAllowed()))
|
||||
{
|
||||
Endpoint_ClearCurrentBank();
|
||||
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
|
||||
return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
|
||||
#endif
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Endpoint_Write_Byte(*(DataStream++));
|
||||
}
|
||||
|
||||
return ENDPOINT_RWSTREAM_ERROR_NoError;
|
||||
}
|
||||
|
||||
uint8_t Endpoint_Write_Stream_BE(const void* Buffer, uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
|
||||
while (Length--)
|
||||
{
|
||||
if (!(Endpoint_ReadWriteAllowed()))
|
||||
{
|
||||
Endpoint_ClearCurrentBank();
|
||||
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
|
||||
return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
|
||||
#endif
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Endpoint_Write_Byte(*(DataStream--));
|
||||
}
|
||||
|
||||
return ENDPOINT_RWSTREAM_ERROR_NoError;
|
||||
}
|
||||
|
||||
uint8_t Endpoint_Read_Stream_LE(void* Buffer, uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
uint8_t* DataStream = (uint8_t*)Buffer;
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
|
||||
while (Length--)
|
||||
{
|
||||
if (!(Endpoint_ReadWriteAllowed()))
|
||||
{
|
||||
Endpoint_ClearCurrentBank();
|
||||
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
|
||||
return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
|
||||
#endif
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
*(DataStream++) = Endpoint_Read_Byte();
|
||||
}
|
||||
|
||||
return ENDPOINT_RWSTREAM_ERROR_NoError;
|
||||
}
|
||||
|
||||
uint8_t Endpoint_Read_Stream_BE(void* Buffer, uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
|
||||
while (Length--)
|
||||
{
|
||||
if (!(Endpoint_ReadWriteAllowed()))
|
||||
{
|
||||
Endpoint_ClearCurrentBank();
|
||||
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
|
||||
return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
|
||||
#endif
|
||||
|
||||
if ((ErrorCode = Endpoint_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
*(DataStream--) = Endpoint_Read_Byte();
|
||||
}
|
||||
|
||||
return ENDPOINT_RWSTREAM_ERROR_NoError;
|
||||
}
|
||||
|
||||
uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length)
|
||||
{
|
||||
uint8_t* DataStream = (uint8_t*)Buffer;
|
||||
bool SendZLP = true;
|
||||
|
||||
while (Length && !(Endpoint_IsSetupOUTReceived()))
|
||||
{
|
||||
while (!(Endpoint_IsSetupINReady()));
|
||||
|
||||
while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
|
||||
{
|
||||
Endpoint_Write_Byte(*(DataStream++));
|
||||
|
||||
Length--;
|
||||
}
|
||||
|
||||
SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
|
||||
Endpoint_ClearSetupIN();
|
||||
}
|
||||
|
||||
if (Endpoint_IsSetupOUTReceived())
|
||||
return ENDPOINT_RWCSTREAM_ERROR_HostAborted;
|
||||
|
||||
if (SendZLP)
|
||||
{
|
||||
while (!(Endpoint_IsSetupINReady()));
|
||||
Endpoint_ClearSetupIN();
|
||||
}
|
||||
|
||||
while (!(Endpoint_IsSetupOUTReceived()));
|
||||
|
||||
return ENDPOINT_RWCSTREAM_ERROR_NoError;
|
||||
}
|
||||
|
||||
uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer, uint16_t Length)
|
||||
{
|
||||
uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
|
||||
bool SendZLP = true;
|
||||
|
||||
while (Length && !(Endpoint_IsSetupOUTReceived()))
|
||||
{
|
||||
while (!(Endpoint_IsSetupINReady()));
|
||||
|
||||
while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
|
||||
{
|
||||
Endpoint_Write_Byte(*(DataStream--));
|
||||
|
||||
Length--;
|
||||
}
|
||||
|
||||
SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
|
||||
Endpoint_ClearSetupIN();
|
||||
}
|
||||
|
||||
if (Endpoint_IsSetupOUTReceived())
|
||||
return ENDPOINT_RWCSTREAM_ERROR_HostAborted;
|
||||
|
||||
if (SendZLP)
|
||||
{
|
||||
while (!(Endpoint_IsSetupINReady()));
|
||||
Endpoint_ClearSetupIN();
|
||||
}
|
||||
|
||||
while (!(Endpoint_IsSetupOUTReceived()));
|
||||
|
||||
return ENDPOINT_RWCSTREAM_ERROR_NoError;
|
||||
}
|
||||
|
||||
uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer, uint16_t Length)
|
||||
{
|
||||
uint8_t* DataStream = (uint8_t*)Buffer;
|
||||
|
||||
while (Length)
|
||||
{
|
||||
while (!(Endpoint_IsSetupOUTReceived()));
|
||||
|
||||
while (Length && Endpoint_BytesInEndpoint())
|
||||
{
|
||||
*(DataStream++) = Endpoint_Read_Byte();
|
||||
|
||||
Length--;
|
||||
}
|
||||
|
||||
Endpoint_ClearSetupOUT();
|
||||
}
|
||||
|
||||
while (!(Endpoint_IsSetupINReady()));
|
||||
|
||||
return ENDPOINT_RWCSTREAM_ERROR_NoError;
|
||||
}
|
||||
|
||||
uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer, uint16_t Length)
|
||||
{
|
||||
uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
|
||||
|
||||
while (Length)
|
||||
{
|
||||
while (!(Endpoint_IsSetupOUTReceived()));
|
||||
|
||||
while (Length && Endpoint_BytesInEndpoint())
|
||||
{
|
||||
*(DataStream--) = Endpoint_Read_Byte();
|
||||
|
||||
Length--;
|
||||
}
|
||||
|
||||
Endpoint_ClearSetupOUT();
|
||||
}
|
||||
|
||||
while (!(Endpoint_IsSetupINReady()));
|
||||
|
||||
return ENDPOINT_RWCSTREAM_ERROR_NoError;
|
||||
}
|
||||
|
||||
#endif
|
||||
842
LUFA/Drivers/USB/LowLevel/Endpoint.h
Normal file
842
LUFA/Drivers/USB/LowLevel/Endpoint.h
Normal file
|
|
@ -0,0 +1,842 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Functions, macros and enums related to endpoint management when in USB Device mode. This
|
||||
* module contains the endpoint management macros, as well as endpoint interrupt and data
|
||||
* send/recieve functions for various datatypes.
|
||||
*/
|
||||
|
||||
#ifndef __ENDPOINT_H__
|
||||
#define __ENDPOINT_H__
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../../../Common/Common.h"
|
||||
#include "../HighLevel/USBTask.h"
|
||||
|
||||
#if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
|
||||
#include "StreamCallbacks.h"
|
||||
#endif
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Endpoint data direction mask for 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
|
||||
|
||||
/** Endpoint data direction mask for 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)
|
||||
|
||||
/** Mask for the bank mode selection for the Endpoint_ConfigureEndpoint() macro. This indicates
|
||||
* that the endpoint should have one single bank, which requires less USB FIFO memory but results
|
||||
* 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
|
||||
|
||||
/** Mask for the bank mode selection for the 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)
|
||||
|
||||
/** Endpoint address for the default control endpoint, which always resides in address 0. This is
|
||||
* defined for convenience to give more readable code when used with the endpoint macros.
|
||||
*/
|
||||
#define ENDPOINT_CONTROLEP 0
|
||||
|
||||
/** Default size of the default control endpoint's bank, until altered by the Endpoint0Size value
|
||||
* in the device descriptor. Not available if the FIXED_CONTROL_ENDPOINT_SIZE token is defined.
|
||||
*/
|
||||
#if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))
|
||||
#define ENDPOINT_CONTROLEP_DEFAULT_SIZE 8
|
||||
#endif
|
||||
|
||||
/** Endpoint number mask, for masking against endpoint addresses to retrieve the endpoint's
|
||||
* numerical address in the device.
|
||||
*/
|
||||
#define ENDPOINT_EPNUM_MASK 0b111
|
||||
|
||||
/** Endpoint bank size mask, for masking against endpoint addresses to retrieve the endpoint's
|
||||
* bank size in the device.
|
||||
*/
|
||||
#define ENDPOINT_EPSIZE_MASK 0x7FF
|
||||
|
||||
/** Maximum size in bytes of a given endpoint.
|
||||
*
|
||||
* \param n Endpoint number, a value between 0 and (ENDPOINT_TOTAL_ENDPOINTS - 1)
|
||||
*/
|
||||
#define ENDPOINT_MAX_SIZE(n) _ENDPOINT_GET_MAXSIZE(n)
|
||||
|
||||
/** Indicates if the given endpoint supports double banking.
|
||||
*
|
||||
* \param n Endpoint number, a value between 0 and (ENDPOINT_TOTAL_ENDPOINTS - 1)
|
||||
*/
|
||||
#define ENDPOINT_DOUBLEBANK_SUPPORTED(n) _ENDPOINT_GET_DOUBLEBANK(n)
|
||||
|
||||
#if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER) || defined(__DOXYGEN__)
|
||||
/** Total number of endpoints (including the default control endpoint at address 0) which may
|
||||
* be used in the device. Different USB AVR models support different amounts of endpoints,
|
||||
* this value reflects the maximum number of endpoints for the currently selected AVR model.
|
||||
*/
|
||||
#define ENDPOINT_TOTAL_ENDPOINTS 7
|
||||
#else
|
||||
#define ENDPOINT_TOTAL_ENDPOINTS 5
|
||||
#endif
|
||||
|
||||
/** Interrupt definition for the endpoint SETUP interrupt (for CONTROL type endpoints). Should be
|
||||
* used with the USB_INT_* macros located in USBInterrupt.h.
|
||||
*
|
||||
* This interrupt will fire if enabled on a CONTROL type endpoint if a new control packet is
|
||||
* received from the host.
|
||||
*/
|
||||
#define ENDPOINT_INT_SETUP UEIENX, (1 << RXSTPE), UEINTX, (1 << RXSTPI)
|
||||
|
||||
/** Interrupt definition for the endpoint IN interrupt (for INTERRUPT type endpoints). Should be
|
||||
* used with the USB_INT_* macros located in USBInterrupt.h.
|
||||
*
|
||||
* This interrupt will fire if enabled on an INTERRUPT type endpoint if a the endpoint interrupt
|
||||
* period has elapsed and the endpoint is ready for a new packet to be written to its FIFO buffer
|
||||
* (if required).
|
||||
*/
|
||||
#define ENDPOINT_INT_IN UEIENX, (1 << TXINE) , UEINTX, (1 << TXINI)
|
||||
|
||||
/** Interrupt definition for the endpoint OUT interrupt (for INTERRUPT type endpoints). Should be
|
||||
* used with the USB_INT_* macros located in USBInterrupt.h.
|
||||
*
|
||||
* This interrupt will fire if enabled on an INTERRUPT type endpoint if a the endpoint interrupt
|
||||
* period has elapsed and the endpoint is ready for a packet from the host to be read from its
|
||||
* FIFO buffer (if received).
|
||||
*/
|
||||
#define ENDPOINT_INT_OUT UEIENX, (1 << RXOUTE), UEINTX, (1 << RXOUTI)
|
||||
|
||||
#if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER) || defined(__DOXYGEN__)
|
||||
/** Indicates the number of bytes currently stored in the current endpoint's selected bank. */
|
||||
#define Endpoint_BytesInEndpoint() UEBCX
|
||||
#else
|
||||
#define Endpoint_BytesInEndpoint() UEBCLX
|
||||
#endif
|
||||
|
||||
/** Returns the endpoint address of the currently selected endpoint. This is typically used to save
|
||||
* the currently selected endpoint number so that it can be restored after another endpoint has
|
||||
* been manipulated.
|
||||
*/
|
||||
#define Endpoint_GetCurrentEndpoint() (UENUM & ENDPOINT_EPNUM_MASK)
|
||||
|
||||
/** Selects the given endpoint number. If the address from the device descriptors is used, the
|
||||
* value should be masked with the ENDPOINT_EPNUM_MASK constant to extract only the endpoint
|
||||
* number (and discarding the endpoint direction bit).
|
||||
*
|
||||
* Any endpoint operations which do not require the endpoint number to be indicated will operate on
|
||||
* the currently selected endpoint.
|
||||
*/
|
||||
#define Endpoint_SelectEndpoint(epnum) MACROS{ UENUM = epnum; }MACROE
|
||||
|
||||
/** Resets the endpoint bank FIFO. This clears all the endpoint banks and resets the USB controller's
|
||||
* In and Out pointers to the bank's contents.
|
||||
*/
|
||||
#define Endpoint_ResetFIFO(epnum) MACROS{ UERST = (1 << epnum); UERST = 0; }MACROE
|
||||
|
||||
/** Enables the currently selected endpoint so that data can be sent and received through it to
|
||||
* and from a host.
|
||||
*
|
||||
* \note Endpoints must first be configured properly rather than just being enabled via the
|
||||
* Endpoint_ConfigureEndpoint() macro, which calls Endpoint_EnableEndpoint() automatically.
|
||||
*/
|
||||
#define Endpoint_EnableEndpoint() MACROS{ UECONX |= (1 << EPEN); }MACROE
|
||||
|
||||
/** Disables the currently selected endpoint so that data cannot be sent and received through it
|
||||
* to and from a host.
|
||||
*/
|
||||
#define Endpoint_DisableEndpoint() MACROS{ UECONX &= ~(1 << EPEN); }MACROE
|
||||
|
||||
/** Returns true if the currently selected endpoint is enabled, false otherwise. */
|
||||
#define Endpoint_IsEnabled() ((UECONX & (1 << EPEN)) ? true : false)
|
||||
|
||||
/** Returns true if the currently selected endpoint may be read from (if data is waiting in the endpoint
|
||||
* bank and the endpoint is an OUT direction, or if the bank is not yet full if the endpoint is an
|
||||
* IN direction). This function will return false if an error has occured in the endpoint, or if
|
||||
* the endpoint is an OUT direction and no packet has been received, or if the endpoint is an IN
|
||||
* direction and the endpoint bank is full.
|
||||
*/
|
||||
#define Endpoint_ReadWriteAllowed() ((UEINTX & (1 << RWAL)) ? true : false)
|
||||
|
||||
/** Returns true if the currently selected endpoint is configured, false otherwise. */
|
||||
#define Endpoint_IsConfigured() ((UESTA0X & (1 << CFGOK)) ? true : false)
|
||||
|
||||
/** Returns a mask indicating which INTERRUPT type endpoints have interrupted - i.e. their
|
||||
* interrupt duration has elapsed. Which endpoints have interrupted can be determined by
|
||||
* masking the return value against (1 << {Endpoint Number}).
|
||||
*/
|
||||
#define Endpoint_GetEndpointInterrupts() UEINT
|
||||
|
||||
/** Clears the endpoint interrupt flag. This clears the specified endpoint number's interrupt
|
||||
* mask in the endpoint interrupt flag register.
|
||||
*/
|
||||
#define Endpoint_ClearEndpointInterrupt(n) MACROS{ UEINT &= ~(1 << n); }MACROE
|
||||
|
||||
/** Returns true if the specified endpoint number has interrupted (valid only for INTERRUPT type
|
||||
* endpoints), false otherwise.
|
||||
*/
|
||||
#define Endpoint_HasEndpointInterrupted(n) ((UEINT & (1 << n)) ? true : false)
|
||||
|
||||
/** Clears the currently selected endpoint bank, and switches to the alternate bank if the currently
|
||||
* selected endpoint is dual-banked. When cleared, this either frees the bank up for the next packet
|
||||
* from the host (if the endpoint is of the OUT direction) or sends the packet contents to the host
|
||||
* (if the endpoint is of the IN direction).
|
||||
*/
|
||||
#define Endpoint_ClearCurrentBank() MACROS{ UEINTX &= ~(1 << FIFOCON); }MACROE
|
||||
|
||||
/** Returns true if the current CONTROL type endpoint is ready for an IN packet, false otherwise. */
|
||||
#define Endpoint_IsSetupINReady() ((UEINTX & (1 << TXINI)) ? true : false)
|
||||
|
||||
/** Returns true if the current CONTROL type endpoint is ready for an OUT packet, false otherwise. */
|
||||
#define Endpoint_IsSetupOUTReceived() ((UEINTX & (1 << RXOUTI)) ? true : false)
|
||||
|
||||
/** Returns true if the current CONTROL type endpoint is ready for a SETUP packet, false otherwise. */
|
||||
#define Endpoint_IsSetupReceived() ((UEINTX & (1 << RXSTPI)) ? true : false)
|
||||
|
||||
/** Clears a received SETUP packet on the currently selected CONTROL type endpoint. */
|
||||
#define Endpoint_ClearSetupReceived() MACROS{ UEINTX &= ~(1 << RXSTPI); }MACROE
|
||||
|
||||
/** Sends an IN packet to the host on the currently selected CONTROL type endpoint. */
|
||||
#define Endpoint_ClearSetupIN() MACROS{ UEINTX &= ~(1 << TXINI); }MACROE
|
||||
|
||||
/** Acknowedges an OUT packet to the host on the currently selected CONTROL type endpoint, freeing
|
||||
* up the endpoint for the next packet.
|
||||
*/
|
||||
#define Endpoint_ClearSetupOUT() MACROS{ UEINTX &= ~(1 << RXOUTI); }MACROE
|
||||
|
||||
/** Stalls the current endpoint, indicating to the host that a logical problem occured with the
|
||||
* indicated endpoint and that the current transfer sequence should be aborted. This provides a
|
||||
* way for devices to indicate invalid commands to the host so that the current transfer can be
|
||||
* aborted and the host can begin its own recovery seqeuence.
|
||||
*
|
||||
* The currently selected endpoint remains stalled until either the Endpoint_ClearStall() macro
|
||||
* is called, or the host issues a CLEAR FEATURE request to the device for the currently selected
|
||||
* endpoint.
|
||||
*/
|
||||
#define Endpoint_StallTransaction() MACROS{ UECONX |= (1 << STALLRQ); }MACROE
|
||||
|
||||
/** Clears the stall on the currently selected endpoint. */
|
||||
#define Endpoint_ClearStall() MACROS{ UECONX |= (1 << STALLRQC); }MACROE
|
||||
|
||||
/** Returns true if the currently selected endpoint is stalled, false othewise. */
|
||||
#define Endpoint_IsStalled() ((UECONX & (1 << STALLRQ)) ? true : false)
|
||||
|
||||
/** Resets the data toggle of the currently selected endpoint. */
|
||||
#define Endpoint_ResetDataToggle() MACROS{ UECONX |= (1 << RSTDT); }MACROE
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible error return codes of the Endpoint_WaitUntilReady function */
|
||||
enum Endpoint_WaitUntilReady_ErrorCodes_t
|
||||
{
|
||||
ENDPOINT_READYWAIT_NoError = 0, /**< Endpoint is ready for next packet, no error. */
|
||||
ENDPOINT_READYWAIT_EndpointStalled = 1, /**< The endpoint was stalled during the stream
|
||||
* transfer by the host or device.
|
||||
*/
|
||||
ENDPOINT_READYWAIT_DeviceDisconnected = 2, /**< Device was disconnected from the host while
|
||||
* waiting for the endpoint to become ready.
|
||||
*/
|
||||
ENDPOINT_READYWAIT_Timeout = 3, /**< The host failed to accept or send the next packet
|
||||
* within the software timeout period set by the
|
||||
* USB_STREAM_TIMEOUT_MS macro.
|
||||
*/
|
||||
};
|
||||
|
||||
/** Enum for the possible error return codes of the Endpoint_*_Stream_* functions. */
|
||||
enum Endpoint_Stream_RW_ErrorCodes_t
|
||||
{
|
||||
ENDPOINT_RWSTREAM_ERROR_NoError = 0, /**< Command completed successfully, no error. */
|
||||
ENDPOINT_RWSTREAM_ERROR_EndpointStalled = 1, /**< The endpoint was stalled during the stream
|
||||
* transfer by the host or device.
|
||||
*/
|
||||
ENDPOINT_RWSTREAM_ERROR_DeviceDisconnected = 1, /**< Device was disconnected from the host during
|
||||
* the transfer.
|
||||
*/
|
||||
ENDPOINT_RWSTREAM_ERROR_Timeout = 2, /**< The host failed to accept or send the next packet
|
||||
* within the software timeout period set by the
|
||||
* USB_STREAM_TIMEOUT_MS macro.
|
||||
*/
|
||||
ENDPOINT_RWSTREAM_ERROR_CallbackAborted = 3, /**< Indicates that the stream's callback function
|
||||
* aborted the transfer early.
|
||||
*/
|
||||
};
|
||||
|
||||
/** Enum for the possible error return codes of the Endpoint_*_Control_Stream_* functions. */
|
||||
enum Endpoint_ControlStream_RW_ErrorCodes_t
|
||||
{
|
||||
ENDPOINT_RWCSTREAM_ERROR_NoError = 0, /**< Command completed successfully, no error. */
|
||||
ENDPOINT_RWCSTREAM_ERROR_HostAborted = 1, /**< The aborted the transfer prematurely. */
|
||||
};
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Reads one byte from the currently selected endpoint's bank, for OUT direction endpoints. */
|
||||
static inline uint8_t Endpoint_Read_Byte(void) ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint8_t Endpoint_Read_Byte(void)
|
||||
{
|
||||
return UEDATX;
|
||||
}
|
||||
|
||||
/** Writes one byte from the currently selected endpoint's bank, for IN direction endpoints. */
|
||||
static inline void Endpoint_Write_Byte(const uint8_t Byte)
|
||||
{
|
||||
UEDATX = Byte;
|
||||
}
|
||||
|
||||
/** Discards one byte from the currently selected endpoint's bank, for OUT direction endpoints. */
|
||||
static inline void Endpoint_Discard_Byte(void)
|
||||
{
|
||||
uint8_t Dummy;
|
||||
|
||||
Dummy = UEDATX;
|
||||
}
|
||||
|
||||
/** Reads two bytes from the currently selected endpoint's bank in little endian format, for OUT
|
||||
* direction endpoints.
|
||||
*/
|
||||
static inline uint16_t Endpoint_Read_Word_LE(void) ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint16_t Endpoint_Read_Word_LE(void)
|
||||
{
|
||||
uint16_t Data;
|
||||
|
||||
Data = UEDATX;
|
||||
Data |= (((uint16_t)UEDATX) << 8);
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
/** Reads two bytes from the currently selected endpoint's bank in big endian format, for OUT
|
||||
* direction endpoints.
|
||||
*/
|
||||
static inline uint16_t Endpoint_Read_Word_BE(void) ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint16_t Endpoint_Read_Word_BE(void)
|
||||
{
|
||||
uint16_t Data;
|
||||
|
||||
Data = (((uint16_t)UEDATX) << 8);
|
||||
Data |= UEDATX;
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
/** Writes two bytes to the currently selected endpoint's bank in little endian format, for IN
|
||||
* direction endpoints.
|
||||
*/
|
||||
static inline void Endpoint_Write_Word_LE(const uint16_t Word)
|
||||
{
|
||||
UEDATX = (Word & 0xFF);
|
||||
UEDATX = (Word >> 8);
|
||||
}
|
||||
|
||||
/** Writes two bytes to the currently selected endpoint's bank in big endian format, for IN
|
||||
* direction endpoints.
|
||||
*/
|
||||
static inline void Endpoint_Write_Word_BE(const uint16_t Word)
|
||||
{
|
||||
UEDATX = (Word >> 8);
|
||||
UEDATX = (Word & 0xFF);
|
||||
}
|
||||
|
||||
/** Discards two bytes from the currently selected endpoint's bank, for OUT direction endpoints. */
|
||||
static inline void Endpoint_Discard_Word(void)
|
||||
{
|
||||
uint8_t Dummy;
|
||||
|
||||
Dummy = UEDATX;
|
||||
Dummy = UEDATX;
|
||||
}
|
||||
|
||||
/** Reads four bytes from the currently selected endpoint's bank in little endian format, for OUT
|
||||
* direction endpoints.
|
||||
*/
|
||||
static inline uint32_t Endpoint_Read_DWord_LE(void) ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint32_t Endpoint_Read_DWord_LE(void)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t DWord;
|
||||
uint8_t Bytes[4];
|
||||
} Data;
|
||||
|
||||
Data.Bytes[0] = UEDATX;
|
||||
Data.Bytes[1] = UEDATX;
|
||||
Data.Bytes[2] = UEDATX;
|
||||
Data.Bytes[3] = UEDATX;
|
||||
|
||||
return Data.DWord;
|
||||
}
|
||||
|
||||
/** Reads four bytes from the currently selected endpoint's bank in big endian format, for OUT
|
||||
* direction endpoints.
|
||||
*/
|
||||
static inline uint32_t Endpoint_Read_DWord_BE(void) ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint32_t Endpoint_Read_DWord_BE(void)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t DWord;
|
||||
uint8_t Bytes[4];
|
||||
} Data;
|
||||
|
||||
Data.Bytes[3] = UEDATX;
|
||||
Data.Bytes[2] = UEDATX;
|
||||
Data.Bytes[1] = UEDATX;
|
||||
Data.Bytes[0] = UEDATX;
|
||||
|
||||
return Data.DWord;
|
||||
}
|
||||
|
||||
/** Writes four bytes to the currently selected endpoint's bank in little endian format, for IN
|
||||
* direction endpoints.
|
||||
*/
|
||||
static inline void Endpoint_Write_DWord_LE(const uint32_t DWord)
|
||||
{
|
||||
Endpoint_Write_Word_LE(DWord);
|
||||
Endpoint_Write_Word_LE(DWord >> 16);
|
||||
}
|
||||
|
||||
/** Writes four bytes to the currently selected endpoint's bank in big endian format, for IN
|
||||
* direction endpoints.
|
||||
*/
|
||||
static inline void Endpoint_Write_DWord_BE(const uint32_t DWord)
|
||||
{
|
||||
Endpoint_Write_Word_BE(DWord >> 16);
|
||||
Endpoint_Write_Word_BE(DWord);
|
||||
}
|
||||
|
||||
/** Discards four bytes from the currently selected endpoint's bank, for OUT direction endpoints. */
|
||||
static inline void Endpoint_Discard_DWord(void)
|
||||
{
|
||||
uint8_t Dummy;
|
||||
|
||||
Dummy = UEDATX;
|
||||
Dummy = UEDATX;
|
||||
Dummy = UEDATX;
|
||||
Dummy = UEDATX;
|
||||
}
|
||||
|
||||
/* External Variables: */
|
||||
/** Global indicating the maximum packet size of the default control endpoint located at address
|
||||
* 0 in the device. This value is set to the value indicated in the device descriptor in the user
|
||||
* project once the USB interface is initialized into device mode.
|
||||
*
|
||||
* If space is an issue, it is possible to fix this to a static value by defining the control
|
||||
* endpoint size in the FIXED_CONTROL_ENDPOINT_SIZE token passed to the compiler in the makefile
|
||||
* via the -D switch. When a fixed control endpoint size is used, the size is no longer dynamically
|
||||
* read from the descriptors at runtime and instead fixed to the given value. When used, it is
|
||||
* important that the descriptor control endpoint size value matches the size given as the
|
||||
* FIXED_CONTROL_ENDPOINT_SIZE token - it is recommended that the FIXED_CONTROL_ENDPOINT_SIZE token
|
||||
* be used in the descriptors to ensure this.
|
||||
*
|
||||
* \note This variable should be treated as read-only in the user application, and never manually
|
||||
* changed in value.
|
||||
*/
|
||||
#if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))
|
||||
extern uint8_t USB_ControlEndpointSize;
|
||||
#else
|
||||
#define USB_ControlEndpointSize FIXED_CONTROL_ENDPOINT_SIZE
|
||||
#endif
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the specified endpoint number with the given endpoint type, direction, bank size
|
||||
* and banking mode. Endpoints should be allocated in ascending order by their address in the
|
||||
* device (i.e. endpoint 1 should be configured before endpoint 2 and so on).
|
||||
*
|
||||
* The endpoint type may be one of the EP_TYPE_* macros listed in LowLevel.h and the direction
|
||||
* may be either ENDPOINT_DIR_OUT or ENDPOINT_DIR_IN.
|
||||
*
|
||||
* The bank size must indicate the maximum packet size that the endpoint can handle. Different
|
||||
* endpoint numbers can handle different maximum packet sizes - refer to the chosen USB AVR's
|
||||
* datasheet to determine the maximum bank size for each endpoint.
|
||||
*
|
||||
* The banking mode may be either ENDPOINT_BANK_SINGLE or ENDPOINT_BANK_DOUBLE.
|
||||
*
|
||||
* The success of this routine can be determined via the Endpoint_IsConfigured() macro.
|
||||
*
|
||||
* By default, the routine is entirely dynamic, and will accept both constant and variable inputs.
|
||||
* If dynamic configuration is unused, a small space savings can be made by defining the
|
||||
* STATIC_ENDPOINT_CONFIGURATION macro via the -D switch to the compiler, to optimize for constant
|
||||
* input values.
|
||||
*
|
||||
* \note This routine will select the specified endpoint, and the endpoint will remain selected
|
||||
* once the routine completes regardless of if the endpoint configuration succeeds.
|
||||
*
|
||||
* \return Boolean true if the configuration succeeded, false otherwise
|
||||
*/
|
||||
bool Endpoint_ConfigureEndpoint(const uint8_t Number, const uint8_t Type, const uint8_t Direction,
|
||||
const uint16_t Size, const uint8_t Banks);
|
||||
|
||||
/** Spinloops until the currently selected non-control endpoint is ready for the next packet of data
|
||||
* to be read or written to it.
|
||||
*
|
||||
* \note This routine should not be called on CONTROL type endpoints.
|
||||
*
|
||||
* \return A value from the Endpoint_WaitUntilReady_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_WaitUntilReady(void);
|
||||
|
||||
/** Reads and discards the given number of bytes from the endpoint from the given buffer,
|
||||
* discarding fully read packets from the host as needed. The last packet is not automatically
|
||||
* discarded once the remaining bytes has been read; the user is responsible for manually
|
||||
* discarding the last packet from the host via the Endpoint_ClearCurrentBank() macro. Between
|
||||
* each USB packet, the given stream callback function is executed repeatedly until the next
|
||||
* packet is ready, allowing for early aborts of stream transfers.
|
||||
*
|
||||
* The callback routine should be created using the STREAM_CALLBACK() macro. If the token
|
||||
* NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are disabled
|
||||
* and this function has the Callback parameter ommitted.
|
||||
*
|
||||
* \note This routine should not be used on CONTROL type endpoints.
|
||||
*
|
||||
* \param Length Number of bytes to send via the currently selected endpoint.
|
||||
* \param Callback Name of a callback routine to call between sucessive USB packet transfers, NULL if no callback
|
||||
*
|
||||
* \return A value from the Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Discard_Stream(uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
);
|
||||
|
||||
/** Writes the given number of bytes to the endpoint from the given buffer in little endian,
|
||||
* sending full packets to the host as needed. The last packet filled is not automatically sent;
|
||||
* the user is responsible for manually sending the last written packet to the host via the
|
||||
* Endpoint_ClearCurrentBank() macro. Between each USB packet, the given stream callback function
|
||||
* is executed repeatedly until the endpoint is ready to accept the next packet, allowing for early
|
||||
* aborts of stream transfers.
|
||||
*
|
||||
* The callback routine should be created using the STREAM_CALLBACK() macro. If the token
|
||||
* NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are disabled
|
||||
* and this function has the Callback parameter ommitted.
|
||||
*
|
||||
* \note This routine should not be used on CONTROL type endpoints.
|
||||
*
|
||||
* \param Buffer Pointer to the source data buffer to read from.
|
||||
* \param Length Number of bytes to read for the currently selected endpoint into the buffer.
|
||||
* \param Callback Name of a callback routine to call between sucessive USB packet transfers, NULL if no callback
|
||||
*
|
||||
* \return A value from the Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Write_Stream_LE(const void* Buffer, uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Writes the given number of bytes to the endpoint from the given buffer in big endian,
|
||||
* sending full packets to the host as needed. The last packet filled is not automatically sent;
|
||||
* the user is responsible for manually sending the last written packet to the host via the
|
||||
* Endpoint_ClearCurrentBank() macro. Between each USB packet, the given stream callback function
|
||||
* is executed repeatedly until the endpoint is ready to accept the next packet, allowing for early
|
||||
* aborts of stream transfers.
|
||||
*
|
||||
* The callback routine should be created using the STREAM_CALLBACK() macro. If the token
|
||||
* NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are disabled
|
||||
* and this function has the Callback parameter ommitted.
|
||||
*
|
||||
* \note This routine should not be used on CONTROL type endpoints.
|
||||
*
|
||||
* \param Buffer Pointer to the source data buffer to read from.
|
||||
* \param Length Number of bytes to read for the currently selected endpoint into the buffer.
|
||||
* \param Callback Name of a callback routine to call between sucessive USB packet transfers, NULL if no callback
|
||||
*
|
||||
* \return A value from the Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Write_Stream_BE(const void* Buffer, uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Reads the given number of bytes from the endpoint from the given buffer in little endian,
|
||||
* discarding fully read packets from the host as needed. The last packet is not automatically
|
||||
* discarded once the remaining bytes has been read; the user is responsible for manually
|
||||
* discarding the last packet from the host via the Endpoint_ClearCurrentBank() macro. Between
|
||||
* each USB packet, the given stream callback function is executed repeatedly until the endpoint
|
||||
* is ready to accept the next packet, allowing for early aborts of stream transfers.
|
||||
*
|
||||
* The callback routine should be created using the STREAM_CALLBACK() macro. If the token
|
||||
* NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are disabled
|
||||
* and this function has the Callback parameter ommitted.
|
||||
*
|
||||
* \note This routine should not be used on CONTROL type endpoints.
|
||||
*
|
||||
* \param Buffer Pointer to the destination data buffer to write to.
|
||||
* \param Length Number of bytes to send via the currently selected endpoint.
|
||||
* \param Callback Name of a callback routine to call between sucessive USB packet transfers, NULL if no callback
|
||||
*
|
||||
* \return A value from the Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Read_Stream_LE(void* Buffer, uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Reads the given number of bytes from the endpoint from the given buffer in big endian,
|
||||
* discarding fully read packets from the host as needed. The last packet is not automatically
|
||||
* discarded once the remaining bytes has been read; the user is responsible for manually
|
||||
* discarding the last packet from the host via the Endpoint_ClearCurrentBank() macro. Between
|
||||
* each USB packet, the given stream callback function is executed repeatedly until the endpoint
|
||||
* is ready to accept the next packet, allowing for early aborts of stream transfers.
|
||||
*
|
||||
* The callback routine should be created using the STREAM_CALLBACK() macro. If the token
|
||||
* NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are disabled
|
||||
* and this function has the Callback parameter ommitted.
|
||||
*
|
||||
* \note This routine should not be used on CONTROL type endpoints.
|
||||
*
|
||||
* \param Buffer Pointer to the destination data buffer to write to.
|
||||
* \param Length Number of bytes to send via the currently selected endpoint.
|
||||
* \param Callback Name of a callback routine to call between sucessive USB packet transfers, NULL if no callback
|
||||
*
|
||||
* \return A value from the Endpoint_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Read_Stream_BE(void* Buffer, uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in little endian,
|
||||
* sending full packets to the host as needed. The host OUT acknowedgement is not automatically cleared
|
||||
* in both failure and success states; the user is responsible for manually clearing the setup OUT to
|
||||
* finalize the transfer via the Endpoint_ClearSetupOUT() macro.
|
||||
*
|
||||
* \note This routine should only be used on CONTROL type endpoints.
|
||||
*
|
||||
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
|
||||
* together; i.e. the entire stream data must be read or written at the one time.
|
||||
*
|
||||
* \param Buffer Pointer to the source data buffer to read from.
|
||||
* \param Length Number of bytes to read for the currently selected endpoint into the buffer.
|
||||
*
|
||||
* \return A value from the Endpoint_ControlStream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in big endian,
|
||||
* sending full packets to the host as needed. The host OUT acknowedgement is not automatically cleared
|
||||
* in both failure and success states; the user is responsible for manually clearing the setup OUT to
|
||||
* finalize the transfer via the Endpoint_ClearSetupOUT() macro.
|
||||
*
|
||||
* \note This routine should only be used on CONTROL type endpoints.
|
||||
*
|
||||
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
|
||||
* together; i.e. the entire stream data must be read or written at the one time.
|
||||
*
|
||||
* \param Buffer Pointer to the source data buffer to read from.
|
||||
* \param Length Number of bytes to read for the currently selected endpoint into the buffer.
|
||||
*
|
||||
* \return A value from the Endpoint_ControlStream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Reads the given number of bytes from the CONTROL endpoint from the given buffer in little endian,
|
||||
* discarding fully read packets from the host as needed. The device IN acknowedgement is not
|
||||
* automatically sent after success or failure states; the user is responsible for manually sending the
|
||||
* setup IN to finalize the transfer via the Endpoint_ClearSetupIN() macro.
|
||||
*
|
||||
* \note This routine should only be used on CONTROL type endpoints.
|
||||
*
|
||||
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
|
||||
* together; i.e. the entire stream data must be read or written at the one time.
|
||||
*
|
||||
* \param Buffer Pointer to the destination data buffer to write to.
|
||||
* \param Length Number of bytes to send via the currently selected endpoint.
|
||||
*
|
||||
* \return A value from the Endpoint_ControlStream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Reads the given number of bytes from the CONTROL endpoint from the given buffer in big endian,
|
||||
* discarding fully read packets from the host as needed. The device IN acknowedgement is not
|
||||
* automatically sent after success or failure states; the user is responsible for manually sending the
|
||||
* setup IN to finalize the transfer via the Endpoint_ClearSetupIN() macro.
|
||||
*
|
||||
* \note This routine should only be used on CONTROL type endpoints.
|
||||
*
|
||||
* \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
|
||||
* together; i.e. the entire stream data must be read or written at the one time.
|
||||
*
|
||||
* \param Buffer Pointer to the destination data buffer to write to.
|
||||
* \param Length Number of bytes to send via the currently selected endpoint.
|
||||
*
|
||||
* \return A value from the Endpoint_ControlStream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/* Function Aliases: */
|
||||
/** Alias for Endpoint_Discard_Byte().
|
||||
*/
|
||||
#define Endpoint_Ignore_Byte() Endpoint_Discard_Byte()
|
||||
|
||||
/** Alias for Endpoint_Discard_Word().
|
||||
*/
|
||||
#define Endpoint_Ignore_Word() Endpoint_Discard_Word()
|
||||
|
||||
/** Alias for Endpoint_Discard_DWord().
|
||||
*/
|
||||
#define Endpoint_Ignore_DWord() Endpoint_Discard_DWord()
|
||||
|
||||
/** Alias for Endpoint_Read_Word_LE(). By default USB transfers use little endian format, thus
|
||||
* the command with no endianness specifier indicates little endian mode.
|
||||
*/
|
||||
#define Endpoint_Read_Word() Endpoint_Read_Word_LE()
|
||||
|
||||
/** Alias for Endpoint_Write_Word_LE(). By default USB transfers use little endian format, thus
|
||||
* the command with no endianness specifier indicates little endian mode.
|
||||
*/
|
||||
#define Endpoint_Write_Word(Word) Endpoint_Write_Word_LE(Word)
|
||||
|
||||
/** Alias for Endpoint_Read_DWord_LE(). By default USB transfers use little endian format, thus
|
||||
* the command with no endianness specifier indicates little endian mode.
|
||||
*/
|
||||
#define Endpoint_Read_DWord() Endpoint_Read_DWord_LE()
|
||||
|
||||
/** Alias for Endpoint_Write_DWord_LE(). By default USB transfers use little endian format, thus
|
||||
* the command with no endianness specifier indicates little endian mode.
|
||||
*/
|
||||
#define Endpoint_Write_DWord(DWord) Endpoint_Write_DWord_LE(DWord)
|
||||
|
||||
/** Alias for Endpoint_Read_Stream_LE(). By default USB transfers use little endian format, thus
|
||||
* the command with no endianness specifier indicates little endian mode.
|
||||
*/
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
#define Endpoint_Read_Stream(Buffer, Length, Callback) Endpoint_Read_Stream_LE(Buffer, Length, Callback)
|
||||
#else
|
||||
#define Endpoint_Read_Stream(Buffer, Length) Endpoint_Read_Stream_LE(Buffer, Length)
|
||||
#endif
|
||||
|
||||
/** Alias for Endpoint_Write_Stream_LE(). By default USB transfers use little endian format, thus
|
||||
* the command with no endianness specifier indicates little endian mode.
|
||||
*/
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
#define Endpoint_Write_Stream(Buffer, Length, Callback) Endpoint_Write_Stream_LE(Buffer, Length, Callback)
|
||||
#else
|
||||
#define Endpoint_Write_Stream(Buffer, Length) Endpoint_Write_Stream_LE(Buffer, Length)
|
||||
#endif
|
||||
|
||||
/** Alias for Endpoint_Read_Control_Stream_LE(). By default USB transfers use little endian format, thus
|
||||
* the command with no endianness specifier indicates little endian mode.
|
||||
*/
|
||||
#define Endpoint_Read_Control_Stream(Data, Length) Endpoint_Read_Control_Stream_LE(Data, Length)
|
||||
|
||||
/** Alias for Endpoint_Write_Control_Stream_LE(). By default USB transfers use little endian format, thus
|
||||
* the command with no endianness specifier indicates little endian mode.
|
||||
*/
|
||||
#define Endpoint_Write_Control_Stream(Data, Length) Endpoint_Write_Control_Stream_LE(Data, Length)
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define Endpoint_AllocateMemory() MACROS{ UECFG1X |= (1 << ALLOC); }MACROE
|
||||
#define Endpoint_DeallocateMemory() MACROS{ UECFG1X &= ~(1 << ALLOC); }MACROE
|
||||
|
||||
#define _ENDPOINT_GET_MAXSIZE(n) _ENDPOINT_GET_MAXSIZE2(ENDPOINT_DETAILS_EP ## n)
|
||||
#define _ENDPOINT_GET_MAXSIZE2(details) _ENDPOINT_GET_MAXSIZE3(details)
|
||||
#define _ENDPOINT_GET_MAXSIZE3(maxsize, db) maxsize
|
||||
|
||||
#define _ENDPOINT_GET_DOUBLEBANK(n) _ENDPOINT_GET_DOUBLEBANK2(ENDPOINT_DETAILS_EP ## n)
|
||||
#define _ENDPOINT_GET_DOUBLEBANK2(details) _ENDPOINT_GET_DOUBLEBANK3(details)
|
||||
#define _ENDPOINT_GET_DOUBLEBANK3(maxsize, db) db
|
||||
|
||||
#if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER)
|
||||
#define ENDPOINT_DETAILS_EP0 64, true
|
||||
#define ENDPOINT_DETAILS_EP1 256, true
|
||||
#define ENDPOINT_DETAILS_EP2 64, true
|
||||
#define ENDPOINT_DETAILS_EP3 64, true
|
||||
#define ENDPOINT_DETAILS_EP4 64, true
|
||||
#define ENDPOINT_DETAILS_EP5 64, true
|
||||
#define ENDPOINT_DETAILS_EP6 64, true
|
||||
#else
|
||||
#define ENDPOINT_DETAILS_EP0 64, true
|
||||
#define ENDPOINT_DETAILS_EP1 64, false
|
||||
#define ENDPOINT_DETAILS_EP2 64, false
|
||||
#define ENDPOINT_DETAILS_EP3 64, true
|
||||
#define ENDPOINT_DETAILS_EP4 64, true
|
||||
#endif
|
||||
|
||||
#if defined(STATIC_ENDPOINT_CONFIGURATION)
|
||||
#define Endpoint_ConfigureEndpoint(Number, Type, Direction, Size, Banks) \
|
||||
Endpoint_ConfigureEndpointStatic(Number, \
|
||||
((Type << EPTYPE0) | Direction), \
|
||||
((1 << ALLOC) | Banks | Endpoint_BytesToEPSizeMask(Size)));
|
||||
#endif
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Endpoint_ClearEndpoints(void);
|
||||
bool Endpoint_ConfigureEndpointStatic(const uint8_t Number, const uint8_t UECFG0XData, const uint8_t UECFG1XData);
|
||||
|
||||
/* Inline Functions: */
|
||||
static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST ATTR_ALWAYSINLINE;
|
||||
static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes)
|
||||
{
|
||||
if (Bytes <= 8)
|
||||
return (0 << EPSIZE0);
|
||||
else if (Bytes <= 16)
|
||||
return (1 << EPSIZE0);
|
||||
else if (Bytes <= 32)
|
||||
return (2 << EPSIZE0);
|
||||
#if defined(USB_LIMITED_CONTROLLER)
|
||||
else
|
||||
return (3 << EPSIZE0);
|
||||
#else
|
||||
else if (Bytes <= 64)
|
||||
return (3 << EPSIZE0);
|
||||
else if (Bytes <= 128)
|
||||
return (4 << EPSIZE0);
|
||||
else
|
||||
return (5 << EPSIZE0);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
115
LUFA/Drivers/USB/LowLevel/Host.c
Normal file
115
LUFA/Drivers/USB/LowLevel/Host.c
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#include "USBMode.h"
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
|
||||
#include "Host.h"
|
||||
|
||||
uint8_t USB_Host_WaitMS(uint8_t MS)
|
||||
{
|
||||
bool BusSuspended = USB_Host_IsBusSuspended();
|
||||
uint8_t ErrorCode = HOST_WAITERROR_Successful;
|
||||
|
||||
USB_INT_Clear(USB_INT_HSOFI);
|
||||
USB_Host_ResumeBus();
|
||||
|
||||
while (MS)
|
||||
{
|
||||
if (USB_INT_HasOccurred(USB_INT_HSOFI))
|
||||
{
|
||||
USB_INT_Clear(USB_INT_HSOFI);
|
||||
MS--;
|
||||
}
|
||||
|
||||
if ((USB_IsConnected == false) || (USB_CurrentMode == USB_MODE_DEVICE))
|
||||
{
|
||||
ErrorCode = HOST_WAITERROR_DeviceDisconnect;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (Pipe_IsError() == true)
|
||||
{
|
||||
Pipe_ClearError();
|
||||
ErrorCode = HOST_WAITERROR_PipeError;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (Pipe_IsStalled() == true)
|
||||
{
|
||||
Pipe_ClearStall();
|
||||
ErrorCode = HOST_WAITERROR_SetupStalled;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (BusSuspended)
|
||||
USB_Host_SuspendBus();
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
void USB_Host_ResetDevice(void)
|
||||
{
|
||||
bool BusSuspended = USB_Host_IsBusSuspended();
|
||||
|
||||
USB_INT_Disable(USB_INT_DDISCI);
|
||||
|
||||
USB_Host_ResetBus();
|
||||
while (!(USB_Host_IsResetBusDone()));
|
||||
|
||||
USB_INT_Clear(USB_INT_HSOFI);
|
||||
USB_Host_ResumeBus();
|
||||
|
||||
for (uint8_t MSRem = 10; MSRem != 0; MSRem--)
|
||||
{
|
||||
/* Workaround for powerless-pullup devices. After a USB bus reset,
|
||||
all disconnection interrupts are supressed while a USB frame is
|
||||
looked for - if it is found within 10ms, the device is still
|
||||
present. */
|
||||
|
||||
if (USB_INT_HasOccurred(USB_INT_HSOFI))
|
||||
{
|
||||
USB_INT_Clear(USB_INT_DDISCI);
|
||||
break;
|
||||
}
|
||||
|
||||
_delay_ms(1);
|
||||
}
|
||||
|
||||
if (BusSuspended)
|
||||
USB_Host_SuspendBus();
|
||||
|
||||
USB_INT_Enable(USB_INT_DDISCI);
|
||||
}
|
||||
#endif
|
||||
245
LUFA/Drivers/USB/LowLevel/Host.h
Normal file
245
LUFA/Drivers/USB/LowLevel/Host.h
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* USB Host mode related macros and enums. This module contains macros and enums which are used when
|
||||
* the USB controller is initialized in host mode.
|
||||
*/
|
||||
|
||||
#ifndef __USBHOST_H__
|
||||
#define __USBHOST_H__
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <stdbool.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#include "../../../Common/Common.h"
|
||||
#include "../HighLevel/USBInterrupt.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Indicates the fixed USB device address which any attached device is enumerated to when in
|
||||
* host mode. As only one USB device may be attached to the AVR in host mode at any one time
|
||||
* and that the address used is not important (other than the fact that it is non-zero), a
|
||||
* fixed value is specified by the library.
|
||||
*/
|
||||
#define USB_HOST_DEVICEADDRESS 1
|
||||
|
||||
#if !defined(USB_HOST_TIMEOUT_MS) || defined(__DOXYGEN__)
|
||||
/** Constant for the maximum software timeout period of sent USB control transactions to an attached
|
||||
* device. If a device fails to respond to a sent control request within this period, the
|
||||
* library will return a timeout error code.
|
||||
*
|
||||
* This value may be overridden in the user project makefile as the value of the
|
||||
* USB_HOST_TIMEOUT_MS token, and passed to the compiler using the -D switch.
|
||||
*/
|
||||
#define USB_HOST_TIMEOUT_MS 1000
|
||||
#endif
|
||||
|
||||
#if !defined(HOST_DEVICE_SETTLE_DELAY_MS) || defined(__DOXYGEN__)
|
||||
/** Constant for the delay in milliseconds after a device is connected before the library
|
||||
* will start the enumeration process. Some devices require a delay of up to 5 seconds
|
||||
* after connection before the enumeration process can start or incorrect operation will
|
||||
* occur.
|
||||
*
|
||||
* This value may be overridden in the user project makefile as the value of the
|
||||
* HOST_DEVICE_SETTLE_DELAY_MS token, and passed to the compiler using the -D switch.
|
||||
*/
|
||||
#define HOST_DEVICE_SETTLE_DELAY_MS 1500
|
||||
#endif
|
||||
|
||||
/** Resets the USB bus, including the endpoints in any attached device and pipes on the AVR host.
|
||||
* USB bus resets leave the default control pipe configured (if already configured).
|
||||
*
|
||||
* If the USB bus has been suspended prior to issuing a bus reset, the attached device will be
|
||||
* woken up automatically and the bus resumed after the reset has been correctly issued.
|
||||
*/
|
||||
#define USB_Host_ResetBus() MACROS{ UHCON |= (1 << RESET); }MACROE
|
||||
|
||||
/** Determines if a previously issued bus reset (via the USB_Host_ResetBus() macro) has
|
||||
* completed. This macro returns true if no bus reset is currently being sent, false
|
||||
* otherwise.
|
||||
*/
|
||||
#define USB_Host_IsResetBusDone() ((UHCON & (1 << RESET)) ? false : true)
|
||||
|
||||
/** Resumes USB communications with an attached and enumerated device, by resuming the transmission
|
||||
* of the 1MS Start Of Frame messages to the device. When resumed, USB communications between the
|
||||
* host and attached device may occur.
|
||||
*/
|
||||
#define USB_Host_ResumeBus() MACROS{ UHCON |= (1 << SOFEN); }MACROE
|
||||
|
||||
/** Suspends the USB bus, preventing any communications from occuring between the host and attached
|
||||
* device until the bus has been resumed. This stops the transmission of the 1MS Start Of Frame
|
||||
* messages to the device.
|
||||
*/
|
||||
#define USB_Host_SuspendBus() MACROS{ UHCON &= ~(1 << SOFEN); }MACROE
|
||||
|
||||
/** Returns true if the USB bus has been suspended via the use of the USB_Host_SuspendBus() macro,
|
||||
* false otherwise. While suspended, no USB communications can occur until the bus is resumed,
|
||||
* except for the Remote Wakeup event from the device if supported.
|
||||
*/
|
||||
#define USB_Host_IsBusSuspended() ((UHCON & (1 << SOFEN)) ? false : true)
|
||||
|
||||
/** Returns true if the attached device is currently enumerated in Full Speed mode (12Mb/s), or
|
||||
* false if the attached device is enumerated in Low Speed mode (1.5Mb/s).
|
||||
*/
|
||||
#define USB_Host_IsDeviceFullSpeed() ((USBSTA & (1 << SPEED)) ? true : false)
|
||||
|
||||
/** Returns true if the attached device is currently issuing a Remote Wakeup request, requesting
|
||||
* that the host resume the USB bus and wake up the device, false otherwise.
|
||||
*/
|
||||
#define USB_Host_IsRemoteWakeupSent() ((UHINT & (1 << RXRSMI)) ? true : false)
|
||||
|
||||
/** Clears the flag indicating that a Remote Wakeup request has been issued by an attached
|
||||
* device.
|
||||
*/
|
||||
#define USB_Host_ClearRemoteWakeupSent() MACROS{ UHINT &= ~(1 << RXRSMI); }MACROE
|
||||
|
||||
/** Accepts a Remote Wakeup request from an attached device. This must be issued in response to
|
||||
* a device's Remote Wakeup request within 2ms for the request to be accepted and the bus to
|
||||
* be resumed.
|
||||
*/
|
||||
#define USB_Host_ResumeFromWakeupRequest() MACROS{ UHCON |= (1 << RESUME); }MACROE
|
||||
|
||||
/** Returns true if no resume from Remote Wakeup request is currently being sent to an attached
|
||||
* device, false otherwise.
|
||||
*/
|
||||
#define USB_Host_IsResumeFromWakeupRequestSent() ((UHCON & (1 << RESUME)) ? false : true)
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the various states of the USB Host state machine. Only some states are
|
||||
* implemented in the LUFA library - other states are left to the user to implement.
|
||||
*
|
||||
* For information on each state, refer to the USB 2.0 specification. Some states have
|
||||
*
|
||||
* \see USBTask.h for information on the global variable USB_HostState, which stores the
|
||||
* current host state machine state.
|
||||
*/
|
||||
enum USB_Host_States_t
|
||||
{
|
||||
HOST_STATE_WaitForDevice = 0, /**< Internally implemented by the library. */
|
||||
HOST_STATE_Unattached = 1, /**< Internally implemented by the library. */
|
||||
HOST_STATE_Attached = 2, /**< Internally implemented by the library. */
|
||||
HOST_STATE_Attached_WaitForDeviceSettle = 3, /**< Internally implemented by the library. */
|
||||
HOST_STATE_Attached_WaitForConnect = 4, /**< Internally implemented by the library. */
|
||||
HOST_STATE_Attached_DoReset = 5, /**< Internally implemented by the library. */
|
||||
HOST_STATE_Powered = 6, /**< Internally implemented by the library. */
|
||||
HOST_STATE_Default = 7, /**< Internally implemented by the library. */
|
||||
HOST_STATE_Default_PostReset = 8, /**< Internally implemented by the library. */
|
||||
HOST_STATE_Default_PostAddressSet = 9, /**< Internally implemented by the library. */
|
||||
HOST_STATE_Addressed = 10, /**< May be implemented by the user project. */
|
||||
HOST_STATE_Configured = 11, /**< May be implemented by the user project. */
|
||||
HOST_STATE_Ready = 12, /**< May be implemented by the user project. */
|
||||
HOST_STATE_Suspended = 13, /**< May be implemented by the user project. */
|
||||
};
|
||||
|
||||
/** Enum for the error codes for the USB_HostError event.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
enum USB_Host_ErrorCodes_t
|
||||
{
|
||||
HOST_ERROR_VBusVoltageDip = 0, /**< VBUS voltage dipped to an unacceptable level. This
|
||||
* error may be the result of an attached device drawing
|
||||
* too much current from the VBUS line, or due to the
|
||||
* AVR's power source being unable to supply sufficient
|
||||
* current.
|
||||
*/
|
||||
};
|
||||
|
||||
/** Enum for the error codes for the USB_DeviceEnumerationFailed event.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
enum USB_Host_EnumerationErrorCodes_t
|
||||
{
|
||||
HOST_ENUMERROR_NoError = 0, /**< No error occurred. Used internally, this is not a valid
|
||||
* ErrorCode parameter value for the USB_DeviceEnumerationFailed
|
||||
* event.
|
||||
*/
|
||||
HOST_ENUMERROR_WaitStage = 1, /**< One of the delays between enumeration steps failed
|
||||
* to complete successfuly, due to a timeout or other
|
||||
* error.
|
||||
*/
|
||||
HOST_ENUMERROR_NoDeviceDetected = 2, /**< No device was detected, despite the USB data lines
|
||||
* indicating the attachment of a device.
|
||||
*/
|
||||
HOST_ENUMERROR_ControlError = 3, /**< One of the enumeration control requests failed to
|
||||
* complete successfuly.
|
||||
*/
|
||||
HOST_ENUMERROR_PipeConfigError = 4, /**< The default control pipe (address 0) failed to
|
||||
* configure correctly.
|
||||
*/
|
||||
};
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define USB_Host_HostMode_On() MACROS{ USBCON |= (1 << HOST); }MACROE
|
||||
#define USB_Host_HostMode_Off() MACROS{ USBCON &= ~(1 << HOST); }MACROE
|
||||
|
||||
#define USB_Host_VBUS_Auto_Enable() MACROS{ OTGCON &= ~(1 << VBUSHWC); UHWCON |= (1 << UVCONE); }MACROE
|
||||
#define USB_Host_VBUS_Manual_Enable() MACROS{ OTGCON |= (1 << VBUSHWC); UHWCON &= ~(1 << UVCONE); DDRE |= (1 << 7); }MACROE
|
||||
|
||||
#define USB_Host_VBUS_Auto_On() MACROS{ OTGCON |= (1 << VBUSREQ); }MACROE
|
||||
#define USB_Host_VBUS_Manual_On() MACROS{ PORTE |= (1 << 7); }MACROE
|
||||
|
||||
#define USB_Host_VBUS_Auto_Off() MACROS{ OTGCON |= (1 << VBUSRQC); }MACROE
|
||||
#define USB_Host_VBUS_Manual_Off() MACROS{ PORTE &= ~(1 << 7); }MACROE
|
||||
|
||||
#define USB_Host_SetDeviceAddress(addr) MACROS{ UHADDR = (addr & 0b01111111); }MACROE
|
||||
|
||||
/* Enums: */
|
||||
enum USB_Host_WaitMSErrorCodes_t
|
||||
{
|
||||
HOST_WAITERROR_Successful = 0,
|
||||
HOST_WAITERROR_DeviceDisconnect = 1,
|
||||
HOST_WAITERROR_PipeError = 2,
|
||||
HOST_WAITERROR_SetupStalled = 3,
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
uint8_t USB_Host_WaitMS(uint8_t MS);
|
||||
void USB_Host_ResetDevice(void);
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
178
LUFA/Drivers/USB/LowLevel/HostChapter9.c
Normal file
178
LUFA/Drivers/USB/LowLevel/HostChapter9.c
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#include "USBMode.h"
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
|
||||
#define INCLUDE_FROM_HOSTCHAPTER9_C
|
||||
#include "HostChapter9.h"
|
||||
|
||||
USB_Host_Request_Header_t USB_HostRequest;
|
||||
|
||||
uint8_t USB_Host_SendControlRequest(void* BufferPtr)
|
||||
{
|
||||
uint8_t* HeaderStream = (uint8_t*)&USB_HostRequest;
|
||||
uint8_t* DataStream = (uint8_t*)BufferPtr;
|
||||
bool BusSuspended = USB_Host_IsBusSuspended();
|
||||
uint8_t ReturnStatus = HOST_SENDCONTROL_Successful;
|
||||
uint16_t DataLen = USB_HostRequest.wLength;
|
||||
|
||||
USB_Host_ResumeBus();
|
||||
|
||||
if ((ReturnStatus = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)
|
||||
return ReturnStatus;
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
Pipe_SetToken(PIPE_TOKEN_SETUP);
|
||||
Pipe_ClearErrorFlags();
|
||||
Pipe_ClearSetupSent();
|
||||
|
||||
Pipe_Unfreeze();
|
||||
|
||||
for (uint8_t HeaderByte = 0; HeaderByte < sizeof(USB_Host_Request_Header_t); HeaderByte++)
|
||||
Pipe_Write_Byte(*(HeaderStream++));
|
||||
|
||||
Pipe_ClearSetupOUT();
|
||||
|
||||
if ((ReturnStatus = USB_Host_Wait_For_Setup_IOS(USB_HOST_WAITFOR_SetupSent)))
|
||||
goto End_Of_Control_Send;
|
||||
|
||||
Pipe_ClearSetupSent();
|
||||
Pipe_Freeze();
|
||||
|
||||
if ((ReturnStatus = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)
|
||||
goto End_Of_Control_Send;
|
||||
|
||||
if ((USB_HostRequest.bmRequestType & CONTROL_REQTYPE_DIRECTION) == REQDIR_DEVICETOHOST)
|
||||
{
|
||||
Pipe_SetToken(PIPE_TOKEN_IN);
|
||||
|
||||
if (DataStream != NULL)
|
||||
{
|
||||
while (DataLen)
|
||||
{
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if ((ReturnStatus = USB_Host_Wait_For_Setup_IOS(USB_HOST_WAITFOR_InReceived)))
|
||||
goto End_Of_Control_Send;
|
||||
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
DataLen = 0;
|
||||
|
||||
while (Pipe_BytesInPipe() && DataLen)
|
||||
{
|
||||
*(DataStream++) = Pipe_Read_Byte();
|
||||
DataLen--;
|
||||
}
|
||||
|
||||
Pipe_Freeze();
|
||||
Pipe_ClearSetupIN();
|
||||
}
|
||||
}
|
||||
|
||||
Pipe_SetToken(PIPE_TOKEN_OUT);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if ((ReturnStatus = USB_Host_Wait_For_Setup_IOS(USB_HOST_WAITFOR_OutReady)))
|
||||
goto End_Of_Control_Send;
|
||||
|
||||
Pipe_ClearSetupOUT();
|
||||
|
||||
if ((ReturnStatus = USB_Host_Wait_For_Setup_IOS(USB_HOST_WAITFOR_OutReady)))
|
||||
goto End_Of_Control_Send;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DataStream != NULL)
|
||||
{
|
||||
Pipe_SetToken(PIPE_TOKEN_OUT);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
while (DataLen)
|
||||
{
|
||||
if ((ReturnStatus = USB_Host_Wait_For_Setup_IOS(USB_HOST_WAITFOR_OutReady)))
|
||||
goto End_Of_Control_Send;
|
||||
|
||||
while (DataLen && (Pipe_BytesInPipe() < USB_ControlPipeSize))
|
||||
{
|
||||
Pipe_Write_Byte(*(DataStream++));
|
||||
DataLen--;
|
||||
}
|
||||
|
||||
Pipe_ClearSetupOUT();
|
||||
}
|
||||
|
||||
if ((ReturnStatus = USB_Host_Wait_For_Setup_IOS(USB_HOST_WAITFOR_OutReady)))
|
||||
goto End_Of_Control_Send;
|
||||
|
||||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
Pipe_SetToken(PIPE_TOKEN_IN);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
if ((ReturnStatus = USB_Host_Wait_For_Setup_IOS(USB_HOST_WAITFOR_InReceived)))
|
||||
goto End_Of_Control_Send;
|
||||
|
||||
Pipe_ClearSetupIN();
|
||||
}
|
||||
|
||||
End_Of_Control_Send:
|
||||
Pipe_Freeze();
|
||||
|
||||
if (BusSuspended)
|
||||
USB_Host_SuspendBus();
|
||||
|
||||
Pipe_ResetPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return ReturnStatus;
|
||||
}
|
||||
|
||||
static uint8_t USB_Host_Wait_For_Setup_IOS(const uint8_t WaitType)
|
||||
{
|
||||
uint16_t TimeoutCounter = USB_HOST_TIMEOUT_MS;
|
||||
|
||||
while (!(((WaitType == USB_HOST_WAITFOR_SetupSent) && Pipe_IsSetupSent()) ||
|
||||
((WaitType == USB_HOST_WAITFOR_InReceived) && Pipe_IsSetupINReceived()) ||
|
||||
((WaitType == USB_HOST_WAITFOR_OutReady) && Pipe_IsSetupOUTReady())))
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((ErrorCode = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)
|
||||
return ErrorCode;
|
||||
|
||||
if (!(TimeoutCounter--))
|
||||
return HOST_SENDCONTROL_SoftwareTimeOut;
|
||||
}
|
||||
|
||||
return HOST_SENDCONTROL_Successful;
|
||||
}
|
||||
|
||||
#endif
|
||||
127
LUFA/Drivers/USB/LowLevel/HostChapter9.h
Normal file
127
LUFA/Drivers/USB/LowLevel/HostChapter9.h
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Module for host mode request processing. This module allows for the transmission of standard, class and
|
||||
* vendor control requests to the default control endpoint of an attached device while in host mode.
|
||||
*
|
||||
* \see Chapter 9 of the USB 2.0 specification.
|
||||
*/
|
||||
|
||||
#ifndef __HOSTCHAPTER9_H__
|
||||
#define __HOSTCHAPTER9_H__
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "LowLevel.h"
|
||||
#include "StdRequestType.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Type Defines: */
|
||||
/** Type define for a standard USB control request.
|
||||
*
|
||||
* \see StdRequestType.h for information on the request type and data.
|
||||
* \see The USB 2.0 specification for more information on standard control requests.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bmRequestType; /**< Type of the request. */
|
||||
uint8_t bRequest; /**< Request command code. */
|
||||
uint16_t wValue; /**< wValue parameter of the request. */
|
||||
uint16_t wIndex; /**< wIndex parameter of the request. */
|
||||
uint16_t wLength; /**< Length of the data to transfer in bytes. */
|
||||
} USB_Host_Request_Header_t;
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the USB_Host_SendControlRequest() return code, indicating the reason for the error
|
||||
* if the transfer of the request is unsuccessful.
|
||||
*/
|
||||
enum USB_Host_SendControlErrorCodes_t
|
||||
{
|
||||
HOST_SENDCONTROL_Successful = 0, /**< No error occurred in the request transfer. */
|
||||
HOST_SENDCONTROL_DeviceDisconnect = 1, /**< The attached device was disconnected during the
|
||||
* request transfer.
|
||||
*/
|
||||
HOST_SENDCONTROL_PipeError = 2, /**< An error occured in the pipe while sending the request. */
|
||||
HOST_SENDCONTROL_SetupStalled = 3, /**< The attached device stalled the request, usually
|
||||
* indicating that the request is unsupported on the device.
|
||||
*/
|
||||
HOST_SENDCONTROL_SoftwareTimeOut = 4, /**< The request or data transfer timed out. */
|
||||
};
|
||||
|
||||
/* Global Variables: */
|
||||
/** Global for the request to send via the USB_Host_SendControlRequest() function. This
|
||||
* global should be filled with the correct control request data before sending the request to
|
||||
* the attached device while in host mode.
|
||||
*/
|
||||
extern USB_Host_Request_Header_t USB_HostRequest;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Sends the request stored in the USB_HostRequest global structure to the attached device,
|
||||
* and transfers the data stored in the buffer to the device, or from the device to the buffer
|
||||
* as requested.
|
||||
*
|
||||
* \param BufferPtr Pointer to the start of the data buffer if the request has a data stage, or
|
||||
* NULL if the request transfers no data to or from the device.
|
||||
*
|
||||
* \return A value from the USB_Host_SendControlErrorCodes_t enum to indicate the result.
|
||||
*/
|
||||
uint8_t USB_Host_SendControlRequest(void* BufferPtr);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Enums: */
|
||||
enum USB_WaitForTypes_t
|
||||
{
|
||||
USB_HOST_WAITFOR_SetupSent,
|
||||
USB_HOST_WAITFOR_InReceived,
|
||||
USB_HOST_WAITFOR_OutReady,
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
#if defined(INCLUDE_FROM_HOSTCHAPTER9_C)
|
||||
static uint8_t USB_Host_Wait_For_Setup_IOS(const uint8_t WaitType);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
260
LUFA/Drivers/USB/LowLevel/LowLevel.c
Normal file
260
LUFA/Drivers/USB/LowLevel/LowLevel.c
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#include "USBMode.h"
|
||||
|
||||
#include "LowLevel.h"
|
||||
|
||||
#if (!defined(USB_HOST_ONLY) && !defined(USB_DEVICE_ONLY))
|
||||
volatile uint8_t USB_CurrentMode = USB_MODE_NONE;
|
||||
#endif
|
||||
|
||||
#if !defined(USE_STATIC_OPTIONS)
|
||||
volatile uint8_t USB_Options;
|
||||
#endif
|
||||
|
||||
void USB_Init(
|
||||
#if defined(USB_CAN_BE_BOTH)
|
||||
const uint8_t Mode
|
||||
#endif
|
||||
|
||||
#if (defined(USB_CAN_BE_BOTH) && !defined(USE_STATIC_OPTIONS))
|
||||
,
|
||||
#elif (!defined(USB_CAN_BE_BOTH) && defined(USE_STATIC_OPTIONS))
|
||||
void
|
||||
#endif
|
||||
|
||||
#if !defined(USE_STATIC_OPTIONS)
|
||||
const uint8_t Options
|
||||
#endif
|
||||
)
|
||||
{
|
||||
USB_ShutDown();
|
||||
|
||||
#if defined(USB_CAN_BE_BOTH)
|
||||
USB_CurrentMode = Mode;
|
||||
#endif
|
||||
|
||||
#if !defined(USE_STATIC_OPTIONS)
|
||||
USB_Options = Options;
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
|
||||
#endif
|
||||
|
||||
#if defined(USB_DEVICE_ONLY) && defined(USB_FULL_CONTROLLER)
|
||||
UHWCON |= (1 << UIMOD);
|
||||
#elif defined(USB_HOST_ONLY)
|
||||
UHWCON &= ~(1 << UIMOD);
|
||||
#elif defined(USB_CAN_BE_BOTH)
|
||||
if (Mode == USB_MODE_UID)
|
||||
{
|
||||
UHWCON |= (1 << UIDE);
|
||||
|
||||
USB_INT_Clear(USB_INT_IDTI);
|
||||
USB_INT_Enable(USB_INT_IDTI);
|
||||
|
||||
USB_CurrentMode = USB_GetUSBModeFromUID();
|
||||
}
|
||||
else if (Mode == USB_MODE_DEVICE)
|
||||
{
|
||||
UHWCON |= (1 << UIMOD);
|
||||
}
|
||||
else if (Mode == USB_MODE_HOST)
|
||||
{
|
||||
UHWCON &= ~(1 << UIMOD);
|
||||
}
|
||||
else
|
||||
{
|
||||
RAISE_EVENT(USB_PowerOnFail, POWERON_ERROR_NoUSBModeSpecified);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
USB_ResetInterface();
|
||||
|
||||
#if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER)
|
||||
USB_OTGPAD_On();
|
||||
#endif
|
||||
|
||||
USB_IsInitialized = true;
|
||||
|
||||
sei();
|
||||
}
|
||||
|
||||
void USB_ShutDown(void)
|
||||
{
|
||||
if (USB_IsConnected)
|
||||
RAISE_EVENT(USB_Disconnect);
|
||||
|
||||
USB_Detach();
|
||||
|
||||
USB_INT_DisableAllInterrupts();
|
||||
USB_INT_ClearAllInterrupts();
|
||||
|
||||
USB_IsConnected = false;
|
||||
USB_IsInitialized = false;
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
USB_HostState = HOST_STATE_Unattached;
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
USB_ConfigurationNumber = 0;
|
||||
#endif
|
||||
|
||||
#if defined(CAN_BE_BOTH)
|
||||
USB_CurrentMode = USB_MODE_NONE;
|
||||
#endif
|
||||
|
||||
USB_Interface_Disable();
|
||||
USB_PLL_Off();
|
||||
|
||||
#if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER)
|
||||
USB_OTGPAD_Off();
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_BOTH)
|
||||
UHWCON &= ~(1 << UIDE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void USB_ResetInterface(void)
|
||||
{
|
||||
USB_INT_DisableAllInterrupts();
|
||||
USB_INT_ClearAllInterrupts();
|
||||
|
||||
USB_IsConnected = false;
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
USB_HostState = HOST_STATE_Unattached;
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
USB_ConfigurationNumber = 0;
|
||||
USB_IsSuspended = false;
|
||||
USB_RemoteWakeupEnabled = false;
|
||||
USB_CurrentlySelfPowered = false;
|
||||
#endif
|
||||
|
||||
if (!(USB_Options & USB_OPT_MANUAL_PLL))
|
||||
{
|
||||
#if defined(USB_MODIFIED_FULL_CONTROLLER)
|
||||
PLLFRQ = ((1 << PLLUSB) | (1 << PDIV3) | (1 << PDIV1));
|
||||
#endif
|
||||
|
||||
USB_PLL_On();
|
||||
while (!(USB_PLL_IsReady()));
|
||||
}
|
||||
|
||||
USB_Interface_Reset();
|
||||
|
||||
#if defined(USB_CAN_BE_BOTH)
|
||||
if (UHWCON & (1 << UIDE))
|
||||
{
|
||||
USB_INT_Clear(USB_INT_IDTI);
|
||||
USB_INT_Enable(USB_INT_IDTI);
|
||||
USB_CurrentMode = USB_GetUSBModeFromUID();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!(USB_Options & USB_OPT_REG_DISABLED))
|
||||
USB_REG_On();
|
||||
|
||||
USB_CLK_Unfreeze();
|
||||
|
||||
#if (defined(USB_CAN_BE_DEVICE) && (defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER)))
|
||||
if (USB_CurrentMode == USB_MODE_DEVICE)
|
||||
{
|
||||
if (USB_Options & USB_DEVICE_OPT_LOWSPEED)
|
||||
USB_Device_SetLowSpeed();
|
||||
else
|
||||
USB_Device_SetHighSpeed();
|
||||
|
||||
USB_INT_Enable(USB_INT_VBUS);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(USB_CAN_BE_DEVICE) && !defined(FIXED_CONTROL_ENDPOINT_SIZE))
|
||||
if (USB_CurrentMode == USB_MODE_DEVICE)
|
||||
{
|
||||
USB_Descriptor_Device_t* DeviceDescriptorPtr;
|
||||
|
||||
if (USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR)
|
||||
{
|
||||
#if defined(USE_RAM_DESCRIPTORS)
|
||||
USB_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
|
||||
#elif defined(USE_EEPROM_DESCRIPTORS)
|
||||
USB_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
|
||||
#else
|
||||
USB_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
USB_Attach();
|
||||
|
||||
#if defined(USB_DEVICE_ONLY)
|
||||
USB_INT_Enable(USB_INT_SUSPEND);
|
||||
USB_INT_Enable(USB_INT_EORSTI);
|
||||
#elif defined(USB_HOST_ONLY)
|
||||
USB_Host_HostMode_On();
|
||||
|
||||
USB_Host_VBUS_Auto_Off();
|
||||
USB_OTGPAD_Off();
|
||||
|
||||
USB_Host_VBUS_Manual_Enable();
|
||||
USB_Host_VBUS_Manual_On();
|
||||
|
||||
USB_INT_Enable(USB_INT_SRPI);
|
||||
USB_INT_Enable(USB_INT_BCERRI);
|
||||
#else
|
||||
if (USB_CurrentMode == USB_MODE_DEVICE)
|
||||
{
|
||||
USB_INT_Enable(USB_INT_SUSPEND);
|
||||
USB_INT_Enable(USB_INT_EORSTI);
|
||||
}
|
||||
else if (USB_CurrentMode == USB_MODE_HOST)
|
||||
{
|
||||
USB_Host_HostMode_On();
|
||||
|
||||
USB_Host_VBUS_Auto_Off();
|
||||
USB_OTGPAD_Off();
|
||||
|
||||
USB_Host_VBUS_Manual_Enable();
|
||||
USB_Host_VBUS_Manual_On();
|
||||
|
||||
USB_INT_Enable(USB_INT_SRPI);
|
||||
USB_INT_Enable(USB_INT_BCERRI);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
371
LUFA/Drivers/USB/LowLevel/LowLevel.h
Normal file
371
LUFA/Drivers/USB/LowLevel/LowLevel.h
Normal file
|
|
@ -0,0 +1,371 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main low level USB driver. This module manages the low level initialization and shut down of the USB AVR's
|
||||
* USB interface in either device or (if supported) host mode.
|
||||
*/
|
||||
|
||||
#ifndef __USBLOWLEVEL_H__
|
||||
#define __USBLOWLEVEL_H__
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "USBMode.h"
|
||||
#include "../../../Common/Common.h"
|
||||
#include "../HighLevel/Events.h"
|
||||
#include "../HighLevel/USBTask.h"
|
||||
#include "../HighLevel/USBInterrupt.h"
|
||||
|
||||
#if defined(USB_CAN_BE_HOST) || defined(__DOXYGEN__)
|
||||
#include "Host.h"
|
||||
#include "Pipe.h"
|
||||
#include "OTG.h"
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__)
|
||||
#include "Device.h"
|
||||
#include "Endpoint.h"
|
||||
#include "DevChapter9.h"
|
||||
#endif
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks and Defines: */
|
||||
#if (F_CPU == 8000000)
|
||||
#if (defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__))
|
||||
#define USB_PLL_PSC 0
|
||||
#elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || \
|
||||
defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || \
|
||||
defined(__AVR_ATmega32U6__))
|
||||
#define USB_PLL_PSC ((1 << PLLP1) | (1 << PLLP0))
|
||||
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
|
||||
#define USB_PLL_PSC 0
|
||||
#endif
|
||||
#elif (F_CPU == 16000000)
|
||||
#if (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_ATmega32U6__))
|
||||
#define USB_PLL_PSC ((1 << PLLP2) | (1 << PLLP1))
|
||||
#elif (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__))
|
||||
#define USB_PLL_PSC ((1 << PLLP2) | (1 << PLLP0))
|
||||
#elif (defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__))
|
||||
#define USB_PLL_PSC (1 << PLLP0)
|
||||
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
|
||||
#define USB_PLL_PSC (1 << PINDIV)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(USB_PLL_PSC)
|
||||
#error No PLL prescale value available for chosen F_CPU value and AVR model.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Mode mask for the USB_CurrentMode global. This indicates that the USB interface is currently not
|
||||
* initialized into any mode.
|
||||
*/
|
||||
#define USB_MODE_NONE 0
|
||||
|
||||
/** Mode mask for the USB_CurrentMode global and the USB_Init() function. This indicates that the
|
||||
* USB interface is or should be initialized in the USB device mode.
|
||||
*/
|
||||
#define USB_MODE_DEVICE 1
|
||||
|
||||
/** Mode mask for the USB_CurrentMode global and the USB_Init() function. This indicates that the
|
||||
* USB interface is or should be initialized in the USB host mode.
|
||||
*
|
||||
* \note Not all USB AVRs support host mode.
|
||||
*/
|
||||
#define USB_MODE_HOST 2
|
||||
|
||||
/** Mode mask for the the USB_Init() function. This indicates that the USB interface should be
|
||||
* initialized into whatever mode the UID pin of the USB AVR indicates, and that the device
|
||||
* should swap over its mode when the level of the UID pin changes during operation.
|
||||
*
|
||||
* \note Not all USB AVRs support host mode, and thus UID mode.
|
||||
*/
|
||||
#define USB_MODE_UID 3
|
||||
|
||||
/** Regulator disable option mask for USB_Init(). This indicates that the internal 3.3V USB data pad
|
||||
* regulator should be enabled to regulate the data pin voltages to within the USB standard.
|
||||
*
|
||||
* \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 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_ENABLED (0 << 1)
|
||||
|
||||
/** Manual PLL control option mask for 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 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)
|
||||
|
||||
/** Mask for a CONTROL type endpoint or pipe.
|
||||
*
|
||||
* \note See Endpoint.h and Pipe.h headers for endpoint/pipe functions.
|
||||
*/
|
||||
#define EP_TYPE_CONTROL 0b00
|
||||
|
||||
/** Mask for an ISOCHRONOUS type endpoint or pipe.
|
||||
*
|
||||
* \note See Endpoint.h and Pipe.h headers for endpoint/pipe functions.
|
||||
*/
|
||||
#define EP_TYPE_ISOCHRONOUS 0b01
|
||||
|
||||
/** Mask for a BULK type endpoint or pipe.
|
||||
*
|
||||
* \note See Endpoint.h and Pipe.h headers for endpoint/pipe functions.
|
||||
*/
|
||||
#define EP_TYPE_BULK 0b10
|
||||
|
||||
/** Mask for an INTERRUPT type endpoint or pipe.
|
||||
*
|
||||
* \note See Endpoint.h and Pipe.h headers for endpoint/pipe functions.
|
||||
*/
|
||||
#define EP_TYPE_INTERRUPT 0b11
|
||||
|
||||
/** Mask for determining the type of an endpoint or pipe. This should then be compared with the
|
||||
* EP_TYPE_* macros elsewhere in this module to determine the exact type of the endpoint or pipe.
|
||||
*
|
||||
* \note See Endpoint.h and Pipe.h headers for endpoint/pipe functions.
|
||||
*/
|
||||
#define EP_TYPE_MASK 0b11
|
||||
|
||||
/** Returns boolean true if the VBUS line is currently high (i.e. the USB host is supplying power),
|
||||
* otherwise returns false.
|
||||
*/
|
||||
#define USB_VBUS_GetStatus() ((USBSTA & (1 << VBUS)) ? true : false)
|
||||
|
||||
/** Detaches the device from the USB bus. This has the effect of removing the device from any
|
||||
* host if, ceasing USB communications. If no host is present, this prevents any host from
|
||||
* enumerating the device once attached until USB_Attach() is called.
|
||||
*/
|
||||
#define USB_Detach() MACROS{ UDCON |= (1 << DETACH); }MACROE
|
||||
|
||||
/** Attaches the device to the USB bus. This announces the device's presence to any attached
|
||||
* USB host, starting the enumeration process. If no host is present, attaching the device
|
||||
* will allow for enumeration once a host is connected to the device.
|
||||
*
|
||||
* This is inexplicably also required for proper operation while in host mode, to enable the
|
||||
* attachment of a device to the host. This is despite the bit being located in the device-mode
|
||||
* register and despite the datasheet making no mention of its requirement in host mode.
|
||||
*/
|
||||
#define USB_Attach() MACROS{ UDCON &= ~(1 << DETACH); }MACROE
|
||||
|
||||
#if !defined(USB_STREAM_TIMEOUT_MS) || defined(__DOXYGEN__)
|
||||
/** Constant for the maximum software timeout period of the USB data stream transfer functions
|
||||
* (both control and standard) when in either device or host mode. If the next packet of a stream
|
||||
* is not received or acknowedged within this time period, the stream function will fail.
|
||||
*
|
||||
* This value may be overridden in the user project makefile as the value of the
|
||||
* USB_STREAM_TIMEOUT_MS token, and passed to the compiler using the -D switch.
|
||||
*/
|
||||
#define USB_STREAM_TIMEOUT_MS 100
|
||||
#endif
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Main function to initialize and start the USB interface. Once active, the USB interface will
|
||||
* allow for device connection to a host when in device mode, or for device enumeration while in
|
||||
* host mode.
|
||||
*
|
||||
* As the USB library relies on USB interrupts for some of its functionality, this routine will
|
||||
* enable global interrupts.
|
||||
*
|
||||
* Calling this function when the USB interface is already initialized will cause a complete USB
|
||||
* interface reset and re-enumeration.
|
||||
*
|
||||
* \param Mode This is a mask indicating what mode the USB interface is to be initialized to.
|
||||
* Valid mode masks are USB_MODE_DEVICE, USB_MODE_HOST or USB_MODE_UID.
|
||||
*
|
||||
* \param Options Mask indicating the options which should be used when initializing the USB
|
||||
* interface to control the USB interface's behaviour. This should be comprised of
|
||||
* a USB_OPT_REG_* mask to control the regulator, a USB_OPT_*_PLL mask to control the
|
||||
* PLL, and a USB_DEVICE_OPT_* mask (when the device mode is enabled) to set the device
|
||||
* mode speed.
|
||||
*
|
||||
* \note To reduce the FLASH requirements of the library if only device or host mode is required,
|
||||
* this can be statically set via defining the token USB_DEVICE_ONLY for device mode or
|
||||
* USB_HOST_ONLY for host mode in the use project makefile, passing the token to the compiler
|
||||
* via the -D switch. If the mode is statically set, this parameter does not exist in the
|
||||
* function prototype.
|
||||
*
|
||||
* \note To reduce the FLASH requirements of the library if only fixed settings are are required,
|
||||
* the options may be set statically in the same manner as the mode (see the Mode parameter of
|
||||
* this function). To statically set the USB options, pass in the USE_STATIC_OPTIONS token,
|
||||
* defined to the appropriate options masks. When the options are statically set, this
|
||||
* parameter does not exist in the function prototype.
|
||||
*
|
||||
* \note The mode parameter does not exist on devices where only one mode is possible, such as USB
|
||||
* AVR models which only implement the USB device mode in hardware.
|
||||
*
|
||||
* \see Device.h for the USB_DEVICE_OPT_* masks.
|
||||
*/
|
||||
void USB_Init(
|
||||
#if defined(USB_CAN_BE_BOTH) || defined(__DOXYGEN__)
|
||||
const uint8_t Mode
|
||||
#endif
|
||||
|
||||
#if (defined(USB_CAN_BE_BOTH) && !defined(USE_STATIC_OPTIONS)) || defined(__DOXYGEN__)
|
||||
,
|
||||
#elif (!defined(USB_CAN_BE_BOTH) && defined(USE_STATIC_OPTIONS))
|
||||
void
|
||||
#endif
|
||||
|
||||
#if !defined(USE_STATIC_OPTIONS) || defined(__DOXYGEN__)
|
||||
const uint8_t Options
|
||||
#endif
|
||||
);
|
||||
|
||||
/** Shuts down the USB interface. This turns off the USB interface after deallocating all USB FIFO
|
||||
* memory, endpoints and pipes. When turned off, no USB functionality can be used until the interface
|
||||
* is restarted with the USB_Init() function.
|
||||
*/
|
||||
void USB_ShutDown(void);
|
||||
|
||||
/** Resets the interface, when already initialized. This will re-enumerate the device if already connected
|
||||
* to a host, or re-enumerate an already attached device when in host mode.
|
||||
*/
|
||||
void USB_ResetInterface(void);
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for error codes relating to the powering on of the USB interface. These error codes are
|
||||
* used in the ErrorCode parameter value of the USB_PowerOnFail event.
|
||||
*/
|
||||
enum USB_PowerOnErrorCodes_t
|
||||
{
|
||||
POWERON_ERROR_NoUSBModeSpecified = 0, /**< Indicates that USB_Init() was called with an
|
||||
* invalid or missing Mode parameter.
|
||||
*/
|
||||
};
|
||||
|
||||
/* Global Variables: */
|
||||
#if (!defined(USB_HOST_ONLY) && !defined(USB_DEVICE_ONLY)) || defined(__DOXYGEN__)
|
||||
/** Indicates the mode that the USB interface is currently initialized to. This value will be
|
||||
* one of the USB_MODE_* masks defined elsewhere in this module.
|
||||
*
|
||||
* \note This variable should be treated as read-only in the user application, and never manually
|
||||
* changed in value.
|
||||
*/
|
||||
extern volatile uint8_t USB_CurrentMode;
|
||||
#endif
|
||||
|
||||
#if !defined(USE_STATIC_OPTIONS) || defined(__DOXYGEN__)
|
||||
extern volatile uint8_t USB_Options;
|
||||
/** Indicates the current USB options that the USB interface was initialized with when USB_Init()
|
||||
* was called. This value will be one of the USB_MODE_* masks defined elsewhere in this module.
|
||||
*
|
||||
* \note This variable should be treated as read-only in the user application, and never manually
|
||||
* changed in value.
|
||||
*/
|
||||
#endif
|
||||
|
||||
/* Throwable Events: */
|
||||
/** This module raises the USB_Disconnect event if the USB interface is reset (such as during a mode
|
||||
* change while in UID mode) while the USB interface is connected to a device when in host mode, or
|
||||
* a host while in device mode.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_Disconnect);
|
||||
|
||||
#if defined(USB_CAN_BE_BOTH) || defined(__DOXYGEN__)
|
||||
/** This module raises the Power On Failure event when an error occurs while initializing the USB
|
||||
* interface.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_PowerOnFail);
|
||||
#endif
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define USB_PLL_On() MACROS{ PLLCSR = USB_PLL_PSC; PLLCSR |= (1 << PLLE); }MACROE
|
||||
#define USB_PLL_Off() MACROS{ PLLCSR = 0; }MACROE
|
||||
#define USB_PLL_IsReady() ((PLLCSR & (1 << PLOCK)) ? true : false)
|
||||
|
||||
#if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER)
|
||||
#define USB_REG_On() MACROS{ UHWCON |= (1 << UVREGE); }MACROE
|
||||
#define USB_REG_Off() MACROS{ UHWCON &= ~(1 << UVREGE); }MACROE
|
||||
#else
|
||||
#define USB_REG_On() MACROS{ REGCR &= ~(1 << REGDIS); }MACROE
|
||||
#define USB_REG_Off() MACROS{ REGCR |= (1 << REGDIS); }MACROE
|
||||
#endif
|
||||
|
||||
#define USB_OTGPAD_On() MACROS{ USBCON |= (1 << OTGPADE); }MACROE
|
||||
#define USB_OTGPAD_Off() MACROS{ USBCON &= ~(1 << OTGPADE); }MACROE
|
||||
|
||||
#define USB_CLK_Freeze() MACROS{ USBCON |= (1 << FRZCLK); }MACROE
|
||||
#define USB_CLK_Unfreeze() MACROS{ USBCON &= ~(1 << FRZCLK); }MACROE
|
||||
|
||||
#define USB_Interface_Enable() MACROS{ USBCON |= (1 << USBE); }MACROE
|
||||
#define USB_Interface_Disable() MACROS{ USBCON &= ~(1 << USBE); }MACROE
|
||||
#define USB_Interface_Reset() MACROS{ uint8_t Temp = USBCON; USBCON = (Temp & ~(1 << USBE)); \
|
||||
USBCON = (Temp | (1 << USBE)); }MACROE
|
||||
|
||||
/* Inline Functions: */
|
||||
static inline uint8_t USB_GetUSBModeFromUID(void) ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint8_t USB_GetUSBModeFromUID(void)
|
||||
{
|
||||
#if (defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__))
|
||||
if (USBSTA & (1 << ID))
|
||||
return USB_MODE_DEVICE;
|
||||
else
|
||||
return USB_MODE_HOST;
|
||||
#else
|
||||
return USB_MODE_DEVICE;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
102
LUFA/Drivers/USB/LowLevel/OTG.h
Normal file
102
LUFA/Drivers/USB/LowLevel/OTG.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Macros for embedded USB hosts with dual role On The Go capabilities, for managing role exchange. OTG
|
||||
* is a way for two USB dual role devices to talk to one another directly without fixed device/host roles.
|
||||
*
|
||||
* \note These macros are only for AVRs which support the OTG protocol, and do not exist for device-only AVRs.
|
||||
*/
|
||||
|
||||
#ifndef __USBOTG_H__
|
||||
#define __USBOTG_H__
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../../../Common/Common.h"
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Initiate a Host Negotiation Protocol request. This indicates to the other connected device
|
||||
* that the device wishes to change device/host roles.
|
||||
*/
|
||||
#define USB_OTG_DEV_Request_HNP() MACROS{ OTGCON |= (1 << HNPREQ); }MACROE
|
||||
|
||||
/** Cancel a Host Negotiation Protocol request. This stops a pending HNP request to the other
|
||||
* connected device.
|
||||
*/
|
||||
#define USB_OTG_DEV_Cancel_HNP_Request() MACROS{ OTGCON &= ~(1 << HNPREQ); }MACROE
|
||||
|
||||
/** Returns boolean false if not currently sending a HNP to the other connected device, or true
|
||||
* if a HNP is currently being issued.
|
||||
*/
|
||||
#define USB_OTG_DEV_IsSendingHNP() ((OTGCON & (1 << HNPREQ)) ? true : false)
|
||||
|
||||
/** Accepts a HNP from a connected device, indicating that both devices should exchange
|
||||
* device/host roles.
|
||||
*/
|
||||
#define USB_OTG_HOST_Accept_HNP() USB_OTG_DEV_Request_HNP()
|
||||
|
||||
/** Rejects a HNP from a connected device, indicating that both devices should remain in their
|
||||
* current device/host roles.
|
||||
*/
|
||||
#define USB_OTG_HOST_Reject_HNP() USB_OTG_DEV_Cancel_HNP_Request()
|
||||
|
||||
/** Returns boolean false if the connected device is not currently sending a HNP request, or true
|
||||
* if a HNP is currently being issued by the connected device.
|
||||
*/
|
||||
#define USB_OTG_HOST_IsHNPReceived() ((OTGCON & (1 << HNPREQ)) ? true : false)
|
||||
|
||||
/** Initiates a Session Request Protocol request. Most OTG devices turn off VBUS when the USB
|
||||
* interface is not in use, to conserve power. Sending a SRP to a USB OTG device running in
|
||||
* host mode indicates that VBUS should be applied and a session started.
|
||||
*
|
||||
* There are two different methods of sending a SRP - either pulses on the VBUS line, or by
|
||||
* pulsing the Data + line via the internal pullup resistor. The SRP mode is given as the
|
||||
* "type" parameter, and can be either USB_OTG_SRP_VBUS or USB_OTG_STP_DATA.
|
||||
*/
|
||||
#define USB_OTG_DEV_Initiate_SRP(type) MACROS{ OTGCON = ((OTGCON & ~(1 << SRPSEL)) | (type | (1 << SRPREQ))); }MACROE
|
||||
|
||||
/** Mask for the VBUS pulsing method of SRP, supported by some OTG devices.
|
||||
*
|
||||
* \see USB_OTG_DEV_Initiate_SRP()
|
||||
*/
|
||||
#define USB_OTG_SRP_VBUS (1 << SRPSEL)
|
||||
|
||||
/** Mask for the Data + pulsing method of SRP, supported by some OTG devices.
|
||||
*
|
||||
* \see USB_OTG_DEV_Initiate_SRP()
|
||||
*/
|
||||
#define USB_OTG_STP_DATA 0
|
||||
|
||||
#endif
|
||||
258
LUFA/Drivers/USB/LowLevel/Pipe.c
Normal file
258
LUFA/Drivers/USB/LowLevel/Pipe.c
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
#include "USBMode.h"
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
|
||||
#define INCLUDE_FROM_PIPE_C
|
||||
#include "Pipe.h"
|
||||
|
||||
uint8_t USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
|
||||
|
||||
bool Pipe_ConfigurePipe(const uint8_t Number, const uint8_t Type, const uint8_t Token, const uint8_t EndpointNumber,
|
||||
const uint16_t Size, const uint8_t Banks)
|
||||
{
|
||||
Pipe_SelectPipe(Number);
|
||||
Pipe_EnablePipe();
|
||||
|
||||
UPCFG1X = 0;
|
||||
|
||||
UPCFG0X = ((Type << EPTYPE0) | Token | (EndpointNumber << PEPNUM0));
|
||||
UPCFG1X = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size));
|
||||
|
||||
return Pipe_IsConfigured();
|
||||
}
|
||||
|
||||
void Pipe_ClearPipes(void)
|
||||
{
|
||||
UPINT = 0;
|
||||
|
||||
for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++)
|
||||
{
|
||||
Pipe_ResetPipe(PNum);
|
||||
Pipe_SelectPipe(PNum);
|
||||
UPIENX = 0;
|
||||
UPINTX = 0;
|
||||
Pipe_ClearError();
|
||||
Pipe_ClearErrorFlags();
|
||||
Pipe_DeallocateMemory();
|
||||
Pipe_DisablePipe();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Pipe_WaitUntilReady(void)
|
||||
{
|
||||
uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
|
||||
|
||||
USB_INT_Clear(USB_INT_HSOFI);
|
||||
|
||||
while (!(Pipe_ReadWriteAllowed()))
|
||||
{
|
||||
if (Pipe_IsStalled())
|
||||
return PIPE_READYWAIT_PipeStalled;
|
||||
else if (!(USB_IsConnected))
|
||||
return PIPE_READYWAIT_DeviceDisconnected;
|
||||
|
||||
if (USB_INT_HasOccurred(USB_INT_HSOFI))
|
||||
{
|
||||
USB_INT_Clear(USB_INT_HSOFI);
|
||||
|
||||
if (!(TimeoutMSRem--))
|
||||
return PIPE_READYWAIT_Timeout;
|
||||
}
|
||||
}
|
||||
|
||||
return PIPE_READYWAIT_NoError;
|
||||
}
|
||||
|
||||
uint8_t Pipe_Write_Stream_LE(const void* Data, uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
uint8_t* DataStream = (uint8_t*)Data;
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
|
||||
while (Length--)
|
||||
{
|
||||
if (!(Pipe_ReadWriteAllowed()))
|
||||
{
|
||||
Pipe_ClearCurrentBank();
|
||||
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
|
||||
return PIPE_RWSTREAM_ERROR_CallbackAborted;
|
||||
#endif
|
||||
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Pipe_Write_Byte(*(DataStream++));
|
||||
}
|
||||
|
||||
return PIPE_RWSTREAM_ERROR_NoError;
|
||||
}
|
||||
|
||||
uint8_t Pipe_Write_Stream_BE(const void* Data, uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
uint8_t* DataStream = (uint8_t*)(Data + Length - 1);
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
|
||||
while (Length--)
|
||||
{
|
||||
if (!(Pipe_ReadWriteAllowed()))
|
||||
{
|
||||
Pipe_ClearCurrentBank();
|
||||
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
|
||||
return PIPE_RWSTREAM_ERROR_CallbackAborted;
|
||||
#endif
|
||||
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Pipe_Write_Byte(*(DataStream--));
|
||||
}
|
||||
|
||||
return PIPE_RWSTREAM_ERROR_NoError;
|
||||
}
|
||||
|
||||
uint8_t Pipe_Discard_Stream(uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
|
||||
while (Length--)
|
||||
{
|
||||
if (!(Pipe_ReadWriteAllowed()))
|
||||
{
|
||||
Pipe_ClearCurrentBank();
|
||||
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
|
||||
return PIPE_RWSTREAM_ERROR_CallbackAborted;
|
||||
#endif
|
||||
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Pipe_Discard_Byte();
|
||||
}
|
||||
|
||||
return PIPE_RWSTREAM_ERROR_NoError;
|
||||
}
|
||||
|
||||
uint8_t Pipe_Read_Stream_LE(void* Buffer, uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
uint8_t* DataStream = (uint8_t*)Buffer;
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
|
||||
while (Length--)
|
||||
{
|
||||
if (!(Pipe_ReadWriteAllowed()))
|
||||
{
|
||||
Pipe_ClearCurrentBank();
|
||||
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
|
||||
return PIPE_RWSTREAM_ERROR_CallbackAborted;
|
||||
#endif
|
||||
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
*(DataStream++) = Pipe_Read_Byte();
|
||||
}
|
||||
|
||||
return PIPE_RWSTREAM_ERROR_NoError;
|
||||
}
|
||||
|
||||
uint8_t Pipe_Read_Stream_BE(void* Buffer, uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
|
||||
uint8_t ErrorCode;
|
||||
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
|
||||
while (Length--)
|
||||
{
|
||||
if (!(Pipe_ReadWriteAllowed()))
|
||||
{
|
||||
Pipe_ClearCurrentBank();
|
||||
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
|
||||
return PIPE_RWSTREAM_ERROR_CallbackAborted;
|
||||
#endif
|
||||
|
||||
if ((ErrorCode = Pipe_WaitUntilReady()))
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
*(DataStream--) = Pipe_Read_Byte();
|
||||
}
|
||||
|
||||
return PIPE_RWSTREAM_ERROR_NoError;
|
||||
}
|
||||
|
||||
#endif
|
||||
788
LUFA/Drivers/USB/LowLevel/Pipe.h
Normal file
788
LUFA/Drivers/USB/LowLevel/Pipe.h
Normal file
|
|
@ -0,0 +1,788 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Functions, macros and enums related to pipe management when in USB Host mode. This
|
||||
* module contains the pipe management macros, as well as pipe interrupt and data
|
||||
* send/recieve functions for various datatypes.
|
||||
*/
|
||||
|
||||
#ifndef __PIPE_H__
|
||||
#define __PIPE_H__
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../../../Common/Common.h"
|
||||
#include "../HighLevel/USBTask.h"
|
||||
|
||||
#if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
|
||||
#include "StreamCallbacks.h"
|
||||
#endif
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Mask for Pipe_GetErrorFlags(), indicating that a CRC error occurred in the pipe on the received data. */
|
||||
#define PIPE_ERRORFLAG_CRC16 (1 << 4)
|
||||
|
||||
/** Mask for Pipe_GetErrorFlags(), indicating that a hardware timeout error occurred in the pipe. */
|
||||
#define PIPE_ERRORFLAG_TIMEOUT (1 << 3)
|
||||
|
||||
/** Mask for Pipe_GetErrorFlags(), indicating that a hardware PID error occurred in the pipe. */
|
||||
#define PIPE_ERRORFLAG_PID (1 << 2)
|
||||
|
||||
/** Mask for Pipe_GetErrorFlags(), indicating that a hardware data PID error occurred in the pipe. */
|
||||
#define PIPE_ERRORFLAG_DATAPID (1 << 1)
|
||||
|
||||
/** Mask for Pipe_GetErrorFlags(), indicating that a hardware data toggle error occurred in the pipe. */
|
||||
#define PIPE_ERRORFLAG_DATATGL (1 << 0)
|
||||
|
||||
/** Token mask for Pipe_ConfigurePipe(). This sets the pipe as a SETUP token (for CONTROL type pipes),
|
||||
* which will trigger a control request on the attached device when data is written to the pipe.
|
||||
*/
|
||||
#define PIPE_TOKEN_SETUP (0b00 << PTOKEN0)
|
||||
|
||||
/** Token mask for Pipe_ConfigurePipe(). This sets the pipe as a IN token (for non-CONTROL type pipes),
|
||||
* indicating that the pipe data will flow from device to host.
|
||||
*/
|
||||
#define PIPE_TOKEN_IN (0b01 << PTOKEN0)
|
||||
|
||||
/** Token mask for Pipe_ConfigurePipe(). This sets the pipe as a IN token (for non-CONTROL type pipes),
|
||||
* indicating that the pipe data will flow from host to device.
|
||||
*/
|
||||
#define PIPE_TOKEN_OUT (0b10 << PTOKEN0)
|
||||
|
||||
/** Mask for the bank mode selection for the Pipe_ConfigurePipe() macro. This indicates that the pipe
|
||||
* should have one single bank, which requires less USB FIFO memory but results in slower transfers as
|
||||
* only one USB device (the AVR or the attached device) can access the pipe's bank at the one time.
|
||||
*/
|
||||
#define PIPE_BANK_SINGLE 0
|
||||
|
||||
/** Mask for the bank mode selection for the Pipe_ConfigurePipe() macro. This indicates that the pipe
|
||||
* should have two banks, which requires more USB FIFO memory but results in faster transfers as one
|
||||
* USB device (the AVR or the attached device) can access one bank while the other accesses the second
|
||||
* bank.
|
||||
*/
|
||||
#define PIPE_BANK_DOUBLE (1 << EPBK0)
|
||||
|
||||
/** Pipe address for the default control pipe, which always resides in address 0. This is
|
||||
* defined for convenience to give more readable code when used with the pipe macros.
|
||||
*/
|
||||
#define PIPE_CONTROLPIPE 0
|
||||
|
||||
/** Default size of the default control pipe's bank, until altered by the Endpoint0Size value
|
||||
* in the device descriptor of the attached device.
|
||||
*/
|
||||
#define PIPE_CONTROLPIPE_DEFAULT_SIZE 8
|
||||
|
||||
/** Pipe number mask, for masking against pipe addresses to retrieve the pipe's numerical address
|
||||
* in the device.
|
||||
*/
|
||||
#define PIPE_PIPENUM_MASK 0x07
|
||||
|
||||
/** Total number of pipes (including the default control pipe at address 0) which may be used in
|
||||
* the device. Different USB AVR models support different amounts of pipes, this value reflects
|
||||
* the maximum number of pipes for the currently selected AVR model.
|
||||
*/
|
||||
#define PIPE_TOTAL_PIPES 7
|
||||
|
||||
/** Size in bytes of the largest pipe bank size possible in the device. Not all banks on each AVR
|
||||
* model supports the largest bank size possible on the device; different pipe numbers support
|
||||
* different maximum bank sizes. This value reflects the largest possible bank of any pipe on the
|
||||
* currently selected USB AVR model.
|
||||
*/
|
||||
#define PIPE_MAX_SIZE 256
|
||||
|
||||
/** Endpoint number mask, for masking against endpoint addresses to retrieve the endpoint's
|
||||
* numerical address in the attached device.
|
||||
*/
|
||||
#define PIPE_EPNUM_MASK 0x07
|
||||
|
||||
/** Endpoint bank size mask, for masking against endpoint addresses to retrieve the endpoint's
|
||||
* bank size in the attached device.
|
||||
*/
|
||||
#define PIPE_EPSIZE_MASK 0x7FF
|
||||
|
||||
/** Interrupt definition for the pipe IN interrupt (for INTERRUPT type pipes). Should be used with
|
||||
* the USB_INT_* macros located in USBInterrupt.h.
|
||||
*
|
||||
* This interrupt will fire if enabled on an INTERRUPT type pipe if the pipe interrupt period has
|
||||
* elapsed and the pipe is ready for the next packet from the attached device to be read out from its
|
||||
* FIFO buffer (if received).
|
||||
*
|
||||
* This interrupt must be enabled on *each* pipe which requires it (after the pipe is selected), and
|
||||
* will fire the common pipe interrupt vector.
|
||||
*
|
||||
* \see ENDPOINT_PIPE_vect for more information on the common pipe and endpoint interrupt vector.
|
||||
*/
|
||||
#define PIPE_INT_IN UPIENX, (1 << RXINE) , UPINTX, (1 << RXINI)
|
||||
|
||||
/** Interrupt definition for the pipe OUT interrupt (for INTERRUPT type pipes). Should be used with
|
||||
* the USB_INT_* macros located in USBInterrupt.h.
|
||||
*
|
||||
* This interrupt will fire if enabled on an INTERRUPT type endpoint if a the pipe interrupt period
|
||||
* has elapsed and the pipe is ready for a packet to be written to the pipe's FIFO buffer and sent
|
||||
* to the attached device (if required).
|
||||
*
|
||||
* This interrupt must be enabled on *each* pipe which requires it (after the pipe is selected), and
|
||||
* will fire the common pipe interrupt vector.
|
||||
*
|
||||
* \see ENDPOINT_PIPE_vect for more information on the common pipe and endpoint interrupt vector. */
|
||||
#define PIPE_INT_OUT UPIENX, (1 << TXOUTE), UPINTX, (1 << TXOUTI)
|
||||
|
||||
/** Interrupt definition for the pipe SETUP bank ready interrupt (for CONTROL type pipes). Should be
|
||||
* used with the USB_INT_* macros located in USBInterrupt.h.
|
||||
*
|
||||
* This interrupt will fire if enabled on an CONTROL type pipe when the pipe is ready for a new
|
||||
* control request.
|
||||
*
|
||||
* This interrupt must be enabled on *each* pipe which requires it (after the pipe is selected), and
|
||||
* will fire the common pipe interrupt vector.
|
||||
*
|
||||
* \see ENDPOINT_PIPE_vect for more information on the common pipe and endpoint interrupt vector.
|
||||
*/
|
||||
#define PIPE_INT_SETUP UPIENX, (1 << TXSTPE) , UPINTX, (1 << TXSTPI)
|
||||
|
||||
/** Interrupt definition for the pipe error interrupt. Should be used with the USB_INT_* macros
|
||||
* located in USBInterrupt.h.
|
||||
*
|
||||
* This interrupt will fire if enabled on a particular pipe if an error occurs on that pipe, such
|
||||
* as a CRC mismatch error.
|
||||
*
|
||||
* This interrupt must be enabled on *each* pipe which requires it (after the pipe is selected), and
|
||||
* will fire the common pipe interrupt vector.
|
||||
*
|
||||
* \see ENDPOINT_PIPE_vect for more information on the common pipe and endpoint interrupt vector.
|
||||
*
|
||||
* \see Pipe_GetErrorFlags() for more information on the pipe errors.
|
||||
*/
|
||||
#define PIPE_INT_ERROR UPIENX, (1 << PERRE), UPINTX, (1 << PERRI)
|
||||
|
||||
/** Interrupt definition for the pipe NAK received interrupt. Should be used with the USB_INT_* macros
|
||||
* located in USBInterrupt.h.
|
||||
*
|
||||
* This interrupt will fire if enabled on a particular pipe if an attached device returns a NAK in
|
||||
* response to a sent packet.
|
||||
*
|
||||
* This interrupt must be enabled on *each* pipe which requires it (after the pipe is selected), and
|
||||
* will fire the common pipe interrupt vector.
|
||||
*
|
||||
* \see ENDPOINT_PIPE_vect for more information on the common pipe and endpoint interrupt vector.
|
||||
*
|
||||
* \see Pipe_IsNAKReceived() for more information on pipe NAKs.
|
||||
*/
|
||||
#define PIPE_INT_NAK UPIENX, (1 << NAKEDE), UPINTX, (1 << NAKEDI)
|
||||
|
||||
/** Interrupt definition for the pipe STALL received interrupt. Should be used with the USB_INT_* macros
|
||||
* located in USBInterrupt.h.
|
||||
*
|
||||
* This interrupt will fire if enabled on a particular pipe if an attached device returns a STALL on the
|
||||
* currently selected pipe. This will also fire if the pipe is an isochronous pipe and a CRC error occurs.
|
||||
*
|
||||
* This interrupt must be enabled on *each* pipe which requires it (after the pipe is selected), and
|
||||
* will fire the common pipe interrupt vector.
|
||||
*
|
||||
* \see ENDPOINT_PIPE_vect for more information on the common pipe and endpoint interrupt vector.
|
||||
*/
|
||||
#define PIPE_INT_STALL UPIENX, (1 << RXSTALLE), UPINTX, (1 << RXSTALLI)
|
||||
|
||||
/** Indicates the number of bytes currently stored in the current pipe's selected bank. */
|
||||
#define Pipe_BytesInPipe() UPBCX
|
||||
|
||||
/** Resets the desired pipe, including the pipe banks and flags. */
|
||||
#define Pipe_ResetPipe(pipenum) MACROS{ UPRST = (1 << pipenum); UPRST = 0; }MACROE
|
||||
|
||||
/** Selects the given pipe number. Any pipe operations which do not require the pipe number to be
|
||||
* indicated will operate on the currently selected pipe.
|
||||
*/
|
||||
#define Pipe_SelectPipe(pipenum) MACROS{ UPNUM = pipenum; }MACROE
|
||||
|
||||
/** Returns the pipe address of the currently selected pipe. This is typically used to save the
|
||||
* currently selected pipe number so that it can be restored after another pipe has been manipulated.
|
||||
*/
|
||||
#define Pipe_GetCurrentPipe() (UPNUM & PIPE_PIPENUM_MASK)
|
||||
|
||||
/** Enables the currently selected pipe so that data can be sent and received through it to and from
|
||||
* an attached device.
|
||||
*
|
||||
* \note Pipes must first be configured properly rather than just being enabled via the
|
||||
* Pipe_ConfigurePipe() macro, which calls Pipe_EnablePipe() automatically.
|
||||
*/
|
||||
#define Pipe_EnablePipe() MACROS{ UPCONX |= (1 << PEN); }MACROE
|
||||
|
||||
/** Disables the currently selected pipe so that data cannot be sent and received through it to and
|
||||
* from an attached device.
|
||||
*/
|
||||
#define Pipe_DisablePipe() MACROS{ UPCONX &= ~(1 << PEN); }MACROE
|
||||
|
||||
/** Returns true if the currently selected pipe is enabled, false otherwise. */
|
||||
#define Pipe_IsEnabled() ((UPCONX & (1 << PEN)) ? true : false)
|
||||
|
||||
/** Sets the token for the currently selected endpoint to one of the tokens specified by the PIPE_TOKEN_*
|
||||
* masks. This should only be used on CONTROL type endpoints, to allow for bidirectional transfer of
|
||||
* data during control requests.
|
||||
*/
|
||||
#define Pipe_SetToken(token) MACROS{ UPCFG0X = ((UPCFG0X & ~PIPE_TOKEN_MASK) | token); }MACROE
|
||||
|
||||
/** Configures the currently selected pipe to allow for an unlimited number of IN requests. */
|
||||
#define Pipe_SetInfiniteINRequests() MACROS{ UPCONX |= (1 << INMODE); }MACROE
|
||||
|
||||
/** Configures the currently selected pipe to only allow the specified number of IN requests to be
|
||||
* accepted by the pipe before it is automatically frozen.
|
||||
*/
|
||||
#define Pipe_SetFiniteINRequests(n) MACROS{ UPCONX &= ~(1 << INMODE); UPINRQX = n; }MACROE
|
||||
|
||||
/** Returns true if the currently selected pipe is configured, false otherwise. */
|
||||
#define Pipe_IsConfigured() ((UPSTAX & (1 << CFGOK)) ? true : false)
|
||||
|
||||
/** Sets the period between interrupts for an INTERRUPT type pipe to a specified number of milliseconds. */
|
||||
#define Pipe_SetInterruptPeriod(ms) MACROS{ UPCFG2X = ms; }MACROE
|
||||
|
||||
/** Returns a mask indicating which pipe's interrupt periods have elapsed, indicating that the pipe should
|
||||
* be serviced.
|
||||
*/
|
||||
#define Pipe_GetPipeInterrupts() UPINT
|
||||
|
||||
/** Clears the interrupt flag for the specified pipe number. */
|
||||
#define Pipe_ClearPipeInterrupt(n) MACROS{ UPINT &= ~(1 << n); }MACROE
|
||||
|
||||
/** Returns true if the specified pipe's interrupt period has elapsed, false otherwise. */
|
||||
#define Pipe_HasPipeInterrupted(n) ((UPINT & (1 << n)) ? true : false)
|
||||
|
||||
/** Clears the pipe bank, and switches to the alternate bank if the currently selected pipe is
|
||||
* dual-banked. When cleared, this either frees the bank up for the next packet from the host
|
||||
* (if the endpoint is of the OUT direction) or sends the packet contents to the host (if the
|
||||
* pipe is of the IN direction).
|
||||
*/
|
||||
#define Pipe_ClearCurrentBank() MACROS{ UPINTX &= ~(1 << FIFOCON); }MACROE
|
||||
|
||||
/** Unfreezes the pipe, allowing it to communicate with an attached device. */
|
||||
#define Pipe_Unfreeze() MACROS{ UPCONX &= ~(1 << PFREEZE); }MACROE
|
||||
|
||||
/** Freezes the pipe, preventing it from communicating with an attached device. */
|
||||
#define Pipe_Freeze() MACROS{ UPCONX |= (1 << PFREEZE); }MACROE
|
||||
|
||||
/** Clears the master pipe error flag. */
|
||||
#define Pipe_ClearError() MACROS{ UPINTX &= ~(1 << PERRI); }MACROE
|
||||
|
||||
/** Returns true if the master pipe error flag is set for the currently selected pipe, indicating that
|
||||
* some sort of hardware error has occurred on the pipe.
|
||||
*
|
||||
* \see Pipe_GetErrorFlags() macro for information on retreiving the exact error flag.
|
||||
*/
|
||||
#define Pipe_IsError() ((UPINTX & (1 << PERRI)) ? true : false)
|
||||
|
||||
/** Clears all the currently selected pipe's hardware error flags, but does not clear the master error
|
||||
* flag for the pipe. */
|
||||
#define Pipe_ClearErrorFlags() MACROS{ UPERRX = 0; }MACROE
|
||||
|
||||
/** Returns a mask of the hardware error flags which have occured on the currently selected pipe. This
|
||||
* value can then be masked against the PIPE_ERRORFLAG_* masks to determine what error has occurred.
|
||||
*/
|
||||
#define Pipe_GetErrorFlags() UPERRX
|
||||
|
||||
/** Returns true if the currently selected pipe may be read from (if data is waiting in the pipe
|
||||
* bank and the pipe is an IN direction, or if the bank is not yet full if the pipe is an OUT
|
||||
* direction). This function will return false if an error has occured in the pipe, or if the pipe
|
||||
* is an IN direction and no packet has been received, or if the pipe is an OUT direction and the
|
||||
* pipe bank is full.
|
||||
*/
|
||||
#define Pipe_ReadWriteAllowed() ((UPINTX & (1 << RWAL)) ? true : false)
|
||||
|
||||
/** Clears the flag indicating that a SETUP request has been sent to the attached device from the
|
||||
* currently selected CONTROL type pipe.
|
||||
*/
|
||||
#define Pipe_ClearSetupSent() MACROS{ UPINTX &= ~(1 << TXSTPI); }MACROE
|
||||
|
||||
/** Returns true if no SETUP request is currently being sent to the attached device, false otherwise. */
|
||||
#define Pipe_IsSetupSent() ((UPINTX & (1 << TXSTPI)) ? true : false)
|
||||
|
||||
/** Returns true if the currently selected pipe has been stalled by the attached device, false otherwise. */
|
||||
#define Pipe_IsStalled() ((UPINTX & (1 << RXSTALLI)) ? true : false)
|
||||
|
||||
/** Clears the stall condition on the currently selected pipe. */
|
||||
#define Pipe_ClearStall() MACROS{ UPINTX &= ~(1 << RXSTALLI); }MACROE
|
||||
|
||||
/** Returns true if an IN request has been received on the currently selected CONTROL type pipe, false
|
||||
* otherwise.
|
||||
*/
|
||||
#define Pipe_IsSetupINReceived() ((UPINTX & (1 << RXINI)) ? true : false)
|
||||
|
||||
/** Returns true if the currently selected CONTROL type pipe is ready to send an OUT request, false
|
||||
* otherwise.
|
||||
*/
|
||||
#define Pipe_IsSetupOUTReady() ((UPINTX & (1 << TXOUTI)) ? true : false)
|
||||
|
||||
/** Acknowedges the reception of a setup IN request from the attached device on the currently selected
|
||||
* CONTROL type endpoint, allowing for the transmission of a setup OUT packet, or the reception of
|
||||
* another setup IN packet.
|
||||
*/
|
||||
#define Pipe_ClearSetupIN() MACROS{ UPINTX &= ~(1 << RXINI); UPINTX &= ~(1 << FIFOCON); }MACROE
|
||||
|
||||
/** Sends the currently selected CONTROL type pipe's contents to the device as a setup OUT packet. */
|
||||
#define Pipe_ClearSetupOUT() MACROS{ UPINTX &= ~(1 << TXOUTI); UPINTX &= ~(1 << FIFOCON); }MACROE
|
||||
|
||||
/** Returns true if the device sent a NAK (Negative Acknowedge) in response to the last sent packet on
|
||||
* the currently selected pipe. This ocurrs when the host sends a packet to the device, but the device
|
||||
* is not currently ready to handle the packet (i.e. its endpoint banks are full). Once a NAK has been
|
||||
* received, it must be cleard using Pipe_ClearNAKReceived() before the previous (or any other) packet
|
||||
* can be re-sent.
|
||||
*/
|
||||
#define Pipe_IsNAKReceived() ((UPINTX & (1 << NAKEDI)) ? true : false)
|
||||
|
||||
/** Clears the NAK condition on the currently selected pipe.
|
||||
*
|
||||
* \see Pipe_IsNAKReceived() for more details.
|
||||
*/
|
||||
#define Pipe_ClearNAKReceived() MACROS{ UPINTX &= ~(1 << NAKEDI); }MACROE
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible error return codes of the Pipe_WaitUntilReady function */
|
||||
enum Pipe_WaitUntilReady_ErrorCodes_t
|
||||
{
|
||||
PIPE_READYWAIT_NoError = 0, /**< Pipe ready for next packet, no error */
|
||||
PIPE_READYWAIT_PipeStalled = 1, /**< The device stalled the pipe while waiting. */
|
||||
PIPE_READYWAIT_DeviceDisconnected = 2, /**< Device was disconnected from the host while waiting. */
|
||||
PIPE_READYWAIT_Timeout = 3, /**< The device failed to accept or send the next packet
|
||||
* within the software timeout period set by the
|
||||
* USB_STREAM_TIMEOUT_MS macro.
|
||||
*/
|
||||
};
|
||||
|
||||
/** Enum for the possible error return codes of the Pipe_*_Stream_* functions. */
|
||||
enum Pipe_Stream_RW_ErrorCodes_t
|
||||
{
|
||||
PIPE_RWSTREAM_ERROR_NoError = 0, /**< Command completed successfully, no error. */
|
||||
PIPE_RWSTREAM_ERROR_PipeStalled = 1, /**< The device stalled the pipe during the transfer. */
|
||||
PIPE_RWSTREAM_ERROR_DeviceDisconnected = 2, /**< Device was disconnected from the host during
|
||||
* the transfer.
|
||||
*/
|
||||
PIPE_RWSTREAM_ERROR_Timeout = 3, /**< The device failed to accept or send the next packet
|
||||
* within the software timeout period set by the
|
||||
* USB_STREAM_TIMEOUT_MS macro.
|
||||
*/
|
||||
PIPE_RWSTREAM_ERROR_CallbackAborted = 4, /**< Indicates that the stream's callback function aborted
|
||||
* the transfer early.
|
||||
*/
|
||||
};
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Reads one byte from the currently selected pipe's bank, for OUT direction pipes. */
|
||||
static inline uint8_t Pipe_Read_Byte(void) ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint8_t Pipe_Read_Byte(void)
|
||||
{
|
||||
return UPDATX;
|
||||
}
|
||||
|
||||
/** Writes one byte from the currently selected pipe's bank, for IN direction pipes. */
|
||||
static inline void Pipe_Write_Byte(const uint8_t Byte)
|
||||
{
|
||||
UPDATX = Byte;
|
||||
}
|
||||
|
||||
/** Discards one byte from the currently selected pipe's bank, for OUT direction pipes. */
|
||||
static inline void Pipe_Discard_Byte(void)
|
||||
{
|
||||
uint8_t Dummy;
|
||||
|
||||
Dummy = UPDATX;
|
||||
}
|
||||
|
||||
/** Reads two bytes from the currently selected pipe's bank in little endian format, for OUT
|
||||
* direction pipes.
|
||||
*/
|
||||
static inline uint16_t Pipe_Read_Word_LE(void) ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint16_t Pipe_Read_Word_LE(void)
|
||||
{
|
||||
uint16_t Data;
|
||||
|
||||
Data = UPDATX;
|
||||
Data |= (((uint16_t)UPDATX) << 8);
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
/** Reads two bytes from the currently selected pipe's bank in big endian format, for OUT
|
||||
* direction pipes.
|
||||
*/
|
||||
static inline uint16_t Pipe_Read_Word_BE(void) ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint16_t Pipe_Read_Word_BE(void)
|
||||
{
|
||||
uint16_t Data;
|
||||
|
||||
Data = (((uint16_t)UPDATX) << 8);
|
||||
Data |= UPDATX;
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
/** Writes two bytes to the currently selected pipe's bank in little endian format, for IN
|
||||
* direction pipes.
|
||||
*/
|
||||
static inline void Pipe_Write_Word_LE(const uint16_t Word)
|
||||
{
|
||||
UPDATX = (Word & 0xFF);
|
||||
UPDATX = (Word >> 8);
|
||||
}
|
||||
|
||||
/** Writes two bytes to the currently selected pipe's bank in big endian format, for IN
|
||||
* direction pipes.
|
||||
*/
|
||||
static inline void Pipe_Write_Word_BE(const uint16_t Word)
|
||||
{
|
||||
UPDATX = (Word >> 8);
|
||||
UPDATX = (Word & 0xFF);
|
||||
}
|
||||
|
||||
/** Discards two bytes from the currently selected pipe's bank, for OUT direction pipes. */
|
||||
static inline void Pipe_Ignore_Word(void)
|
||||
{
|
||||
uint8_t Dummy;
|
||||
|
||||
Dummy = UPDATX;
|
||||
Dummy = UPDATX;
|
||||
}
|
||||
|
||||
/** Reads four bytes from the currently selected pipe's bank in little endian format, for OUT
|
||||
* direction pipes.
|
||||
*/
|
||||
static inline uint32_t Pipe_Read_DWord_LE(void) ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint32_t Pipe_Read_DWord_LE(void)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t DWord;
|
||||
uint8_t Bytes[4];
|
||||
} Data;
|
||||
|
||||
Data.Bytes[0] = UPDATX;
|
||||
Data.Bytes[1] = UPDATX;
|
||||
Data.Bytes[2] = UPDATX;
|
||||
Data.Bytes[3] = UPDATX;
|
||||
|
||||
return Data.DWord;
|
||||
}
|
||||
|
||||
/** Reads four bytes from the currently selected pipe's bank in big endian format, for OUT
|
||||
* direction pipes.
|
||||
*/
|
||||
static inline uint32_t Pipe_Read_DWord_BE(void) ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint32_t Pipe_Read_DWord_BE(void)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t DWord;
|
||||
uint8_t Bytes[4];
|
||||
} Data;
|
||||
|
||||
Data.Bytes[3] = UPDATX;
|
||||
Data.Bytes[2] = UPDATX;
|
||||
Data.Bytes[1] = UPDATX;
|
||||
Data.Bytes[0] = UPDATX;
|
||||
|
||||
return Data.DWord;
|
||||
}
|
||||
|
||||
/** Writes four bytes to the currently selected pipe's bank in little endian format, for IN
|
||||
* direction pipes.
|
||||
*/
|
||||
static inline void Pipe_Write_DWord_LE(const uint32_t DWord)
|
||||
{
|
||||
Pipe_Write_Word_LE(DWord);
|
||||
Pipe_Write_Word_LE(DWord >> 16);
|
||||
}
|
||||
|
||||
/** Writes four bytes to the currently selected pipe's bank in big endian format, for IN
|
||||
* direction pipes.
|
||||
*/
|
||||
static inline void Pipe_Write_DWord_BE(const uint32_t DWord)
|
||||
{
|
||||
Pipe_Write_Word_BE(DWord >> 16);
|
||||
Pipe_Write_Word_BE(DWord);
|
||||
}
|
||||
|
||||
/** Discards four bytes from the currently selected pipe's bank, for OUT direction pipes. */
|
||||
static inline void Pipe_Ignore_DWord(void)
|
||||
{
|
||||
uint8_t Dummy;
|
||||
|
||||
Dummy = UPDATX;
|
||||
Dummy = UPDATX;
|
||||
Dummy = UPDATX;
|
||||
Dummy = UPDATX;
|
||||
}
|
||||
|
||||
/* External Variables: */
|
||||
/** Global indicating the maximum packet size of the default control pipe located at address
|
||||
* 0 in the device. This value is set to the value indicated in the attached device's device
|
||||
* descriptor once the USB interface is initialized into host mode and a device is attached
|
||||
* to the USB bus.
|
||||
*
|
||||
* \note This variable should be treated as read-only in the user application, and never manually
|
||||
* changed in value.
|
||||
*/
|
||||
extern uint8_t USB_ControlPipeSize;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the specified pipe number with the given pipe type, token, target endpoint number in the
|
||||
* attached device, bank size and banking mode. Pipes should be allocated in ascending order by their
|
||||
* address in the device (i.e. pipe 1 should be configured before pipe 2 and so on).
|
||||
*
|
||||
* The pipe type may be one of the EP_TYPE_* macros listed in LowLevel.h, the token may be one of the
|
||||
* PIPE_TOKEN_* masks.
|
||||
*
|
||||
* The bank size must indicate the maximum packet size that the pipe can handle. Different pipe
|
||||
* numbers can handle different maximum packet sizes - refer to the chosen USB AVR's datasheet to
|
||||
* determine the maximum bank size for each pipe.
|
||||
*
|
||||
* The banking mode may be either PIPE_BANK_SINGLE or PIPE_BANK_DOUBLE.
|
||||
*
|
||||
* A newly configured pipe is frozen by default, and must be unfrozen before use via the Pipe_Unfreeze() macro.
|
||||
*
|
||||
* \note This routine will select the specified pipe, and the pipe will remain selected once the
|
||||
* routine completes regardless of if the pipe configuration succeeds.
|
||||
*
|
||||
* \return Boolean true if the configuration is successful, false otherwise
|
||||
*/
|
||||
bool Pipe_ConfigurePipe(const uint8_t Number, const uint8_t Type, const uint8_t Token, const uint8_t EndpointNumber,
|
||||
const uint16_t Size, const uint8_t Banks);
|
||||
|
||||
/** Spinloops until the currently selected non-control pipe is ready for the next packed of data
|
||||
* to be read or written to it.
|
||||
*
|
||||
* \note This routine should not be called on CONTROL type pipes.
|
||||
*
|
||||
* \return A value from the Pipe_WaitUntilReady_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Pipe_WaitUntilReady(void);
|
||||
|
||||
/** Writes the given number of bytes to the pipe from the given buffer in little endian,
|
||||
* sending full packets to the device as needed. The last packet filled is not automatically sent;
|
||||
* the user is responsible for manually sending the last written packet to the host via the
|
||||
* Pipe_ClearCurrentBank() macro. Between each USB packet, the given stream callback function is
|
||||
* executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers.
|
||||
*
|
||||
* The callback routine should be created using the STREAM_CALLBACK() macro. If the token
|
||||
* NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are disabled
|
||||
* and this function has the Callback parameter ommitted.
|
||||
*
|
||||
* \param Buffer Pointer to the source data buffer to read from.
|
||||
* \param Length Number of bytes to read for the currently selected pipe into the buffer.
|
||||
* \param Callback Name of a callback routine to call between sucessive USB packet transfers, NULL if no callback
|
||||
*
|
||||
* \return A value from the Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Pipe_Write_Stream_LE(const void* Buffer, uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Writes the given number of bytes to the pipe from the given buffer in big endian,
|
||||
* sending full packets to the device as needed. The last packet filled is not automatically sent;
|
||||
* the user is responsible for manually sending the last written packet to the host via the
|
||||
* Pipe_ClearCurrentBank() macro. Between each USB packet, the given stream callback function is
|
||||
* executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers.
|
||||
*
|
||||
* The callback routine should be created using the STREAM_CALLBACK() macro. If the token
|
||||
* NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are disabled
|
||||
* and this function has the Callback parameter ommitted.
|
||||
*
|
||||
* \param Buffer Pointer to the source data buffer to read from.
|
||||
* \param Length Number of bytes to read for the currently selected pipe into the buffer.
|
||||
* \param Callback Name of a callback routine to call between sucessive USB packet transfers, NULL if no callback
|
||||
*
|
||||
* \return A value from the Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Pipe_Write_Stream_BE(const void* Buffer, uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Reads and discards the given number of bytes from the pipe, discarding fully read packets from the host
|
||||
* as needed. The last packet is not automatically discarded once the remaining bytes has been read; the
|
||||
* user is responsible for manually discarding the last packet from the host via the Pipe_ClearCurrentBank() macro.
|
||||
* Between each USB packet, the given stream callback function is executed repeatedly until the next packet is ready,
|
||||
* allowing for early aborts of stream transfers.
|
||||
*
|
||||
* The callback routine should be created using the STREAM_CALLBACK() macro. If the token
|
||||
* NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are disabled
|
||||
* and this function has the Callback parameter ommitted.
|
||||
*
|
||||
* \param Length Number of bytes to send via the currently selected pipe.
|
||||
* \param Callback Name of a callback routine to call between sucessive USB packet transfers, NULL if no callback
|
||||
*
|
||||
* \return A value from the Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Pipe_Discard_Stream(uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
);
|
||||
|
||||
/** Reads the given number of bytes from the pipe into the given buffer in little endian,
|
||||
* sending full packets to the device as needed. The last packet filled is not automatically sent;
|
||||
* the user is responsible for manually sending the last written packet to the host via the
|
||||
* Pipe_ClearCurrentBank() macro. Between each USB packet, the given stream callback function is
|
||||
* executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers.
|
||||
*
|
||||
* The callback routine should be created using the STREAM_CALLBACK() macro. If the token
|
||||
* NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are disabled
|
||||
* and this function has the Callback parameter ommitted.
|
||||
*
|
||||
* \param Buffer Pointer to the source data buffer to write to.
|
||||
* \param Length Number of bytes to read for the currently selected pipe to read from.
|
||||
* \param Callback Name of a callback routine to call between sucessive USB packet transfers, NULL if no callback
|
||||
*
|
||||
* \return A value from the Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Pipe_Read_Stream_LE(void* Buffer, uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/** Reads the given number of bytes from the pipe into the given buffer in big endian,
|
||||
* sending full packets to the device as needed. The last packet filled is not automatically sent;
|
||||
* the user is responsible for manually sending the last written packet to the host via the
|
||||
* Pipe_ClearCurrentBank() macro. Between each USB packet, the given stream callback function is
|
||||
* executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers.
|
||||
*
|
||||
* The callback routine should be created using the STREAM_CALLBACK() macro. If the token
|
||||
* NO_STREAM_CALLBACKS is passed via the -D option to the compiler, stream callbacks are disabled
|
||||
* and this function has the Callback parameter ommitted.
|
||||
*
|
||||
* \param Buffer Pointer to the source data buffer to write to.
|
||||
* \param Length Number of bytes to read for the currently selected pipe to read from.
|
||||
* \param Callback Name of a callback routine to call between sucessive USB packet transfers, NULL if no callback
|
||||
*
|
||||
* \return A value from the Pipe_Stream_RW_ErrorCodes_t enum.
|
||||
*/
|
||||
uint8_t Pipe_Read_Stream_BE(void* Buffer, uint16_t Length
|
||||
#if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
|
||||
, uint8_t (* const Callback)(void)
|
||||
#endif
|
||||
) ATTR_NON_NULL_PTR_ARG(1);
|
||||
|
||||
/* Function Aliases: */
|
||||
/** Alias for Pipe_Discard_Byte().
|
||||
*/
|
||||
#define Pipe_Ignore_Byte() Pipe_Discard_Byte()
|
||||
|
||||
/** Alias for Pipe_Discard_Word().
|
||||
*/
|
||||
#define Pipe_Ignore_Word() Pipe_Discard_Word()
|
||||
|
||||
/** Alias for Pipe_Discard_DWord().
|
||||
*/
|
||||
#define Pipe_Ignore_DWord() Pipe_Discard_DWord()
|
||||
|
||||
/** Alias for Pipe_Read_Word_LE(). By default USB transfers use little endian format, thus
|
||||
* the command with no endianness specifier indicates little endian mode.
|
||||
*/
|
||||
#define Pipe_Read_Word() Pipe_Read_Word_LE()
|
||||
|
||||
/** Alias for Pipe_Write_Word_LE(). By default USB transfers use little endian format, thus
|
||||
* the command with no endianness specifier indicates little endian mode.
|
||||
*/
|
||||
#define Pipe_Write_Word(Word) Pipe_Write_Word_LE(Word)
|
||||
|
||||
/** Alias for Pipe_Read_DWord_LE(). By default USB transfers use little endian format, thus
|
||||
* the command with no endianness specifier indicates little endian mode.
|
||||
*/
|
||||
#define Pipe_Read_DWord() Pipe_Read_DWord_LE()
|
||||
|
||||
/** Alias for Pipe_Write_DWord_LE(). By default USB transfers use little endian format, thus
|
||||
* the command with no endianness specifier indicates little endian mode.
|
||||
*/
|
||||
#define Pipe_Write_DWord(DWord) Pipe_Write_DWord_LE(DWord)
|
||||
|
||||
/** Alias for Pipe_Read_Stream_LE(). By default USB transfers use little endian format, thus
|
||||
* the command with no endianness specifier indicates little endian mode.
|
||||
*/
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
#define Pipe_Read_Stream(Buffer, Length, Callback) Pipe_Read_Stream_LE(Buffer, Length, Callback)
|
||||
#else
|
||||
#define Pipe_Read_Stream(Buffer, Length) Pipe_Read_Stream_LE(Buffer, Length)
|
||||
#endif
|
||||
|
||||
/** Alias for Pipe_Write_Stream_LE(). By default USB transfers use little endian format, thus
|
||||
* the command with no endianness specifier indicates little endian mode.
|
||||
*/
|
||||
#if !defined(NO_STREAM_CALLBACKS)
|
||||
#define Pipe_Write_Stream(Buffer, Length, Callback) Pipe_Read_Stream_LE(Buffer, Length, Callback)
|
||||
#else
|
||||
#define Pipe_Write_Stream(Buffer, Length) Pipe_Read_Stream_LE(Buffer, Length)
|
||||
#endif
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define PIPE_TOKEN_MASK (0x03 << PTOKEN0)
|
||||
|
||||
#define Pipe_AllocateMemory() MACROS{ UPCFG1X |= (1 << ALLOC); }MACROE
|
||||
#define Pipe_DeallocateMemory() MACROS{ UPCFG1X &= ~(1 << ALLOC); }MACROE
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Pipe_ClearPipes(void);
|
||||
|
||||
/* Inline Functions: */
|
||||
static inline uint8_t Pipe_BytesToEPSizeMask(uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST ATTR_ALWAYSINLINE;
|
||||
static inline uint8_t Pipe_BytesToEPSizeMask(uint16_t Bytes)
|
||||
{
|
||||
if (Bytes <= 8)
|
||||
return (0 << EPSIZE0);
|
||||
else if (Bytes <= 16)
|
||||
return (1 << EPSIZE0);
|
||||
else if (Bytes <= 32)
|
||||
return (2 << EPSIZE0);
|
||||
else if (Bytes <= 64)
|
||||
return (3 << EPSIZE0);
|
||||
else if (Bytes <= (8 << 4))
|
||||
return (4 << EPSIZE0);
|
||||
else
|
||||
return (5 << EPSIZE0);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
191
LUFA/Drivers/USB/LowLevel/StdRequestType.h
Normal file
191
LUFA/Drivers/USB/LowLevel/StdRequestType.h
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Contains definitions for the various control request parameters, so that the request details (such as data
|
||||
* direction, request recipient, etc.) can be extracted via masking.
|
||||
*/
|
||||
|
||||
#ifndef __STDREQTYPE_H__
|
||||
#define __STDREQTYPE_H__
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Mask for the request type parameter, to indicate the direction of the request data (Host to Device
|
||||
* or Device to Host). The result of this mask should then be compared to the request direction masks.
|
||||
*
|
||||
* \see REQDIR_* macros for masks indicating the request data direction.
|
||||
*/
|
||||
#define CONTROL_REQTYPE_DIRECTION 0b10000000
|
||||
|
||||
/** Mask for the request type parameter, to indicate the type of request (Device, Class or Vendor
|
||||
* Specific). The result of this mask should then be compared to the request type masks.
|
||||
*
|
||||
* \see REQTYPE_* macros for masks indicating the request type.
|
||||
*/
|
||||
#define CONTROL_REQTYPE_TYPE 0b01100000
|
||||
|
||||
/** Mask for the request type parameter, to indicate the recipient of the request (Standard, Class
|
||||
* or Vendor Specific). The result of this mask should then be compared to the request recipient
|
||||
* masks.
|
||||
*
|
||||
* \see REQREC_* macros for masks indicating the request recipient.
|
||||
*/
|
||||
#define CONTROL_REQTYPE_RECIPIENT 0b00011111
|
||||
|
||||
/** Request data direction mask, indicating that the request data will flow from host to device.
|
||||
*
|
||||
* \see CONTROL_REQTYPE_DIRECTION macro.
|
||||
*/
|
||||
#define REQDIR_HOSTTODEVICE (0 << 7)
|
||||
|
||||
/** Request data direction mask, indicating that the request data will flow from device to host.
|
||||
*
|
||||
* \see CONTROL_REQTYPE_DIRECTION macro.
|
||||
*/
|
||||
#define REQDIR_DEVICETOHOST (1 << 7)
|
||||
|
||||
/** Request type mask, indicating that the request is a standard request.
|
||||
*
|
||||
* \see CONTROL_REQTYPE_TYPE macro.
|
||||
*/
|
||||
#define REQTYPE_STANDARD (0 << 5)
|
||||
|
||||
/** Request type mask, indicating that the request is a class-specific request.
|
||||
*
|
||||
* \see CONTROL_REQTYPE_TYPE macro.
|
||||
*/
|
||||
#define REQTYPE_CLASS (1 << 5)
|
||||
|
||||
/** Request type mask, indicating that the request is a vendor specific request.
|
||||
*
|
||||
* \see CONTROL_REQTYPE_TYPE macro.
|
||||
*/
|
||||
#define REQTYPE_VENDOR (2 << 5)
|
||||
|
||||
/** Request recipient mask, indicating that the request is to be issued to the device as a whole.
|
||||
*
|
||||
* \see CONTROL_REQTYPE_RECIPIENT macro.
|
||||
*/
|
||||
#define REQREC_DEVICE (0 << 0)
|
||||
|
||||
/** Request recipient mask, indicating that the request is to be issued to an interface in the
|
||||
* currently selected configuration.
|
||||
*
|
||||
* \see CONTROL_REQTYPE_RECIPIENT macro.
|
||||
*/
|
||||
#define REQREC_INTERFACE (1 << 0)
|
||||
|
||||
/** Request recipient mask, indicating that the request is to be issued to an endpoint in the
|
||||
* currently selected configuration.
|
||||
*
|
||||
* \see CONTROL_REQTYPE_RECIPIENT macro.
|
||||
*/
|
||||
#define REQREC_ENDPOINT (2 << 0)
|
||||
|
||||
/** Request recipient mask, indicating that the request is to be issued to an unspecified element
|
||||
* in the currently selected configuration.
|
||||
*
|
||||
* \see CONTROL_REQTYPE_RECIPIENT macro.
|
||||
*/
|
||||
#define REQREC_OTHER (3 << 0)
|
||||
|
||||
/** Feature indicator for Clear Feature or Set Feature commands. When used in a Clear Feature
|
||||
* request this indicates that an endpoint (whose address is given elsewhere in the request
|
||||
* should have its stall condition cleared. If used in a similar manner inside a Set Feature
|
||||
* request, this stalls an endpoint.
|
||||
*/
|
||||
#define FEATURE_ENDPOINT_HALT 0x00
|
||||
|
||||
/** Feature indicator for Clear Feature or Set Feature commands. When used in a Clear Feature
|
||||
* request this indicates that the remote wakeup enabled device should not issue remote
|
||||
* wakeup requests until further notice. If used in a similar manner inside a Set Feature
|
||||
* request, this re-enabled the remote wakeup feature on the device.
|
||||
*/
|
||||
#define FEATURE_REMOTE_WAKEUP 0x01
|
||||
|
||||
/* Enums: */
|
||||
/** Enumeration for the various standard request commands. These commands are applicable when the
|
||||
* request type is REQTYPE_STANDARD (with the exception of REQ_GetDescriptor, which is always
|
||||
* handled regardless of the request type value).
|
||||
*
|
||||
* \see Chapter 9 of the USB 2.0 Specification.
|
||||
*/
|
||||
enum USB_Control_Request_t
|
||||
{
|
||||
REQ_GetStatus = 0, /**< Implemented in the library for device, endpoint and interface
|
||||
* recipients. Passed to the user application for other recipients
|
||||
* via the USB_UnhandledControlPacket() event when received in
|
||||
* device mode. */
|
||||
REQ_ClearFeature = 1, /**< Implemented in the library for device, endpoint and interface
|
||||
* recipients. Passed to the user application for other recipients
|
||||
* via the USB_UnhandledControlPacket() event when received in
|
||||
* device mode. */
|
||||
REQ_SetFeature = 3, /**< Implemented in the library for device, endpoint and interface
|
||||
* recipients. Passed to the user application for other recipients
|
||||
* via the USB_UnhandledControlPacket() event when received in
|
||||
* device mode. */
|
||||
REQ_SetAddress = 5, /**< Implemented in the library for the device recipient. Passed
|
||||
* to the user application for other recipients via the
|
||||
* USB_UnhandledControlPacket() event when received in
|
||||
* device mode. */
|
||||
REQ_GetDescriptor = 6, /**< Implemented in the library for all recipients and all request
|
||||
* types. */
|
||||
REQ_SetDescriptor = 7, /**< Not implemented in the library, passed to the user application
|
||||
* via the USB_UnhandledControlPacket() event when received in
|
||||
* device mode. */
|
||||
REQ_GetConfiguration = 8, /**< Implemented in the library for the device recipient. Passed
|
||||
* to the user application for other recipients via the
|
||||
* USB_UnhandledControlPacket() event when received in
|
||||
* device mode. */
|
||||
REQ_SetConfiguration = 9, /**< Implemented in the library for the device recipient. Passed
|
||||
* to the user application for other recipients via the
|
||||
* USB_UnhandledControlPacket() event when received in
|
||||
* device mode. */
|
||||
REQ_GetInterface = 10, /**< Not implemented in the library, passed to the user application
|
||||
* via the USB_UnhandledControlPacket() event when received in
|
||||
* device mode. */
|
||||
REQ_SetInterface = 11, /**< Not implemented in the library, passed to the user application
|
||||
* via the USB_UnhandledControlPacket() event when received in
|
||||
* device mode. */
|
||||
REQ_SynchFrame = 12, /**< Not implemented in the library, passed to the user application
|
||||
* via the USB_UnhandledControlPacket() event when received in
|
||||
* device mode. */
|
||||
};
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define FEATURE_SELFPOWERED_ENABLED (1 << 0)
|
||||
#define FEATURE_REMOTE_WAKEUP_ENABLED (1 << 1)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
87
LUFA/Drivers/USB/LowLevel/StreamCallbacks.h
Normal file
87
LUFA/Drivers/USB/LowLevel/StreamCallbacks.h
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Macros and enums for the stream callback routines in Endpoint.h and Pipe.c. This module contains the
|
||||
* code required to easily set up stream callback functions which can be used to force early abort of a
|
||||
* stream read/write process.
|
||||
*/
|
||||
|
||||
#ifndef __STREAMCALLBACK_H__
|
||||
#define __STREAMCALLBACK_H__
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Creates a prototype for or begins a stream callback routine. Stream callback routines are small
|
||||
* routines which are executed during stream read or writes (if the callback-enabled versions of
|
||||
* these functions are used) which allow the user application to abort the transfer when certain
|
||||
* arbitrary conditions are met.
|
||||
*
|
||||
* Stream callback functions should return a value from the StreamCallback_Return_ErrorCodes_t
|
||||
* enum.
|
||||
*
|
||||
* Usage Example (Device Endpoint, but applicable for Host pipes also):
|
||||
* \code
|
||||
* STREAM_CALLBACK(GlobalNotSet); // Callback Prototype
|
||||
*
|
||||
* STREAM_CALLBACK(GlobalNotSet)
|
||||
* {
|
||||
* if (MyGlobal == false)
|
||||
* return ENDPOINT_STREAMCALLBACK_Continue;
|
||||
* else
|
||||
* return ENDPOINT_STREAMCALLBACK_Abort;
|
||||
* }
|
||||
*
|
||||
* //...
|
||||
* // Inside some routine:
|
||||
* if (Endpoint_Write_CStream_LE(DataBuffer, sizeof(DataBuffer), GlobalNotSet) ==
|
||||
* ENDPOINT_RWSTREAM_ERROR_CallbackAborted)
|
||||
* {
|
||||
* // Do something when the callback aborted the transfer early
|
||||
* }
|
||||
* \endcode
|
||||
*/
|
||||
#define STREAM_CALLBACK(name) uint8_t name (void)
|
||||
|
||||
/** Used with the Endpoint and Pipe stream functions as the callback function parameter, indicating that the stream
|
||||
* call has no callback function to be called between USB packets.
|
||||
*/
|
||||
#define NO_STREAM_CALLBACK NULL
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible error return codes of a stream callback function */
|
||||
enum StreamCallback_Return_ErrorCodes_t
|
||||
{
|
||||
STREAMCALLBACK_Continue = 0, /**< Continue sending or receiving the stream. */
|
||||
STREAMCALLBACK_Abort = 1, /**< Abort the stream send or reciving process. */
|
||||
};
|
||||
|
||||
#endif
|
||||
77
LUFA/Drivers/USB/LowLevel/USBMode.h
Normal file
77
LUFA/Drivers/USB/LowLevel/USBMode.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaim all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#ifndef __USBMODE_H__
|
||||
#define __USBMODE_H__
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#if ((defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || \
|
||||
defined(__AVR_AT90USB162__) || defined(__AVR_AT90USB82__) || \
|
||||
defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || \
|
||||
defined(__AVR_ATmega32U6__)) && !defined(USB_DEVICE_ONLY))
|
||||
#define USB_DEVICE_ONLY
|
||||
#endif
|
||||
|
||||
#if (defined(__AVR_AT90USB162__) || defined(__AVR_AT90USB82__))
|
||||
#define USB_LIMITED_CONTROLLER
|
||||
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
|
||||
#define USB_MODIFIED_FULL_CONTROLLER
|
||||
#else
|
||||
#define USB_FULL_CONTROLLER
|
||||
#endif
|
||||
|
||||
#if (!defined(USB_DEVICE_ONLY) && !defined(USB_HOST_ONLY))
|
||||
#define USB_CAN_BE_BOTH
|
||||
#define USB_CAN_BE_HOST
|
||||
#define USB_CAN_BE_DEVICE
|
||||
#elif defined(USB_HOST_ONLY)
|
||||
#define USB_CAN_BE_HOST
|
||||
#define USB_CurrentMode USB_MODE_HOST
|
||||
#elif defined(USB_DEVICE_ONLY)
|
||||
#define USB_CAN_BE_DEVICE
|
||||
#define USB_CurrentMode USB_MODE_DEVICE
|
||||
#endif
|
||||
|
||||
#if (defined(USB_HOST_ONLY) && defined(USB_DEVICE_ONLY))
|
||||
#error USB_HOST_ONLY and USB_DEVICE_ONLY are mutually exclusive.
|
||||
#endif
|
||||
|
||||
#if (defined(USB_RAM_DESCRIPTORS) && defined(USE_EEPROM_DESCRIPTORS))
|
||||
#error USB_RAM_DESCRIPTORS and USE_EEPROM_DESCRIPTORS are mutually exclusive.
|
||||
#endif
|
||||
|
||||
#if defined(USE_STATIC_OPTIONS)
|
||||
#define USB_Options USE_STATIC_OPTIONS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue