diff --git a/firmware/spi.c b/firmware/spi.c index 870a16d..226692a 100644 --- a/firmware/spi.c +++ b/firmware/spi.c @@ -38,41 +38,98 @@ void spi_init(){ d=7; } - //TODO: DDRs setzen + //DDRs setzen +#ifdef SPI_MASTER + DDRB |= _BV(5) | _BV(3) | _BV(2); //MOSI, SCK, unused SS + DDRB &= ~( _BV(4)); //MISO + SPI_SSDDR |= _BV(SPI_SS_PIN); // actually used SS +#else //SPI_MASTER + DDRB |= _BV(4); //MISO + DDRB &= ~( _BV(5) | _BV(3) | _BV(2)); //MOSI, SCK, SS +#endif //SPI_MASTER spsr = 0; spsr |= (d & 1) ? 0 : _BV(SPI2X); - spcr = 0 | _BV(SPIE) | _BV(SPE); + spcr = 0 | _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; + SPCR = spcr; +} + +void spi_mst_start_packet(){ + SPI_SSOUT &= ~(_BV(SPI_SS_PIN)); +} - // initialize interface for ISR: - spi_readptr = spi_readbuf; - spi_readlen = SPI_READBUF_LEN; - spi_writeptr = NULL; +void spi_mst_end_packet(){ + SPI_SSOUT |= _BV(SPI_SS_PIN); } -// return true on success, false on error -uint8_t spi_write(uint8_t *data, uint8_t len){ - if(spi_writeptr != NULL){ - return 0 +#define SPI_WAIT while(SPSR & _BV(SPIF)){;} + +void spi_mst_write(uint8_t len, uint8_t *data){ + while(len>0){ + SPDR = *data++; + len--; + SPI_WAIT; } - spi_writeptr = data; - spi_writelen = len; - //TODO: handle SS, write out first byte - return 1; } -#ifdef SPI_MASTER -ISR(SPI_vector){ +void spi_mst_read(uint8_t len, uint8_t *data){ + while(len>0){ + SPDR = 0; + len--; + SPI_WAIT; + *data++ = SPDR; + } +} +void spi_sla_handle_packet(){ + uint8_t opcode, addr, do_write; + uint16_t data; + SPI_WAIT; + SPDR = 0x53; // random ack + SPI_WAIT; + opcode = SPDR; + do_write = spi_proto_needswrite(opcode); + SPI_WAIT; + addr = SPDR; + SPDR = 0x00; // buys some pause + if(do_write){ + data = spi_proto_handlewrite(opcode, addr); + SPI_WAIT; + SPDR = data >> 8; + SPI_WAIT; + SPDR = data & 0xff; + } else { + SPI_WAIT; + data = SPDR << 8; + SPI_WAIT; + data |= SPDR; + spi_proto_handleread(opcode, addr, data); + } +} + + + + + + + + + + + + +#ifndef SPI_MASTER +ISR(SPI_vector){ } + + #endif //SPI_MASTER diff --git a/firmware/spi.h b/firmware/spi.h index bc9969b..411a1e3 100644 --- a/firmware/spi.h +++ b/firmware/spi.h @@ -1,6 +1,21 @@ #define SPI_BAUDRATE 1000000 #define SPI_MASTER 1 #define SPI_READBUF_LEN 32 +#define SPI_SS_PORT D +#define SPI_SS_PIN 7 + + + +// copied/adapted from usbdrv.h +#define SPI_CONCAT(a, b) a ## b + +#define SPI_OUTPORT(name) SPI_CONCAT(PORT, name) +#define SPI_INPORT(name) SPI_CONCAT(PIN, name) +#define SPI_DDRPORT(name) SPI_CONCAT(DDR, name) + +#define SPI_SSOUT SPI_OUTPORT(SPI_SS_PORT) +#define SPI_SSIN SPI_INPORT(SPI_SS_PORT) +#define SPI_SSDDR SPI_DDRPORT(SPI_SS_PORT) uint8_t spi_write(uint8_t *data, uint8_t len); void spi_init();