Two Qs regarding jm_ez_spi_demo code. Division and Rev operation
Hi, All.
Long-time Propeller 1 user (dozens of successful projects), now playing with Propeller 2 Edge Module. I will eventually be writing code to communicate via SPI with the Adc-6-Click (https://www.mikroe.com/adc-6-click) an 8-ch 24-bit ADC. If anyone has already written code for this device please let me know, I would hate to re-invent the wheel !
I'm using Johnny Mac's jm_ez_spi demo code as a starting point for learning P2 coding.
I have two hopefully-simple-to-answer questions after taking a deep dive into his code:
Q1: Within jm_ez_spi.spin2 file:
At function: pub start(sdipin, sdopin, sckpin, khz) : result | m, x
There is a line of code:
x.word[0] := 2 #> (clkfreq / (khz*1000)) <# $FFFF ' ticks in period
I have a question regarding the division operator "/" in P2.
The Spin2 documentation file shows:
"/" as a "signed divide, return quotient"
and "float expr" is checked.
Elsewhere: "Floats are encoded in IEEE-754 single-precision 32-bit format"
P2 Feature Description: "2-clock execution for all math and logic instructions, including 16 x 16 multiply"
MY QUESTION is in regards to how P2 handles division in general.
Is 16-bit division operation built-in to the P2 assembly ? (I don't think so)
Has Chip incorporated a division routine into his SPIN2 implementation ?
I was not expecting the "/" operation to work for non-constant operations
(in other words, I thought it would be restricted to compile-time only use, like the P1).
So how should I understand the availability of integer division in SPIN2 ?
Q2: Within jm_ez_spi.spin2 file:
At function: pub shiftin(mode, bits) : value
There is a line of code:
value rev= 31
The Spin2 doc file explains: for "var REV= y" : "Reverse y LSBs of x and zero-extend"
I assumed that to reverse the bit position for all 32 bits the expression should read:
"value rev= 32"
I modified the code, and of course it bombed, so "31" is obviously correct.
MY QUESTION:
Should the documentation file be changed to read "Reverse y+1 LSBs of x and zero-extend" ?
Thanks for any guidance you may have to offer. Looking forward to using the P2 in a lot of future work.
Greg
Comments
Please use
code
where necessary. Surround with one backtick for inline, three for a block.Q1 This is spin code.
Assembler has a fast 16*16 hardware multiply and a slower cordic hardware multiply and division.
P2 Manual gives some hints about cordic.
The Spin2 interpreter has a built in routine for 32:32 integer division which uses the CORDIC solver. There is no (single, 2-clock) assembler instruction for division. But there's a scaling instruction (SCA) that can be used to divide by a small constant number with fairly good precision.
Spin also can handle floating point division. "/" always worked for constant float numbers and recently support for runtime floating point math was added. But you need to use "/." instead of "/" because the compiler doesn't keep track of the type of variables.
I did some further experimenting with a block of SPIN2 code using the P2 Edge Module (with its 20MHz crystal) and
_clkfreq = 200_000_000
...Debug spits out 224 cycles (or 1.12uS) of elapsed time for the integer division operation shown above.
The reply from ManAtWork:
seems to be the most logical answer.
By the way ....
When substituting
c1:=1
, I get 80 cycles (or 400nS) of elapsed time.When commenting out the entire line of code I get 40 cycles (or 200nS) of elapsed time.
Remember that it takes time to read the system timer so you have to remove that if you're looking at sub-microsecond accuracy. I do timing checks like this
You'll may need to adjust the constant at the end based on the compiler you're using.