2014-07-25 09:29 AM
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.infClass GUID: {36FC9E60-C465-11CF-8056-444553540000}Service: USBSTORLower Filters: Upper Filters: Problem: 0xAStatus: 0x0So 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 #msc2014-07-25 09:43 AM
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.2014-07-29 10:14 AM
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=false2014-07-29 11:02 AM
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 |
*=============================================================================
2014-07-30 09:59 AM
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 0x200Now 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.2014-07-30 10:45 AM
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.2014-07-31 10:02 AM
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 MBFormat in FATBlock = 512Formatting 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 funtionDRESULT 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 ?2014-07-31 10:46 AM
Doesn't the
http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090
only have 8MB (64 Mbit) on it? 0x4000 x 512byte blocks2014-08-01 09:01 AM
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 MBFile system = FATAllocation unit size = 2048 bytesOn 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 functionint8_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 4096scsi_blk_size = 0x200scsi_blk_nbr = 0x00004000scsi_blk_addr = 0x00000200len = 1So 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 4096scsi_blk_size = 0x200scsi_blk_nbr = 0x00004000scsi_blk_addr = 0x007FFE00len = 1So in STORAGE_Write() passed values are blk_addr = 0x00003FFF and blk_len = 1I 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 ?2014-08-01 10:15 AM
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