From: Jan Michel <j.michel@gsi.de> Date: Mon, 26 May 2014 13:27:23 +0000 (+0200) Subject: added first version of Power module firmware X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=d056350f68eacece250a557321b27ce3f25e38aa;p=electronics.git added first version of Power module firmware --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2a71a89 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.kate* +.~* +*swp diff --git a/Power/firmware/PowerSwitch.c b/Power/firmware/PowerSwitch.c new file mode 100755 index 0000000..74158b6 --- /dev/null +++ b/Power/firmware/PowerSwitch.c @@ -0,0 +1,249 @@ +#define F_CPU 6000000UL + +#include <avr/interrupt.h> +// #include <util/delay.h> +// #include <avr/sleep.h> +// #include <stdint.h> +#include <avr/io.h> +#include <string.h> + + +//A0 Aref In +//A1 Adc2 In (ADC1) +//A2 Relay2 Out +//A3 Relay1 Out +//A4 RX In +//A5 TX Out +//A6 Switch1 In +//A7 Adc1 In (ADC7) + +//B0 X -- +//B1 X -- +//B2 Switch2 In +//B3 Reset -- + +// cc -- channel address in hex +//Scc(0|1|/) -- switch channel off/on/toggle +//Scc? -- read channel status +//Ccc? -- read current +//Lccxxx -- set current limit (hex) +//Lcc? -- read current limit +//Axxx -- answer - three hex digits or chars + +#define STARTTX(i) txcnt = (i);UCSR1B |= (1<< UDRIE1) +#define ISMYADDR() (rxbuf[1] == '0' && (rxbuf[2] == '0' || rxbuf[2] == '1')) + + +uint8_t output_enable = 0; +uint8_t output_error = 0; +uint16_t adc[2]; + +uint8_t rxcnt = 0, txcnt = 0, txpoint = 0; +uint8_t rxbuf[6]; +uint8_t txbuf[6]; +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;} + return t - 10 + 0x61; + } + +uint8_t hex_to_int(uint8_t h) { //assumes valid number + if (h < 0x40) return h-0x30; + if (h < 0x50) return h-0x41+10; + return h-0x61+10; + } + +void sub2(uint8_t* c1, uint8_t* c2) { + uint8_t b = hex_to_int(*c1)*16 + hex_to_int(*c2); + b -= 2; + *c1 = nib_to_hex(b,1); + *c2 = nib_to_hex(b,0); + } + +void forward_msg(uint8_t i) { + sub2(&rxbuf[1],&rxbuf[2]); + memcpy ((uint8_t*)txbuf,(uint8_t*)rxbuf,i); + STARTTX(i); + } + +void send_answer_hex(uint16_t v) { + txbuf[0]='A'; + txbuf[1]=nib_to_hex(v,2); + txbuf[2]=nib_to_hex(v,1); + txbuf[3]=nib_to_hex(v,0); + STARTTX(4); + } + +void send_answer_chars(uint8_t a, uint8_t b, uint8_t c) { + txbuf[0]='A'; + txbuf[1]=a; + txbuf[2]=b; + txbuf[3]=c; + STARTTX(4); + } + + +void switchoutput(uint8_t chan, int8_t to) { + if(to == -1) + output_enable ^= (1<<chan); + else if (to == 0) { + output_enable &= ~(1<<chan); + output_error &= ~(1<<chan); + } + else if (to == 1) + output_enable |= (1<<chan); + + uint8_t en1 = ((output_enable & 1) && !(output_error & 1))?1:0; + uint8_t en2 = ((output_enable & 2) && !(output_error & 2))?1:0; + PORTA = (PORTA & ~(1<<3)) | ((en1&1)<<3); + PORTA = (PORTA & ~(1<<2)) | ((en2&1)<<2); + } + +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] == 100) {switchoutput(0,-1);} + if(dwncnt[1] == 100) {switchoutput(1,-1);} + + ADCSRA |= (1<<ADSC); + } + +ISR(ADC_vect) { + static uint8_t channel = 0; + if(channel == 0) { + adc[0] = ADC; + ADMUXA = 1; + ADCSRA |= (1<<ADSC); + channel = 1; + if(limit[0]<adc[0]) { + output_error |= 2; + switchoutput(0,-2); + } + } + if(channel == 1) { + adc[1] = ADC; + ADMUXA = 7; + channel = 0; + if(limit[1]<adc[1]) { + output_error |= 2; + switchoutput(1,-2); + } + } + } + +ISR(USART1_UDRE_vect) { + UDR1 = txbuf[txpoint++]; + if(--txcnt == 0) { + txpoint = 0; + UCSR1B &= ~(1<< UDRIE1); + } + } + +ISR(USART1_RX_vect) { + uint8_t buf = UDR1; + if (rxcnt != 0 || (buf == 'S' || buf == 'A' || buf == 'L' || buf == 'C')) { + rxbuf[rxcnt++] = buf; + } + //Forward any incoming 4 letter answer + if (rxcnt == 4) { + if (rxbuf[0] == 'A') { + rxcnt = 0; + memcpy ((uint8_t*)txbuf,(uint8_t*)rxbuf,4); + STARTTX(4); + } + //Four letter 'switch' command + if (rxbuf[0] == 'S') { + rxcnt = 0; + if (ISMYADDR()) { + rxbuf[2] -= '0'; + if (rxbuf[3] != '?') { + switchoutput(rxbuf[2],rxbuf[3]-'0'); + } + send_answer_chars('0', (output_error & (1<<rxbuf[2]))?'e':'0', + (output_enable & (1<<rxbuf[2]))?'1':'0'); + } + else { + forward_msg(4); + } + } + //Read current command + if (rxbuf[0] == 'C') { + rxcnt = 0; + if (ISMYADDR()) { + if (rxbuf[3] == '?') + send_answer_hex(adc[rxbuf[2]-'0']); + } + else { + forward_msg(4); + } + } + //Read current limit + if (rxbuf[0] == 'L' && rxbuf[3] == '?') { + rxcnt = 0; + if (ISMYADDR()) { + send_answer_hex(limit[rxbuf[2]-'0']); + } + else { + forward_msg(4); + } + } + } + //Set current limit + if (rxcnt == 6 && rxbuf[0] == 'L') { + rxcnt = 0; + if (ISMYADDR()) { + rxbuf[2] -= '0'; + if(rxbuf[3] != '?') { + uint16_t lim = hex_to_int(rxbuf[3])*256 + hex_to_int(rxbuf[4])*16 + hex_to_int(rxbuf[5]); + limit[rxbuf[2]] = lim; + } + send_answer_hex(limit[rxbuf[2]]); + } + else { + forward_msg(6); + } + } + + if (rxcnt >= 6) { rxcnt = 0; } + +} + + +__attribute__((naked)) int main(void) { + // Configure ports + DDRA = 0b00101100; + DDRB = 0b00000000; + + PORTA = 0b00000000; + PORTB = 0b00000000; + + PUEA = 0b01011100; + PUEB = 0b00001100; + + CLKPR = (0 << CLKPS0); // no prescaler + PRR = (1 << PRTWI) | (0 << PRUSART1) | (1 << PRUSART0) | (1 << PRSPI) + |(1 << PRTIM2) | (1 << PRTIM1) | (0 << PRTIM0) | (0 << PRADC); + + TCCR0B = (4 << CS00); //prescaler 256 -> 6M/256*256 = 91.5 Hz + TIMSK0 = (1 << TOIE0); //Overflow interrupt` + + ADMUXA = 1; //(1 (Out2),7 (Out1)) + ADMUXB = (6 << REFS0); //2.2V reference, with capacitor + ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (7 << ADPS0); //enable, start, irq, /128 + ADCSRB = 0; + DIDR0 = (1<<ADC1D) | (1<< ADC7D); //disable digital inputs + + UCSR1A = (1 << U2X1); + UCSR1B = (1 << RXCIE1) | (0 << TXCIE1) | (1 << RXEN1) | (1 << TXEN1); + UCSR1C = (3 << UCSZ10); //8 Bit + UBRR1 = 0x26; //19200 + + sei(); + while(1) { + + } + } \ No newline at end of file diff --git a/Power/firmware/main.c b/Power/firmware/main.c deleted file mode 100644 index e69de29..0000000