2020-02-11 04:56 PM
I'm developing an application which uses both USB mass storage and BLE. I've started by building two separate applications using STM32CubeMX:
Both of these work fine on their own. But if I build an application that includes both components, the USB mass storage device will not enumerate properly.
Initially, I discovered that in the full application, HAL_PCD_IRQHandler got called, but it never fell through to PCD_EP_ISR_Handler. This makes me think the mass storage endpoints have not been configured properly.
I've also tackled the problem a different way--by systematically eliminating parts of the BLE initialization to determine what is interfering with USB mass storage. Using this method, I've been able to determine that if I comment out the call to SHCI_C2_BLE_Init in APP_BLE_Init (in app_ble.c), USB mass storage enumerates properly. If I then uncomment this line, it stops working again.
SHCI_C2_BLE_Init simply sends a message to CPU telling it to start the BLE stack, so this makes me think that the BLE stack on CPU2 is somehow interfering with USB endpoints configured before the call to APPE_Init in main.c.
I believe USB is a shared resource between CPU1 and CPU2, so it seems likely that the BLE stack is also trying to do something with USB. However, I'm at a loss as to how to debug this further or how to avoid the problem.
Any help would be greatly appreciated!
Michael
Solved! Go to Solution.
2020-05-12 02:52 PM
Of course! The attached project should work on a P-NUCLEO-WB55 board. The microSD card is connected as shown here:
To build this project, I started with an empty P-NUCLEO-WB55 project, added SPI1 and FATFS, configured both, then added/replaced these files in the FATFS/Target folder:
My disk interface (build around ChaN's example) is contained in mmc.* and these functions have been added to the original skeletons in user_diskio.c.
Note that I'm not using SPI very efficiently here. Even for large transfers to the microSD card, I'm using polling HAL functions in mmc.c. To optimize, you should use DMA transfers in the "rcvr_spi_multi" and "xmit_spi_multi" functions.
On the hardware side, you'll need pull-ups on the NSS and MISO lines. I think I'm using 10k.
Michael
2020-05-13 09:54 AM
Hey! Thank you so much for your answer!
I have some questions for you if you have the time. These are the steps that I took:
void init_spi (void)
{
CS_HIGH(); /* Set CS# high */
for (Timer1 = 10; Timer1; ) ; /* 10ms */
}
I am kind of lost here, there are no errors, no warnings, it just keeps running. (I have a pressure sensor connected as well and the system works as I get data from the sensor, however the SD won't get past the f_mount)
You also said about having pull-ups on the NSS and MISO lines. I have no pull-ups, I thought that the SD module was taking care of all of that. Do I still need to add them? And when you say NSS, you mean the CS pin?
Sorry if all of these sound like basic questions and thanks again!
2020-05-13 10:50 AM
A couple of things come to mind:
I hope this helps! I've encountered similar issues to what you're seeing, and the above is how I was able to solve them.
Michael
2020-05-13 11:46 AM
Hello,
Thank you for these answers! I managed to solve the timer problem and now it is not stuck anymore!
However, I got back to the old problem (that I had after trying the tutorials available on the internet) that I get FR_NOT_READY after doing the "f_mount" function. I also added 2 pull up resistors of 10k each on CS and MISO, but I get the same result with or without the pull-ups...
Do you have any idea on why I might be still getting this?
Thanks!
2020-05-13 11:51 AM
The first thing I would do is to step through and find out exactly why it's returning FR_NOT_READY. If you have a logic analyzer, I would also take a look at the communications and make sure you can see both parts communicating on the bus. If you don't have a logic analyzer, I'd highly recommend picking one up--otherwise, debugging digital circuits is like playing darts in a room with no light.
Michael
2020-05-13 12:34 PM
I am gonna check it with a logic analyzer, as you have suggested!
I also notice that from time to time it seems to be working, I get FR_OK, but then when I check for the file, it's not there. Also next time I try I always get again the FR_NOT_READY.
I've seen some posts online that it depends if the SD card is formatted with FAT16. Do you think that matters? I have an SDHC of 16gbs. Nevertheless I formatted it with FAT16, same story. I would also like to ask you, if you have written some data about the card in your code? I've noticed there's a section for the type of the card. Should I be concerned by it?
Than you so much for your time!
2020-05-13 12:49 PM
The code shouldn't care what kind of card you're using. I've written to cards from 512 MB to 32 GB using the same code.
If you have a P-NUCLEO-WB55 board, have you tried compiling and running the project I sent with no modifications (and with the card connected the same way I've connected it)? This should work the same on your board as on mine, and it would provide a good baseline for testing.
Michael
2020-05-13 01:26 PM
Yes, I have tried your project as well and it goes into HardFault_Handler() from stm32wbxx_it.c. I've tried it with and without pull-ups.
At this point I think it comes down to a hardware problem as I can't see where should be the issue with the software..
Bogdan
2020-05-22 10:37 AM
Hello again!
I finally figured it out, I had forgotten to write the interrupt for the mmc file and that is why it was not working! I took me a while to get a grip of it, but I am glad I can finally transfer my data to the SD card!
Now I bumped into another problem, as I am trying to advance the project and send the sensor data via BT to my phone, while also registering it at the same time to the SD card.
It is exactly the same issue you've had. Both applications are working perfectly on their own, but after introducing the code for the SD card nothing works anymore.
I don't get this exactly, but I am trying to set the clock to PLLCLK in order to use the peripherals, but at this point the BT is not working anymore (neither does the SD but this is another thing). I have tried introducing your code that you mentioned above, but it doesn't seem to have any effect. I am definitely approaching this from a wrong perspective.
What else did you change in your code in order to be able to receive sensor data by BT while also storing it via SD? Is there any call function to the code you shared?
How do I deal with the clock in this situation, I saw on the Hands On tutorial that the BT uses HSE, however the SD would use PLLCLK (from what I understand), how do I merge them in order to work together.
Let's say the BT works, however I have my UTIL_SEQ_Run(~0); that starts the BT functions. This would be placed in the main.c function, however so is my code for the SD card. How would I get past this in order to access the rest of the code for the SD? Would I write this one in the template_stm? I also seem to have a problem with the MMC_timerproc handler from stm32wbxx_it.c. When I keep this function there, the BT stops working going into some SPI function.
I hope you could help me with this and thank you for your time!
Bogdan
2020-05-25 05:00 PM
It sounds like there are a few gaps in your understanding which are causing problems here. I would approach it from this angle:
First, check out the STM32WB Workshop here:
Don't just read it, though. Follow along with each step, and make sure you understand exactly why they're doing each one, specifically what the code does, etc. It's easy to overlook opportunities to learn if you're just copying and pasting code.
Next, take a look at this application note from ST:
Again, if you haven't already done so, carefully read the whole thing. This document does a great job of expanding on what's done in the STM32WB Workshop.
Next, take a close look at the BLE_HeartRate example. Don't just compile it and install it. Notice how simple the main loop is. This example does a lot of what you're trying to do (minus the SD interface). So where are they generating "sensor" data? How are they handling low power modes?
Finally, read the RCC chapter in the Reference Manual. The STM32 has a clock tree which generates a lot of different clocks for different peripherals. It's worth reading closely so you understand how each of these clocks is generated, what peripherals they're associated with, and what happens to each one when you go into a low power mode.
I hope this helps!
Michael