SPI Engine faster ?
BTX
Posts: 674
Hi all .
I was looking for an SPI engine object, and I've found, Beau Schwabe·code object.
Is avoiding the "setcommand(cmd, argptr)" method in the engine, and passing data by command directly·?
Or are you refering, another way, to get 2.5M in assembly ?
If I could do a caller in assembly....how to call SPI Object ?? If I'll do in spin, just your demo code !! it's did·...sorry that's confusing me.
This is a part of the engine for reference:
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
I was looking for an SPI engine object, and I've found, Beau Schwabe·code object.
How to call SPI through assembly faster ?.Beau said...
Notes:
Consecutive SHIFTIN/SHIFTOUT updates through Spin at 80 MHz is about 14kHz (Bit rate about 112k)
Consecutive SHIFTIN/SHIFTOUT updates through Assembly at 80 MHz is about 310kHz (Bit rate about 2.5M)
Is avoiding the "setcommand(cmd, argptr)" method in the engine, and passing data by command directly·?
Or are you refering, another way, to get 2.5M in assembly ?
If I could do a caller in assembly....how to call SPI Object ?? If I'll do in spin, just your demo code !! it's did·...sorry that's confusing me.
This is a part of the engine for reference:
CON #1,_SHIFTOUT,_SHIFTIN VAR long cog, command, Flag PUB SHIFTOUT(Dpin, Cpin, Mode, Bits, Value) 'Once called from Spin, SHIFTOUT remains running in its own COG. if Flag == 0 'If SHIFTOUT is called with 'Bits' set to Zero, then the COG will shut start 'down. Another way to shut the COG down is to call 'stop' from Spin. setcommand(_SHIFTOUT, @Dpin) PUB SHIFTIN(Dpin, Cpin, Mode, Bits)|Value 'Once called from Spin, SHIFTIN remains running in its own COG. if Flag == 0 'If SHIFTIN is called with 'Bits' set to Zero, then the COG will shut start 'down. Another way to shut the COG down is to call 'stop' from Spin. setcommand(_SHIFTIN, @Dpin) result := Value '------------------------------------------------------------------------------------------------------------------------------ PUB start : okay '' Start SPI Engine - starts a cog '' returns false if no cog available stop Flag := 1 okay := cog := cognew(@loop, @command) + 1 PUB stop '' Stop SPI Engine - frees a cog Flag := 0 if cog cogstop(cog~ - 1) command~ PRI setcommand(cmd, argptr) command := cmd << 16 + argptr 'write command and pointer repeat while command 'wait for command to be cleared, signifying receipt '################################################################################################################ DAT org ' ' SPI Engine - main loop ' loop rdlong t1,par wz 'wait for command if_z jmp #loop movd :arg,#arg0 'get 5 arguments ; arg0 to arg4 mov t2,t1 ' │ mov t3,#5 '───┘ :arg rdlong arg0,t2 add :arg,d0 add t2,#4 djnz t3,#:arg mov address,t1 'preserve address location for passing 'variables back to Spin language.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Comments
have the cog always running, and give it a status byte to determine it's current status (you can use locks as well if you wish to have halting calls)
Something like
Have the cog running the SPI routines poll count... if it is non zero, set the lock, and set status to logical true. Have it progressively shift out the buffer, while shifting in to the same buffer. After it's done, release the lock and set status to zero.
That way, you main application can do other things while it's running, and you can spi out multiple bytes.
Also, avoiding generic SPI calls would aid you in avoiding large delays. You my also consider just writting it in spin. Although the execution time is relatively low, you would avoid wasting a cog and there is no need for excessive load times.
Remember that booting a cog takes ~8000 cycles, so spin would most likely be faster.
First·of all, thanks so much fo the suggests.
I'm totally agree with you, about to have the cog always running, I don't know that, but 8000 clocks is too much time while booting a cog.
Just I need to send packets of data (of 192 Bit each) to a SPI peripheral, it is important to do that, and maintain those packets in a buffer, so you're poiting exactly in my future application.
Perhaps, I can not express me correctly, and could be a missunderstanding in my questions (or I don't understand your explanation...).
Tha byte that you name "status" ....is not the same as Flag, in the example that I post. ?? (Supoosing the cog is running and the "start' line is not write there....)
If I have the cog running all time, How to pass the values to the SPI engine ?? or.. how to get the comand variable actualized, with a new value from outside the SPI driver..?
Could I avoid this part of spin code ?? and be replaced with some using command := buffer[noparse][[/noparse]data1] etc. ?
Regards and Happy New Year !!
Alberto.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
You just want to have the cog that would be doing the SPI code constantly polling a value (command), and when it sees a non-zero command, have it start it's shift in / shift out code. flags / status would just be a method of determining the status.
You would also want the cog to clear the command value so it doesn't auto repeat after everything is said and done.
I went ahead and slapped this together. It's basically the most efficient method of doing SPI transfers if the buffers are largeish.
The SPI code is missing because I'm not 100% sure on the asm syntax, but it should at least give you an idea of what I'm thinking of.
because this includes some assembly SPI code that is for the secure digital cards. There is one Spin version
and two assembly versions. They are not the absolute fastest but they are not bad.
Sorry, I haven't replied sooner, I have been busy over the Christmas and New Year holidays.
The two statements...
Consecutive SHIFTIN/SHIFTOUT updates through Spin at 80 MHz is about 14kHz (Bit rate about 112k)
Consecutive SHIFTIN/SHIFTOUT updates through Assembly at 80 MHz is about 310kHz (Bit rate about 2.5M)
...are simply indicating a measured thru-put based on an 8-byte data value. If you are using Spin and send
data in a continuous stream. You can expect a thru-put of about 14kHz. If you strip down the assembly code
essentials and use the assembly portion that performs SHIFTIN/SHIFTOUT routines and never leave the assembly
environment, then the thru-put increases to about 310kHz.
http://forums.parallax.com/showthread.php?p=602056
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
I'll be trying your suggests, after a new post.
Regards.
Alberto.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔