PC44 State Machine


Mike Rosing
August 14, 1997

This document describes the DSP code running on the PC44 processor card which implements yet another version of DSS3. The first section describes how the PC44 turns on and what files the host processor needs to send for this state machine to operate. The second section describes the overall state machine operation and the final section describes some of the internal details of each state.

The PC44 has a built in boot rom which uses flash technology. This is a reprogrammable read only memory which is electrically eraseable. This has been programmed with a routine that looks for data in the dual port ram. Once found, it flags that it has moved the data to or from internal ram and dual port ram and then looks for the next command. If a valid "jump to" address is included, the code will exit this boot transfer routine (which I call "core") and execute the downloaded code.

The boot process is simple. The host pulls the reset line on the PC44, releases the reset line, and waits for the first memory location in dual ported ram to be cleared to zero. At that point, the host can begin to send data or code to the PC44. For the state machine, the host sends down the file "romenv.out". The code to do this is in a set of files which are compiled to create the console program "pc44.exe". These files include a WinRT driver which connects the code to the windows NT hardware and the PC44 code loader which reads in an assembled DSP *.out COFF file (supposed to be a standard). At this point the pc44.exe program is hardwired to load the romenv.out routine, but the suboutines in it can download any C44 processor code to the PC44 card running the core routine.

The state machine is designed to allow up to 4 independent channels and a host check. This is very easy to change, but the timing requirements will suffer if more channels are included and can be improved significantly if the number of channels is decreased. It turns out that only 3 external interrupts are available to the processor, so this should probably be changed to 3 independent channels.

A "channel" can be anything, but for this invocation two are used for output to DAC’s. So far only one has been tested. The idea is to allow each channel to have independent states, but the code is the same for all output states and only pointers to memory storage are changed. Input channel states have not yet been implemented. Presumably they would only turn on or off a DMA controller if a gate changed and do nothing otherwise.

The state machine has a master loop which sets up the memory pointers for each channel. Each channel can be in a different state. The system could be programmed to have 3 output channels and no inputs, or it could be programmed to have 3 inputs and no outputs. Each channel is completely independent and can be in any of several possible states.

Each channel has several blocks of ram which describe which state it is in, what parameters it is using and how it should initialize itself. These states and the reasons for them get a bit complex, so the first place to start is with the operation of the hardware.

To send data to a DAC using an external clock the DMA processor has a controller connected to an external interrupt line. This allows the DSP processor to operate asyncronously with the data while the DMA controller sends the data to the DAC at exact times. By building up a buffer of data the DSP can get ahead of the DMA on some channels while other channels are not busy and has time to do some checking if all channels are busy. In the mean time, the data is clocked out the the DAC at very specific times and the processor doesn’t have to worry about it (other than to stay ahead of the output clock).

The state machine has to turn the DMA processor on and off at the correct time. The control gate (an on/off signal from the PC32) is a slow speed signal (relative to everything else) which tells the PC44 processor when to do this. The host sends down information regarding the on ramp and off ramp characteristics, the frequency and the starting phase, etc. The PC44 builds a set of tables for each channel which it uses for the on and off ramps. At present the choice is linear, cosine or gaussian ramps, and the on and off ramps can be any of these. The maximum buffer size for any ramp is 16k steps, and that time duration is a function of the external interrupt rate. It can take as long as 20 milliseconds to build all 4 ramps if they are long, no stimulous should be attempted while reprogramming ramps.

The states for an output channel are "start","wait for go", "initialize", "on", "modify" and "off" or "halt". An internal subroutine is called by several of these states called "next sine". This is the heart of the sine wave generator. The subroutine "next sine" computes the next entry in the data buffer for the DMA controller. This uses the two stage sine table lookup algorithm copied from a rom generator dated about 1971. The table size is much larger, and held in ram. Overall accuracy is 24 bits. The "wait for go", "on" and "off" states call this subroutine. These states set up pointers in a ram block to change the amplitude from an up ramp to duration and then to a down ramp. The "next sine" routine just uses what it’s told to, but it does automaticly transition from up ramp to duration and checks to see if a termination state has occured.

The "start" state resets (turns off) the DMA controller for the channel and sets up the initial parameters to be used by the "next sine" routine. These include a pointer to the on ramp data, the number of steps in the on ramp, the frequency of the sine wave, the starting phase of the sine wave and a pointer to the duration and off ramp data. It then sets the channels state to "wait for go".

The "wait for go" state checks to see if the fill pointer is too close to the end of the DMA buffer. If not, it calls the "next sine" routine. It then checks to see if the PC32 has turned this channel’s gate on. If not, it just returns to the master loop. If the gate is on, it sets the next state for the channel to "initialize".

The "initialize" state turns on the DMA controller for this channel. If you’re lucky, there is already data in the buffer so that the first interrupt will send the correct data to the DAC. The DMA controller is set up to autoinitialize itself so that it will continously pump data out to the DAC. The trick will be to ensure that the loop time thru the master loop will on average be faster than the interrupt time of the fastest output channel. At present this looks like about 250kHz, but no attempt has been made at optimizing any of these routines.

The "initialize" state goes directly to the "on" state. At this point, the fill pointer is kept away from the DMA source pointer to ensure no overwrite of good data. The "on" state continuously calls the "next sine" routine and assumes the transition from on ramp to duration has taken place. After computing the next buffer value, it checks to see if the gate has transitioned to off. If so, it then sets the state for this channel to "modify".

The "modify" state has to change all the data already in the buffer to adjust it to the down ramp amplitude. This ensures we don’t lose phase of the sine wave generator and it’s much faster than calling the next sine routine since the sine wave value is already computed. If the buffer is smaller than the off ramp length, the "modify" state will transition to the "off" state. If the buffer is larger than the off ramp length, there is a good chance that we don’t even need some of the data which is already in the buffer. At that point the fill pointer is set back to the modify pointer location and the "off" state is called.

The "off" state checks to see if the amplitude table is finished. If not, it calls "next sine". If so, it checks to see if another pass of the DMA buffer is needed. Once it is satisfied that this is the last pass, it changes the DMA controller from autoinitialize to simple run and sets the DMA counter to terminate on the last entry in the DMA buffer. It then transitions to the "halt" state.

The "halt" state waits for the DMA controller to report termination. It does nothing else. Once the DMA controller has finished, it changes the channel’s state back to "start" and a new tone pip can begin.

To summerize, the PC44 can run several independent input or output channels and check the host for new data using external clocks and its internal DMA controller. A state machine concept has been implemented to keep each channel independent. Several changes must be made on the outer levels to allow more host control over the sine wave data, and a great deal more experimentation must be done to help find optimal operating parameters. So far the proof is that the PC32 can not do rate generation for DAC output, but we have some hardware that will help solve that problem. The present code does prove the concept that two DSP cards can be integrated to create a multi-channel DSS. It is debatable that it can replace the present DSS but it certainly is more flexable.

Back to Top


Return to DSS Documentation Page
Return to Basement Page
This page last modified on : Aug. 19, 1997