enc28j60 spi Byteverschiebung

Gast #3937880
Lesenswert?
• ▲
▼
frohe weihnachten!

ich versuche den enc28j60 mittels U-Radig_SW an einen M328 
anzuschließen. Problem:

statt
FF.FF.FF.FF.FF.FF.00.1C.BF.A5.DD.91.
sieht der Anfang des EthernetHeaders so aus:
FF.FF.FF.FF.FF.00.1C.BF.A5.DD.91.08

Ich habe das Problem auf den spi-Aufruf eingegrenzt. Im EncRegister 
stehen die korrekten Werte. bei Aufruf von spi_get() wird der erste Wert 
übersprungen:
1
static inline void xspi_put( unsigned char value )
2
{
3
  //ENC_DEBUG("spi_put(%2x)\n", (unsigned) value );
4
  SPDR = value;
5
  while( !(SPSR & (1<<SPIF)) ) ;
6
}
7

8
static inline unsigned char xspi_get(void)
9
{
10
  unsigned char value = SPDR;
11
  //ENC_DEBUG("spi_get()=%2x\n", (unsigned) value );
12
  return value;
13
}
14

15

16
static void enc_read_buf( unsigned char *buf, unsigned int len )
17
{
18
  enc_select();
19
  spi_put( ENC_SPI_OP_RBM );
20
//if(len > 0){len--; buf++ ;*(buf) = xspi_get();}
21
  for(; len > 0; len--, buf++ ) {
22
    xspi_put( 0x00 );
23
    *(buf) = xspi_get();
24
  }
25
  enc_deselect();
26
}
27

28

29

30
unsigned int enc_receive_packet( unsigned int bufsize, unsigned char *buf )
31
{
32
  unsigned char rxheader[18];
33
  unsigned int len, status;
34
  unsigned char u;
35

36
  // check rx packet counter
37
  u = enc_read_reg( ENC_REG_EPKTCNT );
38
  ENC_DEBUG("enc_receive: EPKTCNT=%i\n", (int) u);
39
  if( u == 0 ) {
40
    // packetcounter is 0, there is nothing to receive, go back
41
    return 0;
42
  }
43

44
  //set read pointer to next packet
45
  enc_write_reg( ENC_REG_ERDPTL, LO8(enc_next_packet_ptr) );
46
  enc_write_reg( ENC_REG_ERDPTH, HI8(enc_next_packet_ptr) );
47

48
  // read enc rx packet header
49
  enc_read_buf( rxheader, 6 );
50
  enc_next_packet_ptr  =             rxheader[0];
51
  enc_next_packet_ptr |= ((unsigned)(rxheader[1])) << 8;
52
  len                  =             rxheader[2];
53
  len                 |= ((unsigned)(rxheader[3])) << 8;
54
  status               =             rxheader[4];
55
  status              |= ((unsigned)(rxheader[5])) << 8;
56

57
//kk
58
ePtr=enc_next_packet_ptr;
59
eLen=len;
60
eStatus=status;
61

62
/*
63
//kk
64
  //kein Fehler:
65
  for(i=6;i<12;i++){
66
  tmp_macd[i-6]=rxheader[i];
67
  }
68

69
  for(i=12;i<18;i++){
70
  tmp_macs[i-12]=rxheader[i];
71
  }
72

73
  
74
  //Fehler:
75
  enc_read_buf( tmp_macd, 6 );//1.byte wird ausgelassen
76
  enc_read_buf( tmp_macs, 6 );//1.byte wird ausgelassen
77
*/
78
  // added by Sjors: reset the ENC when needed
79
  // 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
80
  if ((!(status & (1<<7))) || (status & 0x8000) || (len > bufsize))
81
  { 
82
    enc_init();
83
  }
84
  //ENC_DEBUG("enc_receive: status=%4x\n", (unsigned) status);
85

86
  // skip the checksum (4 bytes) at the end of the buffer
87
  len -= 4;
88

89
  // if the application buffer is to small, we just truncate
90
  if( len > bufsize ) len = bufsize;
91

92
  // now read the packet data into buffer
93
  enc_read_buf( buf, len );//1.byte wird ausgelassen
94

95

96

97
  // adjust the ERXRDPT pointer (= free this packet in rx buffer)
98
  if(    enc_next_packet_ptr-1 > ENC_RX_BUFFER_END
99
      || enc_next_packet_ptr-1 < ENC_RX_BUFFER_START ) {
100
    enc_write_reg( ENC_REG_ERXRDPTL, LO8(ENC_RX_BUFFER_END) );
101
    enc_write_reg( ENC_REG_ERXRDPTH, HI8(ENC_RX_BUFFER_END) );
102
  } else {
103
    enc_write_reg( ENC_REG_ERXRDPTL, LO8(enc_next_packet_ptr-1) );
104
    enc_write_reg( ENC_REG_ERXRDPTH, HI8(enc_next_packet_ptr-1) );
105
  }
106

107
  // trigger a decrement of the rx packet counter
108
  // this will clear PKTIF if EPKTCNT reaches 0
109
  enc_setbits_reg( ENC_REG_ECON2, (1<<ENC_BIT_PKTDEC) );
110

111
  // return number of bytes written to the buffer
112
  ENC_DEBUG("enc_receive: %i bytes\n", len);
113
  return len;
114
}

Ich habe versucht, das erste dem spi_get() vorausgehende spi_put() zu 
unterdrücken. dann kommt nur Unsinn.


Da es sich um ein bewährtes Standardprogramm mit einem Standardchip 
handelt, stehe ich vor einem Rätsel. Bin für jede Hilfe dankbar.
Gast #3937983
Lesenswert?
• ▲
▼
heureca
ich habe geändert:
1
static void enc_read_buf( unsigned char *buf, unsigned int len )
2
{
3
  enc_select();
4
  spi_put( ENC_SPI_OP_RBM );
5
//if(len > 0){len--; buf++ ;*(buf) = xspi_get();}
6
  for(; len > 0; len--, buf++ ) {
7
    spi_put( 0x00 );
8
    *(buf) = spi_get();
9
  }
10
  enc_deselect();
11
}
12
static void xenc_read_buf( unsigned char *buf, unsigned int len )
13
{
14
  enc_select();
15
//  spi_put( ENC_SPI_OP_RBM );
16
//if(len > 0){len--; buf++ ;*(buf) = xspi_get();}
17
  for(; len > 0; len--, buf++ ) {
18
    spi_put( ENC_SPI_OP_RBM );
19
    *(buf) = spi_get();
20
  }
21
  enc_deselect();
22
}
23

24

25
unsigned int enc_receive_packet( unsigned int bufsize, unsigned char *buf )
26
{
27
...
28

29
  // read enc rx packet header
30
  enc_read_buf( rxheader, 6 );
31
...
32
  // now read the packet data into buffer
33
  xenc_read_buf( buf, len );//1.byte wird ausgelassen
34
...

beim 2. Aufruf von enc_read_buf() ist spi_put( ENC_SPI_OP_RBM ); ein 
spi_put zuviel, da der buffer hierdurch um ein byte weitergelesen wird. 
Eigentlich logisch. Mit der geänderten xenc_read_buf() kommt jetzt das 
Ping. Alles funktioniert wie es soll.

Was ich jetzt nicht verstehe ist, wie die Original-U-Radig Funktion 
trotz diesem einmal zuviel spi_put funktionieren kann. Ich selbst habe 
das Original schon zigmal verwendet. Jetzt auf einmal geht es nicht 
mehr.





Was ich

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.