www.mikrocontroller.net

Forum: HF, Funk und Felder CC2420 sendet keine Daten


Autor: d-roehrig (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
while((PINE & (1<<CC_FIFOP)) || (PIND & (1<<CC_SFD)));

PORTB &= ~(1<<PB4) & ~(1<<PB5);  //LED's aus

SPI_TxReg(0x3e, 0x0a20);         // SPI_TxReg schreibt ins TXFIFO
SPI_TxReg(0x3e, 0x2200);
SPI_TxReg(0x3e, 0x0002);
SPI_TxReg(0x3e, 0x0001);
SPI_TxReg(0x3e, 0x12);

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:
void CC2420_Init(void)
{
  uint16_t MANAND_reg;

  // Ein- und Ausgänge definieren
  DDRD &= ~(1<<CC_SFD) & ~(1<<CC_CCA);    
  DDRE &= ~(1<<CC_FIFO) & ~(1<<CC_FIFOP);
  
  // CC2420 einschalten
  PORTB |= (1<<CC_VREG_EN);
  _delay_us(600);              // VREG_EN start up time

  // CC2420 Reset
  PORTB |= (1<<CC_RESET);

  PORTB &= ~(1<<DD_CS);        // CS\ low
  SPI_TxRx(0x01);              // SXOSCON
  PORTB |= (1<<DD_CS);         // CS\ high
  _delay_ms(1);                // SXOSCON start up time

  // XOSC16M_PD + BIAS_PD = 0 für Crystal Oscillator (Command Strobe 0x01)
  MANAND_reg = SPI_RxReg(0x61);
  MANAND_reg &= ~(0x4080);
  SPI_TxReg(0x11, MANAND_reg);

  setKanal();
  setShortAddress(0x0001);
  
  // Command Strobe
  PORTB &= ~(1<<DD_CS);             // CS\ low
  SPI_TxRx(0x04);                   // STXON
  SPI_TxRx(0x03);                   // SRXON
  PORTB |= (1<<DD_CS);              // CS\ high
}

Ich hoffe ihr habt eine Idee.

Grüße,
Dennis

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Einfach mal die AN033 von TI anschauen: 
http://focus.ti.com/mcu/docs/mcusupporttechdocsc.t... 
ist doch super kommentiert und klappt auf jeden Fall.

Autor: d-roehrig (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: d-roehrig (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: d-roehrig (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <avr/io.h>

#define F_CPU 8388608

#include <util/delay.h>

#define BAUD 9600
#define MYUBRR (F_CPU/16/BAUD-1)

#define DD_CS PB0        //Selektiert den Master
#define DD_SCK PB1       //Takt
#define DD_MOSI PB2      //Master Out, Slave In
#define DD_MISO PB3      //Master In, Slave Out

#define CC_FIFO PE5
#define CC_FIFOP PE6
#define CC_CCA PD5       //Clear Channel Assessment
#define CC_SFD PD4       //Start of Frame Delimiter
#define CC_RESET PB6     //Reset
#define CC_VREG_EN PB7   //VREG Enable

void SPI_Init(void)
{  
  // MOSI, SCK, CS, RESET ausgang, MISO eingang
  DDRB = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_CS)|(1<<CC_RESET)|(1<<CC_VREG_EN);

  // Master, aktiviere SPI, fck/4, MSB first, SPI mode
  SPCR = (1<<MSTR)|(1<<SPE)|(1<<CPHA);
}

uint8_t SPI_TxRx(uint8_t cData)
{
  SPDR = cData;
  while(!(SPSR & (1<<SPIF)));
  return SPDR;
}

uint16_t SPI_RxReg(uint8_t Address)
{
  uint8_t state;
  uint16_t data;
  Address = Address | 0x40;

  PORTB &= ~(1<<DD_CS);             // CS\ low

  _delay_us(25);          

  state = SPI_TxRx(Address);        // eventuell den Status auswerten
  data = SPI_TxRx(0xff)<<8;         // MSB
  data = data + SPI_TxRx(0xff);     // LSB

  PORTB |= (1<<DD_CS);              // CS\ high
  return data;
}

uint8_t SPI_TxReg(uint8_t Address, uint16_t data)
{
  uint8_t state;

  PORTB &= ~(1<<DD_CS);             // CS\ low
  
  _delay_us(25);          
  
  state = SPI_TxRx(Address);        // eventuell den Status auswerten
  SPI_TxRx(data>>8);                // MSB
  SPI_TxRx(data);                   // LSB

  PORTB |= (1<<DD_CS);              // CS\ high

  return state;
}

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
}

void setKanal()
{
  uint16_t FSCTRL_reg;
  uint16_t FSCTRL_kanal;

  FSCTRL_kanal = 357 + 5 * (26-11);
  FSCTRL_reg = (SPI_RxReg(0x18) & 0xfc00) | FSCTRL_kanal;

  SPI_TxReg(0x18, FSCTRL_reg);
}

void setShortAddress(uint16_t addr)
{
  SPI_TxRam(0x016a, addr);
}

void CC2420_Init(void)
{
  uint8_t oscStatus;
  uint16_t MANAND_reg;

  // Ein- und Ausgänge definieren
  DDRD &= ~(1<<CC_SFD) & ~(1<<CC_CCA);    
  DDRE &= ~(1<<CC_FIFO) & ~(1<<CC_FIFOP);
  
  // CC2420 einschalten
  PORTB |= (1<<CC_VREG_EN);
  _delay_us(600);                   // VREG_EN start up time

  // CC2420 Reset
  PORTB |= (1<<CC_RESET);

  PORTB &= ~(1<<DD_CS);             // CS\ low
  SPI_TxRx(0x01);                   // SXOSCON
  PORTB |= (1<<DD_CS);              // CS\ high
  _delay_ms(1);                     // SXOSCON start up time

  // XOSC16M_PD + BIAS_PD = 0 für Crystal Oscillator (Command Strobe 0x01)
  MANAND_reg = SPI_RxReg(0x21);
  MANAND_reg &= ~(0x4080);
  oscStatus = SPI_TxReg(0x21, MANAND_reg);

  while(!(oscStatus && 0x40));      // Warte bis Crystal Oscillator stable

  setKanal();
  setShortAddress(0x0001);
  
  // Command Strobe
  PORTB &= ~(1<<DD_CS);             // CS\ low
  SPI_TxRx(0x04);                   // STXON
  SPI_TxRx(0x03);                   // SRXON
  PORTB |= (1<<DD_CS);              // CS\ high
}

int main(void)
{
  USART_Init(MYUBRR);
  SPI_Init();
  CC2420_Init();

  _delay_ms(1000);

  while(1) {
    while((PINE & (1<<CC_FIFOP)) || (PIND & (1<<CC_SFD)));

    PORTB &= ~(1<<PB4) & ~(1<<PB5);   //LED's aus

    // Command Strobe
    PORTB &= ~(1<<DD_CS);             // CS\ low
    SPI_TxRx(0x09);                   // SFLUSHTX
    PORTB |= (1<<DD_CS);              // CS\ high

    SPI_TxReg(0x3e, 0x0b20);
    SPI_TxReg(0x3e, 0x2200);
    SPI_TxReg(0x3e, 0x0002);
    SPI_TxReg(0x3e, 0x0001);
    SPI_TxReg(0x3e, 0x1234);
    
    while ((PIND & (1<<CC_SFD)));

    _delay_ms(250);

    PORTB |= (1<<PB4)|(1<<PB5);       //LED's an
    _delay_ms(250);
  }
  return 0;
}

Grüße
Dennis

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.