the data within the stream. The process is simple: After a
break period of at least one millisecond, the board expects
to see up to 16 packets of eight-byte lamp dimmer values.
The address of the board determines which group of bytes
are plucked from the stream and transferred into the
dimmer control registers (chan1–chan8).
The break period is detected by a small section of code
in the ISR. Each time through it will increment a counter
(break Tmr) when the receive line is idle, otherwise, it will
clear this counter and the associated flag (hasBreak). When
the value of break Tmr reaches 154 (about a millisecond),
the hasBreak flag is set and the timer is restarted.
JNB RX, RX_Has_Bit
CJB breakTmr, #BreakCnt, Check_Break_Exit
Remember that a start bit and zero bit in this system
will pull the RX line low, hence the use of JNB (jump if this
bit is 0). By installing this code in the ISR, the foreground
program can simply look for the setting of the hasBreak flag
to indicate that a valid break period has been detected.
breakTmr = 0
hasBreak = No
DO WHILE hasBreak = No
Once the break is detected, we need to flush the
receive UART before proceeding. This seemingly innocuous
step caused me three days of headaches trying to track
down a “fluttering” problem with my lamps. While I had
been clearing the rxReady flag, I neglected to clear rxCount
— this value controls bits coming into the [free-wheeling]
UART. What was happening, I believe, is that garbage values in rxCount caused misaligned data and corrupted my
dimmer values. It was horribly frustrating — I even called
Peter to ask him to review my code to see if I was missing
something. Sometimes just talking through a problem with
a friend can be helpful and I finally determined the problem
while explaining to Peter how the program works.
rxCount = 0
rxReady = No
The next step is to read the board address and multiply that
by eight so that we know how many bytes in the stream to skip.
idx = 0
idx.0 = ~Addr.3
idx.1 = ~Addr.2
idx.2 = ~Addr.1
idx.3 = ~Addr.0
idx = idx << 3
This looks like more work than what’s needed; I did it
this way to “fix” a board layout issue — what I wanted to do
is have the LSB of the switch be to the right so I could read
the markings on the SX28. As the LSB switch is actually connected to RA. 3 instead of RA.0 (see Figure 6), we manually
construct the value to mirror the bits of the address. There
may be some chunk of cute code out there to mirror a byte,
but this bit-by-bit approach seemed to make the most sense
to me. The board address, now in idx, is multiplied by eight
(<< 3) to determine the number of bytes to skip.
And here’s how we do that:
■ FIGURE 6.
November 2007 17