Compare commits

...

2 commits

Author SHA1 Message Date
Stephan I. Böttcher
684d552c13 leia: SPI error propagation and msg 2025-10-28 20:02:32 +01:00
Stephan I. Böttcher
71f5839306 leia: dac ref
The DAC uses the Vref selected in ADMUX.  We _must_ keep the REFS bits
stable to use the DAC as motor current reference.

Add .conf.dac_ref to initialize REFS, in case the ADC conf is missing.
Change the default ADC config to use the internal 2.5V reference for all
channels.
2025-10-28 19:18:59 +01:00
2 changed files with 42 additions and 21 deletions

View file

@ -80,7 +80,8 @@ struct conf {
uint8_t awake; // 22
uint8_t ledoff; // 23
uint8_t disable; // 24
uint8_t pad[7]; // 25
uint8_t dac_ref; // 25
uint8_t pad[6]; // 26
uint8_t adc_ch[16]; // 32
};
@ -109,10 +110,12 @@ struct vars {
#define ADC_NTC1 (ADC_E | 8)
#define ADC_NTC2 (ADC_E | 9)
#define ADC_NTC3 (ADC_E | 10)
#define ADC_Temp (ADC_R | 11)
#define ADC_Vcc (ADC_R | 12)
#define ADC_Temp (ADC_E | 11)
#define ADC_Vcc (ADC_E | 12)
#define ADC_BG (ADC_E | 17)
#define ADC_GND (ADC_E | 18)
#define DAC_R ADC_R
#define DAC_S (DAC_R | ADC_S)
__attribute__((section(".eeprom")))
const struct conf runcon = {
@ -127,17 +130,22 @@ const struct conf runcon = {
.ledoff = LEDON,
.awake = SLEEP,
.reset = RESET,
// The DAC uses the Vref selected here. For proper operation,
// all entries must use the same Vref!
.adc_ch = {
ADC_BG|ADC_SR, ADC_BG|ADC_R, ADC_GND|ADC_R,
ADC_Iprim|ADC_SR, ADC_Iprim|ADC_R,
ADC_Vcc|ADC_S, ADC_Vcc, ADC_Temp,
ADC_BG|ADC_S, ADC_BG, ADC_GND,
ADC_Iprim, ADC_NTC1, ADC_NTC2, ADC_NTC3,
ADC_BG|DAC_S, ADC_BG|DAC_R,
ADC_GND|DAC_S, ADC_GND|DAC_R,
ADC_Iprim|DAC_S, ADC_Iprim|DAC_R,
ADC_Vcc|DAC_S, ADC_Vcc|DAC_R,
ADC_Temp|DAC_R,
ADC_Iprim|DAC_R,
ADC_NTC1|DAC_R, ADC_NTC2|DAC_R, ADC_NTC3|DAC_R,
},
.adc_incr = 16, // one conversions per channel
.dac_ref = DAC_R | ADC_BG,
.adc_incr = 16, // one conversion per channel
.adc_period = TICK_NS(1000000),
.dac_step = 0x20,
.pad = "\xff\xff\xff\xff\xff\xff\xff",
.pad = "\xff\xff\xff\xff\xff\xff",
};
void stepper_init()
@ -402,6 +410,7 @@ void adc_init()
DIDR0 = 1<<ADC3D;
DIDR1 = 1<<ADC8D | 1<<ADC9D | 1<<ADC10D;
ADCSRB = 1<<AREFEN | 2<<ADTS0;
ADMUX = v.conf.dac_ref;
ADCSRA = 1<<ADEN | 1<<ADIF | 6<<ADPS0;
}
@ -847,6 +856,8 @@ void reg88(uint8_t *v1, uint8_t *v2, unsigned char *r, const unsigned char *c)
// ADC: capture conversion results, advance MUX config
// EE_READY: write conf bytes to EEPROM
unsigned char error_msg[6] = "\xff\xff\xff" "EEE";
int main()
{
MCUSR = 0;
@ -863,8 +874,11 @@ int main()
unsigned char cmd[3];
unsigned char resp[3];
stepper_run();
if (spi_slave_Rx(cmd, 3)) {
spi_slave_Tx((const unsigned char*)"\xff\xff\xff" "EEY", 6);
unsigned char e = spi_slave_Rx(cmd, 3);
if (error_msg[5]) {
error_msg[4] = 'S';
error_msg[5] = e;
spi_slave_Tx(error_msg, sizeof(error_msg));
continue;
}
stepper_stop();
@ -877,6 +891,11 @@ int main()
resp[1] = 'E';
resp[2] = cmd[0];
break;
case 'e':
resp[0] = 'e';
resp[1] = error_msg[4];
resp[2] = error_msg[5];
break;
case 'm': reg88(&v.conf.lmask, &v.conf.lval, resp, cmd); break;
case 'q': reg16(&v.conf.period, resp, cmd);
if (0) case 'l': reg16(&v.conf.slen, resp, cmd);

View file

@ -23,15 +23,17 @@ unsigned char spi_slave_Rx_status()
return SPSR & SPSR_IF && !(SPDR & 0x80);
}
#define SPI_LATE 0x80
#define SPI_SHORT 0x40
#define spi_slave_Rx spi_slave_Rx_n
static inline
unsigned char spi_slave_Rx_n(unsigned char d[], unsigned char n)
{
d[0] = 0xff;
if (SPSR & SPSR_IF) {
SPSR;
SPDR;
return n;
SPDR = 0xff;
d[0] = SPDR;
return n | SPI_LATE;
}
register unsigned char b;
do {
@ -45,7 +47,7 @@ unsigned char spi_slave_Rx_n(unsigned char d[], unsigned char n)
while (!(SPSR & SPSR_IF))
if (PIN_SSEL) {
if (s)
return n;
return n | SPI_SHORT;
s = n;
}
SPDR = 0xff;
@ -73,7 +75,7 @@ unsigned char spi_slave_Rx_wdt(unsigned char d[], unsigned char n)
while (!(SPSR & SPSR_IF))
if (PIN_SSEL) {
if (s)
return n;
return n | SPI_SHORT;
s = n;
}
SPDR = 0xff;
@ -92,7 +94,7 @@ unsigned char spi_slave_Tx_n(const unsigned char d[], unsigned char n)
register unsigned char b = *d++;
while (!(SPSR & SPSR_IF))
if (PIN_SSEL)
return n;
return n | SPI_SHORT;
SPDR = b;
n--;
}
@ -174,7 +176,7 @@ static inline
unsigned char spi_slave_Rx_sei(unsigned char d[], unsigned char n)
{
if (!PIN_SSEL)
return 1;
return n | SPI_LATE;
PCIFR |= PCIF_SSEL;
sei();
n = spi_slave_Rx_n(d, n);
@ -226,7 +228,7 @@ unsigned char spi_slave_Rx_sleep(unsigned char d[], unsigned char n)
cli();
}
d[0] = 0xff;
return n;
return n | SPI_LATE | SPI_SHORT;
}
SPSR;
SPDR;