SPI problem myEthernet ATmega644p ENC28J60

OP #3024305
Hallo,

mein myEthernet greift (vorgegeben) mit USART1 in SPI Mode auf den ENC 
zu.
PIN D2=MISO=RX;
D3=MOSI=TX;
D4=SCK=XCK;
D5=invCS;

Initialisierung:

UBRR1=0;//Baud Register erst auf null setzten
SPI2_DDR |= (1<<4);//Clock Ausgang
SPI2_DDR &=~ (1<<SPI2_MISO); //MISO Eingang
SPI2_DDR |= (1<<SPI2_MOSI);//MOSI Ausgang
SPI2_DDR |= (1<<5);//CS Ausgang

UCSR1C = (1<<UMSEL11) | (1<<UMSEL10) | (0<<UCPHA1) | (0<<UCPOL1);//MSPI 
//Mode, SPI Mode 0
UCSR1B = (1<<RXEN1) | (1<<TXEN1);//enable Receiver and Transmitter
UBRR1 = 129;//Baudrate 9600
SPI_DISABLE(); //=CS high

//Es soll zur Probe ein Register aus dem ENC ausgelesen werden
//Nach Reset ist das ERXFCON Register 10100001
//Um den ENC zu lesen wird der OPcode und die Adresse des Registers an 
den ENC gesendet. Dieser antwortet (in diesem Fall) ohne Dummybyte 
direkt mit dem Inhalt des Registers.

SPI_ENABLE();//CS low
//  _delay_ms(1);
dummy=UDR1;//Transmit buffer leeren
while ( ! (UCSR1A & (1<<UDRE1)) );//Wait for empty transmit buffer
reg=(op | (addr & ENC28J60_ADDR_MASK));//RCR register
UDR1 =reg;//sends data; hier:00011000 =  Op code und adressse =read 
ERXFCON
while ( ! (UCSR1A & (1<<RXC1)) );//wait for data to be received
value=UDR1;
SPI_DISABLE();//CS wieder high

DDRA=0xff;//Port A (LEDs-Extern)=Ausgang;
PORTA=value; //Wert zur Kontrolle an die 8 LEDs ausgeben

Nun zum Problem:
Ich bekomme vom UDR1 Register immer nur 0x00 zurück und nicht den Wert, 
den ich von dem abgefragten Register erwarte.
Dass die Register richtig definiert sind und dass die Bits richtig 
gesetzt werden habe ich mit debugging überprüft.

Hat jemand Rat?

Gruß
Manni
Gast #3024754
>//Um den ENC zu lesen wird der OPcode und die Adresse des Registers an
>den ENC gesendet. Dieser antwortet (in diesem Fall) ohne Dummybyte
>direkt mit dem Inhalt des Registers.

Das halte ich für Blödsinn. Woher soll der ENC wissen
welches Register er lesen soll ohne vorher den Opcode
gesendet zu haben? Das wär ja so als könnte er eine
Antwort raten ohne die Frage zu kennen.

Schick das Dummybyte und lies dann noch mal.
OP #3024808
Habe Tx und Rx verbunden.
Damit konnte ich meine gesendete Adresse und opcode selbst empfangen.

@Holger: Der ENC sendet bei Abfragen des MAC Registers erst ein 
Dummybyte, gefolgt von dem Inhalt des MAC registers.
Bei dem abgefragten Ethernet-Register sollte aber sofort der Inhalt 
folgen.


Einen Fehler habe ich schon korrigiert:
Ich habe bisher versucht aus dem falschen Register zu lesen, da es sich 
um ein Bank1 Register handelt. Und nach einem Reset liest der ENC 
erstmal von Bank0.
Habe daraufhin versucht das ERDPTH-Register zu lesen.
das sollte nach Reset nicht null sein.

Ich lese aber immer nur 0x00 aus.

Muss ich den ENC noch zusätzlich irgendwie Initialisieren?
Software-Reset?


Gruß
Gast #3024826
>Bei dem abgefragten Ethernet-Register sollte aber sofort der Inhalt
>folgen.

Wo steht das im Datenblatt? Tut mir leid ich finde das nirgends.
Die Timingdiagramme sagen auch was anderes.
Gast #3024858
>Seite 27 ENC28J60 user guide:
>if the 5 bit address is an ETH Register, then the data in the selected
>register will start shifting out immediately.

Ja, aber erst wenn der Opcode komplett übertragen wurde.
Das rausshiften musst du mit dem senden eines Dummybytes machen.
Sonst werden keine Clock Impulse für das SPI generiert.

Aber was rede ich, du willst ja nicht.
Dein Problem hätte vor 10 Minuten gelöst sein können.
OP #3024896
Ich dachte ich habs verstanden.
Hab den Code abgeändert:

SPI_ENABLE();//CS low
_delay_ms(1);
dummy=UDR1;//Transmit buffer leeren
while ( ! (UCSR1A & (1<<UDRE1)) );//Wait for empty transmit buffer
reg=(op | (addr & ENC28J60_ADDR_MASK));//RCR register
UDR1 =reg;//sends data from transmit buffer to ENC: opcode und adress

UDR1=dummy;//sendet weiterhin clock
//gleichzeitig wird das Register vom ENC gelesen


 while ( ! (UCSR1A & (1<<RXC1)) );//wait for data to be received (from 
ENC)
value=UDR1;

 SPI_DISABLE();//CS wieder high

value liest aber immer nur null aus;


Sollte der code so in Ordnung sein?
OP #3024917
Habe jetzt vor dem Dummybyte den transmitbuffer geleert:



dummy=UDR1;//Transmit buffer leeren
while ( ! (UCSR1A & (1<<UDRE1)) );//Wait for empty transmit buffer
UDR1=dummy;//sendet weiterhin clock
//gleichzeitig wird das Register vom ENC gelesen

usw..

Funktioniert aber immer noch nicht.
OP #3024955
SPI_ENABLE();//CS low
_delay_ms(1);
dummy=UDR1;//Transmit buffer leeren
while ( ! (UCSR1A & (1<<UDRE1)) );//Wait for empty transmit buffer
reg=(op | (addr & ENC28J60_ADDR_MASK));//RCR register
UDR1 =reg;//sends data from transmit buffer: opcode und adress
while ( ! (UCSR1A & (1<<RXC1)) );//wait for data to be received (from 
ENC)
 value=UDR1;

//dummybyte senden damit clock weiterläuft
dummy=UDR1;//Transmit buffer leeren
while ( ! (UCSR1A & (1<<UDRE1)) );//Wait for empty transmit buffer
UDR1=dummy;//sendet weiterhin clock
//gleichzeitig wird das Register vom ENC gelesen
while ( ! (UCSR1A & (1<<RXC1)) );//wait for data to be received (from 
ENC)
value=UDR1;


// jetzt wird adresssiertes register ausgelesen
dummy=UDR1;//Transmit buffer leeren
while ( ! (UCSR1A & (1<<UDRE1)) );//Wait for empty transmit buffer
UDR1=dummy;//sendet weiterhin clock
//gleichzeitig wird das Register vom ENC gelesen
while ( ! (UCSR1A & (1<<RXC1)) );//wait for data to be received (from 
ENC)
value=UDR1;
SPI_DISABLE();//CS wieder high


Es hat geklappt.
Ich konnte erfolgreich ein Register (ECON2) auslesen.

Ich danke euch.
#3024965
holger schrieb:
> Wenn du in UDR1 schreibst musst du warten bis die Daten raus sind.
> Du kannst da nicht einfach kurz nacheinander reinschreiben.

Doch, das geht. UDR1 ist doppelt gepuffert. Ein 16-Bit Transfer kann 
durchgeführt werden, indem 2 Bytes direkt hintereinander in UDR1 
geschrieben werden.

Aber:
Um zu prüfen, ob die Datenübertragung abgeschlossen wurde, darf dann 
nicht das RXC1-Bit (Receive complete) abgefragt werden (dieses wird 
schon nach dem ersten empfangenen Byte gesetzt). Es muss das TXC1-Bit 
(Transmit Complete) im UCSR1A-Register abgefragt werden. Dieses wird 
nämlich erst dann gesetzt, wenn beide Bytes übertragen wurden.

Aber Manfred hat es ja jetzt mit zwei hintereinander ausgeführten 1-Byte 
Transfers hinbekommen.
Gast #3024993
>> Wenn du in UDR1 schreibst musst du warten bis die Daten raus sind.
>> Du kannst da nicht einfach kurz nacheinander reinschreiben.

>Doch, das geht. UDR1 ist doppelt gepuffert. Ein 16-Bit Transfer kann
>durchgeführt werden, indem 2 Bytes direkt hintereinander in UDR1
>geschrieben werden.

Ja, da hast du recht. Das Problem ist nur ob man sicher stellen
kann das nicht vorher schon mal jemand in UDR1 geschrieben hat.
Wenn nicht muss UDRE1 abgefragt werden.

Ansonsten ist SPI über UART wegen des Double Buffers sogar schneller
als das reine SPI Modul. Man muss halt aufpassen was man tut;)
#3025015
holger schrieb:
> Ja, da hast du recht. Das Problem ist nur ob man sicher stellen
> kann das nicht vorher schon mal jemand in UDR1 geschrieben hat.
> Wenn nicht muss UDRE1 abgefragt werden.

UDRE1 sollte vor jedem Transfer abgefragt werden, egal ob 8 oder 16 Bit 
zu übertragen sind.

> Ansonsten ist SPI über UART wegen des Double Buffers sogar schneller
> als das reine SPI Modul.

Ein weiterer Vorteil ist, dass die Clockfrequenz viel feiner einstellbar 
ist.
Gast #3061123
ich vor einiger Zeit recht bereistegt die Buchreihe von Suzanne Collins 
gelesen hatte, war ich sehr gespannt auf den ersten Film der Serie. Ich 
hatte zwar beffcrchtet das

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.