75 lines
1.2 KiB
C++
75 lines
1.2 KiB
C++
#include "spi.h"
|
|
|
|
void SPI::init() const volatile
|
|
{
|
|
// Konfiguriere SPI DDRs
|
|
DDRB |= _BV(SLSL) | _BV(MOSI) | _BV(SCLK);
|
|
DDRB &= ~_BV(MISO);
|
|
|
|
// Konfiguriere DMUX DDRs
|
|
DDRD |= _BV(DMUX1) | _BV(DMUX2) | _BV(DMUX3);
|
|
|
|
// aktiviere SPI, Interruptbetrieb, Master Modus, SPI Modus 0
|
|
// F_SPI = F_CPU / 2 (prescaler 2)
|
|
SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPIE);
|
|
SPSR = _BV(SPI2X);
|
|
|
|
// waehle keinen SPI Slave aus
|
|
setAdr(SPIADR::NONE);
|
|
}
|
|
|
|
void SPI::handleTransfer() volatile
|
|
{
|
|
if(!active)
|
|
{
|
|
setAdr(SPIADR::NONE);
|
|
return;
|
|
}
|
|
|
|
uint8_t next = buffer[index];
|
|
buffer[index++] = SPDR;
|
|
|
|
if(index >= length)
|
|
{
|
|
index = 0;
|
|
active = false;
|
|
}
|
|
|
|
SPDR = next;
|
|
}
|
|
|
|
void SPI::addByte(uint8_t b) volatile
|
|
{
|
|
wait();
|
|
buffer[index++] = b;
|
|
}
|
|
|
|
void SPI::transfer(SPIADR adr) volatile
|
|
{
|
|
if(!index)
|
|
return;
|
|
|
|
wait();
|
|
active = true;
|
|
|
|
setAdr(adr);
|
|
|
|
this->length = index;
|
|
this->index = 0;
|
|
|
|
handleTransfer();
|
|
}
|
|
|
|
void SPI::wait() const volatile
|
|
{
|
|
while(active);
|
|
}
|
|
|
|
void SPI::setAdr(SPIADR adr) const volatile
|
|
{
|
|
PORTD &= ~(_BV(DMUX1) | _BV(DMUX2) | _BV(DMUX3));
|
|
PORTD |= (adr & 0x01) ? _BV(DMUX1) : 0;
|
|
PORTD |= (adr & 0x02) ? _BV(DMUX2) : 0;
|
|
PORTD |= (adr & 0x04) ? _BV(DMUX3) : 0;
|
|
}
|