Forum: FPGA, VHDL & Co. 1-wire EEPROM read/write funktioniert nicht


von Jones S. (defcon3)


Lesenswert?

Hallo Zusammen,

ich habe ein Problem mit dem 1wire-Baustein DS2431 (1kB EEPROM): Ich 
kann zwar die ID auslesen, jeder Zugriff auf das EEPROM funktioniert 
aber leider nicht.

Was ich nirgends finden konnte ist der Unterschied, wie ich ein "Memory 
Function Command" (write/read scratchpad etc.) bzw. wie ich ein "ROM 
Function Command" ausführe. Es gibt hierbei gleiche Kommando-(HEX)-Werte 
für unterschiedliche Befehle. Die müssen doch sicherlich unterschiedlich 
übermittelt werden.

Ich nutze den VHLD-Satz "ds1wm" von Dallas/Maxim für die low-level 
Funktionen im FPGA. Darüber läuft ein IP-Core, in dem C-code nach VHDL 
compiliert wird. Die darin laufende Statemachine ist im folgenden 
gezeigt. Ich sehe lediglich, dass der Code bis zur Zuweisung 
"u4state_out = 7;" im ersten State ausgeführt wird. Danach ist alles 
tot... --> Hier sollte eigentlich die CRC 16 bit vom Baustein übertragen 
werden, die Leitung bleibt aber tot...

Wie gesagt, die ID kann ich hiermit gut auslesen. Auch das Auswerten von 
Temperaturen (DS1825 funktioniert im code gut).

Findet einer den Fehler oder kann sonst irgendwie helfen?

Danke

1
case(STATE_WRITE_EPROM):
2
                u4state_out = 3;
3
                __wait(GLOBAL_WAIT);
4
                //write command followed by two address and one data byte
5
                OWWriteByte(DS2431_CMD_WRITE_SCRATCHPAD);
6
                u4state_out = 4;
7
                OWWriteByte(0x00);//((uint8_t)(u16MemoryAddr&0xFF));
8
                OWWriteByte(0x00);//((uint8_t)((u16MemoryAddr&0xFF00)>>8));     //0x00*/
9
                u4state_out = 6;
10
                for(i=0;i<8;i++)
11
                {
12
                    OWWriteByte(u8MemoryData);    //must send 8 Bytes here
13
                }
14
                //receive 16bit-CRC
15
                u4state_out = 7;
16
                u16InternalCRC = (uint16_t)(OWReadByte());
17
                u16InternalCRC += (uint16_t)(OWReadByte()<<8);
18
                //ToDO: calculate and compare CRC16
19
                //..
20
                u16Debug = u16InternalCRC; // output
21
                //
22
                u8Debug = OWReadByte(); // should read 1s only*/
23
                bReadBackOK = true;
24
                EnterState(STATE_ONE_WIRE_INIT);
25
                //EnterState(STATE_KILL);
26
            break;
27
28
            case(STATE_READ_EPROM_SCRATCHPAD):
29
                u4state_out = 8;
30
                bReadBackOK = false;
31
                //send readScratchpad command and read back Address and E/S
32
                OWWriteByte(DS2431_CMD_READ_SCRATCHPAD);    //AA
33
                u16AddressReadback = (uint16_t)(OWReadByte());
34
                //__wait(GLOBAL_WAIT);
35
                u16AddressReadback += (uint16_t)((OWReadByte())<<8);
36
                u8InternalE_S = OWReadByte();
37
                //__wait(GLOBAL_WAIT);
38
                for(i=0;i<8;i++)
39
                {
40
                    u4state_out = 9;
41
                    u8Debug = OWReadByte();
42
                    __wait(GLOBAL_WAIT);
43
                }
44
                u16InternalCRC = (uint16_t)(OWReadByte());
45
                //__wait(GLOBAL_WAIT);
46
                u16InternalCRC += (uint16_t)(OWReadByte()<<8);
47
                //__wait(GLOBAL_WAIT);
48
                bReadBackOK = true;
49
                u8Debug = OWReadByte(); //should be all 1s
50
                //EnterState(STATE_KILL);
51
                EnterState(STATE_ONE_WIRE_INIT);
52
            break;
53
54
            case(STATE_PROGRAM_EPROM):
55
                u4state_out = 10;
56
                bReadBackOK = false;
57
                OWWriteByte(DS2431_CMD_COPY_SCRATCHPAD);  //55
58
                //send address and E/S
59
                OWWriteByte(0x00);//(uint8_t)(u16MemoryAddr&0xFF));
60
                OWWriteByte(0x00);
61
                OWWriteByte(u8InternalE_S);
62
                //send 10ms programming pulse (Idle High)
63
                u4state_out = 11;
64
                __wait(PROGRAMMING_WAIT);
65
                //read copy Status --> AA = success
66
                u4state_out = 12;
67
                u8Debug = OWReadByte();
68
                bReadBackOK = true;
69
                EnterState(STATE_ONE_WIRE_INIT);
70
            break;
71
72
            case(STATE_READ_MEMORY):
73
                u4state_out = 13;
74
                bReadBackOK = false;
75
                OWWriteByte(DS2431_CMD_READ_MEMORY);
76
                //start at Offset 00
77
                OWWriteByte(0x00);
78
                OWWriteByte(0x00);
79
                __wait(GLOBAL_WAIT);
80
                u4state_out = 14;
81
                //read out 144 DataBytes  --> really??
82
                for(j=0;j<8;j++)
83
                {
84
                    u8Debug = OWReadByte();
85
                }
86
                bReadBackOK = true;
87
                EnterState(STATE_KILL);
88
            break;

: Bearbeitet durch User
von Duke Scarring (Gast)


Lesenswert?

Jones S. schrieb:
> Es gibt hierbei gleiche Kommando-(HEX)-Werte
> für unterschiedliche Befehle. Die müssen doch sicherlich unterschiedlich
> übermittelt werden.
Welche Kommando (HEX) verwendest zu konkret?

> Ich nutze den VHLD-Satz "ds1wm" von Dallas/Maxim für die low-level
> Funktionen im FPGA. Darüber läuft ein IP-Core, in dem C-code nach VHDL
> compiliert wird. Die darin laufende Statemachine ist im folgenden
> gezeigt. Ich sehe lediglich, dass der Code bis zur Zuweisung
> "u4state_out = 7;" im ersten State ausgeführt wird. Danach ist alles
> tot...
Die 8 Byte (schreiben) werden noch übertragen, aber der 16-Bit CRC wird 
nicht mehr gelesen?
Da würde ich ein Problem in der Funktion OWReadByte vermuten.
Normalerweise sollten die 16 Bit ja auch der Leitung zu sehen sein.

Duke

von Jones S. (defcon3)


Lesenswert?

Duke Scarring schrieb:

> Welche Kommando (HEX) verwendest zu konkret?

So wie im Datenblatt, da ist auf der letzten Seite eine ganze Abfolge 
eines Schreibvorgangs. Bis zum Abbruch ist es aber nur der Befehl 0xCC 
(MatchRom) gefolgt von 0x0F (Write Scratchpad). Dann bricht es ja schon 
ab.

Was ich meinte, ist z. B. das Kommando 0xF0, das kann einerseits 
"ReadMemory" und andererseits "SearchRom" bedeuten. Also Memory bzw. ROM 
command. Wie muss ich die jeweils übergeben?

> Die 8 Byte (schreiben) werden noch übertragen, aber der 16-Bit CRC wird
> nicht mehr gelesen?
> Da würde ich ein Problem in der Funktion OWReadByte vermuten.
> Normalerweise sollten die 16 Bit ja auch der Leitung zu sehen sein.

Die Funktion OWReadByte muss aber funktionieren, da ich mit ebendieser 
Funktion die Device-ID sowie von einem anderen Baustein die Temperatur 
auslesen kann. Ich kann sie sogar so manipulieren, dass ich nur einzelne 
Bits auslese... (im SearchRom Algorithmus...)

Ich stehe ansonsten auch gerade mit einem Mitarbeiter von Maxim in 
Kontakt, der auch meinte, die Statemachine sei soweit korrekt. Weiter 
konnte er mir bislang nicht helfen. (Blöd ist die Zeitverschiebung nach 
Amiland. Wir können jeder genau eine Nachricht am Tag schicken... dauert 
echt lang :-(

Hat jemand schon mal einen EEPROM Baustein programmiert?

von Duke Scarring (Gast)


Lesenswert?

Jones S. schrieb:
> Bis zum Abbruch ist es aber nur der Befehl 0xCC
> (MatchRom) gefolgt von 0x0F (Write Scratchpad). Dann bricht es ja schon
> ab.
Bei mir ist 0xCC als SKIP_ROM definiert.
MATCH_ROM wäre die 0x55.

Jones S. schrieb:
> Was ich meinte, ist z. B. das Kommando 0xF0, das kann einerseits
> "ReadMemory" und andererseits "SearchRom" bedeuten. Also Memory bzw. ROM
> command.
Ist mir noch gar nicht aufgefallen, aber stimmt.

> Wie muss ich die jeweils übergeben?
SEARCH_ROM (0xF0) verwende ich nur beim Busscan (array füllen, mit allen 
Busteilnehmern).

MATCH_ROM (+8 Byte ID) wird erst genommen, wenn der Busscan erfolgreich 
war und das richtige Device gefunden wurde.

Duke

von Jones S. (defcon3)


Lesenswert?

Duke Scarring schrieb:
> Bei mir ist 0xCC als SKIP_ROM definiert.
> MATCH_ROM wäre die 0x55.
>
oh, klar, mein Fehler. Ich meinte natürlich SkipRom, das ist ja auch der 
richtige Befehl für diese Stelle. Passt also...


>> Wie muss ich die jeweils übergeben?
> SEARCH_ROM (0xF0) verwende ich nur beim Busscan (array füllen, mit allen
> Busteilnehmern).
>
> MATCH_ROM (+8 Byte ID) wird erst genommen, wenn der Busscan erfolgreich
> war und das richtige Device gefunden wurde.

klar, wie gesagt, hab nur die falsche Kommandobezeichnung 
hingeschrieben. MatchRom verwende ich hier garnicht.

Ich schaue mal in der allgemeinen Beschreibung zum 1-wire. Vielleicht 
ist da was zu finden.

Denn z. B. Resets über das Kommandoregister sind auch nie in den 
bauteilspezifischen Datenblättern beschrieben sondern nur in der 
allgemeinen Beschreibung.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.