#define SPI_EEPROM_WREN 0x6 #define SPI_EEPROM_RDSR 0x5 #define SPI_EEPROM_WRITE 0x2 #define SPI_EEPROM_READ 0x3 #define SELECT_EEPROM PORTB &= ~(1<<PB0) // Low #define DESELECT_EEPROM PORTB |= (1<<PB0) // High #define nop() __asm__ __volatile__("nop") static inline void SPI_SendByte(const uint8_t Byte) { SPDR = Byte; while (!(SPSR & (1 << SPIF))); } static inline uint8_t SPI_ReceiveByte(void) { SPDR = 0x00; while (!(SPSR & (1 << SPIF))); return SPDR; } static inline uint8_t SPI_TransferByte(const uint8_t Byte) { SPDR = Byte; while (!(SPSR & (1 << SPIF))); return SPDR; } void read_SPIeeprom (uint16_t addr, void *data, uint8_t size) { SELECT_EEPROM; nop(); nop(); SPI_SendByte(SPI_EEPROM_READ); SPI_SendByte((uint8_t)(addr >> 8)); SPI_SendByte((uint8_t)(addr)); for (uint8_t x=0; x<size; x++) *(uint8_t*)(data++) = SPI_TransferByte(0); nop(); nop(); DESELECT_EEPROM; } void write_SPIeeprom (uint16_t addr, void *data, uint8_t size) { SELECT_EEPROM; nop(); nop(); SPI_SendByte(SPI_EEPROM_WREN); DESELECT_EEPROM; nop(); nop(); SELECT_EEPROM; nop(); nop(); SPI_SendByte(SPI_EEPROM_WRITE); SPI_SendByte((uint8_t)(addr >> 8)); SPI_SendByte((uint8_t)(addr)); for (uint8_t x=0; x<size; x++) SPI_SendByte(*(uint8_t*)(data++)); DESELECT_EEPROM; _delay_ms(6); }