Forum: Mikrocontroller und Digitale Elektronik RFM12 SDO polling


von René S. (grassh0pper)


Lesenswert?

hallo,

wie genau funktioniert das sdo-polling beim RFM12 modul beim Senden und 
Empfangen?
Ich mache jetzt schon ewig damit rum, komme aber auf keinen grünen 
zweig.

Montan sieht meine Senderoutine (hard-spi) so aus:

1. sendeteil komplett einschalten (cs auf low, 0x8228 in reg. laden, cs 
auf high
2. cs auf low
3. warten, dass sdo high wird, solange nix machen
4. 0xb8aa in reg laden
5. warten, dass sdo high wird, solange nix machen
5. 0xaa in reg laden
6. warten, dass sdo high wird, solange nix machen
7. 0xaa in reg laden
8. warten, dass sdo high wird, solange nix machen
9. synchronmuster in reg laden 0x2DD4
10. warten, dass sdo high wird, solange nix machen
11. nutzdaten senden (je acht bit)
12. warten, dass sdo high wird, solange nix machen
13. 0xaa in reg laden
14. warten, dass sdo high wird, solange nix machen
15. sendetrakt aus (beeinhaltet cs auf high)

funktioniert auch soweit ganz gut, würd ich sagen. Die Bilder auf dem 
Oszi sehen ok aus. Hab quasi das logikdiagramm ausm artikel RFM12 
nachprogrammiert und das sieht wie gesagt ok aus.
Jetzt zur empfangsroutine:
wann genau bekomme ich beim empfangen vom RFM-Modul ein High-Signal am 
SDO?
wie genau funktioniert hier das polling? Bekomme einfach kein 
high-signal am sdo...
Aber einfach durchrauschen ohne auf das rfm modul zu reagieren klappt 
natürlich auch nicht...

von René S. (grassh0pper)


Lesenswert?

1
void rfm_TX(uint8_t *data)
2
  {
3
    rfm_tx_enable(1);        //sendetrakt komplett ein
4
    rfm_enable();
5
    rfm_ready();
6
    spi_master_write_16(0xB8AA);  //takteinlaufbyte
7
    rfm_ready();
8
    spi_master_write_8(0xAA);    //takteinlaufbyte
9
    rfm_ready();
10
    spi_master_write_8(0xAA);    //takteinlaufbyte
11
    rfm_ready();
12
    spi_master_write_16(0x2DD4);  //synchronmuster
13
    for (int i=0; i<2; i++)
14
      {
15
        rfm_ready();
16
        spi_master_write_8(*data);    //nutzdaten: 1byte
17
      }
18
    rfm_ready();
19
    spi_master_write_8(0xAA);    //dummy-byte
20
    rfm_ready();
21
    rfm_tx_enable(0);        //sender ausschalten. (beeinhaltet rfm_disable)
22
  }
23
void rfm_RX(uint8_t *data)
24
  {
25
    rfm_rx_enable(1);    
26
    rfm_writecmd(0xCA81);  //FIFO leeren      
27
    rfm_writecmd(0xCA83);  //FIFO freigeben
28
    
29
    rfm_enable();
30
    rfm_ready();
31
    spi_master_write_16(0xB0000);
32
        rfm_ready();
33
    *data = spi_master_read(0x00);
34
    rfm_disable();
35
    rfm_enable();
36
    
37
    rfm_ready();
38
    spi_master_write_16(0xB000);
39
        rfm_ready();
40
    *data = spi_master_read(0x00);
41
    rfm_disable();
42
    rfm_enable();
43
    
44
    rfm_ready();
45
    
46
    blink(0, 100);
47
    
48
    rfm_rx_enable(0);
49
  }

so siehts aus, funzt aber nicht. Ich schätze es hängt am empfang... 
Achja: ich sende zuerst einmal fest 2 byte, deswegen die for schleife

von René S. (grassh0pper)


Lesenswert?

nachtrag:

fehler lag am (auch / nur?!) am sender:

die Zeile
1
spi_master_write_16(0x2DD4);  //synchronmuster
muss aufgeteilt werden in
1
spi_master_write_8(0x2D);  //synchronmuster
2
rfm_ready();
3
spi_master_write_8(0xD4);  //synchronmuster

da ich cs permanent auf low halte während ich das senderegister 
beschreibe kann ich nach einmaliges 0xb8xx mir dieses sparen, muss aber 
nach jedem byte sdo abfragen!

von Martin K. (maart)


Lesenswert?

Das Modul steht bei mir auch bald auf dem Plan.
Danke für die Beschreibung.
cs ist bei dir nSEL, also chip-select, oder?

von René S. (grassh0pper)


Lesenswert?

ja, genau, cs = chip select!
Inzwischen läuft die Sache wirklich gut. Es war noch ein fehler im code 
des empfängers:

der befehl zum auslesen des FIFO ist im Artikel mit 0xb8000 angegeben. 
Eigentlich ist es so, dass mit den ersten 8 bit 0xb0 schon der befehl 
zum auslesen des FIFO ans rfm modul geschickt wird. die restlichen 8bit 
sind dann nur dazu da, damit der µc (beim hardware SPI) einen takt an 
sck anlegt.
das ganze sieht bei mir so aus (testweise mit 2 byte ohne irgendwelche 
längenangaben oder fehlerprüfsummen...)
1
void rfm_RX(uint8_t *data)
2
  {
3
    rfm_rx_enable(1);    
4
    rfm_writecmd(0xCA81);  //FIFO leeren      
5
    rfm_writecmd(0xCA83);  //FIFO freigeben  
6
    rfm_enable();
7
    
8
    rfm_ready();
9
    spi_master_write_8(0xB0);
10
    *data = spi_master_read(0x00);
11
    rfm_disable();
12
    rfm_enable();
13
    
14
    rfm_ready();
15
    spi_master_write_8(0xB0);
16
    *data = spi_master_read(0x00);
17
    rfm_disable();
18
    rfm_enable();
19
    
20
    rfm_ready();
21
    rfm_rx_enable(0);
22
    blink(LED_rt, 100);
23
  }
1
void spi_master_write_8(uint8_t cmd)
2
  {
3
    SPDR = cmd;
4
    while(!(SPSR & (1<<SPIF)))
5
      ;
6
  }
7
void spi_master_write_16(uint16_t cmd)
8
  {
9
    uint8_t cmd_msb = 0;
10
    uint8_t cmd_lsb = 0;
11
    
12
    cmd_msb = (cmd >> 8) & 0xFF;
13
    cmd_lsb = cmd & 0xFF;
14
    
15
    SPDR = cmd_msb;
16
    while(!(SPSR & (1<<SPIF)))
17
      ;
18
    
19
    SPDR = cmd_lsb;
20
    while(!(SPSR & (1<<SPIF)))
21
      ;
22
  }
23
uint8_t spi_master_read(uint8_t cmd)
24
  {
25
    uint8_t empfang = 0;
26
    
27
    SPDR = cmd;
28
    while(!(SPSR & (1<<SPIF)))
29
      ;
30
    empfang = SPDR;
31
    
32
    return empfang;
33
  }
1
void rfm_writecmd(uint16_t cmd)
2
  {
3
    rfm_enable();    // RFM12 anwählen
4
    spi_master_write_16(cmd);
5
    rfm_disable();  //RFM12 abwählen
6
  }

Höllisch aufpassen muss man dann eben auch noch mit dem chipselect, weil 
dieser maßgeblich am sdo-polling beteiligt ist.
Und fsk beim polling unbedingt auf H-Pegel!

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.