#define STARTTX(i) txcnt = (i);UCSR1B |= (1<< UDRIE1)\r
#define ISMYADDR() (rxbuf[1] == '0' && (rxbuf[2] == '0' || rxbuf[2] == '1'))\r
\r
-\r
-uint8_t output_enable = 0;\r
+volatile uint8_t settings_changed = 0;\r
+uint8_t output_enable = 0x3;\r
uint8_t output_error = 0;\r
uint16_t adc[2];\r
+uint16_t avgadc[2] = {0,0};\r
\r
uint8_t rxcnt = 0, txcnt = 0, txpoint = 0;\r
uint8_t rxbuf[7];\r
void switchoutput(uint8_t chan, int8_t to) {\r
if(to == -1)\r
output_enable ^= (1<<chan);\r
- else if (to == 0) {\r
+ else if (to == 0 || to == -2) {\r
output_enable &= ~(1<<chan);\r
- output_error &= ~(1<<chan);\r
}\r
- else if (to == 1)\r
- output_enable |= (1<<chan);\r
- \r
- uint8_t en1 = ((output_enable & 1) && !(output_error & 1))?1:0;\r
- uint8_t en2 = ((output_enable & 2) && !(output_error & 2))?1:0;\r
- PORTA = (PORTA & ~(1<<3)) | ((en1&1)<<3);\r
- PORTA = (PORTA & ~(1<<2)) | ((en2&1)<<2);\r
+ else if (to == 1) {\r
+ output_enable |= (1<<chan);\r
+ output_error &= ~(1<<chan);\r
+ }\r
+\r
+ if(to >= -1) {settings_changed = 3;}\r
+ \r
+ uint8_t en1 = ((output_enable & 1) && !(output_error & 1))?0:1;\r
+ uint8_t en2 = ((output_enable & 2) && !(output_error & 2))?0:1;\r
+ PORTA = (PORTA & ~(3<<2)) | ((en1&1)<<3) | ((en2&1)<<2);\r
+\r
}\r
\r
ISR(TIMER0_OVF_vect) {\r
if(!(PINA & 0x40)) {dwncnt[0]++;} else {dwncnt[0] = 0;}\r
if(!(PINB & 0x04)) {dwncnt[1]++;} else {dwncnt[1] = 0;}\r
\r
- if(dwncnt[0] == 100) {switchoutput(0,-1);} \r
- if(dwncnt[1] == 100) {switchoutput(1,-1);}\r
+ if(dwncnt[0] == 50) {switchoutput(0,-1);} \r
+ if(dwncnt[1] == 50) {switchoutput(1,-1);}\r
\r
ADCSRA |= (1<<ADSC); \r
+ asm volatile("wdr");\r
}\r
\r
ISR(ADC_vect) {\r
ADMUXA = 1; \r
ADCSRA |= (1<<ADSC); \r
channel = 1;\r
- if(limit[0]<adc[0]) {\r
- output_error |= 2;\r
+ avgadc[0] -= avgadc[0]/8;\r
+ avgadc[0] += adc[0];\r
+ if(limit[0]*8<avgadc[0]) {\r
+ output_error |= 1;\r
switchoutput(0,-2);\r
} \r
}\r
- if(channel == 1) { \r
+ else if(channel == 1) { \r
adc[1] = ADC; \r
ADMUXA = 7; \r
+// ADCSRA |= (1<<ADSC); \r
channel = 0;\r
- if(limit[1]<adc[1]) {\r
+ avgadc[1] -= avgadc[1]/8;\r
+ avgadc[1] += adc[1];\r
+ if(limit[1]*8<avgadc[1]) {\r
output_error |= 2;\r
switchoutput(1,-2);\r
} \r
UDR1 = txbuf[txpoint++];\r
if(--txcnt == 0 || txpoint > 7) { \r
txpoint = 0;\r
+ txcnt = 0;\r
UCSR1B &= ~(1<< UDRIE1);\r
}\r
}\r
\r
ISR(USART1_RX_vect) {\r
uint8_t buf = UDR1;\r
- if (rxcnt != 0 || (buf == 'S' || buf == 'A' || buf == 'L' || buf == 'C')) {\r
+ if (rxcnt != 0 || (buf == 'S' || buf == 'A' || buf == 'L' || buf == 'C' || buf == 'D')) {\r
rxbuf[rxcnt++] = buf;\r
}\r
//Forward any incoming 4 letter answer\r
// }\r
if(rxcnt == 5) {\r
if (rxbuf[0] == 'A') {\r
- memcpy ((uint8_t*)txbuf,(uint8_t*)rxbuf,4);\r
- STARTTX(4);\r
+ memcpy ((uint8_t*)txbuf,(uint8_t*)rxbuf,5);\r
+ STARTTX(5);\r
}\r
//Four letter 'switch' command \r
if (rxbuf[0] == 'S') { \r
forward_msg(5);\r
}\r
}\r
+ //Read average current command\r
+ if (rxbuf[0] == 'D') {\r
+ if (ISMYADDR()) {\r
+ if (rxbuf[3] == '?')\r
+ send_answer_hex(avgadc[rxbuf[2]-'0']/8);\r
+ }\r
+ else {\r
+ forward_msg(5);\r
+ }\r
+ }\r
//Read current limit \r
if (rxbuf[0] == 'L' && rxbuf[3] == '?') {\r
if (ISMYADDR()) {\r
uint16_t lim = hex_to_int(rxbuf[3])*256 + hex_to_int(rxbuf[4])*16 + hex_to_int(rxbuf[5]);\r
limit[rxbuf[2]] = lim;\r
}\r
- send_answer_hex(limit[rxbuf[2]]); \r
+ send_answer_hex(limit[rxbuf[2]]); \r
+ settings_changed = rxbuf[2]+1; \r
}\r
else {\r
forward_msg(7);\r
\r
} \r
\r
+void eeprom_write(uint8_t addr, uint8_t data){\r
+ while(EECR & (1<<EEPE));\r
+ EECR = (0<<EEPM0);\r
+ EEARL = addr;\r
+ EEDR = data;\r
+ cli();\r
+ EECR |= (1<<EEMPE);\r
+ EECR |= (1<<EEPE);\r
+ sei(); \r
+ }\r
\r
+uint8_t eeprom_read(uint8_t addr) {\r
+ while(EECR & (1<<EEPE));\r
+ EEARL = addr;\r
+ EECR |= (1<<EERE);\r
+ return EEDR;\r
+ }\r
+ \r
__attribute__((naked)) int main(void) {\r
// Configure ports\r
+ \r
+ PUEA = 0b01011100;\r
+ PUEB = 0b00001100;\r
+ \r
DDRA = 0b00101100; \r
DDRB = 0b00000000;\r
\r
- PORTA = 0b00000000;\r
+ PORTA = 0b00001100;\r
PORTB = 0b00000000;\r
-\r
- PUEA = 0b01011100;\r
- PUEB = 0b00001100; \r
- \r
+ \r
+ output_enable = eeprom_read(0x14);\r
+ switchoutput(0,-3); \r
+ limit[0] = eeprom_read(0x11)<<8;\r
+ limit[0] |= eeprom_read(0x10);\r
+ limit[1] = eeprom_read(0x13)<<8;\r
+ limit[1] |= eeprom_read(0x12); \r
+ \r
+ //CCP = 0xD8; //allow writing of CLKPR\r
CLKPR = (0 << CLKPS0); // no prescaler \r
PRR = (1 << PRTWI) | (0 << PRUSART1) | (1 << PRUSART0) | (1 << PRSPI) \r
|(1 << PRTIM2) | (1 << PRTIM1) | (0 << PRTIM0) | (0 << PRADC); \r
TCCR0B = (4 << CS00); //prescaler 256 -> 6M/256*256 = 91.5 Hz\r
TIMSK0 = (1 << TOIE0); //Overflow interrupt`\r
\r
- ADMUXA = 1; //(1 (Out2),7 (Out1))\r
+ ADMUXA = 7; //(1 (Out2),7 (Out1))\r
ADMUXB = (6 << REFS0); //2.2V reference, with capacitor\r
- ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (7 << ADPS0); //enable, start, irq, /128\r
+ ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (6 << ADPS0); //enable, start, irq, /128\r
ADCSRB = 0;\r
DIDR0 = (1<<ADC1D) | (1<< ADC7D); //disable digital inputs\r
\r
UCSR1A = (1 << U2X1);\r
UCSR1B = (1 << RXCIE1) | (0 << TXCIE1) | (0 << RXEN1) | (1 << TXEN1);\r
UCSR1C = (3 << UCSZ10); //8 Bit\r
- UBRR1 = 0x26; //19200\r
+ UBRR1 = 0x0C; //57600\r
\r
_delay_ms(100);\r
UCSR1B |= (1 << RXEN1);\r
+\r
+ CCP = 0xD8;\r
+ WDTCSR = (1<<WDE) | (5<<WDP0); //Watchdog at .5 seconds\r
sei(); \r
+ \r
+ \r
while(1) {\r
- \r
+ if (settings_changed == 1) {\r
+ settings_changed = 0;\r
+ eeprom_write(0x10,limit[0]&0xFF);\r
+ eeprom_write(0x11,(limit[0]>>8)&0xFF);\r
+ }\r
+ if (settings_changed == 2) {\r
+ settings_changed = 0;\r
+ eeprom_write(0x12,limit[1]&0xFF);\r
+ eeprom_write(0x13,(limit[1]>>8)&0xFF);\r
+ }\r
+ if (settings_changed == 3) {\r
+ settings_changed = 0;\r
+ eeprom_write(0x14,output_enable);\r
+ }\r
}\r
}
\ No newline at end of file