You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
378 lines
11 KiB
C
378 lines
11 KiB
C
4 years ago
|
/**
|
||
|
* \file
|
||
|
*
|
||
|
* \brief SAM USB HPL
|
||
|
*
|
||
|
* Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
|
||
|
*
|
||
|
* \asf_license_start
|
||
|
*
|
||
|
* \page License
|
||
|
*
|
||
|
* Subject to your compliance with these terms, you may use Microchip
|
||
|
* software and any derivatives exclusively with Microchip products.
|
||
|
* It is your responsibility to comply with third party license terms applicable
|
||
|
* to your use of third party software (including open source software) that
|
||
|
* may accompany Microchip software.
|
||
|
*
|
||
|
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
|
||
|
* WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
|
||
|
* INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
|
||
|
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
|
||
|
* LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
|
||
|
* LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
|
||
|
* SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
|
||
|
* POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
|
||
|
* ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
|
||
|
* RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
|
||
|
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
|
||
|
*
|
||
|
* \asf_license_stop
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#ifndef _HPL_USB_DEVICE_H_INCLUDED
|
||
|
#define _HPL_USB_DEVICE_H_INCLUDED
|
||
|
|
||
|
#include <hpl_usb.h>
|
||
|
#include "hpl_usb_config.h"
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
/** USB Device callback type. */
|
||
|
enum usb_d_cb_type {
|
||
|
/** USB device SOF callback. */
|
||
|
USB_D_CB_SOF,
|
||
|
/** USB device events callbacks. */
|
||
|
USB_D_CB_EVENT,
|
||
|
/** Number of types of USB device callback types. */
|
||
|
USB_D_CB_N
|
||
|
};
|
||
|
|
||
|
/** USB Device endpoint callback type. */
|
||
|
enum usb_d_ep_cb_type {
|
||
|
/** USB device endpoint setup callback. */
|
||
|
USB_D_EP_CB_SETUP,
|
||
|
/** USB device endpoint more data callback. */
|
||
|
USB_D_EP_CB_MORE,
|
||
|
/** USB device endpoint transaction done or error callback. */
|
||
|
USB_D_EP_CB_XFER,
|
||
|
/** Number of types of USB device endpoint callback types. */
|
||
|
USB_D_EP_CB_N
|
||
|
};
|
||
|
|
||
|
/** Control action for USB device LPM handshake. */
|
||
|
enum usb_d_lpm_ctrl {
|
||
|
/** No LPM handshake, not supported. */
|
||
|
USB_D_LPM_DISABLE,
|
||
|
/** ACK the LPM transaction. */
|
||
|
USB_D_LPM_ACK,
|
||
|
/** NYET the LPM transaction. */
|
||
|
USB_D_LPM_NYET
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* USB device transfer descriptor.
|
||
|
*/
|
||
|
struct usb_d_transfer {
|
||
|
/** Pointer to data buffer to transfer.
|
||
|
* Note that it's recommended that the buffer is 32-bit aligned since
|
||
|
* some of USB peripheral require this.
|
||
|
*/
|
||
|
uint8_t *buf;
|
||
|
/** Transfer size, in number of bytes.
|
||
|
* Note that it's recommended that the buffer size is 32-bit aligned
|
||
|
* (modeled by 4) since some of USB peripheral require this.
|
||
|
*/
|
||
|
uint32_t size;
|
||
|
/** Endpoint address. */
|
||
|
uint8_t ep;
|
||
|
/** Append ZLP for IN transfer, wait ZLP for OUT transfer. */
|
||
|
uint8_t zlp;
|
||
|
};
|
||
|
|
||
|
/** USB device transactions status structure. */
|
||
|
struct usb_d_trans_status {
|
||
|
/** Total data size. */
|
||
|
uint32_t size;
|
||
|
/** Total transfered data count. */
|
||
|
uint32_t count;
|
||
|
/** Endpoint address. */
|
||
|
uint8_t ep;
|
||
|
/** Endpoint type - CTRL/ISO/INT/BULK. */
|
||
|
uint8_t xtype : 2;
|
||
|
/** Transactions state, busy or not. */
|
||
|
uint8_t busy : 1;
|
||
|
/** Transactions state, setup received or not. */
|
||
|
uint8_t setup : 1;
|
||
|
/** Transactions state, stall or not. */
|
||
|
uint8_t stall : 1;
|
||
|
/** Transactions direction. */
|
||
|
uint8_t dir : 1;
|
||
|
};
|
||
|
|
||
|
/** Prototype function for callback that is invoked on USB device SOF. */
|
||
|
typedef void (*_usb_d_dev_sof_cb_t)(void);
|
||
|
|
||
|
/** Prototype function for callback that is invoked on USB device events. */
|
||
|
typedef void (*_usb_d_dev_event_cb_t)(const enum usb_event, const uint32_t param);
|
||
|
|
||
|
/** HPL USB device callbacks. */
|
||
|
struct _usb_d_dev_callbacks {
|
||
|
/** Callback that is invoked on SOF. */
|
||
|
_usb_d_dev_sof_cb_t sof;
|
||
|
/** Callback that is invoked on USB RESET/WAKEUP/RESUME/SUSPEND. */
|
||
|
_usb_d_dev_event_cb_t event;
|
||
|
};
|
||
|
|
||
|
/** USB device endpoint callbacks. */
|
||
|
enum usb_d_dev_ep_cb_type {
|
||
|
/** Setup packet is received. */
|
||
|
USB_D_DEV_EP_CB_SETUP,
|
||
|
/** Try to require more data. */
|
||
|
USB_D_DEV_EP_CB_MORE,
|
||
|
/** Transaction done OK/ERROR. */
|
||
|
USB_D_DEV_EP_CB_DONE,
|
||
|
/** Number of device endpoint callbacks. */
|
||
|
USB_D_DEV_EP_CB_N
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Callback that is invoked when control SETUP packet has bee received.
|
||
|
* \ref _usb_d_dev_ep_read_req() must be invoked to read setup data, and allow
|
||
|
* IN/OUT transactions on control endpoint.
|
||
|
*/
|
||
|
typedef void (*_usb_d_dev_ep_cb_setup_t)(const uint8_t ep);
|
||
|
|
||
|
/** Callback that is invoked when buffer is done, but last packet is full size
|
||
|
* packet without ZLP. Return \c true if more data has been requested. */
|
||
|
typedef bool (*_usb_d_dev_ep_cb_more_t)(const uint8_t ep, const uint32_t transfered);
|
||
|
|
||
|
/** Callback that is invoked when all data is finished, including background
|
||
|
* transfer, or error happens. */
|
||
|
typedef void (*_usb_d_dev_ep_cb_done_t)(const uint8_t ep, const int32_t code, const uint32_t transfered);
|
||
|
|
||
|
/** Callbacks for HPL USB device endpoint. */
|
||
|
struct _usb_d_dev_ep_callbacks {
|
||
|
/** Callback that is invoked when SETUP packet is received.
|
||
|
* \ref _usb_d_dev_ep_read_req() must be invoked to read setup data, and
|
||
|
* allow IN/OUT transactions on control endpoint.
|
||
|
*/
|
||
|
_usb_d_dev_ep_cb_setup_t setup;
|
||
|
/** Callback that is invoked to check if buffer is NULL and more data is
|
||
|
* required.
|
||
|
* It's called when last packet is full size packet, without
|
||
|
* auto ZLP enabled.
|
||
|
* It could be called when background transfer is still in progress.
|
||
|
*/
|
||
|
_usb_d_dev_ep_cb_more_t more;
|
||
|
/** Callback that is invoked when transaction is done, including background
|
||
|
* transfer, or error occurs.
|
||
|
*/
|
||
|
_usb_d_dev_ep_cb_done_t done;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* \brief Initialize the USB device instance
|
||
|
* \return Operation result status.
|
||
|
* \retval 0 Success.
|
||
|
* \retval <0 Error code.
|
||
|
*/
|
||
|
int32_t _usb_d_dev_init(void);
|
||
|
|
||
|
/**
|
||
|
* \brief Deinitialize the USB device instance
|
||
|
* \return Operation result status.
|
||
|
* \retval 0 Success.
|
||
|
* \retval <0 Error code.
|
||
|
*/
|
||
|
void _usb_d_dev_deinit(void);
|
||
|
|
||
|
/**
|
||
|
* \brief Register callback to handle USB device events
|
||
|
* \param[in] type Callback type. See \ref usb_d_cb_type.
|
||
|
* \param[in] func Pointer to callback function.
|
||
|
* Refer to \ref _usb_d_dev_callbacks for the prototypes.
|
||
|
*/
|
||
|
void _usb_d_dev_register_callback(const enum usb_d_cb_type type, const FUNC_PTR func);
|
||
|
|
||
|
/**
|
||
|
* \brief Register callback to handle USB device endpoint events
|
||
|
* \param[in] type Callback type. See \ref usb_d_dev_ep_cb_type.
|
||
|
* \param[in] func Pointer to callback function.
|
||
|
* Refer to \ref _usb_d_dev_ep_callbacks for the prototypes.
|
||
|
*/
|
||
|
void _usb_d_dev_register_ep_callback(const enum usb_d_dev_ep_cb_type type, const FUNC_PTR func);
|
||
|
|
||
|
/**
|
||
|
* \brief Enable the USB device
|
||
|
* \return Operation result status.
|
||
|
* \retval 0 Success.
|
||
|
* \retval <0 Error code.
|
||
|
*/
|
||
|
int32_t _usb_d_dev_enable(void);
|
||
|
|
||
|
/**
|
||
|
* \brief Disable the USB device
|
||
|
* \return Operation result status.
|
||
|
* \retval 0 Success.
|
||
|
* \retval <0 Error code.
|
||
|
*/
|
||
|
int32_t _usb_d_dev_disable(void);
|
||
|
|
||
|
/**
|
||
|
* \brief Attach the USB device
|
||
|
*/
|
||
|
void _usb_d_dev_attach(void);
|
||
|
|
||
|
/**
|
||
|
* \brief Detach the USB device
|
||
|
*/
|
||
|
void _usb_d_dev_detach(void);
|
||
|
|
||
|
/**
|
||
|
* \brief Send the USB device remote wakeup to host
|
||
|
*/
|
||
|
void _usb_d_dev_send_remotewakeup(void);
|
||
|
|
||
|
/**
|
||
|
* \brief Get the USB device working speed
|
||
|
* \return USB speed. See \ref usb_speed.
|
||
|
*/
|
||
|
enum usb_speed _usb_d_dev_get_speed(void);
|
||
|
|
||
|
/**
|
||
|
* \brief Set the USB device address
|
||
|
* \param[in] addr Address to be used.
|
||
|
*/
|
||
|
void _usb_d_dev_set_address(const uint8_t addr);
|
||
|
|
||
|
/**
|
||
|
* \brief Get the USB device address
|
||
|
* \return Address that is used.
|
||
|
*/
|
||
|
uint8_t _usb_d_dev_get_address(void);
|
||
|
|
||
|
/**
|
||
|
* \brief Get the USB device frame number
|
||
|
* \return The frame number.
|
||
|
*/
|
||
|
uint16_t _usb_d_dev_get_frame_n(void);
|
||
|
|
||
|
/**
|
||
|
* \brief Get the USB device micro frame number
|
||
|
* \return The micro frame number inside one frame (0~7).
|
||
|
*/
|
||
|
uint8_t _usb_d_dev_get_uframe_n(void);
|
||
|
|
||
|
/**
|
||
|
* \brief Initialize and enable the USB device default endpoint 0
|
||
|
* \param[in] max_pkt_siz Max endpoint size.
|
||
|
* \return Operation result status.
|
||
|
* \retval 0 Success.
|
||
|
* \retval <0 Error code.
|
||
|
*/
|
||
|
int32_t _usb_d_dev_ep0_init(const uint8_t max_pkt_siz);
|
||
|
|
||
|
/**
|
||
|
* \brief Initialize and enable the USB device endpoint
|
||
|
* \param[in] ep Endpoint address,
|
||
|
* see endpoint descriptor details in USB spec.
|
||
|
* \param[in] attr Endpoint attributes,
|
||
|
* see endpoint descriptor details in USB spec.
|
||
|
* \param[in] max_pkt_siz Endpoint size,
|
||
|
* see endpoint descriptor details in USB spec.
|
||
|
* \return Operation result status.
|
||
|
* \retval 0 Success.
|
||
|
* \retval <0 Error code.
|
||
|
*/
|
||
|
int32_t _usb_d_dev_ep_init(const uint8_t ep, const uint8_t attr, uint16_t max_pkt_siz);
|
||
|
|
||
|
/**
|
||
|
* \brief Disable and deinitialize the USB device endpoint
|
||
|
|
||
|
* \param[in] ep The endpoint to deinitialize.
|
||
|
*/
|
||
|
void _usb_d_dev_ep_deinit(const uint8_t ep);
|
||
|
|
||
|
/**
|
||
|
* \brief Enable the endpoint
|
||
|
* \param[in] ep The endpoint to enable.
|
||
|
* \return Operation result status.
|
||
|
* \retval 0 Success.
|
||
|
* \retval <0 Error code.
|
||
|
*/
|
||
|
int32_t _usb_d_dev_ep_enable(const uint8_t ep);
|
||
|
|
||
|
/**
|
||
|
* \brief Disable the endpoint
|
||
|
* \param[in] ep The endpoint to disable.
|
||
|
*/
|
||
|
void _usb_d_dev_ep_disable(const uint8_t ep);
|
||
|
|
||
|
/**
|
||
|
* \brief Set/Clear/Get USB device endpoint stall status
|
||
|
* \param[in] ep Endpoint address.
|
||
|
* \param[in] ctrl Operation selector. See \ref usb_ep_stall_ctrl.
|
||
|
* \return Operation result or stall status.
|
||
|
* \retval 0 Success or not stall.
|
||
|
* \retval 1 Endpoint is stalled.
|
||
|
* \retval -1 error.
|
||
|
*/
|
||
|
int32_t _usb_d_dev_ep_stall(const uint8_t ep, const enum usb_ep_stall_ctrl ctrl);
|
||
|
|
||
|
/**
|
||
|
* \brief Read setup request data from specific endpoint
|
||
|
* \param[in] ep Endpoint address.
|
||
|
* \param[out] req_buf Pointer to buffer to locate the setup packet.
|
||
|
* \return Number of bytes or error code.
|
||
|
* \retval <0 error code.
|
||
|
* \retval 0 No setup packet ready for read.
|
||
|
* \retval >0 Size of bytes read, and ready to start IN/OUT. Note that if
|
||
|
* this number is over 8, only first 8 bytes will be copied.
|
||
|
*/
|
||
|
int32_t _usb_d_dev_ep_read_req(const uint8_t ep, uint8_t *req_buf);
|
||
|
|
||
|
/**
|
||
|
* \brief Start USB device transfer
|
||
|
*
|
||
|
* On different USB peripheral hardware the transaction buffer address and size
|
||
|
* may have different constraints. E.g., some hardware may require input address
|
||
|
* 32-bit aligned, and input size 32-bit aligned. Refer to the corresponding
|
||
|
* hardware usage reference documents.
|
||
|
* The constraints are checked in implementation, with error code returned.
|
||
|
*
|
||
|
* \param[in] trans Pointer to the transaction description.
|
||
|
* \return Operation result status.
|
||
|
* \retval 1 Busy.
|
||
|
* \retval 0 Success.
|
||
|
* \retval <0 Error code.
|
||
|
*/
|
||
|
int32_t _usb_d_dev_ep_trans(const struct usb_d_transfer *trans);
|
||
|
|
||
|
/**
|
||
|
* \brief Abort pending USB device transaction on specific endpoint
|
||
|
* \param[in] ep Endpoint address to abort.
|
||
|
*/
|
||
|
void _usb_d_dev_ep_abort(const uint8_t ep);
|
||
|
|
||
|
/**
|
||
|
* \brief Retrieve endpoint status.
|
||
|
* \param[in] ep Endpoint address.
|
||
|
* \param[out] stat Pointer to buffer to fill status description.
|
||
|
* \return Status.
|
||
|
* \retval 2 Packet writing.
|
||
|
* \retval 1 Busy.
|
||
|
* \retval 0 Ready.
|
||
|
* \retval <0 Error code.
|
||
|
*/
|
||
|
int32_t _usb_d_dev_ep_get_status(const uint8_t ep, struct usb_d_trans_status *stat);
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#endif /* _HPL_USB_DEVICE_H_INCLUDED */
|