SPI / SHIFTIN - High Speed
parsko
Posts: 501
Hi all,
I have, more or less, given up on the search feature in the forums. For some reason, I've never been good at searching (Google is not my friend).
I created an SPI object to interface with a MCP3001 1 channel ADC using SPIN code. The fastest throughput I can get with 10 bits is 0.82ms or 1200 samples/sec. I have a desire to sample faster than that, say at 10,000 samples/second. So, this leads to high speed SPI.
The point above was to point out that I can't find a high speed (costomizable speed) SPI object using the Search engine in the forums. So, I need to write one myself.
Has this been done? Am I reinventing the wheel?
If not, please see the attached. I have included the MCP3001 timing diagram, along with my first start at an object. It is missing mostly everything, except for my outline of how to get it done. I'm not even sure THAT is correct.
Please have a look, as I feel this could be usefull to all in the future. I will not (admittedly) be able to do this by myself. I simply don't know enough about this stuff to make the corect connections/conclusions. But, I want to learn.
My goal:
Have is set-up so that an object can start this in a new cog, and have it update global variables. Also be able to have it capable of using multiple input ADCs. Also to set the bandwidth (baud rate).
Thanks,
-Parsko
I have, more or less, given up on the search feature in the forums. For some reason, I've never been good at searching (Google is not my friend).
I created an SPI object to interface with a MCP3001 1 channel ADC using SPIN code. The fastest throughput I can get with 10 bits is 0.82ms or 1200 samples/sec. I have a desire to sample faster than that, say at 10,000 samples/second. So, this leads to high speed SPI.
The point above was to point out that I can't find a high speed (costomizable speed) SPI object using the Search engine in the forums. So, I need to write one myself.
Has this been done? Am I reinventing the wheel?
If not, please see the attached. I have included the MCP3001 timing diagram, along with my first start at an object. It is missing mostly everything, except for my outline of how to get it done. I'm not even sure THAT is correct.
Please have a look, as I feel this could be usefull to all in the future. I will not (admittedly) be able to do this by myself. I simply don't know enough about this stuff to make the corect connections/conclusions. But, I want to learn.
My goal:
Have is set-up so that an object can start this in a new cog, and have it update global variables. Also be able to have it capable of using multiple input ADCs. Also to set the bandwidth (baud rate).
Thanks,
-Parsko
Comments
Scroll back through the threads looking for a mention of SD or MMC cards and I think you'll find the routines.
Once I get the underlying assm SPI done, I will add a flag to the SPI code itself to "waitpeq", so it won't start until the pin is eiter high or low. When it sees this, it will run through a 4 input ADC routine, using semaphores (or equivalent) to keep the main program from messing with the variables. Dig?
Regarding your suggestion: I have gone through all the posts with SPI and/or MMC, and no luck finding one that reads in SPI via an exclusive assembly program. The obvious links I found were:
http://forums.parallax.com/showthread.php?p=597562
http://forums.parallax.com/showthread.php?p=593778
http://forums.parallax.com/showthread.php?p=588024
http://forums.parallax.com/showthread.php?p=591406
There's a few more I've found, but they weren't too helpful.
Are these what you were refering to?
-Luke
I spent the better part of the day deciphering the timing diagram for the MCP3001. I wrote a sequence that would input the bits, high speed, using assy. I simply have to code it now. I am actually pretty proud of myself. Not only did I figure out this high speed SPI stuff, but I also conquored the Timing Diagrams. The downside: the email I sent to myself from work didn't make it to me... Dat is Jammer!!! The upside: being a paranoid MO-FO, I printed a copy, and brought that home. Who says email is guaranteed?!?
Anyway, I did have one question I couldn't quite put my finger on;
When I code the assm. line to write the bit to my global (or local) variable, what would that command be?
Is assm. capable of writing one bit of a word at a time? Should/could I use an array to do this?
Like I said, I now have the timing down, I just need to code. I think I might be able to get 50kps easy. We'll see...
-Parsko
2) You usually use standard logical operations for bit manipulation. In assembly, really everything is a long. If I'm processing a serial bitstream from LSB to MSB, I usually load a variable with a %1 and shift it left with each cycle like this:
May I comment:
I'm sorry, but I can't figure out how/where the bit is written??
I might be taking your code a bit too literally. Please let me know if this is the case.
I'm getting used to thinking in binary, but it's gonna take more practice and experience.
-Parsko
BTW - Thank you thank you thank you for the help thus far!
Your comments are correct with the exception of the one on the "or" instruction. There I'm essentially copying the contents of the zero flag into the bit in "data" that corresponds to the bit I'm "receiving". The order is LSB to MSB (in this case 8 bits). If I want to reverse the order of the bits, I can initialize "mask" to %10000000 and use a "shr" instead of a "shl". The rest is the same.
The general notion is that I have a bit mask that contains the value of the current bit I'm receiving. If I actually receive that bit, I "or" the mask with the data value I'm accumulating. The next bit to receive has a value two times the value of the current bit and so on.
The "or" instruction is what "writes" the bit. It effectively copies the one bit from the mask into the corresponding bit in data.
When the loop count reaches zero, the byte has been assembled in "data" and is ready to be written to HUB RAM.
You are mostly taking my code literally. It' a pretty simple loop, but the concept may be new to you.
Yeah, you've got to think in terms of binary, bit masks, logical bit arithmetic (and/or/and not/shifts)
My two cents,
Marty
http://forums.parallax.com/showthread.php?p=562370
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
csavage@parallax.com
It simply works. I was so focused on the variable thing, that I didn't even bother a stand alone object with text out built in... and it works. I have to say I'm pretty proud of myself on this one. Extremely proud!! Being a mechanical engineer, only into this whole ucontroller thing for the past year-and-a-half, I never thought I'd be able to do something this high-level/low-level, I don't know, complex. Now that I look at it, it's easy.
But, for now, I am going to go celebrate and spend the rest of the evening with my pregnant spouse. No matter what we watch/do/complain about, there will be a smile on my face!
Please see attached, if you have an MCP3001 layin around, plug it in. I will tweak this in the future to make it a bit more streamlined. I am also open to suggestions to make it more compact.
-Luke
Again, wow! The prop is such an amazing tool to work with. Now that I have tackled an assy program, I realize the power we have at our disposal. I really like the assy thing, A LOT!!! Assy isn't as hard as I thought it would be. But, I've never used any other assy before, so I guess I can't compare.
Toodles,
-Luke
PS- The super high speed version is attached...