Forum: Mikrocontroller und Digitale Elektronik SPI, Breakpoint, CC2500


von Maddin (Gast)


Lesenswert?

Hallo. Ich verwende das Tool EZ430-RT2500. Also MSP an CC2500.

Ich hab mich in Slaa325 eingearbeitet. Dieses enthält eine einfache Doku 
über den CC2500 und den MSP. Ich habe also den Quelltext angepasst, und 
führe irgendwann folgendes aus:
1
TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG2,  0x73);
Der Inhalt spielt erstmal keine Rolle. Ich schreibe in ein Register des 
CC2500 den Wert 0x73. Anschließend will ich das überprüfen mit:
1
TI_CC_SPIReadReg(TI_CCxxx0_MDMCFG2);
Diese Funktion sollte als Ergebnis den Inhalt des übergebenen Registers 
liefern. Nur tut es dies nur wenn ich vorher einen Breakpoint setze und 
die Funktion langsam durchsteppe. Ich sehe dann dass die interne 
Variable x den Wert 0x73 hat.
Aber wenn ich das Programm normal durchlaufen lasse erhält diese 
Variable bzw. der Rückgabewert den Wert 0x00.

Warum ist das so?

Ich arbeite mit IAR 4.21

Bitte um Hilfe

von Stefan B. (Gast)


Lesenswert?

Was steht im Datenblatt zum Timing? Hast du bereits mit einer 
Wartefunktion zwischen der Write- und der Readfunktion experimentiert?

von Maddin (Gast)


Lesenswert?

Hm Datenblatt werde ich mir noch genauer anschauen. Ist einfach zu 
komplex. Habe mal mit Wartezeit probert. Ob kurz oder lang. Es 
funktioniert nur wenn ich per Breakpoints durch die Funktion steppe. 
Finde ich doch sehr verwunderlich.
Über jegliche Hilfe wäre ich sehr dankbar. Auch über Tipps oder 
ähnliches was man beim ersten Umgang mit dem CC2500 beachten sollte.

von B. U. (arm-ee)


Lesenswert?

hallo,

ich bin auch seit gesteren dabei dieses kit zum laufen zu bringen, steht 
seit einem jahr auf dem schreibtisch :)

hab nun i2c zum laufen gebracht und werde jetzt das funkteil anschauen.
wäre cool wenn wir erfahrungen austauschen könnten!

von Frederik G. (fred_g)


Lesenswert?

Hallo,

ich habe mir das AMB2500 Modul von Amber besorgt. Dieses hat auch den 
cc2500 on board. Möchte gerne das Modul mit einem Mega88 via SPI 
ansteuern.
Habe heute damit begonnen mich in das Datenblatt einzulesen. Wenn ich 
die ersten "gehversuche" mache, werde ich das mal hier posten man kann 
sich sicher gegenseitig helfen.

von Martin (Gast)


Lesenswert?

Hallo B.U.,

ich hab Probleme mit diesem sch**ß I2C. Ich weiß nicht recht was ich tun 
soll um einfach nur ein Datenbyte zu senden? Wenn ich StartCondition 
sende, wird dann automatisch das erste Byte also die Slave adresse 
gesendet oder muss ich das manuell machen? Muss ich die Interrupts 
beachten oder kann ich einfach gnadenlos den Bus zu senden. Das wär mir 
für den Anfang erstmal lieber, dann seh ich zumindestens was aufm Oszi.

von Martin (Gast)


Lesenswert?

Kann mir jemand Helfen?
Ich führe nach Initialisierung folgenden Code aus:
1
UCB0CTL1  |= UCTR;            
2
UCB0CTL1  |= UCTXSTT;
3
UCB0TXBUF = 0x5A;  
4
while((UCB0IFG &0x02) == 0);          ///<< Wait till Send finished

Die Slaveadresse wird gesendet Jedoch die 0x5A werden nicht gesendet. 
das IFG wird auch nicht gesetzt, egal ob ich das GIE oder TX Interrupt 
enable Bit setze oder nicht.
Jedenfalls macht das I2c-Modul nichts anderes als die Slaveadresse 
senden. Hab ich was wichtiges vergessen? Init ist aus Ti-Beispielen, 
natürlich angepasst.

von Frederik G. (fred_g)


Lesenswert?

Hallo Martin,

eigentlich müsstest du doch SPI verwenden und nicht I²C.?

von Martin (Gast)


Lesenswert?

aah.. ja klar. Da hab ich wieder meine projekte durcheinander gehauen.

SPI natürlich. Bleibt jedoch mein Problem von ganz oben. Ich bekomme 
immer null. Neben den normalen Buffer Wartezeiten vom MSP sind meiner 
Meinung nach keine vorgesehen (also vom CC2500). Ich bekomme jedoch 
immer nur 0x00 zurück. Dabei verwende ich fast den TI-Code.
Dann verstehe ich nicht warum TI so einen Mist macht:
1
   while (P3IN & PIN_SOMI);           // Wait for CCxxxx ready
2
   UCB0TXBUF = 0x30;                  // Send strobe
3
   // Strobe addr is now being TX'ed
4
   IFG2 &= ~UCB0RXIFG;                         // Clear flag
5
   while (!(IFG2&UCB0RXIFG));                  // Wait for end of addr TX
6
   while (P3IN&PIN_SOMI);
Warum bitte soll ich nach dem Senden auf ein RX Flag warten? (PIN_SOMI 
is von mir, also nicht ganz original TI)

Des weiteren regt mich das total auf warum TI defines bis in die letzten 
Ecken zieht. Da findet man unter anderem defines bei denen man nach 5 
"unterdefines" auf ein normales int stößt. Warum nich gleich int 
schreiben. Da sieht doch kein Mensch durch. Beispiel:

linkID_t -> über typedef zu uint8_t -> wieder über typedef zu 
_bsp_uint8_t_ -> und im letzten typedef dann unsigned char
Hätt man auch gleich unsigned char schreiben können und fertig. Oder 
einfach nur char, da Standardmäßig in IAR das ein char immer unsigned 
ist. Man Man

von Martin (Gast)


Lesenswert?

Ich glaube ich komme dem Problem auf die Spur.
Hab mal ohne TI-Code angefangen. Im userguide ist nichts darüber zu 
finden ob man die Richtung mit PxDIR auch festlegen muss für die mit 
PxSEL eingestellten Ports. Also muss ich SIMO auch als Ausgang 
definieren? Oder macht das P3SEL schon?
Wie kann ich bei einem Ausgang den aktuelen Pegel prüfen? Auch mit PxIN? 
Wenn ja, dann ergibt das immer null. SOMI und SIMO sind bei mir also 
immer low. Trotzdem bekomme ich einen SPI RX Interrupt? im Buffer steht 
dann immer eine null. Wie geht das?

von Frederik G. (fred_g)


Lesenswert?

Hallo Martin,

also ich habe die Module ans laufen bekommen und muss sagen, dass alles 
sauber funktioniert. Ich habe als Grundlage auch den TI-Code verwendet. 
Allerdings benutzte ich einen ATMega und habe den Code auch neu 
aufgebaut. Ich würde Dir gerne helfen, allerdings kenne ich die 
MSP-spezifischen Begriffe leider nicht. Und Du hast recht, dass mit den 
defines im TI Code ist zum lernen und verstehen ein absoluter Krampf.

Also ich gehe so vor, zunächste Resete ich den CC2500 und schalte dann 
den SPI-Bus am AVR frei. Den Interrupt vom SPI nutze ich(bisher) nicht. 
Dann setze ich alle notwendigen Parameter im CC2500 und dann kann es 
losgehen mit senden oder empfangen.

Hier mal meine Reset Funktion :
1
PORTB|=(1<<5);    //CLK Pin   (SCKL)
2
PORTB &=~(1<<3);  //MOSI Pin  (SI)
3
_delay_us(10);
4
PORTB |=(1<<2);   //CS High
5
_delay_us(30);
6
PORTB &=~(1<<2); //CS Low
7
_delay_us(30);
8
// disable device and wait at least 40 microseconds
9
PORTB |=(1<<2);   //CS High
10
_delay_us(45);
11
PORTB &=~(1<<2); //CS Low
12
// wait for device
13
while((PINB&0x10)!=0);  //Wait for SO-Pin goes High
14
//Activate SPI
15
SPCR=0x52;    //Hier habe ich den SPI Prescaler relativ hoch eingestellt, also den SPI Takt recht langsam. Hat sich bei schlecher Verkabelung auf Lochraster als besser herausgestellt. Hier irgendwas um 125kHz. Später habe ich auf 4MHz erhöht.
16
SPSR=0x00;
17
// send reset command (SRES)
18
spiTransfer(0x30);
19
// disable device
20
PORTB |=(1<<2);   //CS High

Was bei mir vorallem bei hohen SPI Takt geholfen hat, ist nachdem man 
den CS-Pin auf Low-Pegel gezogen hat ein kleines sleep einzubauen. So 
ca. 10µs. Damit vorm SPI Tranfer der CC2500 auch sicher erkannt hat, das 
er nun enabled ist.

Ich hoffe diese hilft Dir etwas weiter. Leider habe ich vom MSP keine 
Ahnung. Aber ich denke das ist leicht übertragbar.

Gruß,
Frederik

von Maddin (Gast)


Lesenswert?

Danke für deine Hilfe. Ich bin auch ein wenig weitergekommen.

Der CC2500 reagiert auf meine Headerbytes.Anscheinend ist es nicht so 
wichtig welche Pegel Somi im idle haben. Naja.

Der Grund warum man nach dem Senden auf ein RX IFG wartet ist der, dass 
Senden und Empfangen immer gleicheitig passiert. Ein  Headerbyte und 
statusbyte liegen quasi immer zeitgleich am Bus an.

Nun versuch ich Register auszulesen. Hast du dazu einfach das im 
Datenblatt beshriebene Headerbyte mit entsprechendem BIZ7 gesetzt? Ich 
bekomme nämlich immer nur ein STatusbyte als Antwort. Oder muss man noch 
ein dummy senden (wie in den TI Codes)??

Danke

von Frederik G. (fred_g)


Lesenswert?

Also, wenn Du ein Register auslesen möchtest, bekommst Du "während" des 
senden des Header Bytes immer das Status byte zurück. Nun musst Du, um 
die Nutzdaten empfangen zu können ein weiters Byte (Dummy) auf den Bus 
schicken. Das dann empfangene Byte dürfte Dein gewünschtes sein. 
Probiere es mal aus.

Gruß

von Maddin (Gast)


Lesenswert?

Habe ich bereits. Jedoch habe ich nicht bedacht die Interrupts während 
des Sendens auszuschalten, sonst springt mir das Programm jedesmal in 
die ISR und deaktiviert dort wieder das Flag. Dann kann ich in der 
Sendefunktion langedrauf warten.

Ich probieren weiter....

von Elvis (Gast)


Lesenswert?

Hallo Frederik Grote,

ich interessiere mich auch für die Kommunikation mit dem CC2500. Ebenso 
verwende ich einen Atmega88 als µC. Vielleicht könntest du mir ein wenig 
mehr von deinem Code geben.

Gruß

Elvis

von Frederik G. (fred_g)


Lesenswert?

Hi Elvis,

leider habe ich im moment sehr wenig Zeit. Der Quellcode ist im Moment 
noch etwas "unaufgeräumt" und schlecht dokumentiert. Den gebe ich so 
ungern raus. Wie weit bist du denn mit deinem Aufbau? SPI angeschlossen 
und vielleicht eine RS232 für debugging Zwecke? Hat mit sehr geholfen. 
Hast du noch gar keinen Code, oder treten irgendwo Probleme auf. Falls 
spezielle Fragen oder Probleme sind, kannst du diese ja hier posten. 
Ansonsten versuche ich mal ein vereinfachtes Testprogramm fertig zu 
machen, die eine Kommunikation herstellt. Dieses kann ich dir dann 
geben.

VG
Frederik

von josé (Gast)


Lesenswert?

Ich arbeite auch gerade mit dem CC2500 und bin auch auf dem gleichen 
Problem gestoßen. Ich verwende den ATMega32 und kann über SPI ohne 
Probleme Daten zum Chip schicken sowie empfangen. Als ich nun einen 
Register auslesen wollte bekomme ich nur den Statusbyte als Antwort.

Kann es einer von euch mir erklären wie das geht mit dem Dummy senden?

Bitte um Hilfe

von Frederik G. (fred_g)


Lesenswert?

Moin!

Du musst im Grunde immer zwei Bytes senden. Wenn du das erste sendest 
empfängst du quasie gleichzeitig das Statusbyte. Erst wenn du ein 
zweites Byte sendest empfängst du die Antwort auf deine im ersten Byte 
gesendeten Anfrage.

Hier nochmal zur Veranschaulichung :

Anfrage    --> CC2500 --> Statusbyte
Dummybyte  --> CC2500 --> Antwort auf Anfrage

Du bekommst also immer ein Statusbyte zurück und dann erst die 
Nutzdaten.

Habe schon länger nicht mehr daran gearbeitet, also alles aus dem Kopf. 
Falls ein Fehler in meiner Ausführung ist, gerne korrigieren.

Gruß
Fred

von José (Gast)


Lesenswert?

@Frederik Grote

Danke für die schnelle Antwort. Es hat nun geklappt :)
Ich schicke als Dummy 0x00 und bekomme dann den Registerinhalt zurück. 
Ich muss aber ständig den Chip manuell ins Reset Status schicken sonst 
reagiert er nicht, wenn ich am code was ändere (keine ahnung warum).

Vielen Dank

von ??? (Gast)


Lesenswert?

kennt sich hier jemand mit dem CC2500 (in der EZ430-RF2500 hardware)aus?

ich habe 2 module und bei einen verhält sich das Signal am Pin SO genau 
Invers verglichen mit dem funktionierenden - bezüglich der pegel am 
chipselect...

hat da jemand erfahrung bzw. erfahrung mit dem verhalten kaputter 
CC2500?
danke

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.