dagon/spi.cpp

53 lines
1.2 KiB
C++

#include <SPI.h>
#include "dagon.h"
static const uint32_t ctrlmsg = 0b10010 | (0b0010 << 20);
static const uint32_t readbit = 1 << 23;
static const int DACSS[DACS] = {4, 10, 12, 52};
uint32_t spi_write(uint32_t v, size_t dac) {
uint32_t r;
digitalWrite(DACSS[dac], LOW);
r = SPI.transfer(v >> 16 & 0xFF) << 16;
r |= SPI.transfer(v >> 8 & 0xFF) << 8;
r |= SPI.transfer(v & 0xFF);
digitalWrite(DACSS[dac], HIGH);
return v;
}
uint32_t spi_transfer(uint32_t v, size_t dac) {
spi_write(v, dac);
delayMicroseconds(1);
return spi_write(0, dac);
}
void spi_init() {
SPI.begin();
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE1));
for (size_t i = 0; i < DACS; i++) {
dg.conn[i] = false;
dg.ch[i].used = false;
dg.ch[i].volt = V0;
for (size_t attempts = 0; attempts < 5; attempts++) {
uint32_t c;
pinMode(DACSS[i], OUTPUT);
digitalWrite(DACSS[i], HIGH);
spi_write(ctrlmsg, i);
c = spi_transfer(ctrlmsg | readbit, i);
if (ctrlmsg & 0xFF == c & 0xFF) {
dg.conn[i] = true;
continue;
}
}
}
}
void spi_reset() {
for (size_t i = 0; i < DACS; i++)
spi_write(i, 0b0100 | spi_register(0b0100));
spi_init();
}