-
Notifications
You must be signed in to change notification settings - Fork 2k
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
cpu/stm32f1: optimize SPI driver #5921
Conversation
I've tested this PR with gnrc_networking on iotlab-m3 boards and between one samr21-xpro and one iotlab-m3 board. Pinging 1000 times with 1000 Bytes payload and without delay never lead to packet losses of more than 1%, independent who has pinged. |
With this PR the inter-byte delay can be reduced from 800ns to ~440ns |
transferred++; | ||
while (!(spi->SR & SPI_SR_RXNE)) {} | ||
in[i] = (char)spi->DR; | ||
transferred++; |
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.
Is it desired to increase transferred
twice when you are sending and receiving? If not, you could use transferred
(or a renamed version of it) as a counter for the loops.
} | ||
else { | ||
DEBUG("\nout: %x in: was nullPointer transferred: %x\n", out, transferred); | ||
DEBUG("\nSPI: 'in' NullPointer. Transferred %i Bytes\n", transferred); | ||
} | ||
#endif /*ENABLE_DEBUG */ |
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.
Maybe you can merge those two now that you only have a parameter to print and remove the if
Is it desired to increase |transferred| twice when you are sending and
receiving?
No. That was done in one early driver, but was a bug that got copied
into later drivers.
|
Addressed. Actually I was quite confused about that as well but decided to leave it as is at that time. |
Added a commit to improve "read only" speed |
@@ -275,20 +288,23 @@ void spi_poweroff(spi_t dev) | |||
switch (dev) { | |||
#if SPI_0_EN | |||
case SPI_0: | |||
while ((SPI_0_DEV->SR & SPI_SR_BSY)) {} |
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.
Really needed? IMHO the device can not be busy when this function is called, as it is only busy during transfer and it is check for not being busy when we leave that function. Also the device is locked when using _transfer()
-> so it can not be busy here. Makes sense?
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.
I don't see it critical as well. I've added it for safety reasons. In the referance manual page 721 sec. 25.3.8 Disabling the SPI it is said "Then wait until BSY=0"
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.
ok
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.
ACK
I removed the WIP, was that ok? |
Wait I need to squash first and revert the first commit. Need to wait for #5886. |
0975e37
to
d223eb8
Compare
Rebased and squashed |
@haukepetersen I see many green lights |
} | ||
else { | ||
DEBUG("\nout: %x in: was nullPointer transferred: %x\n", out, transferred); | ||
DEBUG("\nSPI: transferred %i Bytes\n", transferred); |
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.
One last comment (sorry @PeterKietzmann), we could actually get rid of transferred
since at this point transferred
will always be length
. Its super minor but would save 4 bytes :-)
d223eb8
to
bb4bf51
Compare
@lebrush fine, did that |
Everyone is happy -> go |
Wait! you left transferred variable defined and returning always 0 ... |
{ | ||
|
||
SPI_TypeDef *spi; | ||
int transferred = 0; |
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.
yup, this needs to be int transferred = 0 = length;
Sorry. Never do such things in a hurry (like exactly now). See #5966 |
cpu/stm32f1: remove leftover from #5921
-this PR needs further testing (that's why I set the WIP label). Support is happily welcome!