As you can see, we pass the chip select pin,
the clock pin, and the data I/O pin to the init()
method. The /CS pin is set to output and high
to deselect the ‘3204 while the clock pin is set
to output and low; the data I/O pin is left in
input mode until we need it.
Astute readers (that would be you!) will ask,
“Why do we need to pass pin numbers when
they won’t change in a program? Can’t we just
set them as constants?” We could, but it’s a bad
idea for reusable objects like this. If we used
constants for the pin numbers, we’d be forced
to either: 1) always use the same pin numbers
in every design (impractical); or 2) keep
multiple copies of the object with different pin
numbers which is also impractical when it
comes to maintenance and upgrades. So, the
lesson here is this: When designing a Propeller
object, keep it concise yet flexible enough to be
re-used in any of your designs. This will make
your life simpler, and those downloading your code from
the Object Exchange (ObEx) will thank you.
There are two variations of read methods and, in fact,
one calls the other. The reason for two methods is to
accommodate different programming styles. The first
variation expects the channel number (0 to 3) and the
mode (1 for single-ended; 0 for differential):
■ FIGURE 2. MCP3204 Circuit.
pub read(ch, m) | mux
mux := %1_0000 | ((m & 1) << 3) {
} | (ch & %11)
return readx(mux)
The channel and mode settings are used to create a
five-bit configuration word with masking and bit shifting;
this value will be passed to the readx() method that
actually does the heavy lifting:
pub readx(mux) | level
outa[cs] := 0
dira[dio] := 1
mux <<= constant(32-5)
repeat 5
outa[dio] := (mux <-= 1) & 1
outa[clk] := 1
outa[clk] := 0
dira[dio] := 0
level := 0
repeat 13
outa[clk] := 1
outa[clk] := 0
level := (level << 1) | ina[dio]
outa[cs] := 1
return (level & $FFF)
If this code looks a little bit familiar, well, it should. It’s
really a combination of code that simulates the PBASIC
SHIFTOUT and SHIFTIN instructions; we used code
identical in the latter portion when reading the 74x165
shift-register on the encoder board (Nuts & Volts, May
‘ 10). Just a note on my method of naming convention:
When I have two methods that are similar and one is a
simplified interface into the other, the method that really
does the work tends to get appended with “x” (for explicit).