From 498ef86a74bff9df88238bd02b9f4f8705ab0cde Mon Sep 17 00:00:00 2001 From: Adrian Weber Date: Wed, 15 Apr 2020 13:13:25 +0200 Subject: [PATCH] voltage seetting now fills the shift reg correctly. usb init enabled; ADC enabled; more functions in script for readout. --- atmega32u4/dcdc_rich/README.md | 27 ++++++---- atmega32u4/dcdc_rich/dcdc.pl | 82 ++++++++++++++++++++----------- atmega32u4/dcdc_rich/main.c | 55 +++++++++++++-------- atmega32u4/dcdc_rich/usb_serial.c | 2 +- 4 files changed, 105 insertions(+), 61 deletions(-) diff --git a/atmega32u4/dcdc_rich/README.md b/atmega32u4/dcdc_rich/README.md index cdc7231..57e6201 100644 --- a/atmega32u4/dcdc_rich/README.md +++ b/atmega32u4/dcdc_rich/README.md @@ -9,25 +9,29 @@ ________________________________________________________________________________ First, reset the microcontroller. ``` bash -make clean && make NUMBER=55 && sudo dfu-programmer atmega32u4 erase --force && sudo make program_bootloader +make clean && make NUMBER=55 && sudo dfu-programmer atmega32u4 erase && sudo make program_bootloader ``` Don't forget to change the Serial Number (here 55) to the correct value. Note the serial number on a sticker on the board and add it to a database. +If the board was already flashed, the HWB Pin has to be pulled to GND and simuktaneously the RESET Pin has to be pulled to GND. NOw the board enters the Bootloader. + +After flashing with microUSB, please unplug the cable and plug the adapter. Keep in mind to plug the GND connection too. + ______________________________________________________________________________________________________________ ## Register definition -| Registers | description | -|-----------|-------------------------------------------- -| 0 | DCDC On/Off -> not available | -| 1 | DCDC set voltage adjustment resistors | -| 2 | Voltage V_in | -| 3 | Current C_in | -| 4 | Temperature | -| 5 | [15:2] Frimware; [1] Switch ; [0] LED | +| Registers | description | +|-----------|----------------------------------------------------------- +| 0 | DCDC On/Off -> not available | +| 1 | DCDC set voltage adjustment resistors | +| 2 | Voltage V_in | +| 3 | Current C_in | +| 4 | Temperature | +| 5 | [15:4] Firmware; [3:2] reserved; [1] Switch; [0] LED | ______________________________________________________________________________________________________________ @@ -49,3 +53,8 @@ The data format has to end with \n All in all 10 characters close with a "\n", so a correct data fromat would be e.g. "RF2012FE51\n" + +## Usage + +The DCDC boards receives messages over UART and microUSB. It sends out the messaages *just* over UART. The UART Baud rate is 57600. +For a controlled communication, please use the perl script *./dcdc.pl*. diff --git a/atmega32u4/dcdc_rich/dcdc.pl b/atmega32u4/dcdc_rich/dcdc.pl index d579376..ce84968 100755 --- a/atmega32u4/dcdc_rich/dcdc.pl +++ b/atmega32u4/dcdc_rich/dcdc.pl @@ -51,6 +51,51 @@ sub PrintAnswer { } +sub PrintAnswerNice { + my ($s) = @_; + my $FSR = 0.002; #Full Sclae Range is set to +-4.096V; LSB Size is 2mV + if (substr($s,0,1) ne 'A') {die 'not an correct Answer from DCDC board'} + my $command = hex(substr($s,5,1)); + my $ch = hex(substr($s,4,1)); + my $uC = hex(substr($s,1,2)); + my $answ = hex(substr($s,6)); + + print "-----------------------------------------------\n"; + print "Board: ".$uC."\t"; + print "Channel: ".$ch."\n"; + print "-----------------------------------------------\n"; + + if ($command == 1) { # resistor adjustment values + print "Resistors active: "; + print "SEL0 : ".(($answ>> 0)&0xF)."\n"; + print "\t\t SEL1 : ".(($answ>> 4)&0xF)."\n"; + print "\t\t SEL2 : ".(($answ>> 8)&0xF)."\n"; + print "\t\t SEL3 : ".(($answ>>12)&0xF)."\n"; + } + if ($command == 2) { # Voltage + $answ = $answ >> 4; + my $calc = (($answ&0x7FF)-(($answ>>11)&0x1)*2048)*$FSR*11;# *11 to calculate real input value from voltage divider + printf "measured Voltage @ Input : %.3f Volt (RAW: 0x%x)\n", ($calc) , ($answ); + } + if ($command == 3) { # Current + $answ = $answ >> 4; + my $calc = (($answ&0x7FF)-(($answ>>11)&0x1)*2048)*$FSR*2; # 500mV/A -> Thats why multiplied by 2 + printf "measured Current @ Input : %.3f Ampere (RAW: 0x%x)\n", ($calc) , ($answ); + } + if ($command == 4) { # Temperature + $answ = $answ >> 4; + my $calc = (($answ&0x7FF)-(($answ>>11)&0x1)*2048)*0.125; + printf "measured temperature : %.2f°C (RAW: 0x%x)\n", ($calc) , ($answ); + } + if ($command == 5) { #Infos + print "Firmware : ".($answ>>4)."\n"; + print "SEL status : ".(($answ>>1) & 0x1)."\n"; + print "LED status : ".($answ & 0x1)."\n"; + } + print "\n"; + +} + sub SendCmdShort { my ($reg) = @_; @@ -58,7 +103,7 @@ sub SendCmdShort { # microcontroller number in chain my $uC = $ARGV[1]; if (substr($uC,0,2) eq "0x") {$uC = hex(substr($uC,2));} - if ($uC > $num) { + if ($uC >= $num) { die "This microcontroller Number is not allowed! \n"; } @@ -71,8 +116,8 @@ sub SendCmdShort { my $rw = "R"; my $val = 0x0000; my $cmd = sprintf("%s%02x0%01x%01x%04x",$rw,$uC,$ch,$reg,$val); - print $cmd."\n"; - PrintAnswer(Cmd($cmd)) #Answer without \n + #print $cmd."\n"; + PrintAnswerNice(Cmd($cmd)) #Answer without \n } else { die "Not all arguements were specified!\n"; } @@ -119,7 +164,7 @@ if ($help || (defined $ARGV[0] && $ARGV[0] =~ /help/)) { exit; } $port->user_msg('ON'); - $port->baudrate(57600); + $port->baudrate(57600); $port->parity("none"); $port->databits(8); $port->stopbits(1); @@ -155,7 +200,7 @@ if ($mode == 1) { # microcontroller number in chain $uC = $ARGV[1]; if (substr($uC,0,2) eq "0x") {$uC = hex(substr($uC,2));} - if ($uC > $num) { + if ($uC >= $num) { die "This microcontroller Number is not allowed! \n"; } @@ -198,7 +243,7 @@ if ($mode == 1) { } my $cmd = sprintf("%s%02x0%01x%01x%04x",$rw,$uC,$ch,$reg,$val); print $cmd."\n"; - PrintAnswer(Cmd($cmd)) #Answer without \n + PrintAnswerNice(Cmd($cmd)) #Answer without \n } else { die "Not all arguements were specified!\n"; @@ -211,7 +256,7 @@ if($mode == 2) { # microcontroller number in chain $uC = $ARGV[1]; if (substr($uC,0,2) eq "0x") {$uC = hex(substr($uC,2));} - if ($uC > $num) { + if ($uC >= $num) { die "This microcontroller Number is not allowed! \n"; } @@ -251,26 +296,3 @@ if($mode == 6) {SendCmdShort(0x3)} # Infos if($mode == 7) {SendCmdShort(0x5)} - - - - - -# if($args <= 1) { -# print " Ch\t Curr.\t AvgCur\t Limit\n"; - -# for my $i (0..$num-1) { -# next if ($args >= 1 && $ch != $i); -# my $n = sprintf("%02x",$i); - -# my $s = Cmd("S$n?"); -# my $curr = Cmd("C$n?"); -# my $avg = Cmd("D$n?"); -# my $lim = Cmd("L$n?"); - -# if(($s & 0xf0) == 0xe0) {printf(" $n\tERR\t\t (%3i)\n",$lim&0x3FF);} -# if(($s & 0xff) == 0x00) {printf(" $n\t--- \t\t (%3i)\n",$lim&0x3FF);} -# if(($s & 0xff) == 0x01) {printf(" $n\t%3imA\t %3imA\t (%3i)\n",$curr&0x7ff,$avg&0x7ff,$lim&0x3FF);} -# } - -# } \ No newline at end of file diff --git a/atmega32u4/dcdc_rich/main.c b/atmega32u4/dcdc_rich/main.c index 859666f..14249f7 100644 --- a/atmega32u4/dcdc_rich/main.c +++ b/atmega32u4/dcdc_rich/main.c @@ -10,8 +10,8 @@ #define FIRMWARE_VERSION 0x001 -#define LED_ON() PORTB |= (1<> (nib*4)) & 0xF; @@ -103,8 +104,8 @@ uint8_t is_my_address(uint8_t s) { void setVoltages(void){ cli(); STCP_LOW(); - for (uint8_t i = 0; i < 4; i++ ){ - for (unsigned int j = 0; j < 5; j++){// 5 times to fill also Q7S + for (uint8_t i = 0; i < 4; i++ ){ // channel; 0 == channel 3; 3 == channel0; + for (unsigned int j = 0; j < 4; j++){// fill up the 8 bit SHCP_LOW(); SHIFT_DATA_LOW(); SHCP_HIGH(); // write @@ -155,6 +156,15 @@ void setInfo(uint8_t chan, uint8_t val){ information |= (FIRMWARE_VERSION<<4); } + +/*** + * ADC: ADS1018 + * 12 bits left aligned; + * Temperature: (($answ&0x7FF)-(($answ>>11)&0x1)*2048)*0.125; + * Voltage: (($answ&0x7FF)-(($answ>>11)&0x1)*2048)*$FSR*11;# *11 due to voltage divider; FSR = 2mV + * Current: (($answ&0x7FF)-(($answ>>11)&0x1)*2048)*$FSR*2; # 500mV/A -> Thats why multiplied by 2 + ***/ + uint16_t conversion_ADC(uint8_t mode) { uint8_t get_value_1; uint8_t get_value_2; @@ -183,7 +193,6 @@ uint16_t read_ADC(void) { SPDR = 0b00000000; // LSB=Byte2 while ((SPSR & (1< 0: no PullUp 1: Pullup @@ -398,9 +404,10 @@ __attribute__((naked)) int main(void) { //Init USART UCSR1A = (1 << U2X1); // Double Speed Mode + //UCSR1A = (0 << U2X1); // Single Speed Mode UCSR1B = (1 << RXCIE1) | (0 << TXCIE1) | (0 << RXEN1) | (1 << TXEN1); UCSR1C = (3 << UCSZ10); //8 Bit - UBRR1 = 0x10; //57600 + UBRR1 = 0x10; // 38k4 (SSM) //0x33; // 38k4 //0x10; //57600 _delay_ms(10); UCSR1B |= (1 << RXEN1); @@ -440,17 +447,23 @@ __attribute__((naked)) int main(void) { sei(); uint8_t ADC_State = 0; // 0: start of uC; 1: Volt; 2: Current; 3: Temp uint16_t lasttime = 0; - while(1) { + + while(1) { + int n = usb_serial_getchar(); + if (n >= 0) { + isMaster = 1; + //SELECT_MASTER(); + getdata(n); + } if((time != lasttime) && ((time %10) == 0)) { //~330us for each conversion - /*if (ADC_State == 3) {adc_temp = read_ADC(); ADC_State = 0;} + if (ADC_State == 3) {adc_temp = read_ADC(); ADC_State = 0;} if (ADC_State == 2) {adc_volt = read_ADC(); ADC_State = 3;} if (ADC_State == 1) {adc_curr = read_ADC(); ADC_State = 2;} if (ADC_State == 0) ADC_State = 1; conversion_ADC(ADC_State - 1); - */ } lasttime = time; diff --git a/atmega32u4/dcdc_rich/usb_serial.c b/atmega32u4/dcdc_rich/usb_serial.c index 16d7723..4f40451 100644 --- a/atmega32u4/dcdc_rich/usb_serial.c +++ b/atmega32u4/dcdc_rich/usb_serial.c @@ -43,7 +43,7 @@ // You can change these to give your code its own name. On Windows, // these are only used before an INF file (driver install) is loaded. #define STR_MANUFACTURER L"TRB3" -#define STR_PRODUCT L"Power48" +#define STR_PRODUCT L"DCDC" // All USB serial devices are supposed to have a serial number // (according to Microsoft). On windows, a new COM port is created -- 2.43.0