www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Infineon XC886 CAN FIFO zum Senden


Autor: Daniel Schwalm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen!

Ich versuche gerade einen Sende-FIFO für CAN-Nachrichten auf einem XC886 
zu implementieren. Dazu habe ich die 32 Message Objekte des XC886 wie 
folgt aufgeteilt:

0-7: Transmit-FIFO (Base Object: 0)
8-31: Receive-FIFO (Base Object: 8)

Zudem habe ich mir von Dave die Funktion CAN_ubWriteFIFO() generieren 
lassen. Diese Funktion rufe ich in folgender Funktion auf, welche das 
senden einer CAN-Nachricht kapselt:
void komSendeDaten( canDaten8Byte *canMessage )
{ 
  un_32bit  canDataObject;
  un_32bit  canIDObject;
  stCAN_SWObj canTransmitObject;

  canTransmitObject.ubMOdlc  = 0x08;                 // Data Length auf 8 Byte setzen
  canTransmitObject.ubMOcfg  = 0xAA;              // Config-Bits setzen

  canIDObject.ulVal       = canMessage->lCanId;      // neue CAN-ID aufbauen
  canTransmitObject.ulID     = canIDObject;             // ID in CAN Objekt laden

  canDataObject.ubDB[0]     = canMessage->cDaten[3];      // neue low CAN-Daten aufbauen
  canDataObject.ubDB[1]     = canMessage->cDaten[2];
  canDataObject.ubDB[2]     = canMessage->cDaten[1];
  canDataObject.ubDB[3]     = canMessage->cDaten[0];
  canTransmitObject.ulDATAL   = canDataObject;

  canDataObject.ubDB[0]     = canMessage->cDaten[7];      // neue high CAN-Daten aufbauen
  canDataObject.ubDB[1]     = canMessage->cDaten[6];
  canDataObject.ubDB[2]     = canMessage->cDaten[5];
  canDataObject.ubDB[3]     = canMessage->cDaten[4];
  canTransmitObject.ulDATAH   = canDataObject;

//  CAN_vConfigMsgObj( TRANSMIT_OBJECT, &canTransmitObject );   // CAN-Objekt in Message Object laden
//  CAN_vTransmit(TRANSMIT_OBJECT);               // Sende-Prozess starten

  CAN_ubWriteFIFO(TRANSMIT_OBJECT, &canTransmitObject);    // Das zu sendente CAN-Paket in den Transmit FIFO einreihen
}

Nun habe ich das Problem, dass der Controller 8 CAN-Nachrichten sendet 
und danach nichts mehr. Also einmal wird jedes der 8 Message-Objekt des 
Transmit-FIFO zum senden genutzt und sobald der CUR-Zeiger wieder auf 
das erste Message Objekt zeigt, sendet der Controller nichts mehr. Die 
Funktion CAN_ubWriteFIFO() gibt aber weiterhin ein 1 zurück (was 
eigentlich auf korrekte Funktion deuten sollte). Ich habe die Vermutung, 
dass ich nach dem Senden irgendwas an den Message-Objekten 
"umkonfigurieren" oder zurücksetzen muss. Leider bin ich mit Debugging 
und so weiter noch nicht dahinter gekommen, was das ist... In einem 
Beispiel-Code (ich glaube von Infineon) wird aber auch nichts anderes 
gemacht, als die Funktion CAN_ubWriteFIFO() aufzurufen (konnte ich 
leider nicht testen, da ich die Hardware dafür nicht habe). Wenn ich den 
Aufruf von CAN_ubWriteFIFO() auskommentiere und statt dessen die zwei 
Zeilen darüber reinnehme, funktioniert das Senden dauerhaft (allerdings 
ohne FIFO). Vielleicht hat ja jemand eine Idee, woran das FIFO-Problem 
liegen könnte? Evtl. auch ein Fehler in der Funktion CAN_ubWriteFIFO()?

Viele Grüße,
Daniel

Autor: Daniel Schwalm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Manchmal geht es schneller als man denkt ;) Hab nun herausgefunden, 
woran das Problem lag. Hier ein kurzer Bericht, für alle die evtl. mal 
vor dem selbigen stehen:

Der Fehler lag nicht in meiner Funktion sondern in der von Dave 
erzeugten Funktion CAN_ubWriteFIFO() und zwar an folgender Stelle:
...
        CAN_vWriteCANAddress(CAN_MOCTR(j));
        CAN_vReadEN();   // Readmode is Enabled

        if((CAN_DATA1 & 0x01)== 0x00)  // if reset TXRQ
        {
            if(j == CAN_DATA3)  // last MO in a list
            {
               // WritePtr = BOT of the base object
               CAN_vWriteCANAddress(CAN_MOFGPR(ubObjNr));
               CAN_vReadEN();   // Readmode is Enabled
               aubFIFOWritePtr[ubObjNr] = CAN_DATA0;
            }
            else
            {
               // WritePtr = PNEXT of the current selected slave
               aubFIFOWritePtr[ubObjNr] = CAN_DATA3;
            }

            CAN_vWriteCANAddress(CAN_MOCTR(j));  // Addressing CAN_MOCTRn register
            CAN_vWriteCANData(0x00000008);      // reset NEWDAT
...

Hier soll eigentlich sichergestellt werden, dass wenn das letzte 
Message-Objekt des Sende-FIFOs gerade zum Senden genutzt werden soll, 
dass bei der nächsten Sendeanforderung wieder das erste Objekt genutzt 
wird. Dies wird in aubFIFOWritePtr[ubObjNr] gespeichert. Leider prüft 
die Funktion nicht ob das aktuelle Objekt das letzte im FIFO ist sondern 
ob es das letzte in der Liste ist! D.h. mein FIFO geht von den Objekten 
0-7, die Liste aber von 0-31 (da die Liste auch den Empfangs-FIFO 
beinhaltet). Also wurde versucht, nachdem 8 Pakete gesendet wurden, das 
Message Objekt 8 zum senden zu nutzen, was aber ein Receive Message 
Object ist!

Hier die überarbeitet Version, die auf den ersten Blick bei mir wie 
gewünscht funktioniert:
...
        CAN_vWriteCANAddress(CAN_MOCTR(j));
        CAN_vReadEN();   // Readmode is Enabled

        if((CAN_DATA1 & 0x01)== 0x00)  // if reset TXRQ
        {
      CAN_vWriteCANAddress(CAN_MOFGPR(ubObjNr));    // Zeiger-Register des Base-Objektes laden
          CAN_vReadEN();   // Readmode is Enabled
      
            if(j == CAN_DATA1)  // prufen ob letztes MsgObj im Sende-FIFO (=TOP-Objekt)
            {
               // WritePtr = BOT of the base object
               CAN_vWriteCANAddress(CAN_MOFGPR(ubObjNr));
               CAN_vReadEN();   // Readmode is Enabled
               aubFIFOWritePtr[ubObjNr] = CAN_DATA0;
            }
            else
            {
               // WritePtr = PNEXT of the current selected slave
         CAN_vWriteCANAddress(CAN_MOCTR(j));
             CAN_vReadEN();   // Readmode is Enabled
               aubFIFOWritePtr[ubObjNr] = CAN_DATA3;
            }

            CAN_vWriteCANAddress(CAN_MOCTR(j));  // Addressing CAN_MOCTRn register
            CAN_vWriteCANData(0x00000008);      // reset NEWDAT  - OK, Funktioniert!
...

Die Änderung besteht eigentlich nur darin, dass nicht auf das Ende der 
Liste sondern auf das Ende des FIFOs geprüft wird (Vergleich mit dem 
TOP-Zeiger des Transmit-FIFO Base-Objektes).

Ich hoffe das ich damit anderen ein paar Stunden Fehlersuche ersparen 
konnte ;)

Viele Grüße,
Daniel

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.