Monday, March 21, 2022

Code written to write a PC file to the flash chip for the IOB6120 board

FLASH CONTENTS IN PC FILE IN OCTAL WITH CHECKSUMS

The data to be loaded into the flash chip is in a text file in a specific format designed for the SBC6120. The data is written in octal, three characters per byte, with spaces separating them. Eight bytes of data are on each line, started with an address in octal and terminated by a line end. 

The addresses are of the form xxxx.yyy/ where the xxxx identifies which block of 256 bytes where the data belongs, and the yyy representing the relative address within that block of 256. The xxxx part of the address happens to advance sequentially in the data file I was given. The yyy value runs from 000 to 370 since the last line is for bytes 248 to 255 of the block. 

After each eight lines (one block of 256 bytes) we have a line with a four digit octal number that is the checksum of the preceding 256 bytes. Each byte is added to a running counter that is one PDP-8 word long (12 bits), rolling over as necessary, to form the checksum. 

0000.340/ 074 004 211 306 002 005 143 221 

0000.350/ 003 074 006 012 326 000 377 042 

0000.360/ 300 244 257 325 277 256 205 376 

0000.370/ 274 201 036 174 375 014 162 326 

1363

0001.000/ 014 056 374 373 040 014 372 047 

CODE WRITTEN TO READ THE FILE, CONVERT TO HEX AND VERIFY CHECKSUMS

The file will be read on the PC by the terminal program (PuTTY) and sent over line by line to the program running on the Arduino. In the Arduino sketch I will convert the text into a hex address and hex bytes. The hex bytes are added together in a long integer and then trimmed to 12 bits to verify against the checksum sent on the 9th line of each block in the file.

CODE WRITTEN TO WRITE THE CONTENTS OF THE FILE TO THE FLASH CHIP

The basics of writing to the flash chip involves quite a few steps:

  • set up the address field as x00AAA and the data field as xAA
  • turning on CE#
  • waiting a few microseconds
  • turning on WE#
  • Hold that state for 35 microseconds
  • WE# is turned off
  • waiting a few microseconds
  • turn off CE#
  • wait 35 microseconds
  • set up the address field as x00555 and the data field as x55
  • turning on CE#
  • waiting a few microseconds
  • turning on WE#
  • Hold that state for 35 microseconds
  • WE# is turned off
  • waiting a few microseconds
  • turn off CE#
  • wait 35 microseconds
  • set up the address field as x00AAA and the data field as xA0
  • turning on CE#
  • waiting a few microseconds
  • turning on WE#
  • Hold that state for 35 microseconds
  • WE# is turned off
  • waiting a few microseconds
  • turn off CE#
  • wait 35 microseconds
  • setting up the address field for each byte
  • setting up the data field
  • turning on CE#
  • waiting a few microseconds
  • turning on WE#
  • Hold that state for 35 microseconds
  • WE# is turned off
  • waiting a few microseconds
  • turn off CE#
  • wait until the RD/BY# signal goes high before looping again

We loop over the eight bytes of a line coming in over the USB link, first establishing the address field for the new line and then incrementing it as we write each of the eight bytes. The running checksum is updated for each write. When we have reached the end of a block of 256, the next line is going to be a checksum not a data line. We read it, convert to hex, and compare it to the low order 12 bits of our calculated checksum. Assuming it matches, we zero out the running checksum and prepare for the next line from the file.

CODE WRITTEN TO READ BACK AND VERIFY FLASH CONTENTS

To read the contents and verify it, we again send the text file via PuTTY over the USB link. For each data line, convert the address to hex and convert the eight bytes to hex. We won't bother doing checksums just a byte by byte comparison. For this task, WE# remains off.

Each data line has us do the following in a loop:

  • set up the address
  • turn on CE#
  • wait a few microseconds
  • turn on OE#
  • wait 50 microseconds
  • compare the data returned to the byte from the file
  • flag errors if they don't match
  • drop CE# and OE#
  • wait 35 microseconds
  • increment the address if still in the loop
For the checksum lines (each ninth line), just ignore the contents and go back to read the next line. When we reach the end of the file and haven't flagged any errors, we have a verified load.

CODE WRITTEN TO ERASE THE SECTORS WHERE OUR CONTENTS WILL BE WRITTEN

The way that flash memory works is a bit odd. The act of writing is actually called programming and all it will do is flip any bit to 0 if the data bit being written is 0, but it does NOT flip bits to 1. Thus, one has to erase the entire sector before writing into it. The act of erasing sets all bits on in the sector - every byte is xFF. 

This chip looks at address lines A17 to A12 as a sector number, not as an address of a byte in the array. There is a command sequence to start a sector erase which sets up the sector number in those address bits at the appropriate cycle of the command sequence. This will run autonomously in the chip, writing the xFF and verifying the correct state, until the entire sector is complete at which time the RD/BY# line goes high to signal completion. 

Our process of erasing a sector is:

  • set up the address field as x00AAA and the data field as xAA
  • turning on CE#
  • waiting a few microseconds
  • turning on WE#
  • Hold that state for 35 microseconds
  • WE# is turned off
  • waiting a few microseconds
  • turn off CE#
  • wait 35 microseconds
  • set up the address field as x00555 and the data field as x55
  • turning on CE#
  • waiting a few microseconds
  • turning on WE#
  • Hold that state for 35 microseconds
  • WE# is turned off
  • waiting a few microseconds
  • turn off CE#
  • wait 35 microseconds
  • set up the address field as x00AAA and the data field as x80
  • turning on CE#
  • waiting a few microseconds
  • turning on WE#
  • Hold that state for 35 microseconds
  • WE# is turned off
  • waiting a few microseconds
  • turn off CE#
  • wait 35 microseconds
  • set up the address field as x00AAA and the data field as xAA
  • turning on CE#
  • waiting a few microseconds
  • turning on WE#
  • Hold that state for 35 microseconds
  • WE# is turned off
  • waiting a few microseconds
  • turn off CE#
  • wait 35 microseconds
  • set up the address field as x00555 and the data field as x55
  • turning on CE#
  • waiting a few microseconds
  • turning on WE#
  • Hold that state for 35 microseconds
  • WE# is turned off
  • waiting a few microseconds
  • turn off CE#
  • wait 35 microseconds
  • setting up the address field bits A17 to A12 for each sector
  • setting up the data field to x30
  • turning on CE#
  • waiting a few microseconds
  • turning on WE#
  • Hold that state for 35 microseconds
  • WE# is turned off
  • waiting a few microseconds
  • turn off CE#
  • wait until the RD/BY# signal goes high before looping again
We need five sectors to hold the 128KB of contents going into the flash.

No comments:

Post a Comment