Created
March 12, 2013 23:17
-
-
Save blondie7575/5147987 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* 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