cancel
Showing results for 
Search instead for 
Did you mean: 

Nucleo-F722ZE USB MSC and SDMMC interface to uSD card (SOLVED)

Jtron.11
Senior

I tried to create a combination of USB MSC Device and uSD card with SDMMCx interface. The clock for USB was config at 48MHz and also for SDMMC.

In the examples that I saw online, one indicate the SDMMC clock need to be configured at 12MHz so it will match with USB 12Mbits/s for the Full Speed. Some other examples was use slower speed for the SDMMC interface.

If I am playing around with SDMMCCLK clock divide factor, like 2, 3, 4, (2 would be idea because 48Mhz/(2+2) = 12MHz, my eval board only show USB mass storage once I plugged in the USB to the PC, but there is no action like asking for format the device, and time out in couple minutes later.

Playing with this divide factor can made thing worst like the eval couldn't enumerate at all.

Please let me know if there is any correct clock setting for SDMMCx clock and the divide factor?

Another question is if USB Full Speed is only do 12Mbits/s (12MHz), where is the clock divider for USB, can someone point it out for me on the user manual. I am looking for that piece that information as well.

Thank you so much for your times.

6 REPLIES 6
TDK
Guru

There's no need to reduce SDMMC to match 12 MHz. However, having a faster clock can expose bugs in the HAL implementation.

USB clock comes from PLLQ or PLLSAIP. CubeMX clock tree is useful for visualizing clocks. See CK48MSEL bit in RCC->DCKCFGR2.

0693W00000Bbr7hQAB.png

If you feel a post has answered your question, please click "Accept as Solution".
Jtron.11
Senior

TDK,

Thank you for your reply. I have used the clock to configure the clocks exactly in your picture.

From this info

DMMCCLK clock divide factor

SDMMCCLK clock divide factor must be between 0 and 255.

Parameter Description:

SDMMC_CK = SDMMCCLK / [CLKDIV + 2]. The output clock frequency can vary between 187 KHz and 24 MHz. It is advised to keep the default ClockDiv value (0) to have a maximum SDMMC_CK frequency of 24 MHz.   

So if SDMMC1 currently is configured as 48MHz in the clock tree, after the configuration, it will be 24MHz, and if I can adjust the SYSCLK to turn it down to 24MHz, will it become 12MHz?

Ideally SDMMC1 must have the faster speed to USB MSC FS right?

TDK
Guru

> So if SDMMC1 currently is configured as 48MHz in the clock tree, after the configuration, it will be 24MHz, and if I can adjust the SYSCLK to turn it down to 24MHz, will it become 12MHz?

Yes.

Also, the fastest SDMMC clock is 48MHz and can be achieved by enabling the clock divider bypass.

> Ideally SDMMC1 must have the faster speed to USB MSC FS right?

Faster is generally better, but there's no link between the two.

If you feel a post has answered your question, please click "Accept as Solution".
Jtron.11
Senior

Hi all,

For anyone who is seeking for the fast track to implement the SDIO+FATFS+USB MSC I found these example, very good and I follow and it is working

Step 1: try to implement SDIO+FATFS first

https://programmersought.com/article/67725446057/

Note:

Pay attention to see how the interrupt priority is setting between different sources. I made the mistake since I was not paying attention to the interrupts priority which made my project never work, until I realized and confirm with this link for different priorities levels.

None of the example online/youtube will show/mention about the adjustments of the interrupt priorities.

May be it is the known fact for experiences people, but for new comers it is very helpful for any instructions to mention about the interrupts priorities.

Step 2: add in the step 1 project the USB MSC

https://programmersought.com/article/94503880830/

In the tutorial, there is no mentioning of the header file is missing, you may or may not encounter the situation. In my case I am working with nucleo-F722ZE eval board, and I have to manually include one of the header "ff_gen_drv.h" into sd_diskio.c file.

Have fun!

Hi! I know I'm late but i hope that you will still answer 🙂

Where from is "sdWriteStatus" and "sdReadStatus"?

I cant find it anywhere

btw. thanks for your post! it helped me a lot 🙂

Jtron.11
Senior

Ah, those variables were not use the example has them call out. I end up didn't use them at all and in my usbd_storage_if.c I commented them all out

int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)

{

 /* USER CODE BEGIN 6 */

int8_t ret = -1;  

  

 if(BSP_SD_IsDetected() != SD_NOT_PRESENT)

 {  

  BSP_SD_ReadBlocks_DMA((uint32_t *)buf, blk_addr, blk_len);

  /* Wait for Rx Transfer completion */

  // while (sdReadStatus == 0){}

  // sdReadStatus = 0;

  /* Wait until SD card is ready to use for new operation */

  while (BSP_SD_GetCardState() != SD_TRANSFER_OK){}

  ret = 0;

 }

 return ret;

 /* USER CODE END 6 */

}

/**

 * @brief .

 * @param lun: .

 * @retval USBD_OK if all operations are OK else USBD_FAIL

 */

int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)

{

 /* USER CODE BEGIN 7 */

int8_t ret = -1;  

  

 if(BSP_SD_IsDetected() != SD_NOT_PRESENT)

 { 

  BSP_SD_WriteBlocks_DMA((uint32_t *)buf, blk_addr, blk_len);

   

  /* Wait for Tx Transfer completion */

  //while (sdWriteStatus == 0){}

  //sdWriteStatus = 0;

   

  /* Wait until SD card is ready to use for new operation */

  while (BSP_SD_GetCardState() != SD_TRANSFER_OK){}

  ret = 0;

 }

 return ret;

 /* USER CODE END 7 */

}