Skip to content

Instantly share code, notes, and snippets.

@blondie7575
Created March 12, 2013 23:17
Show Gist options
  • Save blondie7575/5147987 to your computer and use it in GitHub Desktop.
Save blondie7575/5147987 to your computer and use it in GitHub Desktop.
/* Name: main.c
* Author: Quinn Dunki
* Copyright: ©2012 Quinn Dunki
* License: All Rights Reserved
*
* ATtiny13A code to program an SRAM chip or EEPROM
* For details, see http://www.quinndunki.com/blondihacks
*/
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#define QDDRB(n) (1<<(DDB##n))
#define QPINBIT(n) PB##n
#define SET_HI(pin) PORTB |= (1<<(QPINBIT(pin)))
#define SET_LO(pin) PORTB &= ~(1<<(QPINBIT(pin)))
#define PULSE(pin) SET_HI(pin); SET_LO(pin);
#define LOPULSE(pin) SET_LO(pin); SET_HI(pin);
#define SER_ADDR 0 // Serial data to Address registers
#define SER_DATA 1 // Serial data to Data register
#define ROM_CLK 2 // Shift & Latch clocks for shift registers
#define BYTE_WRITE 3 // Chip Enable strobe on EEPROM
#define LEDS 4 // Status LEDs (HI=red, LO=green)
#define BASE_ADDRESS 0xf000 // Address at which to load the ROM image
#define ROM_SIZE 4096
#define EEPROM_PAGE_SIZE 64
#define EEPROM_PAGE_MASK 0xffc0
// Invoke our ROM image here, so the code can reference it
#include "rom.c"
// Main loop
int main(void)
{
_delay_ms(15); // Give the EEPROM time to wake up
// Configure all pins as outputs
DDRB = QDDRB(0) | QDDRB(1) | QDDRB(2) | QDDRB(3) | QDDRB(4);
// Initialize some states
SET_LO(ROM_CLK);
SET_HI(BYTE_WRITE);
SET_HI(LEDS);
uint16_t byte = 0;
uint16_t address = BASE_ADDRESS;
uint16_t data = 0;
uint16_t pageByte = 0;
uint16_t pageNum = address & EEPROM_PAGE_MASK;
int bit=0;
// Iterate every byte in the ROM image
for (; byte<ROM_SIZE; byte++)
{
// Calculate the effective address and desired byte from the image
uint8_t db = pgm_read_byte(&romData[byte]);
data = (db<<8) | db; // Double-up the data byte, because it will be shifted out twice
// Push the data and address out to the registers. Note one extra loop
// to compensate for shift and latch clocks being tied together
uint16_t mask = 1<<15;
for (bit=0; bit<17; bit++)
{
if (address & mask)
{
SET_HI(SER_ADDR);
}
else
{
SET_LO(SER_ADDR);
}
if (data & mask)
{
SET_HI(SER_DATA);
}
else
{
SET_LO(SER_DATA);
}
mask >>= 1;
PULSE(ROM_CLK);
}
LOPULSE(BYTE_WRITE);
// After each EEPROM page, wait for the write to complete
address++;
uint16_t nextPageNum = address & EEPROM_PAGE_MASK;
pageByte++;
if (pageByte >= EEPROM_PAGE_SIZE || pageNum != nextPageNum)
{
pageByte = 0;
pageNum = nextPageNum;
_delay_ms(8);
}
}
// We're done, so give the green light
SET_LO(LEDS);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment