From 755ed3c06c173280d4f63bf98b1d289d782f4e29 Mon Sep 17 00:00:00 2001 From: Jan Michel Date: Fri, 25 Jul 2014 15:24:41 +0200 Subject: [PATCH] new version of power switch firmware with more features --- Power/firmware/Makefile | 2 +- Power/firmware/PowerSwitch.c | 291 ++++++++++++++++++++--------------- 2 files changed, 168 insertions(+), 125 deletions(-) diff --git a/Power/firmware/Makefile b/Power/firmware/Makefile index 34364fc..143fc01 100644 --- a/Power/firmware/Makefile +++ b/Power/firmware/Makefile @@ -7,7 +7,7 @@ MCU = attiny441 FORMAT = ihex -TARGET = main +TARGET = PowerSwitch SRC = $(TARGET).c ASRC = OPT = s diff --git a/Power/firmware/PowerSwitch.c b/Power/firmware/PowerSwitch.c index 0c54c6f..1f414d9 100755 --- a/Power/firmware/PowerSwitch.c +++ b/Power/firmware/PowerSwitch.c @@ -2,11 +2,11 @@ #include #include -// #include -// #include #include +#include #include +#define FIRMWARE_VERSION 0x010 //A0 Aref In //A1 Adc2 In (ADC1) @@ -27,24 +27,33 @@ //Scc(0|1|/) -- switch channel off/on/toggle //Scc? -- read channel status - 2nd char: 'e' in case of overcurrent, 3rd char: enable 1/0 //Ccc? -- read current +//Dcc? -- read averaged current //Lccxxx -- set current limit (hex) //Lcc? -- read current limit //Axxx -- answer - three hex digits or chars +//Occ(0|1|2|3) -- switch ADC & set max scale: off|2.2Vref|4.1Vref|VCCref (one setting for both ports) +//Pcc(0|1) -- Do a automatic power cycle (2 seconds long) +//Rcc? -- read ADC measurement of internal 1.1V reference (one register) +//Icc? -- Firmware Info #define STARTTX(i) txcnt = (i);UCSR1B |= (1<< UDRIE1) -#define ISMYADDR() (rxbuf[1] == '0' && (rxbuf[2] == '0' || rxbuf[2] == '1')) +#define ISMYADDR() (rxbuf[1] == '0' && (rxbuf[2] == '0' || rxbuf[2] == '1') ) volatile uint8_t settings_changed = 0; uint8_t output_enable = 0x3; uint8_t output_error = 0; +uint8_t adc_enable = 1; uint16_t adc[2]; uint16_t avgadc[2] = {0,0}; +uint8_t countdown[2] = {0,0}; +uint16_t adc_reference = 0; uint8_t rxcnt = 0, txcnt = 0, txpoint = 0; uint8_t rxbuf[7]; uint8_t txbuf[7]; uint16_t limit[2] = {0x0800,0x0800}; + uint8_t nib_to_hex(uint16_t in, uint8_t nib) { uint8_t t = (in >> (nib*4)) & 0xF; if (t <= 9) {return t + 0x30;} @@ -69,6 +78,17 @@ void forward_msg(uint8_t i) { memcpy ((uint8_t*)txbuf,(uint8_t*)rxbuf,i); STARTTX(i); } + +uint8_t is_my_address(uint8_t s) { + if (ISMYADDR()) { + rxbuf[2] -= '0'; + return 1; + } + else { + forward_msg(s); + return 0; + } + } void send_answer_hex(uint16_t v) { txbuf[0]='A'; @@ -90,8 +110,10 @@ void send_answer_chars(uint8_t a, uint8_t b, uint8_t c) { void switchoutput(uint8_t chan, int8_t to) { - if(to == -1) + if(to == -1) { output_enable ^= (1<= -1) {settings_changed |= 4;} - uint8_t en1 = ((output_enable & 1) && !(output_error & 1))?0:1; - uint8_t en2 = ((output_enable & 2) && !(output_error & 2))?0:1; - PORTA = (PORTA & ~(3<<2)) | ((en1&1)<<3) | ((en2&1)<<2); + uint8_t en1 = ((output_enable & 1) && !(output_error & 1))?1:0; //switched for open drain version + uint8_t en2 = ((output_enable & 2) && !(output_error & 2))?1:0; + + PORTA &= ~((1<<2) | (1<<3)); + DDRA = (DDRA & ~(3<<2)) | ((en1&1)<<3) | ((en2&1)<<2); + //PORTA = (PORTA & ~(3<<2)) | ((en1&1)<<3) | ((en2&1)<<2); } +void correct_adc(uint8_t channel) { + if(adc_enable == 1) return; + if(adc_enable == 2) { + adc[channel] = adc[channel]*2 - (adc[channel]>>3); + } + } + ISR(TIMER0_OVF_vect) { static uint8_t dwncnt[2] = {0,0}; if(!(PINA & 0x40)) {dwncnt[0]++;} else {dwncnt[0] = 0;} if(!(PINB & 0x04)) {dwncnt[1]++;} else {dwncnt[1] = 0;} - if(dwncnt[0] == 50) {switchoutput(0,-1);} - if(dwncnt[1] == 50) {switchoutput(1,-1);} - - ADCSRA |= (1<= 7 || buf == '\n' || buf == '\r') { rxcnt = 0; } } -#define EEPROM_DIS() while(EECR & (1<>8)&0xFF); - } - if (settings_changed & 2) { - settings_changed &= ~2; - eeprom_write(0x12,limit[1]&0xFF); - eeprom_write(0x13,(limit[1]>>8)&0xFF); - } - if (settings_changed & 4) { - settings_changed &= ~4; - eeprom_write(0x14,output_enable); - } - EEPROM_DIS(); - } + _delay_ms(3000); + if(settings_changed != 0) { + if (settings_changed & 1) { + settings_changed &= ~1; + eeprom_update_byte((uint8_t*)0x20,limit[0]&0xFF); + eeprom_update_byte((uint8_t*)0x21,(limit[0]>>8)&0xFF); + } + if (settings_changed & 2) { + settings_changed &= ~2; + eeprom_update_byte((uint8_t*)0x22,limit[1]&0xFF); + eeprom_update_byte((uint8_t*)0x23,(limit[1]>>8)&0xFF); + } + if (settings_changed & 4) { + settings_changed &= ~4; + eeprom_update_byte((uint8_t*)0x24,output_enable); + } + if (settings_changed & 8) { + settings_changed &= ~8; + eeprom_update_byte((uint8_t*)0x25,adc_enable); + } + } } } \ No newline at end of file -- 2.43.0