cancel
Showing results for 
Search instead for 
Did you mean: 

Using STM32F429I-Discovery as USB OTG MSC

michel
Associate II
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
14 REPLIES 14
Posted on August 01, 2014 at 19:23

int8_t STORAGE_Write (uint8_t lun, 
uint8_t *buf, 
uint32_t blk_addr,
uint16_t blk_len)
{
memcpy((void *)(0xD0000000 + (0x200 * blk_addr)), buf, (0x200 * blk_len));
return(whatever);
}
int8_t STORAGE_Read (uint8_t lun, 
uint8_t *buf, 
uint32_t blk_addr,
uint16_t blk_len)
{
memcpy(buf, (void *)(0xD0000000 + (0x200 * blk_addr)), (0x200 * blk_len));
return(whatever);
}

Probably no examples, cause it's trivial. In reality you'd want to range check the inputs, and return success or failure codes as required. Look at what template you have now.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
michel
Associate II
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;

}

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
Up vote any posts that you find helpful, it shows what's working..
michel
Associate II
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
Associate
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