Skip to main content
Visitor II
May 26, 2021
Question

STM32H7 as USB audio device, with external PHY, USB3343, ULPI

  • May 26, 2021
  • 7 replies
  • 8701 views

I'm stuck ... on a number of levels, I believe, but first things first.

I have a custom PCB with a "main" 144-pin STMH743, six "DSP" 100-pin STMH743s, and a USB3343 to speak ULPI to a USB port.

Via SAI, the main H7 will be getting 10 to 12 channels of digital audio, two from each of the 5 to 6 DSP H7s.

The 10 to 12 channels of audio are to be sent via USB out to a host; e.g., a DAW running on a computer.

My current obstacle, one I need to get past before dealing with how to "package" up the digital audio to trasmit to the host, is to configure the main MCU's USB to use the ULPI chip and ... have the host even detect/recognize the STM32H7, running as a USB Audio Device.

I am using CubeMX for pretty much everything.

Under Connectivity, I have USB_OTG_HS chosen and configured as External PHY, Device_Only. The Parameter Settings show Speed: Device High Speed 480MBit/s; Physical interface: External Phy.

Under Middleware, I have USB_Device chosen and configured as Class For HS IP: Audio Device Class.

The CubeMX-generated main.c calls MX_USB_DEVICE_Init() which in turn calls USBD_Init(), USBD_RegisterClass(), USBD_AUDIO_RegisterInterface(), USBD_Start(), and HAL_PWREx_EnableUSBVoltageDetector().

From there the program continues runnning through the endless while, but when I connect the PCBs USB port to my Macbook Pro, no USB device is dectect.

Should I assume that I have need to do something after MX_USB_DEVICE_Init? I see that ST's demo program for USB_Device/Audio_Standalone goes to the endless while immediately after it calls the same functions MX_USB_DEVICE_Init does.

Using CubeMX to configure a simple test program, I have gotten a VCP working on a NUCLEO-H743ZI. Of course that was not with ULPI but my Mac certainly recognized the STM32 as USB device. I fully expect setting up and running an Audio Class device to be rather more complex.

I figure that after MX_USB_DEVICE_Init, the device should be visible to a host, but perhaps I'm missing something. I will later have questions about just how one sends all that audio, but first I have to figure out whatever handshaking I need, right? Does anyone have any suggestions on what I might try next?

Thanks.

    This topic has been closed for replies.

    7 replies

    Visitor II
    May 27, 2021

    Hi @APagl​ ,

    Can you please recheck the Pinouts of your ULPI , if they are well connected ?

    You can refer for example to the usbd_conf.c file of the HID_Standalone application in HS mode. Here how the ULPI pins are configured in HS mode for the STM32H743I_EVAL board:

    if (hpcd->Instance == USB1_OTG_HS)
     {
     /* Configure USB HS GPIOs */
     __GPIOA_CLK_ENABLE();
     __GPIOB_CLK_ENABLE();
     __GPIOC_CLK_ENABLE();
     __GPIOH_CLK_ENABLE();
     __GPIOI_CLK_ENABLE();
     
     /* CLK */
     GPIO_InitStruct.Pin = GPIO_PIN_5;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
     GPIO_InitStruct.Alternate = GPIO_AF10_OTG1_HS;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
     
     /* D0 */
     GPIO_InitStruct.Pin = GPIO_PIN_3;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
     GPIO_InitStruct.Alternate = GPIO_AF10_OTG1_HS;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
     
     /* D1 D2 D3 D4 D5 D6 D7 */
     GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_5 |
     GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Alternate = GPIO_AF10_OTG1_HS;
     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
     
     /* STP */
     GPIO_InitStruct.Pin = GPIO_PIN_0;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Alternate = GPIO_AF10_OTG1_HS;
     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
     
     /* NXT */
     GPIO_InitStruct.Pin = GPIO_PIN_4;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Alternate = GPIO_AF10_OTG1_HS;
     HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
     
     /* DIR */
     GPIO_InitStruct.Pin = GPIO_PIN_11;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Alternate = GPIO_AF10_OTG1_HS;
     HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
     __HAL_RCC_USB1_OTG_HS_ULPI_CLK_ENABLE();
     
     /* Enable USB HS Clocks */
     __HAL_RCC_USB1_OTG_HS_CLK_ENABLE();
     
     /* Set USBHS Interrupt to the lowest priority */
     HAL_NVIC_SetPriority(OTG_HS_IRQn, 1, 0);
     
     /* Enable USBHS Interrupt */
     HAL_NVIC_EnableIRQ(OTG_HS_IRQn);
     }

    Best Regards,

    Ons.

    APaglAuthor
    Visitor II
    May 27, 2021

    Thanks very much.

    I have checked the ULPI pin outs. Evidently via CubeMX, my pins, assigned by default are all the same except for DIR and NXT, which are on pins PC2_C and PC3_C respectively (as opposed to what looks like PI11 and PH4 in the usbd_conf.c you provided). Seems like a minor difference, but in any case, as I say they were assigned by default by CubeMX. See generated code below.

    The only other differences I notice are that in the file you show:

    1) CLK and D0 are set as GPIO_SPEED_FREQ_VERY_HIGH. In my CubeMX-generated file, all pins are GPIO_SPEED_FREQ_HIGH.

    2) Your file: HAL_NVIC_SetPriority(OTG_HS_IRQn, 1, 0). My file: HAL_NVIC_SetPriority(OTG_HS_IRQn, 0, 0);

    I don't see where in CubeMX, I might have the option to change the GPIO frequencies. And, the priority shown for the NVIC is ghosted out.

    And, still no recognition of the USB connection by the Mac.

    Ever hopeful, ....

    void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle)
    {
     GPIO_InitTypeDef GPIO_InitStruct = {0};
     if(pcdHandle->Instance==USB_OTG_HS)
     {
     /* USER CODE BEGIN USB_OTG_HS_MspInit 0 */
     
     /* USER CODE END USB_OTG_HS_MspInit 0 */
     
     __HAL_RCC_GPIOC_CLK_ENABLE();
     __HAL_RCC_GPIOA_CLK_ENABLE();
     __HAL_RCC_GPIOB_CLK_ENABLE();
     /**USB_OTG_HS GPIO Configuration 
     PC0 ------> USB_OTG_HS_ULPI_STP
     PC2_C ------> USB_OTG_HS_ULPI_DIR
     PC3_C ------> USB_OTG_HS_ULPI_NXT
     PA3 ------> USB_OTG_HS_ULPI_D0
     PA5 ------> USB_OTG_HS_ULPI_CK
     PB0 ------> USB_OTG_HS_ULPI_D1
     PB1 ------> USB_OTG_HS_ULPI_D2
     PB10 ------> USB_OTG_HS_ULPI_D3
     PB11 ------> USB_OTG_HS_ULPI_D4
     PB12 ------> USB_OTG_HS_ULPI_D5
     PB13 ------> USB_OTG_HS_ULPI_D6
     PB5 ------> USB_OTG_HS_ULPI_D7 
     */
     GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_3;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
     GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS;
     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
     
     GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_5;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
     GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
     
     GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_10|GPIO_PIN_11 
     |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_5;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
     GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS;
     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
     
     /* Peripheral clock enable */
     __HAL_RCC_USB_OTG_HS_CLK_ENABLE();
     __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE();
     
     /* Peripheral interrupt init */
     HAL_NVIC_SetPriority(OTG_HS_IRQn, 0, 0);
     HAL_NVIC_EnableIRQ(OTG_HS_IRQn);
     /* USER CODE BEGIN USB_OTG_HS_MspInit 1 */
     
     /* USER CODE END USB_OTG_HS_MspInit 1 */
     }
    }

    Visitor II
    May 28, 2021

    Hi @APagl​ ,

    Can you please share with me your usbd_conf.c and usbd_conf.h files? Rather your .ioc file, maybe.

    Best Regards,

    Ons

    APaglAuthor
    Visitor II
    May 30, 2021
    Here are the three files.

    Thanks,
    Alan
    APaglAuthor
    Visitor II
    May 31, 2021

    I am sending page 1 (with the 144-pin H7) and page 3 (with the USB3343 ULPI), out of a total of 11 pages (most of the others are other 100-pin H7s which do DSP, codecs, power management, ten HE sensor inputs to ADCs, and so on)..

    I believe that will be enough. But do let me know if these are not enough to troubleshoot the ULPI issues.

    You will note that in the schematic the ULPI's pin 12 (DATA7) is routed to the H7's PB6, when in fact PB5 is configured via CubeMX as USB_OTG_HS_ULPI_D7 (PB6 cannot be configured for the ULPI). Of course, PB6 is an incorrect routing, which will be physically corrected in the next PCB iteration.

    However, for now as a workaround on this board, the Control H7's pins PB6 and PB5 have been carefully bridged and PB6 is set, in CubeMX, to GPIO mode Input, to more or less have the H7 ignore it.

    I've checked continuity on all the ULPI pins and their corresponding H7 pins.

    As for versions, I am using:

    STM32Cube_FW_H7_V1.5.0

    STM32CubeMX 5.4.0

    SystemWorkbench 4.6.3 (I have not converted my programs ... yet ... to the full-fledged STM32CubeIDE).

    Thanks again.

    APaglAuthor
    Visitor II
    June 8, 2021

    Hello,

    I'm hoping that the schematic and the versions of the different tools has helped track things down.

    Also, I inquired with Microchip, maker of the USB3343 ULPI, and they suggested ... of course ... that I talk to you at ST ;) They did say, "Now, the ULPI communication is handled by the link controller, so ULPI libraries and code should be available in the USB stack of the SoC or microcontroller your are using. As ULPI is a standard communication interface, USB3343 doesn't require any special libraries. Also, Microchip does not have an application example available that would demonstrate an elegant solution for this application. I would recommend researching the controller side USB stack, forums and support for more information."

    I know that ST has libraries for STM32 USB, but I don't know that I've seen anything specifically about ULPI. And I don't think I've see sample code specifically for the MCU to be an audio USB device for streaming multiple channels (and, more specifically, more than two channels) of audio.

    Thanks.

    Visitor II
    February 13, 2022

    Hi,

    Did you find solution?

    APaglAuthor
    Visitor II
    February 13, 2022

    No. I'm afraid not.

    I have been working on a few other aspects of my project where I am able to make progress.

    Still nothing on the ULPI via STM32 front.

    APaglAuthor
    Visitor II
    July 9, 2022

    Any ideas?