Accessing individual bits in a variable (serial sequencing, MSB first)
AkkerKid
Posts: 1
I'm trying to compact my homemade SPI bus protocol into a repeat loop (for a huge series of "outa" commands) and I'm having trouble outputting individual bits from a variable in sequence.
For starters, the data going out can be of any length up to 32 bits.· The clock must be toggled twice between each bit.· and the data must be run through serially MSB first.
this is what has worked but I don't like it:
PUB send (din,dout,clk,cs,speed,input_length,input_data)
···
··· input_data ><= input_length········ 'reverse the data
··· repeat input_length···················· 'repeat for the length of the data (supplied by overhead process)
····· waitcnt(cnt+speed)···················'slow the process down
····· outa[noparse][[/noparse]din]:=input_data[noparse][[/noparse]0]··········· 'output on the "din" pin based on the state of 0th bit (the LSB)
····· outa[noparse][[/noparse]clk]~······························ 'clock line goes low
····· waitcnt(cnt+speed)·················· 'slow the process down
····· outa[noparse][[/noparse]clk]~~···························· 'clock line goes high
····· input_data >>= 1····················· 'bits are shifted right, dropping LSB
What I'd much rather do is iterate through the repeat without manipulating the data:
PUB send (din,dout,clk,cs,speed,input_length,input_data) | index·
··· repeat index from (input_length-1) to 0
····· waitcnt(cnt+speed)···················'slow the process down
····· outa[noparse][[/noparse]din]:=input_data[noparse][[/noparse]index]······ 'address a·bit in the variable and·output it
····· outa[noparse][[/noparse]clk]~······························ 'clock line goes low
····· waitcnt(cnt+speed)·················· 'slow the process down
····· outa[noparse][[/noparse]clk]~~···························· 'clock line goes high
I can't get this to work and I'd really like to know why.· My only thought is that spin will not give me a bit in a location addressed higher than 7th place.
···
For starters, the data going out can be of any length up to 32 bits.· The clock must be toggled twice between each bit.· and the data must be run through serially MSB first.
this is what has worked but I don't like it:
PUB send (din,dout,clk,cs,speed,input_length,input_data)
···
··· input_data ><= input_length········ 'reverse the data
··· repeat input_length···················· 'repeat for the length of the data (supplied by overhead process)
····· waitcnt(cnt+speed)···················'slow the process down
····· outa[noparse][[/noparse]din]:=input_data[noparse][[/noparse]0]··········· 'output on the "din" pin based on the state of 0th bit (the LSB)
····· outa[noparse][[/noparse]clk]~······························ 'clock line goes low
····· waitcnt(cnt+speed)·················· 'slow the process down
····· outa[noparse][[/noparse]clk]~~···························· 'clock line goes high
····· input_data >>= 1····················· 'bits are shifted right, dropping LSB
What I'd much rather do is iterate through the repeat without manipulating the data:
PUB send (din,dout,clk,cs,speed,input_length,input_data) | index·
··· repeat index from (input_length-1) to 0
····· waitcnt(cnt+speed)···················'slow the process down
····· outa[noparse][[/noparse]din]:=input_data[noparse][[/noparse]index]······ 'address a·bit in the variable and·output it
····· outa[noparse][[/noparse]clk]~······························ 'clock line goes low
····· waitcnt(cnt+speed)·················· 'slow the process down
····· outa[noparse][[/noparse]clk]~~···························· 'clock line goes high
I can't get this to work and I'd really like to know why.· My only thought is that spin will not give me a bit in a location addressed higher than 7th place.
···
Comments
You can't do this.
Only registers are bit addressable. What you are doing here is using input_data as an open ended array of whatever data type you defined it as.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pull my finger!
You are setting all pins with this statement, not?
Needs to be outa[noparse][[/noparse]din]:=input_data& $80000000
You can replace
outa[noparse][[/noparse]din] := input_data[noparse][[/noparse]index]
by
outa[noparse][[/noparse]din] := input_data>>index
this shifts the desired bit right into bit 0, and then bit0 is copied to outa[noparse][[/noparse]din]
Andy