-
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
drivers/spi: reworked SPI driver interface #4780
drivers/spi: reworked SPI driver interface #4780
Conversation
Are there any drawbacks to using a pointer as the |
The advantage of a plain int/enum type for What is the CTAS parameter doing exactly, and do you have this different for different devices on the same bus? And what are the possible values? I think |
@haukepetersen the CTAS parameter allows us to switch between two simultaneous timing configurations in hardware. On mulle we use it to allow using both the rf212b and lis3dh devices on the same bus without reconfiguring/reinitializing the hardware. The rf212b requires mode 0 and <7.5 MHz SCK (+ some other timing settings) while the lis3dh requires mode 3. This was more of a minor oversight when we chose the components for the board in the initial design phase but it's a bigger hassle to change the board design than to adapt the software to use two different SPI settings for the devices when the MCU supports it. edit, Added excerpt from Kinetis reference manual:
edit2: Other boards could potentially use it to support two different speeds on the same bus, for example a high speed setting for a flash chip and a low speed setting for a sensor. Many flash chips support >50 MHz speeds. |
I see, sounds very Freescale specific, I have not seen something like this for any other MCU. Running slaves with the need of different configurations is possible with the interface changes as I proposed them, you even have an unlimited number of configurations :-) For implementations this is intended, so that they re-configure the bus every time the Now for the Kinetis MCUs: I would actually tend to only use only a single |
mostly only little fiddling and assignment of 1-3 registers, so as said, very minimal overhead
I might see the benefit, but I fail to see how to implement this opaque, easy to use and as memory efficient. Mind to show an example? Regarding timings: in my opinion they should not be part of the interface: (i) such settings are only supported by < 25% of the MCUs and (ii) they have practically only a minor relevance. We have not encountered a single device (yet), which needed special treatment and so in my opinion it a 1 in 1000 problem where these settings might be important is not worth the extra code. |
01acbb0
to
8ca2233
Compare
rebased |
What's the state here? |
I don't have a code example for the SPI context, but one piece of hardware that I had some issues with is the AT86RF212B which if running at the maximum baud rate described in the data sheet (7.5 MHz) will need extra delays for t_delay and t_quiet (at Eistec, we had some hard-to-trace problems with settings not registering etc on the transceiver at first, until we found that the delay timings were too fast compared to the data sheet spec even though the baud rate was within spec). |
I think we never saw that behavior, since as long as we were treating the CS lines manually via the GPIO module, the timings were always relaxed enough I guess. But I would still not make timings as part of the interface, I think it should be enough to make them configurable on a board-basis via the periph_conf.h if needed. |
So let's recap where we are with this PR: The proposed changes solve some open issues:
Open points:
IMHO, the timing can be done tuned on a per-board base. Most CPUs don't have support for influencing these anyway, and for those that can be influenced, we can put default parameters into the board's periph_conf.h and let the designer of the board adjust these if really needed. So the biggest question that we have to find a solution to is if there is a better approach on defining devices, e.g. if we should introduce something like a driver specific context structs, that contain all the peripheral configuration for a device driver and which needs to be CPU and driver specific. I personally think this would complicate matters and increase code size quite a bit, while only giving minor benefits for certain use cases. Further nobody has come up with a concrete example how this could be done. So I would tend to stay with the current concept as proposed here. @gebart, @kaspar030, @jfischer-phytec-iot, @thomaseichinger: let's try to find an agreement ASAP and get this over with, so we can focus on more fun stuff the the peripheral driver remodeling... |
Hi. Sorry for hopping in so late. Just wanted to state that I also faced t_delay timing problems on the nrf24l01p driver. Because of that I needed to introduce delays between CS_LOW and SPI_START. Would be helpful to have this configurable in an easy way with internally handled CS-lines. I agree that any adaptions in that direction would increase size and complexity. Currently I have not allround-concept in mind but I can test the nrf24l01p driver once a proposal is here. |
hm, can you elaborate? By looking into the nrf24l01+ datasheet (p. 52-55), I would say the problem with the timings is rather the other way around -> we have to be careful not to be too slow. The minimum time for 't_DEALY' (as in the diagram above) is 2ns, which should not cause any trouble with default SPI parameter?! |
Whoops, you're right. Seems I confused something. So, the delay I talked about was definitively needed on some platforms but as it seems it was unrelated to the device timing requirements but rather to anything else (periph driver implementation?). We should consider that once the nrf24l01p driver is reworked. Please remind me then ;-) |
Ok, then I got it right. @gebart: looking at the AT86RF233 datasheet, I see similar numbers in the range of But anyway, this solves not the problem in general. So to have some kind of control over the timings (which is now more of an issue once the CS line is handled internally), first I would like to make the following simplification: Can we for sake of simplicity boil down all timings to a single number number, being the To then specify this delay, I see again two possibilities: add it as parameter to |
@haukepetersen for the rf2xx, the data sheet says "t_5: LSB last byte to MSB next byte, 250 ns" and "t_8: SPI idle time: SEL rising to falling edge, 250 ns" There's even a 500 ns timing if you are using SRAM in a certain way. The 250 ns timing equates to the same timing as a 4 MHz bus clock, which is how we managed to get the device to ignore some bytes when running at default timings on a 7.5 MHz bus. That t_5 timing is missing from the diagram above, and t_8 is equivalent to t_cs,dis. Here's the diagram from the RF233 data sheet: |
ec54947
to
7b1047f
Compare
rebased for the 500th time |
Does the new SPI increase RAM usage? Or why do you need to blacklist them now? |
I wouldn't think so, but might be. Some of the errors seem completely unrelated, though |
Finally -> green! |
@haukepetersen thanks for your all the work you put into this! I will hit the button in about 4 hours, if not already done by someone else then. We know that there are still some open topics with the SPI rework, which we collect in #6437 and handle in follow-up PRs. |
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.
All right. Let's do this now. ACK and go :-)
Hooray! And congrats! |
Yay! Congrats! |
Yeah! |
Thank you for the huge effort put into getting this PR finished. It was finally merged! Congrats! |
Thanks to everyone for their help! |
Congrats 🎉 |
Yeeeaaah!!! Cheers! 🍻 🎉 |
This reconciles the thunderboard branch with the changes from RIOT-OS#4780.
This PR replaces #3216
Finally here my new approach to optimizing our SPI interface. Major design changes:
I implemented the changes for the
stm32f4discovery
(stm32f4
CPU) to demonstrate how this can be done. On thestm32f4
, the new implementations uses roughly HALF the ROM (~400 instead of ~800 byte), while being more flexible...