Acquisition AVR Software

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.


First created 13 May 2007

Last Modified 13 September 2007