SPI Coms: Smart Pins vs Bit-Banged
JonnyMac
Posts: 9,104
I'm working on a flash object for the P1 and thought it would be best to work on the P2 version at the same time -- especially with the P2 Eval board conveniently having a flash chip ready to run with. I had a couple of frustrating days getting the smart pins code to work (it does now).
The attached code is the result of my experiments and may be useful to those wanting to play with smart pin SYNC TX and RX modes (SPI). As you go through you can see that I get things working in Spin, then translate to inline PASM. I left the Spin code [commented] in place so that you can see my journey, or just use it as is.
While speaking with Chip yesterday he suggested that SPI is so easy it might just be better to code it rather than using a smart pin. I think this experiment bears that out. Still, the code as I have it is blocking -- the advantage of a smart pin is that you can set it and forget it until later.
Anyway, your feedback is appreciated. We're all still new at the P2, and I'm especially new at PASM2.
Update: Reduced BB PASM2 for shiftin() by one instruction.
The attached code is the result of my experiments and may be useful to those wanting to play with smart pin SYNC TX and RX modes (SPI). As you go through you can see that I get things working in Spin, then translate to inline PASM. I left the Spin code [commented] in place so that you can see my journey, or just use it as is.
While speaking with Chip yesterday he suggested that SPI is so easy it might just be better to code it rather than using a smart pin. I think this experiment bears that out. Still, the code as I have it is blocking -- the advantage of a smart pin is that you can set it and forget it until later.
Anyway, your feedback is appreciated. We're all still new at the P2, and I'm especially new at PASM2.
Update: Reduced BB PASM2 for shiftin() by one instruction.
Comments
The four instructions from WYPIN to WAITXFI form the code that reads in up to 65,504 bits at a whack from the flash chip. That's one byte every 16 clocks.
Here are the program and boot times from the flash loader, assuming a 20MHz RCFAST clock, which is actually more like 24MHz, but that wouldn't speed up programming, only booting:
The forums is doing that glitchy thing again where updated code doesn't show up. If you click on the data/time of the edit in my original post, the link to the code will re-appear.
When Jon and I spoke about this yesterday, we were talking about using the 'synchronous serial' smart-pin mode for this job, and my mind immediately got plugged up with details that would need to be worked through. Eventually, we will have enough samples and documentation that all the difficulty will be tamed, but for now it's still challenging. Part of my mental block was that I remembered that I used the 'transition' smart-pin mode and the streamer to accomplish all this in the flash loader, with the added benefit of having the streamer handle all the data I/O to and from hub RAM, without any extra activity in my code. So, I was kind of spoiled with one solution that I know works best for flash I/O.
While frustrating, this turned out to be a worthwhile learning experience, and now there is a bit of code in both styles (bit-bang vs smart pin) and languages (Spin2 vs PASM2) that may help others get into the grove.
Ultimately, a flash object will benefit from a very fast sector<-->buffer transfer. I'm going to do it with the code I have, then may ask for help in updating it to use the streamer.
And smartpin SPI only works up to 1/5 or 1/6 of the system clock, while bitbanged, or with Streamer together with a smartpin for clocks can go up to 1/2 sysclock and has no pinlayout limitations.
But for inline assembly-SPI for SD cards smartpin SPI is probably still the best solution.
Andy