Hallo zusammen,
ich hänge hier an einem Thema, bei dem mir langsam die Ideen ausgehen,
daher bin ich für jeden sachdienlichen Hinweis dankbar. Aber jetzt
erstmal der Reihe nach:
Ich verwende in einer Steuerung einen Mega32 mit MCP2515 und einem
Touchpanel EA-eDIP240-7. Der MCP hängt am INT0, das eDIP an INT1. Beide
werden über SPI angesteuert.
Soweit so gut, die Applikation läuft seit mehreren Monaten stabil und
ich wäre eigentlich glücklich. Allerdings ist mir langsam der Speicher
ausgegangen, weswegen ich die selbe Schaltung mit einem Mega644
aufgebaut habe. Das Programm ist erstmal identisch zu dem auf dem Mega32
(bis auf die notwendigen Anpassungen der Registernamen usw.).
Das Programm lässt sich problemlos compilieren und es läuft auch
zufriedenstellend auf dem Mega644. Allerdings kommt es sporadisch
(aktuell nach 3 Tagen) zu einem unerklärlichen Verhalten. Die INT0
Leitung vom MCP bleibt auf "low" "stehen". Daher kann ich keine CAN
Botschaften mehr empfangen. Senden klappt weiterhin, auch die
Kommunikation zum eDIP ist wie gewohnt, einzig, es werden keine
zyklischen CAN Botschaften mehr empfangen. Die Fehlerregister des MCP
zeigen keine Auffälligkeiten, EIFR ist 0... nur zeigt die Interrupt
Leitung weiterhin "low"...ich kann mir keinen Reim darauf machen... wenn
ich dann die Interrupt-Leitung kurzzeitig mit einem "high" Pegel
beaufschlage rennt sofort alles wieder... bis dann nach Stunden, oder
Tagen das selbe Verhalten wieder auftritt.
Hat jemand ne Idee, was hier schief läuft? Nochmals der Hinweis, das
selbe Programm läuft auf der HW mit Mega32 seit vielen Monaten ohne
Auffälligkeit...
Viele Grüße
Volker
Mangels Sourcecode: Benutzt du beim INT0_Init symbolische Bitnamen oder
absolute Werte? Fall letzteres: Hast du beim Wechsel der AVRs die Bits
kontrolliert mit denen du Flanken oder Levelerkennung einstellst? Nicht
dass du beim '32 Levelerkennung und beim '644 ungewollt Flankenerkennung
hast.
Hallo Stefan,
vielen Dank für den Hinweis. Bei der Migration zum 644 hatte ich das mit
den symbolischen Bitnamen bedacht. Seit einiger Zeit habe ich noch eine
Debug-Routine mit eingebaut, die mir die relevanten Register des 644 und
auch des MCP auf dem eDip ausgibt. Selbst im Falle des "nicht zurück
gesetzten INT0" sind die Inhalte der Register wie erwartet. Mir ist
klar, dass die Ausgabe auf dem Display nicht unbedingt den
Registerinhalt zum Zeitpunkt des "nicht zurücksetzens" beinhaltet (ich
lese die Register zyklisch aus). Wenn ich nur eine Möglichkeit finden
würde das Verhalten zu stimulieren oder wenigstens darauf zu triggern,
dann könnte ich mit dem Logic auf die Signale losgehen.
Viele Grüße
Volker
Ich verstehe die Situation noch nicht ganz.
MCP2515 CAN Controllerhttp://ww1.microchip.com/downloads/en/DeviceDoc/21801e.pdfAtmega644http://www.atmel.com/dyn/resources/prod_documents/doc2593.pdf
1/ Der MCP2515 ist mit seinem /INT Ausgang dem Eingang INT0 vom
Atmega644 verbunden. Pullups? Pulldowns? Der '644 nutzt die INT0 ISR für
eine SPI Kommunikation zum MCP um über den MCP eine CAN Kommunikation
abzuwickeln.
2/ Der '644 reagiert auf Level LOW (richtig)? Flanke-DOWN?
3/ Es kommt vor, dass die CAN Kommunikation ausfällt. In diesem Fall
wird beobachtet, dass die MCP---644 Leitung LOW ist.
4/ Obwohl die MCP---644 Leitung LOW ist, ist das INTF0 Flag in EIFR 0,
d.h. es ist kein Interrupt aufgetreten.
Heisst das in 2/ ist INT0 auf Level LOW getriggert und die INT0 ISR wird
seltsamerweise nicht angesprungen?
Oder heisst das in 2/ ist INT0 auf Flanke getriggert und die INT0 ISR
wird bei Dauer-LOW ganz zu recht nicht angesprungen?
5/ Das Setzen der MCP---644 Leitung ist Aufgabe des MCP. Das Versagen
des MCP kann nicht aus den MCP-Registern erschlossen werden.
6/ Ein manueller HIGH seitens des '644 bringt den MCP zurück ins Spiel.
Wurde bereits ein Pullup an der Leitung getestet?
7/ /INT wird vom MCP beim Senden in zwei Fällen benutzt (Figure 3-1) und
beim Empfangen in drei Fällen (Figure 4-3). Teilweise hängen die Fälle
von der Konfiguration des MCP und teils von erfolgreichem
Senden/Empfangen ab.
Ändert sich die Situation, wenn der MCP anders konfiguriert wird (nur
/INT beim erfolgreichen Senden (genauer: Sendepuffer leer!)/Empfangen)?
8/ Wenn der MCP einen /INT ausgelöst hat, müssen die dazugehörigen
Interruptbits gelöscht werden "INT pin is driven low by the MCP2515 and
will remain low until the interrupt is cleared by the MCU"
(Beitrag "Re: CAN mit ATMega128 und MCP2515")
Vielleicht einen Fall aus 7/ vergessen?
Hallo Stefan,
>1/ Der MCP2515 ist mit seinem /INT Ausgang dem Eingang INT0 vom>Atmega644 verbunden. Pullups? Pulldowns? Der '644 nutzt die INT0 ISR für>eine SPI Kommunikation zum MCP um über den MCP eine CAN Kommunikation>abzuwickeln.
Das ist soweit richtig. Ich verwende den internen Pullup des 644, einen
externen hatte ich schon versucht, brachte aber keine Änderung
>2/ Der '644 reagiert auf Level LOW (richtig)? Flanke-DOWN?
Der INT0 ist als edge triggerd (low) konfiguriert
>3/ Es kommt vor, dass die CAN Kommunikation ausfällt. In diesem Fall>wird beobachtet, dass die MCP---644 Leitung LOW ist.
Das ist so richtig
>4/ Obwohl die MCP---644 Leitung LOW ist, ist das INTF0 Flag in EIFR 0,>d.h. es ist kein Interrupt aufgetreten.>Heisst das in 2/ ist INT0 auf Level LOW getriggert und die INT0 ISR wird>seltsamerweise nicht angesprungen?>Oder heisst das in 2/ ist INT0 auf Flanke getriggert und die INT0 ISR>wird bei Dauer-LOW ganz zu recht nicht angesprungen?
Ich vermute, dass die ISR angesprungen wird, die Interrupt-Leitung aber
nicht mehr frei gegeben wird. In diesem Fall würde etwas mit dem
Rücksetzen des Interruptbits im MCP schief gehen. Das würde zumindes das
Verhalten erklären, dass ich von dem Zeitpunkt an keine weiteren CAN
Botschaften über den MCP empfangen kann.
>5/ Das Setzen der MCP---644 Leitung ist Aufgabe des MCP. Das Versagen>des MCP kann nicht aus den MCP-Registern erschlossen werden
Ich kann dadurch immerhin ausschliessen, dass es sich um einen bus-off
handelt. Das CANINTF Register des MCP zeigt mir zu diesem Zeitpunkt auch
nicht an, dass ein Interrupt noch pending ist. => Kapitel 7.7 "Once an
interrupt flag is set by the device, the flag cannot be reset by the MCU
until the interrupt condition is removed."
>6/ Ein manueller HIGH seitens des '644 bringt den MCP zurück ins Spiel.>Wurde bereits ein Pullup an der Leitung getestet?
Ja, leider ohne Erfolg. Der Aufbau mit dem Mega32 nutzt auch keinen
externen Pullup.
>7/ /INT wird vom MCP beim Senden in zwei Fällen benutzt (Figure 3-1) und>beim Empfangen in drei Fällen (Figure 4-3). Teilweise hängen die Fälle>von der Konfiguration des MCP und teils von erfolgreichem>Senden/Empfangen ab.>Ändert sich die Situation, wenn der MCP anders konfiguriert wird (nur>/INT beim erfolgreichen Senden (genauer: Sendepuffer leer!)/Empfangen)?
Ich gehe davon aus, dass ich die Sendeseite nicht weiter betrachten
muss, da diese nicht mit Interrupts arbeitet. Der Versand von
Nachrichten funktioniert auch weiterhin wie gewohnt.
Meine Empfangsroutinen habe ich bislang nicht umkonfiguriert. Der MCP
nutzt keine Filter, roll-over von RXB0 nach RXB1 ist erlaubt. Eine
Änderung der Routinen auf Polling habe ich noch nicht getestet.
>8/ Wenn der MCP einen /INT ausgelöst hat, müssen die dazugehörigen>Interruptbits gelöscht werden "INT pin is driven low by the MCP2515 and>will remain low until the interrupt is cleared by the MCU">(Beitrag "CAN mit ATMega128 und MCP2515")>Vielleicht einen Fall aus 7/ vergessen?
Wahrscheinlich habe ich irgend etwas vergessen, übersehen, nur ins Auge
springen mag es mir noch nicht. Wenn beispielsweise ein roll-over von
RBX0 nach RBX1 stattfindet und bereits ein Interrupt ausgelöst, die
Botschaft aber noch nicht abgeholt wurde, dann würde der Interrupt
"stehen" bleiben, solange bis RBX0 und RBX1 ausgelesen sind und die
beiden Flags im Register zurück gesetzt wurden. Diesen Fall habe ich
bedacht. Es muss die Kombination aus mehreren Ereignissen sein, die in
einem sehr kleinen Zeitfenster zusammentreffen müssen... und irgendwie
spielt da die SPI Kommunikation zum eDIP auch eine Rolle. Es gibt
zyklische Ausgaben auf dem eDIP, die natürlich dann auch immer die SPI
belegen...
Soweit mal für heute, (oder doch schon gestern??) :)
viele Grüße
Volker
> Der INT0 ist als edge triggerd (low) konfiguriert
Würde ich als Levelinterrupt machen. Es kommt ja vom MCP keine Flanke
mehr, sondern der MCP hält /INT LOW solange der '644 den Interrupt des
MCP nicht "cleared/reset" hat:
>>8/ Wenn der MCP einen /INT ausgelöst hat, müssen die dazugehörigen>>Interruptbits gelöscht werden "INT pin is driven low by the MCP2515 and>>will remain low until the interrupt is cleared by the MCU">>(Beitrag "CAN mit ATMega128 und MCP2515")
Der '644 (= MCU) muss dann herausfinden, wieso der MCP einen /INT
ausgelöst hat und die Ursache beseitigen und die Interruptflags (ggf.
mehrere!) zurücksetzen. Ursachen können sein: leerer Sendepuffer (=>
Senden), gefüllter Empfangspuffer (=> Auslesen) oder ggf. Fehler (kann
man abschalten).
> Das CANINTF Register des MCP zeigt mir zu diesem Zeitpunkt auch> nicht an, dass ein Interrupt noch pending ist.
Das verstehe ich nicht. Hast du auch CANSTAT.ICOD (7.1) ausgewertet, ob
ein Interrupt "pending" ist?
Es ist aber auch nicht einfach in dem Datenblatt alle möglichen Ursachen
für den Interrupt zu "clearen", bevor die Flags "resettet" werden. Nach
7.6.1 und REGISTER 6-3 sind bestimmte Bits zu clearen, die nicht in dem
CANINTF angezeigt werden.
Hallo Stefan,
nochmals vielen Dank für Deine Antwort. Besonders der Hinweis mit dem
ICOD hat mich vielleicht auf eine Spur gebracht. Ich werde am nahenden
Wochenende nochmals meinen CAN Treiber reviewen.
Ich geb Dir dann Bescheid!
Viele Grüße
Volker