#include <avr/io.h>
#include <stdint.h>
#include <math.h>


#include <spi.h>


/* 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
