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 July 25, 2014 at 18:43

Built and posted MSC examples for the original STM32F4-DISCO using an MicroSD card (hand wired one and STM32F4-DIS-BB). Used original USB library.

Haven't done with STM32F429I-DISCO (done a VCP one), but could see using the 8 MB SDRAM as a RAM-DISK type implementation. Yes, would need to initialize the SDRAM pins, controller and chip. Yes, you'd want to use HSE, required for USB specs, and you'd need to run at 168 MHz, not 180 MHz, because you need a 48 MHz clock source.
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 July 29, 2014 at 19:14

Hi Clive

Thanks for the quick answer.

Following you recommendation, I have modified my project.

Unfortunately my PC still does not recognize the Discovery card when connecting the micro-USB.

Moreover, now the callback that returns the Device Descriptor structure (coded usbd_desc.c) is not called anymore.

I did not change it:

uint8_t * USBD_HS_DeviceDescriptor( USBD_SpeedTypeDef speed , uint16_t *length)

{

*length = sizeof(USBD_HS_DeviceDesc);

return USBD_HS_DeviceDesc;

}

I can see that the HAL_PCD_IRQHandler() is called when I plug the USB cable. When debugging with my MDK-ARM IDE, interrupt seems good, but I can see that

the function HAL_PCD_SetupStageCallback coded in usbd_conf.c is never called:

So my application cannot send the right descriptor

I wonder if something is still missing.

Concerning the clock, I have:

#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */

#define HSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSE start up, in ms */

And in system_stm32f4xx.c:

uint32_t SystemCoreClock = 168000000

Attached to my answer is the config I have obtained with STM32CubeMX application.

Could you tell me if something is bad or missing ?

Best regards

________________

Attachments :

my_config.txt : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0R1&d=%2Fa%2F0X0000000bam%2FenWA0Ua06Q9UwlJFS7eqgSKfgwV0eYfAr6N4_bPLXCw&asPdf=false
Posted on July 29, 2014 at 20:02

I'm not offering Cube support.

You'd need to have HSE_VALUE reflect the 8 MHz clock used by the STM32F429I-DISCO, and this would also need to be adjust in the PLL_M settings for the initial divider.

*=============================================================================
* Supported STM32F4xx device revision | Rev A
*-----------------------------------------------------------------------------
* System Clock source | PLL (HSE)
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 168000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 168000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB1 Prescaler | 4
*-----------------------------------------------------------------------------
* APB2 Prescaler | 2
*-----------------------------------------------------------------------------
* HSE Frequency(Hz) | 8000000
*-----------------------------------------------------------------------------
* PLL_M | 8
*-----------------------------------------------------------------------------
* PLL_N | 336
*-----------------------------------------------------------------------------
* PLL_P | 2
*-----------------------------------------------------------------------------
* PLL_Q | 7
*-----------------------------------------------------------------------------
* PLLI2S_N | NA
*-----------------------------------------------------------------------------
* PLLI2S_R | NA
*-----------------------------------------------------------------------------
* I2S input clock | NA
*-----------------------------------------------------------------------------
* VDD(V) | 3.3
*-----------------------------------------------------------------------------
* Main regulator output voltage | Scale1 mode
*-----------------------------------------------------------------------------
* Flash Latency(WS) | 5
*-----------------------------------------------------------------------------
* Prefetch Buffer | OFF
*-----------------------------------------------------------------------------
* Instruction cache | ON
*-----------------------------------------------------------------------------
* Data cache | ON
*-----------------------------------------------------------------------------
* Require 48MHz for USB OTG FS, | Enabled
* SDIO and RNG clock |
*=============================================================================

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 July 30, 2014 at 18:59

Ok, now I have something working.

I think it was not only a problem with the clock, because when I also reduced the MSC_MEDIA_PACKET to 4096 in the usbd_conf.h file, my connection problem was solved.

Now Windows 8 correctly detects the Discovery board as a ''USB Mass Storage Device'' and in the properties the event data correctly reports ''USB\VID_0483&PID_5720\00000000001A'' as exepected. 

In my application, the functions STORAGE_Init() and STORAGE_GetCapacity() are called.

I kept the default values:

#define STORAGE_LUN_NBR                  1  

#define STORAGE_BLK_NBR                  0x10000  

#define STORAGE_BLK_SIZ                  0x200

Now when detecting the board, Windows 8 wants to format the disk because the file system is not recognized.

In my application I did:

 /* FatFS: Link the SDRAMDISK disk I/O driver */

FATFS_LinkDriver(&SDRAMDISK_Driver, SDRAMDISK_Path);

 /* Register the file system object to the FatFs module */

f_mount(&RAMDISKFatFs, (TCHAR const*)SDRAMDISK_Path, 1);

 /* Create a FAT file system (format) on the logical drive */

f_mkfs((TCHAR const*)SDRAMDISK_Path, 0, 0) ;

And the SDRAM is corretctly initialized.

When debugging, I see that this is the FAT16 that is selected.

Do you think there is something more I should do to have Windows correctly read the disk?

Or should I let my Windows 8 format the disk ? I am not sure there is no risk.

Posted on July 30, 2014 at 19:45

And you've created the READ/WRITE functionality against the SDRAM buffer?

Windows formatting is fine, it's just going to destroy/alter the SDRAM content, which presumably you don't care about. You could fill with 0xE5 or 0xF6 characters to initialize it.
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 July 31, 2014 at 19:02

Well, this is my next problem.

Each time I try to write to the SDRAM, it ends with a hard fault.

Here is my process:

- Init FAT:

FATFS_LinkDriver(&SDRAMDISK_Driver, SDRAMDISK_Path);

f_mount(&RAMDISKFatFs, (TCHAR const*)SDRAMDISK_Path, 0);

f_mkfs((TCHAR const*)SDRAMDISK_Path, 0, 0);

At this point the SDRAM has been initialized by the SDRAMDISK_initialize() in sdram_diskio.c, which called the BSP_SDRAM_INIT() with:

SdramHandle.Init.SDBank             = FMC_SDRAM_BANK2;

SdramHandle.Init.ColumnBitsNumber   = FMC_SDRAM_COLUMN_BITS_NUM_8;

SdramHandle.Init.RowBitsNumber      = FMC_SDRAM_ROW_BITS_NUM_12;

SdramHandle.Init.MemoryDataWidth    = SDRAM_MEMORY_WIDTH;

SdramHandle.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;

SdramHandle.Init.CASLatency         = SDRAM_CAS_LATENCY;

SdramHandle.Init.WriteProtection    = FMC_SDRAM_WRITE_PROTECTION_DISABLE;

SdramHandle.Init.SDClockPeriod      = SDCLOCK_PERIOD;

SdramHandle.Init.ReadBurst          = SDRAM_READBURST;

SdramHandle.Init.ReadPipeDelay      = FMC_SDRAM_RPIPE_DELAY_1;

Next, I initialize the USB device as MSC, and call USB_Start().

Then I plug the USB cable between CN6 connector and the Windows 8 PC.

Windows detect the board and proposes to format it.

Size = 32 MB

Format in FAT

Block = 512

Formatting starts and function given via USBD_MSC_RegisterStorage() is called:

int8_t STORAGE_Write (uint8_t lun, 

                         uint8_t *buf, 

                         uint32_t blk_addr,

                         uint16_t blk_len)

Now, my questions are:

should I use the sdram_diskio.c funtion

DRESULT SDRAMDISK_write(const BYTE *buff, DWORD sector, BYTE count)

or the BSP_SDRAM_WriteData() one ?

If it is SDRAMDISK_write() then how do I convert blk_addr to sector and blk_len to count ?

And I don't see why I cannot write to the SDRAM. Whatever I do it ends with a hard fault.

But if I run the STM32CubeF4 example under STM32F429I-Discovery\Examples\FMC\FMC_SDRAM_LowPower on the same board, it works.

And I have the same system clock config, and the example also calls BSP_SDRAM_INIT().

According to you, is there something corrupted, or missing ?

Or do I have to modify something in the SDRAM config in order to read/write on it when the board is used as a device mass storage ?

Posted on July 31, 2014 at 19:46

Doesn't the

http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090

only have 8MB (64 Mbit) on it?

0x4000 x 512byte blocks
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 01, 2014 at 18:01

You are right, it is 8 MB.

I have adjusted the defines and fixed my hard faults.

But I am still blocked at the point where Windows 8 wants to format the card.

It sets:

Capacity = 8 MB

File system = FAT

Allocation unit size = 2048 bytes

On my Discovery board, the execution goes to here:

usbd_msc_scsi.c:

  if(((USBD_StorageTypeDef *)pdev->pUserData)->Write(lun ,

                              hmsc->bot_data, 

                              hmsc->scsi_blk_addr / hmsc->scsi_blk_size, 

                              len / hmsc->scsi_blk_size) < 0)

This leads to my function

int8_t STORAGE_Write (uint8_t lun, 

                         uint8_t *buf, 

                         uint32_t blk_addr,

                         uint16_t blk_len)

On first loop:

buffer bot_data size is 4096

scsi_blk_size = 0x200

scsi_blk_nbr = 0x00004000

scsi_blk_addr = 0x00000200

len = 1

So the address I have given to BSP_SDRAM_WriteData() is 0xD0000000.

This is the SDRAM_DEVICE_ADDR define in stm32f429i_discovery_sdram.h.

Works fine. Correctly written to the SDRAM.

Second loop:

buffer bot_data size is 4096

scsi_blk_size = 0x200

scsi_blk_nbr = 0x00004000

scsi_blk_addr = 0x007FFE00

len = 1

So in STORAGE_Write() passed values are blk_addr = 0x00003FFF and blk_len = 1

I call BSP_SDRAM_WriteData(). Given address is 0xD0004000.

But I have a sort of infinite loop where HAL_PCD_IRQHandler(&hpcd_USB_OTG_HS) keeps being called.

So do you think that BSP_SDRAM_WriteData() is the best function to use here ?

Do you know if there is an example somewhere showing how and what to write to the STM32 SDRAM when Windows wants to format it ?

Posted on August 01, 2014 at 19:15

There is some confussion here about what is a Byte Offset Memory Address, and a Block Number

scsi_blk_addr appears to be a Memory Address, 0x800000 representing 8 MB in BYTES

Thus 0xD0000000 + scsi_blk_addr would be where you'd read/write your 512 byte blocks from, or 0xD0000000 + (blk_addr * 0x200) if you want to go back-n-forth between units. SCSI commands use BLOCK addressing, and BLOCK counts.

If you can't find an example, probably means someone has to write one

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..