Updates code to use low level registers. Untested with real eeprom
This commit is contained in:
parent
de712cd340
commit
86a02fdf95
1 changed files with 146 additions and 0 deletions
|
|
@ -1,5 +1,151 @@
|
|||
#define SHIFT_DATA 2
|
||||
#define SHIFT_CLK 3
|
||||
#define SHIFT_LATCH 4
|
||||
#define EEPROM_D0 5
|
||||
#define EEPROM_D7 12
|
||||
#define EEPROM_WE 13
|
||||
|
||||
#define LAST_OP_WRITE 0
|
||||
#define LAST_OP_READ 1
|
||||
|
||||
#define READ_MODE true
|
||||
#define WRITE_MODE false
|
||||
|
||||
// Digital pins 0 to 7 correspond to PD0 to PD7
|
||||
// Digital pins 8 to 13 correspond to PB0 to PB5
|
||||
|
||||
byte lastOp;
|
||||
|
||||
void latchOutput() {
|
||||
static byte latchMask = 0b00010000;
|
||||
|
||||
PORTD &= ~latchMask;
|
||||
delayMicroseconds(1);
|
||||
PORTD |= latchMask;
|
||||
delayMicroseconds(1);
|
||||
PORTD &= ~latchMask;
|
||||
}
|
||||
|
||||
void commitWrite() {
|
||||
static byte writeEnableMask = 0b00100000;
|
||||
|
||||
delayMicroseconds(1);
|
||||
PORTB &= ~writeEnableMask;
|
||||
delayMicroseconds(1);
|
||||
PORTB |= writeEnableMask;
|
||||
}
|
||||
|
||||
void setBusMode(bool busMode) {
|
||||
// When dealing with DDR registers. 1 is output and 0 is input.
|
||||
if (busMode == READ_MODE) {
|
||||
// When reading we want the pins to be inputs.
|
||||
DDRD &= 0b00011111;
|
||||
DDRB &= 0b11100000;
|
||||
} else {
|
||||
// When writing we want the pins to be outputs.
|
||||
DDRD |= 0b11100000;
|
||||
DDRB |= 0b00011111;
|
||||
}
|
||||
}
|
||||
|
||||
void setAddress(int address, bool outputEnable) {
|
||||
// Position of the output enable bit withing the data to be shifted out.
|
||||
static byte outputEnableMask = 0x8000;
|
||||
// Position of the data bit within PORTD.
|
||||
static byte dataMask = 0b00000100;
|
||||
// Position of the clock bit within PORTD.
|
||||
static byte clockMask = 0b00001000;
|
||||
|
||||
if (outputEnable) {
|
||||
// Clear output enable bit.
|
||||
address &= ~outputEnableMask;
|
||||
} else {
|
||||
// Set output enable bit.
|
||||
address |= outputEnableMask;
|
||||
}
|
||||
|
||||
// Make sure the clock pin is low.
|
||||
PORTD &= ~clockMask;
|
||||
|
||||
// Shift the data out LSB first.
|
||||
for (uint8_t i = 0; i < 16; i++, address >>= 1) {
|
||||
if (address & 1) {
|
||||
PORTD |= dataMask;
|
||||
} else {
|
||||
PORTD &= ~dataMask;
|
||||
}
|
||||
|
||||
// Clock the bit out.
|
||||
PORTD |= clockMask;
|
||||
delayMicroseconds(1);
|
||||
PORTD &= ~clockMask;
|
||||
delayMicroseconds(1);
|
||||
}
|
||||
|
||||
latchOutput();
|
||||
}
|
||||
|
||||
byte readEEPROM(int address) {
|
||||
// TODO: Think about adding a delay if the last operation was a write and where it is appropriate to put it.
|
||||
// If the last operation wasn't a read we need to set our pins as input.
|
||||
if (lastOp != LAST_OP_READ) {
|
||||
setBusMode(READ_MODE);
|
||||
}
|
||||
|
||||
// In contrast with the write function, it's okay to set output enable after setting the
|
||||
// pins as inputs. This way, the arduino pins are already ready to sink current when the
|
||||
// EEPROM starts driving the bus.
|
||||
byte result = (PINB << 3) | (PIND >> 5) ;
|
||||
|
||||
lastOp = LAST_OP_READ;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes a single byte of data to the specified address.
|
||||
* If cooldown is true, the function adds a delay to avoid
|
||||
* reading incorrect data after a write.
|
||||
*/
|
||||
void writeEEPROM(int address, byte data, bool cooldown) {
|
||||
// For the write case, must turn output enable off before setting the pins as outputs.
|
||||
// If we don't do this, for a brief period of time, both the arduino and the EEPROM would
|
||||
// drive the bus and this could case problems.
|
||||
setAddress(address, false);
|
||||
|
||||
// If the last operation wasn't a write we need to set our pins as output.
|
||||
if (lastOp != LAST_OP_WRITE) {
|
||||
setBusMode(WRITE_MODE);
|
||||
}
|
||||
|
||||
// EEPROM_D0 to D2 correspond to PD5 to PD7
|
||||
// EEPROM_D3 to D7 correspond to PB0 to PB4
|
||||
PORTD &= (data << 5) & 0b00011111;
|
||||
PORTB &= (data >> 3) & 0b11100000;
|
||||
|
||||
commitWrite();
|
||||
lastOp = LAST_OP_WRITE;
|
||||
|
||||
if (cooldown) {
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setup() {
|
||||
// put your setup code here, to run once:
|
||||
pinMode(SHIFT_DATA, OUTPUT);
|
||||
pinMode(SHIFT_CLK, OUTPUT);
|
||||
pinMode(SHIFT_LATCH, OUTPUT);
|
||||
|
||||
digitalWrite(EEPROM_WE, HIGH);
|
||||
pinMode(EEPROM_WE, OUTPUT);
|
||||
|
||||
// Setting an invalid value.
|
||||
lastOp = -1;
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue