#include #include #include #include /* SPI framework. * * currently alpha, uses interrupts, single master/single slave operation */ uint8_t * volatile spi_writeptr; uint8_t * volatile spi_readptr; uint8_t volatile spi_writelen; uint8_t volatile spi_readlen; uint8_t spi_readbuf[SPI_READBUF_LEN]; void spi_init(){ uint8_t spcr, spsr, d; /* calculate clock divisor, * gcc with optimize will do that calculation compile-time. */ uint8_t spi_clock_divisor(){ double d; d = F_CPU / SPI_BAUDRATE; d = ceil((log(d)/log(2))*0.95); // clock needs dividing by 2^d // the 0.95 to avoid ceil issues return d-1; // the -1 because minimum divisor is /2 } d = spi_clock_divisor(); if(d>7){ #warning "spi baudrate too slow, cannot be set" d=7; } //TODO: DDRs setzen spsr = 0; spsr |= (d & 1) ? 0 : _BV(SPI2X); spcr = 0 | _BV(SPIE) | _BV(SPE); spcr |= (d & 2) ? _BV(SPR0) : 0; spcr |= (d & 4) ? _BV(SPR1) : 0; #ifdef SPI_MASTER spcr |= _BV(MSTR); #endif SPCR = spcr; SPSR = spsr; // initialize interface for ISR: spi_readptr = spi_readbuf; spi_readlen = SPI_READBUF_LEN; spi_writeptr = NULL; } // return true on success, false on error uint8_t spi_write(uint8_t *data, uint8_t len){ if(spi_writeptr != NULL){ return 0 } spi_writeptr = data; spi_writelen = len; //TODO: handle SS, write out first byte return 1; } #ifdef SPI_MASTER ISR(SPI_vector){ } #endif //SPI_MASTER