b15f/firmware/spi.cpp

75 lines
1.2 KiB
C++
Raw Normal View History

2019-03-25 08:57:38 +00:00
#include "spi.h"
2019-04-03 11:30:57 +00:00
void SPI::init() const volatile
2019-03-25 08:57:38 +00:00
{
2019-03-25 12:00:22 +00:00
// Konfiguriere SPI DDRs
2019-03-26 07:44:30 +00:00
DDRB |= _BV(SLSL) | _BV(MOSI) | _BV(SCLK);
DDRB &= ~_BV(MISO);
2019-03-25 12:42:32 +00:00
2019-03-25 12:00:22 +00:00
// Konfiguriere DMUX DDRs
2019-03-26 07:44:30 +00:00
DDRD |= _BV(DMUX1) | _BV(DMUX2) | _BV(DMUX3);
2019-03-25 12:00:22 +00:00
2019-04-03 12:09:58 +00:00
// aktiviere SPI, Interruptbetrieb, Master Modus, SPI Modus 0
2019-03-25 12:00:22 +00:00
// F_SPI = F_CPU / 2 (prescaler 2)
2019-04-03 09:38:15 +00:00
SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPIE);
2019-04-03 12:09:58 +00:00
SPSR = _BV(SPI2X);
2019-03-25 12:00:22 +00:00
2019-03-25 12:42:32 +00:00
// waehle keinen SPI Slave aus
setAdr(SPIADR::NONE);
2019-03-25 12:00:22 +00:00
}
2019-04-03 09:38:15 +00:00
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;
}
2019-04-03 11:30:57 +00:00
void SPI::addByte(uint8_t b) volatile
{
wait();
buffer[index++] = b;
}
void SPI::transfer(SPIADR adr) volatile
2019-04-03 09:38:15 +00:00
{
if(!index)
return;
wait();
active = true;
setAdr(adr);
this->length = index;
this->index = 0;
handleTransfer();
}
2019-04-03 11:35:12 +00:00
void SPI::wait() const volatile
2019-04-03 09:38:15 +00:00
{
while(active);
}
2019-04-03 11:30:57 +00:00
void SPI::setAdr(SPIADR adr) const volatile
2019-03-25 12:00:22 +00:00
{
2019-03-26 07:44:30 +00:00
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;
2019-03-25 12:00:22 +00:00
}