|
The software
for the AVR microcontroller was written in C
and compiled using the GNU gcc compiler suite (avr-gcc) adapted for
cross-compilation to the AVR architecture. The software provides the PC
packet based command interface and executes the commands. It implements
the TWI and UART interfaces, a real time clock, and controls the ADC
and other external interfaces as required.
Specification
-
Implement the UART
interface to communicate with an external PC over RS-232 or other
physical medium.
-
Synchronize with a PC by
sending IDLE characters in response to all characters received while
waiting for a valid packet start character.
-
Interpret the packet
structure, extracting the command and all parameters, and detecting
error conditions.
-
Interpret valid commands
and execute a range of different actions in response.
-
Format packets for error
and success responses, and transmit these back to the PC.
A firmware
upload program and bootloader was also provided, and is described here.
Operating Environment
The program was originally written as a
state machine
to allow interleaving of activities while waiting for events to
complete. This is technically a very effective and efficient means of
developing a complex real-time program, however its poor readability
and lack of modularity leaves a lot to be desired. Any one task tends
to have code interleaved with that of other tasks.
A better approach is to implement a
form of Scheduling Operating System.
This allows all
the code for a task to be collected together in one place. The OS
creates and activate tasks as they are required, and the tasks are
expected to deliberately relinquish control whenever they come
to a time consuming condition or to a need to wait on some external
event to occur.
Design
As the program is mainly driven by external
commands from a PC, the communication with the PC is core to the
running of the program. This requires waiting for characters to be
received, or for transmission to be completed. The entire process is
driven by three separate tasks.
Receive Task
After initialization has been completed, a
receive task is enabled for receiving packets from the PC. The program
then waits for an IDLE character from the PC. It
returns an IDLE character in response to all characters received. The
PC is expected to synchronize to the baud rate from this returned IDLE
character.
When an IDLE
character is finally received, the
program then proceeds to wait for a START-OF-MESSAGE character. In this state it also returns an IDLE in
response to any other character and reverts to the IDLE state if the
character was not START-OF-MESSAGE. From there it passes through a number of states to
receive the entire packet, ending in an END-OF-MESSAGE character. The
command and data in the packet is stored in a buffer. The packet format
is checked for validity but the command is not interpreted at this
point.
Interpretation Task
When the packet is received correctly, the
receive task suspends itself and starts an interpretation task
to interpret the command. Parameters are
read from the receive buffer and results placed into the transmit buffer. When the command has been
completed, the interpretation task is
terminated and a transmit task is started if
no errors have occurred.
Error Task
If at any time an error is detected, a task
is started that sets an
error variable and places relevant data in the transmit
buffer. This task starts a transmit task.
Transmit Task
The transmit task takes data
stored in the transmit buffer and formats up a packet with either an
error response or a success response, followed by the buffered data.
This is transmitted to the PC. When complete the receive task is woken
up and the transmit task terminates.
Unit Information Block
The unit information block identifies the
DAU capabilities to the PC. This is an important feature of
smart transducers. The block can provide anything from a simple ID that
the PC uses to map to a set of information about the device, to a block
of detailed information. The program provides the latter so that the PC
is relieved of the need to make assumptions about the device, and
leaves open the possibility of later expansion (always A Good Thing).
Real Time Clock
The real time clock is used to provide
relative time offset for measurements. A command from the PC resets the
clock to zero and enables it. In the AVR series of microcontrollers,
timer0 is always an 8 bit timer with overflow interrupt. This is used
with appropriate clock scaling to produce an interrupt every 3 to 6
milliseconds (the actual value depends on the clock scales available).
A 32 bit counter is incremented in the ISR giving a total time scale of
about 9 months. The scale factor used is available to the PC in the
device information block.
|