xtoolbox / teenyusb Goto Github PK
View Code? Open in Web Editor NEWLightweight 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
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
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
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处理中,在最后向主机响应了一个字节的数据:
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);
about stm32f405 how to connect two device such as printer using the HOST USB
在复合设备例程中,如果使用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.
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.
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
需要通过电脑读取SD卡中的文件,MCU里面已经挂载了一个fat的文件系统,msc类不再适合。
需要一个mtp的类从文件层面进行文件读写,而不是msc类直接操作SD卡。
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:
TeenyUSB/demo/boards/stm32f407_evk/board.c
Lines 55 to 64 in 303431c
This comment does not reflect the actual pin numbers. Should be UART3 and PC11 and PC10
TeenyUSB/demo/boards/stm32f407_evk/board_config.h
Lines 115 to 121 in 303431c
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
如和编译ch569的demo?是需要用官方那个什么river的开发环境么?
首先感谢楼主付出的努力!
看楼主做了多款开发板的兼容,能否基于cubemx做个移植的说明呢?看了下《USB设备开发指南》还是不清楚怎么把tusb移植到自己的目标板上,真心希望楼主能出个说明资料,谢谢
对应提交: 当前最新提交 9cd8bda (Nov 27, 2020)
对应项目: sample/composite/composite.uvprojx
问题描述:
composite 示例项目的原始程序可正常工作,但修改为只有一个 HID 设备后,在 PC 向设备发送 suspend 和 resume 请求后,第二次 SET_IDLE 请求设备端响应不正常。如果设备插入到了 USB Hub 而不是 Root Hub 上,后续 PC 发送 HID 数据设备端也没有响应。
复现步骤:
附件:
composite_hid_only_modified_files.zip - composite 示例项目修改后的文件
composite_sample_captured_packets.zip - 使用 USB Packet Viewer 工具所抓的包:
由于52840没有USB主机功能,近期某项目用到MAX3421E来做USB Host,NRF52840通过SPI与MAX3421E通讯,但是没有USB Host协议栈.
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.
TeenyUSB/usb_stack/src/teeny_usb_stm32_otg_host.c
Lines 602 to 604 in 303431c
I changed it to this which resolved my issue.
if(HcEpType == HCCHAR_BULK || HcEpType == HCCHAR_INTR){
hc->toggle_out ^= 1U;
}
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.
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!
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.
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.
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, 我试用过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);
}
(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转串口
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.
你好,我最近在实现一个特定的USB HOST Vendor Class,用的FS,里面需要不停地尝试接收Bulk EP的数据,同时有需求时也需要发送数据。
我在使用tusb_pipe_wait的时候,超时无限的情况下,好像不会返回NAK状态。
怎么修改才能让其返回NAK状态呢?我这里测试是会无限等待下去。
或者关于实现这个是否有更好的思路呢?我是一个USB方面的菜鸟。
谢谢。
目前只看的stm32的,有没有TI msp430或者NXP的例子 ?
主机使用CTRL-TRANSFER来获取数据的时候
如果不在SETUP回调函数(class-handler)中立即发送数据
而转到线程中再调用tusb_control_send,则主机无法收到发送的数据
用wireshark抓包,返回的包长度为0字节
比如:HID-GET-REPORT
如果在SETUP中断中立即调用tusb_control_send发送数据,则主机收到正确数据
如果转发到线程模式,在线程中调用tusb_control_send,则主机收到0字节包
hi, I found MDK-ARM project inside demo/host folder failed to compile.
maybe you forgot to add tusbh_cdc_acm.c and tusbh_cdc_rdnis.c into usb_host group.
是否能添加只依赖寄存器的版本,这样通用性更强。
我用了HID+CDC+MSC复合设备后,可以在PC端正常读写W25Q32,但是怎么样都无法挂载fatfs到W25Q32上
I want to test usb MSC test application. How can i access it .
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.