2024-02-15 01:10 AM - edited 2024-02-19 01:20 AM
Hi,
I am trying to set up a basic HS USB MSC project on a custom board with an STM32F723.
The project is based on these tutorials from ST, the only difference is, that I'm using USB HS and not USB FS.
https://www.st.com/content/st_com/en/support/learning/stm32-education/stm32-moocs/STM32-USB-training.html
https://www.youtube.com/watch?v=GjQqZd1keBo&ab_channel=STMicroelectronics
https://www.youtube.com/watch?v=Us_sTdGGcOQ&t=363s&ab_channel=ControllersTech
I'll shortly show the CubeMX setup and the code changes I made (all like in the tutorials) and then I will show what the error Message is on the Host.
Project Setup:
Linker Settings:
Minimum Heap Size 0x2000
Minimum Stack Size 0x2000
This is are all configuration I made. The rest is set to default when you start a new project with the project wizard. The IOC File is also attached to this post.
In the code I made these addons in the usbd_storage_if.c file:
#define STORAGE_LUN_NBR 1
#define STORAGE_BLK_NBR 0x10000
#define STORAGE_BLK_SIZ 0x200
/* USER CODE BEGIN PRIVATE_DEFINES */
#define STORAGE_BLK_NBR 128
uint8_t usb_buffer[STORAGE_BLK_NBR*STORAGE_BLK_SIZ];
int8_t STORAGE_Read_HS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
/* USER CODE BEGIN 13 */
memcpy(&usb_buffer[blk_addr*STORAGE_BLK_SIZ], buf, blk_len*STORAGE_BLK_SIZ);
return (USBD_OK);
/* USER CODE END 13 */
}
int8_t STORAGE_Write_HS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
/* USER CODE BEGIN 14 */
memcpy(buf, &usb_buffer[blk_addr*STORAGE_BLK_SIZ], blk_len*STORAGE_BLK_SIZ);
return (USBD_OK);
/* USER CODE END 14 */
}
After building and running the FW the host computer (Windows 10) detects a new storage device and shows this message (german):
It say's you have to format the device before using it.
If I do so:
I'll get this error message which says: Windows could not complete the formatting
I have also tried to format the device on an Linux host which also failed.
In the link I shared on the top, the youtube Video from ST, there people in the comments facing the same problems.
Further it is to say, that the USB CDC example works. So the USB connection works.
Is there anyone faced the same problems and have a solution?
Solved! Go to Solution.
2024-02-16 09:34 PM
Sure, your USB enumeration seems to work: you can see your device a "USB Memory dongle" (MSC).
No idea about the details of your code. But based on my experience/understanding with USB MSC:
It looks to me as:
memcpy(&usb_buffer[blk_addr*STORAGE_BLK_SIZ], buf, blk_len*STORAGE_BLK_SIZ);
OK, assuming you want to "emulate" a file storage (internal SRAM instead, via usb_buffer, and not an SD card used (as often intended to do) - thinking about (besides this "bug" with *STORAGE_BLK_SIZE):
Do you have really 64KB (or even more) for usb_buffer? (as done via format parameter)
There is also a function as:
int8_t STORAGE_GetCapacity(uint8_t lun, uint32_t * block_num, uint16_t * block_size)
What do you return from here?
This matters a lot, because it tells the host (PC) how large your storage is.
If you do not have reserved the same amount of memory for your usb_buffer - it will corrupt your memory.
See the examples where the SD Card is used as file system storage:
they assume a block_num as linear, 0...X, in sector size 512bytes: you are right with
&usb_buffer[blk_addr*STORAGE_BLK_SIZ]
but not with:
blk_len*STORAGE_BLK_SIZ
2024-02-16 09:34 PM
Sure, your USB enumeration seems to work: you can see your device a "USB Memory dongle" (MSC).
No idea about the details of your code. But based on my experience/understanding with USB MSC:
It looks to me as:
memcpy(&usb_buffer[blk_addr*STORAGE_BLK_SIZ], buf, blk_len*STORAGE_BLK_SIZ);
OK, assuming you want to "emulate" a file storage (internal SRAM instead, via usb_buffer, and not an SD card used (as often intended to do) - thinking about (besides this "bug" with *STORAGE_BLK_SIZE):
Do you have really 64KB (or even more) for usb_buffer? (as done via format parameter)
There is also a function as:
int8_t STORAGE_GetCapacity(uint8_t lun, uint32_t * block_num, uint16_t * block_size)
What do you return from here?
This matters a lot, because it tells the host (PC) how large your storage is.
If you do not have reserved the same amount of memory for your usb_buffer - it will corrupt your memory.
See the examples where the SD Card is used as file system storage:
they assume a block_num as linear, 0...X, in sector size 512bytes: you are right with
&usb_buffer[blk_addr*STORAGE_BLK_SIZ]
but not with:
blk_len*STORAGE_BLK_SIZ
2024-02-17 02:17 AM
You have swapped the arguments of memcpy. Just swap the first with the second in both calls.
2024-02-19 01:00 AM
Dear @tjaekel,
Thank you for taking time to check my question an provide such a detailed answer.
Yes, I would like to write, for testing, to the internal RAM. Next I would like to write to external RAM via FMC. But first I have to get the basic example, provided in these two tutorials running:
https://www.youtube.com/watch?v=Us_sTdGGcOQ&t=363s&ab_channel=ControllersTech
https://www.youtube.com/watch?v=GjQqZd1keBo&ab_channel=STMicroelectronics
Both tutorials using USB FS and not USB HS.
I have checkt your succestions. And Yes I made an error in the wite and read function with the use of memcpy.
I fixed it like this:
int8_t STORAGE_Read_HS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
/* USER CODE BEGIN 13 */
memcpy(buf, &usb_buffer[blk_addr*STORAGE_BLK_SIZ], blk_len*STORAGE_BLK_SIZ);
return (USBD_OK);
/* USER CODE END 13 */
}
int8_t STORAGE_Write_HS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
/* USER CODE BEGIN 14 */
memcpy(&usb_buffer[blk_addr*STORAGE_BLK_SIZ], buf, blk_len*STORAGE_BLK_SIZ);
return (USBD_OK);
/* USER CODE END 14 */
}
When debuging, I can see the blk_len is always 1. So it tries to read always 512Byte block, which should be ok. What is strange is, that it always tries to read. The STORAGE_Read_HS function is always called, nonstop...
For the Capacity, I'm using the same function as in the example:
int8_t STORAGE_GetCapacity_HS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{
/* USER CODE BEGIN 10 */
//UNUSED(lun);
*block_num = STORAGE_BLK_NBR;
*block_size = STORAGE_BLK_SIZ;
return (USBD_OK);
/* USER CODE END 10 */
}
So I am still facing the same problem.. formating on the host fails.
In the attachment, I'll provide the usbd_storage_if.c file and the main.c file.
Best regards,
Corsin
2024-02-19 01:03 AM
Dear @gbm ,
Yes I have seen I made a *** error there. It happend because I tried everything possible and then when cleaning the whole project and restart it, I used the wrong memcpy functions for write and read.
As I answered to @tjaekel, you can see, that I'm still facing the formatting error on the host.
Do you may have an idea where it comes from?
Best regards,
Corsin
2024-02-19 04:47 AM
The size of data being copied by memcpy should be simply STORAGE_BLK_SIZ - no multliplication here.
2024-02-22 08:40 AM
Hello @CObri.1
Have you faced similar issues using different classes acm cdc for example? Ensure that your USB device descriptor correctly identifies the device as an MSC device.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.