/** | |
* \file | |
* | |
* \brief Common API for USB Device Drivers (UDD) | |
* | |
* Copyright (C) 2009 Atmel Corporation. All rights reserved. | |
* | |
* \page License | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted provided that the following conditions are met: | |
* | |
* 1. Redistributions of source code must retain the above copyright notice, | |
* this list of conditions and the following disclaimer. | |
* | |
* 2. Redistributions in binary form must reproduce the above copyright notice, | |
* this list of conditions and the following disclaimer in the documentation | |
* and/or other materials provided with the distribution. | |
* | |
* 3. The name of Atmel may not be used to endorse or promote products derived | |
* from this software without specific prior written permission. | |
* | |
* 4. This software may only be redistributed and used in connection with an | |
* Atmel AVR product. | |
* | |
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | |
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | |
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | |
* DAMAGE. | |
*/ | |
#ifndef _UDD_H_ | |
#define _UDD_H_ | |
#include "usb_protocol.h" | |
#include "udc_desc.h" | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
/** | |
* \ingroup usb_device_group | |
* \defgroup udd_group USB Device Driver (UDD) | |
* | |
* The UDD driver provides a low-level abstraction of the device | |
* controller hardware. Most events coming from the hardware such as | |
* interrupts, which may cause the UDD to call into the UDC and UDI. | |
* | |
* @{ | |
*/ | |
//! \brief Endpoint identifier | |
typedef uint8_t udd_ep_id_t; | |
//! \brief Endpoint transfer status | |
//! Returned in parameters of callback register via udd_ep_run routine. | |
typedef enum { | |
UDD_EP_TRANSFER_OK = 0, | |
UDD_EP_TRANSFER_ABORT = 1 | |
} udd_ep_status_t; | |
/** | |
* \brief A USB Device SETUP request | |
* | |
* SETUP packet contains following information. | |
*/ | |
COMPILER_PACK_SET(1); | |
typedef struct { | |
uint8_t bmRequestType; | |
uint8_t bRequest; | |
uint16_t wValue; | |
uint16_t wIndex; | |
uint16_t wLength; | |
} udd_setup_req_t; | |
COMPILER_PACK_RESET(); | |
/** | |
* \brief Global variable to give and record information of the setup request management | |
* | |
* This global variable allows to decode and response a setup request. | |
* It can be updated by udc_process_setup() from UDC or *setup() from UDIs. | |
*/ | |
typedef struct { | |
udd_setup_req_t req; //!< Data received in USB SETUP packet | |
uint8_t *payload; //!< Point to buffer to send or fill with data following SETUP packet | |
uint16_t payload_size; //!< Size of buffer to send or fill, and content the number of byte transfered | |
//! when the calbbacks "callback/over_under_run" are called. | |
void (*callback) (void); //!< Callback called after reception of ZLP from setup request | |
bool(*over_under_run) (void); //!< Callback called when the buffer given (.payload) is full or empty. | |
//! This one return false to abort data transfer, or true with a new buffer in .payload. | |
} udd_ctrl_request_t; | |
extern udd_ctrl_request_t udd_g_ctrlreq; | |
//! Return true if the setup request \a udd_g_ctrlreq indicates IN data transfer | |
#define Udd_setup_is_in() \ | |
(USB_REQ_DIR_IN == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) | |
//! Return true if the setup request \a udd_g_ctrlreq indicates OUT data transfer | |
#define Udd_setup_is_out() \ | |
(USB_REQ_DIR_OUT == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) | |
//! Return the type of the SETUP request \a udd_g_ctrlreq. \see usb_reqtype. | |
#define Udd_setup_type() \ | |
(udd_g_ctrlreq.req.bmRequestType & USB_REQ_TYPE_MASK) | |
//! Return the recipient of the SETUP request \a udd_g_ctrlreq. \see usb_recipient | |
#define Udd_setup_recipient() \ | |
(udd_g_ctrlreq.req.bmRequestType & USB_REQ_RECIP_MASK) | |
/** | |
* \brief End of halt callback function type. | |
* Registered by routine udd_ep_wait_stall_clear() | |
* Callback called when endpoint stall is cleared. | |
*/ | |
typedef void (*udd_callback_halt_cleared_t) (void); | |
/** | |
* \brief End of transfer callback function type. | |
* Registered by routine udd_ep_run() | |
* Callback called by USB interrupt after data transfer or abort (reset,...). | |
* | |
* \param status UDD_EP_TRANSFER_OK, if transfer is complete | |
* \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted | |
* \param n number of data transfered | |
*/ | |
typedef void (*udd_callback_trans_t) (udd_ep_status_t status, | |
iram_size_t nb_transfered); | |
/** | |
* \brief Authorizes the VBUS event | |
* | |
* \return true, if the VBUS monitoring is possible. | |
*/ | |
bool udd_include_vbus_monitoring(void); | |
/** | |
* \brief Enables the USB Device mode | |
*/ | |
void udd_enable(void); | |
/** | |
* \brief Disables the USB Device mode | |
*/ | |
void udd_disable(void); | |
/** | |
* \brief Attach device to the bus when possible | |
* | |
* \warning If a VBus control is included in driver, | |
* then it will attach device when an acceptable Vbus | |
* level from the host is detected. | |
*/ | |
void udd_attach(void); | |
/** | |
* \brief Detaches the device from the bus | |
* | |
* The driver must remove pull-up on USB line D- or D+. | |
*/ | |
void udd_detach(void); | |
/** | |
* \brief Test whether the USB Device Controller is running at high | |
* speed or not. | |
* | |
* \return \c true if the Device is running at high speed mode, otherwise \c false. | |
*/ | |
bool udd_is_high_speed(void); | |
/** | |
* \brief Changes the USB address of device | |
* | |
* \param address New USB address | |
*/ | |
void udd_set_address(uint8_t address); | |
/** | |
* \brief Returns the USB address of device | |
* | |
* \return USB address | |
*/ | |
uint8_t udd_getaddress(void); | |
/** | |
* \brief Returns the current start of frame number | |
* | |
* \return current start of frame number. | |
*/ | |
uint16_t udd_get_frame_number(void); | |
/*! \brief The USB driver sends a resume signal called Upstream Resume | |
*/ | |
void udd_send_wake_up(void); | |
/** | |
* \brief Load setup payload | |
* | |
* \param payload Pointer on payload | |
* \param payload_size Size of payload | |
*/ | |
void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size ); | |
/** | |
* \name Endpoint Management | |
* | |
* The following functions allow drivers to create and remove | |
* endpoints, as well as set, clear and query their "halted" and | |
* "wedged" states. | |
*/ | |
//@{ | |
#if (0!=USB_DEVICE_MAX_EP) | |
/** | |
* \brief Configures and enables an endpoint | |
* | |
* \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). | |
* \param bmAttributes Attributes of endpoint declared in the descriptor. | |
* \param MaxEndpointSize Endpoint maximum size | |
* | |
* \return \c 1 if the endpoint is enabled, otherwise \c 0. | |
*/ | |
bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, | |
uint16_t MaxEndpointSize); | |
/** | |
* \brief Disables an endpoint | |
* | |
* \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). | |
*/ | |
void udd_ep_free(udd_ep_id_t ep); | |
/** | |
* \brief Check if the endpoint \a ep is halted. | |
* | |
* \param ep The ID of the endpoint to check. | |
* | |
* \return \c 1 if \a ep is halted, otherwise \c 0. | |
*/ | |
bool udd_ep_is_halted(udd_ep_id_t ep); | |
/** | |
* \brief Set the halted state of the endpoint \a ep | |
* | |
* After calling this function, any transaction on \a ep will result | |
* in a STALL handshake being sent. Any pending transactions will be | |
* performed first, however. | |
* | |
* \param ep The ID of the endpoint to be halted | |
* | |
* \return \c 1 if \a ep is halted, otherwise \c 0. | |
*/ | |
bool udd_ep_set_halt(udd_ep_id_t ep); | |
/** | |
* \brief Clear the halted state of the endpoint \a ep | |
* | |
* After calling this function, any transaction on \a ep will | |
* be handled normally, i.e. a STALL handshake will not be sent, and | |
* the data toggle sequence will start at DATA0. | |
* | |
* \param ep The ID of the endpoint to be un-halted | |
* | |
* \return \c 1 if function was successfully done, otherwise \c 0. | |
*/ | |
bool udd_ep_clear_halt(udd_ep_id_t ep); | |
/** | |
* \brief Registers a callback to call when endpoint halt is cleared | |
* | |
* \param ep The ID of the endpoint to use | |
* \param callback NULL or function to call when endpoint halt is cleared | |
* | |
* \warning if the endpoint is not halted then the \a callback is called immediately. | |
* | |
* \return \c 1 if the register is accepted, otherwise \c 0. | |
*/ | |
bool udd_ep_wait_stall_clear(udd_ep_id_t ep, | |
udd_callback_halt_cleared_t callback); | |
/** | |
* \brief Allows to receive or send data on an endpoint | |
* | |
* The driver uses a specific DMA USB to transfer data | |
* from internal RAM to endpoint, if this one is available. | |
* When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. | |
* The \a callback returns the transfer status and eventually the number of byte transfered. | |
* | |
* \param ep The ID of the endpoint to use | |
* \param b_shortpacket Enabled automatic short packet | |
* \param buf Buffer on Internal RAM to send or fill. | |
* It must be align, then use COMPILER_WORD_ALIGNED. | |
* \param buf_size Buffer size to send or fill | |
* \param callback NULL or function to call at the end of transfer | |
* | |
* \warning About \a b_shortpacket, for IN endpoint it means that a short packet | |
* (or a Zero Length Packet) will be sent to the USB line to properly close the usb | |
* transfer at the end of the data transfer. | |
* For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer | |
* at the end of the data transfer (received short packet). | |
* | |
* \return \c 1 if function was successfully done, otherwise \c 0. | |
*/ | |
bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, | |
uint8_t * buf, iram_size_t buf_size, | |
udd_callback_trans_t callback); | |
/** | |
* \brief Aborts transfer on going on endpoint | |
* | |
* If a transfer is on going, then it is stopped and the callback registered is called to signal the end of transfer. | |
* | |
* \param ep The ID of the endpoint to use | |
* \param b_shortpacket Enabled automatic short packet | |
* \param buf Buffer on Internal RAM to send or fill | |
* \param buf_size Buffer size to send or fill | |
* \param callback NULL or function to call at the end of transfer | |
*/ | |
void udd_ep_abort(udd_ep_id_t ep); | |
#endif | |
//@} | |
/** | |
* \name High speed test mode management | |
* | |
* The following functions allow the device to jump to a specific test mode required in high speed mode. | |
*/ | |
//@{ | |
void udd_test_mode_j(void); | |
void udd_test_mode_k(void); | |
void udd_test_mode_se0_nak(void); | |
void udd_test_mode_packet(void); | |
//@} | |
/** | |
* \name UDC callbacks to provide for UDD | |
* | |
* The following callbacks are used by UDD. | |
*/ | |
//@{ | |
/** | |
* \brief Decodes and manages a setup request | |
* | |
* The driver call it when a SETUP packet is received. | |
* The \c udd_g_ctrlreq contains the data of SETUP packet. | |
* If this callback accepts the setup request then it must | |
* return \c 1 and eventually update \c udd_g_ctrlreq to send or receive data. | |
* | |
* \return \c 1 if the request is accepted, otherwise \c 0. | |
*/ | |
extern bool udc_process_setup(void); | |
/** | |
* \brief Reset the UDC | |
* | |
* The UDC must reset all configuration. | |
*/ | |
extern void udc_reset(void); | |
//@} | |
//@} | |
#ifdef __cplusplus | |
} | |
#endif | |
#endif // _UDD_H_ |