Convert over internal pseudo-function macros to true inline functions for added type-safety and compile-checking.

pull/1469/head
Dean Camera 14 years ago
parent 2461ae508c
commit 9b0e4b8356

@ -65,6 +65,13 @@
#define Req_GetCapabilities 0x07 #define Req_GetCapabilities 0x07
#define Req_IndicatorPulse 0x40 #define Req_IndicatorPulse 0x40
#define TMC_REQUEST_STATUS_SUCCESS 0x01
#define TMC_REQUEST_STATUS_PENDING 0x02
#define TMC_REQUEST_STATUS_FAILED 0x80
#define TMC_REQUEST_STATUS_NOTRANSFER 0x81
#define TMC_REQUEST_STATUS_NOCHECKINITIATED 0x82
#define TMC_REQUEST_STATUS_CHECKINPROGRESS 0x83
/* Function Prototypes: */ /* Function Prototypes: */
void SetupHardware(void); void SetupHardware(void);
void TMC_Task(void); void TMC_Task(void);

@ -79,6 +79,44 @@
#define DATAFLASH_PAGES // TODO: Replace with the total number of pages inside one of the Dataflash ICs #define DATAFLASH_PAGES // TODO: Replace with the total number of pages inside one of the Dataflash ICs
/* Inline Functions: */ /* Inline Functions: */
/** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC.
* The AVR's SPI driver MUST be initialized before any of the dataflash commands are used.
*/
static inline void Dataflash_Init(void)
{
DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK;
DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK;
}
/** Determines the currently selected dataflash chip.
*
* \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected
* or a DATAFLASH_CHIPn mask (where n is the chip number).
*/
static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
static inline uint8_t Dataflash_GetSelectedChip(void)
{
return (DATAFLASH_CHIPCS_PORT & DATAFLASH_CHIPCS_MASK);
}
/** Selects the given dataflash chip.
*
* \param[in] ChipMask Mask of the Dataflash IC to select, in the form of DATAFLASH_CHIPn mask (where n is
* the chip number).
*/
static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE;
static inline void Dataflash_SelectChip(const uint8_t ChipMask)
{
DATAFLASH_CHIPCS_PORT = ((DATAFLASH_CHIPCS_PORT & ~DATAFLASH_CHIPCS_MASK) | ChipMask);
}
/** Deselects the current dataflash chip, so that no dataflash is selected. */
static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE;
static inline void Dataflash_DeselectChip(void)
{
Dataflash_SelectChip(DATAFLASH_NO_CHIP);
}
/** Selects a dataflash IC from the given page number, which should range from 0 to /** Selects a dataflash IC from the given page number, which should range from 0 to
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one
* dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside * dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside
@ -105,6 +143,28 @@
#endif #endif
} }
/** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive
* a new command.
*/
static inline void Dataflash_ToggleSelectedChipCS(void)
{
uint8_t SelectedChipMask = Dataflash_GetSelectedChip();
Dataflash_DeselectChip();
Dataflash_SelectChip(SelectedChipMask);
}
/** Spin-loops while the currently selected dataflash is busy executing a command, such as a main
* memory page program or main memory to buffer transfer.
*/
static inline void Dataflash_WaitWhileBusy(void)
{
Dataflash_ToggleSelectedChipCS();
Dataflash_SendByte(DF_CMD_GETSTATUS);
while (!(Dataflash_ReceiveByte() & DF_STATUS_READY));
Dataflash_ToggleSelectedChipCS();
}
/** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with
* dataflash commands which require a complete 24-byte address. * dataflash commands which require a complete 24-byte address.
* *

@ -91,34 +91,59 @@
*/ */
#define DATAFLASH_CHIP_MASK(index) __GET_DATAFLASH_MASK(index) #define DATAFLASH_CHIP_MASK(index) __GET_DATAFLASH_MASK(index)
/* Pseudo-Function Macros: */ /* Inline Functions: */
#if defined(__DOXYGEN__) /** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC.
* The AVR's SPI driver MUST be initialized before any of the dataflash commands are used.
*/
static inline void Dataflash_Init(void);
/** Determines the currently selected dataflash chip. /** Determines the currently selected dataflash chip.
* *
* \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected * \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected
* or a DATAFLASH_CHIPn mask (where n is the chip number). * or a DATAFLASH_CHIPn mask (where n is the chip number).
*/ */
static inline uint8_t Dataflash_GetSelectedChip(void); static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
/** Selects the given dataflash chip. /** Selects the given dataflash chip.
* *
* \param[in] ChipMask Mask of the Dataflash IC to select, in the form of DATAFLASH_CHIPn mask (where n is * \param[in] ChipMask Mask of the Dataflash IC to select, in the form of DATAFLASH_CHIPn mask (where n is
* the chip number). * the chip number).
*/ */
static inline void Dataflash_SelectChip(uint8_t ChipMask); static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE;
/** Deselects the current dataflash chip, so that no dataflash is selected. */ /** Deselects the current dataflash chip, so that no dataflash is selected. */
static inline void Dataflash_DeselectChip(void); static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE;
#else
#define Dataflash_GetSelectedChip() (DATAFLASH_CHIPCS_PORT & DATAFLASH_CHIPCS_MASK)
#define Dataflash_SelectChip(mask) MACROS{ DATAFLASH_CHIPCS_PORT = ((DATAFLASH_CHIPCS_PORT \ /** Selects a dataflash IC from the given page number, which should range from 0 to
& ~DATAFLASH_CHIPCS_MASK) | (mask)); }MACROE * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one
* dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside
* the total number of pages contained in the boards dataflash ICs, all dataflash ICs
* are deselected.
*
* \param[in] PageAddress Address of the page to manipulate, ranging from
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1).
*/
static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress);
#define Dataflash_DeselectChip() Dataflash_SelectChip(DATAFLASH_NO_CHIP) /** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive
#endif * a new command.
*/
static inline void Dataflash_ToggleSelectedChipCS(void);
/** Spin-loops while the currently selected dataflash is busy executing a command, such as a main
* memory page program or main memory to buffer transfer.
*/
static inline void Dataflash_WaitWhileBusy(void);
/** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with
* dataflash commands which require a complete 24-byte address.
*
* \param[in] PageAddress Page address within the selected dataflash IC
* \param[in] BufferByte Address within the dataflash's buffer
*/
static inline void Dataflash_SendAddressBytes(uint16_t PageAddress,
const uint16_t BufferByte);
/* Inline Functions: */
/** Sends a byte to the currently selected dataflash IC, and returns a byte from the dataflash. /** Sends a byte to the currently selected dataflash IC, and returns a byte from the dataflash.
* *
* \param[in] Byte of data to send to the dataflash * \param[in] Byte of data to send to the dataflash
@ -172,58 +197,6 @@
#error The selected board does not contain a dataflash IC. #error The selected board does not contain a dataflash IC.
#endif #endif
/* Inline Functions: */
/** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC.
* The AVR's SPI driver MUST be initialized before any of the dataflash commands are used.
*/
static inline void Dataflash_Init(void)
{
DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK;
DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK;
}
/** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive
* a new command.
*/
static inline void Dataflash_ToggleSelectedChipCS(void)
{
uint8_t SelectedChipMask = Dataflash_GetSelectedChip();
Dataflash_DeselectChip();
Dataflash_SelectChip(SelectedChipMask);
}
/** Spin-loops while the currently selected dataflash is busy executing a command, such as a main
* memory page program or main memory to buffer transfer.
*/
static inline void Dataflash_WaitWhileBusy(void)
{
Dataflash_ToggleSelectedChipCS();
Dataflash_SendByte(DF_CMD_GETSTATUS);
while (!(Dataflash_ReceiveByte() & DF_STATUS_READY));
Dataflash_ToggleSelectedChipCS();
}
/** Selects a dataflash IC from the given page number, which should range from 0 to
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one
* dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside
* the total number of pages contained in the boards dataflash ICs, all dataflash ICs
* are deselected.
*
* \param[in] PageAddress Address of the page to manipulate, ranging from
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1).
*/
static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress);
/** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with
* dataflash commands which require a complete 24-byte address.
*
* \param[in] PageAddress Page address within the selected dataflash IC.
* \param[in] BufferByte Address within the dataflash's buffer.
*/
static inline void Dataflash_SendAddressBytes(uint16_t PageAddress,
const uint16_t BufferByte);
/* Disable C linkage for C++ Compilers: */ /* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus) #if defined(__cplusplus)
} }

@ -85,6 +85,44 @@
#define DATAFLASH_PAGES 8192 #define DATAFLASH_PAGES 8192
/* Inline Functions: */ /* Inline Functions: */
/** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC.
* The AVR's SPI driver MUST be initialized before any of the dataflash commands are used.
*/
static inline void Dataflash_Init(void)
{
DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK;
DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK;
}
/** Determines the currently selected dataflash chip.
*
* \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected
* or a DATAFLASH_CHIPn mask (where n is the chip number).
*/
static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
static inline uint8_t Dataflash_GetSelectedChip(void)
{
return (DATAFLASH_CHIPCS_PORT & DATAFLASH_CHIPCS_MASK);
}
/** Selects the given dataflash chip.
*
* \param[in] ChipMask Mask of the Dataflash IC to select, in the form of DATAFLASH_CHIPn mask (where n is
* the chip number).
*/
static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE;
static inline void Dataflash_SelectChip(const uint8_t ChipMask)
{
DATAFLASH_CHIPCS_PORT = ((DATAFLASH_CHIPCS_PORT & ~DATAFLASH_CHIPCS_MASK) | ChipMask);
}
/** Deselects the current dataflash chip, so that no dataflash is selected. */
static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE;
static inline void Dataflash_DeselectChip(void)
{
Dataflash_SelectChip(DATAFLASH_NO_CHIP);
}
/** Selects a dataflash IC from the given page number, which should range from 0 to /** Selects a dataflash IC from the given page number, which should range from 0 to
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one
* dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside * dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside
@ -104,6 +142,28 @@
Dataflash_SelectChip(DATAFLASH_CHIP1); Dataflash_SelectChip(DATAFLASH_CHIP1);
} }
/** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive
* a new command.
*/
static inline void Dataflash_ToggleSelectedChipCS(void)
{
uint8_t SelectedChipMask = Dataflash_GetSelectedChip();
Dataflash_DeselectChip();
Dataflash_SelectChip(SelectedChipMask);
}
/** Spin-loops while the currently selected dataflash is busy executing a command, such as a main
* memory page program or main memory to buffer transfer.
*/
static inline void Dataflash_WaitWhileBusy(void)
{
Dataflash_ToggleSelectedChipCS();
Dataflash_SendByte(DF_CMD_GETSTATUS);
while (!(Dataflash_ReceiveByte() & DF_STATUS_READY));
Dataflash_ToggleSelectedChipCS();
}
/** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with
* dataflash commands which require a complete 24-byte address. * dataflash commands which require a complete 24-byte address.
* *

@ -85,6 +85,44 @@
#define DATAFLASH_PAGES 8192 #define DATAFLASH_PAGES 8192
/* Inline Functions: */ /* Inline Functions: */
/** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC.
* The AVR's SPI driver MUST be initialized before any of the dataflash commands are used.
*/
static inline void Dataflash_Init(void)
{
DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK;
DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK;
}
/** Determines the currently selected dataflash chip.
*
* \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected
* or a DATAFLASH_CHIPn mask (where n is the chip number).
*/
static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
static inline uint8_t Dataflash_GetSelectedChip(void)
{
return (DATAFLASH_CHIPCS_PORT & DATAFLASH_CHIPCS_MASK);
}
/** Selects the given dataflash chip.
*
* \param[in] ChipMask Mask of the Dataflash IC to select, in the form of DATAFLASH_CHIPn mask (where n is
* the chip number).
*/
static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE;
static inline void Dataflash_SelectChip(const uint8_t ChipMask)
{
DATAFLASH_CHIPCS_PORT = ((DATAFLASH_CHIPCS_PORT & ~DATAFLASH_CHIPCS_MASK) | ChipMask);
}
/** Deselects the current dataflash chip, so that no dataflash is selected. */
static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE;
static inline void Dataflash_DeselectChip(void)
{
Dataflash_SelectChip(DATAFLASH_NO_CHIP);
}
/** Selects a dataflash IC from the given page number, which should range from 0 to /** Selects a dataflash IC from the given page number, which should range from 0 to
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one
* dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside * dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside
@ -104,6 +142,28 @@
Dataflash_SelectChip(DATAFLASH_CHIP1); Dataflash_SelectChip(DATAFLASH_CHIP1);
} }
/** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive
* a new command.
*/
static inline void Dataflash_ToggleSelectedChipCS(void)
{
uint8_t SelectedChipMask = Dataflash_GetSelectedChip();
Dataflash_DeselectChip();
Dataflash_SelectChip(SelectedChipMask);
}
/** Spin-loops while the currently selected dataflash is busy executing a command, such as a main
* memory page program or main memory to buffer transfer.
*/
static inline void Dataflash_WaitWhileBusy(void)
{
Dataflash_ToggleSelectedChipCS();
Dataflash_SendByte(DF_CMD_GETSTATUS);
while (!(Dataflash_ReceiveByte() & DF_STATUS_READY));
Dataflash_ToggleSelectedChipCS();
}
/** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with
* dataflash commands which require a complete 24-byte address. * dataflash commands which require a complete 24-byte address.
* *

@ -85,6 +85,44 @@
#define DATAFLASH_PAGES 8192 #define DATAFLASH_PAGES 8192
/* Inline Functions: */ /* Inline Functions: */
/** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC.
* The AVR's SPI driver MUST be initialized before any of the dataflash commands are used.
*/
static inline void Dataflash_Init(void)
{
DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK;
DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK;
}
/** Determines the currently selected dataflash chip.
*
* \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected
* or a DATAFLASH_CHIPn mask (where n is the chip number).
*/
static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
static inline uint8_t Dataflash_GetSelectedChip(void)
{
return (DATAFLASH_CHIPCS_PORT & DATAFLASH_CHIPCS_MASK);
}
/** Selects the given dataflash chip.
*
* \param[in] ChipMask Mask of the Dataflash IC to select, in the form of DATAFLASH_CHIPn mask (where n is
* the chip number).
*/
static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE;
static inline void Dataflash_SelectChip(const uint8_t ChipMask)
{
DATAFLASH_CHIPCS_PORT = ((DATAFLASH_CHIPCS_PORT & ~DATAFLASH_CHIPCS_MASK) | ChipMask);
}
/** Deselects the current dataflash chip, so that no dataflash is selected. */
static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE;
static inline void Dataflash_DeselectChip(void)
{
Dataflash_SelectChip(DATAFLASH_NO_CHIP);
}
/** Selects a dataflash IC from the given page number, which should range from 0 to /** Selects a dataflash IC from the given page number, which should range from 0 to
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one
* dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside * dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside
@ -104,6 +142,28 @@
Dataflash_SelectChip(DATAFLASH_CHIP1); Dataflash_SelectChip(DATAFLASH_CHIP1);
} }
/** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive
* a new command.
*/
static inline void Dataflash_ToggleSelectedChipCS(void)
{
uint8_t SelectedChipMask = Dataflash_GetSelectedChip();
Dataflash_DeselectChip();
Dataflash_SelectChip(SelectedChipMask);
}
/** Spin-loops while the currently selected dataflash is busy executing a command, such as a main
* memory page program or main memory to buffer transfer.
*/
static inline void Dataflash_WaitWhileBusy(void)
{
Dataflash_ToggleSelectedChipCS();
Dataflash_SendByte(DF_CMD_GETSTATUS);
while (!(Dataflash_ReceiveByte() & DF_STATUS_READY));
Dataflash_ToggleSelectedChipCS();
}
/** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with
* dataflash commands which require a complete 24-byte address. * dataflash commands which require a complete 24-byte address.
* *

@ -86,18 +86,18 @@
/** Maximum returnable temperature from the \ref Temperature_GetTemperature() function. */ /** Maximum returnable temperature from the \ref Temperature_GetTemperature() function. */
#define TEMP_MAX_TEMP ((TEMP_TABLE_SIZE - 1) + TEMP_TABLE_OFFSET) #define TEMP_MAX_TEMP ((TEMP_TABLE_SIZE - 1) + TEMP_TABLE_OFFSET)
/* Pseudo-Function Macros: */ /* Inline Functions: */
#if defined(__DOXYGEN__)
/** Initializes the temperature sensor driver, including setting up the appropriate ADC channel. /** Initializes the temperature sensor driver, including setting up the appropriate ADC channel.
* This must be called before any other temperature sensor routines. * This must be called before any other temperature sensor routines.
* *
* \pre The ADC itself (not the ADC channel) must be configured separately before calling the * \pre The ADC itself (not the ADC channel) must be configured separately before calling the
* temperature sensor functions. * temperature sensor functions.
*/ */
static inline void Temperature_Init(void); static inline void Temperature_Init(void) ATTR_ALWAYS_INLINE;
#else static inline void Temperature_Init(void)
#define Temperature_Init() ADC_SetupChannel(TEMP_ADC_CHANNEL); {
#endif ADC_SetupChannel(TEMP_ADC_CHANNEL);
}
/* Function Prototypes: */ /* Function Prototypes: */
/** Performs a complete ADC on the temperature sensor channel, and converts the result into a /** Performs a complete ADC on the temperature sensor channel, and converts the result into a

@ -88,6 +88,44 @@
#define DATAFLASH_PAGES 8192 #define DATAFLASH_PAGES 8192
/* Inline Functions: */ /* Inline Functions: */
/** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC.
* The AVR's SPI driver MUST be initialized before any of the dataflash commands are used.
*/
static inline void Dataflash_Init(void)
{
DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK;
DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK;
}
/** Determines the currently selected dataflash chip.
*
* \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected
* or a DATAFLASH_CHIPn mask (where n is the chip number).
*/
static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
static inline uint8_t Dataflash_GetSelectedChip(void)
{
return (DATAFLASH_CHIPCS_PORT & DATAFLASH_CHIPCS_MASK);
}
/** Selects the given dataflash chip.
*
* \param[in] ChipMask Mask of the Dataflash IC to select, in the form of DATAFLASH_CHIPn mask (where n is
* the chip number).
*/
static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE;
static inline void Dataflash_SelectChip(const uint8_t ChipMask)
{
DATAFLASH_CHIPCS_PORT = ((DATAFLASH_CHIPCS_PORT & ~DATAFLASH_CHIPCS_MASK) | ChipMask);
}
/** Deselects the current dataflash chip, so that no dataflash is selected. */
static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE;
static inline void Dataflash_DeselectChip(void)
{
Dataflash_SelectChip(DATAFLASH_NO_CHIP);
}
/** Selects a dataflash IC from the given page number, which should range from 0 to /** Selects a dataflash IC from the given page number, which should range from 0 to
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one
* dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside * dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside
@ -110,6 +148,28 @@
Dataflash_SelectChip(DATAFLASH_CHIP1); Dataflash_SelectChip(DATAFLASH_CHIP1);
} }
/** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive
* a new command.
*/
static inline void Dataflash_ToggleSelectedChipCS(void)
{
uint8_t SelectedChipMask = Dataflash_GetSelectedChip();
Dataflash_DeselectChip();
Dataflash_SelectChip(SelectedChipMask);
}
/** Spin-loops while the currently selected dataflash is busy executing a command, such as a main
* memory page program or main memory to buffer transfer.
*/
static inline void Dataflash_WaitWhileBusy(void)
{
Dataflash_ToggleSelectedChipCS();
Dataflash_SendByte(DF_CMD_GETSTATUS);
while (!(Dataflash_ReceiveByte() & DF_STATUS_READY));
Dataflash_ToggleSelectedChipCS();
}
/** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with
* dataflash commands which require a complete 24-byte address. * dataflash commands which require a complete 24-byte address.
* *

@ -91,6 +91,44 @@
#endif #endif
/* Inline Functions: */ /* Inline Functions: */
/** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC.
* The AVR's SPI driver MUST be initialized before any of the dataflash commands are used.
*/
static inline void Dataflash_Init(void)
{
DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK;
DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK;
}
/** Determines the currently selected dataflash chip.
*
* \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected
* or a DATAFLASH_CHIPn mask (where n is the chip number).
*/
static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
static inline uint8_t Dataflash_GetSelectedChip(void)
{
return (DATAFLASH_CHIPCS_PORT & DATAFLASH_CHIPCS_MASK);
}
/** Selects the given dataflash chip.
*
* \param[in] ChipMask Mask of the Dataflash IC to select, in the form of DATAFLASH_CHIPn mask (where n is
* the chip number).
*/
static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE;
static inline void Dataflash_SelectChip(const uint8_t ChipMask)
{
DATAFLASH_CHIPCS_PORT = ((DATAFLASH_CHIPCS_PORT & ~DATAFLASH_CHIPCS_MASK) | ChipMask);
}
/** Deselects the current dataflash chip, so that no dataflash is selected. */
static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE;
static inline void Dataflash_DeselectChip(void)
{
Dataflash_SelectChip(DATAFLASH_NO_CHIP);
}
/** Selects a dataflash IC from the given page number, which should range from 0 to /** Selects a dataflash IC from the given page number, which should range from 0 to
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one
* dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside * dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside
@ -110,6 +148,28 @@
Dataflash_SelectChip(DATAFLASH_CHIP1); Dataflash_SelectChip(DATAFLASH_CHIP1);
} }
/** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive
* a new command.
*/
static inline void Dataflash_ToggleSelectedChipCS(void)
{
uint8_t SelectedChipMask = Dataflash_GetSelectedChip();
Dataflash_DeselectChip();
Dataflash_SelectChip(SelectedChipMask);
}
/** Spin-loops while the currently selected dataflash is busy executing a command, such as a main
* memory page program or main memory to buffer transfer.
*/
static inline void Dataflash_WaitWhileBusy(void)
{
Dataflash_ToggleSelectedChipCS();
Dataflash_SendByte(DF_CMD_GETSTATUS);
while (!(Dataflash_ReceiveByte() & DF_STATUS_READY));
Dataflash_ToggleSelectedChipCS();
}
/** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with
* dataflash commands which require a complete 24-byte address. * dataflash commands which require a complete 24-byte address.
* *

@ -197,52 +197,6 @@
#endif #endif
//@} //@}
/* Pseudo-Function Macros: */
#if defined(__DOXYGEN__)
/** Initializes the ADC, ready for conversions. This must be called before any other ADC operations.
* The "mode" parameter should be a mask comprised of a conversion mode (free running or single) and
* prescaler masks.
*
* \param[in] Mode Mask of ADC settings, including adjustment, prescale, mode and reference.
*/
static inline void ADC_Init(uint8_t Mode);
/** Turns off the ADC. If this is called, any further ADC operations will require a call to
* \ref ADC_Init() before the ADC can be used again.
*/
static inline void ADC_ShutDown(void);
/** Indicates if the ADC is currently enabled.
*
* \return Boolean true if the ADC subsystem is currently enabled, false otherwise.
*/
static inline bool ADC_GetStatus(void);
/** Indicates if the current ADC conversion is completed, or still in progress.
*
* \return Boolean false if the reading is still taking place, or true if the conversion is
* complete and ready to be read out with \ref ADC_GetResult().
*/
static inline bool ADC_IsReadingComplete(void);
/** Retrieves the conversion value of the last completed ADC conversion and clears the reading
* completion flag.
*
* \return The result of the last ADC conversion as an unsigned value.
*/
static inline uint16_t ADC_GetResult(void);
#else
#define ADC_Init(mode) MACROS{ ADCSRA = ((1 << ADEN) | mode); }MACROE
#define ADC_ShutDown() MACROS{ ADCSRA = 0; }MACROE
#define ADC_GetStatus() ((ADCSRA & (1 << ADEN)) ? true : false)
#define ADC_IsReadingComplete() ((ADCSRA & (1 << ADIF)) ? true : false)
#define ADC_GetResult() (ADCSRA |= (1 << ADIF), ADC)
#endif
/* Inline Functions: */ /* Inline Functions: */
/** Configures the given ADC channel, ready for ADC conversions. This function sets the /** Configures the given ADC channel, ready for ADC conversions. This function sets the
* associated port pin as an input and disables the digital portion of the I/O to reduce * associated port pin as an input and disables the digital portion of the I/O to reduce
@ -354,6 +308,29 @@
ADCSRA |= (1 << ADSC); ADCSRA |= (1 << ADSC);
} }
/** Indicates if the current ADC conversion is completed, or still in progress.
*
* \return Boolean false if the reading is still taking place, or true if the conversion is
* complete and ready to be read out with \ref ADC_GetResult().
*/
static inline bool ADC_IsReadingComplete(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool ADC_IsReadingComplete(void)
{
return ((ADCSRA & (1 << ADIF)) ? true : false);
}
/** Retrieves the conversion value of the last completed ADC conversion and clears the reading
* completion flag.
*
* \return The result of the last ADC conversion as an unsigned value.
*/
static inline uint16_t ADC_GetResult(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint16_t ADC_GetResult(void)
{
ADCSRA |= (1 << ADIF);
return ADC;
}
/** Performs a complete single reading from channel, including a polling spin-loop to wait for the /** Performs a complete single reading from channel, including a polling spin-loop to wait for the
* conversion to complete, and the returning of the converted value. * conversion to complete, and the returning of the converted value.
* *
@ -373,6 +350,37 @@
return ADC_GetResult(); return ADC_GetResult();
} }
/** Initializes the ADC, ready for conversions. This must be called before any other ADC operations.
* The "mode" parameter should be a mask comprised of a conversion mode (free running or single) and
* prescaler masks.
*
* \param[in] Mode Mask of ADC settings, including adjustment, prescale, mode and reference.
*/
static inline void ADC_Init(uint8_t Mode) ATTR_ALWAYS_INLINE;
static inline void ADC_Init(uint8_t Mode)
{
ADCSRA = ((1 << ADEN) | Mode);
}
/** Turns off the ADC. If this is called, any further ADC operations will require a call to
* \ref ADC_Init() before the ADC can be used again.
*/
static inline void ADC_ShutDown(void) ATTR_ALWAYS_INLINE;
static inline void ADC_ShutDown(void)
{
ADCSRA = 0;
}
/** Indicates if the ADC is currently enabled.
*
* \return Boolean true if the ADC subsystem is currently enabled, false otherwise.
*/
static inline bool ADC_GetStatus(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool ADC_GetStatus(void)
{
return ((ADCSRA & (1 << ADEN)) ? true : false);
}
/* Disable C linkage for C++ Compilers: */ /* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus) #if defined(__cplusplus)
} }

@ -70,24 +70,27 @@
#endif #endif
/* Public Interface - May be used in end-application: */ /* Public Interface - May be used in end-application: */
/* Pseudo-Function Macros: */ /* Inline Functions: */
#if defined(__DOXYGEN__)
/** Initializes the TWI hardware into master mode, ready for data transmission and reception. This must be /** Initializes the TWI hardware into master mode, ready for data transmission and reception. This must be
* before any other TWI operations. * before any other TWI operations.
*/ */
static inline void TWI_Init(void); static inline void TWI_Init(void) ATTR_ALWAYS_INLINE;
static inline void TWI_Init(void)
{
TWCR |= (1 << TWEN);
}
/** Turns off the TWI driver hardware. If this is called, any further TWI operations will require a call to /** Turns off the TWI driver hardware. If this is called, any further TWI operations will require a call to
* \ref TWI_Init() before the TWI can be used again. * \ref TWI_Init() before the TWI can be used again.
*/ */
static inline void TWI_ShutDown(void); static inline void TWI_ShutDown(void) ATTR_ALWAYS_INLINE;
#else static inline void TWI_ShutDown(void)
#define TWI_Init() MACROS{ TWCR |= (1 << TWEN); }MACROE {
#define TWI_ShutDown() MACROS{ TWCR &= ~(1 << TWEN); }MACROE TWCR &= ~(1 << TWEN);
#endif }
/* Inline Functions: */
/** Sends a TWI STOP onto the TWI bus, terminating communication with the currently addressed device. */ /** Sends a TWI STOP onto the TWI bus, terminating communication with the currently addressed device. */
static inline void TWI_StopTransmission(void) ATTR_ALWAYS_INLINE;
static inline void TWI_StopTransmission(void) static inline void TWI_StopTransmission(void)
{ {
TWCR = ((1 << TWINT) | (1 << TWSTO) | (1 << TWEN)); TWCR = ((1 << TWINT) | (1 << TWSTO) | (1 << TWEN));

@ -76,17 +76,6 @@
*/ */
#define SERIAL_2X_UBBRVAL(baud) ((((F_CPU / 8) + (baud / 2)) / (baud)) - 1) #define SERIAL_2X_UBBRVAL(baud) ((((F_CPU / 8) + (baud / 2)) / (baud)) - 1)
/* Pseudo-Function Macros: */
#if defined(__DOXYGEN__)
/** Indicates whether a character has been received through the USART.
*
* \return Boolean true if a character has been received, false otherwise.
*/
static inline bool Serial_IsCharReceived(void);
#else
#define Serial_IsCharReceived() ((UCSR1A & (1 << RXC1)) ? true : false)
#endif
/* Function Prototypes: */ /* Function Prototypes: */
/** Transmits a given string located in program space (FLASH) through the USART. /** Transmits a given string located in program space (FLASH) through the USART.
* *
@ -133,10 +122,21 @@
UBRR1 = 0; UBRR1 = 0;
} }
/** Indicates whether a character has been received through the USART.
*
* \return Boolean true if a character has been received, false otherwise.
*/
static inline bool Serial_IsCharReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Serial_IsCharReceived(void)
{
return ((UCSR1A & (1 << RXC1)) ? true : false);
}
/** Transmits a given byte through the USART. /** Transmits a given byte through the USART.
* *
* \param[in] DataByte Byte to transmit through the USART. * \param[in] DataByte Byte to transmit through the USART.
*/ */
static inline void Serial_TxByte(const char DataByte) ATTR_ALWAYS_INLINE;
static inline void Serial_TxByte(const char DataByte) static inline void Serial_TxByte(const char DataByte)
{ {
while (!(UCSR1A & (1 << UDRE1))); while (!(UCSR1A & (1 << UDRE1)));
@ -147,6 +147,7 @@
* *
* \return Byte received from the USART. * \return Byte received from the USART.
*/ */
static inline char Serial_RxByte(void) ATTR_ALWAYS_INLINE;
static inline char Serial_RxByte(void) static inline char Serial_RxByte(void)
{ {
while (!(UCSR1A & (1 << RXC1))); while (!(UCSR1A & (1 << RXC1)));

@ -50,11 +50,13 @@
#define __USBDEVICE_H__ #define __USBDEVICE_H__
/* Includes: */ /* Includes: */
#include <avr/io.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <avr/eeprom.h> #include <avr/eeprom.h>
#include "../../../Common/Common.h" #include "../../../Common/Common.h"
#include "../HighLevel/StdDescriptors.h" #include "../HighLevel/StdDescriptors.h"
#include "USBInterrupt.h"
#include "Endpoint.h" #include "Endpoint.h"
/* Preprocessor Checks: */ /* Preprocessor Checks: */
@ -108,24 +110,6 @@
*/ */
void USB_Device_SendRemoteWakeup(void); void USB_Device_SendRemoteWakeup(void);
/* Pseudo-Function Macros: */
#if defined(__DOXYGEN__)
/** Enables the device mode Start Of Frame events. When enabled, this causes the
* \ref EVENT_USB_Device_StartOfFrame() event to fire once per millisecond, synchronized to the USB bus,
* at the start of each USB frame when enumerated in device mode.
*/
static inline bool USB_Device_EnableSOFEvents(void);
/** Disables the device mode Start Of Frame events. When disabled, this stop the firing of the
* \ref EVENT_USB_Device_StartOfFrame() event when enumerated in device mode.
*/
static inline bool USB_Device_DisableSOFEvents(void);
#else
#define USB_Device_EnableSOFEvents() MACROS{ USB_INT_Enable(USB_INT_SOFI); }MACROE
#define USB_Device_DisableSOFEvents() MACROS{ USB_INT_Disable(USB_INT_SOFI); }MACROE
#endif
/* Type Defines: */ /* Type Defines: */
enum USB_Device_States_t enum USB_Device_States_t
{ {
@ -155,6 +139,26 @@
*/ */
}; };
/* Inline Functions: */
/** Enables the device mode Start Of Frame events. When enabled, this causes the
* \ref EVENT_USB_Device_StartOfFrame() event to fire once per millisecond, synchronized to the USB bus,
* at the start of each USB frame when enumerated in device mode.
*/
static inline void USB_Device_EnableSOFEvents(void) ATTR_ALWAYS_INLINE;
static inline void USB_Device_EnableSOFEvents(void)
{
USB_INT_Enable(USB_INT_SOFI);
}
/** Disables the device mode Start Of Frame events. When disabled, this stop the firing of the
* \ref EVENT_USB_Device_StartOfFrame() event when enumerated in device mode.
*/
static inline void USB_Device_DisableSOFEvents(void) ATTR_ALWAYS_INLINE;
static inline void USB_Device_DisableSOFEvents(void)
{
USB_INT_Disable(USB_INT_SOFI);
}
/* Function Prototypes: */ /* Function Prototypes: */
/** Function to retrieve a given descriptor's size and memory location from the given descriptor type value, /** Function to retrieve a given descriptor's size and memory location from the given descriptor type value,
* index and language ID. This function MUST be overridden in the user application (added with full, identical * index and language ID. This function MUST be overridden in the user application (added with full, identical
@ -191,12 +195,26 @@
/* Private Interface - For use in library only: */ /* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__) #if !defined(__DOXYGEN__)
/* Macros: */ /* Inline Functions: */
#define USB_Device_SetLowSpeed() MACROS{ UDCON |= (1 << LSM); }MACROE #if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
#define USB_Device_SetFullSpeed() MACROS{ UDCON &= ~(1 << LSM); }MACROE static inline void USB_Device_SetLowSpeed(void) ATTR_ALWAYS_INLINE;
static inline void USB_Device_SetLowSpeed(void)
{
UDCON |= (1 << LSM);
}
#define USB_Device_SetDeviceAddress(addr) MACROS{ UDADDR = ((1 << ADDEN) | (addr & 0x7F)); }MACROE static inline void USB_Device_SetFullSpeed(void) ATTR_ALWAYS_INLINE;
static inline void USB_Device_SetFullSpeed(void)
{
UDCON &= ~(1 << LSM);
}
#endif
static inline void USB_Device_SetDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE;
static inline void USB_Device_SetDeviceAddress(const uint8_t Address)
{
UDADDR = ((1 << ADDEN) | (Address & 0x7F));
}
#endif #endif
#endif #endif

@ -83,6 +83,7 @@
#include "../../../Common/Common.h" #include "../../../Common/Common.h"
#include "../HighLevel/USBTask.h" #include "../HighLevel/USBTask.h"
#include "USBInterrupt.h"
#if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__) #if !defined(NO_STREAM_CALLBACKS) || defined(__DOXYGEN__)
#include "../HighLevel/StreamCallbacks.h" #include "../HighLevel/StreamCallbacks.h"
@ -149,7 +150,7 @@
/** Endpoint bank size mask, for masking against endpoint addresses to retrieve the endpoint's /** Endpoint bank size mask, for masking against endpoint addresses to retrieve the endpoint's
* bank size in the device. * bank size in the device.
*/ */
#define ENDPOINT_EPSIZE_MASK 0x7FF #define ENDPOINT_EPSIZE_MASK 0x7F
/** Maximum size in bytes of a given endpoint. /** Maximum size in bytes of a given endpoint.
* *
@ -177,8 +178,74 @@
#define ENDPOINT_TOTAL_ENDPOINTS 1 #define ENDPOINT_TOTAL_ENDPOINTS 1
#endif #endif
/* Pseudo-Function Macros: */ /* Enums: */
#if defined(__DOXYGEN__) /** Enum for the possible error return codes of the \ref Endpoint_WaitUntilReady() function.
*
* \ingroup Group_EndpointRW
*/
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_BusSuspended = 3, /**< The USB bus has been suspended by the host and
* no USB endpoint traffic can occur until the bus
* has resumed.
*/
ENDPOINT_READYWAIT_Timeout = 4, /**< The host failed to accept or send the next packet
* within the software timeout period set by the
* \ref USB_STREAM_TIMEOUT_MS macro.
*/
};
/** Enum for the possible error return codes of the Endpoint_*_Stream_* functions.
*
* \ingroup Group_EndpointStreamRW
*/
enum Endpoint_Stream_RW_ErrorCodes_t
{
ENDPOINT_RWSTREAM_NoError = 0, /**< Command completed successfully, no error. */
ENDPOINT_RWSTREAM_EndpointStalled = 1, /**< The endpoint was stalled during the stream
* transfer by the host or device.
*/
ENDPOINT_RWSTREAM_DeviceDisconnected = 2, /**< Device was disconnected from the host during
* the transfer.
*/
ENDPOINT_RWSTREAM_BusSuspended = 3, /**< The USB bus has been suspended by the host and
* no USB endpoint traffic can occur until the bus
* has resumed.
*/
ENDPOINT_RWSTREAM_Timeout = 4, /**< The host failed to accept or send the next packet
* within the software timeout period set by the
* \ref USB_STREAM_TIMEOUT_MS macro.
*/
ENDPOINT_RWSTREAM_CallbackAborted = 5, /**< Indicates that the stream's callback function
* aborted the transfer early.
*/
};
/** Enum for the possible error return codes of the Endpoint_*_Control_Stream_* functions..
*
* \ingroup Group_EndpointStreamRW
*/
enum Endpoint_ControlStream_RW_ErrorCodes_t
{
ENDPOINT_RWCSTREAM_NoError = 0, /**< Command completed successfully, no error. */
ENDPOINT_RWCSTREAM_HostAborted = 1, /**< The aborted the transfer prematurely. */
ENDPOINT_RWCSTREAM_DeviceDisconnected = 2, /**< Device was disconnected from the host during
* the transfer.
*/
ENDPOINT_RWCSTREAM_BusSuspended = 3, /**< The USB bus has been suspended by the host and
* no USB endpoint traffic can occur until the bus
* has resumed.
*/
};
/* Inline Functions: */
/** Indicates the number of bytes currently stored in the current endpoint's selected bank. /** Indicates the number of bytes currently stored in the current endpoint's selected bank.
* *
* \note The return width of this function may differ, depending on the maximum endpoint bank size * \note The return width of this function may differ, depending on the maximum endpoint bank size
@ -188,7 +255,17 @@
* *
* \return Total number of bytes in the currently selected Endpoint's FIFO buffer. * \return Total number of bytes in the currently selected Endpoint's FIFO buffer.
*/ */
static inline uint16_t Endpoint_BytesInEndpoint(void); static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint16_t Endpoint_BytesInEndpoint(void)
{
#if defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
return UEBCX;
#elif defined(USB_SERIES_4_AVR)
return (((uint16_t)UEBCHX << 8) | UEBCLX);
#elif defined(USB_SERIES_2_AVR)
return UEBCLX;
#endif
}
/** Get the endpoint address of the currently selected endpoint. This is typically used to save /** Get 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 * the currently selected endpoint number so that it can be restored after another endpoint has
@ -196,7 +273,15 @@
* *
* \return Index of the currently selected endpoint. * \return Index of the currently selected endpoint.
*/ */
static inline uint8_t Endpoint_GetCurrentEndpoint(void); static inline uint8_t Endpoint_GetCurrentEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint8_t Endpoint_GetCurrentEndpoint(void)
{
#if !defined(CONTROL_ONLY_DEVICE)
return (UENUM & ENDPOINT_EPNUM_MASK);
#else
return ENDPOINT_CONTROLEP;
#endif
}
/** Selects the given endpoint number. If the address from the device descriptors is used, the /** Selects the given endpoint number. If the address from the device descriptors is used, the
* value should be masked with the \ref ENDPOINT_EPNUM_MASK constant to extract only the endpoint * value should be masked with the \ref ENDPOINT_EPNUM_MASK constant to extract only the endpoint
@ -207,32 +292,55 @@
* *
* \param[in] EndpointNumber Endpoint number to select. * \param[in] EndpointNumber Endpoint number to select.
*/ */
static inline void Endpoint_SelectEndpoint(const uint8_t EndpointNumber); static inline void Endpoint_SelectEndpoint(const uint8_t EndpointNumber) ATTR_ALWAYS_INLINE;
static inline void Endpoint_SelectEndpoint(const uint8_t EndpointNumber)
{
#if !defined(CONTROL_ONLY_DEVICE)
UENUM = EndpointNumber;
#endif
}
/** Resets the endpoint bank FIFO. This clears all the endpoint banks and resets the USB controller's /** 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. * In and Out pointers to the bank's contents.
* *
* \param[in] EndpointNumber Endpoint number whose FIFO buffers are to be reset. * \param[in] EndpointNumber Endpoint number whose FIFO buffers are to be reset.
*/ */
static inline void Endpoint_ResetFIFO(const uint8_t EndpointNumber); static inline void Endpoint_ResetFIFO(const uint8_t EndpointNumber) ATTR_ALWAYS_INLINE;
static inline void Endpoint_ResetFIFO(const uint8_t EndpointNumber)
{
UERST = (1 << EndpointNumber);
UERST = 0;
}
/** Enables the currently selected endpoint so that data can be sent and received through it to /** Enables the currently selected endpoint so that data can be sent and received through it to
* and from a host. * and from a host.
* *
* \note Endpoints must first be configured properly via \ref Endpoint_ConfigureEndpoint(). * \note Endpoints must first be configured properly via \ref Endpoint_ConfigureEndpoint().
*/ */
static inline void Endpoint_EnableEndpoint(void); static inline void Endpoint_EnableEndpoint(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_EnableEndpoint(void)
{
UECONX |= (1 << EPEN);
}
/** Disables the currently selected endpoint so that data cannot be sent and received through it /** Disables the currently selected endpoint so that data cannot be sent and received through it
* to and from a host. * to and from a host.
*/ */
static inline void Endpoint_DisableEndpoint(void); static inline void Endpoint_DisableEndpoint(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_DisableEndpoint(void)
{
UECONX &= ~(1 << EPEN);
}
/** Determines if the currently selected endpoint is enabled, but not necessarily configured. /** Determines if the currently selected endpoint is enabled, but not necessarily configured.
* *
* \return Boolean True if the currently selected endpoint is enabled, false otherwise. * \return Boolean True if the currently selected endpoint is enabled, false otherwise.
*/ */
static inline bool Endpoint_IsEnabled(void); static inline bool Endpoint_IsEnabled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Endpoint_IsEnabled(void)
{
return ((UECONX & (1 << EPEN)) ? true : false);
}
/** Determines if the currently selected endpoint may be read from (if data is waiting in the endpoint /** Determines 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 * bank and the endpoint is an OUT direction, or if the bank is not yet full if the endpoint is an IN
@ -244,13 +352,21 @@
* *
* \return Boolean true if the currently selected endpoint may be read from or written to, depending on its direction. * \return Boolean true if the currently selected endpoint may be read from or written to, depending on its direction.
*/ */
static inline bool Endpoint_IsReadWriteAllowed(void); static inline bool Endpoint_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Endpoint_IsReadWriteAllowed(void)
{
return ((UEINTX & (1 << RWAL)) ? true : false);
}
/** Determines if the currently selected endpoint is configured. /** Determines if the currently selected endpoint is configured.
* *
* \return Boolean true if the currently selected endpoint has been configured, false otherwise. * \return Boolean true if the currently selected endpoint has been configured, false otherwise.
*/ */
static inline bool Endpoint_IsConfigured(void); static inline bool Endpoint_IsConfigured(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Endpoint_IsConfigured(void)
{
return ((UESTA0X & (1 << CFGOK)) ? true : false);
}
/** Returns a mask indicating which INTERRUPT type endpoints have interrupted - i.e. their /** 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 * interrupt duration has elapsed. Which endpoints have interrupted can be determined by
@ -258,7 +374,11 @@
* *
* \return Mask whose bits indicate which endpoints have interrupted. * \return Mask whose bits indicate which endpoints have interrupted.
*/ */
static inline uint8_t Endpoint_GetEndpointInterrupts(void); static inline uint8_t Endpoint_GetEndpointInterrupts(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint8_t Endpoint_GetEndpointInterrupts(void)
{
return UEINT;
}
/** Determines if the specified endpoint number has interrupted (valid only for INTERRUPT type /** Determines if the specified endpoint number has interrupted (valid only for INTERRUPT type
* endpoints). * endpoints).
@ -267,7 +387,11 @@
* *
* \return Boolean true if the specified endpoint has interrupted, false otherwise. * \return Boolean true if the specified endpoint has interrupted, false otherwise.
*/ */
static inline bool Endpoint_HasEndpointInterrupted(const uint8_t EndpointNumber); static inline bool Endpoint_HasEndpointInterrupted(const uint8_t EndpointNumber) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Endpoint_HasEndpointInterrupted(const uint8_t EndpointNumber)
{
return ((UEINT & (1 << EndpointNumber)) ? true : false);
}
/** Determines if the selected IN endpoint is ready for a new packet. /** Determines if the selected IN endpoint is ready for a new packet.
* *
@ -275,7 +399,11 @@
* *
* \return Boolean true if the current endpoint is ready for an IN packet, false otherwise. * \return Boolean true if the current endpoint is ready for an IN packet, false otherwise.
*/ */
static inline bool Endpoint_IsINReady(void); static inline bool Endpoint_IsINReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Endpoint_IsINReady(void)
{
return ((UEINTX & (1 << TXINI)) ? true : false);
}
/** Determines if the selected OUT endpoint has received new packet. /** Determines if the selected OUT endpoint has received new packet.
* *
@ -283,7 +411,11 @@
* *
* \return Boolean true if current endpoint is has received an OUT packet, false otherwise. * \return Boolean true if current endpoint is has received an OUT packet, false otherwise.
*/ */
static inline bool Endpoint_IsOUTReceived(void); static inline bool Endpoint_IsOUTReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Endpoint_IsOUTReceived(void)
{
return ((UEINTX & (1 << RXOUTI)) ? true : false);
}
/** Determines if the current CONTROL type endpoint has received a SETUP packet. /** Determines if the current CONTROL type endpoint has received a SETUP packet.
* *
@ -291,7 +423,11 @@
* *
* \return Boolean true if the selected endpoint has received a SETUP packet, false otherwise. * \return Boolean true if the selected endpoint has received a SETUP packet, false otherwise.
*/ */
static inline bool Endpoint_IsSETUPReceived(void); static inline bool Endpoint_IsSETUPReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Endpoint_IsSETUPReceived(void)
{
return ((UEINTX & (1 << RXSTPI)) ? true : false);
}
/** Clears a received SETUP packet on the currently selected CONTROL type endpoint, freeing up the /** Clears a received SETUP packet on the currently selected CONTROL type endpoint, freeing up the
* endpoint for the next packet. * endpoint for the next packet.
@ -300,21 +436,41 @@
* *
* \note This is not applicable for non CONTROL type endpoints. * \note This is not applicable for non CONTROL type endpoints.
*/ */
static inline void Endpoint_ClearSETUP(void); static inline void Endpoint_ClearSETUP(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_ClearSETUP(void)
{
UEINTX &= ~(1 << RXSTPI);
}
/** Sends an IN packet to the host on the currently selected endpoint, freeing up the endpoint for the /** Sends an IN packet to the host on the currently selected endpoint, freeing up the endpoint for the
* next packet and switching to the alternative endpoint bank if double banked. * next packet and switching to the alternative endpoint bank if double banked.
* *
* \ingroup Group_EndpointPacketManagement * \ingroup Group_EndpointPacketManagement
*/ */
static inline void Endpoint_ClearIN(void); static inline void Endpoint_ClearIN(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_ClearIN(void)
{
#if !defined(CONTROL_ONLY_DEVICE)
UEINTX &= ~((1 << TXINI) | (1 << FIFOCON));
#else
UEINTX &= ~(1 << TXINI);
#endif
}
/** Acknowledges an OUT packet to the host on the currently selected endpoint, freeing up the endpoint /** Acknowledges an OUT packet to the host on the currently selected endpoint, freeing up the endpoint
* for the next packet and switching to the alternative endpoint bank if double banked. * for the next packet and switching to the alternative endpoint bank if double banked.
* *
* \ingroup Group_EndpointPacketManagement * \ingroup Group_EndpointPacketManagement
*/ */
static inline void Endpoint_ClearOUT(void); static inline void Endpoint_ClearOUT(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_ClearOUT(void)
{
#if !defined(CONTROL_ONLY_DEVICE)
UEINTX &= ~((1 << RXOUTI) | (1 << FIFOCON));
#else
UEINTX &= ~(1 << RXOUTI);
#endif
}
/** Stalls the current endpoint, indicating to the host that a logical problem occurred with the /** Stalls the current endpoint, indicating to the host that a logical problem occurred with the
* indicated endpoint and that the current transfer sequence should be aborted. This provides a * indicated endpoint and that the current transfer sequence should be aborted. This provides a
@ -327,13 +483,21 @@
* *
* \ingroup Group_EndpointPacketManagement * \ingroup Group_EndpointPacketManagement
*/ */
static inline void Endpoint_StallTransaction(void); static inline void Endpoint_StallTransaction(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_StallTransaction(void)
{
UECONX |= (1 << STALLRQ);
}
/** Clears the STALL condition on the currently selected endpoint. /** Clears the STALL condition on the currently selected endpoint.
* *
* \ingroup Group_EndpointPacketManagement * \ingroup Group_EndpointPacketManagement
*/ */
static inline void Endpoint_ClearStall(void); static inline void Endpoint_ClearStall(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_ClearStall(void)
{
UECONX |= (1 << STALLRQC);
}
/** Determines if the currently selected endpoint is stalled, false otherwise. /** Determines if the currently selected endpoint is stalled, false otherwise.
* *
@ -341,162 +505,39 @@
* *
* \return Boolean true if the currently selected endpoint is stalled, false otherwise. * \return Boolean true if the currently selected endpoint is stalled, false otherwise.
*/ */
static inline bool Endpoint_IsStalled(void); static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Endpoint_IsStalled(void)
{
return ((UECONX & (1 << STALLRQ)) ? true : false);
}
/** Resets the data toggle of the currently selected endpoint. */ /** Resets the data toggle of the currently selected endpoint. */
static inline void Endpoint_ResetDataToggle(void); static inline void Endpoint_ResetDataToggle(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_ResetDataToggle(void)
{
UECONX |= (1 << RSTDT);
}
/** Determines the currently selected endpoint's direction. /** Determines the currently selected endpoint's direction.
* *
* \return The currently selected endpoint's direction, as a ENDPOINT_DIR_* mask. * \return The currently selected endpoint's direction, as a ENDPOINT_DIR_* mask.
*/ */
static inline uint8_t Endpoint_GetEndpointDirection(void); static inline uint8_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint8_t Endpoint_GetEndpointDirection(void)
{
return (UECFG0X & ENDPOINT_DIR_IN);
}
/** Sets the direction of the currently selected endpoint. /** Sets the direction of the currently selected endpoint.
* *
* \param[in] DirectionMask New endpoint direction, as a ENDPOINT_DIR_* mask. * \param[in] DirectionMask New endpoint direction, as a ENDPOINT_DIR_* mask.
*/ */
static inline void Endpoint_SetEndpointDirection(const uint8_t DirectionMask); static inline void Endpoint_SetEndpointDirection(const uint8_t DirectionMask) ATTR_ALWAYS_INLINE;
#else static inline void Endpoint_SetEndpointDirection(const uint8_t DirectionMask)
#if defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
#define Endpoint_BytesInEndpoint() UEBCX
#elif defined(USB_SERIES_4_AVR)
#define Endpoint_BytesInEndpoint() (((uint16_t)UEBCHX << 8) | UEBCLX)
#elif defined(USB_SERIES_2_AVR)
#define Endpoint_BytesInEndpoint() UEBCLX
#endif
#if !defined(CONTROL_ONLY_DEVICE)
#define Endpoint_GetCurrentEndpoint() (UENUM & ENDPOINT_EPNUM_MASK)
#else
#define Endpoint_GetCurrentEndpoint() ENDPOINT_CONTROLEP
#endif
#if !defined(CONTROL_ONLY_DEVICE)
#define Endpoint_SelectEndpoint(epnum) MACROS{ UENUM = (epnum); }MACROE
#else
#define Endpoint_SelectEndpoint(epnum) (void)(epnum)
#endif
#define Endpoint_ResetFIFO(epnum) MACROS{ UERST = (1 << (epnum)); UERST = 0; }MACROE
#define Endpoint_EnableEndpoint() MACROS{ UECONX |= (1 << EPEN); }MACROE
#define Endpoint_DisableEndpoint() MACROS{ UECONX &= ~(1 << EPEN); }MACROE
#define Endpoint_IsEnabled() ((UECONX & (1 << EPEN)) ? true : false)
#if !defined(CONTROL_ONLY_DEVICE)
#define Endpoint_IsReadWriteAllowed() ((UEINTX & (1 << RWAL)) ? true : false)
#endif
#define Endpoint_IsConfigured() ((UESTA0X & (1 << CFGOK)) ? true : false)
#define Endpoint_GetEndpointInterrupts() UEINT
#define Endpoint_HasEndpointInterrupted(n) ((UEINT & (1 << (n))) ? true : false)
#define Endpoint_IsINReady() ((UEINTX & (1 << TXINI)) ? true : false)
#define Endpoint_IsOUTReceived() ((UEINTX & (1 << RXOUTI)) ? true : false)
#define Endpoint_IsSETUPReceived() ((UEINTX & (1 << RXSTPI)) ? true : false)
#define Endpoint_ClearSETUP() MACROS{ UEINTX &= ~(1 << RXSTPI); }MACROE
#if !defined(CONTROL_ONLY_DEVICE)
#define Endpoint_ClearIN() MACROS{ UEINTX &= ~((1 << TXINI) | (1 << FIFOCON)); }MACROE
#else
#define Endpoint_ClearIN() MACROS{ UEINTX &= ~(1 << TXINI); }MACROE
#endif
#if !defined(CONTROL_ONLY_DEVICE)
#define Endpoint_ClearOUT() MACROS{ UEINTX &= ~((1 << RXOUTI) | (1 << FIFOCON)); }MACROE
#else
#define Endpoint_ClearOUT() MACROS{ UEINTX &= ~(1 << RXOUTI); }MACROE
#endif
#define Endpoint_StallTransaction() MACROS{ UECONX |= (1 << STALLRQ); }MACROE
#define Endpoint_ClearStall() MACROS{ UECONX |= (1 << STALLRQC); }MACROE
#define Endpoint_IsStalled() ((UECONX & (1 << STALLRQ)) ? true : false)
#define Endpoint_ResetDataToggle() MACROS{ UECONX |= (1 << RSTDT); }MACROE
#define Endpoint_GetEndpointDirection() (UECFG0X & ENDPOINT_DIR_IN)
#define Endpoint_SetEndpointDirection(dir) MACROS{ UECFG0X = ((UECFG0X & ~ENDPOINT_DIR_IN) | (dir)); }MACROE
#endif
/* Enums: */
/** Enum for the possible error return codes of the \ref Endpoint_WaitUntilReady() function.
*
* \ingroup Group_EndpointRW
*/
enum Endpoint_WaitUntilReady_ErrorCodes_t
{ {
ENDPOINT_READYWAIT_NoError = 0, /**< Endpoint is ready for next packet, no error. */ UECFG0X = ((UECFG0X & ~ENDPOINT_DIR_IN) | DirectionMask);
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_BusSuspended = 3, /**< The USB bus has been suspended by the host and
* no USB endpoint traffic can occur until the bus
* has resumed.
*/
ENDPOINT_READYWAIT_Timeout = 4, /**< The host failed to accept or send the next packet
* within the software timeout period set by the
* \ref USB_STREAM_TIMEOUT_MS macro.
*/
};
/** Enum for the possible error return codes of the Endpoint_*_Stream_* functions.
*
* \ingroup Group_EndpointStreamRW
*/
enum Endpoint_Stream_RW_ErrorCodes_t
{
ENDPOINT_RWSTREAM_NoError = 0, /**< Command completed successfully, no error. */
ENDPOINT_RWSTREAM_EndpointStalled = 1, /**< The endpoint was stalled during the stream
* transfer by the host or device.
*/
ENDPOINT_RWSTREAM_DeviceDisconnected = 2, /**< Device was disconnected from the host during
* the transfer.
*/
ENDPOINT_RWSTREAM_BusSuspended = 3, /**< The USB bus has been suspended by the host and
* no USB endpoint traffic can occur until the bus
* has resumed.
*/
ENDPOINT_RWSTREAM_Timeout = 4, /**< The host failed to accept or send the next packet
* within the software timeout period set by the
* \ref USB_STREAM_TIMEOUT_MS macro.
*/
ENDPOINT_RWSTREAM_CallbackAborted = 5, /**< Indicates that the stream's callback function
* aborted the transfer early.
*/
};
/** Enum for the possible error return codes of the Endpoint_*_Control_Stream_* functions..
*
* \ingroup Group_EndpointStreamRW
*/
enum Endpoint_ControlStream_RW_ErrorCodes_t
{
ENDPOINT_RWCSTREAM_NoError = 0, /**< Command completed successfully, no error. */
ENDPOINT_RWCSTREAM_HostAborted = 1, /**< The aborted the transfer prematurely. */
ENDPOINT_RWCSTREAM_DeviceDisconnected = 2, /**< Device was disconnected from the host during
* the transfer.
*/
ENDPOINT_RWCSTREAM_BusSuspended = 3, /**< The USB bus has been suspended by the host and
* no USB endpoint traffic can occur until the bus
* has resumed.
*/
};
/* Inline Functions: */
/** Reads one byte from the currently selected endpoint's bank, for OUT direction endpoints. /** Reads one byte from the currently selected endpoint's bank, for OUT direction endpoints.
* *
* \ingroup Group_EndpointPrimitiveRW * \ingroup Group_EndpointPrimitiveRW
@ -1260,13 +1301,6 @@
Endpoint_BytesToEPSizeMask(Size) : \ Endpoint_BytesToEPSizeMask(Size) : \
Endpoint_BytesToEPSizeMaskDynamic(Size)))) Endpoint_BytesToEPSizeMaskDynamic(Size))))
/* Function Prototypes: */
void Endpoint_ClearEndpoints(void);
uint8_t Endpoint_BytesToEPSizeMaskDynamic(const uint16_t Size);
bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number,
const uint8_t UECFG0XData,
const uint8_t UECFG1XData);
/* Inline Functions: */ /* Inline Functions: */
static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST ATTR_ALWAYS_INLINE; static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST ATTR_ALWAYS_INLINE;
static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes)
@ -1283,6 +1317,12 @@
return (MaskVal << EPSIZE0); return (MaskVal << EPSIZE0);
} }
/* Function Prototypes: */
void Endpoint_ClearEndpoints(void);
uint8_t Endpoint_BytesToEPSizeMaskDynamic(const uint16_t Size);
bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number,
const uint8_t UECFG0XData,
const uint8_t UECFG1XData);
#endif #endif
/* Disable C linkage for C++ Compilers: */ /* Disable C linkage for C++ Compilers: */

@ -101,148 +101,6 @@
#define HOST_DEVICE_SETTLE_DELAY_MS 1500 #define HOST_DEVICE_SETTLE_DELAY_MS 1500
#endif #endif
/* Pseudo-Function Macros: */
#if defined(__DOXYGEN__)
/** 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.
*/
static inline void USB_Host_ResetBus(void);
/** Determines if a previously issued bus reset (via the \ref USB_Host_ResetBus() macro) has
* completed.
*
* \return Boolean true if no bus reset is currently being sent, false otherwise.
*/
static inline void USB_Host_IsBusResetComplete(void);
/** 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.
*/
static inline void USB_Host_ResumeBus(void);
/** Suspends the USB bus, preventing any communications from occurring 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.
*/
static inline void USB_Host_SuspendBus(void);
/** Determines if the USB bus has been suspended via the use of the \ref 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.
*
* \return Boolean true if the bus is currently suspended, false otherwise.
*/
static inline bool USB_Host_IsBusSuspended(void);
/** Determines 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).
*
* \return Boolean true if the attached device is enumerated in Full Speed mode, false otherwise.
*/
static inline bool USB_Host_IsDeviceFullSpeed(void);
/** Determines 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.
*
* \return Boolean true if the attached device has sent a Remote Wakeup request, false otherwise.
*/
static inline bool USB_Host_IsRemoteWakeupSent(void);
/** Clears the flag indicating that a Remote Wakeup request has been issued by an attached device. */
static inline void USB_Host_ClearRemoteWakeupSent(void);
/** 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.
*/
static inline void USB_Host_ResumeFromWakeupRequest(void);
/** Determines if a resume from Remote Wakeup request is currently being sent to an attached
* device.
*
* \return Boolean true if no resume request is currently being sent, false otherwise.
*/
static inline bool USB_Host_IsResumeFromWakeupRequestSent(void);
#else
#define USB_Host_ResetBus() MACROS{ UHCON |= (1 << RESET); }MACROE
#define USB_Host_IsBusResetComplete() ((UHCON & (1 << RESET)) ? false : true)
#define USB_Host_ResumeBus() MACROS{ UHCON |= (1 << SOFEN); }MACROE
#define USB_Host_SuspendBus() MACROS{ UHCON &= ~(1 << SOFEN); }MACROE
#define USB_Host_IsBusSuspended() ((UHCON & (1 << SOFEN)) ? false : true)
#define USB_Host_IsDeviceFullSpeed() ((USBSTA & (1 << SPEED)) ? true : false)
#define USB_Host_IsRemoteWakeupSent() ((UHINT & (1 << RXRSMI)) ? true : false)
#define USB_Host_ClearRemoteWakeupSent() MACROS{ UHINT &= ~(1 << RXRSMI); }MACROE
#define USB_Host_ResumeFromWakeupRequest() MACROS{ UHCON |= (1 << RESUME); }MACROE
#define USB_Host_IsResumeFromWakeupRequestSent() ((UHCON & (1 << RESUME)) ? false : true)
#endif
/* Function Prototypes: */
/** Convenience function. This routine sends a SetConfiguration standard request to the attached
* device, with the given configuration index. This can be used to easily set the device
* configuration without creating and sending the request manually.
*
* \note After this routine returns, the control pipe will be selected.
*
* \param[in] ConfigNumber Configuration index to send to the device.
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
*/
uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber);
/** Convenience function. This routine sends a GetDescriptor standard request to the attached
* device, requesting the device descriptor. This can be used to easily retrieve information
* about the device such as its VID, PID and power requirements.
*
* \note After this routine returns, the control pipe will be selected.
*
* \param[out] DeviceDescriptorPtr Pointer to the destination device descriptor structure where
* the read data is to be stored.
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
*/
uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr);
/** Convenience function. This routine sends a GetDescriptor standard request to the attached
* device, requesting the string descriptor of the specified index. This can be used to easily
* retrieve string descriptors from the device by index, after the index is obtained from the
* Device or Configuration descriptors.
*
* \note After this routine returns, the control pipe will be selected.
*
* \param[in] Index Index of the string index to retrieve.
* \param[out] Buffer Pointer to the destination buffer where the retrieved string descriptor is
* to be stored.
* \param[in] BufferLength Maximum size of the string descriptor which can be stored into the buffer.
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
*/
uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index,
void* const Buffer,
const uint8_t BufferLength);
/** Clears a stall condition on the given pipe, via a ClearFeature request to the attached device.
*
* \note After this routine returns, the control pipe will be selected.
*
* \param[in] EndpointIndex Index of the endpoint to clear.
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
*/
uint8_t USB_Host_ClearPipeStall(uint8_t EndpointIndex);
/* Enums: */ /* Enums: */
/** Enum for the various states of the USB Host state machine. Only some states are /** 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. * implemented in the LUFA library - other states are left to the user to implement.
@ -385,22 +243,226 @@
*/ */
}; };
/* Inline Functions: */
/** 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.
*/
static inline void USB_Host_ResetBus(void) ATTR_ALWAYS_INLINE;
static inline void USB_Host_ResetBus(void)
{
UHCON |= (1 << RESET);
}
/** Determines if a previously issued bus reset (via the \ref USB_Host_ResetBus() macro) has
* completed.
*
* \return Boolean true if no bus reset is currently being sent, false otherwise.
*/
static inline bool USB_Host_IsBusResetComplete(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool USB_Host_IsBusResetComplete(void)
{
return ((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.
*/
static inline void USB_Host_ResumeBus(void) ATTR_ALWAYS_INLINE;
static inline void USB_Host_ResumeBus(void)
{
UHCON |= (1 << SOFEN);
}
/** Suspends the USB bus, preventing any communications from occurring 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.
*/
static inline void USB_Host_SuspendBus(void) ATTR_ALWAYS_INLINE;
static inline void USB_Host_SuspendBus(void)
{
UHCON &= ~(1 << SOFEN);
}
/** Determines if the USB bus has been suspended via the use of the \ref 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.
*
* \return Boolean true if the bus is currently suspended, false otherwise.
*/
static inline bool USB_Host_IsBusSuspended(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool USB_Host_IsBusSuspended(void)
{
return ((UHCON & (1 << SOFEN)) ? false : true);
}
/** Determines 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).
*
* \return Boolean true if the attached device is enumerated in Full Speed mode, false otherwise.
*/
static inline bool USB_Host_IsDeviceFullSpeed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool USB_Host_IsDeviceFullSpeed(void)
{
return ((USBSTA & (1 << SPEED)) ? true : false);
}
/** Determines 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.
*
* \return Boolean true if the attached device has sent a Remote Wakeup request, false otherwise.
*/
static inline bool USB_Host_IsRemoteWakeupSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool USB_Host_IsRemoteWakeupSent(void)
{
return ((UHINT & (1 << RXRSMI)) ? true : false);
}
/** Clears the flag indicating that a Remote Wakeup request has been issued by an attached device. */
static inline void USB_Host_ClearRemoteWakeupSent(void) ATTR_ALWAYS_INLINE;
static inline void USB_Host_ClearRemoteWakeupSent(void)
{
UHINT &= ~(1 << RXRSMI);
}
/** 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.
*/
static inline void USB_Host_ResumeFromWakeupRequest(void) ATTR_ALWAYS_INLINE;
static inline void USB_Host_ResumeFromWakeupRequest(void)
{
UHCON |= (1 << RESUME);
}
/** Determines if a resume from Remote Wakeup request is currently being sent to an attached
* device.
*
* \return Boolean true if no resume request is currently being sent, false otherwise.
*/
static inline bool USB_Host_IsResumeFromWakeupRequestSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool USB_Host_IsResumeFromWakeupRequestSent(void)
{
return ((UHCON & (1 << RESUME)) ? false : true);
}
/* Function Prototypes: */
/** Convenience function. This routine sends a SetConfiguration standard request to the attached
* device, with the given configuration index. This can be used to easily set the device
* configuration without creating and sending the request manually.
*
* \note After this routine returns, the control pipe will be selected.
*
* \param[in] ConfigNumber Configuration index to send to the device.
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
*/
uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber);
/** Convenience function. This routine sends a GetDescriptor standard request to the attached
* device, requesting the device descriptor. This can be used to easily retrieve information
* about the device such as its VID, PID and power requirements.
*
* \note After this routine returns, the control pipe will be selected.
*
* \param[out] DeviceDescriptorPtr Pointer to the destination device descriptor structure where
* the read data is to be stored.
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
*/
uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr);
/** Convenience function. This routine sends a GetDescriptor standard request to the attached
* device, requesting the string descriptor of the specified index. This can be used to easily
* retrieve string descriptors from the device by index, after the index is obtained from the
* Device or Configuration descriptors.
*
* \note After this routine returns, the control pipe will be selected.
*
* \param[in] Index Index of the string index to retrieve.
* \param[out] Buffer Pointer to the destination buffer where the retrieved string descriptor is
* to be stored.
* \param[in] BufferLength Maximum size of the string descriptor which can be stored into the buffer.
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
*/
uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index,
void* const Buffer,
const uint8_t BufferLength);
/** Clears a stall condition on the given pipe, via a ClearFeature request to the attached device.
*
* \note After this routine returns, the control pipe will be selected.
*
* \param[in] EndpointIndex Index of the endpoint to clear.
*
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
*/
uint8_t USB_Host_ClearPipeStall(uint8_t EndpointIndex);
/* Private Interface - For use in library only: */ /* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__) #if !defined(__DOXYGEN__)
/* Macros: */ /* Macros: */
#define USB_Host_HostMode_On() MACROS{ USBCON |= (1 << HOST); }MACROE static inline void USB_Host_HostMode_On(void) ATTR_ALWAYS_INLINE;
#define USB_Host_HostMode_Off() MACROS{ USBCON &= ~(1 << HOST); }MACROE static inline void USB_Host_HostMode_On(void)
{
USBCON |= (1 << HOST);
}
#define USB_Host_VBUS_Auto_Enable() MACROS{ OTGCON &= ~(1 << VBUSHWC); UHWCON |= (1 << UVCONE); }MACROE static inline void USB_Host_HostMode_Off(void) ATTR_ALWAYS_INLINE;
#define USB_Host_VBUS_Manual_Enable() MACROS{ OTGCON |= (1 << VBUSHWC); UHWCON &= ~(1 << UVCONE); DDRE |= (1 << 7); }MACROE static inline void USB_Host_HostMode_Off(void)
{
USBCON &= ~(1 << HOST);
}
#define USB_Host_VBUS_Auto_On() MACROS{ OTGCON |= (1 << VBUSREQ); }MACROE static inline void USB_Host_VBUS_Auto_Enable(void) ATTR_ALWAYS_INLINE;
#define USB_Host_VBUS_Manual_On() MACROS{ PORTE |= (1 << 7); }MACROE static inline void USB_Host_VBUS_Auto_Enable(void)
{
OTGCON &= ~(1 << VBUSHWC);
UHWCON |= (1 << UVCONE);
}
#define USB_Host_VBUS_Auto_Off() MACROS{ OTGCON |= (1 << VBUSRQC); }MACROE static inline void USB_Host_VBUS_Manual_Enable(void) ATTR_ALWAYS_INLINE;
#define USB_Host_VBUS_Manual_Off() MACROS{ PORTE &= ~(1 << 7); }MACROE static inline void USB_Host_VBUS_Manual_Enable(void)
{
OTGCON |= (1 << VBUSHWC);
UHWCON &= ~(1 << UVCONE);
#define USB_Host_SetDeviceAddress(addr) MACROS{ UHADDR = ((addr) & 0x7F); }MACROE DDRE |= (1 << 7);
}
static inline void USB_Host_VBUS_Auto_On(void) ATTR_ALWAYS_INLINE;
static inline void USB_Host_VBUS_Auto_On(void)
{
OTGCON |= (1 << VBUSREQ);
}
static inline void USB_Host_VBUS_Manual_On(void) ATTR_ALWAYS_INLINE;
static inline void USB_Host_VBUS_Manual_On(void)
{
PORTE |= (1 << 7);
}
static inline void USB_Host_VBUS_Auto_Off(void) ATTR_ALWAYS_INLINE;
static inline void USB_Host_VBUS_Auto_Off(void)
{
OTGCON |= (1 << VBUSRQC);
}
static inline void USB_Host_VBUS_Manual_Off(void) ATTR_ALWAYS_INLINE;
static inline void USB_Host_VBUS_Manual_Off(void)
{
PORTE &= ~(1 << 7);
}
static inline void USB_Host_SetDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE;
static inline void USB_Host_SetDeviceAddress(const uint8_t Address)
{
UHADDR = (Address & 0x7F);
}
/* Enums: */ /* Enums: */
enum USB_Host_WaitMSErrorCodes_t enum USB_Host_WaitMSErrorCodes_t

@ -76,23 +76,34 @@
*/ */
#define USB_OTG_STP_DATA 0 #define USB_OTG_STP_DATA 0
/* Pseudo-Function Macros: */ /* Inline Functions: */
#if defined(__DOXYGEN__)
/** Initiate a Host Negotiation Protocol request. This indicates to the other connected device /** Initiate a Host Negotiation Protocol request. This indicates to the other connected device
* that the device wishes to change device/host roles. * that the device wishes to change device/host roles.
*/ */
static inline void USB_OTG_Device_RequestHNP(void); static inline void USB_OTG_Device_RequestHNP(void) ATTR_ALWAYS_INLINE;
static inline void USB_OTG_Device_RequestHNP(void)
{
OTGCON |= (1 << HNPREQ);
}
/** Cancel a Host Negotiation Protocol request. This stops a pending HNP request to the other /** Cancel a Host Negotiation Protocol request. This stops a pending HNP request to the other
* connected device. * connected device.
*/ */
static inline void USB_OTG_Device_CancelHNPRequest(void); static inline void USB_OTG_Device_CancelHNPRequest(void) ATTR_ALWAYS_INLINE;
static inline void USB_OTG_Device_CancelHNPRequest(void)
{
OTGCON &= ~(1 << HNPREQ);
}
/** Determines if the device is currently sending a HNP to an attached host. /** Determines if the device is currently sending a HNP to an attached host.
* *
* \return Boolean true if currently sending a HNP to the other connected device, false otherwise * \return Boolean true if currently sending a HNP to the other connected device, false otherwise
*/ */
static inline bool USB_OTG_Device_IsSendingHNP(void); static inline bool USB_OTG_Device_IsSendingHNP(void) ATTR_ALWAYS_INLINE;
static inline bool USB_OTG_Device_IsSendingHNP(void)
{
return ((OTGCON & (1 << HNPREQ)) ? true : false);
}
/** Initiates a Session Request Protocol request. Most OTG devices turn off VBUS when the USB /** 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 * interface is not in use, to conserve power. Sending a SRP to a USB OTG device running in
@ -104,38 +115,39 @@
* \param[in] SRPTypeMask Mask indicating the type of SRP to use, either \ref USB_OTG_SRP_VBUS or * \param[in] SRPTypeMask Mask indicating the type of SRP to use, either \ref USB_OTG_SRP_VBUS or
* \ref USB_OTG_STP_DATA. * \ref USB_OTG_STP_DATA.
*/ */
static inline void USB_OTG_Device_InitiateSRP(const uint8_t SRPTypeMask); static inline void USB_OTG_Device_InitiateSRP(const uint8_t SRPTypeMask) ATTR_ALWAYS_INLINE;
static inline void USB_OTG_Device_InitiateSRP(const uint8_t SRPTypeMask)
{
OTGCON = ((OTGCON & ~(1 << SRPSEL)) | (SRPTypeMask | (1 << SRPREQ)));
}
/** Accepts a HNP from a connected device, indicating that both devices should exchange /** Accepts a HNP from a connected device, indicating that both devices should exchange
* device/host roles. * device/host roles.
*/ */
static inline void USB_OTG_Host_AcceptHNP(void); static inline void USB_OTG_Host_AcceptHNP(void) ATTR_ALWAYS_INLINE;
static inline void USB_OTG_Host_AcceptHNP(void)
{
OTGCON |= (1 << HNPREQ);
}
/** Rejects a HNP from a connected device, indicating that both devices should remain in their /** Rejects a HNP from a connected device, indicating that both devices should remain in their
* current device/host roles. * current device/host roles.
*/ */
static inline void USB_OTG_Host_RejectHNP(void); static inline void USB_OTG_Host_RejectHNP(void) ATTR_ALWAYS_INLINE;
static inline void USB_OTG_Host_RejectHNP(void)
{
OTGCON &= ~(1 << HNPREQ);
}
/** Indicates if the connected device is not currently sending a HNP request. /** Indicates if the connected device is not currently sending a HNP request.
* *
* \return Boolean true if a HNP is currently being issued by the connected device, false otherwise. * \return Boolean true if a HNP is currently being issued by the connected device, false otherwise.
*/ */
static inline bool USB_OTG_Host_IsHNPReceived(void); static inline bool USB_OTG_Host_IsHNPReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
#else static inline bool USB_OTG_Host_IsHNPReceived(void)
#define USB_OTG_Device_RequestHNP() MACROS{ OTGCON |= (1 << HNPREQ); }MACROE {
return ((OTGCON & (1 << HNPREQ)) ? true : false);
#define USB_OTG_Device_CancelHNPRequest() MACROS{ OTGCON &= ~(1 << HNPREQ); }MACROE }
#define USB_OTG_Device_IsSendingHNP() ((OTGCON & (1 << HNPREQ)) ? true : false)
#define USB_OTG_Device_InitiateSRP(type) MACROS{ OTGCON = ((OTGCON & ~(1 << SRPSEL)) | ((type) | (1 << SRPREQ))); }MACROE
#define USB_OTG_Host_AcceptHNP() MACROS{ OTGCON |= (1 << HNPREQ); }MACROE
#define USB_OTG_Host_RejectHNP() MACROS{ OTGCON &= ~(1 << HNPREQ); }MACROE
#define USB_OTG_Host_IsHNPReceived() ((OTGCON & (1 << HNPREQ)) ? true : false)
#endif
#endif #endif

@ -106,6 +106,14 @@
#error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead.
#endif #endif
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#if !defined(ENDPOINT_CONTROLEP) && !defined(__DOXYGEN__)
#define ENDPOINT_CONTROLEP 0
#endif
#endif
/* Public Interface - May be used in end-application: */ /* Public Interface - May be used in end-application: */
/* Macros: */ /* Macros: */
/** Mask for \ref Pipe_GetErrorFlags(), indicating that an overflow error occurred in the pipe on the received data. */ /** Mask for \ref Pipe_GetErrorFlags(), indicating that an overflow error occurred in the pipe on the received data. */
@ -195,8 +203,43 @@
*/ */
#define PIPE_EPDIR_MASK 0x80 #define PIPE_EPDIR_MASK 0x80
/* Pseudo-Function Macros: */ /* Enums: */
#if defined(__DOXYGEN__) /** Enum for the possible error return codes of the Pipe_WaitUntilReady function.
*
* \ingroup Group_PipeRW
*/
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
* \ref USB_STREAM_TIMEOUT_MS macro.
*/
};
/** Enum for the possible error return codes of the Pipe_*_Stream_* functions.
*
* \ingroup Group_PipeRW
*/
enum Pipe_Stream_RW_ErrorCodes_t
{
PIPE_RWSTREAM_NoError = 0, /**< Command completed successfully, no error. */
PIPE_RWSTREAM_PipeStalled = 1, /**< The device stalled the pipe during the transfer. */
PIPE_RWSTREAM_DeviceDisconnected = 2, /**< Device was disconnected from the host during
* the transfer.
*/
PIPE_RWSTREAM_Timeout = 3, /**< The device failed to accept or send the next packet
* within the software timeout period set by the
* \ref USB_STREAM_TIMEOUT_MS macro.
*/
PIPE_RWSTREAM_CallbackAborted = 4, /**< Indicates that the stream's callback function aborted
* the transfer early.
*/
};
/* Inline Functions: */
/** Indicates the number of bytes currently stored in the current pipes's selected bank. /** Indicates the number of bytes currently stored in the current pipes's selected bank.
* *
* \note The return width of this function may differ, depending on the maximum pipe bank size * \note The return width of this function may differ, depending on the maximum pipe bank size
@ -206,51 +249,84 @@
* *
* \return Total number of bytes in the currently selected Pipe's FIFO buffer. * \return Total number of bytes in the currently selected Pipe's FIFO buffer.
*/ */
static inline uint16_t Pipe_BytesInPipe(void); static inline uint16_t Pipe_BytesInPipe(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint16_t Pipe_BytesInPipe(void)
{
return UPBCX;
}
/** Returns the pipe address of the currently selected pipe. This is typically used to save the /** 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. * currently selected pipe number so that it can be restored after another pipe has been manipulated.
* *
* \return Index of the currently selected pipe. * \return Index of the currently selected pipe.
*/ */
static inline uint8_t Pipe_GetCurrentPipe(void); static inline uint8_t Pipe_GetCurrentPipe(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint8_t Pipe_GetCurrentPipe(void)
{
return (UPNUM & PIPE_PIPENUM_MASK);
}
/** Selects the given pipe number. Any pipe operations which do not require the pipe number to be /** 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. * indicated will operate on the currently selected pipe.
* *
* \param[in] PipeNumber Index of the pipe to select. * \param[in] PipeNumber Index of the pipe to select.
*/ */
static inline void Pipe_SelectPipe(uint8_t PipeNumber); static inline void Pipe_SelectPipe(const uint8_t PipeNumber) ATTR_ALWAYS_INLINE;
static inline void Pipe_SelectPipe(const uint8_t PipeNumber)
{
UPNUM = PipeNumber;
}
/** Resets the desired pipe, including the pipe banks and flags. /** Resets the desired pipe, including the pipe banks and flags.
* *
* \param[in] PipeNumber Index of the pipe to reset. * \param[in] PipeNumber Index of the pipe to reset.
*/ */
static inline void Pipe_ResetPipe(uint8_t PipeNumber); static inline void Pipe_ResetPipe(const uint8_t PipeNumber) ATTR_ALWAYS_INLINE;
static inline void Pipe_ResetPipe(const uint8_t PipeNumber)
{
UPRST = (1 << PipeNumber);
UPRST = 0;
}
/** Enables the currently selected pipe so that data can be sent and received through it to and from /** Enables the currently selected pipe so that data can be sent and received through it to and from
* an attached device. * an attached device.
* *
* \pre The currently selected pipe must first be configured properly via \ref Pipe_ConfigurePipe(). * \pre The currently selected pipe must first be configured properly via \ref Pipe_ConfigurePipe().
*/ */
static inline void Pipe_EnablePipe(void); static inline void Pipe_EnablePipe(void) ATTR_ALWAYS_INLINE;
static inline void Pipe_EnablePipe(void)
{
UPCONX |= (1 << PEN);
}
/** Disables the currently selected pipe so that data cannot be sent and received through it to and /** Disables the currently selected pipe so that data cannot be sent and received through it to and
* from an attached device. * from an attached device.
*/ */
static inline void Pipe_DisablePipe(void); static inline void Pipe_DisablePipe(void) ATTR_ALWAYS_INLINE;
static inline void Pipe_DisablePipe(void)
{
UPCONX &= ~(1 << PEN);
}
/** Determines if the currently selected pipe is enabled, but not necessarily configured. /** Determines if the currently selected pipe is enabled, but not necessarily configured.
* *
* \return Boolean True if the currently selected pipe is enabled, false otherwise. * \return Boolean True if the currently selected pipe is enabled, false otherwise.
*/ */
static inline bool Pipe_IsEnabled(void); static inline bool Pipe_IsEnabled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Pipe_IsEnabled(void)
{
return ((UPCONX & (1 << PEN)) ? true : false);
}
/** Gets the current pipe token, indicating the pipe's data direction and type. /** Gets the current pipe token, indicating the pipe's data direction and type.
* *
* \return The current pipe token, as a PIPE_TOKEN_* mask. * \return The current pipe token, as a PIPE_TOKEN_* mask.
*/ */
static inline uint8_t Pipe_GetPipeToken(void); static inline uint8_t Pipe_GetPipeToken(void) ATTR_ALWAYS_INLINE;
static inline uint8_t Pipe_GetPipeToken(void)
{
return (UPCFG0X & (0x03 << PTOKEN0));
}
/** Sets the token for the currently selected pipe to one of the tokens specified by the PIPE_TOKEN_* /** Sets the token for the currently selected pipe to one of the tokens specified by the PIPE_TOKEN_*
* masks. This can be used on CONTROL type pipes, to allow for bidirectional transfer of data during * masks. This can be used on CONTROL type pipes, to allow for bidirectional transfer of data during
@ -259,43 +335,72 @@
* *
* \param[in] Token New pipe token to set the selected pipe to, as a PIPE_TOKEN_* mask. * \param[in] Token New pipe token to set the selected pipe to, as a PIPE_TOKEN_* mask.
*/ */
static inline void Pipe_SetPipeToken(uint8_t Token); static inline void Pipe_SetPipeToken(const uint8_t Token) ATTR_ALWAYS_INLINE;
static inline void Pipe_SetPipeToken(const uint8_t Token)
{
UPCFG0X = ((UPCFG0X & ~(0x03 << PTOKEN0)) | Token);
}
/** Configures the currently selected pipe to allow for an unlimited number of IN requests. */ /** Configures the currently selected pipe to allow for an unlimited number of IN requests. */
static inline void Pipe_SetInfiniteINRequests(void); static inline void Pipe_SetInfiniteINRequests(void) ATTR_ALWAYS_INLINE;
static inline void Pipe_SetInfiniteINRequests(void)
{
UPCONX |= (1 << INMODE);
}
/** Configures the currently selected pipe to only allow the specified number of IN requests to be /** 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. * accepted by the pipe before it is automatically frozen.
* *
* \param[in] TotalINRequests Total number of IN requests that the pipe may receive before freezing. * \param[in] TotalINRequests Total number of IN requests that the pipe may receive before freezing.
*/ */
static inline void Pipe_SetFiniteINRequests(uint8_t TotalINRequests); static inline void Pipe_SetFiniteINRequests(const uint8_t TotalINRequests) ATTR_ALWAYS_INLINE;
static inline void Pipe_SetFiniteINRequests(const uint8_t TotalINRequests)
{
UPCONX &= ~(1 << INMODE);
UPINRQX = TotalINRequests;
}
/** Determines if the currently selected pipe is configured. /** Determines if the currently selected pipe is configured.
* *
* \return Boolean true if the selected pipe is configured, false otherwise. * \return Boolean true if the selected pipe is configured, false otherwise.
*/ */
static inline bool Pipe_IsConfigured(void); static inline bool Pipe_IsConfigured(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Pipe_IsConfigured(void)
{
return ((UPSTAX & (1 << CFGOK)) ? true : false);
}
/** Retrieves the endpoint number of the endpoint within the attached device that the currently selected /** Retrieves the endpoint number of the endpoint within the attached device that the currently selected
* pipe is bound to. * pipe is bound to.
* *
* \return Endpoint number the currently selected pipe is bound to. * \return Endpoint number the currently selected pipe is bound to.
*/ */
static inline uint8_t Pipe_BoundEndpointNumber(void); static inline uint8_t Pipe_BoundEndpointNumber(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint8_t Pipe_BoundEndpointNumber(void)
{
return ((UPCFG0X >> PEPNUM0) & PIPE_EPNUM_MASK);
}
/** Sets the period between interrupts for an INTERRUPT type pipe to a specified number of milliseconds. /** Sets the period between interrupts for an INTERRUPT type pipe to a specified number of milliseconds.
* *
* \param[in] Milliseconds Number of milliseconds between each pipe poll. * \param[in] Milliseconds Number of milliseconds between each pipe poll.
*/ */
static inline void Pipe_SetInterruptPeriod(uint8_t Milliseconds); static inline void Pipe_SetInterruptPeriod(const uint8_t Milliseconds) ATTR_ALWAYS_INLINE;
static inline void Pipe_SetInterruptPeriod(const uint8_t Milliseconds)
{
UPCFG2X = Milliseconds;
}
/** Returns a mask indicating which pipe's interrupt periods have elapsed, indicating that the pipe should /** Returns a mask indicating which pipe's interrupt periods have elapsed, indicating that the pipe should
* be serviced. * be serviced.
* *
* \return Mask whose bits indicate which pipes have interrupted. * \return Mask whose bits indicate which pipes have interrupted.
*/ */
static inline uint8_t Pipe_GetPipeInterrupts(void); static inline uint8_t Pipe_GetPipeInterrupts(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint8_t Pipe_GetPipeInterrupts(void)
{
return UPINT;
}
/** Determines if the specified pipe number has interrupted (valid only for INTERRUPT type /** Determines if the specified pipe number has interrupted (valid only for INTERRUPT type
* pipes). * pipes).
@ -304,22 +409,42 @@
* *
* \return Boolean true if the specified pipe has interrupted, false otherwise. * \return Boolean true if the specified pipe has interrupted, false otherwise.
*/ */
static inline bool Pipe_HasPipeInterrupted(uint8_t PipeNumber); static inline bool Pipe_HasPipeInterrupted(const uint8_t PipeNumber) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Pipe_HasPipeInterrupted(const uint8_t PipeNumber)
{
return ((UPINT & (1 << PipeNumber)) ? true : false);
}
/** Unfreezes the selected pipe, allowing it to communicate with an attached device. */ /** Unfreezes the selected pipe, allowing it to communicate with an attached device. */
static inline void Pipe_Unfreeze(void); static inline void Pipe_Unfreeze(void) ATTR_ALWAYS_INLINE;
static inline void Pipe_Unfreeze(void)
{
UPCONX &= ~(1 << PFREEZE);
}
/** Freezes the selected pipe, preventing it from communicating with an attached device. */ /** Freezes the selected pipe, preventing it from communicating with an attached device. */
static inline void Pipe_Freeze(void); static inline void Pipe_Freeze(void) ATTR_ALWAYS_INLINE;
static inline void Pipe_Freeze(void)
{
UPCONX |= (1 << PFREEZE);
}
/** Determines if the currently selected pipe is frozen, and not able to accept data. /** Determines if the currently selected pipe is frozen, and not able to accept data.
* *
* \return Boolean true if the currently selected pipe is frozen, false otherwise. * \return Boolean true if the currently selected pipe is frozen, false otherwise.
*/ */
static inline bool Pipe_IsFrozen(void); static inline bool Pipe_IsFrozen(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Pipe_IsFrozen(void)
{
return ((UPCONX & (1 << PFREEZE)) ? true : false);
}
/** Clears the master pipe error flag. */ /** Clears the master pipe error flag. */
static inline void Pipe_ClearError(void); static inline void Pipe_ClearError(void) ATTR_ALWAYS_INLINE;
static inline void Pipe_ClearError(void)
{
UPINTX &= ~(1 << PERRI);
}
/** Determines if the master pipe error flag is set for the currently selected pipe, indicating that /** Determines 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. * some sort of hardware error has occurred on the pipe.
@ -328,19 +453,34 @@
* *
* \return Boolean true if an error has occurred on the selected pipe, false otherwise. * \return Boolean true if an error has occurred on the selected pipe, false otherwise.
*/ */
static inline bool Pipe_IsError(void); static inline bool Pipe_IsError(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Pipe_IsError(void)
{
return ((UPINTX & (1 << PERRI)) ? true : false);
}
/** Clears all the currently selected pipe's hardware error flags, but does not clear the master error /** Clears all the currently selected pipe's hardware error flags, but does not clear the master error
* flag for the pipe. * flag for the pipe.
*/ */
static inline void Pipe_ClearErrorFlags(void); static inline void Pipe_ClearErrorFlags(void) ATTR_ALWAYS_INLINE;
static inline void Pipe_ClearErrorFlags(void)
{
UPERRX = 0;
}
/** Gets a mask of the hardware error flags which have occurred on the currently selected pipe. This /** Gets a mask of the hardware error flags which have occurred on the currently selected pipe. This
* value can then be masked against the PIPE_ERRORFLAG_* masks to determine what error has occurred. * value can then be masked against the PIPE_ERRORFLAG_* masks to determine what error has occurred.
* *
* \return Mask comprising of PIPE_ERRORFLAG_* bits indicating what error has occurred on the selected pipe. * \return Mask comprising of PIPE_ERRORFLAG_* bits indicating what error has occurred on the selected pipe.
*/ */
static inline uint8_t Pipe_GetErrorFlags(void); static inline uint8_t Pipe_GetErrorFlags(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint8_t Pipe_GetErrorFlags(void)
{
return ((UPERRX & (PIPE_ERRORFLAG_CRC16 | PIPE_ERRORFLAG_TIMEOUT |
PIPE_ERRORFLAG_PID | PIPE_ERRORFLAG_DATAPID |
PIPE_ERRORFLAG_DATATGL)) |
(UPSTAX & (PIPE_ERRORFLAG_OVERFLOW | PIPE_ERRORFLAG_UNDERFLOW)));
}
/** Determines if the currently selected pipe may be read from (if data is waiting in the pipe /** Determines 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 * bank and the pipe is an IN direction, or if the bank is not yet full if the pipe is an OUT
@ -354,7 +494,11 @@
* *
* \return Boolean true if the currently selected pipe may be read from or written to, depending on its direction. * \return Boolean true if the currently selected pipe may be read from or written to, depending on its direction.
*/ */
static inline bool Pipe_IsReadWriteAllowed(void); static inline bool Pipe_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Pipe_IsReadWriteAllowed(void)
{
return ((UPINTX & (1 << RWAL)) ? true : false);
}
/** Determines if an IN request has been received on the currently selected pipe. /** Determines if an IN request has been received on the currently selected pipe.
* *
@ -362,7 +506,11 @@
* *
* \return Boolean true if the current pipe has received an IN packet, false otherwise. * \return Boolean true if the current pipe has received an IN packet, false otherwise.
*/ */
static inline bool Pipe_IsINReceived(void); static inline bool Pipe_IsINReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Pipe_IsINReceived(void)
{
return ((UPINTX & (1 << RXINI)) ? true : false);
}
/** Determines if the currently selected pipe is ready to send an OUT request. /** Determines if the currently selected pipe is ready to send an OUT request.
* *
@ -370,7 +518,11 @@
* *
* \return Boolean true if the current pipe is ready for an OUT packet, false otherwise. * \return Boolean true if the current pipe is ready for an OUT packet, false otherwise.
*/ */
static inline bool Pipe_IsOUTReady(void); static inline bool Pipe_IsOUTReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Pipe_IsOUTReady(void)
{
return ((UPINTX & (1 << TXOUTI)) ? true : false);
}
/** Determines if no SETUP request is currently being sent to the attached device on the selected /** Determines if no SETUP request is currently being sent to the attached device on the selected
* CONTROL type pipe. * CONTROL type pipe.
@ -379,27 +531,43 @@
* *
* \return Boolean true if the current pipe is ready for a SETUP packet, false otherwise. * \return Boolean true if the current pipe is ready for a SETUP packet, false otherwise.
*/ */
static inline bool Pipe_IsSETUPSent(void); static inline bool Pipe_IsSETUPSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Pipe_IsSETUPSent(void)
{
return ((UPINTX & (1 << TXSTPI)) ? true : false);
}
/** Sends the currently selected CONTROL type pipe's contents to the device as a SETUP packet. /** Sends the currently selected CONTROL type pipe's contents to the device as a SETUP packet.
* *
* \ingroup Group_PipePacketManagement * \ingroup Group_PipePacketManagement
*/ */
static inline void Pipe_ClearSETUP(void); static inline void Pipe_ClearSETUP(void) ATTR_ALWAYS_INLINE;
static inline void Pipe_ClearSETUP(void)
{
UPINTX &= ~((1 << TXSTPI) | (1 << FIFOCON));
}
/** Acknowledges the reception of a setup IN request from the attached device on the currently selected /** Acknowledges the reception of a setup IN request from the attached device on the currently selected
* pipe, freeing the bank ready for the next packet. * pipe, freeing the bank ready for the next packet.
* *
* \ingroup Group_PipePacketManagement * \ingroup Group_PipePacketManagement
*/ */
static inline void Pipe_ClearIN(void); static inline void Pipe_ClearIN(void) ATTR_ALWAYS_INLINE;
static inline void Pipe_ClearIN(void)
{
UPINTX &= ~((1 << RXINI) | (1 << FIFOCON));
}
/** Sends the currently selected pipe's contents to the device as an OUT packet on the selected pipe, freeing /** Sends the currently selected pipe's contents to the device as an OUT packet on the selected pipe, freeing
* the bank ready for the next packet. * the bank ready for the next packet.
* *
* \ingroup Group_PipePacketManagement * \ingroup Group_PipePacketManagement
*/ */
static inline void Pipe_ClearOUT(void); static inline void Pipe_ClearOUT(void) ATTR_ALWAYS_INLINE;
static inline void Pipe_ClearOUT(void)
{
UPINTX &= ~((1 << TXOUTI) | (1 << FIFOCON));
}
/** Determines if the device sent a NAK (Negative Acknowledge) in response to the last sent packet on /** Determines if the device sent a NAK (Negative Acknowledge) in response to the last sent packet on
* the currently selected pipe. This occurs when the host sends a packet to the device, but the device * the currently selected pipe. This occurs when the host sends a packet to the device, but the device
@ -411,7 +579,11 @@
* *
* \return Boolean true if an NAK has been received on the current pipe, false otherwise. * \return Boolean true if an NAK has been received on the current pipe, false otherwise.
*/ */
static inline bool Pipe_IsNAKReceived(void); static inline bool Pipe_IsNAKReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Pipe_IsNAKReceived(void)
{
return ((UPINTX & (1 << NAKEDI)) ? true : false);
}
/** Clears the NAK condition on the currently selected pipe. /** Clears the NAK condition on the currently selected pipe.
* *
@ -419,7 +591,11 @@
* *
* \see \ref Pipe_IsNAKReceived() for more details. * \see \ref Pipe_IsNAKReceived() for more details.
*/ */
static inline void Pipe_ClearNAKReceived(void); static inline void Pipe_ClearNAKReceived(void) ATTR_ALWAYS_INLINE;
static inline void Pipe_ClearNAKReceived(void)
{
UPINTX &= ~(1 << NAKEDI);
}
/** Determines if the currently selected pipe has had the STALL condition set by the attached device. /** Determines if the currently selected pipe has had the STALL condition set by the attached device.
* *
@ -427,124 +603,23 @@
* *
* \return Boolean true if the current pipe has been stalled by the attached device, false otherwise. * \return Boolean true if the current pipe has been stalled by the attached device, false otherwise.
*/ */
static inline bool Pipe_IsStalled(void); static inline bool Pipe_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Pipe_IsStalled(void)
{
return ((UPINTX & (1 << RXSTALLI)) ? true : false);
}
/** Clears the STALL condition detection flag on the currently selected pipe, but does not clear the /** Clears the STALL condition detection flag on the currently selected pipe, but does not clear the
* STALL condition itself (this must be done via a ClearFeature control request to the device). * STALL condition itself (this must be done via a ClearFeature control request to the device).
* *
* \ingroup Group_PipePacketManagement * \ingroup Group_PipePacketManagement
*/ */
static inline void Pipe_ClearStall(void); static inline void Pipe_ClearStall(void) ATTR_ALWAYS_INLINE;
#else static inline void Pipe_ClearStall(void)
#define Pipe_BytesInPipe() UPBCX
#define Pipe_GetCurrentPipe() (UPNUM & PIPE_PIPENUM_MASK)
#define Pipe_SelectPipe(pipenum) MACROS{ UPNUM = (pipenum); }MACROE
#define Pipe_ResetPipe(pipenum) MACROS{ UPRST = (1 << (pipenum)); UPRST = 0; }MACROE
#define Pipe_EnablePipe() MACROS{ UPCONX |= (1 << PEN); }MACROE
#define Pipe_DisablePipe() MACROS{ UPCONX &= ~(1 << PEN); }MACROE
#define Pipe_IsEnabled() ((UPCONX & (1 << PEN)) ? true : false)
#define Pipe_GetPipeToken() (UPCFG0X & PIPE_TOKEN_MASK)
#define Pipe_SetPipeToken(token) MACROS{ UPCFG0X = ((UPCFG0X & ~PIPE_TOKEN_MASK) | (token)); }MACROE
#define Pipe_SetInfiniteINRequests() MACROS{ UPCONX |= (1 << INMODE); }MACROE
#define Pipe_SetFiniteINRequests(n) MACROS{ UPCONX &= ~(1 << INMODE); UPINRQX = (n); }MACROE
#define Pipe_IsConfigured() ((UPSTAX & (1 << CFGOK)) ? true : false)
#define Pipe_BoundEndpointNumber() ((UPCFG0X >> PEPNUM0) & PIPE_EPNUM_MASK)
#define Pipe_SetInterruptPeriod(ms) MACROS{ UPCFG2X = (ms); }MACROE
#define Pipe_GetPipeInterrupts() UPINT
#define Pipe_HasPipeInterrupted(n) ((UPINT & (1 << (n))) ? true : false)
#define Pipe_Unfreeze() MACROS{ UPCONX &= ~(1 << PFREEZE); }MACROE
#define Pipe_Freeze() MACROS{ UPCONX |= (1 << PFREEZE); }MACROE
#define Pipe_IsFrozen() ((UPCONX & (1 << PFREEZE)) ? true : false)
#define Pipe_ClearError() MACROS{ UPINTX &= ~(1 << PERRI); }MACROE
#define Pipe_IsError() ((UPINTX & (1 << PERRI)) ? true : false)
#define Pipe_ClearErrorFlags() MACROS{ UPERRX = 0; }MACROE
#define Pipe_GetErrorFlags() ((UPERRX & (PIPE_ERRORFLAG_CRC16 | PIPE_ERRORFLAG_TIMEOUT | \
PIPE_ERRORFLAG_PID | PIPE_ERRORFLAG_DATAPID | \
PIPE_ERRORFLAG_DATATGL)) | \
(UPSTAX & PIPE_ERRORFLAG_OVERFLOW | PIPE_ERRORFLAG_UNDERFLOW))
#define Pipe_IsReadWriteAllowed() ((UPINTX & (1 << RWAL)) ? true : false)
#define Pipe_IsINReceived() ((UPINTX & (1 << RXINI)) ? true : false)
#define Pipe_IsOUTReady() ((UPINTX & (1 << TXOUTI)) ? true : false)
#define Pipe_IsSETUPSent() ((UPINTX & (1 << TXSTPI)) ? true : false)
#define Pipe_ClearIN() MACROS{ UPINTX &= ~((1 << RXINI) | (1 << FIFOCON)); }MACROE
#define Pipe_ClearOUT() MACROS{ UPINTX &= ~((1 << TXOUTI) | (1 << FIFOCON)); }MACROE
#define Pipe_ClearSETUP() MACROS{ UPINTX &= ~((1 << TXSTPI) | (1 << FIFOCON)); }MACROE
#define Pipe_IsNAKReceived() ((UPINTX & (1 << NAKEDI)) ? true : false)
#define Pipe_ClearNAKReceived() MACROS{ UPINTX &= ~(1 << NAKEDI); }MACROE
#define Pipe_IsStalled() ((UPINTX & (1 << RXSTALLI)) ? true : false)
#define Pipe_ClearStall() MACROS{ UPINTX &= ~(1 << RXSTALLI); }MACROE
#endif
/* Enums: */
/** Enum for the possible error return codes of the Pipe_WaitUntilReady function.
*
* \ingroup Group_PipeRW
*/
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
* \ref USB_STREAM_TIMEOUT_MS macro.
*/
};
/** Enum for the possible error return codes of the Pipe_*_Stream_* functions.
*
* \ingroup Group_PipeRW
*/
enum Pipe_Stream_RW_ErrorCodes_t
{ {
PIPE_RWSTREAM_NoError = 0, /**< Command completed successfully, no error. */ UPINTX &= ~(1 << RXSTALLI);
PIPE_RWSTREAM_PipeStalled = 1, /**< The device stalled the pipe during the transfer. */ }
PIPE_RWSTREAM_DeviceDisconnected = 2, /**< Device was disconnected from the host during
* the transfer.
*/
PIPE_RWSTREAM_Timeout = 3, /**< The device failed to accept or send the next packet
* within the software timeout period set by the
* \ref USB_STREAM_TIMEOUT_MS macro.
*/
PIPE_RWSTREAM_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. /** Reads one byte from the currently selected pipe's bank, for OUT direction pipes.
* *
* \ingroup Group_PipePrimitiveRW * \ingroup Group_PipePrimitiveRW
@ -1047,13 +1122,6 @@
/* Private Interface - For use in library only: */ /* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__) #if !defined(__DOXYGEN__)
/* Macros: */
#define PIPE_TOKEN_MASK (0x03 << PTOKEN0)
#if !defined(ENDPOINT_CONTROLEP)
#define ENDPOINT_CONTROLEP 0
#endif
/* Function Prototypes: */ /* Function Prototypes: */
void Pipe_ClearPipes(void); void Pipe_ClearPipes(void);

@ -196,20 +196,40 @@
*/ */
#define EP_TYPE_INTERRUPT 0x03 #define EP_TYPE_INTERRUPT 0x03
#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 acknowledged within this time period, the stream function will fail.
*
* This value may be overridden in the user project makefile as the value of the
* \ref USB_STREAM_TIMEOUT_MS token, and passed to the compiler using the -D switch.
*/
#define USB_STREAM_TIMEOUT_MS 100
#endif
/* Inline Functions: */
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) || defined(__DOXYGEN__) #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) || defined(__DOXYGEN__)
/** Returns boolean true if the VBUS line is currently high (i.e. the USB host is supplying power), /** Returns boolean true if the VBUS line is currently high (i.e. the USB host is supplying power),
* otherwise returns false. * otherwise returns false.
* *
* \note This token is not available on some AVR models which do not support hardware VBUS monitoring. * \note This function is not available on some AVR models which do not support hardware VBUS monitoring.
*/ */
#define USB_VBUS_GetStatus() ((USBSTA & (1 << VBUS)) ? true : false) static inline bool USB_VBUS_GetStatus(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool USB_VBUS_GetStatus(void)
{
return ((USBSTA & (1 << VBUS)) ? true : false);
}
#endif #endif
/** Detaches the device from the USB bus. This has the effect of removing the device from any /** Detaches the device from the USB bus. This has the effect of removing the device from any
* attached host, ceasing USB communications. If no host is present, this prevents any host from * attached host, ceasing USB communications. If no host is present, this prevents any host from
* enumerating the device once attached until \ref USB_Attach() is called. * enumerating the device once attached until \ref USB_Attach() is called.
*/ */
#define USB_Detach() MACROS{ UDCON |= (1 << DETACH); }MACROE static inline void USB_Detach(void) ATTR_ALWAYS_INLINE;
static inline void USB_Detach(void)
{
UDCON |= (1 << DETACH);
}
/** Attaches the device to the USB bus. This announces the device's presence to any attached /** 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 * USB host, starting the enumeration process. If no host is present, attaching the device
@ -219,18 +239,11 @@
* attachment of a device to the host. This is despite the bit being located in the device-mode * 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. * register and despite the datasheet making no mention of its requirement in host mode.
*/ */
#define USB_Attach() MACROS{ UDCON &= ~(1 << DETACH); }MACROE static inline void USB_Attach(void) ATTR_ALWAYS_INLINE;
static inline void USB_Attach(void)
#if !defined(USB_STREAM_TIMEOUT_MS) || defined(__DOXYGEN__) {
/** Constant for the maximum software timeout period of the USB data stream transfer functions UDCON &= ~(1 << DETACH);
* (both control and standard) when in either device or host mode. If the next packet of a stream }
* is not received or acknowledged within this time period, the stream function will fail.
*
* This value may be overridden in the user project makefile as the value of the
* \ref USB_STREAM_TIMEOUT_MS token, and passed to the compiler using the -D switch.
*/
#define USB_STREAM_TIMEOUT_MS 100
#endif
/* Function Prototypes: */ /* Function Prototypes: */
/** Main function to initialize and start the USB interface. Once active, the USB interface will /** Main function to initialize and start the USB interface. Once active, the USB interface will
@ -342,31 +355,93 @@
/* Private Interface - For use in library only: */ /* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__) #if !defined(__DOXYGEN__)
/* Macros: */ /* Inline Functions: */
#define USB_PLL_On() MACROS{ PLLCSR = USB_PLL_PSC; PLLCSR |= (1 << PLLE); }MACROE static inline void USB_PLL_On(void) ATTR_ALWAYS_INLINE;
#define USB_PLL_Off() MACROS{ PLLCSR = 0; }MACROE static inline void USB_PLL_On(void)
#define USB_PLL_IsReady() ((PLLCSR & (1 << PLOCK)) ? true : false) {
PLLCSR = USB_PLL_PSC;
PLLCSR |= (1 << PLLE);
}
static inline void USB_PLL_Off(void) ATTR_ALWAYS_INLINE;
static inline void USB_PLL_Off(void)
{
PLLCSR = 0;
}
static inline bool USB_PLL_IsReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool USB_PLL_IsReady(void)
{
return ((PLLCSR & (1 << PLOCK)) ? true : false);
}
static inline void USB_REG_On(void) ATTR_ALWAYS_INLINE;
static inline void USB_REG_On(void)
{
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
#define USB_REG_On() MACROS{ UHWCON |= (1 << UVREGE); }MACROE UHWCON |= (1 << UVREGE);
#define USB_REG_Off() MACROS{ UHWCON &= ~(1 << UVREGE); }MACROE
#else #else
#define USB_REG_On() MACROS{ REGCR &= ~(1 << REGDIS); }MACROE REGCR &= ~(1 << REGDIS);
#define USB_REG_Off() MACROS{ REGCR |= (1 << REGDIS); }MACROE #endif
}
static inline void USB_REG_Off(void) ATTR_ALWAYS_INLINE;
static inline void USB_REG_Off(void)
{
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
UHWCON &= ~(1 << UVREGE);
#else
REGCR |= (1 << REGDIS);
#endif
}
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
static inline void USB_OTGPAD_On(void) ATTR_ALWAYS_INLINE;
static inline void USB_OTGPAD_On(void)
{
USBCON |= (1 << OTGPADE);
}
static inline void USB_OTGPAD_Off(void) ATTR_ALWAYS_INLINE;
static inline void USB_OTGPAD_Off(void)
{
USBCON &= ~(1 << OTGPADE);
}
#endif #endif
#define USB_OTGPAD_On() MACROS{ USBCON |= (1 << OTGPADE); }MACROE static inline void USB_CLK_Freeze(void) ATTR_ALWAYS_INLINE;
#define USB_OTGPAD_Off() MACROS{ USBCON &= ~(1 << OTGPADE); }MACROE static inline void USB_CLK_Freeze(void)
{
USBCON |= (1 << FRZCLK);
}
#define USB_CLK_Freeze() MACROS{ USBCON |= (1 << FRZCLK); }MACROE static inline void USB_CLK_Unfreeze(void) ATTR_ALWAYS_INLINE;
#define USB_CLK_Unfreeze() MACROS{ USBCON &= ~(1 << FRZCLK); }MACROE static inline void USB_CLK_Unfreeze(void)
{
USBCON &= ~(1 << FRZCLK);
}
#define USB_Controller_Enable() MACROS{ USBCON |= (1 << USBE); }MACROE static inline void USB_Controller_Enable(void) ATTR_ALWAYS_INLINE;
#define USB_Controller_Disable() MACROS{ USBCON &= ~(1 << USBE); }MACROE static inline void USB_Controller_Enable(void)
#define USB_Controller_Reset() MACROS{ const uint8_t Temp = USBCON; USBCON = (Temp & ~(1 << USBE)); \ {
USBCON = (Temp | (1 << USBE)); }MACROE USBCON |= (1 << USBE);
}
static inline void USB_Controller_Disable(void) ATTR_ALWAYS_INLINE;
static inline void USB_Controller_Disable(void)
{
USBCON &= ~(1 << USBE);
}
static inline void USB_Controller_Reset(void) ATTR_ALWAYS_INLINE;
static inline void USB_Controller_Reset(void)
{
const uint8_t Temp = USBCON;
USBCON = (Temp & ~(1 << USBE));
USBCON = (Temp | (1 << USBE));
}
/* Inline Functions: */
#if defined(USB_CAN_BE_BOTH) #if defined(USB_CAN_BE_BOTH)
static inline uint8_t USB_GetUSBModeFromUID(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; static inline uint8_t USB_GetUSBModeFromUID(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint8_t USB_GetUSBModeFromUID(void) static inline uint8_t USB_GetUSBModeFromUID(void)

@ -47,11 +47,6 @@
#include <util/atomic.h> #include <util/atomic.h>
#include <stdbool.h> #include <stdbool.h>
#include "../../../Common/Common.h"
#include "../HighLevel/USBMode.h"
#include "../HighLevel/Events.h"
#include "USBController.h"
/* Enable C linkage for C++ Compilers: */ /* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
@ -91,6 +86,12 @@
#define USB_INT_SRPI OTGIEN, (1 << SRPE) , OTGINT, (1 << SRPI) #define USB_INT_SRPI OTGIEN, (1 << SRPE) , OTGINT, (1 << SRPI)
#define USB_INT_RXSTPI UEIENX, (1 << RXSTPE) , UEINTX, (1 << RXSTPI) #define USB_INT_RXSTPI UEIENX, (1 << RXSTPE) , UEINTX, (1 << RXSTPI)
/* Includes: */
#include "../../../Common/Common.h"
#include "../HighLevel/USBMode.h"
#include "../HighLevel/Events.h"
#include "USBController.h"
/* Function Prototypes: */ /* Function Prototypes: */
void USB_INT_ClearAllInterrupts(void); void USB_INT_ClearAllInterrupts(void);
void USB_INT_DisableAllInterrupts(void); void USB_INT_DisableAllInterrupts(void);

@ -36,6 +36,7 @@
* - Removed the automated checking of event names in the demo, project and bootloader makefiles due to inconsistancies between the * - Removed the automated checking of event names in the demo, project and bootloader makefiles due to inconsistancies between the
* behaviour of the command line tools used to perform the check on each platform * behaviour of the command line tools used to perform the check on each platform
* - Internal USB driver source files renamed and moved to ease future possible architecture ports * - Internal USB driver source files renamed and moved to ease future possible architecture ports
* - All internal pseudo-function macros have been converted to true inline functions for type-safety and readability
* *
* <b>Fixed:</b> * <b>Fixed:</b>
* - Fixed AVRISP project sending a LOAD EXTENDED ADDRESS command to 128KB AVRs after programming or reading from * - Fixed AVRISP project sending a LOAD EXTENDED ADDRESS command to 128KB AVRs after programming or reading from

@ -12,6 +12,11 @@
* *
* \section Sec_Migration100513 Migrating from 100513 to XXXXXX * \section Sec_Migration100513 Migrating from 100513 to XXXXXX
* *
* <b>Non-USB Library Components</b>
* - The Dataflash board driver stub file has changed, as dataflash functions previously located in the internal
* Dataflash driver of the library have now been moved to the individual board files. Existing drivers can
* copy-paste the new functions from the board Dataflash stub driver.
*
* <b>USB Core</b> * <b>USB Core</b>
* - A new USB driver source file, Drivers/USB/LowLevel/Device.c now exists. This source file should be added to all project * - A new USB driver source file, Drivers/USB/LowLevel/Device.c now exists. This source file should be added to all project
* makefiles using the USB driver of LUFA, or the makefile should be updated to use the new module source variables. * makefiles using the USB driver of LUFA, or the makefile should be updated to use the new module source variables.

Loading…
Cancel
Save