2021-08-13 12:26 AM
My current project is based on STM32H743IIT6 microcontroller with CMSIS RTOS v2, FATFS, USB FS as Mass Storage Host class. Recently, I upgraded to H7 firmware v1.9 after which FATFS API return "FR_DISK_ERR" error frequently.
As a workaround, I had to replace these files "stm32h7xx_ll_usb.c", "stm32h7xx_ll_usb.h", "stm32h7xx_hal_hcd.c" and "stm32h7xx_hal_hcd.h" in latest drivers in v1.9 to the once present in earlier version that is H7 firmware v1.8.
There are changes in USB link layer drivers & HCD drivers in latest firmware and that seems to be the root cause of these issue. I narrowed down at a place in USB link layer "stm32h7xx_ll_usb.c" to function like "USB_ReadPacket()", "USB_WritePacket()" where in earlier v1.8 read and write from USBx_DFIFO were 32bit word aligned which is NOT the case with latest firmware v1.9. I am not sure if word alignment is the issue here but it has something to do with this USB and HCD drivers cause replacing them with the older version in latest firmware seems to work for me.
2021-08-23 04:30 AM
Hi @VShet.2 ,
I reported your case to our development team for more investigation. Internal ticket number: 112204 (PS: This is an internal tracking number and is not accessible or usable by customers).
Thanks for all relevant details you provided and the analysis you added. This is helpful to identify the root cause.
-Amel
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.
2021-08-27 12:42 AM
Hi @Amel NASRI ,
I did some more work on this issue and I have narrowed it down to clock issue. Everything with latest firmware work correctly if I change my clock source for USB peripheral to internal RC48 instead of 48 MHz generated from PLL3Q which I was using earlier. This is precisely the ONLY change I require in my project for USB and FATFS to work correctly with the new firmware for H7: v1.9.
PLL3 in my project using divider PLL3R is used for LTDC peripheral. There is only one clock source possible for LTDC so, cannot modify that. If I disable LTDC so that NO other peripheral uses PLL3 then USB & FATFS works correctly with latest firmware.
I have attached both working and not working IOC files of my project in this thread for reference.
Conclusion: USB and FATFS works correctly in latest firmware with PLL3 as clock source only if this PLL3 is NOT used by any other peripheral. If any other peripheral uses PLL3 then you need to use RC48 as source for USB. This issue was NOT there in older H7 firmware.
@Amel NASRI Can you please share this information and attached files to relevant internal ticket ( Internal ticket number: 112204 ). This might help in focusing on exact issue.
2021-08-27 04:21 AM
Hi @VShet.2 ,
The results of your investigation are quite interesting. As you asked for it, I shared your findings with development team.
Thanks again.
-Amel
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.
2021-08-30 02:20 AM
Hi @VShet.2 ,
Just to make sure, do you confirm that there is no problem with exactly the same application in following cases:
Is that summary correct?
-Amel
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.
2021-08-30 02:33 AM
Hi @Amel NASRI ,
Yes, that's correct.
OR
Note: My application uses FreeRTOS i.e CMSIS OS v2
2021-09-01 06:35 AM
Hi @VShet.2 ,
To go ahead with problem analysis, I have 2 proposals:
Thanks.
-Amel
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.
2021-09-02 03:24 AM
Hi @Amel NASRI ,
Let me know if I misunderstood anything from your two proposals ? If you want I can create a new project with just USB and LTDC, TouchGFX and share that code with you but again you can't run it at your side because its my custom board.
2021-09-02 03:47 AM
Hi @VShet.2 ,
1- In the mentioned example, we have this configuration for USB clock in SystemClock_Config():
/* PLL3 for USB Clock */
PeriphClkInitStruct.PLL3.PLL3M = 25;
PeriphClkInitStruct.PLL3.PLL3N = 336;
PeriphClkInitStruct.PLL3.PLL3FRACN = 0;
PeriphClkInitStruct.PLL3.PLL3P = 2;
PeriphClkInitStruct.PLL3.PLL3Q = 7;
PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOMEDIUM;
PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_0;
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
My understanding is that PLL3 is being used for the suggested project, not RC48 as USB clock source.
2- OK thanks for confirming.
Yes indeed, sharing a project with the complete configuration and minimum code to reproduce the issue will be helpful.
Thanks again.
-Amel
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.
2021-09-04 05:10 AM
Hi @Amel NASRI ,
/**
* This function searches for files inside search_dir which matches file extension specified by ext. It calls function to check
* validity and update RAM. RAM is NOT updated with file info if that file fails to open/read.
* @param search_dir Search Directory is path of H<HookNo> if exists otherwise root of PenFolder
* @param ext String specifing file extension: ".bmp", ".bmc"
*/
void USB_search_read_header(char *search_dir, char *ext)
{
FRESULT fr; /* Return value */
DIR dj; /* Directory object */
FILINFO fno; /* File information */
uint8_t len = 0;
char search_file[270] = {0};
Update_typedef update;
FRESULT (*File_Type)(char *Path, char *Name);
File_Type = &USB_save_BMP_header;
strcpy(search_file, search_dir);
strcat(search_file, "/");
len = strlen(search_file);
fr = f_findfirst(&dj, &fno, search_dir, ext); /* Start to search for files */
while (fr == FR_OK && fno.fname[0]) /* Repeat while an item is found */
{
memcpy((search_file+len), fno.fname, (strlen(fno.fname)+1));
memcpy(DsgName_CurrAddr, fno.fname, (strlen(fno.fname)+1));
if((*File_Type)(search_file, fno.fname) == FR_OK) // Call through Function pointer
{
DsgName_CurrAddr += (strlen(fno.fname)+1);
}
if(USB_FileCnt_all < USB_Max_Dsg) // USB MAX files supported 4000
{
fr = f_findnext(&dj, &fno); /* Search for next item */
}
else
{
break;
}
}
if(fr == FR_OK)
{
update.type = USB_File_ready;
}
else
{
update.type = USB_Disk_Error;
}
// osMessageQueuePut(Model_QueueHandle, (void *)&update, 0, 0);
f_closedir(&dj);
}
Let me know if any clarification is required in my test code.
Thanks,
Vatsal