Raspberry SPI Empfang Problem

Gast #5306833
Lesenswert?
• ▲
▼
Hallo Welt,

ich teste gerade das SPI Interface des Raspberry Pi 3 Model B. Dabei ist 
an den GPIO's und am SPI Interface nichts angeschlossen. Das Senden von 
Daten funktioniert (mit nem Scope gemessen), allerdings empfange ich 
immer die Daten, die ich auch versendet habe. Auch wenn ich den MISO Pin 
mit z.B. dem SCK Pin kurzschließe, "empfange" ich immer die Nachricht, 
die ich auch versendet habe.

Hat jemand einen Rat? Vielen Dank!
1
#include <stdio.h>
2
#include <fcntl.h>
3
#include <sys/ioctl.h>
4
#include <linux/spi/spidev.h>
5
#include <inttypes.h>
6
#include <stdlib.h>
7
#include <wiringPiSPI.h>
8

9
int main()
10
{
11
  unsigned char* buffer = "Hallo Welt!!!\n";
12
  int i =0;
13
  if(wiringPiSPISetup(1, 500000)==-1)
14
  {
15
    printf("Could not initialise SPI\n");
16
    return 0;
17
  }
18
  while(1)
19
  {
20
    wiringPiSPIDataRW(1, buffer, 8);
21
    printf("Data send %i, %s\n", i++, buffer);
22
  }
23
  
24
  return 0;
25
}
Gast
Lesenswert?
• ▲
▼
Hi,

Gordon hat vor dem ioctl-Aufruf so programmiert:
...
 memset (&spi, 0, sizeof (spi)) ;
 spi.tx_buf        = (unsigned long)data ;
 spi.rx_buf        = (unsigned long)data ;
 spi.len           = len ;
...

Das erklärt, wieso Du das "empfangen" kannst, was Du gesendet hast, wenn 
Du nichts empfängst :-)
Gast
Lesenswert?
• ▲
▼
Hallo WiringPiSPI,

danke für deine Antwort! Ich bin aber noch nicht auf die Lösung des 
Problems gekommen. Ich habe die Funktion für Debugzwecke erweitert:
1
int wiringPiSPIDataRW (int channel, unsigned char *data, int len)
2
{
3
  int ret,i;
4
  struct spi_ioc_transfer spi ;
5

6
  channel &= 1 ;
7

8
// Mentioned in spidev.h but not used in the original kernel documentation
9
//  test program )-:
10

11
  memset (&spi, 0, sizeof (spi)) ;
12

13
  spi.tx_buf        = (unsigned long)data ;
14
  spi.rx_buf        = (unsigned long)data ;
15
  spi.len           = len ;
16
  spi.delay_usecs   = spiDelay ;
17
  spi.speed_hz      = spiSpeeds [channel] ;
18
  spi.bits_per_word = spiBPW ;
19
  ret = ioctl (spiFds [channel], SPI_IOC_MESSAGE(1), &spi) ;
20
  for(i=0;i<12;i++)
21
  printf("%x ", ((char*)spi.tx_buf)[i]);
22
  for(i=0;i<12;i++)
23
  printf("%x ", ((char*)spi.rx_buf)[i]);
24
  return ret;
25
}

Die Ausgabe der einzelnen Bytes enthält jeweils die abgesendete 
Nachricht.

Ich kenn mich mit der ioctl Funktion nicht so aus, kann es sein, dass 
sie nur den Prozess startet und ich die Antwort irgendwie per Interrupt 
erhalte?

Danke und viele Grüße
Gast
Lesenswert?
• ▲
▼
Hi,

der Hinweis auf die Implementierung von wiringPiSPIDataRW sollte nur 
erklären, wieso man die gesendeten Daten wieder empfangen kann.

Die Debug Ausgabe hat aber nicht geschadet :-)

>Ich kenn mich mit der ioctl Funktion nicht so aus, kann es sein, dass
>sie nur den Prozess startet und ich die Antwort irgendwie per Interrupt
>erhalte?

Nein, denn wenn alles gut geht liefert die Funktion wiringPiSPIDataRW 
die empfangenen Daten in dem Bereich, auf den der 2. Parameter zeigt und 
der ioctl-Aufruf steht ja im return Befehl:

return ioctl (spiFds [channel], SPI_IOC_MESSAGE(1), &spi) ;


Ich denke, ich steck nachher mal was zusammen und teste auch mal. Kann 
aber etwas dauern :-)

Viele Grüße
Gast
Lesenswert?
• ▲
▼
Die ioctl Funktion innerhalb der wiringPiSPIDataRW Funktion gibt -1 
zurück. Das Setup Funktioniert: fd=3.

Mich wundert ja, dass das Senden funktioniert. Leider empfange ich aber 
immer noch nichts und ich weiß nicht weiter... :-/
Gast
Lesenswert?
• ▲
▼
Hi,

hol Dir spidev_test.c.

https://github.com/torvalds/linux/blob/master/tools/spi/spidev_test.c

Ein Test ohne und dann mit Verbindung zwischen MOSI und MISO sieht damit 
so aus:

pi@spipi:~/spitest $ sudo ./spidev_test -v -p "1234"    -D 
/dev/spidev0.1
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
TX | 31 32 33 34 _ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ _ 
_ __ __ __ __ __ __ __ __ _  | 1234
RX | 00 00 00 00 _ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ _ 
_ __ __ __ __ __ __ __ __ _  | ....
pi@spipi:~/spitest $ sudo ./spidev_test -v -p "1234"    -D 
/dev/spidev0.1
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
TX | 31 32 33 34 _ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ _ 
_ __ __ __ __ __ __ __ __ _  | 1234
RX | 31 32 33 34 _ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ _ 
_ __ __ __ __ __ __ __ __ _  | 1234

Viel Erfolg!
Gast
Lesenswert?
• ▲
▼
Na,weiter gekommen?

spidev_test.c sollte bei Dir auch funktionieren. Wenn nicht stimmt was 
am Raspi nicht.

Dein Testprogramm wird aber trotzdem nicht so laufen, wie Du denkst.

In wiringPiSPIDataRW sieht man ja, wie der Puffer verwendet wird. Du 
hast aber keinen Zeiger auf einen Puffer übergeben, sondern einen Zeiger 
auf eine Stringkonstante.

Ändere mal Dein Testprogramm so ab:

int main()
{
//  unsigned char* buffer = "Hallo Welt!!!\n";
 unsigned char buffer [32];
 int i =0;
  if(wiringPiSPISetup(1, 500000)==-1)
  {
    printf("Could not initialise SPI\n");
    return 0;
  }
  while(1)
  {
    strcpy(buffer,  "Hallo Welt!!!\n");
    wiringPiSPIDataRW(1, buffer, 8);
    printf("Data send %i, %s\n", i++, buffer);
  }

  return 0;
}

Dann teste mit offenen MOSI und MISO Ports und mit kurzgeschlossenen.

Dann oder spätestens wenn Du zusätzlich noch mit

    wiringPiSPIDataRW(1, buffer, 1);

testest, also in jedem Durchlauf nur 1 Byte per SPI raus- bzw. raus- und 
reinschiebst, sollte alles klar sein.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 8 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.