-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
STM: Clear stale data from STM SPI peripheral before starting data transfer #14534
Conversation
@rvasquez6089, thank you for your changes. |
@rvasquez6089 thanks for analysing the issue you have faced and coming up with a proposed fix. We could suppose that a reset would avoid any stale data ... if not the system reset, then the peripheral reset should do ... mbed-os/targets/TARGET_STM/stm_spi_api.c Line 330 in ddc9fc8
Could you try to test a peripheral reset sequence during init as well for your peripheral under test and see if that helps ? mbed-os/targets/TARGET_STM/stm_spi_api.c Line 194 in ddc9fc8
#if defined SPI2_BASE ? |
@LMESTM I will give this a try and report back next week. 👍 |
…the spi transfer clearning of the recieve buffer
I had to change the order of the reset and enable. It seems like the reset functions disable the peripheral in some way so it is best to enable after resetting them.
I added this change to all of the SPI peripherals. Check my commits for the full change. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good! :-)
SPI tests are all OK on my side for all STM32 families.
Just request to correct space alignment and remove unused code.
Thx!
targets/TARGET_STM/stm_spi_api.c
Outdated
//#if TARGET_STM32H7 | ||
// if (!LL_SPI_IsActiveFlag_RXP(SPI_INST(obj)))///Clears stale data in the receive buffer is there is any. | ||
//#else /* TARGET_STM32H7 */ | ||
// /* Wait for RXNE flag before reading */ | ||
// if (LL_SPI_IsActiveFlag_RXNE(SPI_INST(obj)))///Clears stale data in the receive buffer is there is any. | ||
//#endif /* TARGET_STM32H7 */ | ||
// { | ||
// if (LL_SPI_IsActiveFlag_RXNE(SPI_INST(obj))) | ||
// { | ||
// /* Read received data */ | ||
// if (bitshift == 1) | ||
// { | ||
// LL_SPI_ReceiveData16(SPI_INST(obj)); | ||
//#ifdef HAS_32BIT_SPI_TRANSFERS | ||
// } else if (bitshift == 2) { | ||
// LL_SPI_ReceiveData32(SPI_INST(obj)); | ||
//#endif | ||
// } | ||
// else{ | ||
// LL_SPI_ReceiveData8(SPI_INST(obj)); | ||
// } | ||
// } | ||
// } | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this code
@@ -184,41 +183,53 @@ static void _spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap) | |||
#if defined SPI1_BASE | |||
// Enable SPI clock | |||
if (spiobj->spi == SPI_1) { | |||
__HAL_RCC_SPI1_FORCE_RESET(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alignment issue :-)
@rvasquez6089 so do you confirm that the reset sequence is fixing the issue you're facing ? |
@LMESTM The issue stills seems to be there intermittently, but the frequency of issue has gone down significantly. I will check that my user code isn't causing this issue. However, I don't see how that could be the case when using the high level mbed SPI library. |
All, I have also found that adding a 100us second delay after changing the SPI frequency increases the chances of the SPI send/receiving data in the correct mode. I hoping that someone on the STM team can shed light on my findings. I found the results to be very random . I have tested my sample code on 3 identical boards just to verify there isn't any damage to my MCU or other parts of my test setup. Lastly, here are some pre compiled binary of the sample code with the changes below if it helps. 👍 System Informationmbed cli version: 1.10.2 Here are the output waveforms from the STM32F767. Original Code: Tag mbed-os-6.9.0 + Output waveforms.Channel 1 (Yellow) CLK After Reprogramming.I get this waveform after programming the chip with an ST-LINKV3 Mini After Reset with Reset ButtonI get this waveform after pressing the reset button on my custom development board. Sometimes the transfer doesn't even complete before the chip select line goes high again. This is a random occurrence. Method 1: Clear the receive buffer before each transfer. rvasquez6089/mbed-os commit ddc9fc8I get this waveform after programming the chip with an ST-LINKV3 Mini After Reset with Reset ButtonI get this waveform after pressing the reset button on the development board. Everything still works as expected. 👍 There doesn't appear be a significant added delay from the extra branch in the code either Method 2: Suggested fix from @LMESTM rvasquez6089/mbed-os commit 6f6443f (Force reset in the _spi_init_direct)After Reprogramming.Works the same after programming. 👍 After Reset with Reset ButtonI get this waveform after pressing the reset button on my custom development board. Same as before. |
@rvasquez6089 hmm, I don't really have a clue. It may take some time before we find time to reproduce locally and investigate further. for now, I will ask internally if that rings a bell to anyone. I am just wondering if you shouldn't move the CS initialization before the SPI driver creation to make sure that CS is never asserted before your actual code starts. Even if without clock, I wouldn't expect anything to happen ...
EDIT: first input from SPI experts, the the MOSI would be expected LOW after and before each sequence. So there might be some glitch related to wrong pins default states / configuration. Maybe we should use pull_down for MOSI ... so, after testing CS1 init change above, may you also try to change pull_non to pull_down and see if it helps ? thanks |
I will give this a try early next week and post the results. |
Did you have time to check with the pull down configuration? Thx |
I will get back you next week with results. I am/was in the process of finishing a project for a customer. |
This pull request has automatically been marked as stale because it has had no recent activity. @rvasquez6089, please carry out any necessary work to get the changes merged. Thank you for your contributions. |
Any chance to find some testing time ? :-) |
@jeromecoutant Not yet. I've been peeling F767ZI chips from Nucleo boards to put on customer projects due to chip shortage. 😆 I'm all out of Nulceo's to do testing on. I will eventually get back to this PR. I want to get the problem solved in a way that meets the Mbed foundation standards. For now I'm just shipping code from my fork to customers. |
@rvasquez6089 thanks for the update. We can close this pull request and you can reopen once updated. I'll close it now. |
Summary of changes
Note: This is a resubmission. I accidentally closed my previous PR.
This change fixes a bug in in STM SPI API. I was having trouble with the SPI peripheral reading in data after resetting the micro controller using the reset pin. It would seem that after a reset by the reset pin.... stale data would be left in the read buffer of the SPI peripheral.
This would cause the RXNE flag of the SPI peripheral to be high.
This would cause the spi_master_write() function to incorrectly read the receive buffer before valid data was in the buffer. I was able to verify this bug with an oscilloscope.
This pull request checks the state of the RXNE flag and clears the receive buffer appropriately before starting an SPI data transfer.
I'm not sure if this is a silicon error or a hal error, but this code fixes the issue!
It has preliminary support for the STM32H7 series, as well as 16 and 32bit transfers.
I have only been able to test this code on a STM32F767ZI on SPI 2. More testing will be needed on other platforms to verify this fix.
Impact of changes
Migration actions required
Documentation
None.
Pull request type
Test results
Reviewers