From: Adrian Weber <adrian.a.weber@exp2.physik.uni-giessen.de> Date: Thu, 11 Feb 2021 11:02:53 +0000 (+0100) Subject: CBM Rich Sensoring uC: start of DS28E17 libraray and fixes due to first test with... X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=49c4a25fe370d21b029de1ca0691c8dee6336bc5;p=avr.git CBM Rich Sensoring uC: start of DS28E17 libraray and fixes due to first test with real sensor modules. Readout is functional. --- diff --git a/atmega32u4/CbmRich_sensoring/DS28E17/DS28E17.c b/atmega32u4/CbmRich_sensoring/DS28E17/DS28E17.c new file mode 100644 index 0000000..13f123d --- /dev/null +++ b/atmega32u4/CbmRich_sensoring/DS28E17/DS28E17.c @@ -0,0 +1,88 @@ +#include "DS28E17.h" + +int ds28e17_Write_with_Stop(owu_struct_t *wire, uint8_t *OW_addr, uint8_t I2C_Addr) +{ + int wire_status; + + uint8_t CRC_data_buf[] = {0,0,0,0}; + wire_status = owu_reset(wire); + if (wire_status != OW_OK) return wire_status; + + wire_status = owu_select_device(wire, OW_addr); + if (wire_status != OW_OK) return wire_status; + + wire_status = owu_write_byte(wire, CMD_WwS); + if (wire_status != OW_OK) return wire_status; + CRC_data_buf[0] = CMD_WwS; + + //Send I2C Address + //uint8_t addr_i2c = (I2C_Addr << 1) | 0x1; + // not sure if Address has to be shifted or not + wire_status = owu_write_byte(wire, ((I2C_Addr << 1) | 0x0)); // 0x0: write + if (wire_status != OW_OK) return wire_status; + CRC_data_buf[1] = ((I2C_Addr << 1) | 0x0); // check if address has to be shifted or not + + //Length of Data + wire_status = owu_write_byte(wire, 0x01); + if (wire_status != OW_OK) return wire_status; + CRC_data_buf[2] = 0x01; + + //Data + wire_status = owu_write_byte(wire, 0x80); + if (wire_status != OW_OK) return wire_status; + CRC_data_buf[3] = 0x80; + + //CRC16 + uint8_t CRC16 = ds28e17_crc16(CRC_data_buf,4); + wire_status = owu_write_byte(wire, CRC16); + if (wire_status != OW_OK) return wire_status; + + // read status: read bit until 0; + uint8_t bit; + do { + wire_status = read_bit(wire->driver, &bit); + if (wire_status != OW_OK) return wire_status; + } while(bit != 0); + + // read status + uint8_t status; + wire_status = owu_read_byte(wire, &status); + if (wire_status != OW_OK) return wire_status; + + // read status write + wire_status = owu_read_byte(wire, &status); + if (wire_status != OW_OK) return wire_status; + + return wire_status; +} + +int ds28e17_Write_Read_with_Stop(owu_struct_t *wire, uint8_t *OW_addr, uint8_t I2C_Addr) +{ + int wire_status; + + wire_status = owu_reset(wire); + + + return wire_status; +} + +uint16_t ds28e17_crc16(uint8_t* data, uint32_t len) +{ + // TO BE DONE; code is from CRC8 + uint16_t crc = 0; + + while (len--) { + uint8_t inbyte = *data++; + uint8_t i; + for (i = 8; i; i--) { + uint8_t mix = (crc ^ inbyte) & 0x01; + crc >>= 1; + + if (mix) crc ^= 0xA001; + inbyte >>= 1; + } + } + crc ^= 0xFFFF; + + return crc; +} \ No newline at end of file diff --git a/atmega32u4/CbmRich_sensoring/DS28E17/DS28E17.h b/atmega32u4/CbmRich_sensoring/DS28E17/DS28E17.h new file mode 100644 index 0000000..cd93a2c --- /dev/null +++ b/atmega32u4/CbmRich_sensoring/DS28E17/DS28E17.h @@ -0,0 +1,28 @@ +#ifndef INCLUDE_DS28E17_H_ +#define INCLUDE_DS28E17_H_ + +// Sensor type +#define TYPE_DS28E17 0x19 + + +#define CMD_WRwS 0x2D // Write Read data with Stop +#define CMD_WwS 0x4B // Write Read data with Stop8 + +#include <stdint.h> +#include "onewire.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +int ds28e17_Write_Read_with_Stop(owu_struct_t *wire, uint8_t *addr, uint8_t I2C_Addr); + +int ds28e17_Write_with_Stop(owu_struct_t *wire, uint8_t *addr, uint8_t I2C_Addr); + +uint16_t ds28e17_crc16(uint8_t*, uint32_t); + +#if defined(__cplusplus) +} +#endif + +#endif /* INCLUDE_DS28E17_H_ */ \ No newline at end of file diff --git a/atmega32u4/CbmRich_sensoring/Makefile b/atmega32u4/CbmRich_sensoring/Makefile index a4c30de..59ebbc2 100644 --- a/atmega32u4/CbmRich_sensoring/Makefile +++ b/atmega32u4/CbmRich_sensoring/Makefile @@ -8,7 +8,7 @@ MCU = atmega32u4 FORMAT = ihex TARGET = main -SRC = $(TARGET).c usb_serial.c lib/1wire/drivers/ow_driver_avr_gpio.c lib/1wire/dallas/dallas.c lib/1wire/onewire/onewire.c +SRC = $(TARGET).c usb_serial.c lib/1wire/drivers/ow_driver_avr_gpio.c lib/1wire/dallas/dallas.c lib/1wire/onewire/onewire.c DS28E17/DS28E17.c ASRC = OPT = 2 PORT=/dev/ttyACM0 @@ -33,7 +33,7 @@ CDEFS = -DF_CPU=8000000 # Place -I options here #CINCS = -CINCS = -I. -I./lib/1wire/dallas -I./lib/1wire/onewire -I./lib/1wire/drivers +CINCS = -I. -I./lib/1wire/dallas -I./lib/1wire/onewire -I./lib/1wire/drivers -I./DS28E17 CDEBUG = -g$(DEBUG) diff --git a/atmega32u4/CbmRich_sensoring/main.c b/atmega32u4/CbmRich_sensoring/main.c index 6bf7167..6172143 100644 --- a/atmega32u4/CbmRich_sensoring/main.c +++ b/atmega32u4/CbmRich_sensoring/main.c @@ -11,6 +11,7 @@ #include "ow_driver_avr_gpio.h" #include "onewire.h" #include "dallas.h" +#include "DS28E17.h" #include <stdio.h> @@ -21,8 +22,8 @@ //#define DEBUG_USB_OUT // BEGIN define 1-wire parameters -#define MAX_OW_DEV_COUNT_PER_PIN 17 -#define NUM_1W_PINS 9 +#define MAX_OW_DEV_COUNT_PER_PIN 10 +#define NUM_1W_PINS 3 typedef enum { DS18B20 = 0, @@ -48,6 +49,8 @@ uint8_t txbuf[22]; uint8_t tx_test_buf[100]; +uint8_t configMode = 0; + int search_devices(owu_struct_t []); int init_OW_measurements(owu_struct_t []); @@ -57,13 +60,24 @@ void send_Values(uint8_t line , uint8_t devNbr, uint8_t valType, uint16_t value) void getdata(uint8_t buf) { - -} + if (rxcnt != 0 || (buf == 'C')) { + rxbuf[rxcnt++] = buf; + } + if (buf == '\n' || buf == '\r') { + if (rxbuf[0] == 'C') { + // To be defined + sprintf((char*) txbuf, "Config Mode\n"); + UCSR1B |= (1<< UDRIE1); + } + } + + if (rxcnt >= 10 || buf == '\n' || buf == '\r') { rxcnt = 0; } +} ISR(USART1_RX_vect) { - //uint8_t buf = UDR1; - //getdata(buf); + uint8_t buf = UDR1; + getdata(buf); //usb_serial_putchar(buf); } @@ -160,13 +174,15 @@ int main(void) { init_OW_measurements(ow_Q); uint16_t lasttime = 0; + uint16_t lastMeasTime = 0; // here start first scan of all Temp devices that are found //TODO while(1) { // delay a measurement run by a specific time if (cur_meas_line == 0 && cur_meas_devNbr == 0){ cli(); // Deactivate Interrupt for solid calculation - if((time % 30) == 0 && (time != lasttime)) { + if (time-lastMeasTime > 30) { // a min. of 30 timer overflows until next measurement + lastMeasTime = time; sei(); OW_measurements(ow_Q); } @@ -256,6 +272,10 @@ int search_devices(owu_struct_t ow_Q[]){ } } + + //ds28e17_Write_with_Stop(&ow_Q[0], dev_addr[0][dev_count[0]],0x45); + + return 0; } @@ -360,16 +380,24 @@ void send_Address(uint8_t line , uint8_t devNbr, uint8_t I2C_add){ // xx: 48-bit UID // CC: I2C Address (maybe not needed) + // wait if previous UART transmission is not finished + while ( ((UCSR1B >> UDRIE1) & 0x1) == 1) + { + delay_us(5); // TO DO: change to ASM command + } + uint8_t nbytes = sprintf((char*) txbuf, "A%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",dev_addr[line][devNbr][0], dev_int_addr[line][devNbr], - dev_addr[cur_meas_line][cur_meas_devNbr][1], - dev_addr[cur_meas_line][cur_meas_devNbr][2], - dev_addr[cur_meas_line][cur_meas_devNbr][3], - dev_addr[cur_meas_line][cur_meas_devNbr][4], - dev_addr[cur_meas_line][cur_meas_devNbr][5], - dev_addr[cur_meas_line][cur_meas_devNbr][6], + dev_addr[line][devNbr][1], + dev_addr[line][devNbr][2], + dev_addr[line][devNbr][3], + dev_addr[line][devNbr][4], + dev_addr[line][devNbr][5], + dev_addr[line][devNbr][6], I2C_add); usb_serial_write(txbuf,nbytes); + + // Send via UART UCSR1B |= (1<< UDRIE1); } @@ -382,10 +410,18 @@ void send_Values(uint8_t line , uint8_t devNbr, uint8_t valType, uint16_t value) // T: char for data type (T,X,Y,Z) // VAL: value of measurement in hex + // wait if previous UART transmission is not finished + while ( ((UCSR1B >> UDRIE1) & 0x1) == 1) + { + delay_us(5); // TO DO: change to ASM command + } + uint8_t nbytes = sprintf((char*) txbuf, "V%02x%02x%c%x\n",dev_addr[line][devNbr][0], dev_int_addr[line][devNbr], (char) valType, value); usb_serial_write(txbuf,nbytes); + + // Transmit txbuf via UART UCSR1B |= (1<< UDRIE1); } \ No newline at end of file diff --git a/atmega32u4/CbmRich_sensoring/readout.pl b/atmega32u4/CbmRich_sensoring/readout.pl new file mode 100755 index 0000000..5bfbaac --- /dev/null +++ b/atmega32u4/CbmRich_sensoring/readout.pl @@ -0,0 +1,130 @@ +#!/usr/bin/perl +# if ($ENV{'SERVER_SOFTWARE'} =~ /HTTPi/i) { +# print "HTTP/1.0 200 OK\n"; +# print "Content-type: text/html\r\n\r\n"; +# } +# else { +# use lib '..'; +# print "Content-type: text/html\n\n"; +# } + +use strict; +use warnings; +use Device::SerialPort; +use IO::Socket; +use IO::Handle; +use Fcntl; + +use feature 'state'; +use URI::Escape; +use Data::Dumper; +use Time::HiRes qw( usleep); +use Getopt::Long; + +my $port; +my $help; +my $ser_dev; +my $isTrbNet = 0; +Getopt::Long::Configure(qw(gnu_getopt pass_through)); +GetOptions( + 'help|h' => \$help, + 'device|d=s' => \$ser_dev, + ) ; + +my $isEthernet = 0; +my $mode = 0; +my $ch; +my $uC; +my $reg; +my $rw; +my $val; +my $num = 0; +my $args = scalar @ARGV; + +# my $envstring = $ENV{'QUERY_STRING'}; +# +# +# my @new_command = split('&',$envstring); +# my $ser_dev = shift(@new_command); + +$ser_dev = "/dev/ttyUSB0" unless defined $ser_dev; + + + +if ($help || (defined $ARGV[0] && $ARGV[0] =~ /help/)) { + print "dcdc.pl [-d DEVICE] reg [uC [CHANNEL [OPERATION [REGISTER [VALUE]]]]]\n"; + print "dcdc.pl [-d DEVICE] CMD [uC [CHANNEL [VALUE]]]\n\n"; + print "DEVICE: Either a serial device or an IP number.\n"; + print "CMD: s: set DCDC setting, g: get DCDC setting,\n"; + print " t: temperature, v: input voltage, c: input current;\n"; + print "uC: number of Microcontrolle rin chain. As Hex or Dec\n"; + print "CHANNEL: Channel number, hex or decimal\n"; + print "OPERATION: R = Read; W = write\n"; + print "REGISTER: Register to access (dec or hex)\n"; + print "VALUE: A 16 Bit value, 4 hex digits or decimal\n"; + exit; +} + +if ($ser_dev =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) { + $isEthernet = 1; + $port = IO::Socket::INET->new(PeerAddr => $ser_dev, PeerPort => 2323, Proto => "tcp", Type => SOCK_STREAM, Timeout => 1) + or (print("Device not found") && return); + } +else { + $port = new Device::SerialPort($ser_dev); + unless ($port) { + print "can't open serial interface $ser_dev\n"; + exit; + } + $port->user_msg('ON'); + $port->baudrate(57600); + $port->parity("none"); + $port->databits(8); + $port->stopbits(1); + $port->handshake("none"); + $port->read_char_time(0); + $port->read_const_time(50); + $port->write_settings; + } + +sub Cmd { + my ($c) = @_; + $c .= "\n"; + if($isEthernet == 0) { + for my $i (0..0) { + $port->write($c); + my $a = ""; + for my $j (0..16) { + my ($l,$s) = $port->read(12); + $a .= $l; + if ($l < 1) {next;} + # if ($s =~ /^\w[a-f0-9]{0,11}/) { my $size = length $s; $s = substr($s,0,$size-1); return $s;} + usleep(10000); + } + usleep(50000); + #print '.'; + } + } + if($isEthernet == 1) { + print $port "$c"; + my $x = ""; + for my $i (0..10) { + $x .= <$port>; + if($x && ($x =~ /\n/ || $x =~ /\r/) ) { + chomp $x; + return $x; + } + usleep(1000); + } + } + return ; +} + +# microcontroller number in chain +if($args > 1) { + +} + +Cmd("C1"); +#print $cmd."C\n"; + # PrintAnswerNice(Cmd($cmd)) #Answer without \n