首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >STM32F7发现- USB主机/设备模式检测

STM32F7发现- USB主机/设备模式检测
EN

Stack Overflow用户
提问于 2017-11-03 03:04:47
回答 1查看 3.4K关注 0票数 1

STM32F723IEK6发现板有一个全速的USB接口。我试图初始化它是徒劳的。没有从主机接收重置信号,也没有设置适当的中断标志。

FS接口是OTG。它应该检测VBUS电压和ID引脚的状态,以确定它是作为主机连接还是作为设备连接。在设备模式中,主机应提供VBUS,ID引脚应断开并拉高。当设备检测到连接时,它应该拔出DP引脚来指示与主机的连接。然后主机通过将数据线拉低发送复位信号。这就是理论。

看来董事会没有拉高DP线。在启用VBUS检测的默认OTG配置(如下面的程序)中,GINTSTS寄存器中始终只设置CIDSCHG (ID更改)、SRQINT (session)和SOF位。CMOD位为零,指示设备模式。ID线似乎很低,即使电缆没有连接。

我在AF 10模式下配置适当的引脚(A9、A10、A11、A12)。然而,这可能是不必要的,因为FS PHY似乎是直接连接到引脚,绕过GPIO复用器(不确定)。

我尝试过强制设备模式和禁用VBUS检测,但这没有造成任何影响,以及从GPIO中提取ID行。

我以前在STM32F4板上运行了相同的代码,没有这样的问题。

我想了解为什么连接检测不起作用。

代码如下,抱歉,它有时钟、GPIO和USB初始化代码,省略了一些辅助功能。

STM32F72x参考手册(15 manual!) manual/dm00305990.pdf

数据表http://www.st.com/resource/en/datasheet/DM00330506.pdf

板手册manual/dm00342318.pdf

代码语言:javascript
复制
#include "stm32f7xx.h"

#define PLL_M 25
#define PLL_N 336
#define PLL_P 0
#define PLL_Q 7
#define SYS_FREQ 168000000

void rcc_config(void)
{
    RCC->APB1ENR |= RCC_APB1ENR_PWREN;
    PWR->CR1 = (PWR->CR1 & ~PWR_CR1_VOS_Msk)
            | PWR_CR1_VOS_1;
    RCC->CR |= RCC_CR_HSEON;
    while ((RCC->CR & RCC_CR_HSERDY) == 0);
    RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (PLL_P << 16) | RCC_PLLCFGR_PLLSRC_HSE | (PLL_Q << 24);
    RCC->CR |= RCC_CR_PLLON;
    RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_HPRE_Msk | RCC_CFGR_PPRE1_Msk | RCC_CFGR_PPRE2_Msk))
            | RCC_CFGR_HPRE_DIV1
            | RCC_CFGR_PPRE2_DIV2
            | RCC_CFGR_PPRE1_DIV4;
    FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ARTEN | FLASH_ACR_LATENCY_5WS;
    while ((RCC->CR & RCC_CR_PLLRDY) == 0);
    while ((PWR->CSR1 & PWR_CSR1_VOSRDY) == 0);
    RCC->CFGR &= RCC_CFGR_SW;
    RCC->CFGR |= RCC_CFGR_SW_PLL;
    while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
}

#define GPIO_OTYPE_PP 0
#define GPIO_OTYPE_OD 1
#define GPIO_PULLUP   1

void gpio_config_mode(GPIO_TypeDef* gpio, unsigned pin, unsigned mode)
{
    gpio->MODER = (gpio->MODER & ~(3u << (2 * pin))) | (mode << (2 * pin));
}
void gpio_config_in(GPIO_TypeDef* gpio, unsigned pin)
{
    gpio_config_mode(gpio, pin, 0);
}
void gpio_config_out(GPIO_TypeDef* gpio, unsigned pin, unsigned otype, unsigned ospeed)
{
    gpio_config_mode(gpio, pin, 1);
    gpio->OTYPER  = (gpio->OTYPER  & ~(1u << (1 * pin))) | (otype  << (1 * pin));
    gpio->OSPEEDR = (gpio->OSPEEDR & ~(3u << (2 * pin))) | (ospeed << (2 * pin));
}
void gpio_config_af(GPIO_TypeDef* gpio, unsigned pin, unsigned af)
{
    gpio_config_mode(gpio, pin, 2);
    unsigned pin_group = pin >> 3;
    unsigned pin_offset = pin & 7;
    gpio->AFR[pin_group] = (gpio->AFR[pin_group] & ~(0xf << (pin_offset * 4)))
            | (af << (pin_offset * 4));
}
void gpio_config_pullup(GPIO_TypeDef* gpio, unsigned pin, unsigned pupd)
{
    gpio->PUPDR = (gpio->PUPDR   & ~(3u << (2 * pin))) | (pupd   << (2 * pin));
}

USB_OTG_GlobalTypeDef *usb = USB_OTG_FS;
USB_OTG_DeviceTypeDef *usb_dev = (USB_OTG_DeviceTypeDef *)(USB_OTG_FS_PERIPH_BASE + USB_OTG_DEVICE_BASE);

void usb_config(void)
{
    /* The application must program this register before starting any transactions
     * on either the AHB or the USB. Do not make changes to this register after
     * the initial programming. */
    usb->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; // TODO: no effect for F7, read-only bit
//  usb->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
    /* After setting the force bit, the application must wait at least * 25 ms
     * before the change takes effect. */
    delay_ms(25);

    // USB core reset
    while ((usb->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0);
    usb->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
    while ((usb->GRSTCTL & USB_OTG_GRSTCTL_CSRST) != 0);
    delay_us(1); // actually, 3 PHY clocks

    usb_dev->DCFG = USB_OTG_DCFG_DSPD_0 | USB_OTG_DCFG_DSPD_1; // full speed
//  usb->GAHBCFG = 0;
//  usb->PCGCTL = 0;
    usb->GCCFG |= USB_OTG_GCCFG_VBDEN; // VBUS detection
    usb->GCCFG |= USB_OTG_GCCFG_PWRDWN; // enable PHY

/// usb->GINTSTS= 0xFFFFFFFF;
//  usb->GINTMSK = 0;
//  usb->GINTSTS = 0xFFFFFFFF;
//  usb->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
}

void usb_poll(void)
{
    uint32_t intsts = usb->GINTSTS;
    if (intsts & USB_OTG_GINTSTS_USBRST)
        usb->GINTSTS = USB_OTG_GINTSTS_USBRST;
    if (intsts & USB_OTG_GINTSTS_RSTDET)
        usb->GINTSTS = USB_OTG_GINTSTS_RSTDET;
    if (intsts & USB_OTG_GINTSTS_ENUMDNE)
        usb->GINTSTS = USB_OTG_GINTSTS_ENUMDNE;
    if (intsts & USB_OTG_GINTSTS_CIDSCHG)
        usb->GINTSTS = USB_OTG_GINTSTS_CIDSCHG;
    if (intsts & USB_OTG_GINTSTS_SRQINT)
        usb->GINTSTS = USB_OTG_GINTSTS_SRQINT;
}

#define LED_PIN 5
#define USB_AF 10

int main()
{
    rcc_config();

    SysTick->LOAD = 0xffffffu;
    SysTick->VAL = 0;
    SysTick->CTRL = 5;

    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
    gpio_config_out(GPIOA, LED_PIN, GPIO_OTYPE_PP, 0);
    gpio_config_af(GPIOA,  9, USB_AF); // VBUS_DET
    gpio_config_af(GPIOA, 10, USB_AF); // ID
    gpio_config_af(GPIOA, 11, USB_AF); // DM
    gpio_config_af(GPIOA, 12, USB_AF); // DP

    RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
    usb_config();
    while (1)
        usb_poll();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-03 15:44:21

当然了。

OTG_FS_DCTL寄存器:

第1位 SDIS: 软断开应用程序使用此位来向USB核心发送信号以执行软断开。只要设置了此位,主机就不会看到设备已经连接,并且设备也不会在USB上接收信号。核心处于断开状态,直到应用程序清除此位。正常操作。当软断开后清除此位时,核心将生成设备连接事件到USB主机。当设备重新连接时,USB主机重新启动设备枚举。1:核心产生一个设备断开事件到USB主机。

来自STM32F411手册:

重置值: 0x0000

来自STM32F723手册:

重置值: 0x0000 0002

除非应用程序修改重置值,否则STM32F7 USB块将在“软断开”状态下启动,而STM32F4则在检测到VBUS时尝试立即连接。文件(例如第32.6.2节外围状态)根本没有提到这一事实。

在我的示例中,清除SDIS位启用了成功的连接握手。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47087858

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档