Compare commits
No commits in common. "d9cde306901506f2c90ae9e10fb952ca74e1b0bc" and "bf69d871f451180b905a99dcaf2897370944222c" have entirely different histories.
d9cde30690
...
bf69d871f4
3 changed files with 42 additions and 50 deletions
3
Makefile
3
Makefile
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue