Forum: HF, Funk und Felder CC2420 sendet keine Daten


von d-roehrig (Gast)


Lesenswert?

Hallo,

ich habe ein kleines Problem! Ich habe einen ATMega128 und einen CC2420 
über SPI verbunden. Jedoch kann ich mit dem CC2420 noch nichts senden. 
Dazu ein paar Fragen:

1. Muss ich die Felder der MPDU selber ins TX Fifo schreiben? Bisher 
habe ich noch nichts gefunden wo ich sonst die Empfängeradresse 
einstellen kann.

so ca:
1
while((PINE & (1<<CC_FIFOP)) || (PIND & (1<<CC_SFD)));
2
3
PORTB &= ~(1<<PB4) & ~(1<<PB5);  //LED's aus
4
5
SPI_TxReg(0x3e, 0x0a20);         // SPI_TxReg schreibt ins TXFIFO
6
SPI_TxReg(0x3e, 0x2200);
7
SPI_TxReg(0x3e, 0x0002);
8
SPI_TxReg(0x3e, 0x0001);
9
SPI_TxReg(0x3e, 0x12);
10
11
while (!(PIND & (1<<CC_SFD)));   //Hier sitzt er immer fest!

2. Welche Einstellungen muss ich noch bei der Initialisierung vornehmen, 
wenn ich es bisher so habe:
1
void CC2420_Init(void)
2
{
3
  uint16_t MANAND_reg;
4
5
  // Ein- und Ausgänge definieren
6
  DDRD &= ~(1<<CC_SFD) & ~(1<<CC_CCA);    
7
  DDRE &= ~(1<<CC_FIFO) & ~(1<<CC_FIFOP);
8
  
9
  // CC2420 einschalten
10
  PORTB |= (1<<CC_VREG_EN);
11
  _delay_us(600);              // VREG_EN start up time
12
13
  // CC2420 Reset
14
  PORTB |= (1<<CC_RESET);
15
16
  PORTB &= ~(1<<DD_CS);        // CS\ low
17
  SPI_TxRx(0x01);              // SXOSCON
18
  PORTB |= (1<<DD_CS);         // CS\ high
19
  _delay_ms(1);                // SXOSCON start up time
20
21
  // XOSC16M_PD + BIAS_PD = 0 für Crystal Oscillator (Command Strobe 0x01)
22
  MANAND_reg = SPI_RxReg(0x61);
23
  MANAND_reg &= ~(0x4080);
24
  SPI_TxReg(0x11, MANAND_reg);
25
26
  setKanal();
27
  setShortAddress(0x0001);
28
  
29
  // Command Strobe
30
  PORTB &= ~(1<<DD_CS);             // CS\ low
31
  SPI_TxRx(0x04);                   // STXON
32
  SPI_TxRx(0x03);                   // SRXON
33
  PORTB |= (1<<DD_CS);              // CS\ high
34
}

Ich hoffe ihr habt eine Idee.

Grüße,
Dennis

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


Lesenswert?

d-roehrig wrote:

> 1. Muss ich die Felder der MPDU selber ins TX Fifo schreiben?

Wenn du etwas senden willst: ja.

Zum Empfangen: nein.

> Bisher
> habe ich noch nichts gefunden wo ich sonst die Empfängeradresse
> einstellen kann.

Gibt's irgendwo einen Speicherbereich (oberhalb des FIFOs, wenn
ich mich recht entsinne -- ist paar Jahre her, dass ich den CC2420
das letzte Mal in den Fingern hatte).

Das Adressfilter kann man aber auch ausschalten, dann empfängt er
halt jeden Rahmen.

> SPI_TxReg(0x3e, 0x0a20);         // SPI_TxReg schreibt ins TXFIFO

Da das Protokoll byteorientiert ist, ist ein 16-bittiger Zugriff
auf den FIFO recht irreführend.

> 2. Welche Einstellungen muss ich noch bei der Initialisierung vornehmen,
> wenn ich es bisher so habe:

Da gibt's doch irgendwo Beispielcode von Chipc^H^H^H^H^HTI, oder?

von Christian R. (supachris)


Lesenswert?

Einfach mal die AN033 von TI anschauen: 
http://focus.ti.com/mcu/docs/mcusupporttechdocsc.tsp?sectionId=96&tabId=1502&abstractName=swra059a 
ist doch super kommentiert und klappt auf jeden Fall.

von d-roehrig (Gast)


Lesenswert?

Hey, danke für eure Antwort. Das mit dem AppNote hat mir bisher nicht 
weiter geholfen. Angeguckt hab ich mir das vorher schon...

Kann vielleicht die PLL schuld sein. Im Status Bit ist sie nämlich nicht 
Locked.

Grüße

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


Lesenswert?

d-roehrig wrote:
> Im Status Bit ist sie nämlich nicht
> Locked.

Das muss sie auf jeden Fall sein, damit sich dort irgendwas tut.

von d-roehrig (Gast)


Lesenswert?

Das betrifft aber nur das Senden, oder? Der Empfang läuft nämlich mit 
einem ähnlichen Code. Habe zum Schluss aber das Status byte nicht mehr 
kontrolliert.

Wie kommt es denn dazu, dass das PLL bit nicht auf locked steht?

Grüße,
Dennis

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


Lesenswert?

d-roehrig wrote:
> Das betrifft aber nur das Senden, oder?

Nein, die PLL wird auch für den Empfang gebraucht (nur auf einer
geringfügig anderen Frequenz).

> Wie kommt es denn dazu, dass das PLL bit nicht auf locked steht?

Da wird wohl was mit dem Einschalten nicht hinhauen, oder du wartest
nicht, bis sich die Frequenz ausreichend stabilisiert hat.

von d-roehrig (Gast)


Lesenswert?

Ich habs geschafft :D jetzt bekomme ich 0x66 als Status Byte. Jedoch 
sagt er das ich einen TX underflow verursache. Den habe ich anschließend 
mit SFLUSTX beseitigt. Jedoch bekomme ich immer noch keine Daten. Ich 
schicke dir einfach mal den Code. Vielleicht siehst du noch einen 
Fehler:
1
#include <avr/io.h>
2
3
#define F_CPU 8388608
4
5
#include <util/delay.h>
6
7
#define BAUD 9600
8
#define MYUBRR (F_CPU/16/BAUD-1)
9
10
#define DD_CS PB0        //Selektiert den Master
11
#define DD_SCK PB1       //Takt
12
#define DD_MOSI PB2      //Master Out, Slave In
13
#define DD_MISO PB3      //Master In, Slave Out
14
15
#define CC_FIFO PE5
16
#define CC_FIFOP PE6
17
#define CC_CCA PD5       //Clear Channel Assessment
18
#define CC_SFD PD4       //Start of Frame Delimiter
19
#define CC_RESET PB6     //Reset
20
#define CC_VREG_EN PB7   //VREG Enable
21
22
void SPI_Init(void)
23
{  
24
  // MOSI, SCK, CS, RESET ausgang, MISO eingang
25
  DDRB = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_CS)|(1<<CC_RESET)|(1<<CC_VREG_EN);
26
27
  // Master, aktiviere SPI, fck/4, MSB first, SPI mode
28
  SPCR = (1<<MSTR)|(1<<SPE)|(1<<CPHA);
29
}
30
31
uint8_t SPI_TxRx(uint8_t cData)
32
{
33
  SPDR = cData;
34
  while(!(SPSR & (1<<SPIF)));
35
  return SPDR;
36
}
37
38
uint16_t SPI_RxReg(uint8_t Address)
39
{
40
  uint8_t state;
41
  uint16_t data;
42
  Address = Address | 0x40;
43
44
  PORTB &= ~(1<<DD_CS);             // CS\ low
45
46
  _delay_us(25);          
47
48
  state = SPI_TxRx(Address);        // eventuell den Status auswerten
49
  data = SPI_TxRx(0xff)<<8;         // MSB
50
  data = data + SPI_TxRx(0xff);     // LSB
51
52
  PORTB |= (1<<DD_CS);              // CS\ high
53
  return data;
54
}
55
56
uint8_t SPI_TxReg(uint8_t Address, uint16_t data)
57
{
58
  uint8_t state;
59
60
  PORTB &= ~(1<<DD_CS);             // CS\ low
61
  
62
  _delay_us(25);          
63
  
64
  state = SPI_TxRx(Address);        // eventuell den Status auswerten
65
  SPI_TxRx(data>>8);                // MSB
66
  SPI_TxRx(data);                   // LSB
67
68
  PORTB |= (1<<DD_CS);              // CS\ high
69
70
  return state;
71
}
72
73
void SPI_TxRam(uint16_t Address, uint16_t data)
74
{
75
  uint8_t status;
76
  Address = (Address<<6) | 0x8000;
77
78
  PORTB &= ~(1<<DD_CS);             // CS\ low
79
  
80
  _delay_us(25);          
81
  status = SPI_TxRx((uint8_t)(Address>>8));
82
83
  _delay_us(25);
84
  SPI_TxRx((uint8_t)(Address & 0x00ff));
85
  SPI_TxRx((uint8_t)(data>>8));
86
  SPI_TxRx((uint8_t)(data & 0x00ff));
87
 
88
  PORTB |= (1<<DD_CS);              // CS\ high
89
}
90
91
void setKanal()
92
{
93
  uint16_t FSCTRL_reg;
94
  uint16_t FSCTRL_kanal;
95
96
  FSCTRL_kanal = 357 + 5 * (26-11);
97
  FSCTRL_reg = (SPI_RxReg(0x18) & 0xfc00) | FSCTRL_kanal;
98
99
  SPI_TxReg(0x18, FSCTRL_reg);
100
}
101
102
void setShortAddress(uint16_t addr)
103
{
104
  SPI_TxRam(0x016a, addr);
105
}
106
107
void CC2420_Init(void)
108
{
109
  uint8_t oscStatus;
110
  uint16_t MANAND_reg;
111
112
  // Ein- und Ausgänge definieren
113
  DDRD &= ~(1<<CC_SFD) & ~(1<<CC_CCA);    
114
  DDRE &= ~(1<<CC_FIFO) & ~(1<<CC_FIFOP);
115
  
116
  // CC2420 einschalten
117
  PORTB |= (1<<CC_VREG_EN);
118
  _delay_us(600);                   // VREG_EN start up time
119
120
  // CC2420 Reset
121
  PORTB |= (1<<CC_RESET);
122
123
  PORTB &= ~(1<<DD_CS);             // CS\ low
124
  SPI_TxRx(0x01);                   // SXOSCON
125
  PORTB |= (1<<DD_CS);              // CS\ high
126
  _delay_ms(1);                     // SXOSCON start up time
127
128
  // XOSC16M_PD + BIAS_PD = 0 für Crystal Oscillator (Command Strobe 0x01)
129
  MANAND_reg = SPI_RxReg(0x21);
130
  MANAND_reg &= ~(0x4080);
131
  oscStatus = SPI_TxReg(0x21, MANAND_reg);
132
133
  while(!(oscStatus && 0x40));      // Warte bis Crystal Oscillator stable
134
135
  setKanal();
136
  setShortAddress(0x0001);
137
  
138
  // Command Strobe
139
  PORTB &= ~(1<<DD_CS);             // CS\ low
140
  SPI_TxRx(0x04);                   // STXON
141
  SPI_TxRx(0x03);                   // SRXON
142
  PORTB |= (1<<DD_CS);              // CS\ high
143
}
144
145
int main(void)
146
{
147
  USART_Init(MYUBRR);
148
  SPI_Init();
149
  CC2420_Init();
150
151
  _delay_ms(1000);
152
153
  while(1) {
154
    while((PINE & (1<<CC_FIFOP)) || (PIND & (1<<CC_SFD)));
155
156
    PORTB &= ~(1<<PB4) & ~(1<<PB5);   //LED's aus
157
158
    // Command Strobe
159
    PORTB &= ~(1<<DD_CS);             // CS\ low
160
    SPI_TxRx(0x09);                   // SFLUSHTX
161
    PORTB |= (1<<DD_CS);              // CS\ high
162
163
    SPI_TxReg(0x3e, 0x0b20);
164
    SPI_TxReg(0x3e, 0x2200);
165
    SPI_TxReg(0x3e, 0x0002);
166
    SPI_TxReg(0x3e, 0x0001);
167
    SPI_TxReg(0x3e, 0x1234);
168
    
169
    while ((PIND & (1<<CC_SFD)));
170
171
    _delay_ms(250);
172
173
    PORTB |= (1<<PB4)|(1<<PB5);       //LED's an
174
    _delay_ms(250);
175
  }
176
  return 0;
177
}

Grüße
Dennis

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


Lesenswert?

d-roehrig wrote:

Vorab: bitte lies dir das Datenblatt des CC2420 von vorn bis hinten
durch.  Mir scheint, du hast daran einiges noch nicht verstanden.
Bitte fang nicht an, Code zu schreiben, bevor deine Fragen geklärt
sind.  Das hat keinen Sinn.

> Ich habs geschafft :D jetzt bekomme ich 0x66 als Status Byte. Jedoch
> sagt er das ich einen TX underflow verursache. Den habe ich anschließend
> mit SFLUSTX beseitigt.

Du hast also die Wirkung beseitigt, statt nach der Ursache zu
forschen...

> Jedoch bekomme ich immer noch keine Daten.

Was hast du denn als Sniffer dran?  Zeigt dein Sniffer auch
x-beliebige Daten an, die bspw. kaputte CRC haben?

> void SPI_TxRam(uint16_t Address, uint16_t data)
> {
>   uint8_t status;
>   Address = (Address<<6) | 0x8000;
>
>   PORTB &= ~(1<<DD_CS);             // CS\ low
>
>   _delay_us(25);
>   status = SPI_TxRx((uint8_t)(Address>>8));
>
>   _delay_us(25);
>   SPI_TxRx((uint8_t)(Address & 0x00ff));
>   SPI_TxRx((uint8_t)(data>>8));
>   SPI_TxRx((uint8_t)(data & 0x00ff));
>
>   PORTB |= (1<<DD_CS);              // CS\ high
> }

Das schreibt genau 2 Bytes in den SRAM.  Sowas ist nur sinnvoll
für die Adress-Konfiguration, aber normalerweise kann man den
SRAM in beliebigen Teilstücken beschreiben und lesen.

>   SPI_TxRx(0x04);                   // STXON

Wo schreibst du denn hier jemals einen Frame in den FIFO?

>   SPI_TxRx(0x03);                   // SRXON

Was soll das?  Du bist doch gerade beim Senden eines Frames.
Was soll der Empfänger hier?  Hab' jetzt nicht nachgeguckt, wie
der CC2420 darauf reagiert: entweder wird der das SRXON ignorieren,
weil er gerade bei Senden ist, oder er bricht die aktuelle
Übertragung ab und geht auf Empfang.  Ist beides wohl eher nicht,
was du willst.

von Christian R. (supachris)


Lesenswert?

Ich verstehe nicht, wieso du soviel rumrätselst. Nimm doch den Code aus 
der Appnote als Ausgangspunkt und da kannst du immer noch die 
SPI-Funktionen durch deine eigenen ersetzen. Klar hast du einen 
FIFO-Underrun, wenn du senden willst, aber vorher nix in den TX-FIFO 
geschrieben hast. Übrigens muss man erst den CC2420 in den RX-Modus 
bringen, um was senden zu können.

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.