pgodfrin
Member
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
}
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
}