# Arachnid Plus...



## pgodfrin (Jan 29, 2020)

Howdy Folks,
Here's my Arachnid build - no artwork on it yet, but I did something fun.



See the switch? I was advised on this forum to tap to ground the resistor connected to the FV1 eeprom switch and voila, I can switch between the internal and external eeprom.
But wait there's more. The 24LC32A eepron is empty...hmmm...how to fill it?

Well the folks at Spin are kind enough to provide an assembler and a project builder, which works great with their prototyper. Being really cheap I found another way:



Using an Arduino, an Adafruit sd reader, a little doohickey I made to house the eeprom and pullup reistors (and an LED of course). I was able to write some of the sample source code Spin provides to the eeprom. Darn it my C is so rusty is took me 20 hours (at least) to figure it out, but here it is  (and it works!):
#include <stdlib.h>
#include <SD.h>
#include <Wire.h>
#include <HexDump.h>

#define HEXFILE "/HEX/Arachv01.hex"
#define EEPROM_ADR 0x50
#define MAX_I2C_WRITE 32
File myFile;

// Useful message printing definitions
#define sp(string) Serial.print(string);
#define spb(string) Serial.print(string,BIN);
#define sph(string) Serial.print(string,HEX);
#define spd(string) Serial.print(string,DEC);
#define spl(string) Serial.println(string);
#define spld(string) Serial.println(string,DEC);
#define splh(string) Serial.println(string,HEX);
#define splb(string) Serial.println(string,BIN);
#define spw(string) Serial.write(string);

/*
:       *Start code, one character, an ASCII colon ':'.
xx      Byte count, two hex digits (one hex digit pair), indicating the number of
        bytes (hex digit pairs) in the data field. The maximum byte count is
        255 (0xFF). 16 (0x10) and 32 (0x20) are commonly used byte counts.
xxxx    Address, four hex digits, representing the 16-bit beginning memory
        address offset of the data. The physical address of the data is
        computed by adding this offset to a previously established base
        address, thus allowing memory addressing beyond the 64 kilobyte
        limit of 16-bit addresses. The base address, which defaults to zero,
        can be changed by various types of records. Base addresses and
        address offsets are always expressed as big endian values.
xx      Record type (see record types below), two hex digits, 00 to 05,
        defining the meaning of the data field.
n       Data, a sequence of n bytes of data, represented by 2n hex digits.
        Some records omit this field (n equals zero). The meaning and
        interpretation of data bytes depends on the application.
xx      Checksum, two hex digits, a computed value that can be used to verify the record has no errors.

EOF     :00000001FF
*/

char    ihstart;            //  pos 00
char    ihlen[2];           //  pos 01
char    ihaddr[5];          //  pos 03
char    ihtype[2];          //  pos 07
char    ihdata[9];          //  pos 09
char    ihchksum[2];        //  pos 17
                            //  pos 19 (windows nul term is 2 bytes)
unsigned long    eepaddr=0;  //  eeprom address for binary write
unsigned long    eepbin=0;   //  binary data for eeprom
unsigned int     totbytes=0;  //  erm, total bytes?

void setup()
{ 
    //Start the I2C Library
    Wire.begin();
    Wire.setClock(400000);

    Serial.begin(9600);
    spl("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<Initializing SD card>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
    spl("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<Initializing SD card>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
    spl("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<Initializing SD card>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
    // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
    // Note that even if it's not used as the CS pin, the hardware SS pin 
    // (10 on most Arduino boards, 53 on the Mega) must be left as an output 
    // or the SD library functions will not work. 
    pinMode(10, OUTPUT);

    if (!SD.begin(10)) {
        Serial.println("initialization failed!");
        return;
    }
    Serial.println("initialization done.");

    // open the file for reading:
    myFile = SD.open(HEXFILE);
    if (myFile) {
        spl("Starting read");
        int count=0;
        char hexch[21];
        // read from the file until there's nothing else in it:
        while (myFile.available())
        {
            memset(hexch, '\0', sizeof(hexch));
            memset(ihaddr, '\0', sizeof(ihaddr));
            memset(ihdata, '\0', sizeof(ihdata));
            myFile.read(hexch,sizeof(hexch));
            //sp(hexch);
            if(strncmp(hexch,":00000001FF",11)==0)
            {
                spl("Found EOD");
                break;
            }
            for(short i=0;i<4;i++)
                ihaddr_=hexch[3+i];
            for(short i=0;i<8;i++)
            {
                //sp(ihdata);sp("=");spl(hexch[9+i]);
                ihdata=hexch[9+i];
            }
            eepaddr=strtoul(ihaddr,0,16);
            eepbin=strtoul(ihdata,0,16);
            //splh(eepbin);
            //spl();

            totbytes+=writeEEPROMPage(eepaddr);
            //spld(totbytes);
        }   //  end while
    // close the file:
    myFile.close();
  } else {
      // if the file didn't open, print an error:
    spl("error opening file");
  } //  end while available
  sp("Load ended, total bytes written: ");
  spld(totbytes);
}

/* This is a 3 step memory writing procedure
First we send the MSB of the address. 
Then we send the LSB of the address. Then we send the 
data that we want to store. */

int writeEEPROMPage(int eeAddress)
{
    Wire.beginTransmission(EEPROM_ADR);

    Wire.write((int)(eeAddress >> 8)); // MSB
    Wire.write((int)(eeAddress & 0xFF)); // LSB

    spl();
    sph(eeAddress);
    sp(":");
    //splh(eepbin);
    int bc=0;
    byte eepdata=B0;
    //eepdata = ((unsigned int *)(&eepbin))[i+1];
    //eepdata = ((unsigned char *)(&eepbin));
    eepdata=((eepbin>>24)&0xFF); //extract fourth byte
    sph(eepdata);
    bc+=Wire.write(eepdata); //Write the data

    eepdata=((eepbin>>16)&0xFF); //extract third byte
    sph(eepdata);
    bc+=Wire.write(eepdata); //Write the data

    eepdata=((eepbin>>8)&0xFF); //extract second bytes
    sph(eepdata);
    bc+=Wire.write(eepdata); //Write the data

    eepdata=(eepbin&0xFF); //extract first byte
    sph(eepdata);
    bc+=Wire.write(eepdata); //Write the data

    Wire.endTransmission(); //Send stop condition
    delay(10);
    return bc;
} 
void loop()
{
    // nothing happens after setup
}_


----------



## Robert (Jan 30, 2020)

How long does it take for the Arduino to write the EEPROM?  (Just a guess)


----------



## pgodfrin (Jan 30, 2020)

About 30 seconds. It's only 4K of data...
pg


----------



## pgodfrin (Jan 31, 2020)

My next challenge is to tap into the eeprom socket so I don't have to take the whole thing aoart to change the code. A female usb port has 4 lrads, that would work perfectly. Only how do I mount it into the side of the enclosure??


----------



## jejj (Feb 1, 2020)

Been looking at doing an Arachnid and seeing your code really has piqued my interest.  Keep us posted on how the USB setup goes.  Great Job!!


----------



## pgodfrin (Feb 1, 2020)

Thanks. I'll post the eeprom init code and the print code once I work out the bugs...


----------



## Robert (Feb 1, 2020)

pgodfrin said:


> Only how do I mount it into the side of the enclosure??



They do make panel mounted USB ports, although most might be too large physically.


----------



## phi1 (Feb 1, 2020)

I like the idea about the usb for accessing the pins... maybe you could find a headphone jack with 4 connections (like iPhone headphones). Or just two headphone jacks and spread the 4 connections between them.


----------



## pgodfrin (Feb 2, 2020)

_Here's the init code:_
//Include the Wire I2C Library
#include <Wire.h>
// Useful message printing definitions
#define sp(string) Serial.print(string);
#define spb(string) Serial.print(string,BIN);
#define sph(string) Serial.print(string,HEX);
#define spd(string) Serial.print(string,DEC);
#define spl(string) Serial.println(string);
#define spld(string) Serial.println(string,DEC);
#define splh(string) Serial.println(string,HEX);
#define splb(string) Serial.println(string,BIN);
#define spw(string) Serial.write(string);
/*This address is determined by the way your address pins are wired.
In the diagram from earlier, we connected A0 and A1 to Ground and 
A2 to 5V. To get the address, we start with the control code from 
the datasheet (1010) and add the logic state for each address pin
in the order A2, A1, A0 (100) which gives us 0b1010100, or in 
Hexadecimal, 0x54*/

//#define EEPROM_ADR 0x54
//  PG 12/22/19
//  arduino setup with a0,a1,a2 to ground therefore the address is 0b1010000
#define EEPROM_ADR 0x50
#define EEPROM_ROM_SZ 0x8000    //  32K
//  The 24LC32A has a 32 byte page buffer BUT, the  MSB and LSB take up 2!
#define EEPROM_PAGE 16 

//  leave this as zero to be safe, change only when initializing chip
//#define INIT_CHIP 0
#define INIT_CHIP 1

void setup()
{

//Start the I2C Library
  Wire.begin();
  Wire.setClock(400000);

//Start the serial port
  Serial.begin(9600);

  if(INIT_CHIP)
  {
    Serial.println("Initializing EEPROM, and then exit");

    unsigned int byte_count=0;
    byte_count=do_init();
    sp("Pass 1, total bytes:");
    spl(byte_count);
    //do_init();
    //Serial.print("Pass 2, total bytes:");
    //Serial.println(byte_count);
    //do_init();
    //Serial.print("Pass 3, total bytes:");
    //Serial.println(byte_count);

    Serial.println("Initialize complete, transmission ended.");
    Serial.println("Please close the session.");
    return;
  }

} //  end setup

int do_init()
{
    unsigned int byte_count=0;
    for (long x = 0 ; x < EEPROM_ROM_SZ ; x+=EEPROM_PAGE)
    {
        byte init_data=0x41;    //    ascii 'A'

        if(x % 1024==0)
        {
            if(x==0) continue;
              Serial.print("x:");
              Serial.print(x);
              Serial.print(" ,bytes so far:");
              Serial.println(byte_count);
        }

        Wire.beginTransmission(EEPROM_ADR);
        Wire.write((int)(x >> 8)); // MSB
        Wire.write((int)(x & 0xFF)); // LSB
        for(short b=0; b < EEPROM_PAGE; b++)
            byte_count+=Wire.write(0xFF); //Write the data

        //for(short b=0; b < EEPROM_PAGE; b++)
        //{
        //    if(init_data > 0x5A)
        //      init_data=0x41;
        //    byte_count+=Wire.write(init_data); //Write the data
        //    init_data += 0x01;
        //}   //  end for
        Wire.endTransmission(); //Send stop condition
        delay(10);
    } //  end for
    return(byte_count);
} //  end do_init
void loop()
{
    // Don't do anything here
}


----------

