simple, we’ll use a word variable to receive the return value
from VAL_TO_PACKW.
FUNC VAL_TO_PACKW
IF __PARAMCNT = 1 THEN
tmpW1 = __PARAM1
ELSE
tmpW1 = __WPARAM12
ENDIF
tmpW1 = tmpW1 << 1
tmpW1_LSB = tmpW1_LSB >> 1
tmpW1_MSB = tmpW1_MSB & $7F
RETURN tmpW1
ENDFUNC
This function is set up to accommodate bytes or words
so that we can also use it in future MIDI applications. The
value to split is moved into tmpW1 and then shifted left.
This moves BIT7 of the lower byte into BIT0 of the upper.
The next step is to shift the lower byte right by one to re-align its BIT0; BIT7 of the low byte will now be 0 as required
by the protocol. The final step is to ensure that BIT7 of the
high byte is clear before returning the new value.
We will move the low byte of the return value to fifo(1)
and the high byte to fifo( 2) – fifo(0) already holds the port
number so we don’t have to change that. The message is
set to RD_PORT_ACK, the packet length to three, and then
we send the response.
While chatting with Peter about networking, he told me
— and he was — that designing these kinds of projects can
turn into a bit of a chicken-and-egg dilemma. Testing a node
requires another node, and writing the code for that requires
specifications on both ends. Case in point is when I was
sending a bad port number from my PC node; the slave
node originally sent a MSG_FAIL packet (just four bytes), but
my PC node was expecting success and waiting for seven.
To keep things easy — and easy is usually best — the slave
node will always have a three-byte packet for RD_PORT,
even if the return message is MSG_FAIL. The port number is
maintained so the master node can deal with it, and the
incoming transmission processing is simplified by assigning
an expected return message length to each command.
You’ve probably noticed that all message handlers
jump to a routine called Unit_Reply. Here it is:
Unit_Reply:
IF rxNode = MY_NODE THEN
rxNode = txNode | $80
TX_BYTE rxNode
TX_BYTE MY_NODE
TX_BYTE msgNum
TX_BYTE packLen
idx = 0
DO WHILE idx < packLen
TX_BYTE fifo(idx)
INC idx
LOOP
ENDIF
GOTO Main
The only time a node will send a response is when the
STAMP APPLICATIONS
■ FIGURE 3.
SX-Net bench test.
node is individually addressed. A node could, for example,
send a message to the global address of 0 that all nodes
react to; in this case, there will be no responses from the
nodes as they would likely end up stomping on each other
and the messages would be trashed. You can see that
Unit_Reply takes the sender node address and turns it into
the header start byte by setting BIT7.
Okay, now we have the makings of a reasonably
sophisticated control network using the SX, and can do all
kinds of cool things with it. Figure 3 shows my first prototype node along with a port-powered RS-485 interface, and
Figure 4 shows the VB test node for experimenting with
messages (the compiled program and source code is
included in the download files for the article). In the Query
frame, you can see four primary values; these comprise the
message header. The middle row of inputs allows for
uncompressed data. The lower row of [red] boxes shows
the actual packet bytes transmitted to the receiver node.
The Response frame is similarly constructed, except that the
middle line holds seven-bit “packed” values and the lower
■ FIGURE 4. SX-Net test panel.
January 2008 19