Documentation for Firmware D, version 1.1
for UBW Boards
SparkFun ships this fimware version on their UBW boards
Back to
main UBW page
Description:
Firmware version D is a more advanced (and more complicated) firmware
version than Firmware C. Wheras C just allows you to write out 8 bits
at a time to Port B, Firmware D allows you to use every one of the 19
I/O pins on the UBW Board as an input or an output, and to read the
state of every one of those pins. In order to do this, it has an actual
command structure that must be followed when communicating with it.
(Note: If you want the latest version of Firmware D, check here for version 1.3)
Commands:
The "C" Command:
- The "C" command stands for 'Configure' and allows you to set
the state of the port direction registers for ports A, B and C. This
allows you to turn each pin into an input or an output on a pin by pin
basis.
- Format:
"C,<DirA>,<DirB>,<DirC>,<AnalogDirection><CR>"
where <DirX> is a value between 0 and 255 that indicates the
direction bits for that port. A 1 is an input, a 0 is an
output.<AnalogDirection> should always be zero at this point in
time. (For future use.)
- Example: "C,4,245,52"
(with a carrige return at the end that you can't see)
The "O" Command:
- The "O" command stands for 'Output state' and will take the
values you give it and write them to the port A, B and C data
registers. This allows you to set the state of any pin that is an
output.
- Format:
"O,<PortA>,<PortB>,<PortC><CR>" where
<PortX> is a value between 0 and 255 that indicates the value of
the port pins for that register.
- Example: "O,0,255,22"
(with a carrige return at the end that you can't see)
The "I" Command
- The "I" Command stands for 'Input state' and when you send the
UBW an "I" command, it will respond with an "I" packet back that will
hold the value of each bit in each of the three ports A, B and C. It
reads the state of the pin, no matter if the pin is an input or an
output.
- Format: "I<CR>"
- Example: "I" (with a
carrige return at the end that you can't see)
- Return Packet:
"I,<StatusA>,<StatusB>,<StatusC><CR>" where
<StatusX> is a number from 0 to 255 that indicates the current
value of the pins on that port. Note that <StatusX> will always
be 3 chacaters long, which means that leading zeros will be added so
that the return packet is always the same length regardless of the data
values.
- Example Return Packet:
"I,001,045,205" (with a carrige return at the end that you can't see)
The "V" Command
(new for version 1.1)
- The "V" Command stands for 'Version' and when you send the
UBW an "V" command, it will respond with a text string that looks
something like this: "UBW FW D Version 1.1.0"
- Format: "V<CR>"
- Return Packet:
"UBW FW D Version 1.1.0"
The "R" Command
(new for version 1.1)
- The "R" Command stands for 'Reset to default state' and when you
send the
UBW an "R" command it will initalize all pins to inputs and stop any
running timers.
- Format: "R<CR>"
- Return Packet: None.
The "T" Command (new for
version 1.1)
- The "T" Command stands for 'Timer read inputs' and when you send
the
UBW an "T" command, it will start a timer. This timer will cause an "I"
packet response to get sent to the PC at a regular interval. The time
between I packets is determined by the
<TimeBetweenPacketsInMilliseconds> value, and is expressed as a
number between (and including) 10 and 30000. If you send a 10 for
<TimeBetweenPacketsInMilliseonds> then a new I paket response
would be sent every 10ms with the current state of the I/O pins at that
time. If you sent a value of 30000, then it would send an I packet
response every 30seconds. If you want to turn off the timer so that no
more I packets are sent, send a
<TimeBetweenPacketsInMilliseconds> of zero. <Mode> should
always be sent as a zero for FW D Version 1.1. Note that the UBW is
acutally sampling the input pins at an extremely precise time interval
of whatever you sent in the T command. The values of the pins are
stored in a buffer, and then I packet responses are generated whenever
there is 'free time' on the USB back to the PC. So you can count the I
packet reponses between rising or falling edges and know the time
between those events to the precission of the value of
<TimeBetweenPacketsInMilliseconds>.
- Format: "T,<TimeBetweenPacketsInMilliseconds><Mode><CR>"
- Example: "T,100,0" (with
a
carrige return at the end that you can't see)
- Return Packet: There is
no return packet from a T command. However, the I packet responses will
start flowing at regular intervals after the T command is received by
the UWB.
Hints on using Firmware D:
- Currently (FW D v1.1) the only way to directly read the values of
any of
the pins is by sending an "I" command and waiting for the responce. If
you max out the USB pipe by sending another "I" as soon as you receive
the last one, you can get about 80 packets/second coming back from the
UBW, or about 12ms per sample.
- By using the "T" command, you can get up to 100 "I"
packets/second back
fromt the UBW. (100Hz update rate)
- If the "I" packet reponses stop coming back after you've done a
"T" command, and you didn't stop them yourself (with a "T,0,0") then
what's happened is that the internal buffer in the UBW for I packet
data has been filled up. (There is room for 16 I packet data sets.)
This means that the USB system is too busy to get the I packet reponses
back to the PC fast enough. You need to have less USB traffic (from
other devices) or increase the time between I packet responses.
Errors:
There are some rules about sending these commands to
the UBW. If any of the rules is violated, an error charater will be
sent back. You can monitor the serial port for these characters to know
what you are doing wrong.
- If the length of the command you are sending to the UBW is
greater than just one character and the carrige return, then the second
character needs to be a comma. If not, you will get an error back of
",".
- If the last character of the USB packet (the command) is not a
carrige return (0x0D) then you will get back an error of "!".
- If all of the parameters of a packet are parsed by the UWB and
the next character is not a carrige return, you will get back an error
of "#".
- If you are missing a comma in the packet, you will get an error
of "^".
- If the value you put in a parameter is out of range, you will get
an error of "~".
Other things to note:
- Each error responce from the UBW will terminate in a <CR>
(0x0D).
- New for version 1.1 - FW D now no longer requires incoming
commands to be placed in a single USB packet. This means you can easily
try out your UBW board by connecting it to a terminal emulator on your
PC and typing packets to the UBW.
- New for version 1.1 - FW D now no longer requires a single
<CR> at the end of a command. It can take any number of
<CR> or <LF> characters together and recogiznes them as a
single "end of packet" symbol. This also helps make the UWB friendly
for Terminal Emulator use.
Files:
The full zip file for Firmware D v1.1, including all
source and project files necessary to rebuilt it are located here.
Example Liberty Basic
Application:
This is a very, very simple app that illustrates how
to talk to Firmware D.
' This is a super-simple demo of how to use Firmware D on a UBW board
' Step through this in the debugger to see everything in slow motion
' To be used with Firmware D v 1.1 or above
' First we open the COM port that we're going to use (COM15 for me)
print "Opening com port"
open "COM15:9600,8,N,1,RS,DS0,CS0" for random as #commHandle
' Then we write a C packet with the directions we want for each pin
' All of port A will be inputs and all of port B and C will be outputs.
print "Setting direction registers"
print #commHandle, "C,255,0,0,0"
' Then we're going to write out an O packet with the values for the
pins that are outputs
' We'll make all of Port C high (which will turn on the yellow LED on
the UBW)
print "Setting bit states"
print #commHandle, "O,0,0,255"
' Then we'll wait for one of our input pins to go High with an I command
print "Waiting for PortA bit 0 to go high"
[WaitForHigh]
' First send the I command
print #commHandle, "I"
' Wait for something to come back
while lof(#commHandle) < 1
scan
wend
' Read in what was sent to us
DataIn$ = input$(#commHandle, lof(#commHandle))
' Check to make sure it's what we wanted
if left$(DataIn$,2) = "I," then
' "I,AAA,BBB,CCC" and pull
appart the packet
StatusA = val(mid$(DataIn$,
3, 3))
StatusB = val(mid$(DataIn$,
7, 3))
StatusC = val(mid$(DataIn$,
11, 3))
' Now check to see if Port
A, bit 0 is high
if TstBit(StatusA,0) = 1 then
goto
[NextStep]
end if
end if
scan
goto [WaitForHigh]
' Then Low
[NextStep]
print "Waiting for PortA bit 0 to go low"
[WaitForLow]
' First send the I command
print #commHandle, "I"
' Wait for something to come back
while lof(#commHandle) < 1
scan
wend
' Read in what was sent to us
DataIn$ = input$(#commHandle, lof(#commHandle))
' Check to make sure it's what we wanted
if left$(DataIn$,2) = "I," then
' "I,AAA,BBB,CCC" and pull
appart the packet
StatusA = val(mid$(DataIn$,
3, 3))
StatusB = val(mid$(DataIn$,
7, 3))
StatusC = val(mid$(DataIn$,
11, 3))
' Now check to see if Port
A, bit 0 is Low
if TstBit(StatusA,0) = 0 then
goto
[Done]
end if
end if
goto [WaitForLow]
' And finally we'll write out another set of values to the pins with
the O command
' All output bits will be low.
[Done]
print "Writing out final bit states"
print #commHandle, "O,0,0,0"+chr$(13);
' And now we're done!
print "Closing com port"
close #commHandle
END
' Test bit "Bit" (zero based) in variable "Byte" and return it's value
(1 or 0)
function TstBit(Byte, Bit)
TestBit = 0
if ((Byte AND (2^Bit)) > 0) then
TstBit = 1
end if
end function
Questions? E-mail me at