]> jspc29.x-matter.uni-frankfurt.de Git - avr.git/commitdiff
finished power48 design - untested
authorJan Michel <j.michel@gsi.de>
Mon, 23 Jan 2017 16:00:10 +0000 (17:00 +0100)
committerJan Michel <j.michel@gsi.de>
Mon, 23 Jan 2017 16:00:10 +0000 (17:00 +0100)
atmega32u4/power48/Makefile
atmega32u4/power48/main.c

index aec081620c2bd13e08be7bac4dbaca4de14b152d..df1b1fcfae4a0f9301740b0a6e4a8077500cb8c7 100644 (file)
@@ -29,7 +29,7 @@ DEBUG = stabs
 CSTANDARD = -std=gnu99
 
 # Place -D or -U options here
-CDEFS = -DF_CPU=16000000
+CDEFS = -DF_CPU=8000000
 
 # Place -I options here
 CINCS =
index e083da91bad399e054b4db172ca89a9ec745fe0c..c17970e67603c59fcc55a9b68522ac2fcff2944b 100644 (file)
@@ -1,4 +1,4 @@
-#define F_CPU 8000000UL
+// #define F_CPU 8000000UL
 
 #include <avr/interrupt.h>
 #include <util/delay.h>
@@ -31,7 +31,6 @@
 //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' || rxbuf[2] == '2' || rxbuf[2] == '3') )
 
 volatile uint8_t settings_changed = 0;
@@ -42,12 +41,18 @@ uint16_t adc[4];
 uint16_t avgadc[4] = {0,0,0,0};
 uint8_t  countdown[4] = {0,0,0,0};
 uint16_t adc_reference = 0;
+volatile uint16_t time = 0;
 
 uint8_t rxcnt = 0, txcnt = 0, txpoint = 0;
 uint8_t rxbuf[7];
 uint8_t txbuf[7];
 uint16_t limit[4] = {0x0800,0x0800,0x0800,0x0800};
 
+  
+void uart_puts(const uint8_t *s ){
+  while (*s) 
+    usb_serial_putchar(*s++);
+  } 
 
 uint8_t nib_to_hex(uint16_t in, uint8_t nib) {
   uint8_t t = (in >> (nib*4)) & 0xF;
@@ -71,7 +76,8 @@ void sub2(uint8_t* c1, uint8_t* c2) {
 void forward_msg(uint8_t i) {
   sub2(&rxbuf[1],&rxbuf[2]);
   memcpy ((uint8_t*)txbuf,(uint8_t*)rxbuf,i);
-  STARTTX(i);
+  txbuf[i] = 0;
+  uart_puts(txbuf);
   }  
 
 uint8_t is_my_address(uint8_t s) {
@@ -91,7 +97,8 @@ void send_answer_hex(uint16_t v) {
   txbuf[2]=nib_to_hex(v,1);
   txbuf[3]=nib_to_hex(v,0);
   txbuf[4]='\n';
-  STARTTX(5);
+  txbuf[5] = 0;
+  uart_puts(txbuf);
   }
   
 void send_answer_chars(uint8_t a, uint8_t b, uint8_t c) {
@@ -100,32 +107,43 @@ void send_answer_chars(uint8_t a, uint8_t b, uint8_t c) {
   txbuf[2]=b;
   txbuf[3]=c;
   txbuf[4]='\n';
-  STARTTX(5);
+  txbuf[5] = 0;
+  uart_puts(txbuf);
   }
 
-//----------------------------------------------------------------------------------------------------  
+
+//Channels 0 1 2 3: PD4, PB6, PF6, PF1
 void switchoutput(uint8_t chan, int8_t to) {
-  if(to == -1) {
+  if(to == -1) {//toggle
     output_enable ^= (1<<chan);
     output_error  &= ~(1<<chan);
     }
-  else if (to == 0 || to == -2) {
+  else if (to == 0 || to == -2) {//off
     output_enable &= ~(1<<chan);
     }
-  else if (to == 1) {
+  else if (to == 1) {//on
     output_enable |=  (1<<chan);
     output_error  &= ~(1<<chan);
     }
 
   if(to >= -1) {settings_changed |= 16;}
   
-  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);
-
+  if((output_enable & chan) && !(output_error & chan)) {
+    switch (chan) {
+      case 0 : PORTD |= (1<<4);   break;
+      case 1 : PORTB |= (1<<6);   break;
+      case 2 : PORTF |= (1<<6);   break;
+      case 3 : PORTF |= (1<<1);   break;
+      }
+    }  
+  else {
+    switch (chan) {
+      case 0 : PORTD &= ~(1<<4);   break;
+      case 1 : PORTB &= ~(1<<6);   break;
+      case 2 : PORTF &= ~(1<<6);   break;
+      case 3 : PORTF &= ~(1<<1);   break;
+      }
+    }    
   }
 
 void correct_adc(uint8_t channel) {
@@ -134,14 +152,16 @@ void correct_adc(uint8_t channel) {
       adc[channel] = adc[channel]*2 - (adc[channel]>>3);
       }
     }
-  
+//Buttons 0 1 2 3:  PD1, PD0, PB7, PB3
 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;}
+  static uint8_t dwncnt[4] = {0,0,0,0};
+  if(!(PIND & 0x02)) {dwncnt[0]++;} else {dwncnt[0] = 0;}
+  if(!(PIND & 0x01)) {dwncnt[1]++;} else {dwncnt[1] = 0;}
+  if(!(PINB & 0x80)) {dwncnt[2]++;} else {dwncnt[2] = 0;}
+  if(!(PINB & 0x08)) {dwncnt[3]++;} else {dwncnt[3] = 0;}
          
-       
-  for(uint8_t i=0; i<=1;i++) {
+       time++;
+  for(uint8_t i=0; i<=3;i++) {
     if(dwncnt[i] == 50) {switchoutput(i,-1);}    
     if(countdown[i] != 0) {
       if(countdown[i] == 1) {
@@ -149,58 +169,45 @@ ISR(TIMER0_OVF_vect) {
         }
       countdown[i]--;
       }
-       }
+    }
   
   if(adc_enable) {ADCSRA |= (1<<ADSC);}
   asm volatile("wdr");
   }  
-  
+
+//ADC ref:          PF0(0)
+//Sense 0 1 2 3:    PD6(9), PD7(10), PF7(7), PF4(4)  
+//ADC ref:          PF0(0,0)
+//Sense 0 1 2 3:    PD6(9,3+MUX5), PD7(10,4+MUX5), PF7(7,7), PF4(4,4) (channel, ADMUX value)
+
 ISR(ADC_vect) {
   static uint8_t channel = 0;
-  if(channel == 0) { 
-    adc_reference = ADC;
-    ADMUXA = 7;  
-    ADCSRA |= (1<<ADSC); 
-    channel = 1;
-    }
-  else if(channel == 1) { 
-    adc[0] = ADC; 
-    correct_adc(0);
-    ADMUXA = 1;  
-    ADCSRA |= (1<<ADSC); 
-    channel = 2;
-    avgadc[0] -= avgadc[0]/8;
-    avgadc[0] += adc[0];
-    if(limit[0]*8<avgadc[0]) {
-      output_error |= 1;
-      switchoutput(0,-2);
-      }  
+  switch(channel) {
+    case 0: adc_reference = ADC; break;
+    default: 
+      adc[channel] = ADC; 
+      correct_adc(channel);
+      avgadc[channel] -= avgadc[channel]/8;
+      avgadc[channel] += adc[channel];
+      if(limit[channel]*8<avgadc[channel]) {
+        output_error |= 1;
+        switchoutput(channel,-2);
+        }
     }
-  else if(channel == 2) { 
-    adc[1] = ADC; 
-    correct_adc(1);
-    ADMUXA = 0xD;
-    channel = 0;
-    avgadc[1] -= avgadc[1]/8;
-    avgadc[1] += adc[1];
-    if(limit[1]*8<avgadc[1]) {
-      output_error |= 2;
-      switchoutput(1,-2);
-      }    
+  channel++;
+  switch(channel) {
+    case 0: ADMUX &= 0xe0; ADMUX |= 9;  ADCSRB |= (1<<MUX5);  break;
+    case 1: ADMUX &= 0xe0; ADMUX |= 10; ADCSRB |= (1<<MUX5);  break;
+    case 2: ADMUX &= 0xe0; ADMUX |= 7;  ADCSRB &= ~(1<<MUX5); break;
+    case 3: ADMUX &= 0xe0; ADMUX |= 4;  ADCSRB &= ~(1<<MUX5); break;
+    case 4: ADMUX &= 0xe0; ADMUX |= 0;  ADCSRB &= ~(1<<MUX5); break;
     }
+  if (channel != 5)   
+    ADCSRA |= (1<<ADSC);
   }
 
-ISR(USART1_UDRE_vect) {
-  UDR1 = txbuf[txpoint++];
-  if(--txcnt == 0 || txpoint > 7) {  
-    txpoint = 0;
-    txcnt = 0;
-    UCSR1B &= ~(1<< UDRIE1);
-    }
-  }
   
-ISR(USART1_RX_vect) {
-  uint8_t buf = UDR1;
+void getdata(uint8_t buf) {
   if (rxcnt != 0 || (buf == 'S' || buf == 'A' || buf == 'L' || buf == 'C' || buf == 'I'
                                 || buf == 'D' || buf == 'O' || buf == 'P' || buf == 'R')) {
     rxbuf[rxcnt++] = buf;
@@ -212,7 +219,8 @@ ISR(USART1_RX_vect) {
 //Forward any incoming 4 letter answer    
       if (rxbuf[0] == 'A') {
         memcpy ((uint8_t*)txbuf,(uint8_t*)rxbuf,5);
-        STARTTX(5);
+        txbuf[5] = 0;
+        uart_puts(txbuf);
         }
         
 //Switch command  
@@ -248,19 +256,16 @@ ISR(USART1_RX_vect) {
 
 //Read firmware info
       if (rxbuf[0] == 'I' && rxbuf[3] == '?' && is_my_address(5)) {
-           send_answer_hex(FIRMWARE_VERSION);
+        send_answer_hex(FIRMWARE_VERSION);
         }
         
 //Switch ADC
       if (rxbuf[0] == 'O' && is_my_address(5)) {
-               if(rxbuf[3] != '?')
-                 adc_enable = rxbuf[3] - '0';
+        if(rxbuf[3] != '?')
+          adc_enable = rxbuf[3] - '0';
         send_answer_hex(adc_enable);
         settings_changed |= 32;
-//TODO correct ADC settings        
-        if (adc_enable == 1)  ADMUXB = (6 << REFS0);   //2.2V reference, with capacitor
-        if (adc_enable == 2)  ADMUXB = (7 << REFS0);   //4.096V as reference
-        if (adc_enable == 3)  ADMUXB = (0 << REFS0);   //Vcc as reference
+        if (adc_enable == 1)  ADMUX = (3 << REFS0);   //2.56V reference, with capacitor
         }
       
 //Read current limit    
@@ -290,7 +295,36 @@ ISR(USART1_RX_vect) {
     
 } 
 
-
+void update_eeprom(void) {
+  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,limit[2]&0xFF);
+    eeprom_update_byte((uint8_t*)0x25,(limit[2]>>8)&0xFF);
+    }
+  if (settings_changed & 8) {
+    settings_changed &= ~8;
+    eeprom_update_byte((uint8_t*)0x26,limit[3]&0xFF);
+    eeprom_update_byte((uint8_t*)0x27,(limit[3]>>8)&0xFF);
+    }        
+  if (settings_changed & 16) {
+    settings_changed &= ~16;
+    eeprom_update_byte((uint8_t*)0x29,output_enable);
+    }
+  if (settings_changed & 32) {
+    settings_changed &= ~32;
+    eeprom_update_byte((uint8_t*)0x28,adc_enable);
+    }
+  }
   
 __attribute__((naked)) int main(void) {
   
@@ -334,7 +368,7 @@ __attribute__((naked)) int main(void) {
   TIMSK0 = (1 << TOIE0); //Overflow interrupt`
 
 
-  ADMUX  = (3 << REFS0); --reference 2.56V internal
+  ADMUX  = (3 << REFS0); //reference 2.56V internal
   ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIE)  | (7 << ADPS0); //enable, start, irq, /128
   DIDR0  = (1 << ADC4D) | (1 << ADC7D);
   DIDR2  = (1 << ADC10D) | (1 << ADC9D);
@@ -344,38 +378,16 @@ __attribute__((naked)) int main(void) {
   WDTCSR = (1<<WDE) | (5<<WDP0); 
   sei();  
   
-  
+  uint16_t lasttime = 0;
   while(1) {
-    _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,limit[2]&0xFF);
-        eeprom_update_byte((uint8_t*)0x25,(limit[2]>>8)&0xFF);
-        }
-      if (settings_changed & 8) {
-        settings_changed &= ~8;
-        eeprom_update_byte((uint8_t*)0x26,limit[3]&0xFF);
-        eeprom_update_byte((uint8_t*)0x27,(limit[3]>>8)&0xFF);
-        }        
-      if (settings_changed & 16) {
-        settings_changed &= ~16;
-        eeprom_update_byte((uint8_t*)0x29,output_enable);
-        }
-      if (settings_changed & 32) {
-        settings_changed &= ~32;
-        eeprom_update_byte((uint8_t*)0x28,adc_enable);
-        }
+    int n = usb_serial_getchar();
+    if (n >= 0) {
+      getdata(n);
+      }
+      
+    if(settings_changed != 0 && (lasttime & 0xff) == 255 && (time & 0xff) == 0) {
+      update_eeprom();
       }
+    lasttime = time;
     }
   }