Skip to main content
michel
Associate
July 25, 2014
Question

Using STM32F429I-Discovery as USB OTG MSC

  • July 25, 2014
  • 14 replies
  • 4028 views
Posted on July 25, 2014 at 18:29

Hi

My company wants to evaluate the STM32F429I-Discovery kit and its functions.

One of the applications I have to develop will consist in using the board itself as a USB OTG Mass Storage Class, so that I can transfer files and data from my PC to its internal memory.

I did the job, using the examples provided by the STM32F4Cube. I work with the Keil MDK-ARM.

ST-Link V2 driver installed and working fine. I can program and debug the card.

But my problem is that when connecting the board to my PC (Windows 8 installed), it is not recognized.

In the Device Manager it appears as a ''unknown device'' with error ''Windows has stopped this device because it has reported problems. (Code 43)''.

In the properties the events say:

Device USB\VID_0000&PID_0002\6&7e58c76&0&1 had a problem starting.

But I had filled the device description structure with:

__ALIGN_BEGIN uint8_t USBD_HS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =

  {

    0x12,                       /*bLength */

    0x01,       /*bDescriptorType*/

    0x00,                       /*bcdUSB */

    0x02,

    0x00,                       /*bDeviceClass*/

    0x00,                       /*bDeviceSubClass*/

    0x00,                       /*bDeviceProtocol*/

    0x40,          /*bMaxPacketSize*/

    0x83,           /*idVendor*/

    0x04,           /*idVendor*/

    0x2A,           /*idVendor*/

    0x57,           /*idVendor*/

    0x00,                       /*bcdDevice rel. 2.00*/

    0x02,

    0x01,           /*Index of manufacturer  string*/

    0x02,       /*Index of product string*/

    0x03,        /*Index of serial number string*/

    0x01  /*bNumConfigurations*/

  } ; 

I tried to reconfigure the GPIO (pin, pull, mode...) ,timers,, etc... now my PC sees the board as a ''USB Mass Storage device'' but produces the following status:

''This device cannot start. (Code 10)''

and event details:

Device USB\VID_0483&PID_572A\00000000001A had a problem starting.

Driver Name: usbstor.inf

Class GUID: {36FC9E60-C465-11CF-8056-444553540000}

Service: USBSTOR

Lower Filters: 

Upper Filters: 

Problem: 0xA

Status: 0x0

So I can't find exactly what I have to program and configure.

Which GPIO should I use and which configuration ?

What about the system clock ? Should I use the RCC HSE ?

What about the NVIC ?

How do I configure the SDRAM ?

As you see I am quite lost. I tried to use the STM32CubeMX but this does not help a lot.

Has someone already worked on this type of project ?

Is it really possible to use the STM32F429I-Discovery itself as a USB OTG MSC ?

If I could have technical tips and even some examples, that would be great.

Thanks in advance for your help

#stm32f4-usb #msc
This topic has been closed for replies.

14 replies

michel
michelAuthor
Associate
August 6, 2014
Posted on August 06, 2014 at 19:00

Well, I had already done something similar but I can't go further.

Whe I try to access it from my Windows Explorer, I receive continuous interruptions in:

void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)

In this function there is a test to see if the USB is in device mode:

  /* ensure that we are in device mode */

  if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)

  ...

Function is coded as:

uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx)

{

  return ((USBx->GINTSTS ) & 0x1);

} 

When debugging I see that hpcd->Instance = 0x0 and this GINTSTS is set to 0x080004DD

So USB_GetMode() returns 1 instead of 0

But I have configured USB as OTG device in my usb_conf.c.

I did this using examples from the STM32CubeF4 and STM specifications.

So I have a doubt concerning my config.

For using the Discovery board as a USB device Mass Storage, do you know what is exactly the configuration to use ?

Which GPIO do I have to use and with which config ?

Here is what I have:

void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd)

{

  GPIO_InitTypeDef GPIO_InitStruct;

  if(hpcd->Instance==USB_OTG_FS)

  {  

    /**USB_OTG_FS GPIO Configuration    

    PA9     ------> USB_OTG_FS_VBUS

    PA11     ------> USB_OTG_FS_DM

    PA12     ------> USB_OTG_FS_DP 

    */

    GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; /*GPIO_SPEED_LOW*/

    GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_9;

    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* Peripheral clock enable */

    /* Enable USB FS Clocks */

    __USB_OTG_FS_CLK_ENABLE();

    /* Peripheral interrupt init*/

    /* Sets the priority grouping field */

    HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

    HAL_NVIC_SetPriority(OTG_FS_IRQn, 7, 0);

    HAL_NVIC_EnableIRQ(OTG_FS_IRQn);

  }

  else if(hpcd->Instance==USB_OTG_HS)

  { 

  /* Peripheral clock enable */

    __USB_OTG_HS_CLK_ENABLE();

    /**USB_OTG_HS GPIO Configuration    

    PB12     ------> USB_OTG_HS_ID

    PB13     ------> USB_OTG_HS_VBUS

    PB14     ------> USB_OTG_HS_DM

    PB15     ------> USB_OTG_HS_DP 

    */

    GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_15;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;

    GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 

    GPIO_InitStruct.Pin = GPIO_PIN_13;

    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* Peripheral interrupt init*/

    /* Sets the priority grouping field */

    HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

    HAL_NVIC_SetPriority(OTG_HS_IRQn, 7, 0);

    HAL_NVIC_EnableIRQ(OTG_HS_IRQn);

  }

}

USBD_StatusTypeDef  USBD_LL_Init (USBD_HandleTypeDef *pdev)

{ 

  /* Init USB_IP */

  if (pdev->id == DEVICE_FS) {

  /* Link The driver to the stack */

  hpcd_USB_OTG_FS.pData = pdev;

  pdev->pData = &hpcd_USB_OTG_FS; 

  

  hpcd_USB_OTG_FS.Instance = USB_OTG_FS;

  hpcd_USB_OTG_FS.Init.dev_endpoints = 7;

  hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL;

  hpcd_USB_OTG_FS.Init.dma_enable = DISABLE;

  hpcd_USB_OTG_FS.Init.ep0_mps = DEP0CTL_MPS_64;

  hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED;

  hpcd_USB_OTG_FS.Init.Sof_enable = DISABLE;

  hpcd_USB_OTG_FS.Init.low_power_enable = ENABLE;

  hpcd_USB_OTG_FS.Init.vbus_sensing_enable = ENABLE;

  hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE;

  hpcd_USB_OTG_FS.Init.use_external_vbus = ENABLE;

  HAL_PCD_Init(&hpcd_USB_OTG_FS);

  HAL_PCD_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);

  HAL_PCD_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);

  HAL_PCD_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);

  }

  if (pdev->id == DEVICE_HS) {

  /* Link The driver to the stack */

  hpcd_USB_OTG_HS.pData = pdev;

  pdev->pData = &hpcd_USB_OTG_HS;

  hpcd_USB_OTG_HS.Instance = USB_OTG_HS;

  hpcd_USB_OTG_HS.Init.dev_endpoints = 11;

  hpcd_USB_OTG_HS.Init.speed = PCD_SPEED_FULL;

  hpcd_USB_OTG_HS.Init.dma_enable = ENABLE;

  hpcd_USB_OTG_HS.Init.ep0_mps = DEP0CTL_MPS_64;

  hpcd_USB_OTG_HS.Init.phy_itface = USB_OTG_EMBEDDED_PHY;

  hpcd_USB_OTG_HS.Init.Sof_enable = DISABLE;

  hpcd_USB_OTG_HS.Init.low_power_enable = ENABLE;

  hpcd_USB_OTG_HS.Init.vbus_sensing_enable = DISABLE;

  hpcd_USB_OTG_HS.Init.use_dedicated_ep1 = DISABLE;

  hpcd_USB_OTG_HS.Init.use_external_vbus = DISABLE;

  HAL_PCD_Init(&hpcd_USB_OTG_HS);

  HAL_PCD_SetRxFiFo(&hpcd_USB_OTG_HS, 0x200);

  HAL_PCD_SetTxFiFo(&hpcd_USB_OTG_HS, 0, 0x80);

  HAL_PCD_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x174);

  }

  return USBD_OK;

}

Tesla DeLorean
Guru
August 6, 2014
Posted on August 06, 2014 at 20:33

Attached is the .HEX file from a quick port of my STM32F4-DISCO-SDIO-MSC to STM32F429I-DISCO-SDRAM-MSC, I used the original USB Firmware library (I don't use/support HAL/CUBE) and built it with GNU/GCC (Yagarto 4.7.2)

Updated with a build that retains SDRAM content as long as board is powered.

________________

Attachments :

stm32f429i_discovery_msc_sdram_001.hex : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0ZY&d=%2Fa%2F0X0000000bak%2FJu1jXvNAK_cQunC4R_dApQW6g4rV.c8fZCXnQltP.iA&asPdf=false
Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
michel
michelAuthor
Associate
August 12, 2014
Posted on August 12, 2014 at 16:38

All right, finally I got it. When looking at your hex file, I found that I had a bad serial number.

As I have coded my application to support both FS and HS USB, the real values should have been:

#define USBD_MSC_SERIALNUMBER_STRING_HS     ''000000000001A''

#define USBD_MSC_SERIALNUMBER_STRING_FS     ''000000000001B''

Now it works. I can write and read data to the device connected in MSC mode.

But my problems are not over :)

I have another application for testing the USB in CDC mode. It works.

But now I would like to have one single application to support both MSC AND CDC.

But I have a problem with the descriptors.

Which values should be set ?

Is 000000000001A/000000000001B pair correct for a USB composite ?

I think no, but I don''t know which values should be used.

Do I have to keep the same PID for both MSC and CDC descriptors ?

In stm32f4xx_it.c I have to handle interrupts. 

So I coded this:

void OTG_FS_IRQHandler(void)

{

  HAL_NVIC_ClearPendingIRQ(OTG_FS_IRQn);

  HAL_PCD_IRQHandler(&hpcd_USB_OTG_MSC_FS);

  HAL_PCD_IRQHandler(&hpcd_USB_OTG_CDC_FS);

}

void OTG_HS_IRQHandler(void)

{

  HAL_NVIC_ClearPendingIRQ(OTG_HS_IRQn);

  HAL_PCD_IRQHandler(&hpcd_USB_OTG_MSC_HS);

  HAL_PCD_IRQHandler(&hpcd_USB_OTG_CDC_HS);

}

Do you think this is correct ?

valen
Visitor II
November 17, 2014
Posted on November 17, 2014 at 21:04

Hello michel.j

Just curious if you got it working and if you can share your code.

Thanks,

Valentin