esp_rom: add USB related headers from the ROM code

This commit is contained in:
Ivan Grokhotkov 2020-04-30 15:18:49 +02:00
parent dafc6676ae
commit 4901917ea3
13 changed files with 1971 additions and 2 deletions

View file

@ -570,6 +570,11 @@ PROVIDE ( rom_txiq_set_reg = 0x4000bf64 );
PROVIDE ( rom_tx_paon_set = 0x40009db8 );
PROVIDE ( rom_tx_pwr_backoff = 0x4000ceb8 );
PROVIDE ( rom_txtone_linear_pwr = 0x4000c0b0 );
PROVIDE ( rom_usb_dev = 0x3ffffb9c ); /* static "usb_dev" */
PROVIDE ( rom_usb_dev_end = 0x3ffffc78 ); /* end of "usb_dev" */
PROVIDE ( rom_usb_dw_ctrl = 0x3ffffa74 ); /* static "usb_dw_ctrl" */
PROVIDE ( rom_usb_dw_ctrl_end = 0x3ffffb9c ); /* end of "usb_dw_ctrl" */
PROVIDE ( rom_usb_curr_desc = 0x3ffffa54 ); /* static "s_curr_descr" */
PROVIDE ( rom_wait_rfpll_cal_end = 0x4000af3c );
PROVIDE ( rom_wifi_11g_rate_chg = 0x4000d260 );
PROVIDE ( rom_wifi_rifs_mode_en = 0x40009d2c );
@ -646,7 +651,7 @@ PROVIDE ( string0_descr = 0x3ffaeeae );
PROVIDE ( str_manu_descr = 0x3ffaee9a );
PROVIDE ( str_prod_descr = 0x3ffaee88 );
PROVIDE ( str_serial_descr = 0x3ffaee84 );
PROVIDE ( s_usb_osglue = 0x3ffffcdc );
PROVIDE ( rom_usb_osglue = 0x3ffffcdc );
PROVIDE ( _SyscallException = 0x4000732a );
PROVIDE ( syscall_table_ptr_pro = 0x3ffffd78 );
PROVIDE ( tdefl_compress = 0x400041dc );

View file

@ -162,6 +162,14 @@ typedef struct {
int received;
} UartDevice;
typedef enum {
ROM_UART_0,
ROM_UART_1,
ROM_UART_USB
} rom_uart_num_t;
#define CDC_ACM_WORK_BUF_MIN 128
/**
* @brief Init uart device struct value and reset uart0/uart1 rx.
* Please do not call this function in SDK.
@ -428,7 +436,8 @@ uint8_t UartConnCheck(uint8_t uart_no);
/**
* @brief Initialize the USB ACM UART
* Needs to be fed a buffer of at least 128 bytes, plus any rx buffer you may want to have.
* Needs to be fed a buffer of at least 128 bytes (CDC_ACM_WORK_BUF_MIN),
* plus any rx buffer you may want to have.
*
* @param cdc_acm_work_mem Pointer to work mem for CDC-ACM code
* @param cdc_acm_work_mem_len Length of work mem

View file

@ -0,0 +1,262 @@
/*******************************************************************************
*
* Copyright(c) 2015,2016 Intel Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS 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.
*
******************************************************************************/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void cdc_acm_device;
extern cdc_acm_device *uart_acm_dev;
#define ACM_BYTES_PER_TX 64
//ACM statuses are negative to distinguish from USB_DC_* status codes
#define ACM_STATUS_LINESTATE_CHANGED -1
#define ACM_STATUS_LINECODING_CHANGED -2
#define ACM_STATUS_TX -3
#define ACM_STATUS_RX -4
typedef void(*uart_irq_callback_t)(cdc_acm_device *dev, int status);
/**
* @brief Get amount of received characters in buffer
*
* @returns character count
*/
int cdc_acm_rx_fifo_cnt(cdc_acm_device *dev);
/*
* @brief Poll the device for input.
*
* @return -ENOTSUP Since underlying USB device controller always uses
* interrupts, polled mode UART APIs are not implemented for the UART interface
* exported by CDC ACM driver. Apps should use fifo_read API instead.
*/
int cdc_acm_poll_in(cdc_acm_device *dev, unsigned char *c);
/*
* @brief Output a character in polled mode.
*
* The UART poll method for USB UART is simulated by waiting till
* we get the next BULK In upcall from the USB device controller or 100 ms.
*
* @return the same character which is sent
*/
unsigned char cdc_acm_poll_out(cdc_acm_device *dev, unsigned char c);
/**
* @brief Fill FIFO with data
*
* @param dev CDC ACM device struct.
* @param tx_data Data to transmit.
* @param len Number of bytes to send.
*
* @return Number of bytes sent.
*/
int cdc_acm_fifo_fill(cdc_acm_device *dev, const uint8_t *tx_data, int len);
/**
* @brief Read data from FIFO
*
* @param dev CDC ACM device struct.
* @param rx_data Pointer to data container.
* @param size Container size.
*
* @return Number of bytes read.
*/
int cdc_acm_fifo_read(cdc_acm_device *dev, uint8_t *rx_data, const int size);
/**
* @brief Enable TX interrupt
*
* @param dev CDC ACM device struct.
*
* @return N/A.
*/
void cdc_acm_irq_tx_enable(cdc_acm_device *dev);
/**
* @brief Disable TX interrupt
*
* @param dev CDC ACM device struct.
*
* @return N/A.
*/
void cdc_acm_irq_tx_disable(cdc_acm_device *dev);
/**
* @brief Check if Tx IRQ has been raised
*
* @param dev CDC ACM device struct.
*
* @return 1 if a Tx IRQ is pending, 0 otherwise.
*/
int cdc_acm_irq_tx_ready(cdc_acm_device *dev);
/**
* @brief Enable RX interrupt
*
* @param dev CDC ACM device struct.
*
* @return N/A
*/
void cdc_acm_irq_rx_enable(cdc_acm_device *dev);
/**
* @brief Disable RX interrupt
*
* @param dev CDC ACM device struct.
*
* @return N/A.
*/
void cdc_acm_irq_rx_disable(cdc_acm_device *dev);
/**
* @brief Enable line state interrupt
*
* @param dev CDC ACM device struct.
*
* @return N/A.
*/
void cdc_acm_irq_state_enable(cdc_acm_device *dev);
/**
* @brief Disable line state interrupt
*
* @param dev CDC ACM device struct.
*
* @return N/A.
*/
void cdc_acm_irq_state_disable(cdc_acm_device *dev);
/**
* @brief Check if Rx IRQ has been raised
*
* @param dev CDC ACM device struct.
*
* @return 1 if an IRQ is ready, 0 otherwise.
*/
int cdc_acm_irq_rx_ready(cdc_acm_device *dev);
/**
* @brief Check if Tx or Rx IRQ is pending
*
* @param dev CDC ACM device struct.
*
* @return 1 if a Tx or Rx IRQ is pending, 0 otherwise.
*/
int cdc_acm_irq_is_pending(cdc_acm_device *dev);
/**
* @brief Set the callback function pointer for IRQ.
*
* @param dev CDC ACM device struct.
* @param cb Callback function pointer.
*
* @return N/A
*/
void cdc_acm_irq_callback_set(cdc_acm_device *dev, uart_irq_callback_t cb);
/**
* @brief Manipulate line control for UART.
*
* @param dev CDC ACM device struct
* @param ctrl The line control to be manipulated
* @param val Value to set the line control
*
* @return 0 if successful, failed otherwise.
*/
int cdc_acm_line_ctrl_set(cdc_acm_device *dev, uint32_t ctrl, uint32_t val);
/**
* @brief Manipulate line control for UART.
*
* @param dev CDC ACM device struct
* @param ctrl The line control to be manipulated
* @param val Value to set the line control
*
* @return 0 if successful, failed otherwise.
*/
int cdc_acm_line_ctrl_get(cdc_acm_device *dev, uint32_t ctrl, uint32_t *val);
/**
* @brief Initialize UART channel
*
* This routine is called to reset the chip in a quiescent state.
* It is assumed that this function is called only once per UART.
*
* @param mem_chunk Memory chunk to use for internal use
* @param mem_chunk_size Size of the memory chunk in bytes
*
* @return dev or NULL
*/
cdc_acm_device *cdc_acm_init(void *mem_chunk, int mem_chunk_size);
/** Common line controls for UART.*/
#define LINE_CTRL_BAUD_RATE (1 << 0)
#define LINE_CTRL_RTS (1 << 1)
#define LINE_CTRL_DTR (1 << 2)
#define LINE_CTRL_DCD (1 << 3)
#define LINE_CTRL_DSR (1 << 4)
/* Common communication errors for UART.*/
/** @brief Overrun error */
#define UART_ERROR_OVERRUN (1 << 0)
/** @brief Parity error */
#define UART_ERROR_PARITY (1 << 1)
/** @brief Framing error */
#define UART_ERROR_FRAMING (1 << 2)
/**
* @brief Break interrupt error:
*
* A break interrupt was received. This happens when the serial input is
* held at a logic '0' state for longer than the sum of start time + data bits
* + parity + stop bits.
*/
#define UART_ERROR_BREAK (1 << 3)
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,30 @@
// Copyright 2019-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
int chip_usb_dw_init(void);
int chip_usb_dw_did_persist(void);
void chip_usb_dw_prepare_persist(void);
uint32_t chip_usb_get_persist_flags(void);
void chip_usb_set_persist_flags(uint32_t flags);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,180 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* Archive to parse cpio data in the newc and crc formats. Generate a cpio archive like that by e.g.
* find . | cpio -o -H newc > archive.cpio
*/
#pragma once
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#define CPIO_MODE_FILETYPE_MASK 0xF000
#define CPIO_MODE_FILETYPE_SOCKET 0xC000
#define CPIO_MODE_FILETYPE_SYMLINK 0xA000
#define CPIO_MODE_FILETYPE_REGULAR 0x8000
#define CPIO_MODE_FILETYPE_BLOCKDEV 0x6000
#define CPIO_MODE_FILETYPE_DIR 0x4000
#define CPIO_MODE_FILETYPE_CHARDEV 0x2000
#define CPIO_MODE_FILETYPE_FIFO 0x1000
#define CPIO_MODE_SUID 0x0800
#define CPIO_MODE_SGID 0x0400
#define CPIO_MODE_STICKY 0x0200
typedef struct {
size_t filesize;
char *name;
uint32_t mode;
uint32_t check;
} cpio_file_t;
typedef enum {
CPIO_RET_MORE = 0,
CPIO_RET_DONE,
CPIO_RET_ERR
} cpio_ret_t;
typedef struct cpio_handle_data_t cpio_handle_data_t;
typedef cpio_handle_data_t *cpio_handle_t;
typedef enum {
CPIO_RSN_FILE_ALL = 0,
CPIO_RSN_FILE_INITIAL,
CPIO_RSN_FILE_MORE,
CPIO_RSN_FILE_END
} cpio_callback_reason_t;
/**
* Callback for cpio file data.
*
* This callback will be called by the library to indicate data for a file is available.
*
* For files in the cpio archive that fit entirely in the internal buffer, or when no internal
* buffer is available, are entirely contained in the buffer fed to cpio_feed(), this callback
* is only called once, with reason=CPIO_RNS_FILE_ALL. fileinfo will contain the information
* for that specific file (name, size, ...), buff_offset will be 0, buff_len is the file
* size and buff contains all the information for the file.
*
* For files that do not fit in the buffer, this callback will be called multiple times.
* The initial time with reason=CPIO_RSN_FILE_INITIAL, when more data is available with
* CPIO_RSN_FILE_MORE and finally with CPIO_RSN_FILE_END. For these calls, fileinfo
* will again contain file information. buff will be the information contained in the
* file at offset buff_offset, and the lenght of this buffer will be in buff_len.
*
* The library guarantees to feed all file data to the callback consequitively, so
* within the same file, the buff_offset from a call will always be (buff_offset+buff_len)
* from the call before that. If cpio_start is
*
* The library also guarantees every file in the cpio archive will either generate a single
* callback call with CPIO_RSN_ALL, or multiple with in sequence CPIO_RSN_FILE_INITIAL, 0 or
* more CPIO_RSN_FILE_MORE and finally a CPIO_RSN_FILE_END.
*
* When a non-zero buffer size is passed to cpio_start, the library guarantees that all callback
* calls with a reason of CPIO_RSN_FILE_INITIAL and CPIO_RSN_FILE_MORE will have a buffer
* filled with exactly this amount of bytes.
*
*/
typedef void (*cpio_callback_t)(cpio_callback_reason_t reason, cpio_file_t *fileinfo, size_t buff_offset, size_t buff_len, char *buff, void *arg);
/**
* @brief Initialize a cpio handle.
*
* Call this to start parsing a cpio archive. You can set the callback that handles the
* files/data here.
*
* @param callback The callback that will handle the data of the files inside the cpio archive
*
* @param cbarg User-supplied argument. The callback will be called with this as an argument.
*
* @param buflen Length of internal buffer used.
* If this is zero, the callback will be called with data that lives in the data buffer
* supplied to the cpio library by whomever called cpio_feed(). Because this library has
* no power over that buffer, the callback can be passed as little as 1 and as many as
* INT_MAX bytes at a time.
* If this is non-zero, the library will allocate an internal buffer of this size. All
* cpio_feed()-calls will be rebuffered, and the callback is guaranteed to only be called
* with this many bytes in the buffer, given there's enough data in the file to fill it.
*
* @param memchunk Chunk of memory to allocate everything (handle, I/O buffer, filename buffer) in. Minimum size
* (estimate) is 160+buflen+sizeof(largest filename/path).
* @param memchunklen Size of the mem chunk
*
* @return
* - Success: A pointer to a cpio handle
* - Error: NULL
*
*/
cpio_handle_t cpio_start(cpio_callback_t callback, void *cbarg, size_t buflen, void *memchunk, int memchunklen);
/**
* @brief Feed data from a cpio archive into the library
*
* This routine is used to feed consecutive data of the cpio archive into the library. While processing,
* the library can call the callback function one or more times if needed.
*
* @param cpio Handle obtained by calling cpio_start()
*
* @param buffer Pointer to buffer containing cpio archive data
*
* @param len Length of the buffer, in bytes
*
* @return
* - CPIO_RET_MORE: CPIO archive isn't done yet, please feed more data.
* - CPIO_RET_DONE: CPUI archive is finished.
* - CPIO_RET_ERR: Invalid CPIO archive data; decoding aborted.
*
*/
cpio_ret_t cpio_feed(cpio_handle_t cpio, char *buffer, int len);
/**
* @brief Indicate there is no more cpio data to be fed into the archive
*
* This call is to be called when the source data is exhausted. Normally, the library can find the end of the
* cpio archive by looking for the end marker,
*
* @param timer_conf Pointer of LEDC timer configure struct
*
*
* @return
* - CPIO_RET_DONE on success
* - CPIO_RET_ERR when cpio archive is invalid
*
*/
cpio_ret_t cpio_done(cpio_handle_t cpio);
/**
* @brief Free the memory allocated for a cpio handle.
*
* @param cpio Handle obtained by calling cpio_start()
*
* @return
* - CPIO_RET_DONE on success
*
*/
cpio_ret_t cpio_destroy(cpio_handle_t cpio);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,174 @@
/* usb_cdc.h - USB CDC-ACM and CDC-ECM public header */
/*
* Copyright (c) 2017 PHYTEC Messtechnik GmbH
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief USB Communications Device Class (CDC) public header
*
* Header follows the Class Definitions for
* Communications Devices Specification (CDC120-20101103-track.pdf),
* PSTN Devices Specification (PSTN120.pdf) and
* Ethernet Control Model Devices Specification (ECM120.pdf).
* Header is limited to ACM and ECM Subclasses.
*/
#pragma once
#include <stdint.h>
#include <sys/cdefs.h>
#ifdef __cplusplus
extern "C" {
#endif
/** CDC Specification release number in BCD format */
#define CDC_SRN_1_20 0x0120
/** Communications Class Subclass Codes */
#define ACM_SUBCLASS 0x02
#define ECM_SUBCLASS 0x06
#define EEM_SUBCLASS 0x0c
/** Communications Class Protocol Codes */
#define AT_CMD_V250_PROTOCOL 0x01
#define EEM_PROTOCOL 0x07
/**
* @brief Data Class Interface Codes
* @note CDC120-20101103-track.pdf, 4.5, Table 6
*/
#define DATA_INTERFACE_CLASS 0x0A
/**
* @brief Values for the bDescriptorType Field
* @note CDC120-20101103-track.pdf, 5.2.3, Table 12
*/
#define CS_INTERFACE 0x24
#define CS_ENDPOINT 0x25
/**
* @brief bDescriptor SubType for Communications
* Class Functional Descriptors
* @note CDC120-20101103-track.pdf, 5.2.3, Table 13
*/
#define HEADER_FUNC_DESC 0x00
#define CALL_MANAGEMENT_FUNC_DESC 0x01
#define ACM_FUNC_DESC 0x02
#define UNION_FUNC_DESC 0x06
#define ETHERNET_FUNC_DESC 0x0F
/**
* @brief PSTN Subclass Specific Requests
* for ACM devices
* @note PSTN120.pdf, 6.3, Table 13
*/
#define CDC_SEND_ENC_CMD 0x00
#define CDC_GET_ENC_RSP 0x01
#define SET_LINE_CODING 0x20
#define GET_LINE_CODING 0x21
#define SET_CONTROL_LINE_STATE 0x22
/** Control Signal Bitmap Values for SetControlLineState */
#define SET_CONTROL_LINE_STATE_RTS 0x02
#define SET_CONTROL_LINE_STATE_DTR 0x01
/** UART State Bitmap Values */
#define SERIAL_STATE_OVERRUN 0x40
#define SERIAL_STATE_PARITY 0x20
#define SERIAL_STATE_FRAMING 0x10
#define SERIAL_STATE_RING 0x08
#define SERIAL_STATE_BREAK 0x04
#define SERIAL_STATE_TX_CARRIER 0x02
#define SERIAL_STATE_RX_CARRIER 0x01
/**
* @brief Class-Specific Request Codes for Ethernet subclass
* @note ECM120.pdf, 6.2, Table 6
*/
#define SET_ETHERNET_MULTICAST_FILTERS 0x40
#define SET_ETHERNET_PM_FILTER 0x41
#define GET_ETHERNET_PM_FILTER 0x42
#define SET_ETHERNET_PACKET_FILTER 0x43
#define GET_ETHERNET_STATISTIC 0x44
/** Ethernet Packet Filter Bitmap */
#define PACKET_TYPE_MULTICAST 0x10
#define PACKET_TYPE_BROADCAST 0x08
#define PACKET_TYPE_DIRECTED 0x04
#define PACKET_TYPE_ALL_MULTICAST 0x02
#define PACKET_TYPE_PROMISCUOUS 0x01
/** Header Functional Descriptor */
struct cdc_header_descriptor {
uint8_t bFunctionLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint16_t bcdCDC;
} __packed;
/** Union Interface Functional Descriptor */
struct cdc_union_descriptor {
uint8_t bFunctionLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bControlInterface;
uint8_t bSubordinateInterface0;
} __packed;
/** Call Management Functional Descriptor */
struct cdc_cm_descriptor {
uint8_t bFunctionLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bmCapabilities;
uint8_t bDataInterface;
} __packed;
/** Abstract Control Management Functional Descriptor */
struct cdc_acm_descriptor {
uint8_t bFunctionLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bmCapabilities;
} __packed;
/** Data structure for GET_LINE_CODING / SET_LINE_CODING class requests */
struct cdc_acm_line_coding {
uint32_t dwDTERate;
uint8_t bCharFormat;
uint8_t bParityType;
uint8_t bDataBits;
} __packed;
/** Data structure for the notification about SerialState */
struct cdc_acm_notification {
uint8_t bmRequestType;
uint8_t bNotificationType;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
uint16_t data;
} __packed;
/** Ethernet Networking Functional Descriptor */
struct cdc_ecm_descriptor {
uint8_t bFunctionLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t iMACAddress;
uint32_t bmEthernetStatistics;
uint16_t wMaxSegmentSize;
uint16_t wNumberMCFilters;
uint8_t bNumberPowerFilters;
} __packed;
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,244 @@
/***************************************************************************
*
*
* Copyright(c) 2015,2016 Intel Corporation.
* Copyright(c) 2017 PHYTEC Messtechnik GmbH
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS 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.
*
***************************************************************************/
/**
* @file
* @brief useful constants and macros for the USB application
*
* This file contains useful constants and macros for the USB applications.
*/
#pragma once
#include <stdint.h>
#include <sys/cdefs.h>
#ifdef __cplusplus
extern "C" {
#endif
#define BCD(x) ((((x) / 10) << 4) | ((x) / 10))
/* Descriptor size in bytes */
#define USB_DEVICE_DESC_SIZE 18
#define USB_CONFIGURATION_DESC_SIZE 9
#define USB_INTERFACE_DESC_SIZE 9
#define USB_ENDPOINT_DESC_SIZE 7
#define USB_STRING_DESC_SIZE 4
#define USB_HID_DESC_SIZE 9
#define USB_DFU_DESC_SIZE 9
#define USB_DEVICE_QUAL_DESC_SIZE 10
#define USB_INTERFACE_ASSOC_DESC_SIZE 8
/* Descriptor type */
#define USB_DEVICE_DESC 0x01
#define USB_CONFIGURATION_DESC 0x02
#define USB_STRING_DESC 0x03
#define USB_INTERFACE_DESC 0x04
#define USB_ENDPOINT_DESC 0x05
#define USB_DEVICE_QUAL_DESC 0x06
#define USB_INTERFACE_ASSOC_DESC 0x0B
#define USB_DEVICE_CAPABILITY_DESC 0x10
#define USB_HID_DESC 0x21
#define USB_HID_REPORT_DESC 0x22
#define USB_DFU_FUNCTIONAL_DESC 0x21
#define USB_ASSOCIATION_DESC 0x0B
#define USB_BINARY_OBJECT_STORE_DESC 0x0F
/* Useful define */
#define USB_1_1 0x0110
#define USB_2_0 0x0200
/* Set USB version to 2.1 so that the host will request the BOS descriptor */
#define USB_2_1 0x0210
#define BCDDEVICE_RELNUM (BCD(KERNEL_VERSION_MAJOR) << 8 | \
BCD(KERNEL_VERSION_MINOR))
/* 100mA max power, per 2mA units */
/* USB 1.1 spec indicates 100mA(max) per unit load, up to 5 loads */
#define MAX_LOW_POWER 0x32
#define MAX_HIGH_POWER 0xFA
/* bmAttributes:
* D7:Reserved, always 1,
* D6:Self-Powered -> 1,
* D5:Remote Wakeup -> 0,
* D4...0:Reserved -> 0
*/
#define USB_CONFIGURATION_ATTRIBUTES 0xC0
/* Classes */
#define COMMUNICATION_DEVICE_CLASS 0x02
#define COMMUNICATION_DEVICE_CLASS_DATA 0x0A
#define HID_CLASS 0x03
#define MASS_STORAGE_CLASS 0x08
#define WIRELESS_DEVICE_CLASS 0xE0
#define MISC_CLASS 0xEF
#define CUSTOM_CLASS 0xFF
#define DFU_DEVICE_CLASS 0xFE
/* Sub-classes */
#define CDC_NCM_SUBCLASS 0x0d
#define BOOT_INTERFACE_SUBCLASS 0x01
#define SCSI_TRANSPARENT_SUBCLASS 0x06
#define DFU_INTERFACE_SUBCLASS 0x01
#define RF_SUBCLASS 0x01
#define CUSTOM_SUBCLASS 0xFF
#define COMMON_SUBCLASS 0x02
/* Misc subclasses */
#define MISC_RNDIS_SUBCLASS 0x04
#define CDC_ABSTRACT_CONTROL_MODEL 0x02
/* Protocols */
#define V25TER_PROTOCOL 0x01
#define MOUSE_PROTOCOL 0x02
#define BULK_ONLY_PROTOCOL 0x50
#define DFU_RUNTIME_PROTOCOL 0x01
#define DFU_MODE_PROTOCOL 0x02
#define BLUETOOTH_PROTOCOL 0x01
/* CDC ACM protocols */
#define ACM_VENDOR_PROTOCOL 0xFF
/* Misc protocols */
#define MISC_ETHERNET_PROTOCOL 0x01
#define IAD_PROTOCOL 0x01
/** Standard Device Descriptor */
struct usb_device_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
} __packed;
/** Unicode (UTF16LE) String Descriptor */
struct usb_string_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bString;
} __packed;
/** Association Descriptor */
struct usb_association_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bFirstInterface;
uint8_t bInterfaceCount;
uint8_t bFunctionClass;
uint8_t bFunctionSubClass;
uint8_t bFunctionProtocol;
uint8_t iFunction;
} __packed;
/** Standard Configuration Descriptor */
struct usb_cfg_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
} __packed;
/** Standard Interface Descriptor */
struct usb_if_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
} __packed;
/** Standard Endpoint Descriptor */
struct usb_ep_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} __packed;
struct string_descriptor_zero {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wBcdLang[];
} __packed;
struct string_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bString[];
} __packed;
#define ROM_MAX_CFG_DESC_CNT 1
struct rom_usb_descriptors {
const struct usb_device_descriptor *device_descr;
const void *config_descr[ROM_MAX_CFG_DESC_CNT];
int string_count; // including string_descriptor_zero
const struct string_descriptor_zero *string0_descr;
const struct string_descriptor *string_descrs[];
};
/* Descriptors defined in the ROM */
extern struct usb_device_descriptor general_device_descr;
extern const void* acm_config_descr;
extern const void* dfu_config_descr;
extern const struct string_descriptor str_manu_descr;
extern const struct string_descriptor str_prod_descr;
extern const struct string_descriptor_zero string0_descr;
extern const struct rom_usb_descriptors acm_usb_descriptors;
extern const struct rom_usb_descriptors dfu_usb_descriptors;
extern const struct rom_usb_descriptors *rom_usb_curr_desc;
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,392 @@
/* usb_dc.h - USB device controller driver interface */
/*
* Copyright (c) 2016 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief USB device controller APIs
*
* This file contains the USB device controller APIs. All device controller
* drivers should implement the APIs described in this file.
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* USB endpoint direction and number.
*/
#define USB_EP_DIR_MASK 0x80
#define USB_EP_DIR_IN 0x80
#define USB_EP_DIR_OUT 0x00
/**
* USB Driver Status Codes
*/
enum usb_dc_status_code {
USB_DC_ERROR, /* USB error reported by the controller */
USB_DC_RESET, /* USB reset */
/* USB connection established, hardware enumeration is completed */
USB_DC_CONNECTED,
USB_DC_CONFIGURED, /* USB configuration done */
USB_DC_DISCONNECTED, /* USB connection lost */
USB_DC_SUSPEND, /* USB connection suspended by the HOST */
USB_DC_RESUME, /* USB connection resumed by the HOST */
USB_DC_INTERFACE, /* USB interface selected */
USB_DC_SET_HALT, /* Set Feature ENDPOINT_HALT received */
USB_DC_CLEAR_HALT, /* Clear Feature ENDPOINT_HALT received */
USB_DC_UNKNOWN /* Initial USB connection status */
};
/**
* USB Endpoint Callback Status Codes
*/
enum usb_dc_ep_cb_status_code {
USB_DC_EP_SETUP, /* SETUP received */
/* Out transaction on this EP, data is available for read */
USB_DC_EP_DATA_OUT,
USB_DC_EP_DATA_IN, /* In transaction done on this EP */
};
/**
* USB Endpoint type
*/
enum usb_dc_ep_type {
USB_DC_EP_CONTROL = 0, /* Control type endpoint */
USB_DC_EP_ISOCHRONOUS, /* Isochronous type endpoint */
USB_DC_EP_BULK, /* Bulk type endpoint */
USB_DC_EP_INTERRUPT /* Interrupt type endpoint */
};
/**
* USB Endpoint Configuration.
*/
struct usb_dc_ep_cfg_data {
/** The number associated with the EP in the device
* configuration structure
* IN EP = 0x80 | \<endpoint number\>
* OUT EP = 0x00 | \<endpoint number\>
*/
uint8_t ep_addr;
uint16_t ep_mps; /** Endpoint max packet size */
enum usb_dc_ep_type ep_type; /** Endpoint type */
};
/**
* Callback function signature for the USB Endpoint status
*/
typedef void (*usb_dc_ep_callback)(uint8_t ep,
enum usb_dc_ep_cb_status_code cb_status);
/**
* Callback function signature for the device
*/
typedef void (*usb_dc_status_callback)(enum usb_dc_status_code cb_status,
uint8_t *param);
/**
* @brief attach USB for device connection
*
* Function to attach USB for device connection. Upon success, the USB PLL
* is enabled, and the USB device is now capable of transmitting and receiving
* on the USB bus and of generating interrupts.
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_attach(void);
/**
* @brief detach the USB device
*
* Function to detach the USB device. Upon success, the USB hardware PLL
* is powered down and USB communication is disabled.
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_detach(void);
/**
* @brief reset the USB device
*
* This function returns the USB device and firmware back to it's initial state.
* N.B. the USB PLL is handled by the usb_detach function
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_reset(void);
/**
* @brief set USB device address
*
* @param[in] addr device address
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_set_address(const uint8_t addr);
/**
* @brief set USB device controller status callback
*
* Function to set USB device controller status callback. The registered
* callback is used to report changes in the status of the device controller.
*
* @param[in] cb callback function
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_set_status_callback(const usb_dc_status_callback cb);
/**
* @brief check endpoint capabilities
*
* Function to check capabilities of an endpoint. usb_dc_ep_cfg_data structure
* provides the endpoint configuration parameters: endpoint address,
* endpoint maximum packet size and endpoint type.
* The driver should check endpoint capabilities and return 0 if the
* endpoint configuration is possible.
*
* @param[in] cfg Endpoint config
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data *const cfg);
/**
* @brief configure endpoint
*
* Function to configure an endpoint. usb_dc_ep_cfg_data structure provides
* the endpoint configuration parameters: endpoint address, endpoint maximum
* packet size and endpoint type.
*
* @param[in] cfg Endpoint config
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data *const cfg);
/**
* @brief set stall condition for the selected endpoint
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_ep_set_stall(const uint8_t ep);
/**
* @brief clear stall condition for the selected endpoint
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_ep_clear_stall(const uint8_t ep);
/**
* @brief check if selected endpoint is stalled
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
* @param[out] stalled Endpoint stall status
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_ep_is_stalled(const uint8_t ep, uint8_t *const stalled);
/**
* @brief halt the selected endpoint
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_ep_halt(const uint8_t ep);
/**
* @brief enable the selected endpoint
*
* Function to enable the selected endpoint. Upon success interrupts are
* enabled for the corresponding endpoint and the endpoint is ready for
* transmitting/receiving data.
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_ep_enable(const uint8_t ep);
/**
* @brief disable the selected endpoint
*
* Function to disable the selected endpoint. Upon success interrupts are
* disabled for the corresponding endpoint and the endpoint is no longer able
* for transmitting/receiving data.
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_ep_disable(const uint8_t ep);
/**
* @brief flush the selected endpoint
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_ep_flush(const uint8_t ep);
/**
* @brief write data to the specified endpoint
*
* This function is called to write data to the specified endpoint. The supplied
* usb_ep_callback function will be called when data is transmitted out.
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
* @param[in] data pointer to data to write
* @param[in] data_len length of data requested to write. This may
* be zero for a zero length status packet.
* @param[out] ret_bytes bytes scheduled for transmission. This value
* may be NULL if the application expects all
* bytes to be written
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_ep_write(const uint8_t ep, const uint8_t *const data,
const uint32_t data_len, uint32_t *const ret_bytes);
/**
* @brief Indicate if the write to an IN endpoint (using usb_dc_ep_write) would block
* to wait until the endpoint has enoug space
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
*
* @return 0 when writable, 0 when not, negative errno code on fail.
*/
int usb_dc_ep_write_would_block(const uint8_t ep);
/**
* @brief read data from the specified endpoint
*
* This function is called by the Endpoint handler function, after an OUT
* interrupt has been received for that EP. The application must only call this
* function through the supplied usb_ep_callback function. This function clears
* the ENDPOINT NAK, if all data in the endpoint FIFO has been read,
* so as to accept more data from host.
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
* @param[in] data pointer to data buffer to write to
* @param[in] max_data_len max length of data to read
* @param[out] read_bytes Number of bytes read. If data is NULL and
* max_data_len is 0 the number of bytes
* available for read should be returned.
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_ep_read(const uint8_t ep, uint8_t *const data,
const uint32_t max_data_len, uint32_t *const read_bytes);
/**
* @brief set callback function for the specified endpoint
*
* Function to set callback function for notification of data received and
* available to application or transmit done on the selected endpoint,
* NULL if callback not required by application code.
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
* @param[in] cb callback function
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_ep_set_callback(const uint8_t ep, const usb_dc_ep_callback cb);
/**
* @brief read data from the specified endpoint
*
* This is similar to usb_dc_ep_read, the difference being that, it doesn't
* clear the endpoint NAKs so that the consumer is not bogged down by further
* upcalls till he is done with the processing of the data. The caller should
* reactivate ep by invoking usb_dc_ep_read_continue() do so.
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
* @param[in] data pointer to data buffer to write to
* @param[in] max_data_len max length of data to read
* @param[out] read_bytes Number of bytes read. If data is NULL and
* max_data_len is 0 the number of bytes
* available for read should be returned.
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_ep_read_wait(uint8_t ep, uint8_t *data, uint32_t max_data_len,
uint32_t *read_bytes);
/**
* @brief Continue reading data from the endpoint
*
* Clear the endpoint NAK and enable the endpoint to accept more data
* from the host. Usually called after usb_dc_ep_read_wait() when the consumer
* is fine to accept more data. Thus these calls together acts as flow control
* mechanism.
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
*
* @return 0 on success, negative errno code on fail.
*/
int usb_dc_ep_read_continue(uint8_t ep);
/**
* @brief Get endpoint max packet size
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
*
* @return enpoint max packet size (mps)
*/
int usb_dc_ep_mps(uint8_t ep);
//Hack - fake interrupts by pollinfg
void usb_dc_check_poll_for_interrupts(void);
//Prepare for USB persist. You should reboot after this.
int usb_dc_prepare_persist(void);
void usb_dw_isr_handler(void);
int usb_dc_ep_write_would_block(const uint8_t ep);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,34 @@
// Copyright 2019-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#define USB_DESCRIPTOR_TYPE_ACM 0
#define USB_DESCRIPTOR_TYPE_DFU 1
void usb_set_current_descriptor(int descriptor_type);
bool usb_get_descriptor(uint16_t type_index, uint16_t lang_id,
int32_t *len, uint8_t **data);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,402 @@
/*
* LPCUSB, an USB device driver for LPC microcontrollers
* Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
* Copyright (c) 2016 Intel Corporation
*
* 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 the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR 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.
*/
/**
* @file
* @brief USB device core layer APIs and structures
*
* This file contains the USB device core layer APIs and structures.
*/
#pragma once
#include <stddef.h>
#include <sys/cdefs.h>
#include "usb_dc.h"
#ifdef __cplusplus
extern "C" {
#endif
/*************************************************************************
* USB configuration
**************************************************************************/
#define MAX_PACKET_SIZE0 64 /**< maximum packet size for EP 0 */
//Note: for FS this should be 8, 16, 32, 64 bytes. HS can go up to 512.
/*************************************************************************
* USB application interface
**************************************************************************/
/** setup packet definitions */
struct usb_setup_packet {
uint8_t bmRequestType; /**< characteristics of the specific request */
uint8_t bRequest; /**< specific request */
uint16_t wValue; /**< request specific parameter */
uint16_t wIndex; /**< request specific parameter */
uint16_t wLength; /**< length of data transferred in data phase */
} __packed;
_Static_assert(sizeof(struct usb_setup_packet) == 8, "USB setup packet struct size error");
/**
* Callback function signature for the device
*/
typedef void (*usb_status_callback)(enum usb_dc_status_code status_code,
uint8_t *param);
/**
* Callback function signature for the USB Endpoint status
*/
typedef void (*usb_ep_callback)(uint8_t ep,
enum usb_dc_ep_cb_status_code cb_status);
/**
* Function which handles Class specific requests corresponding to an
* interface number specified in the device descriptor table
*/
typedef int (*usb_request_handler) (struct usb_setup_packet *detup,
int32_t *transfer_len, uint8_t **payload_data);
/**
* Function for interface runtime configuration
*/
typedef void (*usb_interface_config)(uint8_t bInterfaceNumber);
/*
* USB Endpoint Configuration
*/
struct usb_ep_cfg_data {
/**
* Callback function for notification of data received and
* available to application or transmit done, NULL if callback
* not required by application code
*/
usb_ep_callback ep_cb;
/**
* The number associated with the EP in the device configuration
* structure
* IN EP = 0x80 | \<endpoint number\>
* OUT EP = 0x00 | \<endpoint number\>
*/
uint8_t ep_addr;
};
/**
* USB Interface Configuration
*/
struct usb_interface_cfg_data {
/** Handler for USB Class specific Control (EP 0) communications */
usb_request_handler class_handler;
/** Handler for USB Vendor specific commands */
usb_request_handler vendor_handler;
/**
* The custom request handler gets a first chance at handling
* the request before it is handed over to the 'chapter 9' request
* handler
*/
usb_request_handler custom_handler;
/**
* This data area, allocated by the application, is used to store
* Class specific command data and must be large enough to store the
* largest payload associated with the largest supported Class'
* command set. This data area may be used for USB IN or OUT
* communications
*/
uint8_t *payload_data;
/**
* This data area, allocated by the application, is used to store
* Vendor specific payload
*/
uint8_t *vendor_data;
};
/*
* @brief USB device configuration
*
* The Application instantiates this with given parameters added
* using the "usb_set_config" function. Once this function is called
* changes to this structure will result in undefined behaviour. This structure
* may only be updated after calls to usb_deconfig
*/
struct usb_cfg_data {
/**
* USB device description, see
* http://www.beyondlogic.org/usbnutshell/usb5.shtml#DeviceDescriptors
*/
const uint8_t *usb_device_description;
/** Pointer to interface descriptor */
const void *interface_descriptor;
/** Function for interface runtime configuration */
usb_interface_config interface_config;
/** Callback to be notified on USB connection status change */
usb_status_callback cb_usb_status;
/** USB interface (Class) handler and storage space */
struct usb_interface_cfg_data interface;
/** Number of individual endpoints in the device configuration */
uint8_t num_endpoints;
/**
* Pointer to an array of endpoint structs of length equal to the
* number of EP associated with the device description,
* not including control endpoints
*/
struct usb_ep_cfg_data *endpoint;
};
/*
* @brief configure USB controller
*
* Function to configure USB controller.
* Configuration parameters must be valid or an error is returned
*
* @param[in] config Pointer to configuration structure
*
* @return 0 on success, negative errno code on fail
*/
int usb_set_config(struct usb_cfg_data *config);
/*
* @brief return the USB device to it's initial state
*
* @return 0 on success, negative errno code on fail
*/
int usb_deconfig(void);
/*
* @brief enable USB for host/device connection
*
* Function to enable USB for host/device connection.
* Upon success, the USB module is no longer clock gated in hardware,
* it is now capable of transmitting and receiving on the USB bus and
* of generating interrupts.
*
* @return 0 on success, negative errno code on fail.
*/
int usb_enable(struct usb_cfg_data *config);
/*
* @brief disable the USB device.
*
* Function to disable the USB device.
* Upon success, the specified USB interface is clock gated in hardware,
* it is no longer capable of generating interrupts.
*
* @return 0 on success, negative errno code on fail
*/
int usb_disable(void);
/*
* @brief Check if a write to an in ep would block until there is enough space
* in the fifo
*
* @param[in] ep Endpoint address corresponding to the one listed in the
* device configuration table
*
* @return 0 if free to write, 1 if a write would block, negative errno code on fail
*/
int usb_write_would_block(uint8_t ep);
/*
* @brief write data to the specified endpoint
*
* Function to write data to the specified endpoint. The supplied
* usb_ep_callback will be called when transmission is done.
*
* @param[in] ep Endpoint address corresponding to the one listed in the
* device configuration table
* @param[in] data Pointer to data to write
* @param[in] data_len Length of data requested to write. This may be zero for
* a zero length status packet.
* @param[out] bytes_ret Bytes written to the EP FIFO. This value may be NULL if
* the application expects all bytes to be written
*
* @return 0 on success, negative errno code on fail
*/
int usb_write(uint8_t ep, const uint8_t *data, uint32_t data_len,
uint32_t *bytes_ret);
/*
* @brief read data from the specified endpoint
*
* This function is called by the Endpoint handler function, after an
* OUT interrupt has been received for that EP. The application must
* only call this function through the supplied usb_ep_callback function.
*
* @param[in] ep Endpoint address corresponding to the one listed in
* the device configuration table
* @param[in] data Pointer to data buffer to write to
* @param[in] max_data_len Max length of data to read
* @param[out] ret_bytes Number of bytes read. If data is NULL and
* max_data_len is 0 the number of bytes available
* for read is returned.
*
* @return 0 on success, negative errno code on fail
*/
int usb_read(uint8_t ep, uint8_t *data, uint32_t max_data_len,
uint32_t *ret_bytes);
/*
* @brief set STALL condition on the specified endpoint
*
* This function is called by USB device class handler code to set stall
* conditionin on endpoint.
*
* @param[in] ep Endpoint address corresponding to the one listed in
* the device configuration table
*
* @return 0 on success, negative errno code on fail
*/
int usb_ep_set_stall(uint8_t ep);
/*
* @brief clears STALL condition on the specified endpoint
*
* This function is called by USB device class handler code to clear stall
* conditionin on endpoint.
*
* @param[in] ep Endpoint address corresponding to the one listed in
* the device configuration table
*
* @return 0 on success, negative errno code on fail
*/
int usb_ep_clear_stall(uint8_t ep);
/**
* @brief read data from the specified endpoint
*
* This is similar to usb_ep_read, the difference being that, it doesn't
* clear the endpoint NAKs so that the consumer is not bogged down by further
* upcalls till he is done with the processing of the data. The caller should
* reactivate ep by invoking usb_ep_read_continue() do so.
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
* @param[in] data pointer to data buffer to write to
* @param[in] max_data_len max length of data to read
* @param[out] read_bytes Number of bytes read. If data is NULL and
* max_data_len is 0 the number of bytes
* available for read should be returned.
*
* @return 0 on success, negative errno code on fail.
*/
int usb_ep_read_wait(uint8_t ep, uint8_t *data, uint32_t max_data_len,
uint32_t *read_bytes);
/**
* @brief Continue reading data from the endpoint
*
* Clear the endpoint NAK and enable the endpoint to accept more data
* from the host. Usually called after usb_ep_read_wait() when the consumer
* is fine to accept more data. Thus these calls together acts as flow control
* mechanism.
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
*
* @return 0 on success, negative errno code on fail.
*/
int usb_ep_read_continue(uint8_t ep);
/**
* Callback function signature for transfer completion.
*/
typedef void (*usb_transfer_callback)(uint8_t ep, int tsize, void *priv);
/* USB transfer flags */
#define USB_TRANS_READ BIT(0) /** Read transfer flag */
#define USB_TRANS_WRITE BIT(1) /** Write transfer flag */
#define USB_TRANS_NO_ZLP BIT(2) /** No zero-length packet flag */
/**
* @brief Transfer management endpoint callback
*
* If a USB class driver wants to use high-level transfer functions, driver
* needs to register this callback as usb endpoint callback.
*/
void usb_transfer_ep_callback(uint8_t ep, enum usb_dc_ep_cb_status_code);
/**
* @brief Start a transfer
*
* Start a usb transfer to/from the data buffer. This function is asynchronous
* and can be executed in IRQ context. The provided callback will be called
* on transfer completion (or error) in thread context.
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
* @param[in] data Pointer to data buffer to write-to/read-from
* @param[in] dlen Size of data buffer
* @param[in] flags Transfer flags (USB_TRANS_READ, USB_TRANS_WRITE...)
* @param[in] cb Function called on transfer completion/failure
* @param[in] priv Data passed back to the transfer completion callback
*
* @return 0 on success, negative errno code on fail.
*/
int usb_transfer(uint8_t ep, uint8_t *data, size_t dlen, unsigned int flags,
usb_transfer_callback cb, void *priv);
/**
* @brief Start a transfer and block-wait for completion
*
* Synchronous version of usb_transfer, wait for transfer completion before
* returning.
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
* @param[in] data Pointer to data buffer to write-to/read-from
* @param[in] dlen Size of data buffer
* @param[in] flags Transfer flags
*
* @return number of bytes transferred on success, negative errno code on fail.
*/
int usb_transfer_sync(uint8_t ep, uint8_t *data, size_t dlen, unsigned int flags);
/**
* @brief Cancel any ongoing transfer on the specified endpoint
*
* @param[in] ep Endpoint address corresponding to the one
* listed in the device configuration table
*
* @return 0 on success, negative errno code on fail.
*/
void usb_cancel_transfer(uint8_t ep);
void usb_dev_resume(int configuration);
int usb_dev_get_configuration(void);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,147 @@
/***************************************************************************
*
* Copyright(c) 2015,2016 Intel Corporation.
* Copyright(c) 2017 PHYTEC Messtechnik GmbH
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS 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.
*
***************************************************************************/
/**
* @file
* @brief USB Device Firmware Upgrade (DFU) public header
*
* Header follows the Device Class Specification for
* Device Firmware Upgrade Version 1.1
*/
#pragma once
#include <stdint.h>
#include <stddef.h>
#include "usb_device.h"
#ifdef __cplusplus
extern "C" {
#endif
/** DFU Class Subclass */
#define DFU_SUBCLASS 0x01
/** DFU Class runtime Protocol */
#define DFU_RT_PROTOCOL 0x01
/** DFU Class DFU mode Protocol */
#define DFU_MODE_PROTOCOL 0x02
/**
* @brief DFU Class Specific Requests
*/
#define DFU_DETACH 0x00
#define DFU_DNLOAD 0x01
#define DFU_UPLOAD 0x02
#define DFU_GETSTATUS 0x03
#define DFU_CLRSTATUS 0x04
#define DFU_GETSTATE 0x05
#define DFU_ABORT 0x06
/** DFU FUNCTIONAL descriptor type */
#define DFU_FUNC_DESC 0x21
/** DFU attributes DFU Functional Descriptor */
#define DFU_ATTR_WILL_DETACH 0x08
#define DFU_ATTR_MANIFESTATION_TOLERANT 0x04
#define DFU_ATTR_CAN_UPLOAD 0x02
#define DFU_ATTR_CAN_DNLOAD 0x01
/** DFU Specification release */
#define DFU_VERSION 0x0110
/** Run-Time Functional Descriptor */
struct dfu_runtime_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bmAttributes;
uint16_t wDetachTimeOut;
uint16_t wTransferSize;
uint16_t bcdDFUVersion;
} __packed;
/** bStatus values for the DFU_GETSTATUS response */
enum dfu_status {
statusOK,
errTARGET,
errFILE,
errWRITE,
errERASE,
errCHECK_ERASED,
errPROG,
errVERIFY,
errADDRESS,
errNOTDONE,
errFIRMWARE,
errVENDOR,
errUSB,
errPOR,
errUNKNOWN,
errSTALLEDPKT
};
/** bState values for the DFU_GETSTATUS response */
enum dfu_state {
appIDLE,
appDETACH,
dfuIDLE,
dfuDNLOAD_SYNC,
dfuDNBUSY,
dfuDNLOAD_IDLE,
dfuMANIFEST_SYNC,
dfuMANIFEST,
dfuMANIFEST_WAIT_RST,
dfuUPLOAD_IDLE,
dfuERROR,
};
/*
These callbacks are made public so the ACM driver can call them to handle the switch to DFU.
*/
int dfu_class_handle_req(struct usb_setup_packet *pSetup,
int32_t *data_len, uint8_t **data);
void dfu_status_cb(enum usb_dc_status_code status, uint8_t *param);
int usb_dfu_init(void);
int dfu_custom_handle_req(struct usb_setup_packet *pSetup,
int32_t *data_len, uint8_t **data);
typedef void(*usb_dfu_detach_routine_t)(int delay);
void usb_dfu_set_detach_cb(usb_dfu_detach_routine_t cb);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,40 @@
// Copyright 2019-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void(*usb_osglue_intdisena_routine_t)(void);
typedef int(*usb_osglue_wait_routine_t)(int delay_us);
typedef struct {
/* Disable USB interrupt */
usb_osglue_intdisena_routine_t int_dis_proc;
/* Enable USB interrupt */
usb_osglue_intdisena_routine_t int_ena_proc;
/* Wait for a set amount of uS. Return the amount actually waited. If delay_us is 0, just yield.*/
usb_osglue_wait_routine_t wait_proc;
} usb_osglue_data_t;
extern usb_osglue_data_t rom_usb_osglue;
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,50 @@
// Copyright 2019-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// USB persistence flags.
//This bit indicates persistence has been enabled, that is, the USB initialization routines should not
//reset the USB device as the device still is initialized and the host detected it with the same cdcacm/dfu
//descriptor as the ROM uses; we can just re-initialize the software side and have at 'er.
#define USBDC_PERSIST_ENA (1<<31)
//This bit indicates to the ROM that we rebooted because of a request to go into DFU mode; the ROM should
//honour this request.
#define USBDC_BOOT_DFU (1<<30)
//This being non-0 indicates a memory location where a 'testament' is stored, aka a piece of text that should be output
//after a reboot. Can contain core dump info or something.
#define USBDC_TESTAMENT_LOC_MASK 0x7FFFF //bits 19-0; this is added to a base address of 0x3FF80000.
//The testament is a FIFO. The ROM will output all data between textstart and textend; if textend is lower than textstart it will
//output everything from textstart to memend, then memstart to textend.
typedef struct {
char *memstart; //start of memory region
char *memend; //end of memory region
char *textstart; //start of text to output
char *textend;
} usbdc_testament_t;
#ifdef __cplusplus
}
#endif