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;
}
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.
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.
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
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
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.
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.
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.
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.
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...
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?
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...
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
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?
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.
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.
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...
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
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.shtmlhttp://tuxgraphics.org/electronics/200606/article06061.shtmlhttp://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