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-bitfields \
-fpack-struct \
-fshort-enums
-fshort-enums \
-fverbose-asm
CFLAGS = $($*_CFLAGS) $(DEBUG)

View file

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