Forum: HF, Funk und Felder Atmel 86RF230 - RX_ON + CCA -> PLL_ON 15µs "verwundbar" - Hilfe!


von Joan P. (joan)


Lesenswert?

Ok, hoffe dass das hier hergehört..

Geht um folgendes:

ZigBit Modul von Meshnetics: 
http://www.mikrocontroller.net/articles/Meshnetics_Zigbee

Ich steuere den RF-Chip im Basic Operating Mode und möchte nach dem 
Clear Channel Assessment Test je nach Ergebnis mit dem Senden beginnen 
oder CCA wiederholen (siehe Datenblatt S. 21: 
http://www.atmel.com/dyn/resources/prod_documents/doc5131.pdf)

Da gibts aber ein für mich nicht unerhebliches Problem beim Timing und 
der Verlässlichkeit der Zustände des RF230 Chips.

- CCA kann man nur im RX_ON Modus starten
- RX_ON Modus empfängt automatisch 802.15.4-konforme Frames, wenn er 
nix anderes zu tun hat, also auch sofort nach CCA-Test
- CCA_DONE wird nicht per Interrupt bekannt gegeben, man muss pollen
- PLL_ON Befehl braucht per SPI mit maximalem Speed 4µs

mein Code dafür:
1
...
2
spi_write (REG_PHY_CC_CCA, (CMD_CCA_REQUEST | SET_CCA_MODE_3 | SET_CHGRP_1)); // dauert ca 140µs (RX_ON -> CCA_DONE)
3
do // Poll CCA-Result
4
{
5
    cca_result = spi_read(REG_TRX_STATUS); // CCA Status einlesen
6
}
7
while (!(STS_CCA_DONE == (MSK_CCA_DONE & cca_result))); // CCA fertig?
8
if (STS_CCA_FREE == (MSK_CCA_STATUS & cca_result)) // wenn Kanal frei, senden..
9
{
10
    spi_write (REG_TRX_CMD, CMD_PLL_ON); // in PLL_ON Staus wechseln -> Transmittermodus vorbereiten
11
...
Bemerkung:
spi_write (<zieladresse>,<zu_schreibender_register_wert>)
spi_read (<zieladresse>) // liefert Register_Wert selber zurück

Daraus folgt mein Problem:
Selbst wenn CCA ein "Kanal frei" signalisiert hat, braucht man mit 
pollen, Frei/Besetzt-Entscheidung und Start des PLL-Modus ca 10..15µs 
bis man überhaupt nur ans Senden denken darf.
Wenn in dem Zeitraum ein SFD eines 802.15.4-konformen Frames 
reinschneit, läuft der PLL_ON Befehl ins Leere...
Und ich kann nichts dagegen tun.

Im Moment bastel ich am RX_START Interrupt rum, der ausgelöst wird, 
sobald der RF230 was empfängt - allerdings kommt der laut Datenblatt 
auch erst 8µs nachdem das PHR eines 802.15.4-konformen Frames 
eingelesen wird (Datenblatt, S. 25, Figure 7-2).

Ich denke aber ich werd nach dem PLL_ON-Befehl nochmal das Status 
Register abfragen und dann wohl zurück zum CCA springen, wenn er mir da 
was anderes erzählt, als "PLL_ON aktive".

Hat sonst noch jemand ne Idee? ...Programmierteschnisch?

Das wär alles nicht notwendig, wenn man CCA aus dem PLL_ON heraus 
starten könnte und er da selber wieder hingeht, aber ok, so ist das 
Leben.. :(

Grüsse & Danke fürs lesen.

PS: Ansonsten tolles Modul und RF-Chip, kann man nur empfehlen.. alle 
meine sonstigen Anforderungen werden super erfüllt.. das Programm und 
der RF-Chip läuft ohne penetrante, selbstprogrammierte 802.15.4-Störer 
der gleichen Sorte wie am Schnürchen :)
Im höheren Betrieb mit ZigBee-Stack dürfte dieser Fehler wohl gar nicht 
auftreten, aber den brauch ich ja nicht - wer schmeißt schon mit dem 
Schinken nach der Wurst? ;)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Der CCA geht nur im RX_ON, weil er (logischerweise) den Empfänger
benötigt: die RSSI-Auswertung wird für die Ermittlung des ED-Wertes
gebraucht, und die Synchro im Baseband wird benötigt, falls du einen
CCA-Mode mit CS haben möchtest.

Du musst das Bit nicht zwingend pollen, du kannst auch stur die 140 µs
abwarten.  (128 µs für die Messung, weitere 16 µs werden für die
Umschaltung der PLL auf die Empfangsfrequenz und andere
,,Kleinigkeiten'' benötigt.)

Du kannst sofort nach dem Ende der Messung ein FORCE_TRX_OFF auf den
Chip bügeln, den du unmittelbar wieder von einem PLL_ON folgen
lässt.  Dadurch brauchst du nur einige µs, bis die PLL wieder da ist.
Der Löwenanteil der Zeit, die man vom TRX_OFF bis in den PLL_ON
benötigt, geht nämlich fürs Aufladen des 1-µF-Kondensators am analogen
Spannungsregler drauf, der wird aber in den paar µs zwischen dem
FORCE_TRX_OFF und dem PLL_ON noch nicht ernsthaft entladen, damit geht
das Ganze schnell (auch wenn's das Datenblatt nicht garantiert).  Wenn
du auch bis vor den Beginn der CCA-Messung noch im PLL_ON geblieben
bist und erst danach auf RX_ON geschaltet hast, dürfte es kaum eine
Chance geben, dass die Synchro überhaupt einen Frame erkannt hat (die
Präambel dauert ja 160 µs).  Außerdem isses eigentlich egal: wenn sie
einen Frame erkannt hat, ist dein Kanal ja sowieso belegt und du musst
es neu versuchen.

von Joan P. (joan)


Lesenswert?

Herzlichen Dank Jörg!
..hat super funktioniert.

Code sieht jetzt so aus:
1
..
2
spi_write (REG_TRX_CMD, CMD_RX_ON); // RX_ON starten
3
spi_write (REG_PHY_CC_CCA, (CMD_CCA_REQUEST | SET_CCA_MODE | SET_CH_1)); // CCA starten, dauert 27µs ab 'CMD_RX_ON'
4
do
5
{
6
  cca_result = spi_read(REG_TRX_STATUS); // CCA Status einlesen
7
}
8
while (!(STS_CCA_DONE == (MSK_CCA_DONE & cca_result))); // CCA fertig? dauert 154µs ab 'CMD_RX_ON'
9
spi_write (REG_TRX_CMD, CMD_FORCE_TRX_OFF); // TRX_OFF starten
10
spi_write (REG_TRX_CMD, CMD_PLL_ON); // PLL_ON starten, dauert 14µs ab 'CMD_FORCE_TRX_OFF'
11
while (STS_PLL_ON != (MSK_TRX_STATUS & spi_read(REG_TRX_STATUS))) // dauert 21µs ab 'CMD_FORCE_TRX_OFF'
12
if (STS_CCA_STATUS == (MSK_CCA_STATUS & cca_result)) // wenn Kanal frei, senden..
13
{ }
14
...
 (für Nachahmer: Zeitangaben gelten für fCPUI/O = 8MHz und SPI = 4MHz, 
dann sind 2 byte über SPI ca 4µs lang)

Ich polle CCA_DONE immer noch, weil ich mich auf die 140µs nicht so 
recht verlassen mag. Auf das pollen vom PLL_LOCK könnt ich vielleicht 
verzichten, aber wenns dann doch mal nicht passt (wie du angedeutet 
hast), bleibt er wenigstens hier stehen und wartet, bevor er Unsinn 
macht :D

Meine selbstgemachten Störer bringen das Prog jetzt jedenfalls nicht 
mehr aus dem Tritt. Ist wirklich toll etwas anzusehen, dass sich selber 
"steuert" :)

Grüsse

PS: auch nochmal Danke für den Link zu µracoli. Habs zwar nicht 
genutzt, sondern nur reingeguckt (vor allem weil ichs nicht geschafft 
hab, das an das ZigBit-Modul anzupassen), aber der Gedanke zählt ja.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Joan P. wrote:

> Ich polle CCA_DONE immer noch, weil ich mich auf die 140µs nicht so
> recht verlassen mag.

Die sind vermutlich genauer als dein gesamter Code im Microcontroller,
da sie durch einen Hardwaretimer erzeugt werden. ;-)

U. U. ist es sinnvoller, erstmal einen Software-Timer zu starten und
erst danach zu pollen: während der Timer tickt, kann der Prozessor
ja sogar noch ein wenig schlafen, außerdem kostet das SPI-Interface
des AT86RF230 zusätzlichen Strom (da wackeln ja Bits in irgendwelchen
Schieberegistern herum).

> Auf das pollen vom PLL_LOCK könnt ich vielleicht
> verzichten, aber wenns dann doch mal nicht passt (wie du angedeutet
> hast), bleibt er wenigstens hier stehen und wartet, bevor er Unsinn
> macht :D

Sicher 'ne gute Idee, klar.

> PS: auch nochmal Danke für den Link zu µracoli. Habs zwar nicht
> genutzt, sondern nur reingeguckt (vor allem weil ichs nicht geschafft
> hab, das an das ZigBit-Modul anzupassen), aber der Gedanke zählt ja.

Naja, die ZigBit-Anpassung dafür müsste wohl nochmal jemand machen.

von Jann J. (jann)


Lesenswert?

hallo Leute,
ich habe einer art Wetterstation  mit Altmega 16 gebauen. Ein
externes,Modul zum Senden der Temperaturen und ein, internes
Modul zum Empfang der Daten und  Ausgabe auf ein Display.
für die  Funkübertragung wurde der AT86RF231 bereitgestellt.
bis jetzt hatte ich kein erfahrung mit Funkübertragung.
kann mir jemand bei der initialiserung und send und
empfangsfunktionen(TX.RX)RF von AT86RF231 hilfen.
 und woran ich achten muss und mölich beispiel cod
Grüsse und Danke fürs Lesen

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Nein, nein, bitte kapere jetzt nicht alle Threads!

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.