Compare commits

..

2 commits

Author SHA1 Message Date
stephan
d9cde30690 arm/avr/chaos: hv_safe()
- WDT timeout at 1s
- toggle LED in WDT interrupt
- enable WDT reset
- keep WDT interrupting, reset only when stuck `cli()`
- `hv_safe()` when WDT interrupts accumulate
- `hv_safe()` shuts down hvosc, dac and optionally portc.  
- `hv_is_safe()` when hvosc is off and dac is off.


git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm/avr@8952 bc5caf13-1734-44f8-af43-603852e9ee25
2024-05-24 15:45:11 +00:00
stephan
c080c89273 arm/avr: -fverbose-asm
git-svn-id: svn+ssh://asterix.ieap.uni-kiel.de/home/subversion/stephan/solo/eda/arm/avr@8951 bc5caf13-1734-44f8-af43-603852e9ee25
2024-05-24 15:36:20 +00:00
3 changed files with 50 additions and 42 deletions

View file

@ -16,7 +16,8 @@ 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>
unsigned char wdt_init(unsigned char mode); void wdt_init(unsigned char mode);
unsigned char wdt_count; unsigned char wdt_count;
unsigned char wdt_saved; unsigned char wdt_saved;
@ -74,8 +74,7 @@ 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_FULL = 5, // ≥ do not allow HV reset to be interrupted WDT_MODE_RAMP = 5, // ≥ dac_ramp kicks
WDT_MODE_RAMP = 6, // ≥ dac_ramp kicks
}; };
static inline void wdt_kick() static inline void wdt_kick()
@ -89,7 +88,6 @@ 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;
@ -111,14 +109,11 @@ struct {
unsigned char hvosc_dc; unsigned char hvosc_dc;
unsigned char padding[2]; unsigned char padding[2];
} conf = { } conf = {
.wdt_timeout = 10, // 2 min .wdt_timeout = 120, // 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 {
@ -164,10 +159,26 @@ void conf_init()
} }
} }
static inline void led_hv() int hv_is_safe()
{
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 (conf.dac == conf.dac_off) if (hv_is_safe())
led_toggle(LED_GREEN); led_toggle(LED_GREEN);
else else
led_toggle(LED_RED); led_toggle(LED_RED);
@ -200,8 +211,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]) {
@ -254,13 +265,12 @@ int main()
hvosc_init(conf.hvosc_freq, conf.hvosc_dc); hvosc_init(conf.hvosc_freq, conf.hvosc_dc);
break; break;
case 'I': case 'I':
int2frame(tick_freq(), resp+1);
conf.tick_period = frame2int(cmd+1);
tick_init(conf.tick_period);
break;
case 'i': case 'i':
int2frame(conf.wdt_tick_period, resp+1); int2frame(tick_freq(), resp+1);
conf.wdt_tick_period = frame2int(cmd+1); if (upcase(cmd[0])) {
conf.tick_period = frame2int(cmd+1);
tick_init(conf.tick_period);
}
break; break;
case 'A': case 'A':
ads8688_cmd(cmd+1, resp+1); ads8688_cmd(cmd+1, resp+1);
@ -311,10 +321,12 @@ 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]) {
sreg = wdt_init(cmd[1]); wdt_init(cmd[1]);
sreg = (1<<SREG_I);
}
else { else {
int2frame(wdt_count, resp+1); resp[2] = wdt_count;
wdt_kick(); wdt_kick();
} }
break; break;
@ -515,45 +527,34 @@ 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)
return; goto wdt_out;
tick_init(conf.wdt_tick_period); hv_safe();
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);
} }
WDTCSR |= WDIF; // should not be necessary wdt_out:
WDTCSR |= WDIE;
} }
unsigned char wdt_init(unsigned char mode) void 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 0; return;
} }
// 8s timeout, WDT interrupt enabled // 1s 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<<WDP3 | 1<<WDP0)), [CE] "r" ((unsigned char)(1<<WDCE | 1<<WDE | 1<<WDP2 | 1<<WDP1)),
[IE] "r" ((unsigned char)(1<<WDIE | 1<<WDP3 | 1<<WDP0)) [IE] "r" ((unsigned char)(1<<WDIE | 1<<WDE | 1<<WDP2 | 1<<WDP1))
); );
return 1 << SREG_I;
} }
void eeprom_save(unsigned char a) void eeprom_save(unsigned char a)

View file

@ -18,3 +18,9 @@ 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;
}