Forum: Mikrocontroller und Digitale Elektronik RFM12: Was macht dieser Code?


von Bernd V. (berndv)


Lesenswert?

Hallo,

ich bastle zur Zeit mit den RFM12 Funkmodulen und der Ethersex Firmware 
rum. Kann mir jemand von euch erklären, was der unten stehende Code 
macht?

Speziell interessiert mich, warum am Anfang der Interruptroutine 
'rfm12_trans (0x0000)' aufgerufen wird (was macht rfm12_trans (0x0000) 
überhaupt?).

Und, unter welchen Umständen kann es passieren, dass man in das letzte 
'if' reinläuft. Was läuft da falsch?

1
ISR(RFM12_vect)      /* PCINT */
2
{
3
  uint16_t status = rfm12_trans (0x0000);
4
5
  if (status & 0x4000) {
6
    RFM12_DEBUG ("rfm12/por -> init");
7
    rfm12_init ();
8
    return;
9
  }
10
11
  if (status & 0x2000) {
12
    RFM12_DEBUG ("rfm12/overflow -> init");
13
    rfm12_init ();
14
    return;
15
  }
16
17
  if ((status & 0x8000) == 0) {
18
    RFM12_DEBUG ("rfm12/spurious int: %x", status);
19
    return;
20
  }
21
22
  ...
23
}

Gruß,
Bernd

P.S.: Den kompletten Code gibt es hier 
https://github.com/ethersex/ethersex/blob/master/hardware/radio/rfm12/rfm12.c

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Bernd Vogt schrieb:
> Und, unter welchen Umständen kann es passieren, dass man in das letzte
> 'if' reinläuft. Was läuft da falsch?
Unter dem Umstand, dass in der Variable status z.B. der Wert 0 ist. 
Das könnte sein, wenn z.B. das RFM12 Modul nicht versorgt wird, oder, 
oder...

> was macht rfm12_trans (0x0000) überhaupt?
Das sieht man, wenn man sich die Funktion mal genauer ansieht...
1
uint16_t
2
rfm12_trans(uint16_t wert)
3
{
4
  uint16_t werti = 0;
5
6
  PIN_CLEAR(SPI_CS_RFM12);
7
8
/* spi clock down */
9
#ifdef CONF_RFM12_SLOW_SPI
10
  _SPCR0 |= (uint8_t)_BV(SPR1);
11
#else
12
  _SPCR0 |= (uint8_t)_BV(SPR0);
13
#endif
14
15
  werti = (uint16_t)(spi_send ((uint8_t)((0xff00U & wert) >> 8)) << 8);
16
  werti += spi_send ((uint8_t)(0x00ffU & wert));
17
18
/* spi clock high */
19
#ifdef CONF_RFM12_SLOW_SPI
20
  _SPCR0 &= (uint8_t)~_BV(SPR1);
21
#else
22
  _SPCR0 &= (uint8_t)~_BV(SPR0);
23
#endif
24
25
  PIN_SET(SPI_CS_RFM12);
26
  return werti;
27
}
Dann wird klar: damit wird eine SPI-Übertragung abgewickelt. Und mit dem 
Wort 0x0000 wird der Status abgefragt:
http://www.mikrocontroller.net/articles/RFM12#Register

von gerd (Gast)


Lesenswert?

Sieht nach Fehlerbehandlung aus.

- gerd

von Michael U. (amiga)


Lesenswert?

Hallo,

Status holen, Interruptquelle maskieren, um den Auslöser zu 
identifizieren.
PowerOnReset und FIFO-Overflow werden zuerst getestet.

Der letzte Fall testet, ob ein anderes Int-Bit außer 0x8000 (FIFO hat 
Daten) gesetzt ist. Wenn nicht, wurde der Interrupt wohl durch eine 
Störung und nicht vom RFM12 ausgelöst...

Gruß aus berlin
Michael

von Bernd V. (berndv)


Lesenswert?

Zunächst mal Danke für eure Antworten! Ich denke ich beginne zu 
begreifen was hier passiert... wobei mir die Ursache noch föllig unklar 
ist :(

Ich verstehe das jetzt so: Der Befehl 0x0000 liest das Statusregister 
des RFM12 aus. Es wird erwartet, dass das erste Bit im Register gesetzt 
ist, was soviel bedeutet, wie dass das RFM12 Modul bereit zum Senden 
ist. Leider ist aber dieses Bit 0 und das bedeutet, dass das Modul 
gerade Daten empfängt? Evtl. durch eine Störung?

Was könnte die Ursache für diese Störung sein? Kann es evtl. auch an 
einer fehlerhaften Initialisierung oder sogar Verkabelung des Moduls 
liegen?

Das Seltsame ist, dass ich das selbe Verhalten auf zwei verschiedenen 
Boards (AVR-NET-IO und Pollin Funkboard) und auch an zwei föllig 
verschiedenen Standorten habe...

Grüße,
Bernd

von wb1 (Gast)


Lesenswert?

Hallo,
da ich das gleiche Problem habe, interessiert mich wie weit Du gekommen 
bist.
In den vielen Seiten die ich durchkämmt habe, fand ich das die 868 
module mit rx-fifo-read (b000), dazu muß ef-bit gesetzt sein oder 
status-read gelesen werden.
Ich glaube, der Interrupt kommt von RX, aber warum?

von Bernd V. (berndv)


Lesenswert?

Hi,

ich habe hier [1] noch eine recht gute Antwort zu meinem Problem 
bekommen.

Die momentane Vermutung geht dahin, dass beim Senden ganz kurz die 
Stromversorgung zusammenbricht, da das RFM12 beim Umschalten von RX auf 
TX schnell mehr Strom benötigt.

Die Lösung könnte sein, einen 100nF Kondensator in direkter Nähe des 
RFM12 einzubauen, so wie hier [2]. Der sollte dann die Schwankung 
ausgleichen können.

Gruß,
Bernd

P.S.: wb1 lass mich wissen, ob du weiter gekommen bist.

[1] 
http://list.zerties.org/pipermail/ethersex-devel/2011-January/000139.html
[2] 
https://m21.hyte.de/attachment/wiki/Projekte/EthersexStromzaehler/AVR_NetIO_RFM12-ethersex-Aufsatzboard_Schema.jpg

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.