Forum: Mikrocontroller und Digitale Elektronik M16C29 und ENC28J60 via SPI


von Christian (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich versuche an einen Renesas M16C29 den Microchip enc28j60 
anzuschliessen. Leider gelingt mir das nicht. Mittlerweile habe ich 
alles ausprobiert, was mir eingefallen ist und es läuft noch immer 
nicht. Ich schreib jetzt mal, was ich gemacht habe bzw wie ich es 
verstanden habe und vielleicht findet ja jemand, der etwas Erfahrung mit 
dem enc28j60 oder/und M16C hat, meinen Fehler.

Die Kommunikation erfolgt via SPI, das Hardware SPI des M16C habe ich 
zuerst versucht zu konfigurieren, mit mehr oder weniger Erfolg. Um es 
besser verstehen zu können habe ich dann eine Software SPI auf denselben 
Ports geschrieben. Ich habe das so aus dem Microchip-Manual verstanden, 
dass der M16C Daten auf der steigenden Flanke sendet und der enc28j60 
auf der sinkenden Flanke Daten zurücksendet. Ausserdem muss das 
Clocksignal bei Idle auf Low-Pegel sein. Die Selectleitung ist bei 
Nichtbenutzung auf High, bei Benutzung wird der enc28j60 via Low 
ausgewählt.

Mein Problem ist, dass mir der enc28j60 nicht mit erwarteten Werten 
antwortet, als Beispiel versuche ich das ESTAT-Register zu lesen, das 
LSB soll dort auf 1 gesetzt werden, wenn der Oszillator sich 
eingeschwungen hat. (ESTAT.CLKRDY) Im Anhang ist das auf dem 
Logikanalyser zu sehen. Der Ausschnitt wurde einige Zeit nach Anschalten 
gemacht, das Bit sollte also 1 sein. Der enc28j60 liefert aber 0x02, das 
sehe ich im Logikanalyser als auch im M16C.

Ich möchte den AVR-Lib Treiber für den enc28j60 benutzen, darauf möchte 
ich uIP bauen. Zur Entwicklung benutze ich den IAR Embedded Workshop in 
der kostenlosen Variante (< 16k). Zum Flashen wird der E8-Debugger von 
Renesas benutzt.

ciao
Christian

Hier noch der Quelltext meiner Software SPI (falls notwendig):
(Das Cableselect Signal wird in einer anderen, höheren Funktion gesetzt, 
ich hoffe die Makros sind selbsterklärend.)

void tx( unsigned char value ) {
  unsigned char bits;

  __disable_interrupt();
  for (bits = 8; bits > 0; bits--)
  {
    if (value & 0x80) {
       SPI_TX_ON;
    } else {
      SPI_TX_OFF;
    }
    value <<= 1;

    SPI_CLK_OFF;      // rising edge
    SPI_CLK_ON;
  }
  SPI_CLK_OFF;
  __enable_interrupt();
}


unsigned char rx(unsigned char extradummy) {
  unsigned char bits;
  unsigned char value = 0x00;

  __disable_interrupt();
  SPI_TX_OFF;       // dummy 0x00

  // send dummy byte
  if(extradummy) {
    for (bits = 8; bits > 0; bits--)
    {
        SPI_CLK_ON;
        SPI_CLK_OFF;
    }
  }
  // end dummy byte

  for (bits = 8; bits > 0; bits--)
  {
    SPI_CLK_ON;     // falling edge
    SPI_CLK_OFF;

    value <<= 1;

    if(SPI_RX_VAL) {
      value |= 0x01;
    }

  }
  SPI_CLK_OFF;
  __enable_interrupt();

  return value;
}

von Christian (Gast)


Lesenswert?

Vielleicht noch etwas zu der Hardware.
Ich benutze das Renesas Starterkit RSKM16C29, den Enc28j60 benutze ich 
auf der Olimex-Platine http://www.olimex.com/dev/enc28j60-h.html. Ich 
betreibe beide Controller mit 3.3V, die Ports sind direkt verbunden, 
keine Pegelwandler.
Am M16C29 (80 PIN Variante) sind es die Pins 25 CLK, 26 RX, 27 TX, 23 
CS. Interrupts werden keine benutzt.

von Christian (Gast)


Lesenswert?

Ich habe inzwischen rausgefunden, dass mein Clocksignal so nicht richtig 
war, mit "high" bei Nichtbenutzung hat es besser funktioniert.
Ausserdem weiss ich jetzt, dass ich die älteste Silicon-Version habe 
Refid=2, die soll unter 8MHz SPI-Takt nicht zuverlässig funktionieren.
Da auch das Manual nicht richtig eindeutig ist, gebe ich auf.

von Sascha (Gast)


Lesenswert?

Hi,

ich hab es mit einem M16C28 versucht. Habe den Code von Nick Bambig 
umgeschrieben. Bei mir hat sich beim Ping Test nach 20 mal das Prg. 
aufgehängt. Meines erachtens liegt es am SPI des M16C.

Mfg Sascha.

PS Das gleiche hat mit einem ATmega644 sofort funktioniert

von Judge (Gast)


Lesenswert?

Hallo,

bei mir läuft das Hardware-SPI einwandfrei (M32C/83). Die Einstellungen 
sind folgendermaßen:

u2brg =  0x00  (halber Prozessortakt)
u2mr  =   0x01
u2c0  =  0x90
u2c1  =  0x05
u2smr =  0x00
u2smr2=  0x00
u2smr3=  0x02
u2smr4=  0x00

So müsste das auf dem M16C/29 auch funktionieren. Andernfalls ist bei 
den Pin-Einstellungen oder in den Übertragungsroutinen irgendwo ein 
Fehler.
Ich würde aber mal darauf tippen das Du das CKPH-Bit (u2smr3) übersehen 
hast. Dies ist in "Special Mode 2" beschrieben. Wenn es nicht gesetzt 
ist passt das Clock-Signal nicht.

Ich verwende ebenfalls eine alte Version des ENC28J60. Die Übertragung 
hat ab 500 kHz dennoch einwandfrei funktioniert.

Nicht aufgeben!

Gruß
Judge

von Michi (Gast)


Lesenswert?

Geht den auch der R8C 1B mit SPI MOde 0???

von Christian (Gast)


Lesenswert?

So geht es bei mir gar nicht!
Bei halbem Takt (10MHz) funktioniert der M16C nicht mehr, er macht dann 
extra Bytes dazwischen. Vermutlich Wartebytes oder so. Nur unterhalb von 
1 MHz geht das.

u2brg =  0x00  (halber Prozessortakt)
u2mr  =  0x01
u2c0  =  0x90
u2c1  =  0x05
u2smr =  0x00
u2smr2=  0x00
u2smr3=  0x02
u2smr4=  0x00


Die Einstellungen hatte ich auch so, hat aber nicht hingehauen (eben 
nochmal getestet). Es scheint so, als wären die Bytes um eine Stelle 
verschoben, anstatt bei ESTAT 0x01 zubekommen sehe ich 0x02 zB. Das 
hatte ich via Software-SPI versucht zu lösen, das Clocksignal auf High 
zwischen den Bytes. das hatte etwas besser funktioniert, zumindest ESTAT 
und EREVID (die Silicon-ID) sahen danach ok aus.

Judge, welchen Treiber benutzt Du? Ich glaube auch, dass das, was ich 
gemacht habe, ewt nicht so gut ist. Ich habe den AVR-Treiber der AVR-LIB 
portiert.

von Christian (Gast)


Angehängte Dateien:

Lesenswert?

So, ich habe wieder den halben Tag rumprobiert und gesucht. Kein 
Fortschritt.
Ich habe die Initialisierung etwas verändert, sie ist jetzt quasi gleich 
der von Microchip.

Problem ist zB die MAC-Adresse, die ich nicht setzen kann. Ich bekomme 
immer an der Adresse MAADR0 den Wert zurück, den ich an einer der 
Mac-Adressen (MAADR0 - MAADR5) zuletzt geschrieben habe. Die übrigen 
Werte sind immer 0x00.

Ich hänge mal den Treiber von mir an, vielleicht interessiert sich ja 
jemand dafür. Vielleicht sieht jemand sogar ein Problem.

von Judge (Gast)


Angehängte Dateien:

Lesenswert?

Ja, das Problem wird sein das gewartet werden muss bis die Daten die 
gesendet werden sollen im Übertragungsregister angekommen sind 
(ti-flag). Anders hat es bei mir bisher jedenfalls nicht funktioniert.
Ich war mal so frei und habe Deine Übertragungsroutinen dahingehend ein 
klein wenig abgeändert. So sollte das Hardware-SPI auf jeden Fall 
korrekt funktionieren.

Als Treiber habe ich übrigens auch die AVR-Lib portiert. Bisher gabs 
damit keine Probleme.
Deinen Treiber habe ich mir jetzt nicht angeschaut da ich denke das das 
Problem bei der Kommunikation liegt.

von Judge (Gast)


Lesenswert?

So, jetzt habe ich auch noch einen Blick auf den Treiber und die 
Initialisierung geworfen. Die sind so in Ordnung.

Es handelt sich bei Dir also definitiv um ein Kommunikationsproblem. 
Laut Datenblatt des ENC28J60 müssen die Daten übrigens bei steigender 
Flanke eingelesen werden, und das Clock-Signal sollte zwischen den 
Übertragungen Low-Pegel haben.
Diese beiden Fehler solltest Du in der Software-SPI noch beheben. 
Hardware-SPI hatte ich ja oben schon beschrieben.

von Christian (Gast)


Angehängte Dateien:

Lesenswert?

Super, ich bin jetzt weiter als je zuvor. Ich musste zu Deiner Version 
noch eine Zeile hinzufuegen damit es läuft. (while(READ_U2C0_TXEPT == 
U2C0_TXEPT_FULL);) Beim TX muss man noch auf U2C0.TXEPT warten, sonst 
gerät es aus dem Takt. (das CS ist schon oben bevor beide Bytes über die 
Leitung gingen)
Das mit der MAC geht jetzt, viel mehr kann ich noch nicht sagen. Das 
muss ich mir jetzt erstmal genauer ansehen.
Ich habe das noch mit dem Extradummy eingebaut, siehe Anhang.

Vielen vielen Dank schonmal.

Trotzdem sehe ich den grossen Unterschied zu meiner Version gar nicht...

von Judge (Gast)


Lesenswert?

Oh, sorry. Das txept-Flag hatte ich vergessen einzufügen. Klar das das 
Programm dann schon ein Stück weiter ist, insbesondere bei langsamen 
SPI-Takt.
Beim Empfangen kannst Du Dir die Abfrage von txept aber sparen, da ri 
(fast) zeitgleich gesetzt wird.

Der einzige Unterschied ist der das Du jetzt direkt nach dem Schreiben 
ins Transmit-Register wartest bis die Daten dort angekommen sind 
(ti-Flag). Sonst war die Programmabfolge schon richtig.

Funktioniert die Kommunikation jetzt auch bei höherer 
Übertragungsgeschwindigkeit fehlerfrei?

von Christian (Gast)


Lesenswert?

Bei der Kommunikation komme ich nicht über 1 MHz hinaus, sonst schickt 
der M16C nur noch Murks. Das ist weiterhin so. Ich werde aber mal einen 
anderen M16C29 testen, vielleicht macht der das besser.

Das txept werd ich noch wegmachen, hatte ich mir schon gedacht.

Danke nochmal, vielleicht schaffe ich es auch bald etwas IP-artiges 
drüberzubauen...

von Thorsten (Gast)


Lesenswert?

Habe gerade ein ähnliches Problem, die SPI-Kommunikation zw. einem 
ATmega128 und dem ENC28J60 funktioniert nur bis 1MHz einwandfrei. Ich 
habe testweise mal  folgende MAC-Adresse programmiert:

MAADR1 = 0x01
MAADR2 = 0x02
MAADR3 = 0x03
MAADR4 = 0x04
MAADR5 = 0x05
MAADR6 = 0x06

Beim Auslesen der 6 Register erhalte ich bei niedrigen SPI-Frequenzen 
wie erwartet

0x06-0x05-0x04-0x03-0x02-0x01

Bei höheren Frequenzen erhalte ich jedoch

0x01-0x06-0x05-0x04-0x03-0x02

Mein ENC ist übrigend die Version 5. Hast du bereits eine Lösung für 
dein Problem gefunden?

Gruß
Thorsten

von Judge (Gast)


Lesenswert?

Viele Möglichkeiten kommen da eigentlich nicht mehr in Frage. Beim M16C 
läuft es mit den o.g. Einstellungen jedenfalls einwandfrei. Kommen die 
Daten denn tatsächlich falsch raus oder werden sie nur falsch gelesen? 
Sind die Pull-Up Widerstände ausreichend dimensioniert?

von Thorsten (Gast)


Lesenswert?

Sch..., wenn man blöd ist :)

Die MAADRx-Register gehören zur MAC-Einheit und folglich umfaßt ein 
vollständiger Schreibzyklus 16 Bit ein Lesezyklus hingegen 24 Bit. Das 
habe ich nicht beachtet, und jeweils nur 16 Bit eingelesen. Dadurch läßt 
sich das o. g. Phänomen vollständig erklären. Datenblatt sorgfältig 
lesen ist also nie verkehrt :)

Trotzdem beruhigend. Ich hatte schon Angst, dass mit den Pegeln und dem 
Layout was nicht stimmt.

von Christian (Gast)


Lesenswert?

Ich habe festgestellt, dass mein enc28j60 relativ häufig Ethernetpakete 
zerstört. Grover Schätzung nach sind 1% kaputt, man sieht dann z.B. eine 
Byteverschiebung irgendwo in der Mitte.
Ich habe ja nun die fehlerhafte Rev 2, die ich mit ca 900 kHz betreibe. 
Thorsten, läuft Deine Ref 5 vielleicht besser?

An sich ist das kein Problem, um die kaputten Frames müsste sich dann 
das IP kümmern.

von Christian (Gast)


Lesenswert?

Also ...
Mein enc28j60 funktioniert wirklich schlecht!
Ich habe jetzt einen kleinen IP-Stack mit ICMP fuer Echos gemacht. Wenn 
ich mal ein längeres Pingen mache sind 10 - 20% der Pakete zerstört. Die 
Fehler sind unterschiedlich, teilweise gehts 100 mal gut, dann wieder ne 
Zeit gar nicht.
Ich denke es liegt an der SPI-Kommunikation, die ist wohl nicht 
zuverlässig.
Morgen werde ich verschiedene Geschwindigkeiten fuer SPI ausprobieren, 
vielleicht bringt das was.

Einen neuen enc28j60 habe ich auch, allerdngs nur den Chip an sich und 
das noch in einer Grösse, die ich nicht mehr selbst einlöten kann...

von Christian (Gast)


Lesenswert?

Problem gelöst, die Interrupts meiner Uhr waren das Problem... Während 
des Sendens und Empfangens sollten keine Interrupts kommen.

von Sascha F. (sascha_focus) Benutzerseite


Lesenswert?

Sorry, das ich Thread wieder ausgrabe.

Versuch mich gerade, den ENC28J60 mit einem M16C62P zu verbinden. Laut 
App.-Note REU05B0019-0100Z kann der M16C nur Mode 1 und Mode 3.
Der ENC brauc laut Datenblatt Mode 0.

Im Post von Judge vom 2.12.2006 steht:

So müsste das auf dem M16C/29 auch funktionieren. Andernfalls ist bei
den Pin-Einstellungen oder in den Übertragungsroutinen irgendwo ein
Fehler.
Ich würde aber mal darauf tippen das Du das CKPH-Bit (u2smr3) übersehen
hast. Dies ist in "Special Mode 2" beschrieben. Wenn es nicht gesetzt
ist passt das Clock-Signal nicht.


Im Datenblatt steht das Bit aber für Clock Delay.

Habe ich irgendwas übersehen oder falsch verstanden?

Gruß Sascha

von Eduardo (Gast)


Lesenswert?

Hi colleagues,

I has work very strong to translate german to english language, and then 
english to spanish. Excuse that i write in (bad) English.

Using MC16/29 or M16C/28 SPI port with ENC28J60 is possible by means of 
a small trick. I explain it:

1. Using SIO3 SPI port (following M16C/29 hardware manual).
2. Very important!. Set S3C control register to 0x68 value
(01101000 = f1, Sout3 enable, Sout3 output CLK3 function, CLK polarity 
TX ouput at falling edge and RX data at rising edge, msb first, internal 
clock).
3. The trick!. To solve the idle clock state problem, we need to
make a "false" falling os clock signal (SCK), at end of every read/write 
operation. This example is fully explanatory:

First, place a pull-down resistor () in SCK (P3.0) pin.

Then, replace "CS to OFF" operation with this code:
          S3C.6 = 0;               // External clock
    P3D.0 = 0;               // P3.0 (SCK) pin to input mode
     P3.3 = SIGNAL_OFF;       // Chip Select signal to OFF
    P3D.0 = 1;               // P3.0 (SCK) pin returns to output mode
          S3C.6 = 1;               // Internal clock

I work correctly with a 12,5 MHz SPI clock.

About TCP/IP, network drivers (ENC28J60 included) for tiny CPU's,
best tutorials, code, hardware and reference guides and more...:

http://tuxgraphics.org/electronics/200611/article06111.shtml
http://tuxgraphics.org/electronics/200606/article06061.shtml
http://tuxgraphics.org/common/src2/article06111/

http://hubbard.engr.scu.edu/avr/avrlib/

http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1489&redirects=tcpip

Best regards,
Eduardo

von Alex (Gast)


Lesenswert?

Hi Eduardo,

it's maybe possible to make public your driver?


Regards,
Alex

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.