espressif_idf-extra-components/usb/usb_host_cdc_acm/include/usb/cdc_acm_host.h

342 lines
12 KiB
C++

/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "usb/usb_host.h"
#include "usb_types_cdc.h"
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct cdc_dev_s *cdc_acm_dev_hdl_t;
/**
* @brief Line Coding structure
* @see Table 17, USB CDC-PSTN specification rev. 1.2
*/
typedef struct {
uint32_t dwDTERate; // in bits per second
uint8_t bCharFormat; // 0: 1 stopbit, 1: 1.5 stopbits, 2: 2 stopbits
uint8_t bParityType; // 0: None, 1: Odd, 2: Even, 3: Mark, 4: Space
uint8_t bDataBits; // 5, 6, 7, 8 or 16
} __attribute__((packed)) cdc_acm_line_coding_t;
/**
* @brief UART State Bitmap
* @see Table 31, USB CDC-PSTN specification rev. 1.2
*/
typedef union {
struct {
uint16_t bRxCarrier : 1; // State of receiver carrier detection mechanism of device. This signal corresponds to V.24 signal 109 and RS-232 signal DCD.
uint16_t bTxCarrier : 1; // State of transmission carrier. This signal corresponds to V.24 signal 106 and RS-232 signal DSR.
uint16_t bBreak : 1; // State of break detection mechanism of the device.
uint16_t bRingSignal : 1; // State of ring signal detection of the device.
uint16_t bFraming : 1; // A framing error has occurred.
uint16_t bParity : 1; // A parity error has occurred.
uint16_t bOverRun : 1; // Received data has been discarded due to overrun in the device.
uint16_t reserved : 9;
};
uint16_t val;
} cdc_acm_uart_state_t;
/**
* @brief CDC-ACM Device Event types to upper layer
*
*/
typedef enum {
CDC_ACM_HOST_ERROR,
CDC_ACM_HOST_SERIAL_STATE,
CDC_ACM_HOST_NETWORK_CONNECTION,
CDC_ACM_HOST_DEVICE_DISCONNECTED
} cdc_acm_host_dev_event_t;
/**
* @brief CDC-ACM Device Event data structure
*
*/
typedef struct {
cdc_acm_host_dev_event_t type;
union {
int error; //!< Error code from USB Host
cdc_acm_uart_state_t serial_state; //!< Serial (UART) state
bool network_connected; //!< Network connection event
cdc_acm_dev_hdl_t cdc_hdl; //!< Disconnection event
} data;
} cdc_acm_host_dev_event_data_t;
/**
* @brief New USB device callback
*
* Provides already opened usb_dev, that will be closed after this callback returns.
* This is useful for peeking device's descriptors, e.g. peeking VID/PID and loading proper driver.
*
* @attention This callback is called from USB Host context, so the CDC device can't be opened here.
*/
typedef void (*cdc_acm_new_dev_callback_t)(usb_device_handle_t usb_dev);
/**
* @brief Data receive callback type
*/
typedef void (*cdc_acm_data_callback_t)(uint8_t *data, size_t data_len, void *user_arg);
/**
* @brief Device event callback type
* @see cdc_acm_host_dev_event_data_t
*/
typedef void (*cdc_acm_host_dev_callback_t)(const cdc_acm_host_dev_event_data_t *event, void *user_ctx);
/**
* @brief Configuration structure of USB Host CDC-ACM driver
*
*/
typedef struct {
size_t driver_task_stack_size; /**< Stack size of the driver's task */
unsigned driver_task_priority; /**< Priority of the driver's task */
int xCoreID; /**< Core affinity of the driver's task */
cdc_acm_new_dev_callback_t new_dev_cb; /**< New USB device connected callback. Can be NULL. */
} cdc_acm_host_driver_config_t;
/**
* @brief Configuration structure of CDC-ACM device
*
*/
typedef struct {
uint32_t connection_timeout_ms; /**< Timeout for USB device connection in [ms] */
size_t out_buffer_size; /**< Maximum size of USB bulk out transfer, set to 0 for read-only devices */
cdc_acm_host_dev_callback_t event_cb; /**< Device's event callback function. Can be NULL */
cdc_acm_data_callback_t data_cb; /**< Device's data RX callback function. Can be NULL for write-only devices */
void *user_arg; /**< User's argument that will be passed to the callbacks */
} cdc_acm_host_device_config_t;
/**
* @brief Install CDC-ACM driver
*
* - USB Host Library must already be installed before calling this function (via usb_host_install())
* - This function should be called before calling any other CDC driver functions
*
* @param[in] driver_config Driver configuration structure. If set to NULL, a default configuration will be used.
* @return esp_err_t
*/
esp_err_t cdc_acm_host_install(const cdc_acm_host_driver_config_t *driver_config);
/**
* @brief Uninstall CDC-ACM driver
*
* - Users must ensure that all CDC devices must be closed via cdc_acm_host_close() before calling this function
*
* @return esp_err_t
*/
esp_err_t cdc_acm_host_uninstall(void);
/**
* @brief Open CDC-ACM compliant device
*
* CDC-ACM compliant device must contain either an Interface Association Descriptor or CDC-Union descriptor,
* which are used for the driver's configuration.
*
* @param[in] vid Device's Vendor ID
* @param[in] pid Device's Product ID
* @param[in] interface_idx Index of device's interface used for CDC-ACM communication
* @param[in] dev_config Configuration structure of the device
* @param[out] cdc_hdl_ret CDC device handle
* @return esp_err_t
*/
esp_err_t cdc_acm_host_open(uint16_t vid, uint16_t pid, uint8_t interface_idx, const cdc_acm_host_device_config_t *dev_config, cdc_acm_dev_hdl_t *cdc_hdl_ret);
/**
* @brief Open CDC-ACM non-compliant device
*
* CDC-ACM non-compliant device acts as CDC-ACM device but doesn't support all its features.
* User must provide the interface index that will be used (zero for non-composite devices).
*
* @param[in] vid Device's Vendor ID
* @param[in] pid Device's Product ID
* @param[in] interface_idx Index of device's interface used for CDC-ACM like communication
* @param[in] dev_config Configuration structure of the device
* @param[out] cdc_hdl_ret CDC device handle
* @return esp_err_t
*/
esp_err_t cdc_acm_host_open_vendor_specific(uint16_t vid, uint16_t pid, uint8_t interface_num, const cdc_acm_host_device_config_t *dev_config, cdc_acm_dev_hdl_t *cdc_hdl_ret);
/**
* @brief Close CDC device and release its resources
*
* @note All in-flight transfers will be prematurely canceled.
* @param cdc_hdl CDC handle obtained from cdc_acm_host_open()
* @return esp_err_t
*/
esp_err_t cdc_acm_host_close(cdc_acm_dev_hdl_t cdc_hdl);
/**
* @brief Transmit data - blocking mode
*
* @param cdc_hdl CDC handle obtained from cdc_acm_host_open()
* @param[in] data Data to be sent
* @param[in] data_len Data length
* @param[in] timeout_ms Timeout in [ms]
* @return esp_err_t
*/
esp_err_t cdc_acm_host_data_tx_blocking(cdc_acm_dev_hdl_t cdc_hdl, const uint8_t *data, size_t data_len, uint32_t timeout_ms);
/**
* @brief SetLineCoding function
*
* @see Chapter 6.3.10, USB CDC-PSTN specification rev. 1.2
*
* @param cdc_hdl CDC handle obtained from cdc_acm_host_open()
* @param[in] line_coding Line Coding structure
* @return esp_err_t
*/
esp_err_t cdc_acm_host_line_coding_set(cdc_acm_dev_hdl_t cdc_hdl, const cdc_acm_line_coding_t *line_coding);
/**
* @brief GetLineCoding function
*
* @see Chapter 6.3.11, USB CDC-PSTN specification rev. 1.2
*
* @param cdc_hdl CDC handle obtained from cdc_acm_host_open()
* @param[out] line_coding Line Coding structure to be filled
* @return esp_err_t
*/
esp_err_t cdc_acm_host_line_coding_get(cdc_acm_dev_hdl_t cdc_hdl, cdc_acm_line_coding_t *line_coding);
/**
* @brief SetControlLineState function
*
* @see Chapter 6.3.12, USB CDC-PSTN specification rev. 1.2
*
* @param cdc_hdl CDC handle obtained from cdc_acm_host_open()
* @param[in] dtr Indicates to DCE if DTE is present or not. This signal corresponds to V.24 signal 108/2 and RS-232 signal Data Terminal Ready.
* @param[in] rts Carrier control for half duplex modems. This signal corresponds to V.24 signal 105 and RS-232 signal Request To Send.
* @return esp_err_t
*/
esp_err_t cdc_acm_host_set_control_line_state(cdc_acm_dev_hdl_t cdc_hdl, bool dtr, bool rts);
/**
* @brief SendBreak function
*
* This function will block until the duration_ms has passed.
*
* @see Chapter 6.3.13, USB CDC-PSTN specification rev. 1.2
*
* @param cdc_hdl CDC handle obtained from cdc_acm_host_open()
* @param[in] duration_ms Duration of the Break signal in [ms]
* @return esp_err_t
*/
esp_err_t cdc_acm_host_send_break(cdc_acm_dev_hdl_t cdc_hdl, uint16_t duration_ms);
/**
* @brief Print device's descriptors
*
* Device and full Configuration descriptors are printed in human readable format to stdout.
*
* @param cdc_hdl CDC handle obtained from cdc_acm_host_open()
*/
void cdc_acm_host_desc_print(cdc_acm_dev_hdl_t cdc_hdl);
/**
* @brief Get protocols defined in USB-CDC interface descriptors
*
* @param cdc_hdl CDC handle obtained from cdc_acm_host_open()
* @param[out] comm Communication protocol
* @param[out] data Data protocol
* @return esp_err_t
*/
esp_err_t cdc_acm_host_protocols_get(cdc_acm_dev_hdl_t cdc_hdl, cdc_comm_protocol_t *comm, cdc_data_protocol_t *data);
/**
* @brief Send command to CTRL endpoint
*
* Sends Control transfer as described in USB specification chapter 9.
* This function can be used by device drivers that use custom/vendor specific commands.
* These commands can either extend or replace commands defined in USB CDC-PSTN specification rev. 1.2.
*
* @param cdc_hdl CDC handle obtained from cdc_acm_host_open()
* @param[in] bmRequestType Field of USB control request
* @param[in] bRequest Field of USB control request
* @param[in] wValue Field of USB control request
* @param[in] wIndex Field of USB control request
* @param[in] wLength Field of USB control request
* @param[inout] data Field of USB control request
* @return esp_err_t
*/
esp_err_t cdc_acm_host_send_custom_request(cdc_acm_dev_hdl_t cdc_hdl, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength, uint8_t *data);
#ifdef __cplusplus
}
class CdcAcmDevice {
public:
// Operators
CdcAcmDevice() : cdc_hdl(NULL) {};
virtual ~CdcAcmDevice()
{
// Close CDC-ACM device, if it wasn't explicitly closed
if (this->cdc_hdl != NULL) {
this->close();
}
}
inline esp_err_t tx_blocking(uint8_t *data, size_t len, uint32_t timeout_ms = 100)
{
return cdc_acm_host_data_tx_blocking(this->cdc_hdl, data, len, timeout_ms);
}
inline esp_err_t open(uint16_t vid, uint16_t pid, uint8_t interface_idx, const cdc_acm_host_device_config_t *dev_config)
{
return cdc_acm_host_open(vid, pid, interface_idx, dev_config, &this->cdc_hdl);
}
inline esp_err_t open_vendor_specific(uint16_t vid, uint16_t pid, uint8_t interface_idx, const cdc_acm_host_device_config_t *dev_config)
{
return cdc_acm_host_open_vendor_specific(vid, pid, interface_idx, dev_config, &this->cdc_hdl);
}
inline esp_err_t close()
{
const esp_err_t err = cdc_acm_host_close(this->cdc_hdl);
if (err == ESP_OK) {
this->cdc_hdl = NULL;
}
return err;
}
virtual inline esp_err_t line_coding_get(cdc_acm_line_coding_t *line_coding) const
{
return cdc_acm_host_line_coding_get(this->cdc_hdl, line_coding);
}
virtual inline esp_err_t line_coding_set(cdc_acm_line_coding_t *line_coding)
{
return cdc_acm_host_line_coding_set(this->cdc_hdl, line_coding);
}
virtual inline esp_err_t set_control_line_state(bool dtr, bool rts)
{
return cdc_acm_host_set_control_line_state(this->cdc_hdl, dtr, rts);
}
virtual inline esp_err_t send_break(uint16_t duration_ms)
{
return cdc_acm_host_send_break(this->cdc_hdl, duration_ms);
}
inline esp_err_t send_custom_request(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength, uint8_t *data)
{
return cdc_acm_host_send_custom_request(this->cdc_hdl, bmRequestType, bRequest, wValue, wIndex, wLength, data);
}
private:
CdcAcmDevice &operator= (const CdcAcmDevice &Copy);
bool operator== (const CdcAcmDevice &param) const;
bool operator!= (const CdcAcmDevice &param) const;
cdc_acm_dev_hdl_t cdc_hdl;
};
#endif