AVR: ENC28J60 Ethernet Multicast

#8000967
Lesenswert?

Hallo, ich arbeite schon länger mit dem enc28j60 Ethernetchip. Soweit problemlos. Nun möchte ich Multicast Pakete empfangen. Leider funktioniert das nicht. Es werden nur Broadcast oder Unicast Pakete empfangen.

Zur Auswertung schicke ich die Daten direkt nach dem Empfang per UART raus.

Den Paketfilter habe ich bereits auf Multicast gesetzt bzw. auch komplett gelöscht. Keine Abweichung.

Paket abholen:

1
unsigned int enc_receive_packet( unsigned int bufsize, unsigned char *buf )
2
  {
3
    unsigned char rxheader[6];
4
    unsigned int len, status;
5
    unsigned char u;
6

7
    // check rx packet counter
8
    u = enc_read_reg( ENC_REG_EPKTCNT );
9
    ENC_DEBUG("enc_receive: EPKTCNT=%i\n", (int) u);
10
    if( u == 0 ) {
11
      // packetcounter is 0, there is nothing to receive, go back
12
      return 0;
13
    }
14

15
    //set read pointer to next packet
16
    enc_write_reg( ENC_REG_ERDPTL, LO8(enc_next_packet_ptr) );
17
    enc_write_reg( ENC_REG_ERDPTH, HI8(enc_next_packet_ptr) );
18

19
    // read enc rx packet header
20
    enc_read_buf( rxheader, sizeof(rxheader) );
21
    enc_next_packet_ptr  =             rxheader[0];
22
    enc_next_packet_ptr |= ((unsigned)(rxheader[1])) << 8;
23
    len                  =             rxheader[2];
24
    len                 |= ((unsigned)(rxheader[3])) << 8;
25
    status               =             rxheader[4];
26
    status              |= ((unsigned)(rxheader[5])) << 8;
27
        
28
        print("IN_STATUS: %4x ", status);
29
        if ((status & 0x0010)) print("| CRC-ERROR ");
30
        if ((status & 0x0020)) print("| LEN-CHECK-ERROR ");
31
        if ((status & 0x0040)) print("| LENGHT Out RANGE ");
32
        if ((status & 0x0080)) print("| RX OK ");
33
        if ((status & 0x0100)) print("| RX MC ");
34
        if ((status & 0x0200)) print("| RX BC" );
35
        if ((status & 0x0800)) print("| RecControlFrame ");
36
        if ((status & 0x2000)) print("| UNKNOWN-OPCODE ");
37
        if ((status & 0x4000)) print("| DECTECT-VLAN ");
38
        print("\r\n");
39
        
40
    // added by Sjors: reset the ENC when needed
41
    // If the receive OK bit is not 1 or the zero bit is not zero, or the packet is larger then the buffer, reset the enc chip and SPI
42
    if ((!(status & (1<<7))) || (status & 0x8000) || (len > bufsize))
43
    {
44
      enc_init();
45
    }
46
    //ENC_DEBUG("enc_receive: status=%4x\n", (unsigned) status);
47

48
    // skip the checksum (4 bytes) at the end of the buffer
49
    len -= 4;
50

51
    // if the application buffer is to small, we just truncate
52
    if( len > bufsize ) len = bufsize;
53

54
    // now read the packet data into buffer
55
    enc_read_buf( buf, len );
56

57
    // adjust the ERXRDPT pointer (= free this packet in rx buffer)
58
    if(    enc_next_packet_ptr-1 > ENC_RX_BUFFER_END
59
    || enc_next_packet_ptr-1 < ENC_RX_BUFFER_START ) {
60
      enc_write_reg( ENC_REG_ERXRDPTL, LO8(ENC_RX_BUFFER_END) );
61
      enc_write_reg( ENC_REG_ERXRDPTH, HI8(ENC_RX_BUFFER_END) );
62
      } else {
63
      enc_write_reg( ENC_REG_ERXRDPTL, LO8(enc_next_packet_ptr-1) );
64
      enc_write_reg( ENC_REG_ERXRDPTH, HI8(enc_next_packet_ptr-1) );
65
    }
66

67
    // trigger a decrement of the rx packet counter
68
    // this will clear PKTIF if EPKTCNT reaches 0
69
    enc_setbits_reg( ENC_REG_ECON2, (1<<ENC_BIT_PKTDEC) );
70

71
    // return number of bytes written to the buffer
72
    ENC_DEBUG("enc_receive: %i bytes\n", len);
73
    return len;
74
  }

Filterregister: enc_setbits_reg( ENC_REG_ERXFCON, 0);

Hab ich etwas übersehen? Muss irgendwo ein Bit im NIC noch gesetzt werden oder hat der Chip ein Problem, dass IGMP z.B. < 61 Bytes ist?

Ich freue mich über jeden Tipp. DANKE!

: Bearbeitet durch User
#8001469
Lesenswert?

Leider nur eine Idee in der anderen Richtung: ist sicher, dass die Pakete überhaupt auf der Leitung sind? Hatte mir für solche kniffligen Fälle extra einen uralten Hub (nicht Switch) organisiert, der den kompletten Traffic auf alle Ports legt, so dass man mit Wireshark sieht was da tatsächlich läuft, wenn zwei nicht so richtig miteinander reden wollen.

: Bearbeitet durch User
#8001543
Lesenswert?

Ich würde das Problem eingrenzen, indem ich einen funktionierenden Frame nehme, und dann Bit für Bit ändere, schicke, schaue, bis er plötzlich nicht mehr ankommt. Mehrfach, um festzustellen, ob immer das gleiche Bit den Ausschlag gibt, oder Zufallseffekte im Spiel sind. Kann mir eigentlich nur vorstellen, dass ein Filter auf die MAC-Adresse noch irgendwo übrig geblieben ist beim Umbauen.

#8001574
Lesenswert?

Kai schrieb:

Multicast wird generell erstmal per Broadcast gesendet

Genau genommen ist die Broadcast-Adresse ff-ff-ff-ff-ff-ff eine spezielle Multicast-Adresse. Mit welcher MAC-Adresse werden die Pakete vom PC gesendet? Bessere Switche geben Multicast erst weiter, nachdem die Empfänger sich per IGMP dafür angemeldet haben. Verbinde PC und ENC28J60 doch mal direkt per Crossover-Kabel.

Kai schrieb:

Filterregister: enc_setbits_reg( ENC_REG_ERXFCON, 0);

Damit aktiviert man den Promiscuous-Mode, damit müssen alle Pakete empfangen werden.

#8001576
Lesenswert?

Was macht denn die Funktion enc_setbits_reg() genau, setzt/löscht sie einzelne Bits oder schreibt sie das Byte ins Register?

Ich hatte vor einer Weile einen ENC28J60 mit einem STM32 verwendet und da hat der Multicastempfang soweit ich mich erinnere funktioniert. Bei mir war nur das "CRCEN" Bit im ERXFCON Register gesetzt.

Eventuell auch mal das ERXFCON Register zurücklesen und schauen was dort tatsächlich steht.

#8001674
Lesenswert?

Ich habe noch mal kurz das Code-Fragment des TO angeschaut, es gibt dort enc_write_reg() und enc_setbits_reg(). Dann wird wohl enc_setbits_reg() einzelne Bits im Register setzen und der Aufruf "enc_setbits_reg(ENC_REG_ERXFCON, 0)" müsste dann vermutlich "enc_write_reg(ENC_REG_ERXFCON, 0)" sein damit es das gewünschte macht.

#8001743
Lesenswert?

Uwe schrieb:

Ich würde das Problem eingrenzen, indem ich einen funktionierenden Frame nehme, und dann Bit für Bit ändere, schicke, schaue, bis er plötzlich nicht mehr ankommt. Mehrfach, um festzustellen, ob immer das gleiche Bit den Ausschlag gibt, oder Zufallseffekte im Spiel sind. Kann mir eigentlich nur vorstellen, dass ein Filter auf die MAC-Adresse noch irgendwo übrig geblieben ist beim Umbauen.

Das wäre eine aufwendige aber sehr detaillierte Idee um das Problem einzugrenzen. Danke für den Tipp. Werde ich vermutlich so machen müssen.

Mario M. schrieb:

Genau genommen ist die Broadcast-Adresse ff-ff-ff-ff-ff-ff eine spezielle Multicast-Adresse. Mit welcher MAC-Adresse werden die Pakete vom PC gesendet? Bessere Switche geben Multicast erst weiter, nachdem die Empfänger sich per IGMP dafür angemeldet haben.

Korrekt, wenn Multicast Snooping deaktiviert ist sendet der Switch es als Broadcast, also auf allen Ports. Der AVR meldet sich über den NIC bereits für die passende Gruppe an. Zudem habe ich kontrolliert, dass die Paket auch wirklich aus dem Port kommen. Das ist zumindest sichergestellt. Aktuell bezieht sich das Problem nur auf dem Empfang der MC Paket zwischen Switchport Ausgang und AVR SPI Eingang. Also auf den ENC28J60. Da liegt im Moment das Problem.

Dieter S. schrieb:

Was macht denn die Funktion enc_setbits_reg() genau, setzt/löscht sie einzelne Bits oder schreibt sie das Byte ins Register?

Tatsächlich ist es die falsche Funktion, es muss heißen: enc_write_reg(); //damit wird das komplette Byte geschrieben. Werde ich testen.

Mario M. schrieb:

Stimmt. Mir war entgangen, dass da nur das Broadcast-Bit gesetzt wird. Sonst würde ja nur Broadcast erlaubt. Für Multicast müsste Bit 1 (MCEN) gesetzt sein.

Nicht ganz korrekt: Wird der Filter aktiviert, müssen mehrere Bits gesetzt werden, oder halt keine, wenn der Filter aus sein soll.

Danke erstmal für die ganzen Tipps. Ich schau mir das jetzt im Detail nochmal an.

#8001988
Lesenswert?

Der Teufel steck meist im Detail: Das Problem lag tatsächlich am Filter: Beim Einsetzen der Funktion, habe ich write BIT mit write BYTE vertauscht. Kleiner Unterschied, große Wirkung! Das war der entscheidene Tipp!

Dann bleibt nur zu hoffen, dass Anderen dieses Thread nutzt, wenn sie ein ähnliches Problem mit dem Empfang von Paketen haben.

VIELEN DANK!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren