Tuesday, August 9, 2022

Arduino link state machine written and in debug

ARDUINO LINK IS AN SPI BASED LINK WITH 325 WORD TRANSACTIONS

The connection between the FPGA and the Arduino is a four wire SPI (Serial Peripheral Interface) link with the Arduino as the controller. Every transaction is initiated by the Arduino, first turning on a fifth wire that marks a transaction, then sending 325 words. Each word is 16 bits and the Slave Select line of the SPI link is switched on and off for each word. This makes it easy to detect the incoming words.

The link sends a five bit command code plus the cylinder, track and sector address as the first word - the command word. The second word sent is the same word with every bit inverted. This serves as a kind of error check on the transaction. 

Next we send 321 words, one for each word of the sector from 0 to the end. As the words are processed, a running checksum is accumulated. It is simply the exclusive-OR of each of the 16 bits of each word with the corresponding bits of the checksum. The initial value or seed is x1234 to ensure that a completely open link doesn't produce a seemingly valid checksum at the end.

After the last sector word is sent, the checksum is transmitted as the penultimate word of the transaction. If the checksum calculated matches the checksum received over the link, and if the inverted command word was correct, then the pattern xA5A5 is transmitted as the final word, a flag. If any error occurred the flag is set to x0000 which is also the value that would be received on an open SPI link.

All error recovery is the responsibility of the Arduino, generally by resending the same sector down until it is successful. The FPGA won't respond to the drive electronics until a transaction is sent with a command word whose command bits request a switchover to drive mode. Drive mode also allows the drive modeling logic in the FPGA to control RAM access.

This can be rescinded such as when the heads are unloaded at spin down, by sending a different command bit pattern to return control of RAM to the SPI link machine. Initially the system is in SPI link mode as that is how we load a virtual cartridge image into RAM. 

TIMING IS CRITICAL WITH LINK STATE MACHINE

When a transaction word begins, the data to be sent out to the Arduino must already be set up in the output word. The Slave Select is activated then the SPI clock toggles 16 times to shift 16 bits across the link, taking one bit off the output on each clock pulse and sending it out over the MISO line. At the same time, it is grabbing bits from the Arduino off the MOSI line and shifting them into a 16 bit input word. Thus at the end of the word, as Slave Select is turned off, we have exchanged two words.

If one wishes to respond to the last exchange of words based on the contents sent down from the Arduino, the output word must be set up before the Slave Select activates for the next exchange. If it is set up too late we have the wrong bits going up to the Arduino. 

The SPI link operates at 4MHz, therefore it is clocking at 250 ns per clock. The FPGA main logic is switching with a 50ns clock, which does give us a bare minimum of five clock cycles even if the Arduino were blazingly fast reasserting the Slave Select. 

TESTBENCH CREATED TO DRIVE SPI TRANSACTIONS IN LIEU OF ARDUINO

I put together a procedure to switch the SPI MISO, clock and Slave Select lines to shift out one output word. Stringing these together, 325 of them, bounded by the SPI transaction signal I defined, will drive the SPI slave module and the state machine to handle the transaction. 

INITIAL TESTING

I started with the Unload command, which sends a cylinder, head and sector address to the FPGA along with 321 words of all zero. The state machine, after validating the command words, will read RAM for each of the word addresses and send out the contents of RAM on the output word for the same exchange - zeros in, RAM content out. 

I could indeed see the logic managing the stream, verifying the command and its inverse, reading and sending out all the words, then transmitting the checksum and a flag word. The flag word will be a given pattern if nothing went wrong, otherwise it is x0000 to indicate an error.

I found a few small issues and fixed them up, moving on to fully validating all the error checking behavior of the link for this command type. I did test the two trivial commands - switch the RAM control to the drive circuits and switch it to the SPI link engine, which worked exactly as designed.

TOMORROWS TEST PLAN

The major work for tomorrow will be debugging the Load command. This is a transfer from the Arduino to the FPGA of 321 words of content, each of which must be written to RAM at the proper address, added to the running checksum, and then at the end we must have a good compare of our calculated checksum with the value sent down by the Arduino in order to give a good flag value indicating success. 

No comments:

Post a Comment