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
#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();
}发布于 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位启用了成功的连接握手。
https://stackoverflow.com/questions/47087858
复制相似问题