IDF master c13afea63 (#5214)

esp-dsp: master 7cc5073
esp-face: master 420fc7e
esp-rainmaker: f1b82c7
esp32-camera: master 6f8489e
esp_littlefs: master b58f00c
This commit is contained in:
Me No Dev
2021-05-31 16:32:51 +03:00
committed by GitHub
parent 0db9e2f45b
commit a618fc1361
616 changed files with 11842 additions and 4932 deletions

View File

@ -165,7 +165,7 @@ static inline bool cpu_ll_is_debugger_attached(void)
static inline void cpu_ll_break(void)
{
__asm__ ("break 0,0");
__asm__ ("break 1,15");
}
static inline void cpu_ll_set_vecbase(const void* vecbase)

View File

@ -18,6 +18,8 @@
#include "soc/soc_caps.h"
#include "soc/soc.h"
#include "xtensa/xtensa_api.h"
#include "xtensa/config/specreg.h"
#include "xt_instr_macros.h"
#ifdef __cplusplus
extern "C" {
@ -43,6 +45,18 @@ static inline void intr_cntrl_ll_disable_interrupts(uint32_t mask)
xt_ints_off(mask);
}
/**
* @brief Read the current interrupt mask of the CPU running this code.
*
* @return The current interrupt bitmask.
*/
static inline uint32_t intr_cntrl_ll_read_interrupt_mask(void)
{
uint32_t int_mask;
RSR(INTENABLE, int_mask);
return int_mask;
}
/**
* @brief checks if given interrupt number has a valid handler
*
@ -79,27 +93,6 @@ static inline void *intr_cntrl_ll_get_int_handler_arg(uint8_t intr)
return xt_get_interrupt_handler_arg(intr);
}
/**
* @brief Disables interrupts that are not located in iram
*
* @param newmask mask of interrupts needs to be disabled
* @return oldmask where to store old interrupts state
*/
static inline uint32_t intr_cntrl_ll_disable_int_mask(uint32_t newmask)
{
return xt_int_disable_mask(newmask);
}
/**
* @brief Enables interrupts that are not located in iram
*
* @param newmask mask of interrupts needs to be disabled
*/
static inline void intr_cntrl_ll_enable_int_mask(uint32_t newmask)
{
xt_int_enable_mask(newmask);
}
/**
* @brief Acknowledge an edge-trigger interrupt by clearing its pending flag
*

View File

@ -22,7 +22,7 @@
extern "C" {
#endif
static inline uint32_t mpu_ll_id_to_addr(int id)
static inline uint32_t mpu_ll_id_to_addr(unsigned id)
{
// vpn - id
// 0x00000000 = 0

View File

@ -0,0 +1,166 @@
// Copyright 2015-2021 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.
/*******************************************************************************
* NOTICE
* The ll is not public api, don't use in application code.
* See readme.md in hal/include/hal/readme.md
******************************************************************************/
// The Lowlevel layer for SPI Flash Encryption.
#include "soc/system_reg.h"
#include "soc/hwcrypto_reg.h"
#include "soc/soc.h"
#include "string.h"
#include "assert.h"
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/// Choose type of chip you want to encrypt manully
typedef enum
{
FLASH_ENCRYPTION_MANU = 0, ///!< Manually encrypt the flash chip.
PSRAM_ENCRYPTION_MANU = 1 ///!< Manually encrypt the psram chip.
} flash_encrypt_ll_type_t;
/**
* Enable the flash encryption function under spi boot mode and download boot mode.
*/
static inline void spi_flash_encrypt_ll_enable(void)
{
REG_SET_BIT(DPORT_EXTERNAL_DEVICE_ENCRYPT_DECRYPT_CONTROL_REG,
DPORT_ENABLE_DOWNLOAD_MANUAL_ENCRYPT |
DPORT_ENABLE_SPI_MANUAL_ENCRYPT);
}
/**
* Enable the AES accelerator.
* Also clear reset on digital signature unit, otherwise AES is held in resetop.
*/
static inline void spi_flash_encrypt_ll_aes_accelerator_enable(void)
{
REG_SET_BIT(DPORT_CPU_PERIP_CLK_EN1_REG, DPORT_CRYPTO_AES_CLK_EN);
REG_CLR_BIT(DPORT_CPU_PERIP_RST_EN1_REG, DPORT_CRYPTO_AES_RST | DPORT_CRYPTO_DS_RST);
}
/*
* Disable the flash encryption mode.
*/
static inline void spi_flash_encrypt_ll_disable(void)
{
REG_CLR_BIT(DPORT_EXTERNAL_DEVICE_ENCRYPT_DECRYPT_CONTROL_REG,
DPORT_ENABLE_SPI_MANUAL_ENCRYPT);
}
/**
* Choose type of chip you want to encrypt manully
*
* @param type The type of chip to be encrypted
*
* @note The hardware currently support flash encryption.
*/
static inline void spi_flash_encrypt_ll_type(flash_encrypt_ll_type_t type)
{
// Our hardware only support flash encryption
assert(type == FLASH_ENCRYPTION_MANU);
REG_WRITE(AES_XTS_DESTINATION_REG, type);
}
/**
* Configure the data size of a single encryption.
*
* @param block_size Size of the desired block.
*/
static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size)
{
// Desired block should not be larger than the block size.
REG_WRITE(AES_XTS_SIZE_REG, size >> 5);
}
/**
* Save 32-bit piece of plaintext.
*
* @param address the address of written flash partition.
* @param buffer Buffer to store the input data.
* @param size Buffer size.
*/
static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size)
{
uint32_t plaintext_offs = (address % 64);
memcpy((void *)(AES_XTS_PLAIN_BASE + plaintext_offs), buffer, size);
}
/**
* Copy the flash address to XTS_AES physical address
*
* @param flash_addr flash address to write.
*/
static inline void spi_flash_encrypt_ll_address_save(uint32_t flash_addr)
{
REG_WRITE(AES_XTS_PHYSICAL_ADDR_REG, flash_addr);
}
/**
* Start flash encryption
*/
static inline void spi_flash_encrypt_ll_calculate_start(void)
{
REG_WRITE(AES_XTS_TRIGGER_REG, 1);
}
/**
* Wait for flash encryption termination
*/
static inline void spi_flash_encrypt_ll_calculate_wait_idle(void)
{
while(REG_READ(AES_XTS_STATE_REG) == 0x1) {
}
}
/**
* Finish the flash encryption and make encrypted result accessible to SPI.
*/
static inline void spi_flash_encrypt_ll_done(void)
{
REG_WRITE(AES_XTS_RELEASE_REG, 1);
while(REG_READ(AES_XTS_STATE_REG) != 0x3) {
}
}
/**
* Set to destroy encrypted result
*/
static inline void spi_flash_encrypt_ll_destroy(void)
{
REG_WRITE(AES_XTS_DESTROY_REG, 1);
}
/**
* Check if is qualified to encrypt the buffer
*
* @param address the address of written flash partition.
* @param length Buffer size.
*/
static inline bool spi_flash_encrypt_ll_check(uint32_t address, uint32_t length)
{
return ((address % length) == 0) ? true : false;
}
#ifdef __cplusplus
}
#endif

View File

@ -995,7 +995,7 @@ static inline void spi_ll_set_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
static inline void spi_ll_clear_intr(spi_dev_t* hw, spi_ll_intr_t intr_mask)
{
#define CLR_INTR(intr_bit, _, __, clr_op) if (intr_mask & (intr_bit)) hw->clr_op;
#define CLR_INTR(intr_bit, _, __, clr_reg) if (intr_mask & (intr_bit)) hw->clr_reg;
FOR_EACH_ITEM(CLR_INTR, INTR_LIST);
#undef CLR_INTR
}

View File

@ -1,4 +1,4 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
// Copyright 2020-2021 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.
@ -13,124 +13,158 @@
// limitations under the License.
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "soc/systimer_struct.h"
#define SYSTIMER_LL_COUNTER_CLOCK (0) // Counter used for "wallclock" time
#define SYSTIMER_LL_ALARM_CLOCK (2) // Alarm used for "wallclock" time
#define SYSTIMER_LL_TICKS_PER_US (80) // 80 systimer ticks == 1us
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include "soc/soc.h"
#include "soc/systimer_reg.h"
// All these functions get invoked either from ISR or HAL that linked to IRAM.
// Always inline these functions even no gcc optimization is applied.
/*******************counter*************************/
/******************* Clock *************************/
__attribute__((always_inline)) static inline void systimer_ll_enable_clock(void)
__attribute__((always_inline)) static inline void systimer_ll_enable_clock(systimer_dev_t *dev, bool en)
{
REG_SET_BIT(SYSTIMER_CONF_REG, SYSTIMER_CLK_EN);
dev->conf.clk_en = en;
}
__attribute__((always_inline)) static inline void systimer_ll_apply_counter_value(void)
/******************* Counter *************************/
__attribute__((always_inline)) static inline void systimer_ll_enable_counter(systimer_dev_t *dev, uint32_t counter_id, bool en)
{
REG_SET_BIT(SYSTIMER_LOAD_REG, SYSTIMER_TIMER_LOAD);
// ESP32-S2 only has one counter in systimer group
(void)dev;
(void)counter_id;
}
__attribute__((always_inline)) static inline void systimer_ll_load_counter_value(uint64_t value)
__attribute__((always_inline)) static inline void systimer_ll_counter_can_stall_by_cpu(systimer_dev_t *dev, uint32_t counter_id, uint32_t cpu_id, bool can)
{
REG_WRITE(SYSTIMER_LOAD_LO_REG, value & 0xFFFFFFFF);
REG_WRITE(SYSTIMER_LOAD_HI_REG, (value & 0xFFFFFFFF00000000) >> 32);
(void)dev;
(void)counter_id;
(void)cpu_id;
(void)can;
}
__attribute__((always_inline)) static inline void systimer_ll_set_step_for_pll(uint32_t step)
__attribute__((always_inline)) static inline void systimer_ll_counter_snapshot(systimer_dev_t *dev, uint32_t counter_id)
{
REG_SET_FIELD(SYSTIMER_STEP_REG, SYSTIMER_TIMER_PLL_STEP, step);
(void)counter_id;
dev->update.timer_update = 1;
}
__attribute__((always_inline)) static inline void systimer_ll_set_step_for_xtal(uint32_t step)
__attribute__((always_inline)) static inline bool systimer_ll_is_counter_value_valid(systimer_dev_t *dev, uint32_t counter_id)
{
REG_SET_FIELD(SYSTIMER_STEP_REG, SYSTIMER_TIMER_XTAL_STEP, step);
(void)counter_id;
return dev->update.timer_value_valid;
}
__attribute__((always_inline)) static inline void systimer_ll_counter_snapshot(void)
__attribute__((always_inline)) static inline void systimer_ll_set_counter_value(systimer_dev_t *dev, uint32_t counter_id, uint64_t value)
{
REG_WRITE(SYSTIMER_UPDATE_REG, SYSTIMER_TIMER_UPDATE);
(void)counter_id;
dev->load_hi.timer_load_hi = value >> 32;
dev->load_lo.timer_load_lo = value;
}
__attribute__((always_inline)) static inline bool systimer_ll_is_counter_value_valid(void)
__attribute__((always_inline)) static inline uint32_t systimer_ll_get_counter_value_low(systimer_dev_t *dev, uint32_t counter_id)
{
return REG_GET_BIT(SYSTIMER_UPDATE_REG, SYSTIMER_TIMER_VALUE_VALID);
return dev->value_lo.timer_value_lo;
}
__attribute__((always_inline)) static inline uint32_t systimer_ll_get_counter_value_low(void)
__attribute__((always_inline)) static inline uint32_t systimer_ll_get_counter_value_high(systimer_dev_t *dev, uint32_t counter_id)
{
return REG_READ(SYSTIMER_VALUE_LO_REG);
return dev->value_hi.timer_value_hi;
}
__attribute__((always_inline)) static inline uint32_t systimer_ll_get_counter_value_high(void)
__attribute__((always_inline)) static inline void systimer_ll_apply_counter_value(systimer_dev_t *dev, uint32_t counter_id)
{
return REG_READ(SYSTIMER_VALUE_HI_REG);
dev->load.timer_load = 1;
}
/*******************alarm*************************/
__attribute__((always_inline)) static inline void systimer_ll_set_alarm_value(uint32_t alarm_id, uint64_t value)
__attribute__((always_inline)) static inline void systimer_ll_set_step_for_pll(systimer_dev_t *dev, uint32_t step)
{
REG_WRITE(SYSTIMER_TARGET0_LO_REG + alarm_id * 8, value & 0xFFFFFFFF);
REG_WRITE(SYSTIMER_TARGET0_HI_REG + alarm_id * 8, (value & 0xFFFFFFFF00000000) >> 32);
dev->step.timer_pll_step = step;
}
__attribute__((always_inline)) static inline uint64_t systimer_ll_get_alarm_value(uint32_t alarm_id)
__attribute__((always_inline)) static inline void systimer_ll_set_step_for_xtal(systimer_dev_t *dev, uint32_t step)
{
return (uint64_t)REG_READ(SYSTIMER_TARGET0_HI_REG + alarm_id * 8) << 32 | REG_READ(SYSTIMER_TARGET0_LO_REG + alarm_id * 8);
dev->step.timer_xtal_step = step;
}
__attribute__((always_inline)) static inline void systimer_ll_enable_alarm(uint32_t alarm_id)
/******************* Alarm *************************/
__attribute__((always_inline)) static inline void systimer_ll_set_alarm_target(systimer_dev_t *dev, uint32_t alarm_id, uint64_t value)
{
REG_SET_BIT(SYSTIMER_TARGET0_CONF_REG + alarm_id * 4, BIT(31));
dev->target_val[alarm_id].hi.timer_target_hi = value >> 32;
dev->target_val[alarm_id].lo.timer_target_lo = value;
}
__attribute__((always_inline)) static inline void systimer_ll_disable_alarm(uint32_t alarm_id)
__attribute__((always_inline)) static inline uint64_t systimer_ll_get_alarm_target(systimer_dev_t *dev, uint32_t alarm_id)
{
REG_CLR_BIT(SYSTIMER_TARGET0_CONF_REG + alarm_id * 4, BIT(31));
return ((uint64_t)(dev->target_val[alarm_id].hi.timer_target_hi) << 32) | dev->target_val[alarm_id].lo.timer_target_lo;
}
__attribute__((always_inline)) static inline void systimer_ll_enable_alarm_oneshot(uint32_t alarm_id)
__attribute__((always_inline)) static inline void systimer_ll_connect_alarm_counter(systimer_dev_t *dev, uint32_t alarm_id, uint32_t counter_id)
{
REG_CLR_BIT(SYSTIMER_TARGET0_CONF_REG + alarm_id * 4, BIT(30));
// On esp32-s2, counter int the systimer is fixed connectred to other three alarm comparators
(void)dev;
(void)alarm_id;
(void)counter_id;
}
__attribute__((always_inline)) static inline void systimer_ll_enable_alarm_period(uint32_t alarm_id)
__attribute__((always_inline)) static inline void systimer_ll_enable_alarm_oneshot(systimer_dev_t *dev, uint32_t alarm_id)
{
REG_SET_BIT(SYSTIMER_TARGET0_CONF_REG + alarm_id * 4, BIT(30));
dev->target_conf[alarm_id].target_period_mode = 0;
}
__attribute__((always_inline)) static inline void systimer_ll_set_alarm_period(uint32_t alarm_id, uint32_t period)
__attribute__((always_inline)) static inline void systimer_ll_enable_alarm_period(systimer_dev_t *dev, uint32_t alarm_id)
{
REG_SET_FIELD(SYSTIMER_TARGET0_CONF_REG + alarm_id * 4, SYSTIMER_TARGET0_PERIOD, period);
dev->target_conf[alarm_id].target_period_mode = 1;
}
/*******************interrupt*************************/
__attribute__((always_inline)) static inline void systimer_ll_enable_alarm_int(uint32_t alarm_id)
__attribute__((always_inline)) static inline void systimer_ll_set_alarm_period(systimer_dev_t *dev, uint32_t alarm_id, uint32_t period)
{
REG_SET_BIT(SYSTIMER_INT_ENA_REG, 1 << alarm_id);
assert(period < (1 << 30));
dev->target_conf[alarm_id].target_period = period;
}
__attribute__((always_inline)) static inline void systimer_ll_disable_alarm_int(uint32_t alarm_id)
__attribute__((always_inline)) static inline void systimer_ll_apply_alarm_value(systimer_dev_t *dev, uint32_t alarm_id)
{
REG_CLR_BIT(SYSTIMER_INT_ENA_REG, 1 << alarm_id);
(void)dev;
(void)alarm_id;
}
__attribute__((always_inline)) static inline bool systimer_ll_is_alarm_int_fired(uint32_t alarm_id)
__attribute__((always_inline)) static inline void systimer_ll_enable_alarm(systimer_dev_t *dev, uint32_t alarm_id, bool en)
{
return REG_GET_BIT(SYSTIMER_INT_RAW_REG, 1 << alarm_id);
dev->target_conf[alarm_id].target_work_en = en;
}
__attribute__((always_inline)) static inline void systimer_ll_clear_alarm_int(uint32_t alarm_id)
/******************* Interrupt *************************/
__attribute__((always_inline)) static inline void systimer_ll_enable_alarm_int(systimer_dev_t *dev, uint32_t alarm_id, bool en)
{
REG_SET_BIT(SYSTIMER_INT_CLR_REG, 1 << alarm_id);
if (en) {
dev->int_ena.val |= 1 << alarm_id;
} else {
dev->int_ena.val &= ~(1 << alarm_id);
}
}
__attribute__((always_inline)) static inline bool systimer_ll_is_alarm_int_fired(systimer_dev_t *dev, uint32_t alarm_id)
{
return dev->int_raw.val & (1 << alarm_id);
}
__attribute__((always_inline)) static inline void systimer_ll_clear_alarm_int(systimer_dev_t *dev, uint32_t alarm_id)
{
dev->int_clr.val |= 1 << alarm_id;
}
#ifdef __cplusplus

View File

@ -0,0 +1,49 @@
// Copyright 2015-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.
/*
Note: This header file contains USB2.0 related types and macros that can be used by code specific to the DWC_OTG
controller (i.e., the HW specific layers of the USB host stack). Thus, this header is only meant to be used below (and
including) the HAL layer. For types and macros that are HW implementation agnostic (i.e., HCD layer and above), add them
to the "usb.h" header instead.
*/
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief USB speeds supported by the DWC OTG controller
*/
typedef enum {
USB_PRIV_SPEED_FULL,
USB_PRIV_SPEED_LOW,
} usb_priv_speed_t;
/**
* @brief USB transfer types supported by the DWC OTG controller
*/
typedef enum {
USB_PRIV_XFER_TYPE_CTRL,
USB_PRIV_XFER_TYPE_ISOCHRONOUS,
USB_PRIV_XFER_TYPE_BULK,
USB_PRIV_XFER_TYPE_INTR,
} usb_priv_xfer_type_t;
#ifdef __cplusplus
}
#endif

View File

@ -28,7 +28,7 @@ NOTE: Thread safety is the responsibility fo the HAL user. All USB Host HAL
#include "soc/usbh_struct.h"
#include "soc/usb_wrap_struct.h"
#include "hal/usbh_ll.h"
#include "hal/usb_types.h"
#include "hal/usb_types_private.h"
/* -----------------------------------------------------------------------------
------------------------------- Macros and Types -------------------------------
@ -121,7 +121,7 @@ typedef enum {
typedef struct {
union {
struct {
usb_xfer_type_t type: 2; /**< The type of endpoint */
usb_priv_xfer_type_t type: 2; /**< The type of endpoint */
uint32_t bEndpointAddress: 8; /**< Endpoint address (containing endpoint number and direction) */
uint32_t mps: 11; /**< Maximum Packet Size */
uint32_t dev_addr: 8; /**< Device Address */
@ -413,9 +413,9 @@ static inline bool usbh_hal_port_check_if_connected(usbh_hal_context_t *hal)
* connected to the host port
*
* @param hal Context of the HAL layer
* @return usb_speed_t Speed of the connected device
* @return usb_priv_speed_t Speed of the connected device (FS or LS only on the esp32-s2)
*/
static inline usb_speed_t usbh_hal_port_get_conn_speed(usbh_hal_context_t *hal)
static inline usb_priv_speed_t usbh_hal_port_get_conn_speed(usbh_hal_context_t *hal)
{
return usbh_ll_hprt_get_speed(hal->dev);
}

View File

@ -22,7 +22,7 @@ extern "C" {
#include <stdbool.h>
#include "soc/usbh_struct.h"
#include "soc/usb_wrap_struct.h"
#include "hal/usb_types.h"
#include "hal/usb_types_private.h"
/* -----------------------------------------------------------------------------
------------------------------- Global Registers -------------------------------
@ -419,7 +419,7 @@ static inline void usbh_ll_hcfg_set_fsls_pclk_sel(usbh_dev_t *hw)
*
* @param hw
*/
static inline void usbh_ll_hcfg_set_defaults(usbh_dev_t *hw, usb_speed_t speed)
static inline void usbh_ll_hcfg_set_defaults(usbh_dev_t *hw, usb_priv_speed_t speed)
{
hw->hcfg_reg.descdma = 1; //Enable scatt/gatt
hw->hcfg_reg.fslssupp = 1; //FS/LS supp only
@ -428,13 +428,13 @@ static inline void usbh_ll_hcfg_set_defaults(usbh_dev_t *hw, usb_speed_t speed)
Note: It seems like our PHY has an implicit 8 divider applied when in LS mode,
so the values of FSLSPclkSel and FrInt have to be adjusted accordingly.
*/
hw->hcfg_reg.fslspclksel = (speed == USB_SPEED_FULL) ? 1 : 2;
hw->hcfg_reg.fslspclksel = (speed == USB_PRIV_SPEED_FULL) ? 1 : 2; //esp32-s2 only supports FS or LS
hw->hcfg_reg.perschedena = 0; //Disable perio sched
}
// ----------------------------- HFIR Register ---------------------------------
static inline void usbh_ll_hfir_set_defaults(usbh_dev_t *hw, usb_speed_t speed)
static inline void usbh_ll_hfir_set_defaults(usbh_dev_t *hw, usb_priv_speed_t speed)
{
usb_hfir_reg_t hfir;
hfir.val = hw->hfir_reg.val;
@ -444,7 +444,7 @@ static inline void usbh_ll_hfir_set_defaults(usbh_dev_t *hw, usb_speed_t speed)
Note: It seems like our PHY has an implicit 8 divider applied when in LS mode,
so the values of FSLSPclkSel and FrInt have to be adjusted accordingly.
*/
hfir.frint = (speed == USB_SPEED_FULL) ? 48000 : 6000;
hfir.frint = (speed == USB_PRIV_SPEED_FULL) ? 48000 : 6000; //esp32-s2 only supports FS or LS
hw->hfir_reg.val = hfir.val;
}
@ -510,14 +510,19 @@ static inline uint32_t usbh_ll_get_frame_list_base_addr(usbh_dev_t *hw)
// ----------------------------- HPRT Register ---------------------------------
static inline usb_speed_t usbh_ll_hprt_get_speed(usbh_dev_t *hw)
static inline usb_priv_speed_t usbh_ll_hprt_get_speed(usbh_dev_t *hw)
{
int prtspd = hw->hprt_reg.prtspd;
if (prtspd == 1) {
return USB_SPEED_FULL;
} else {
return USB_SPEED_LOW;
usb_priv_speed_t speed;
//esp32-s2 only supports FS or LS
switch (hw->hprt_reg.prtspd) {
case 1:
speed = USB_PRIV_SPEED_FULL;
break;
default:
speed = USB_PRIV_SPEED_LOW;
break;
}
return speed;
}
static inline uint32_t usbh_ll_hprt_get_test_ctl(usbh_dev_t *hw)
@ -674,24 +679,24 @@ static inline void usbh_ll_chan_set_dev_addr(volatile usb_host_chan_regs_t *chan
chan->hcchar_reg.devaddr = addr;
}
static inline void usbh_ll_chan_set_ep_type(volatile usb_host_chan_regs_t *chan, usb_xfer_type_t type)
static inline void usbh_ll_chan_set_ep_type(volatile usb_host_chan_regs_t *chan, usb_priv_xfer_type_t type)
{
uint32_t ep_type;
switch (type) {
case USB_XFER_TYPE_CTRL:
chan->hcchar_reg.eptype = 0x0;
case USB_PRIV_XFER_TYPE_CTRL:
ep_type = 0;
break;
case USB_XFER_TYPE_ISOCHRONOUS:
chan->hcchar_reg.eptype = 0x1;
case USB_PRIV_XFER_TYPE_ISOCHRONOUS:
ep_type = 1;
break;
case USB_XFER_TYPE_BULK:
chan->hcchar_reg.eptype = 0x2;
case USB_PRIV_XFER_TYPE_BULK:
ep_type = 2;
break;
case USB_XFER_TYPE_INTR:
chan->hcchar_reg.eptype = 0x3;
default: //USB_PRIV_XFER_TYPE_INTR
ep_type = 3;
break;
default:
;
}
chan->hcchar_reg.eptype = ep_type;
}
//Indicates whether channel is commuunicating with a LS device connected via a FS hub. Setting this bit to 1 will cause
@ -716,9 +721,9 @@ static inline void usbh_ll_chan_set_mps(volatile usb_host_chan_regs_t *chan, uin
chan->hcchar_reg.mps = mps;
}
static inline void usbh_ll_chan_hcchar_init(volatile usb_host_chan_regs_t *chan, int dev_addr, int ep_num, int mps, usb_xfer_type_t type, bool is_in, bool is_ls)
static inline void usbh_ll_chan_hcchar_init(volatile usb_host_chan_regs_t *chan, int dev_addr, int ep_num, int mps, usb_priv_xfer_type_t type, bool is_in, bool is_ls)
{
//Sets all persistent fields of the channel over its lifetime
//Sets all persistent fields of the channel over its lifetimez
usbh_ll_chan_set_dev_addr(chan, dev_addr);
usbh_ll_chan_set_ep_type(chan, type);
usbh_ll_chan_set_lspddev(chan, is_ls);

View File

@ -60,11 +60,6 @@ void ds_hal_start(void);
*/
void ds_hal_finish(void);
/**
* @brief Check whether the key input (HMAC on ESP32-C3) is correct.
*/
ds_key_check_t ds_hal_check_decryption_key(void);
/**
* @brief Write the initialization vector.
*/

View File

@ -76,6 +76,9 @@ typedef enum {
#define GPIO_SEL_44 ((uint64_t)(((uint64_t)1)<<44)) /*!< Pin 44 selected */
#define GPIO_SEL_45 ((uint64_t)(((uint64_t)1)<<45)) /*!< Pin 45 selected */
#define GPIO_SEL_46 ((uint64_t)(((uint64_t)1)<<46)) /*!< Pin 46 selected */
#if CONFIG_IDF_TARGET_ESP32S3
#define GPIO_SEL_47 ((uint64_t)(((uint64_t)1)<<47)) /*!< Pin 47 selected */
#endif
#endif
#define GPIO_PIN_REG_0 IO_MUX_GPIO0_REG
@ -125,6 +128,7 @@ typedef enum {
#define GPIO_PIN_REG_44 IO_MUX_GPIO44_REG
#define GPIO_PIN_REG_45 IO_MUX_GPIO45_REG
#define GPIO_PIN_REG_46 IO_MUX_GPIO46_REG
#define GPIO_PIN_REG_47 IO_MUX_GPIO47_REG
#if CONFIG_IDF_TARGET_ESP32
typedef enum {

View File

@ -135,6 +135,16 @@ static inline void interrupt_controller_hal_disable_interrupts(uint32_t mask)
intr_cntrl_ll_disable_interrupts(mask);
}
/**
* @brief Read the current interrupt mask.
*
* @return The bitmask of current interrupts
*/
static inline uint32_t interrupt_controller_hal_read_interrupt_mask(void)
{
return intr_cntrl_ll_read_interrupt_mask();
}
/**
* @brief checks if given interrupt number has a valid handler
*
@ -171,27 +181,6 @@ static inline void * interrupt_controller_hal_get_int_handler_arg(uint8_t intr)
return intr_cntrl_ll_get_int_handler_arg(intr);
}
/**
* @brief Disables interrupts that are not located in iram
*
* @param newmask mask of interrupts needs to be disabled
* @return oldmask where to store old interrupts state
*/
static inline uint32_t interrupt_controller_hal_disable_int_mask(uint32_t newmask)
{
return intr_cntrl_ll_disable_int_mask(newmask);
}
/**
* @brief Enables interrupts that are not located in iram
*
* @param newmask mask of interrupts needs to be disabled
*/
static inline void interrupt_controller_hal_enable_int_mask(uint32_t newmask)
{
intr_cntrl_ll_enable_int_mask(newmask);
}
/**
* @brief Acknowledge an edge-trigger interrupt by clearing its pending flag
*

View File

@ -134,6 +134,10 @@ typedef struct {
ledc_timer_t timer_sel; /*!< Select the timer source of channel (0 - 3) */
uint32_t duty; /*!< LEDC channel duty, the range of duty setting is [0, (2**duty_resolution)] */
int hpoint; /*!< LEDC channel hpoint value, the max value is 0xfffff */
struct {
unsigned int output_invert: 1;/*!< Enable (1) or disable (0) gpio output invert */
} flags; /*!< LEDC flags */
} ledc_channel_config_t;
/**

View File

@ -0,0 +1,62 @@
// Copyright 2021 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.
/*******************************************************************************
* NOTICE
* The HAL is not public api, don't use in application code.
* See readme.md in hal/include/hal/readme.md
******************************************************************************/
// The HAL layer for SPI Flash Encryption
#include "hal/spi_flash_encrypted_ll.h"
/**
* @brief Enable the flash encryption
*/
void spi_flash_encryption_hal_enable(void);
/**
* @brief Disable the flash encryption
*/
void spi_flash_encryption_hal_disable(void);
/**
* Prepare flash encryption before operation.
*
* @param address The destination address in flash for the write operation.
* @param buffer Data for programming
* @param size Size to program.
*
* @note address and buffer must be 8-word aligned.
*/
void spi_flash_encryption_hal_prepare(uint32_t address, const uint32_t* buffer, uint32_t size);
/**
* @brief flash data encryption operation is done.
*/
void spi_flash_encryption_hal_done(void);
/**
* Destroy encrypted result
*/
void spi_flash_encryption_hal_destroy(void);
/**
* Check if is qualified to encrypt the buffer
*
* @param address the address of written flash partition.
* @param length Buffer size.
*/
bool spi_flash_encryption_hal_check(uint32_t address, uint32_t length);

View File

@ -86,6 +86,44 @@ typedef struct {
};
} spi_flash_sus_cmd_conf;
/// Structure for flash encryption operations.
typedef struct
{
/**
* @brief Enable the flash encryption
*/
void (*flash_encryption_enable)(void);
/**
* @brief Disable the flash encryption
*/
void (*flash_encryption_disable)(void);
/**
* Prepare flash encryption before operation.
*
* @param address The destination address in flash for the write operation.
* @param buffer Data for programming
* @param size Size to program.
*
* @note address and buffer must be 8-word aligned.
*/
void (*flash_encryption_data_prepare)(uint32_t address, const uint32_t* buffer, uint32_t size);
/**
* @brief flash data encryption operation is done.
*/
void (*flash_encryption_done)(void);
/**
* Destroy encrypted result
*/
void (*flash_encryption_destroy)(void);
/**
* Check if is qualified to encrypt the buffer
*
* @param address the address of written flash partition.
* @param length Buffer size.
*/
bool (*flash_encryption_check)(uint32_t address, uint32_t length);
} spi_flash_encryption_t;
///Slowest io mode supported by ESP32, currently SlowRd
#define SPI_FLASH_READ_MODE_MIN SPI_FLASH_SLOWRD

View File

@ -31,13 +31,17 @@ typedef enum {
/// SPI Events
typedef enum {
SPI_EV_BUF_TX = BIT(0), ///< The buffer has sent data to master, Slave HD only
SPI_EV_BUF_RX = BIT(1), ///< The buffer has received data from master, Slave HD only
SPI_EV_SEND = BIT(2), ///< Slave has loaded some data to DMA, and master has received certain number of the data, the number is determined by master. Slave HD only
SPI_EV_RECV = BIT(3), ///< Slave has received certain number of data from master, the number is determined by master. Slave HD only.
SPI_EV_CMD9 = BIT(4), ///< Received CMD9 from master, Slave HD only
SPI_EV_CMDA = BIT(5), ///< Received CMDA from master, Slave HD only
SPI_EV_TRANS = BIT(6), ///< A transaction has done
/* Slave HD Only */
SPI_EV_BUF_TX = BIT(0), ///< The buffer has sent data to master.
SPI_EV_BUF_RX = BIT(1), ///< The buffer has received data from master.
SPI_EV_SEND_DMA_READY = BIT(2), ///< Slave has loaded its TX data buffer to the hardware (DMA).
SPI_EV_SEND = BIT(3), ///< Master has received certain number of the data, the number is determined by Master.
SPI_EV_RECV_DMA_READY = BIT(4), ///< Slave has loaded its RX data buffer to the hardware (DMA).
SPI_EV_RECV = BIT(5), ///< Slave has received certain number of data from master, the number is determined by Master.
SPI_EV_CMD9 = BIT(6), ///< Received CMD9 from master.
SPI_EV_CMDA = BIT(7), ///< Received CMDA from master.
/* Common Event */
SPI_EV_TRANS = BIT(8), ///< A transaction has done
} spi_event_t;
FLAG_ATTR(spi_event_t)

View File

@ -14,78 +14,91 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "soc/soc_caps.h"
#include "soc/systimer_struct.h"
#include "hal/systimer_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include "hal/systimer_types.h"
/**
* @brief enable systimer counter
*/
void systimer_hal_enable_counter(systimer_counter_id_t counter_id);
/**
* @brief get current counter value
*/
uint64_t systimer_hal_get_counter_value(systimer_counter_id_t counter_id);
/**
* @brief get current time (in microseconds)
*/
uint64_t systimer_hal_get_time(systimer_counter_id_t counter_id);
/*
* @brief set alarm target value (used in one-shot mode)
*/
void systimer_hal_set_alarm_target(systimer_alarm_id_t alarm_id, uint64_t target);
/**
* @brief set alarm period value (used in period mode)
*/
void systimer_hal_set_alarm_period(systimer_alarm_id_t alarm_id, uint32_t period);
/**
* @brief get alarm time
*/
uint64_t systimer_hal_get_alarm_value(systimer_alarm_id_t alarm_id);
/**
* @brief enable alarm interrupt
*/
void systimer_hal_enable_alarm_int(systimer_alarm_id_t alarm_id);
/**
* @brief select alarm mode
*/
void systimer_hal_select_alarm_mode(systimer_alarm_id_t alarm_id, systimer_alarm_mode_t mode);
/**
* @brief update systimer step when apb clock gets changed
*/
void systimer_hal_on_apb_freq_update(uint32_t apb_ticks_per_us);
/**
* @brief move systimer counter value forward or backward
*/
void systimer_hal_counter_value_advance(systimer_counter_id_t counter_id, int64_t time_us);
typedef struct {
systimer_dev_t *dev;
} systimer_hal_context_t;
/**
* @brief initialize systimer in HAL layer
*/
void systimer_hal_init(void);
void systimer_hal_init(systimer_hal_context_t *hal);
/**
* @brief enable systimer counter
*/
void systimer_hal_enable_counter(systimer_hal_context_t *hal, uint32_t counter_id);
/**
* @brief get current counter value
*/
uint64_t systimer_hal_get_counter_value(systimer_hal_context_t *hal, uint32_t counter_id);
/**
* @brief get current time (in microseconds)
*/
uint64_t systimer_hal_get_time(systimer_hal_context_t *hal, uint32_t counter_id);
/*
* @brief set alarm target value (used in one-shot mode)
*/
void systimer_hal_set_alarm_target(systimer_hal_context_t *hal, uint32_t alarm_id, uint64_t target);
/**
* @brief set alarm period value (used in period mode)
*/
void systimer_hal_set_alarm_period(systimer_hal_context_t *hal, uint32_t alarm_id, uint32_t period);
/**
* @brief get alarm time
*/
uint64_t systimer_hal_get_alarm_value(systimer_hal_context_t *hal, uint32_t alarm_id);
/**
* @brief enable alarm interrupt
*/
void systimer_hal_enable_alarm_int(systimer_hal_context_t *hal, uint32_t alarm_id);
/**
* @brief select alarm mode
*/
void systimer_hal_select_alarm_mode(systimer_hal_context_t *hal, uint32_t alarm_id, systimer_alarm_mode_t mode);
/**
* @brief update systimer step when apb clock gets changed
*/
void systimer_hal_on_apb_freq_update(systimer_hal_context_t *hal, uint32_t apb_ticks_per_us);
/**
* @brief move systimer counter value forward or backward
*/
void systimer_hal_counter_value_advance(systimer_hal_context_t *hal, uint32_t counter_id, int64_t time_us);
/**
* @brief connect alarm unit to selected counter
*/
void systimer_hal_connect_alarm_counter(systimer_alarm_id_t alarm_id, systimer_counter_id_t counter_id);
void systimer_hal_connect_alarm_counter(systimer_hal_context_t *hal, uint32_t alarm_id, uint32_t counter_id);
/**
* @brief set if a counter should be stalled when CPU is halted by the debugger
*/
void systimer_hal_counter_can_stall_by_cpu(uint32_t counter_id, uint32_t cpu_id, bool can);
void systimer_hal_counter_can_stall_by_cpu(systimer_hal_context_t *hal, uint32_t counter_id, uint32_t cpu_id, bool can);
#if !SOC_SYSTIMER_FIXED_TICKS_US
/**
* @brief set increase steps for systimer counter on different clock source
*/
void systimer_hal_set_steps_per_tick(systimer_hal_context_t *hal, int clock_source, uint32_t steps);
#endif
#ifdef __cplusplus
}

View File

@ -14,13 +14,13 @@
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "soc/soc_caps.h"
/*
* @brief The structure of the counter value in systimer
*
@ -39,27 +39,6 @@ typedef struct {
_Static_assert(sizeof(systimer_counter_value_t) == 8, "systimer_counter_value_t should occupy 8 bytes in memory");
/** @endcond */
/**
* @brief systimer counter ID
*
*/
typedef enum {
SYSTIMER_COUNTER_0, /*!< systimer counter 0 */
#if SOC_SYSTIMER_COUNTER_NUM > 1
SYSTIMER_COUNTER_1, /*!< systimer counter 1 */
#endif
} systimer_counter_id_t;
/**
* @brief systimer alarm ID
*
*/
typedef enum {
SYSTIMER_ALARM_0, /*!< systimer alarm 0 */
SYSTIMER_ALARM_1, /*!< systimer alarm 1 */
SYSTIMER_ALARM_2, /*!< systimer alarm 2 */
} systimer_alarm_id_t;
/**
* @brief systimer alarm mode
*

View File

@ -1,452 +0,0 @@
// Copyright 2015-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
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
#define USB_CTRL_REQ_ATTR __attribute__((packed))
#define USB_DESC_ATTR __attribute__((packed))
/* -----------------------------------------------------------------------------
------------------------------- Common USB Types -------------------------------
----------------------------------------------------------------------------- */
// ----------------------------- Device Related --------------------------------
/**
* @brief Enumeration of USB PHY type
*/
typedef enum {
USB_PHY_INTERNAL = 0, /**< Use the chip's internal USB PHY */
USB_PHY_EXTERNAL, /**< Use an external USB PHY */
} usb_phy_t;
// ------------------------------ Bus Related ----------------------------------
/**
* @brief USB Standard Speeds
*/
typedef enum {
USB_SPEED_LOW = 0, /**< USB Low Speed (1.5 Mbit/s) */
USB_SPEED_FULL, /**< USB Full Speed (12 Mbit/s) */
} usb_speed_t;
// ---------------------------- Transfer Related -------------------------------
/**
* @brief The type of USB transfer
*
* @note The enum values need to match the bmAttributes field of an EP descriptor
*/
typedef enum {
USB_XFER_TYPE_CTRL = 0,
USB_XFER_TYPE_ISOCHRONOUS,
USB_XFER_TYPE_BULK,
USB_XFER_TYPE_INTR,
} usb_xfer_type_t;
/**
* @brief The status of a particular transfer
*/
typedef enum {
USB_TRANSFER_STATUS_COMPLETED, /**< The transfer was successful (but may be short) */
USB_TRANSFER_STATUS_ERROR, /**< The transfer failed because due to excessive errors (e.g. no response or CRC error) */
USB_TRANSFER_STATUS_TIMED_OUT, /**< The transfer failed due to to a time out */
USB_TRANSFER_STATUS_CANCELLED, /**< The transfer was cancelled */
USB_TRANSFER_STATUS_STALL, /**< The transfer was stalled */
USB_TRANSFER_STATUS_NO_DEVICE, /**< The transfer failed because the device is no longer valid (e.g., disconencted */
USB_TRANSFER_STATUS_OVERFLOW, /**< The transfer as more data was sent than was requested */
} usb_transfer_status_t;
/**
* @brief Isochronous packet descriptor
*
* If the number of bytes in an IRP transfer is larger than the MPS of the
* endpoint, the IRP is split over multiple packets (one packet per bInterval
* of the endpoint). An array of Isochronous packet descriptos describes how
* an IRP should be split over multiple packets.
*/
typedef struct {
int length; /**< Number of bytes to transmit/receive in the packet */
int actual_length; /**< Actual number of bytes transmitted/received in the packet */
usb_transfer_status_t status; /**< Status of the packet */
} usb_iso_packet_desc_t;
/**
* @brief USB IRP (I/O Request Packet). See USB2.0 Spec
*
* An identifiable request by a software client to move data between itself (on the
* host) and an endpoint of a device in an appropriate direction.
*
* This structure represents the barebones of the request. Different layers of
* USB drivers will wrap their own objects around this.
*
* See 10.5.3.1 os USB2.0 specification
* Bulk: Represnts a single bulk transfer which a pipe will transparently split
* into multiple MPS transactions (until the last)
* Control: Represents a single contorl transfer with the setup packet at the
* first 8 bytes of the buffer.
* Interrupt: Represnts a single interrupt transaction
* Isochronous: Represnts a buffer of a stream of bytes which the pipe will transparently
* transfer the stream of bytes one or more service periods
*/
typedef struct {
int num_bytes; /**< Number of bytes in IRP. Control should exclude size of setup. IN should be integer multiple of MPS */
int actual_num_bytes; /**< Actual number of bytes transmitted/receives in the IRP */
uint8_t *data_buffer; /**< Pointer to data buffer. Must be DMA capable memory */
usb_transfer_status_t status; /**< Status of the transfer */
int num_iso_packets; /**< Only relevant to isochronous. Number of service periods to transfer data buffer over. Set to 0 for non-iso transfers */
usb_iso_packet_desc_t iso_packet_desc[0]; /**< Descriptors for each ISO packet */
} usb_irp_t;
/* -----------------------------------------------------------------------------
----------------------------------- Chapter 9 ----------------------------------
----------------------------------------------------------------------------- */
// ------------------------------ Control Request ------------------------------
/**
* @brief Size of a USB control transfer setup packet in bytes
*/
#define USB_CTRL_REQ_SIZE 8
/**
* @brief Structure representing a USB control transfer setup packet
*/
typedef union {
struct {
uint8_t bRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} USB_CTRL_REQ_ATTR;
uint8_t val[USB_CTRL_REQ_SIZE];
} usb_ctrl_req_t;
_Static_assert(sizeof(usb_ctrl_req_t) == USB_CTRL_REQ_SIZE, "Size of usb_ctrl_req_t incorrect");
/**
* @brief Bit masks pertaining to the bRequestType field of a setup packet
*/
#define USB_B_REQUEST_TYPE_DIR_OUT (0X00 << 7)
#define USB_B_REQUEST_TYPE_DIR_IN (0x01 << 7)
#define USB_B_REQUEST_TYPE_TYPE_STANDARD (0x00 << 5)
#define USB_B_REQUEST_TYPE_TYPE_CLASS (0x01 << 5)
#define USB_B_REQUEST_TYPE_TYPE_VENDOR (0x02 << 5)
#define USB_B_REQUEST_TYPE_TYPE_RESERVED (0x03 << 5)
#define USB_B_REQUEST_TYPE_TYPE_MASK (0x03 << 5)
#define USB_B_REQUEST_TYPE_RECIP_DEVICE (0x00 << 0)
#define USB_B_REQUEST_TYPE_RECIP_INTERFACE (0x01 << 0)
#define USB_B_REQUEST_TYPE_RECIP_ENDPOINT (0x02 << 0)
#define USB_B_REQUEST_TYPE_RECIP_OTHER (0x03 << 0)
#define USB_B_REQUEST_TYPE_RECIP_MASK (0x1f << 0)
/**
* @brief Bit masks pertaining to the bRequest field of a setup packet
*/
#define USB_B_REQUEST_GET_STATUS 0x00
#define USB_B_REQUEST_CLEAR_FEATURE 0x01
#define USB_B_REQUEST_SET_FEATURE 0x03
#define USB_B_REQUEST_SET_ADDRESS 0x05
#define USB_B_REQUEST_GET_DESCRIPTOR 0x06
#define USB_B_REQUEST_SET_DESCRIPTOR 0x07
#define USB_B_REQUEST_GET_CONFIGURATION 0x08
#define USB_B_REQUEST_SET_CONFIGURATION 0x09
#define USB_B_REQUEST_GET_INTERFACE 0x0A
#define USB_B_REQUEST_SET_INTERFACE 0x0B
#define USB_B_REQUEST_SYNCH_FRAME 0x0C
/**
* @brief Bit masks pertaining to the wValue field of a setup packet
*/
#define USB_W_VALUE_DT_DEVICE 0x01
#define USB_W_VALUE_DT_CONFIG 0x02
#define USB_W_VALUE_DT_STRING 0x03
#define USB_W_VALUE_DT_INTERFACE 0x04
#define USB_W_VALUE_DT_ENDPOINT 0x05
#define USB_W_VALUE_DT_DEVICE_QUALIFIER 0x06
#define USB_W_VALUE_DT_OTHER_SPEED_CONFIG 0x07
#define USB_W_VALUE_DT_INTERFACE_POWER 0x08
/**
* @brief Initializer for a SET_ADDRESS request
*
* Sets the address of a connected device
*/
#define USB_CTRL_REQ_INIT_SET_ADDR(ctrl_req_ptr, addr) ({ \
(ctrl_req_ptr)->bRequestType = USB_B_REQUEST_TYPE_DIR_OUT | USB_B_REQUEST_TYPE_TYPE_STANDARD |USB_B_REQUEST_TYPE_RECIP_DEVICE; \
(ctrl_req_ptr)->bRequest = USB_B_REQUEST_SET_ADDRESS; \
(ctrl_req_ptr)->wValue = (addr); \
(ctrl_req_ptr)->wIndex = 0; \
(ctrl_req_ptr)->wLength = 0; \
})
/**
* @brief Initializer for a request to get a device's device descriptor
*/
#define USB_CTRL_REQ_INIT_GET_DEVC_DESC(ctrl_req_ptr) ({ \
(ctrl_req_ptr)->bRequestType = USB_B_REQUEST_TYPE_DIR_IN | USB_B_REQUEST_TYPE_TYPE_STANDARD | USB_B_REQUEST_TYPE_RECIP_DEVICE; \
(ctrl_req_ptr)->bRequest = USB_B_REQUEST_GET_DESCRIPTOR; \
(ctrl_req_ptr)->wValue = (USB_W_VALUE_DT_DEVICE << 8); \
(ctrl_req_ptr)->wIndex = 0; \
(ctrl_req_ptr)->wLength = 18; \
})
/**
* @brief Initializer for a request to get a device's current configuration number
*/
#define USB_CTRL_REQ_INIT_GET_CONFIG(ctrl_req_ptr) ({ \
(ctrl_req_ptr)->bRequestType = USB_B_REQUEST_TYPE_DIR_IN | USB_B_REQUEST_TYPE_TYPE_STANDARD | USB_B_REQUEST_TYPE_RECIP_DEVICE; \
(ctrl_req_ptr)->bRequest = USB_B_REQUEST_GET_CONFIGURATION; \
(ctrl_req_ptr)->wValue = 0; \
(ctrl_req_ptr)->wIndex = 0; \
(ctrl_req_ptr)->wLength = 1; \
})
/**
* @brief Initializer for a request to get one of the device's current configuration descriptor
*
* - desc_index indicates the configuration's index number
* - Number of bytes of the configuration descriptor to get
*/
#define USB_CTRL_REQ_INIT_GET_CFG_DESC(ctrl_req_ptr, desc_index, desc_len) ({ \
(ctrl_req_ptr)->bRequestType = USB_B_REQUEST_TYPE_DIR_IN | USB_B_REQUEST_TYPE_TYPE_STANDARD | USB_B_REQUEST_TYPE_RECIP_DEVICE; \
(ctrl_req_ptr)->bRequest = USB_B_REQUEST_GET_DESCRIPTOR; \
(ctrl_req_ptr)->wValue = (USB_W_VALUE_DT_CONFIG << 8) | ((desc_index) & 0xFF); \
(ctrl_req_ptr)->wIndex = 0; \
(ctrl_req_ptr)->wLength = (desc_len); \
})
/**
* @brief Initializer for a request to set a device's current configuration number
*/
#define USB_CTRL_REQ_INIT_SET_CONFIG(ctrl_req_ptr, config_num) ({ \
(ctrl_req_ptr)->bRequestType = USB_B_REQUEST_TYPE_DIR_OUT | USB_B_REQUEST_TYPE_TYPE_STANDARD | USB_B_REQUEST_TYPE_RECIP_DEVICE; \
(ctrl_req_ptr)->bRequest = USB_B_REQUEST_SET_CONFIGURATION; \
(ctrl_req_ptr)->wValue = (config_num); \
(ctrl_req_ptr)->wIndex = 0; \
(ctrl_req_ptr)->wLength = 0; \
})
// ---------------------------- Device Descriptor ------------------------------
/**
* @brief Size of a USB device descriptor in bytes
*/
#define USB_DESC_DEV_SIZE 18
/**
* @brief Structure representing a USB device descriptor
*/
typedef union {
struct {
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;
} USB_DESC_ATTR;
uint8_t val[USB_DESC_DEV_SIZE];
} usb_desc_devc_t;
_Static_assert(sizeof(usb_desc_devc_t) == USB_DESC_DEV_SIZE, "Size of usb_desc_devc_t incorrect");
/**
* @brief Possible base class values of the bDeviceClass field of a USB device descriptor
*/
#define USB_CLASS_PER_INTERFACE 0x00
#define USB_CLASS_AUDIO 0x01
#define USB_CLASS_COMM 0x02
#define USB_CLASS_HID 0x03
#define USB_CLASS_PHYSICAL 0x05
#define USB_CLASS_STILL_IMAGE 0x06
#define USB_CLASS_PRINTER 0x07
#define USB_CLASS_MASS_STORAGE 0x08
#define USB_CLASS_HUB 0x09
#define USB_CLASS_CDC_DATA 0x0a
#define USB_CLASS_CSCID 0x0b
#define USB_CLASS_CONTENT_SEC 0x0d
#define USB_CLASS_VIDEO 0x0e
#define USB_CLASS_WIRELESS_CONTROLLER 0xe0
#define USB_CLASS_PERSONAL_HEALTHCARE 0x0f
#define USB_CLASS_AUDIO_VIDEO 0x10
#define USB_CLASS_BILLBOARD 0x11
#define USB_CLASS_USB_TYPE_C_BRIDGE 0x12
#define USB_CLASS_MISC 0xef
#define USB_CLASS_APP_SPEC 0xfe
#define USB_CLASS_VENDOR_SPEC 0xff
/**
* @brief Vendor specific subclass code
*/
#define USB_SUBCLASS_VENDOR_SPEC 0xff
// ----------------------- Configuration Descriptor ----------------------------
/**
* @brief Size of a short USB configuration descriptor in bytes
*
* @note The size of a full USB configuration includes all the interface and endpoint
* descriptors of that configuration.
*/
#define USB_DESC_CFG_SIZE 9
/**
* @brief Structure representing a short USB configuration descriptor
*
* @note The full USB configuration includes all the interface and endpoint
* descriptors of that configuration.
*/
typedef union {
struct {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
} USB_DESC_ATTR;
uint8_t val[USB_DESC_CFG_SIZE];
} usb_desc_cfg_t;
_Static_assert(sizeof(usb_desc_cfg_t) == USB_DESC_CFG_SIZE, "Size of usb_desc_cfg_t incorrect");
/**
* @brief Bit masks pertaining to the bmAttributes field of a configuration descriptor
*/
#define USB_BM_ATTRIBUTES_ONE (1 << 7) //Must be set
#define USB_BM_ATTRIBUTES_SELFPOWER (1 << 6) //Self powered
#define USB_BM_ATTRIBUTES_WAKEUP (1 << 5) //Can wakeup
#define USB_BM_ATTRIBUTES_BATTERY (1 << 4) //Battery powered
// ------------------------- Interface Descriptor ------------------------------
/**
* @brief Size of a USB interface descriptor in bytes
*/
#define USB_DESC_INTF_SIZE 9
/**
* @brief Structure representing a USB interface descriptor
*/
typedef union {
struct {
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;
} USB_DESC_ATTR;
uint8_t val[USB_DESC_INTF_SIZE];
} usb_desc_intf_t;
_Static_assert(sizeof(usb_desc_intf_t) == USB_DESC_INTF_SIZE, "Size of usb_desc_intf_t incorrect");
// ------------------------- Endpoint Descriptor -------------------------------
/**
* @brief Size of a USB endpoint descriptor in bytes
*/
#define USB_DESC_EP_SIZE 7
/**
* @brief Structure representing a USB endp;oint descriptor
*/
typedef union {
struct {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} USB_DESC_ATTR;
uint8_t val[USB_DESC_EP_SIZE];
} usb_desc_ep_t;
_Static_assert(sizeof(usb_desc_ep_t) == USB_DESC_EP_SIZE, "Size of usb_desc_ep_t incorrect");
/**
* @brief Bit masks pertaining to the bEndpointAddress field of an endpoint descriptor
*/
#define USB_B_ENDPOINT_ADDRESS_EP_NUM_MASK 0x0f
#define USB_B_ENDPOINT_ADDRESS_EP_DIR_MASK 0x80
/**
* @brief Bit masks pertaining to the bmAttributes field of an endpoint descriptor
*/
#define USB_BM_ATTRIBUTES_XFERTYPE_MASK 0x03
#define USB_BM_ATTRIBUTES_XFER_CONTROL (0 << 0)
#define USB_BM_ATTRIBUTES_XFER_ISOC (1 << 0)
#define USB_BM_ATTRIBUTES_XFER_BULK (2 << 0)
#define USB_BM_ATTRIBUTES_XFER_INT (3 << 0)
#define USB_BM_ATTRIBUTES_SYNCTYPE_MASK 0x0C /* in bmAttributes */
#define USB_BM_ATTRIBUTES_SYNC_NONE (0 << 2)
#define USB_BM_ATTRIBUTES_SYNC_ASYNC (1 << 2)
#define USB_BM_ATTRIBUTES_SYNC_ADAPTIVE (2 << 2)
#define USB_BM_ATTRIBUTES_SYNC_SYNC (3 << 2)
#define USB_BM_ATTRIBUTES_USAGETYPE_MASK 0x30
#define USB_BM_ATTRIBUTES_USAGE_DATA (0 << 4)
#define USB_BM_ATTRIBUTES_USAGE_FEEDBACK (1 << 4)
#define USB_BM_ATTRIBUTES_USAGE_IMPLICIT_FB (2 << 4)
/**
* @brief Macro helpers to get information about an endpoint from its descriptor
*/
#define USB_DESC_EP_GET_XFERTYPE(desc_ptr) ((usb_xfer_type_t) ((desc_ptr)->bmAttributes & USB_BM_ATTRIBUTES_XFERTYPE_MASK))
#define USB_DESC_EP_GET_EP_NUM(desc_ptr) ((desc_ptr)->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_NUM_MASK)
#define USB_DESC_EP_GET_EP_DIR(desc_ptr) (((desc_ptr)->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_DIR_MASK) ? 1 : 0)
#define USB_DESC_EP_GET_MPS(desc_ptr) ((desc_ptr)->wMaxPacketSize & 0x7FF)
// --------------------------- String Descriptor -------------------------------
/**
* @brief Size of a short USB string descriptor in bytes
*/
#define USB_DESC_STR_SIZE 4
/**
* @brief Structure representing a USB string descriptor
*/
typedef union {
struct {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wData[1]; /* UTF-16LE encoded */
} USB_DESC_ATTR;
uint8_t val[USB_DESC_STR_SIZE];
} usb_desc_str_t;
_Static_assert(sizeof(usb_desc_str_t) == USB_DESC_STR_SIZE, "Size of usb_desc_str_t incorrect");
#ifdef __cplusplus
}
#endif