// spi.c #include "spi.h" #include // Define pin macros for CS, MOSI, MISO, SCK #define SPI_DDR DDRB #define SPI_PORT PORTB #define SPI_PIN PINB #define SPI_CS PB4 // Chip Select pin #define SPI_MOSI PB2 #define SPI_MISO PB3 #define SPI_SCK PB1 #define SPI_SS PB0 void spi_init(void) { // Set MOSI, SCK, SS, CS as output; MISO input SPI_DDR |= (1 << SPI_MOSI) | (1 << SPI_SCK) | (1 << SPI_SS) | (1 << SPI_CS); SPI_DDR &= ~(1 << SPI_MISO); // Pull CS high initially SPI_PORT |= (1 << SPI_CS); // Enable SPI, Master mode, fosc/4 SPCR = (1 << SPE) | (1 << MSTR); SPSR = 0; } void spi_cs_low(void) { SPI_PORT &= ~(1 << SPI_CS); } void spi_cs_high(void) { SPI_PORT |= (1 << SPI_CS); } uint8_t spi_transfer(uint8_t data) { SPDR = data; while (!(SPSR & (1 << SPIF))); return SPDR; } void spi_write_buffer(const uint8_t *buf, uint16_t len) { for (uint16_t i = 0; i < len; i++) { spi_transfer(buf[i]); } } uint8_t spi_read(void) { return spi_transfer(0xFF); } // UART support #define UART_BAUD 9600 #define UBRR_VALUE ((F_CPU / (16UL * UART_BAUD)) - 1) void uart_init(void) { UBRR0H = (uint8_t)(UBRR_VALUE >> 8); UBRR0L = (uint8_t)(UBRR_VALUE); UCSR0B = (1 << RXEN0) | (1 << TXEN0); UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); } void uart_putc(char c) { while (!(UCSR0A & (1 << UDRE0))); UDR0 = c; } char uart_getc(void) { while (!(UCSR0A & (1 << RXC0))); return UDR0; } void uart_puts(const char *s) { while (*s) { uart_putc(*s++); } }