Compare commits

...

3 commits

Author SHA1 Message Date
Stephan I. Böttcher
d20586f0fc leia: '?' query GPIOR 2025-10-29 17:38:17 +01:00
Stephan I. Böttcher
be2d75f3b4 leia: eeprom isr __asm__ selected and tested 2025-10-29 17:20:10 +01:00
Stephan I. Böttcher
344e3a073d leia: do not enable interrupts when reading eeprom 2025-10-29 15:58:52 +01:00

View file

@ -8,7 +8,7 @@
// OCR1A: interrupt: assert STEP
// OCR1B: interrupt: deassert STEP, RESET
// ADC: Three NTCs ADC8,9,10, Iprim ADC3, internals.
// Interrupt stores conversionresults and advances channels.
// Interrupt stores conversion results and advances channels.
// DAC: Motor current reference.
// TIMER0: ADC conversion cadence, 92µs resolution, range 23ms range.
// Interrupt: DAC ramp ticks
@ -88,8 +88,10 @@ struct stat {
uint16_t adc[16]; // 48
uint16_t dac; // 80
uint8_t adc_idx; // 82
uint8_t pad[45]; //128
};
uint8_t eewr_n; // 83
uint16_t eewr_a; // 84
uint8_t pad[42]; // 86
}; //128
struct vars {
struct conf conf;
@ -143,8 +145,8 @@ const struct conf runcon = {
},
.dac_ref = DAC_R | ADC_BG,
.adc_incr = 16, // one conversion per channel
.adc_period = TICK_NS(1000000),
.dac_step = 0x20,
.adc_period = TICK_NS(10000000),
.dac_step = 0x40,
.pad = "\xff\xff\xff\xff\xff\xff",
};
@ -575,7 +577,6 @@ ISR(ADC_vect, ISR_NAKED)
static void conf_init()
{
cli();
adc_init();
adc_start(v.stat.adc_idx>>4);
dac_set(v.conf.dac_ramp);
@ -586,16 +587,13 @@ static void conf_init()
// Write EEPROM in interrupt.
uint8_t eewr_n; // number of bytes to write
uint16_t eewr_a; // EEPROM conf base address
#if 1
#if 0
ISR(EE_READY_vect)
{
uint8_t n = eewr_n;
uint8_t n = v.stat.eewr_n;
while (n) {
eewr_n = --n;
EEAR = eewr_a + n;
v.stat.eewr_n = --n;
EEAR = v.stat.eewr_a + n;
EECR |= 1<<EERE;
uint8_t d = ((uint8_t*)&v.conf)[n];
if (EEDR == d)
@ -619,16 +617,16 @@ ISR(EE_READY_vect, ISR_NAKED)
"push r30" "\n\t"
"push r31" "\n\t"
"cbi %[C], %[IE]" "\n\t"
"lds r24, eewr_n" "\n"
"lds r24, %[EN]" "\n"
"1:" "\n\t"
"clr r31" "\n\t"
"cp r24, r31" "\n\t"
"breq 2f" "\n\t"
"subi r24, 1" "\n\t"
"lds r30, eewr_a" "\n\t"
"lds r30, %[EA]" "\n\t"
"add r30, r24" "\n\t"
"out %[AL], r30" "\n\t"
"lds r30, eewr_a+1" "\n\t"
"lds r30, %[EA]+1" "\n\t"
"adc r30, r31" "\n\t"
"out %[AH], r30" "\n\t"
"sbi %[C], %[RE]" "\n\t"
@ -650,15 +648,16 @@ ISR(EE_READY_vect, ISR_NAKED)
"subi r30, -1" "\n\t"
"out %[CC], r30" "\n\t"
"2:" "\n\t"
"sts eewr_n, r24" "\n\t"
"sts %[EN], r24" "\n\t"
"pop r31" "\n\t"
"pop r30" "\n\t"
"pop r24" "\n\t"
"out __SREG__, r24" "\n\t"
"pop r24" "\n\t"
"reti" "\n"
:
:[V] "m" (v.conf),
:[EN] "+m" (v.stat.eewr_n)
:[EA] "m" (v.stat.eewr_a),
[V] "m" (v.conf),
[C] "n" (_SFR_IO_ADDR(EECR)),
[AL] "n" (_SFR_IO_ADDR(EEARL)),
[AH] "n" (_SFR_IO_ADDR(EEARH)),
@ -677,8 +676,8 @@ uint8_t eeprom_save(uint16_t a)
{
if (EECR & 1<<EERIE)
return 1;
eewr_a = a;
eewr_n = sizeof(struct conf);
v.stat.eewr_a = a;
v.stat.eewr_n = sizeof(struct conf);
GPIOR2 = 0;
EECR = 1<<EERIE;
return 0;
@ -687,11 +686,8 @@ uint8_t eeprom_save(uint16_t a)
static inline
uint8_t eeprom_load(uint16_t a)
{
cli();
if (EECR & 1<<EEWE) {
sei();
if (EECR & 1<<EEWE)
return 1;
}
uint8_t n = sizeof(struct conf);
uint8_t *c = (uint8_t*)&v.conf;
while (n--) {
@ -699,22 +695,17 @@ uint8_t eeprom_load(uint16_t a)
EECR |= 1<<EERE;
*c++ = EEDR;
}
sei();
return 0;
}
static inline
uint8_t eeprom_read_byte(uint16_t a, uint8_t *r)
{
cli();
if (EECR & 1<<EEWE) {
sei();
if (EECR & 1<<EEWE)
return 1;
}
EEAR = a;
EECR |= 1<<EERE;
*r = EEDR;
sei();
return 0;
}
@ -850,6 +841,8 @@ void reg88(uint8_t *v1, uint8_t *v2, unsigned char *r, const unsigned char *c)
// goes low.
//
// Interrupts
// are enabled only while sleeping, waiting for the SPI master
//
// PCINT2: disable global interrupts
// TIMER1_COMPA: assert STEP
// TIMER1_COMPB: deassert STEP, RESET
@ -897,6 +890,10 @@ int main()
resp[1] = error_msg[4];
resp[2] = error_msg[5];
break;
case '?':
resp[1] = GPIOR2;
resp[2] = GPIOR1;
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);