2 #include <avr/pgmspace.h>
3 #include <avr/interrupt.h>
6 #define SPIEE_CS_PIN PA1
7 #define SPIEE_CS_PORT PORTA
12 #define sbi(p,b) (p) |= (1<<(b))
16 #define cbi(p,b) (p) &= ~(1<<(b))
19 #define SPI_EEPROM_READ 0x3
20 #define SPI_EEPROM_WRITE 0x2
21 #define SPI_EEPROM_WREN 0x6
22 #define SPI_EEPROM_RDSR 0x5
23 #define SPI_EEPROM_WRSR 0x1
25 //**************************************************
27 //**************************************************
28 uint8_t internal_eeprom_read8(uint16_t addr
) {
29 loop_until_bit_is_clear(EECR
, EEWE
); // wait for last write to finish
31 sbi(EECR
, EERE
); // start EEPROM read
32 return EEDR
; // takes only 1 cycle
35 void internal_eeprom_write8(uint8_t data
, uint16_t addr
) {
36 loop_until_bit_is_clear(EECR
, EEWE
); // wait for last write to finish
39 cli(); // turn off interrupts
40 sbi(EECR
, EEMWE
); // these instructions must happen within 4 cycles
42 sei(); // turn on interrupts again
46 //**************************************************
47 // Serial Programming Interface EEPROM
48 //**************************************************
49 void spieeprom_write(uint8_t data
, uint16_t addr
) {
55 cbi(SPIEE_CS_PORT
, SPIEE_CS_PIN
); // pull CS low
58 SPDR
= SPI_EEPROM_RDSR
;
59 while (!(SPSR
& (1<<SPIF
)));
62 while (!(SPSR
& (1<<SPIF
)));
64 sbi(SPIEE_CS_PORT
, SPIEE_CS_PIN
); // pull CS high
66 } while ((status
& 0x1) != 0);
67 /* set the spi write enable latch */
69 cbi(SPIEE_CS_PORT
, SPIEE_CS_PIN
); // pull CS low
73 SPDR
= SPI_EEPROM_WREN
; // send command
74 while (!(SPSR
& (1<<SPIF
)));
76 sbi(SPIEE_CS_PORT
, SPIEE_CS_PIN
); // pull CS low
78 NOP
; NOP
; NOP
; NOP
; // wait for write enable latch
80 cbi(SPIEE_CS_PORT
, SPIEE_CS_PIN
); // pull CS low
83 SPDR
= SPI_EEPROM_WRITE
; // send command
84 while (!(SPSR
& (1<<SPIF
)));
86 SPDR
= addr
>> 8; // send high addr
87 while (!(SPSR
& (1<<SPIF
)));
89 SPDR
= addr
& 0xFF; // send low addr
90 while (!(SPSR
& (1<<SPIF
)));
92 SPDR
= data
; // send data
93 while (!(SPSR
& (1<<SPIF
)));
98 sbi(SPIEE_CS_PORT
, SPIEE_CS_PIN
); // pull CS low
102 uint8_t spieeprom_read(uint16_t addr
) {
107 cbi(SPIEE_CS_PORT
, SPIEE_CS_PIN
); // pull CS low
110 SPDR
= SPI_EEPROM_READ
; // send command
111 while (!(SPSR
& (1<<SPIF
)));
113 SPDR
= addr
>> 8; // send high addr
114 while (!(SPSR
& (1<<SPIF
)));
116 SPDR
= addr
& 0xFF; // send low addr
117 while (!(SPSR
& (1<<SPIF
)));
122 while (!(SPSR
& (1<<SPIF
)));
125 sbi(SPIEE_CS_PORT
, SPIEE_CS_PIN
); // pull CS high