Hallo miteinander,
Ich habe ein Funkmodul (Olimex MOD-NRF24L mit Nordic Semiconductor
nRF24L01 Chip), welches ich mit dem MSP430F449 über SPI (polling mode)
ansteuere.
Folgendes Problem besteht jedoch noch:
Wenn ich per SPI ein Byte einlese, so ist dieses immer um 1 Bit
verschoben.
Das letzte Bit (LSB) scheint immer unterzugehen, obwohl es korrekt
übertragen wird.
Ich habe die Kommunikation sowohl mittels Logic Analyzer und dem KO
überprüft. Der MSP430 und auch der nRF24L01 scheinen die Daten
einwandfrei zu senden. (siehe Screenshots)
Schreiben über SPI mit dem MSP430 ist kein Problem:
Ich kann die Register des nRF24L01 beschreiben und anschliessend wieder
auslesen. Die Daten stimmen (zumindest vom Interpreter des Logic
Analyzers) überein. Das jeweilige Datenbyte im Empfangsbuffer des MSP430
ist jedoch immer um dieses eine Bit nach rechts geschoben mit einem
vorangehenden 0.
Ja sogar die Funkschnittstelle habe ich (mit ein paar Umwegen)
unidirektional zum laufen gebracht!
Ich glaube mir scheint irgendwo ein gravierender Fehler in der
Konfiguration oder in der Implementation der SPI-routine unterlaufen zu
sein, aber welcher?
Für mich sieht es so aus, als ob ich den Receive-Buffer auslese, bevor
das letzte bit "hinein-geshiftet" wurde. aber ich prüfe doch alle flags,
sodass dies nicht der fall sein wird?
Ich habe heute schon einige Stunden verzweifelt danach gesucht. Ich
vermute jedoch schwer, dass jemand von euch das Problem auch schon
hatte.
Meine SPI-Routine sieht wie folgt aus:
1 | unsigned char SPI_WriteByte(unsigned char dataByte) {
|
2 | #if NRF24L_SPI_NUMBER == 0
|
3 |
|
4 |
|
5 | while(!(IFG1&UTXIFG0)) //wait for transmission buffer to be empty
|
6 | ;;
|
7 |
|
8 | IFG1 &=~URXIFG0; //URXIFGx is automatically reset if the pending interrupt is served or when UxRXBUF is read.
|
9 |
|
10 | U0TXBUF = dataByte; //fill buffer with desired data
|
11 |
|
12 | while(!(IFG1&URXIFG0)) //wait for reception to be completed
|
13 | ;;
|
14 | while(!(TXEPT&U0TCTL)) //wait for reception to be completed
|
15 | ;;
|
16 |
|
17 | dataByte = U0RXBUF;
|
18 | return dataByte;
|
19 |
|
20 | #else
|
21 | return 0;
|
22 | #endif
|
23 | }
|
Und die Initialisierungsroutine so:
1 | void NRF24L_Init(void) {
|
2 | //Initialize all I/O Ports
|
3 | #if NRF24L_SPI_NUMBER == 0
|
4 |
|
5 | U0CTL = 0;
|
6 | // U0CTL &= ~I2C; //SPI mode
|
7 | U0CTL |= CHAR; //8-bit data
|
8 | U0CTL |= SYNC; //synchronous mode (SPI)
|
9 | U0CTL |= MM; //master mode (SPI)
|
10 |
|
11 | U0TCTL = 0;
|
12 | U0TCTL |= CKPH;
|
13 | U0TCTL &= ~CKPL; //data valid on rising edge
|
14 | U0TCTL |= SSEL1 | SSEL0; //SMCLK (valid for master mode only)
|
15 | U0TCTL |= STC; //3-pin SPI mode: STE disabled.
|
16 |
|
17 | U0BR1 = (CPU_SMCLK / NRF24L_SPI_BAUDRATE) >> 8; //set baudrate
|
18 | U0BR0 = (CPU_SMCLK / NRF24L_SPI_BAUDRATE) & 0x00FF;
|
19 | U0MCTL = 0; //modulator - for SPI mode and is recommended to be set to 000h
|
20 |
|
21 | ME1 |= USPIE0; //enable SPI module
|
22 |
|
23 | P3DIR |= BIT1; //SIMO
|
24 | P3SEL |= BIT1;
|
25 | P3DIR &= ~BIT2; //SOMI
|
26 | P3SEL |= BIT2;
|
27 | P3DIR |= BIT3; //UCLK
|
28 | P3SEL |= BIT3;
|
29 | #else
|
30 | #error "Only SPI0 implemented for now!"
|
31 | #endif
|
32 |
|
33 | //IRQ signal
|
34 | NRF24L_IRQ_PDIR &= ~NRF24L_IRQ_BIT;
|
35 | P2IES |= NRF24L_IRQ_BIT; //... on falling edge
|
36 | P2IFG &= ~NRF24L_IRQ_BIT; //pre-clear flag
|
37 | P2IE |= NRF24L_IRQ_BIT; //enable interrupt for IRQ pin
|
38 |
|
39 | //Chip enable signal
|
40 | NRF24L_CE_PDIR |= NRF24L_CE_BIT;
|
41 | NRF24L_CE_POUT &= ~NRF24L_CE_BIT;
|
42 |
|
43 | //Chip select signal
|
44 | NRF24L_CSN_PDIR |= NRF24L_CSN_BIT;
|
45 | NRF24L_CSN_POUT |= NRF24L_CSN_BIT;
|
46 |
|
47 |
|
48 | /* DEBUG STUFF START */
|
49 | //NRF24L_ISR();
|
50 |
|
51 |
|
52 | /* DEBUG STUFF END */
|
53 |
|
54 | }
|
Beste Dank für eure Hilfe!
Grüsse aus der Schweiz
Fabian