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 #5306907
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 #5306972
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 #5307915
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 #5308095
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 #5308860
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 #5309421
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren