Ich empfange hier Frames mit 4 Byte Payload, wobei sich die Nachricht
nach dem 2ten Byte wiederholt.. also doppelt vorhanden ist.
Das mach ich, weil ich recht schnell ohne großes Sicherheitsnetzt (nur
CCA beim Senden) viele Statusmeldungen mit mehreren Modulen verschicke..
da kommen schon mal Fehler durch, trotz meiner kleinen CRC. Insgesamt
kommt noch eine 16Bit CRC vom RF230 automatisch erzeugt über das ganze.
Aber genug der Vorrede..
Laut dem Datenblatt vom dem RF230 kann man während des Empfangs schon
mit dem Lesen der empfangenen Bytes beginnen. Zuerst lese ich also 32µs
nach dem RX_START Interrupt nur die PHR ein (1byte via 802.15.4 brauchte
32µs), um zu entscheiden, ob die Nachricht überhaupt von mir ist (meine
Nachrichten sind immer gleich lang) sonst kann ich das Empfangen gleich
wieder beenden und auf das nächste SFD warten.
Das funktioniert problemlos.
Danach warte ich 64µs und lese dann byte 1&2 meiner eigentlichen
Nachricht nochmal zusammen mit dem PHR-byte ein und schaue nach, ob mein
selbstgebasteltes CRC stimmt (Bit2:0 von byte 2), sonst kann ich auch
hier wieder den Empfang abbrechen. Ohne Störungen auch dies Problemlos.
Keine Ausfälle.
Nun vergehen wieder 64µs bis byte 3&4 meiner Nachricht eintrudeln,
welche genau das gleiche wie byte 1&2 enthalten sollten. Da ich jetzt
aber nicht schon wieder PHR + byte 1&2 einlesen will (4µs/byte) habe ich
es hier mit SRAM-Lesezugriff versucht.
Das verursacht aber sehr häufig Fehler.. byte 3&4 != byte 1&2.
Im Vergleich mit dem Lesen von byte 3&4 im Rahmen eines kompletten
Lesevorganges mit PHR enstehen keine Fehler, dh. byte 3&4 == byte 1&2.
Selbst wenn ich mittels SRAM-Zugriff byte 1&2 (wie im Code aufgeführt)
einlese werden Fehler angezeigt, obwohl ichs nur mit dem vorher per
normalem Lesezugriff erhaltenen vergleiche.. was mache ich falsch?!
Die entsprechenden Codeschnipsel:
1
ISR(INT5_vect)// kommt 8µs nachdem das PHR-Octet begonnen hat (per Octet 32µs)
2
{
3
initialize_timer4B_us(32);// Timer 4 Compare Match in 32us
4
// 32µs warten, dann PHR einlesen
5
poll_timer4B_CompareMatch();
6
initialize_timer4B_us(64);// Timer 4 Compare Match in 62ms
Hmm, naja, einen offensichtlichen Fehler sehe ich erstmal nicht.
Aber nur so: richtig gewinnen kannst du durch den SRAM-Zugriff bei
derart kurzen Frames eigentlich nicht. Die beiden zusätzlichen
SPI-Transfers für das neue Kommando und die SRAM-Adresse lohnen
nicht. Warum startest du nicht einfach einen frame read und
lässt diesen solange aktiv, solange es ein möglicher, dich
interessierender Frame ist? D. h. /SEL auf low, frame read Kommando,
PHR lesen. Wenn Länge != 4 => Abbruch. Zwei weitere Bytes
abwarten und einlesen, CRC überprüfen, wenn falsch => Abbruch.
Noch zwei Bytes abwarten und lesen, gegen die vorigen vergleichen,
wenn falsch => Abbruch. CRC abwarten und lesen, /SEL auf high.
CRC-16 noch vergleichen (wenn's dich interessieren sollte).
Oh, das ist auch ne Idee.. stimmt, da wär ich nicht drauf gekommen.
Das werd ich gleich mal umsetzen und probieren.
So richtig wild ist das Problem mit dem SRAM für mich ja eigentlich
nicht, weil wie du schon sagtes ich so viel Zeit ja nicht verlustiere
wenn ich von vorn lese.
Bin auch nur wegen dem CRC16 Problem drauf gekommen, was in dem neuen
Thread drin ist.
Danke schon mal für die Idee :-)
Die Lösung mit dem Lesen der 4 Byte Frames als 2x2 Bytes nach dem
RX_START IRQ scheint mir doch etwas speziell auf das Problem optimiert
zu sein.
Wenn ein Byte 4us zum Upload braucht, dann sind die
o.g. Rahmen inkl. SPI-Command, PHR und CRC in 8 * 4us = 32us im
Controller. Wenn die Verarbeitung der Empfangsdaten um diese Dauer
verzoegert werden kann, reicht also der TRX_END Interrupt aus, da der
nächste Frame frühestens nach ca. 6*32us (5 Byte Preambel + 1 Byte SFD)
in den SRAM geschrieben wird. Ein Vorteil dieser Lösung wäre außerdem
eine kurze Verweildauer in der ISR.
Hier einfach noch so paar Ideen zum ursprünglichen Problem (auch wenn
ich nicht denke, dass du mit dem SRAM-Zugriff wirklich was gewinnst):
Den Sinn der NOPs verstehe ich nicht ganz: das Pollen des SPIF kostet
doch am Ende auch nicht mehr Zeit, und man kann sich zumindest 100%ig
sicher sein, dass das SPI auch wirklich schon fertig ist.
Das Timing könnte knapp sein. Wenn du dich irgendwo um 1 oder 2 µs
vertust, versuchst du ein Byte zu lesen, das noch gar nicht im Puffer
steht. Ich würde ,,für alle Fälle'' erstmal 1...2 µs ,,drauflegen'',
um auf der sicheren Seite zu sein. Da du mittels SRAM zugreifst,
bekommst du ja nicht einmal einen underrun-Interrupt, den gibt's nur
beim Frame-Lesen.
Die Frage ist noch, was du denn eigentlich als falsche Bytes liest.
Steht das in irgendeinem Zusammenhang mit den gesendeten Daten, oder
ist das einfach nur der vorherige Inhalt des SRAMs? Ggf. kannst du
ja zum Debuggen den SRAM mal vor dem Empfang mit einer bekannten
Bytefolge füllen?
Danke für eure Ideen.. ich hab mittlerweile die Version am laufen, wo
ich per SPI immer dann das byte lese wenn ich es brauche, so wie das
Jörg zuerst vorgeschlagen hat. SRAM Zugriff hab ich nicht genutzt jetzt.
Ich muss zwar zu Anfang 160µs warten, bis ich mit dem einlesen des PHR
anfangen kann nachdem das RX-START Interrupt kam, aber das reicht für
mein Timing locker aus.
Es läuft nun alles so wie ich mir das vorgestellt hab, zwar bisschen
anders, aber es läuft und stabil. Habe dank der CRC16, die der Chip
macht und der doppelten Nachrichtenversendung 2 Modulpaare bisher über
20h ungestört am laufen (je Paar wechselseitig Sender und Emfpänger bei
den Paaren, Umschaltzeit ca 43ms).. und keine Ausfälle, obwohl die sich
gegenseitig beharken. Ich bin sowas von glücklich im Moment :-)
Zum Schluss hat sich dann lustigerweise noch der im Datenblatt
beschriebene Fehler mit dem CCA-Rückmeldungsausfall gemeldet, was bisher
nie der Fall bei mir war.. da hab ich nicht schlecht geguckt.
Dort werkelt jetzt die von Jörg empfohlene harte Abfrage nach 140µs nach
CCA-START.
Wenn nun nix mehr ausfällt auf Sicht von 5 Tagen Dauereinsatz ändere ich
nix mehr am Code. :-)
Eine eigene Frage?
Dieser Thread ist über 18 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.