Compare commits
2 commits
bf69d871f4
...
d9cde30690
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9cde30690 | ||
|
|
c080c89273 |
3 changed files with 50 additions and 42 deletions
3
Makefile
3
Makefile
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue