Software 1-Wire AVR: Frage zur Checksummenberechnung

Begonnen von ritchie, 09 März 2014, 13:24:02

Vorheriges Thema - Nächstes Thema

ritchie

Hallo Zusammen,

ich bin derzeit an der Simulation eines DS2408 mittels attiny44a am Arbeiten und suche derzeit den Fehler in meiner Checksumme und finde ihn nicht.

Hier der Code der Teilcode, welcher bearbeitet wird, wenn das Control-Kommando "0xf0" in Arbeit ist.
Zitat
               RESET_LOW;                                 // Set low the line
               if ((lscrc&1)!=p)
                  lscrc=(lscrc>>1)^0xA001;                  // calculate the crc
               else
                  lscrc >>=1;

               lbitp=(lbitp<<1);                           // shift the next bit
               if (!lbitp)                                 // do we have shift already all
                  {
                  lbytep++;                              // send the next byte
                  lbitp=1;                              // reset the bit counter
                  if (lbytep> 0 && lbytep <= 5)               // check. if we reached the control reg. area
                     {
                     ow_iobuffer[0]   = Register_state[lbytep];   // get the requested Data
                     }
                  else
                     {
                     if (lbytep > 8 )                        // Did we reached the end of the registers (did not send unused data
                        {
                        lscrc = ~lscrc;                     // inverted Checksum   
                        ow_iobuffer[1] = (lscrc & 0xff);
                        ow_iobuffer[0] = (lscrc & 0xff00) >> 8; // get the upper value of the check sum
                        ow_iobuffer[2] = 0xff;
                        ow_size_answer=3;
                        lbytep=0;                        // Reset transmit pointer                        
                        lactbit=(lbitp&ow_iobuffer[0])==lbitp;   // get the actual bit to send from scratch buffer
                        lwmode=lactbit;                     // this is the actual bit to send
                        lmode=OWM_ANSWER_CHECKSUM_DS2408;      // we are finished,  Send the checksum
                        break;                           // Stop communication here
                        }
                     else
                        {
                        ow_iobuffer[0]   = 0xff;               // invalid data
                        }   
                     }
                  }
               lactbit=(lbitp & ow_iobuffer[0])==lbitp;      // get the actual bit to send from scratch buffer
               lwmode=lactbit;                              // this is the actual bit to send
               break;


Der Code basiert grundsätzlich auf dem Code von Tobias Mueller, wurde aber deutlich geändert. Nur die Vorgehensweise einer Statemachine habe ich weiter ausgeführt.

Kann mir jemand hier helfen. Derzeit bekomme ich noch keine Daten im Webinterface angezeigt, da ich hier jede Menge CRC Fehler habe.

Gruss R.
IPU662  Ipfire & Fhem (Homematic + MAX) - Produktiv
Cubietruck (1Wire - USB) - Produktiv

Prof. Dr. Peter Henning

Es gibt im Code weiter oben einen Bereich , indem das Kommando 0xF0 abgefragt wird - so wie im folgenden Beispiel das 0xA5.
Da wird der CRC initialisiert:


        //READ_MEMORY_COUNTER COMMAND
case 0xA5:
lmode=OWM_GET_ADRESS; 
lbytep=0;
lscrc=0x7bc0; //CRC16 of 0xA5
counterpack.bytes[0]=0;
break;


Ist das korrekt gemacht worden ?

LG

pah

P.S.: Wieso den DS2408 emulieren ? Den gibt es doch für wenig Geld zu kaufen.

ritchie

Hallo Pah,

ich denke mal, das hier das Kommando 0xF0 (SEARCH_ROM) gemein ist.

Der Chip  DS2408 hat aber noch ein Kontroll-Kommando, womit die Register ausgelesen werden können. Hier habe ich die CRC16 mit 0 vorbelegt, da zu diesem Zeitpunkt keine der Daten bekannt sind (im Gegensatz zur Addressübermittlung).

Mein Aufruf der Teilroutine sieht so aus:

case OW_READ_PIO_REGISTERS:
lscrc=0; // init the check sum of the data to transmit
lmode=OWM_READ_DS2408_PIO_REGISTERS;
lbytep=ow_iobuffer[1] - 0x88; // load the start register from where data request
if(lbytep >= 0 && lbytep<= 5 ) // is it a valid control register area
{
ow_iobuffer[0]=Register_state[lbytep]; // get the requested Data
}
else
{
lbytep = 0x0; // Send the complete buffer
ow_iobuffer[0]=Register_state[lbytep]; // get the requested Data
}
lactbit=(lbitp&ow_iobuffer[0])==lbitp; // get the actual bit to send from scratch buffer
lwmode=lactbit; // this is the actual bit to send
if ((lscrc&1)!=lactbit) // do the check sum for the last byte
{
lscrc=(lscrc>>1)^0xA001; //
}
else
{
lscrc >>=1; // bit shifting
}
break;


Ich habe die Checksumme (Deine Vermutung), nur von den Daten, welche ich zurücksende ermittelt.
Laut Datenblatt Flowchart Seite 13, steht hier aber "CRC16 of Command, Adresses and Databytes." Das habe ich wohl überlesen.

Da würde dann wohl in meinem Fall 0xF0, 0x88, 0x00 hinzukommen.

Generell gebe ich Dir recht, das der DS2408 eigentlich sehr preiswert ist, jedoch kann ich hier keine "autonomen" Funktionen hinterlegen.

Beispiel: Ich lasse Lüfter und Pumpen gesteuert durch FHEM/OWServer laufen, sollte FHEM ausfallen, würde der anstehende Status (Ein-Befehl), bis zum Neustart von FHEM anstehen. Einen Watchdog kann ich so nicht erreichen.

Der Emulator kann aber feststellen, ob die Abfrage noch weiterhin arbeitet und wenn nicht, die Ausgänge ausschalten. Ebenso kann ich eine gewisse Eigenintelligenz (Schreibbefehl erkannt) in die Module einbauen. Derzeit habe ich auch 3 DS2408 im Einsatz, jedoch ohne Eigenkontrolle.

Gruss R.




IPU662  Ipfire & Fhem (Homematic + MAX) - Produktiv
Cubietruck (1Wire - USB) - Produktiv