Question regarding Dira and in/outa selecting pins
frank freedman
Posts: 1,985
in Propeller 1
Yeah, the subject line is rather lumpy, hard to say it in a short blurb.
In the Prop Ed manual and the Prop manual v1.2, there are examples of DIRA[3] or DIRA[9..11] etc, but there does not seem to be a way to set the pin range as a constant or otherwise in the Con block of the code. So, down in some object, there ends up being a line like
DIRA[0..3]~ ' set input pins for partx
but it would be nice to be able to have a Con block entry like
...
PartX_inp = something
and down in some part of the code a line like
DIRA[PartX_inp]~
INA[PartX_inp]
...
So, the question is did I miss something or is this not possible to do with the Prop1
Thanks
In the Prop Ed manual and the Prop manual v1.2, there are examples of DIRA[3] or DIRA[9..11] etc, but there does not seem to be a way to set the pin range as a constant or otherwise in the Con block of the code. So, down in some object, there ends up being a line like
DIRA[0..3]~ ' set input pins for partx
but it would be nice to be able to have a Con block entry like
...
PartX_inp = something
and down in some part of the code a line like
DIRA[PartX_inp]~
INA[PartX_inp]
...
So, the question is did I miss something or is this not possible to do with the Prop1
Thanks

Comments
Remember, too, that when writing to a group of outputs there is a binary transfer so it's usually best to be obvious. For example, if you have three pins that correspond to an RGB LED.
The first line makes the red LED output high when the second line sets the RGB pins to output mode.
Pin fields and bit fields exist in the P2 which simplify (in many cases) some of this stuff.
Bit 0 11110000
Bit 1 11101100
Bit 2 11011111
Bit 3 10001010
Bit 4 10001010
Bit 5 10001010 <====== from 8 MCP3201s into pins 1-8
Bit 6 10001010
Bit 7 10001010
Bit 8 10001010
Bit 9 10101010
Bit 10 11101010
Bit 11 11111110
Channel 0 0200 631mV
Channel 1 03FF 1261mV
Channel 2 0601 1894mV
Channel 3 07FF 2523mV
Channel 4 0A01 3157mV <======== Bit Array rotated into channels results of hex values match values on AD2 SPI capture
Channel 5 0C07 3796mV
Channel 6 0E03 4422mV
Channel 7 0FFF 5048mV
Clock Counts = 608656 <== ballpark PC counts. ~7ms, AD2 shows conversion time of ~1.5ms CS* pulse width
PUB ReadADCs (DataArray, Bits, Lead, CS, CK, ChannelArray, ChanCnt, ChanBase )| ChanEnd, Selector, x, y Bits-- ' correct for loop bit count Lead-- ' correct for loop lead pulse count ChanCnt-- ' same for channel count for ch 0 - channel m-1 ChanEnd := ChanBase+ChanCnt ' determine channel high pin. Pins must be contiguous dira[ChanBase..ChanEnd]~ repeat x from 0 to bits ' clear bits array word[DataArray][x] := 0 repeat x from 0 to ChanCnt ' clear channel array word[ChannelArray][x] := 0 outa[CS..CK]~ ' start with clock low and dira[CS..CK]~~ ' set chip sel to output outa[CS]~ ' drop CS to start sequence waitcnt(clkfreq/90000 + cnt) repeat x from 0 to Lead ' waste 3 pulses for capture and hold time waitcnt(clkfreq/90000 + cnt) ' could have just dummped this section and captured all 15 outa[CK]~~ ' counts here, but that would have made things more complex later waitcnt(clkfreq/90000 + cnt) ' this actually came out faster in the overall result outa[CK]~ repeat y from 0 to Bits ' get data bits from MSB to LSB (because that is the order they read out) waitcnt(clkfreq/90000 + cnt) outa[CK]~~ waitcnt(clkfreq/90000 + cnt) byte[DataArray][y] := ina[ChanBase..ChanEnd] ' get the data bit for all channels outa[CK]~ outa[CS]~~ ' until all bits for all channels are in an array x bits deep and y channels wide repeat x from 0 to Bits ' Convert bits to channels starting with MSB repeat y from 0 to ChanCnt ' unwind the bits for each channel Selector := |< y ' Use bit selector to identify destination channel if ( Selector & byte[DataArray][x]) ' is bit 2^n set for channel m word[ChannelArray][y] ++ ' if true +1 then word[ChannelArray][y] <<= 1 ' shift word for next value repeat y from 0 to ChanCnt ' unwinding leaves one extra shift per channel word[ChannelArray][y] >>= 1 ' shift word right to correct for extra shiftAssumptions
-- you're accessing all ADCs at the same time (i.e., CS and CLK are tied to all devices)
-- you have 8 MISO pins connected to the Propeller
If that's the case, I think you can simplify your code. As we say in Hollywood.... for your consideration:
pub read_adcs(bits, p_dest) | temp[8], ch outa[CS] := 0 longfill(@temp, 0, 8) ' clear temp repeat 3 ' lead pulses outa[CLK] := 1 outa[CLK] := 0 repeat bits ' read ADCs outa[CLK] := 1 repeat ch from 0 to LAST_CH ' loop through channels temp[ch] := (temp[ch] << 1) | ina[MISO+ch] ' get bits, MSBFIRST outa[CLK] := 0 outa[CS] := 1 longmove(p_dest, @temp, work) ' copy local array to targetNotes:
-- The CS and CLK pins should be defined using constants, and set to outputs (CLK low, CS high) at start-up
-- The LAST_CH constant is the index of your last channel.
-- ADCs are connected as a contiguous group in ascending order
Advice:
-- Don't use the ~~ and ~ operators; they are confusing and slower than straight assignments.
-- You're adding delays that are probably not necessary; that device can run 800kHz and you'll never hit that with bytecode Spin
Thank you Jon, that is some nice work. Difference between master and (probably) apprentice. Hence my doing a bit more brute force coding and refinement once working. Still more to learn. Will try this. Did not think of reading all the bits in the clock period. Also didn't know that ~ and ~~ was slower.
Your assumptions are spot on, I had a handful of this part to play with and even though this is on a mini, pin count isn't yet a problem.