Compare commits

..

No commits in common. "d9cde306901506f2c90ae9e10fb952ca74e1b0bc" and "bf69d871f451180b905a99dcaf2897370944222c" have entirely different histories.

3 changed files with 42 additions and 50 deletions

View file

@ -16,8 +16,7 @@ CC=avr-gcc -Wall -MMD -std=c99 -O3 -mmcu=$(MCU) \
-funsigned-char \ -funsigned-char \
-funsigned-bitfields \ -funsigned-bitfields \
-fpack-struct \ -fpack-struct \
-fshort-enums \ -fshort-enums
-fverbose-asm
CFLAGS = $($*_CFLAGS) $(DEBUG) CFLAGS = $($*_CFLAGS) $(DEBUG)

View file

@ -66,7 +66,7 @@ static inline void avrdac_set(unsigned int d)
} }
#include <avr/wdt.h> #include <avr/wdt.h>
void wdt_init(unsigned char mode); unsigned char wdt_init(unsigned char mode);
unsigned char wdt_count; unsigned char wdt_count;
unsigned char wdt_saved; unsigned char wdt_saved;
@ -74,7 +74,8 @@ enum {
WDT_MODE_LIVE = 2, // = any command kick WDT_MODE_LIVE = 2, // = any command kick
WDT_MODE_KICK = 3, // only 'W' command kicks WDT_MODE_KICK = 3, // only 'W' command kicks
WDT_MODE_HV = 4, // ≥ 'H' command kicks WDT_MODE_HV = 4, // ≥ 'H' command kicks
WDT_MODE_RAMP = 5, // ≥ dac_ramp kicks WDT_MODE_FULL = 5, // ≥ do not allow HV reset to be interrupted
WDT_MODE_RAMP = 6, // ≥ dac_ramp kicks
}; };
static inline void wdt_kick() static inline void wdt_kick()
@ -88,6 +89,7 @@ struct {
unsigned int dac_nominal; unsigned int dac_nominal;
unsigned int dac_off; unsigned int dac_off;
unsigned int tick_period; unsigned int tick_period;
unsigned int wdt_tick_period;
unsigned char flags; unsigned char flags;
unsigned char flags2; unsigned char flags2;
unsigned char wdt_timeout; unsigned char wdt_timeout;
@ -109,11 +111,14 @@ struct {
unsigned char hvosc_dc; unsigned char hvosc_dc;
unsigned char padding[2]; unsigned char padding[2];
} conf = { } conf = {
.wdt_timeout = 120, // 2 min .wdt_timeout = 10, // 2 min
.wdt_tick_period = TICK_NS(100000L), // 100µs
.tick_period = TICK_NS(10000000L), // 10ms .tick_period = TICK_NS(10000000L), // 10ms
.avradc = 0x7f, // off .avradc = 0x7f, // off
.adcconf = 0x8500,// RST .adcconf = 0x8500,// RST
.ddrc = 2, // OC1B HVOSC .ddrc = 2, // OC1B HVOSC
.hvosc_freq = 51,
.hvosc_dc = 9,
}; };
enum { enum {
@ -159,26 +164,10 @@ void conf_init()
} }
} }
int hv_is_safe() static inline void led_hv()
{
return !hvosc_is_on() && conf.dac==conf.dac_off;
}
void hv_safe()
{
hvosc_init(0, 0);
if (conf.flags2 & FLAG2_PC_HV)
PORTC = conf.portc_off;
unsigned char sreg = disable_irq();
ltc1655_cmd(INT2FRAME(conf.dac_off));
conf.dac = conf.dac_off;
enable_irq(sreg);
}
void toggle_hv_led()
{ {
if (conf.flags2 & FLAG2_HVLED) { if (conf.flags2 & FLAG2_HVLED) {
if (hv_is_safe()) if (conf.dac == conf.dac_off)
led_toggle(LED_GREEN); led_toggle(LED_GREEN);
else else
led_toggle(LED_RED); led_toggle(LED_RED);
@ -211,8 +200,8 @@ int main()
const char *p; const char *p;
spi_slave_Rx(cmd, 3); spi_slave_Rx(cmd, 3);
resp[0] = cmd[0]; resp[0] = cmd[0];
toggle_hv_led();
sreg = disable_irq(); sreg = disable_irq();
led_hv();
if (conf.wdt_mode == WDT_MODE_LIVE) if (conf.wdt_mode == WDT_MODE_LIVE)
wdt_kick(); wdt_kick();
switch (cmd[0]) { switch (cmd[0]) {
@ -265,12 +254,13 @@ int main()
hvosc_init(conf.hvosc_freq, conf.hvosc_dc); hvosc_init(conf.hvosc_freq, conf.hvosc_dc);
break; break;
case 'I': case 'I':
case 'i':
int2frame(tick_freq(), resp+1); int2frame(tick_freq(), resp+1);
if (upcase(cmd[0])) { conf.tick_period = frame2int(cmd+1);
conf.tick_period = frame2int(cmd+1); tick_init(conf.tick_period);
tick_init(conf.tick_period); break;
} case 'i':
int2frame(conf.wdt_tick_period, resp+1);
conf.wdt_tick_period = frame2int(cmd+1);
break; break;
case 'A': case 'A':
ads8688_cmd(cmd+1, resp+1); ads8688_cmd(cmd+1, resp+1);
@ -321,12 +311,10 @@ int main()
resp[2] = conf.wdt_timeout; resp[2] = conf.wdt_timeout;
if (cmd[2]) if (cmd[2])
conf.wdt_timeout = cmd[2]; conf.wdt_timeout = cmd[2];
if (cmd[1]) { if (cmd[1])
wdt_init(cmd[1]); sreg = wdt_init(cmd[1]);
sreg = (1<<SREG_I);
}
else { else {
resp[2] = wdt_count; int2frame(wdt_count, resp+1);
wdt_kick(); wdt_kick();
} }
break; break;
@ -527,34 +515,45 @@ void dac_ramp(unsigned int target)
ISR(WDT_vect) ISR(WDT_vect)
{ {
toggle_hv_led();
if (wdt_count++ < conf.wdt_timeout) if (wdt_count++ < conf.wdt_timeout)
goto wdt_out; return;
hv_safe(); tick_init(conf.wdt_tick_period);
unsigned char mode = conf.wdt_mode;
conf.wdt_mode = WDT_MODE_RAMP;
do
dac_ramp(conf.dac_off);
while (mode >= WDT_MODE_FULL && conf.dac != conf.dac_off);
wdt_reset(); wdt_reset();
if (conf.dac == conf.dac_off) {
if (conf.flags2 & FLAG2_PC_HV)
PORTC = conf.portc_off;
if (conf.flags2 & FLAG2_HVOSC)
hvosc_init(0, 0);
}
tick_init(conf.tick_period);
if (conf.wdt_save_addr && !wdt_saved) { if (conf.wdt_save_addr && !wdt_saved) {
wdt_saved = 1; wdt_saved = 1;
eeprom_save(conf.wdt_save_addr); eeprom_save(conf.wdt_save_addr);
} }
wdt_out: WDTCSR |= WDIF; // should not be necessary
WDTCSR |= WDIE;
} }
void wdt_init(unsigned char mode) unsigned char wdt_init(unsigned char mode)
{ {
conf.wdt_mode = mode; conf.wdt_mode = mode;
wdt_reset(); wdt_reset();
if (mode < WDT_MODE_LIVE) { if (mode < WDT_MODE_LIVE) {
WDTCSR = 0; WDTCSR = 0;
return; return 0;
} }
// 1s timeout, WDT interrupt enabled // 8s timeout, WDT interrupt enabled
__asm__("STS %[CSR], %[CE]" "\n\t" __asm__("STS %[CSR], %[CE]" "\n\t"
"STS %[CSR], %[IE]" "\n" "STS %[CSR], %[IE]" "\n"
::[CSR] "n" (&WDTCSR), ::[CSR] "n" (&WDTCSR),
[CE] "r" ((unsigned char)(1<<WDCE | 1<<WDE | 1<<WDP2 | 1<<WDP1)), [CE] "r" ((unsigned char)(1<<WDCE | 1<<WDE | 1<<WDP3 | 1<<WDP0)),
[IE] "r" ((unsigned char)(1<<WDIE | 1<<WDE | 1<<WDP2 | 1<<WDP1)) [IE] "r" ((unsigned char)(1<<WDIE | 1<<WDP3 | 1<<WDP0))
); );
return 1 << SREG_I;
} }
void eeprom_save(unsigned char a) void eeprom_save(unsigned char a)

View file

@ -18,9 +18,3 @@ static inline void hvosc_init(unsigned char freq, unsigned char dc)
OCR1BH = 0; OCR1BH = 0;
OCR1BL = freq-dc; OCR1BL = freq-dc;
} }
static inline
int hvosc_is_on()
{
return TCCR1A;
}