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. The libraries for these interfaces are provided separately.

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 very basic 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: receiving of packets and interpretation of the protocol, interpretation and activation of commands carried by the packets, and transmission of result packets.

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 the receive task is woken up. The transmit task is started if no errors have occurred. The interpretation task must not introduce any significant time delays before rescheduling the receive task, lest incoming characters be lost.

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 transmit task terminates.

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 the transmit task.

Conversion Task

If an independent long-running A/D conversion is requested, a conversion task is activated. This task manages the activation of the A/D conversions (usually a series of conversions that are averaged), writing of results to the external EEPROM over the TWI interface, and introduction of delays between successive conversions. The delay process is implemented by means of a counter that is read and decremented by the RTC ISR. A delay of an integral number of RTC clock ticks can be activated by simply setting the counter to the appropriate integer value, and placing the conversion task into a wait state. The ISR will reschedule the conversion task when the counter reaches zero. This is used not only for the delay between conversions, but also for a delay between switching on the power to the analogue circuits and the conversion, necessary to allow the power supplies to settle.

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 DAU 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.

Auxiliary Libraries

The following libraries are used:

  • UART library based on that by Peter Fleury.

  • ADC, TWI and Timer libraries based on those by Chris Efstathiou.

  • NARTOS a minimal operating system that is not strictly real-time.

Note that modifications to these libraries have been made to ensure that they are non-blocking, that is, if a function cannot complete its purpose, it returns immediately with a status notification. Status polling functions are provided to assist calling programs in synchronizing with the operations of the hardware. This is essential to ensure that the operating system maintains a semblance of real-time response.

Installation

Install cdk4avr as described, or use the latest avr-gcc tools*. Unpack the source code and the libraries into the same directory. The libraries will appear as a set of subdirectories. The makefile is already setup for compilation using optimization level 2. Optimization level s will produce slightly smaller code, but it may inline small functions which can cause problems for the Operating System NARTOS. Run make to produce the hex file. The binary size is slightly less than 7K.

* Important note: at the latest time of writing the latest avr-gcc compiles the program, but the program crashes in the AVR. Also the binary produced is large enough that it may not fit into an 8K AVR device along with a bootloader. The compiler suite that has been used successfully is the latest cdk4avr suite of 2006.

Changes: some simplification of the code was made primarily to improve readability and modularity. A power off/on feature was added. Changes to port allocations were made in response to modifications to the hardware.


First created 13 May 2007

Last Modified 31 January 2010