Trouble shifting bits
lardom
Posts: 1,659
in Propeller 1
I've been trying to write a method for SPI and what I thought would work doesn't. The code I've written will read the bits right to left but I had to add another zero to the right. I'm testing it with leds. The line I commented out works the same as the binary line.
PUB READ_BYTE | idx dira[1]~~ dira[2]~~ Test_Byte := %1110010110 repeat idx from 1 to 9 outa[2] := %1110010110 >> (idx) 'outa[2] := Test_Byte >> (idx) waitcnt(clkfreq/4 + cnt) outa[2]~ waitcnt(clkfreq/4 + cnt)
Comments
Only Shift right worked though and I'm hoping someone can tell me why.
Enjoy!
Mike
IMHO, using numbers for pins and the post ~ and ~~ is a recipe for bug generation. I've used the code above in a number of apps. It's flexible, which makes it easy to use, and readable, which makes it easy to debug. "Quick and dirty" is never quick, but always dirty.
Thanks JonnyMac, I'll run this on the PST. I did want to make 'sure' the bits were shifting before started thinking about clocking data.
Counting from 1 to 9 means that you're not getting the lowest bit value, because the smallest shift you use is 1, not 0.
I think you missed this from lardom's post:
I looked at his code and didn't see any major issues, which made me wonder if he had his LED wired correctly.
-Phil
110100111
110100111
Mine is the first one, iterating the bits from 0 to 8, without the extra zero on the value. His is the 2nd one, with the extra zero, iterating the bits from 1 to 9.
I also learned the purpose of 'rotate bits' 'reverse bits' and 'shift bits'. BTW, thanks for the tips on hexadecimal and binary numbers. I'm using both in building the code for my current project.
One of my questions is does a 32-bit-shift move those bits to a different register?
In Spin, unless you use an assignment operator (e.g. "x := 2" or "x += 2" or "x >>= 2", as opposed to "x >> 2", which is not an assignment operation), it will never overwrite a value. Shifting a value with the normal ">>" right shift will not overwrite the old value but will only return the shifted result, while the ">>=" right shift will overwrite your value.
I'm sorry if I misunderstood your question or if I confused you even more with my answer.
Before you freak out - bits/2 has the same effect as bits >>1 because we are in the binary system. To compare, in decimal system say 200>>1 has the same effect as 200/10, 10 being the base of decimal, while 2 is being the base of binary.
Erlend
Yes /2 and >>1 are the same, only that a division takes about thousand clock cycles, while the shift takes 4 clock cycles.
So never do shifts with multiply and division in Spin. C may optimize that to a shift, but Spin does not.
Andy
Edit: As I rethink it: /2 and >>1 is not exactly the same, one works with signed numbers the other with unsigned, so /2 and ~>1 is the same.
frida, I'll copy and paste. Thanks.
>> can be used in place of division when divisor is power of 2 (2, 4, 8 16...).
<< can be used in place of multiplication when multiplier is power of 2.
Instead of
you can use:
because 8 is 2^3. Same rules apply for dividing by right shifting.
Additional tip: If you're dividing a signed number that can be negative, there is an operator called SAR that looks like this ~>. This operator will preserve the sign of the value value being divided (>> pads the sign bit end with zeroes for each bit shifted). As Andy pointed out, using shifts for multiplication and division where possible are faster than * and / operators.
1 / 2 = 0 (in integer math)
-1 / 2 = 0
1 ~> 1 = 0
BUT
-1 ~> 1 = -1
So, in very specific cases, signed right shift is not the same as divide by two.
I do now have a working SPI method, mode 0, msb 1st. Thanks to everybody.
My apologies in advance if that seems nitpicky ...
-Phil
'Apologies' from the guy who used Goertzel's algorithm to program the Propeller to respond to spoken words???