2017-11-03 32 views
0

STM32F723IEK6ディスカバリ・ボードはフルスピードUSBインタフェースを備えています。私は無駄にそれを初期化しようとしています。リセット信号は決してホストから受信されず、適切な割り込みフラグはセットされない。STM32F7ディスカバリ - USB FSホスト/デバイス・モード検出

FSインターフェイスはOTGです。 VBUS電圧とIDピンの状態を検出して、ホストまたはデバイスとして接続されているかどうかを判断します。デバイスモードではVBUSをホストから供給し、IDピンを切断してHIGHにします。デバイスが接続を検出すると、DPピンをプルしてホストへの接続を示す必要があります。次に、ホストは、データラインをローに引き下げることによってRESET信号を送信します。これが理論です。

ボードがDPラインを引き上げないようです。 VBUS検出が有効になっているデフォルトのOTG構成(以下のプログラム)では、CIDSCHG(ID変更)、SRQINT(セッション)、およびSOFビットのみがGINTSTSレジスタに設定されます。 CMODビットはゼロであり、デバイスモードを示す。ケーブルが接続されていなくても、IDラインは低く見えます。

AF10モード(OTG FS)で適切なピン(A9、A10、A11、A12)を構成します。しかし、FS PHYはGPIOマルチプレクサ(わからない)をバイパスしてピンに直接接続されているように見えるため、これは不要です。

私はデバイスモードを強制してVBUS検出を無効にしようとしましたが、GPIOからIDラインを引き上げるだけでなく、効果もありませんでした。

以前は同じコードをSTM32F4ボード上で実行していましたが、そのような問題はありませんでした。

なぜ接続検出が機能しないのか理解したいと思います。

コードは以下のとおりです。クロック、GPIO、USB初期化コードがありますが、いくつかの補助機能は省略されています。

STM32F72xリファレンスマニュアル(15メガバイト!)http://www.st.com/resource/en/reference_manual/dm00305990.pdf

データシートhttp://www.st.com/resource/en/datasheet/DM00330506.pdf

ボードマニュアルもちろんhttp://www.st.com/resource/en/user_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(); 
} 

答えて

0

登録OTG_FS_DCTL:

ビット1

SDIS:

ソフト、アプリケーションソフト切断を実行する のUSB OTGコアを知らせるために、このビットを使用して切断します。このビットが である限り、ホストはデバイスが接続されていることを認識せず、 デバイスはUSB上で信号を受信しません。アプリケーションがこのビットをクリアするまで、コアは切断された状態の にとどまります。 0:正常 操作です。ソフト切断後にこのビットがクリアされると、コア はUSBホストへのデバイス接続イベントを生成します。デバイスが に再接続されると、USBホストはデバイスの列挙を再開します。 1:コア は、USBホストへのデバイス切断イベントを生成します。STM32F723マニュアルから0000 0000

リセット値:STM32F411マニュアルから

リセット値:0000 0002

リセット値がアプリケーションによって変更されない限り、STM32F7 USBブロックは「ソフト・ディスコネクト」状態で開始し、STM32F4はVBUSの検出時に直ちに接続を試みます。ドキュメント(32.6.2周辺機器状態など)には、この事実はまったく言及されていません。

私の場合、SDISビットをクリアすると接続ハンドシェイクが成功しました。

関連する問題