Giter Site home page Giter Site logo

xtoolbox / teenyusb Goto Github PK

View Code? Open in Web Editor NEW
540.0 32.0 172.0 6.16 MB

Lightweight USB device and host stack for STM32 and other MCUs. Ready for USB 3.0 device.

Home Page: http://www.tusb.org

License: MIT License

C 99.57% Assembly 0.43%
usb stm32 host hub composite hid cdc msc winusb rndis

teenyusb's People

Contributors

xtoolbox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

teenyusb's Issues

composite/bulk demo does not connect

Hi.
Thank you for writing TeenyUSB. I'm interested in using TeenyUSB on STM32F103 (and GD32F303, same usb hardware as STM32). I have compiled TeenyUSB and tried the STM32F103 composite and the bulk demo. Unfortunately, when I connect the STM32F103 to a linux system, there is no connection. I add the logging output. What should I do?

regards,

koen

f103bulk:

[ 2317.374473] usb 1-1.3: new full-speed USB device number 27 using xhci_hcd
[ 2317.476365] usb 1-1.3: not running at top speed; connect to a high speed hub
[ 2317.484076] usb 1-1.3: New USB device found, idVendor=0483, idProduct=0001, bcdDevice= 1.00
[ 2317.484093] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 2317.484104] usb 1-1.3: Product: TeenyUSB Custom Bulk
[ 2317.484115] usb 1-1.3: Manufacturer: TeenyUSB
[ 2317.484125] usb 1-1.3: SerialNumber: TUSB123456
[ 2322.671064] usb 1-1.3: can't set config #1, error -110

logfile:
usbmon_bulk.txt

f103comp:

[ 3340.243722] usb 1-1.3: new full-speed USB device number 30 using xhci_hcd
[ 3340.345680] usb 1-1.3: not running at top speed; connect to a high speed hub
[ 3340.352183] usb 1-1.3: New USB device found, idVendor=0483, idProduct=0011, bcdDevice= 1.00
[ 3340.352201] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 3340.352216] usb 1-1.3: Product: TeenyUSB Composite DEMO
[ 3340.352230] usb 1-1.3: Manufacturer: TeenyUSB
[ 3340.352243] usb 1-1.3: SerialNumber: TUSB123456
[ 3345.396632] usb 1-1.3: can't set config #1, error -110

usbmon_comp.txt

The logfile also contains a bit of traffic from keyboard and mouse (connected to same usb bus).

linux used:

 $ uname -a
Linux raspberrypi 5.10.52-v8+ #1441 SMP PREEMPT Tue Aug 3 18:14:03 BST 2021 aarch64 GNU/Linux

感谢!

正在看《设备开发指南》,很受用!非常感谢

默认的USB_REQ_SET_INTERFACE响应有误

默认的USB_REQ_SET_INTERFACE处理中,在最后向主机响应了一个字节的数据:
tusb_control_send(dev, &dev->temp_buffer, 1);
而USB_REQ_SET_INTERFACE的请求报文为01 0b 00 00,最后的长度域为00,就是不需要设备向主机响应数据的。
所以,默认的USB_REQ_SET_INTERFACE处理中,最后的响应应修改为:
tusb_send_status(dev);

STM32F407 FS复合设备MSC失败,Composite demo MSC fail when use STM32F407 FS core

在复合设备例程中,如果使用STM32F407的FS USB内核会造成U盘枚举失败。原因是STM32F407没有4号端点。
解决办法,去掉不需要的接口,在 STM32F407的FS core上不使用端点4.

In the composite device demo, the MSC class use enpoint 4 for data transfer. If we USB FS core on STM32F407, the MSC will fail to transfer data by a transaction error.
Solution, do not use ep 4 when select STM32F407 FS core.

STM32F407

Is it possible to get separate demo projects in STM32CubeIDE for Device CDC and Host RNDIS?

I did get a translation of STM32_USB design guide PDF to English but a lot of it looks like it has changed since it was written.

Thanks

Andy.

HUB Support

Hi, You have mentioned Hub support on project front page but I cannot find any indication of that support on your code. After executing the program I saw that hub class is not recognized:

D] [HOST] HS DEV:00 Set device address to 01
[D] [HOST] HS DEV:01 Device VID:05e3 PID:0608
[D] [HOST] HS DEV:01 Class (0x09,0x00,0x00) not found, init it as raw device
[D] [HOST] HS DEV:01 Interface (0x09,0x00,0x00) has 1 endpoints:
[D] [HOST] HS DEV:01   Ep  addr:0x81, attr:INTR, mps:1
[D] [HOST] HS DEV:01 Device has 1 interfaces
[D] [HOST] HS DEV:01 Set to configuration 1(1)

Can you confirm that missed support or indicate the source files ?
Thanks

是否有计划支持MTP类?

需要通过电脑读取SD卡中的文件,MCU里面已经挂载了一个fat的文件系统,msc类不再适合。
需要一个mtp的类从文件层面进行文件读写,而不是msc类直接操作SD卡。

STM32f407_evk Board Config Issues

Hello, great project, it is working very well for me. I did notice these small issues when working with the STM32F40 that may be worth looking at:

Confusing comment

/**USART3 GPIO Configuration
PC7 ------> USART6_RX
PC6 ------> USART6_TX
*/
GPIOC->MODER &= ~ (MODE(3,10) | MODE(3,11));
GPIOC->MODER |= (MODE(2,10) | MODE(2,11));
GPIOC->OTYPER &= ~(TYPE(1,10) | TYPE(1,11));
GPIOC->OSPEEDR |= (MODE(3,10) | MODE(3,11));
GPIOC->AFR[1] &= ~(AF(0xf,10) | AF(0xf,11));
GPIOC->AFR[1] |= (AF(GPIO_AF7_USART3,10) | AF(GPIO_AF7_USART3,11));

This comment does not reflect the actual pin numbers. Should be UART3 and PC11 and PC10

HOST_PORT_POWER_ON_FS should be active low?

#define HOST_PORT_POWER_ON_FS() \
do{\
__HAL_RCC_GPIOC_CLK_ENABLE();\
GPIOC->MODER &= ~(GPIO_MODER_MODER0 << (1*2));\
GPIOC->MODER |= (GPIO_MODER_MODER0_0 << (1*2));\
GPIOC->BSRR = GPIO_PIN_1<<16;\
}while(0)

Refer user manual page 30/34. I had to change this section of code to enable VBUS at the USB connector.

Thank you!
Regards
Ryan

希望能补充一些tusb库的移植说明

首先感谢楼主付出的努力!
看楼主做了多款开发板的兼容,能否基于cubemx做个移植的说明呢?看了下《USB设备开发指南》还是不清楚怎么把tusb移植到自己的目标板上,真心希望楼主能出个说明资料,谢谢

composite 示例程序修改为只有一个 HID 设备后,suspend & resume 后的第二次 SET_IDLE 设备端无应答

对应提交: 当前最新提交 9cd8bda (Nov 27, 2020)
对应项目: sample/composite/composite.uvprojx

问题描述:

composite 示例项目的原始程序可正常工作,但修改为只有一个 HID 设备后,在 PC 向设备发送 suspend 和 resume 请求后,第二次 SET_IDLE 请求设备端响应不正常。如果设备插入到了 USB Hub 而不是 Root Hub 上,后续 PC 发送 HID 数据设备端也没有响应。

复现步骤:

  1. 使用附件 composite_hid_only_modified_files.zip 中的文件覆盖 sample/composite 目录下的原有文件,编译下载到 STM32F072C8T6/CBT6 中
  2. 将设备插入到连接到 PC 的 USB Hub 上 (若只看 SET_IDLE 请求的问题,插到 Root Hub 的接口上也可以)
  3. 在 PC 识别到 USB HID 设备后,等待 10s 左右。打开 USB HID 调试工具 (我使用的是“单片机多功能调试助手”),查找和打开该 USB 设备,尝试发送数据。
  4. 在第 3 步中点击查找后,PC 就应该向设备发出了 suspend & resume 后的第二次 SET_IDLE 请求,抓包可以看到此事物没有来自设备的应答。

附件:

composite_hid_only_modified_files.zip - composite 示例项目修改后的文件

composite_sample_captured_packets.zip - 使用 USB Packet Viewer 工具所抓的包:

  • composite_sample_01_original_on_usb_hub.upv:
    使用原有 composite 示例程序,设备接在 USB Hub 上时所抓的包。PC 识别到设备后,一直有通信,未 suspend, 整体正常
  • composite_sample_02_hid_only_on_usb_hub.upv:
    使用修改为只有一个 HID 设备后的 composite 示例程序,设备接在 USB Hub 上时所抓的包。14s 处在 suspend & resume 后 PC 发送的第二次 SET_IDLE 请求未收到应答,USB Packet Viewer 显示这些事物的状态为 incomplete。25s 处的后续 PC 端发送 HID 数据的包解析出来也不正常。
  • composite_sample_03_hid_only_on_root_hub.upv:
    使用程序和 composite_sample_02_hid_only_on_usb_hub.upv 相同,但设备直接接在 Root Hub 上。16s 处的 SET_IDLE 仍然为 incomplete 状态,但从 16.837s 处的 Get Descriptor 请求开始恢复正常,HID 数据可正常发送。
  • composite_sample_02_hid_only_on_usb_hub_device_info.txt 和 composite_sample_03_hid_only_on_root_hub_device_info.txt:
    使用 UsbTreeView 工具查看到的,在插入到 USB Hub 和 Root Hub 时的设备信息。一个主要区别是,在插入到 USB Hub 时 Power State 为 D0 (supported: D0, D2, D3, wake from D0, wake from D2), 插入到 Root Hub 时 Power State 为 D0 (supported: D0, D3, wake from D0)。

是否有计划支持NRF52840?

由于52840没有USB主机功能,近期某项目用到MAX3421E来做USB Host,NRF52840通过SPI与MAX3421E通讯,但是没有USB Host协议栈.

Interrupt out pipe toggle bit does not change

When using tusb_host_xfer_data on a interrupt endpoint only the first packet is registered by my USB device. Subsequent packets are ignored.

The hc->toggle_out variable is never toggled by tusb_otg_out_channel_handler . Interrupt endpoints should behave the same as bulk endpoints in this regard.

The below code should also check HCCHAR_INTR and toggle the toggle_out bit.

if(HcEpType == HCCHAR_BULK){
hc->toggle_out ^= 1U;
}

I changed it to this which resolved my issue.

if(HcEpType == HCCHAR_BULK || HcEpType == HCCHAR_INTR){
    hc->toggle_out ^= 1U;
}

Reference:
https://books.google.com.au/books?id=pkefBgAAQBAJ&lpg=PA52&ots=6_nyePBwxH&dq=interrupt%20endpoint%20toggle%20bits&pg=PA52#v=onepage&q&f=false

multiple buffer overflow vulnerabilities in TeenyUSB

buffer overflow and out of bound in tusb_rndis_device_request

static int tusb_rndis_device_request(tusb_rndis_device_t* cdc, tusb_setup_packet* setup_req)
{
    tusb_device_t* dev = cdc->dev;

	.......................
	.......................
	
    }else if(setup_req->bRequest == CDC_SEND_ENCAPSULATED_COMMAND){
        dev->ep0_rx_done = rndis_dataout_request;
        
        // overflow !!!
        tusb_set_recv_buffer(dev, 0, cdc->encapsulated_buffer, setup_req->wLength);
        tusb_set_rx_valid(dev, 0);
        return 1;
    }

if setup_req->wLength > the size of cdc->encapsulated_buffer, it could overflow.

struct _tusb_rndis_device
{
    tusb_device_t* dev;
	......................
	......................
    uint8_t    encapsulated_buffer[256];

if setup_req->wLength > 256 , it could overflow.

out of bound

    if(setup_req->bRequest == CDC_GET_ENCAPSULATED_RESPONSE){
        tusb_fix_control_xfer_corrupt_issue(dev);
        
        // vuln!!!
        tusb_control_send(dev, cdc->encapsulated_buffer, ((rndis_generic_msg_t *)cdc->encapsulated_buffer)->MessageLength );
        return 1;

cdc->encapsulated_buffer is receive from other usb device, which is recv in CDC_SEND_ENCAPSULATED_COMMAND case.

if MessageLength is too large, it could out of bound read.

out of bound read in rndis_handle_set_msg

cdc->encapsulated_buffer is receive from other usb device

static void rndis_handle_set_msg(tusb_rndis_device_t* cdc)
{
    rndis_set_cmplt_t *c;
    rndis_set_msg_t *m;
    rndis_Oid_t oid;

    c = (rndis_set_cmplt_t *)cdc->encapsulated_buffer;
    m = (rndis_set_msg_t *)cdc->encapsulated_buffer;
	
	...............
	...............

    oid = m->Oid;
    c->MessageType = REMOTE_NDIS_SET_CMPLT;
    c->MessageLength = sizeof(rndis_set_cmplt_t);
    c->Status = RNDIS_STATUS_SUCCESS;

    switch (oid)
    {
        case OID_GEN_RNDIS_CONFIG_PARAMETER:
            {
                rndis_config_parameter_t *p;
                char *ptr = (char *)m;
                ptr += sizeof(rndis_generic_msg_t);
                ptr += m->InformationBufferOffset;
                p = (rndis_config_parameter_t *)ptr;
                if(cdc->config_param){
                
                	// vuln !!!
                    cdc->config_param(cdc, ptr+p->ParameterNameOffset, ptr+p->ParameterValueOffset, p->ParameterNameLength, p->ParameterValueLength);
                }
            }
            break;

when m->InformationBufferOffset is large, it could out of bound read!

buffer overflow in tusb_cdc_device_request

static int tusb_cdc_device_request(tusb_cdc_device_t* cdc, tusb_setup_packet* setup_req)
{
  if( (setup_req->bmRequestType & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_CLASS){
    if(setup_req->wLength > 0){ 
      	
      	// overflow !!!
        tusb_set_recv_buffer(dev, 0, dev_config->cmd_buffer, setup_req->wLength);

if setup_req->wLength > the size of dev_config->cmd_buffer, it could overflow.

buffer overflow in tusb_hid_device_request

static int tusb_hid_device_request(tusb_hid_device_t* hid, tusb_setup_packet* setup_req)
{
	  ......................
	  ......................
      case HID_REQ_SET_REPORT:
      	
      	// overflow !!!
        tusb_set_recv_buffer(dev, 0, dev_config->cmd_buffer, setup_req->wLength);
        tusb_set_rx_valid(dev, 0);

if setup_req->wLength > the size of dev_config->cmd_buffer, it could overflow.

out of bound read in msc_scsi_write_10

static int msc_scsi_write_10(tusb_msc_device_t* msc)
{
  tusb_msc_cbw_t * cbw = &msc->state.cbw;
  tusb_msc_csw_t       * csw = &msc->state.csw;
  scsi_read_10_cmd_t* cmd = (scsi_read_10_cmd_t*)cbw->command;
 	......
 	......
    uint32_t block_addr = GET_BE32(cmd->logical_block_addr);
    uint32_t block_size = cbw->total_bytes/ GET_BE16(cmd->transfer_length);
    int length = msc->state.data_out_length;
    uint16_t block_count = length/block_size;
    
    if(msc->block_write){
      // TODO: support data buffer length less than the block size
      int xferred_length = cbw->total_bytes - csw->data_residue;
      
      // vuln !!! 
      length = msc->block_write(msc, cbw->lun, msc->state.data_buffer, block_addr + xferred_length/block_size, block_count);

cbw and cmd is receive from other usb device, if block_count too large , it could lead oob read.

F723-HS-Device Initialization

F723, 我试用过Composite Device Demo, 发现stm32_otg_init.c文件里面的code有问题。 在我单独的F723板子(STLINK-V3MINI) 上面不能枚举成功。
后来,我参考ST的源码,改来改去改到最后可以用了。
因为修改得比较乱,我也不知哪些是关键的部分,没有办法提交Pull requests。还有一个原因是,修改后的部分,可能只适用于F723的Device,我不知道如何融合到通用的stm32_otg_init.c文件里面。

现将,我修改过的代码部分放在这里,供您参考:

static void Wait_CoreReset(USB_OTG_GlobalTypeDef *USBx)
{
uint32_t count = 0U;

/* Wait for AHB master IDLE state. */
do
{
if (++count > 200000U)
{
break;
}
}
while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);

/* Core Soft Reset */
count = 0U;
USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;

do
{
if (++count > 200000U)
{
break;
}
}
while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
}

#if defined(USB_HS_PHYC)
static void USB_HS_PHYCInit(USB_OTG_GlobalTypeDef USBx)
{
uint32_t count = 0U;
/
Enable LDO /
USB_HS_PHYC->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE;
/
wait for LDO Ready /
while ((USB_HS_PHYC->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) == 0U)
{
if (++count > 200000U)
{
break;
}
}
/
Controls PHY frequency operation selection /
if (HSE_VALUE == 12000000){ /
HSE = 12MHz /
USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x0 << 1);
}else if (HSE_VALUE == 12500000){ /
HSE = 12.5MHz /
USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x2 << 1);
}else if (HSE_VALUE == 16000000){ /
HSE = 16MHz /
USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x3 << 1);
}else if (HSE_VALUE == 24000000){ /
HSE = 24MHz /
USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x4 << 1);
}else if (HSE_VALUE == 25000000){ /
HSE = 25MHz /
USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x5 << 1);
}else if (HSE_VALUE == 32000000){ /
HSE = 32MHz /
USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x7 << 1);
}
/
Control the tuning interface of the High Speed PHY /
USB_HS_PHYC->USB_HS_PHYC_TUNE |= USB_HS_PHYC_TUNE_VALUE;
/
Enable PLL internal PHY /
USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN;
/
2ms Delay required to get internal phy clock stable */
HAL_Delay(2U);
}
#endif

// init the IO and OTG core
static void tusb_otg_core_init(tusb_core_t* core)
{
USB_OTG_GlobalTypeDef* USBx = GetUSB(core);
(void)USBx;
if(GetUSB(core) == USB_OTG_FS){
// Init the FS core
#if defined(OTG_FS_EMBEDDED_PHY)
// 1. Init the IO
tusb_setup_otg_fs_io();
// 2. Init the interrupt
NVIC_SetPriority(OTG_FS_IRQn, 0);
NVIC_EnableIRQ(OTG_FS_IRQn);
// 3. Init the core
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
/* Select FS Embedded PHY /
USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
/
Reset after a PHY select and set Host mode /
Wait_CoreReset(USBx);
/
Deactivate the power down*/
USBx->GCCFG = USB_OTG_GCCFG_PWRDWN;
#endif
}
#if defined(OTG_HS_EXTERNAL_PHY) || defined(OTG_HS_EMBEDDED_PHY)
else if(GetUSB(core) == USB_OTG_HS){
// Init the HS core
// 1. Init the IO
// 2. Setup Interrupt
#if defined(OTG_HS_EMBEDDED_PHY)
// tusb_setup_otg_hs_io();

GPIO_InitTypeDef GPIO_InitStruct = {0};

__HAL_RCC_GPIOB_CLK_ENABLE();
/**USB_OTG_HS GPIO Configuration    
PB14     ------> USB_OTG_HS_DM
PB15     ------> USB_OTG_HS_DP 
*/
GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* Peripheral clock enable */
__HAL_RCC_OTGPHYC_CLK_ENABLE();
__HAL_RCC_USB_OTG_HS_CLK_ENABLE();
__HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE();

/* Peripheral interrupt init */
HAL_NVIC_SetPriority(OTG_HS_EP1_OUT_IRQn, 3, 0);
HAL_NVIC_EnableIRQ  (OTG_HS_EP1_OUT_IRQn);
HAL_NVIC_SetPriority(OTG_HS_EP1_IN_IRQn, 2, 0);
HAL_NVIC_EnableIRQ  (OTG_HS_EP1_IN_IRQn);
HAL_NVIC_SetPriority(OTG_HS_IRQn, 1, 0);
HAL_NVIC_EnableIRQ  (OTG_HS_IRQn);

#elif defined(OTG_HS_EXTERNAL_PHY)
OTG_HS_ULPI_IO_CLK_ENABLE();
set_io_af_mode( OTG_HS_ULPI_D0 );
set_io_af_mode( OTG_HS_ULPI_D1 );
set_io_af_mode( OTG_HS_ULPI_D2 );
set_io_af_mode( OTG_HS_ULPI_D3 );
set_io_af_mode( OTG_HS_ULPI_D4 );
set_io_af_mode( OTG_HS_ULPI_D5 );
set_io_af_mode( OTG_HS_ULPI_D6 );
set_io_af_mode( OTG_HS_ULPI_D7 );
set_io_af_mode( OTG_HS_ULPI_DIR );
set_io_af_mode( OTG_HS_ULPI_STP );
set_io_af_mode( OTG_HS_ULPI_NXT );
set_io_af_mode( OTG_HS_ULPI_CK );

NVIC_SetPriority(OTG_HS_IRQn, 0);
NVIC_EnableIRQ(OTG_HS_IRQn);

__HAL_RCC_USB_OTG_HS_CLK_ENABLE();
__HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE();    

#endif
// 3. Init the OTG HS core
#if defined(OTG_HS_EMBEDDED_PHY)
// init embedded phy
USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
/* Init The UTMI Interface /
USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
/
Select vbus source /
USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
/
Select UTMI Interace /
USBx->GUSBCFG &= ~ USB_OTG_GUSBCFG_ULPI_UTMI_SEL;
USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;
/
Enables control of a High Speed USB PHY /
USB_HS_PHYCInit(USBx);
#elif defined(OTG_HS_EXTERNAL_PHY)
// Init external phy
__HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE();
USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
/
Init The ULPI Interface /
USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
/
Select vbus source */
USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
#endif

#if defined(ENABLE_VBUS_DETECT)
USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
#endif
/* Reset after a PHY select */
Wait_CoreReset(USBx);
}
#endif // defined(OTG_HS_EXTERNAL_PHY) || defined(OTG_HS_EMBEDDED_PHY)

#if defined(OTG_HS_ENABLE_DMA)
if(GetUSB(core) == USB_OTG_HS){
// only HS core has DMA feature
USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
}
#endif
}

//for STM32F723 HS only
void tusb_open_device(tusb_device_t* dev)
{
USB_OTG_GlobalTypeDef* USBx = GetUSB(dev);

/* Initialize low level driver */
GPIO_InitTypeDef GPIO_InitStruct = {0};

__HAL_RCC_GPIOB_CLK_ENABLE();
/**USB_OTG_HS GPIO Configuration
PB14 ------> USB_OTG_HS_DM
PB15 ------> USB_OTG_HS_DP
*/
GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* Peripheral clock enable */
__HAL_RCC_OTGPHYC_CLK_ENABLE();
__HAL_RCC_USB_OTG_HS_CLK_ENABLE();
__HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE();

/* Peripheral interrupt init */
HAL_NVIC_SetPriority(OTG_HS_EP1_OUT_IRQn, 3, 0);
HAL_NVIC_EnableIRQ(OTG_HS_EP1_OUT_IRQn);
HAL_NVIC_SetPriority(OTG_HS_EP1_IN_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(OTG_HS_EP1_IN_IRQn);
HAL_NVIC_SetPriority(OTG_HS_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(OTG_HS_IRQn);

//USB_DisableGlobalInt(???)
USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;

USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);

/* Init The UTMI Interface */
USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);

/* Select vbus source */
USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);

/* Select UTMI Interace */
USBx->GUSBCFG &= ~ USB_OTG_GUSBCFG_ULPI_UTMI_SEL;
USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;

USB_HS_PHYCInit(USBx);

/* Reset after a PHY select */
Wait_CoreReset(USBx);

#if defined(OTG_HS_ENABLE_DMA)
// only HS core has DMA feature
USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
#endif //#if defined(OTG_HS_ENABLE_DMA)

USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
HAL_Delay(50U);

/* Deactivate VBUS Sensing B */
USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;

/* B-peripheral session valid override enable */
USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;

/* Restart the Phy Clock */
USBx_PCGCCTL = 0U;

/* Device mode configuration */
USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80;
USBx_DEVICE->DCFG &= ~((uint32_t) 3U ); //High-speed

/* Clear all pending Device Interrupts */
USBx_DEVICE->DIEPMSK = 0U;
USBx_DEVICE->DOEPMSK = 0U;
USBx_DEVICE->DAINTMSK = 0U;

USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);

USBx_DEVICE->DTHRCTL = USB_OTG_DTHRCTL_TXTHRLEN_6 |
USB_OTG_DTHRCTL_RXTHRLEN_6;

USBx_DEVICE->DTHRCTL |= USB_OTG_DTHRCTL_RXTHREN |
USB_OTG_DTHRCTL_ISOTHREN |
USB_OTG_DTHRCTL_NONISOTHREN;

/* Disable all interrupts. */
USBx->GINTMSK = 0U;

/* Clear any pending interrupts */
USBx->GINTSTS = 0xBFFFFFFFU;

/* Enable the common interrupts */
USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;

/* Enable interrupts matching to the Device mode ONLY */
USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |
USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |
USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM |
USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;

USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;

//HAL_PCDEx_ActivateLPM
USBx->GINTMSK |= USB_OTG_GINTMSK_LPMINTM;
USBx->GLPMCFG |= (USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL);

//USB_DevDisconnect
USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
HAL_Delay(3U);

// (void)USB_DevConnect(hpcd->Instance);
USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
HAL_Delay(3U);

// __HAL_PCD_ENABLE(hpcd)
// (void)USB_EnableGlobalInt ((HANDLE)->Instance)
USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
HAL_Delay(50);

tusb_init_otg_device(dev);
}

针对STM32F1系列的PMA自动分配计算方法有误

(1)针对STM32F1系列处理器,一个端点的缓冲区配置表项里,每个成员之间有2个字节的填充占位,所以,每个端点的缓冲区配置表项大小应该为16字节。代码中tusb_dev_drv_setup_endpoint函数里面,bt_start的计算中,固定将端点数乘以8,显然是无法兼容F1系列处理器的。考虑到stm32_fs_platform.h中为不同处理器定义了不同的pma_ep_desc结构体来描述一个缓冲区配置表项。所以,bt_start的算式中将8修改为sizeof(pma_ep_desc)更合理。
(2)tusb_dev_drv_setup_endpoint函数里面采用的自动端点配置策略,是依据现行激活的Interface来按需配置端点的。在bt_start的计算中,引用到的局部变量max_ep_id是已激活的Interface中最大的端点编号。注意其中,当端点号为0,且is_reset为假时,端点0的pma项并不会得到更新。在代码中,默认的SetInterface处理代码调用了tusb_init_endpoint_by_config用于配置新Interface的端点,tusb_init_endpoint_by_config调用tusb_dev_drv_setup_endpoint时,is_reset参数传递了0。也就是说,SetInterface时是不会重新配置端点0的pma的。所以,如果我们实现的设备有两个Interface,且非默认的Interface(1)使用到了更大的端点编号时,当设备初启动的时候,端点0的pma并没有考虑给Interface(1)端点预留空间,当切换到Interface(1)时,端点0的pma也没有更新,那么端点0的缓冲就会和Interface(1)的端点pma配置项相互冲突。我采用了一个简单的修改,将bt_start计算时的缓冲区配置表项的保留数量,固定按照TUSB_MAX_EP_PAIR_COUNT来计算。

最终修改代码如下:
int tusb_dev_drv_setup_endpoint(...) { ... uint32_t bt_start = TUSB_MAX_EP_PAIR_COUNT * sizeof(pma_ep_desc); ... }

该问题在我实现UVC设备时发现。若不做以上修改,则要么UVC会发送出不可预期的数据,要么程序会陷入HardFault异常。经过以上修改后,UVC设备方可正常工作。

虚拟串口参数改变问题,目前无法更改转到实际的串口发出

现在看到这一段:

void cdc_line_coding_change(tusb_cdc_device_t *cdc) { // TODO, handle the line coding change //cdc->line_coding.bitrate; //cdc->line_coding.databits; //cdc->line_coding.stopbits; //cdc->line_coding.parity; }
这一段是用来改串口的波特率的吗,现在发现这个函数好像没用,我想更改波特率的时候,STM32端能够收到并且重新初始化串口用来做USB转串口

ch569

Hello! This project is great! But iI ca not gget the ch56x to work. Its very possible its my makefile etc especially was t sure on boards.mk I coukdnt ffind a makefile for the ch56x any chance you have a working one? Any chance you hhave ssome old ccode for them as well you miggt be willing to share? Any and all info/code/makefiles woukd be super appreciated. Thank you sir.

[Question]关于tusb_pipe_wait的NAK返回

你好,我最近在实现一个特定的USB HOST Vendor Class,用的FS,里面需要不停地尝试接收Bulk EP的数据,同时有需求时也需要发送数据。
我在使用tusb_pipe_wait的时候,超时无限的情况下,好像不会返回NAK状态。
怎么修改才能让其返回NAK状态呢?我这里测试是会无限等待下去。
或者关于实现这个是否有更好的思路呢?我是一个USB方面的菜鸟。
谢谢。

USBDevice模式下SETUP在线程模式中处理无法发包

主机使用CTRL-TRANSFER来获取数据的时候
如果不在SETUP回调函数(class-handler)中立即发送数据
而转到线程中再调用tusb_control_send,则主机无法收到发送的数据
用wireshark抓包,返回的包长度为0字节

比如:HID-GET-REPORT
如果在SETUP中断中立即调用tusb_control_send发送数据,则主机收到正确数据
如果转发到线程模式,在线程中调用tusb_control_send,则主机收到0字节包

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.