Compare commits

..

No commits in common. "d20586f0fca1be711e2451b471b621eddd4a3639" and "04e72a30109f91470034da3ed6774ebe4209e521" have entirely different histories.

View file

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