Forum: Mikrocontroller und Digitale Elektronik Beaglebone Black per SPI mit atmega328p verbinden


von zibi d. (zibi)


Lesenswert?

Wie die Überschrift andeutet möchte ich das BBB als Master und einen 
atmega328p als Slave kommunizieren lassen.
So hatte ich die Anleitung im GNUBLIN Wiki in freudiger Erwartung 
durchgearbeitet:

http://wiki.gnublin.org/index.php/Tutorial_API_Beaglebone_Black

Über ssh wird auf dem BBB compiliert wie im Wiki beschrieben.
Hier der leicht modifizierte Beispielcode:

#define BOARD BEAGLEBONE_BLACK
#include "gnublin.h"
#include <iostream>

int main()
{
   gnublin_spi spi;

   spi.setSpeed(1000);
   spi.setCS(14);
   unsigned char sendbuffer[9] ={1,2,3,4,5,6,7,8,9};
   char buffer[9];
   char i;
   while(1){
     spi.send(sendbuffer,8);
     sleep(2);
     spi.receive(buffer,8);

     for(i=0;i<9;i++){
        cout << "Element SPI Data:" << buffer[i] << endl;
     }
     cout << '\n';
   }
}


Der buffer soll also elementweise ausgegeben werden.
Leider kommen hierbei nur ein D, komisches Fragezeichensymbol etc. 
heraus.
Und das unabhängig ob der Slave angeschloßen ist oder nicht!! (hab CS am 
slave auch mal manuel auf GND gelegt, kam das Gleiche heraus):

Habt Ihr eine Idee was ich da falsch mache?

Vielen Dank schon mal!

von Irgendwer (Gast)


Lesenswert?

zibi dziubek schrieb:
> unsigned char sendbuffer[9] ={1,2,3,4,5,6,7,8,9};

Wenn du einen Text empfangen willst, solltest du vielleicht auch einen 
senden:

const char sendbuffer[] ={'1','2','3','4','5','6','7','8','9'};

oder einfacher als Null-Terminierter String

const char sendbuffer[] ={"123456789"};

von zibi d. (zibi)


Angehängte Dateien:

Lesenswert?

Hallo "Irgendwer"!

Stimmt! Danke für den Hinweis.
hab's mit ’ ’ ausprobiert, liefert aber das gleiche Ergebniss..


Anbei ein screenshot des laufenden Terminalprogramms.
Würde mich über weitere Hinweisen sehr freuen!

von Irgendwer (Gast)


Lesenswert?

Sieht irgendwie aus als ob du immer noch ungültige ASCII Zeichen senden 
würdest. Bei einem Code kleiner 20 war es ja noch klar das du nur 
Schmierzeichen siehtst.

Ich frage mich aber ob du deine SPI-Schnittstelle überhaupt vollständig 
un richtig initialisierst. Speed und Mode(den du anscheinend überhaupt 
nicht einstellst?) auf beiden Seiten zueinanderpassend?
Wird z.B. spi.setSpeed() überhaupt erfolgreich ausgeführt(Rückgabewert)?
https://github.com/embeddedprojects/gnublin-api/blob/master/gnublin.cpp#L730

Die ganzen Pinzuordnungen Richtig? Nicht das zwar der Takt ankommt, aber 
nicht die Daten.
Besteht das Problem in beide Richtungen oder nur in eine?(Geht hier 
nicht so genau hervor von wo nach wo du Sendest und wo die Anzeige 
herkommt).

Auf einem Logic Analyzer würde man hier mit großer Wahrscheinlichkeit 
recht schnell sehen wo es nicht passt...

von zibi d. (zibi)


Angehängte Dateien:

Lesenswert?

Guten Morgen,

spi.setSpeed(1000) gibt 1 zurück
spi.setMode(0) gibt 1 zurück
spi.setCS(17) ab hier -1 (Fehler)
spi.send() -1
spi.receive() -1

ich kann mir nicht erklären warum das chip select nicht funktioniert.
Es handelt sich nach der Pinbelegung in der Overlay file um pin 
17(GPIO4)

habe spi.setMode(17), spi.setMode(4) sowie spi.setMode(0) versucht..

Leider kenne ich mich mit "++" in C++ nicht aus, und fühle mich etw. 
überfordert.

Anbei der gesammte code des BBB.
Der atmega328p wurde als slave konfiguriert, mode 0(CPOL und CPHA bei 0 
belassen), und macht nichts anderes als zu warten bis eine SPI 
Übertragung abgeschlossen ist, um dann 0x41 ASCII Zeichen A zu senden. 
Die Verkabelung nach Overlay aus dem gnublin wiki habe ich durchgepiepst 
(Durchgangstest).
Wie der Debugger zeigt bleibt der uC beim polling auf "SPI Transfer 
abgeschlossen?" und geht nicht weiter. So denke ich, es liegt am BBB.

Code des atmega:
        //SPI Init
PRR &= ~(1<<PRSPI);  //disable power save by SPI block
DDRB |= (1<<DDB4);  //MISO pin as output
DDRB &= ~ ((1<<DDB5)|(1<<DDB3)|(1<<DDB2)); //SCK, MOSI and SS as inputs
PORTB|= (1<<PB2);  //pull up on SS pin
SPCR &= ~(1<<MSTR);  //slave mode selected
SPCR |= (1<<SPE);       //SPI enable
  //SPI Init END



    while(1){
  SPDR = 0x41;    //ascii code for A

    /* Wait for reception complete */
    while(!(SPSR & (1<<SPIF))){}

                PORTC = SPDR;

  }

von PittyJ (Gast)


Lesenswert?

Auch in C++ funktioniert ein klassischer printf().
Und den Empfangsbuffer vor dem Lesen löschen, damit man sehen kann was 
wirklich rein kommt.

also
   while(1){
     spi.send(sendbuffer,8);
     sleep(2);

     memset(buffer,0,sizeof(buffer));

     spi.receive(buffer,8);

     for(i=0;i<9;i++)
     {
        printf("Element %02x \n",buffer[i]);
     }

von zibi d. (zibi)


Lesenswert?

Leider gibt der code von Pittyj (Ausgaben per printf())
alles 00 heraus. Der Buffer wird also nicht beschrieben.

Soweit ich das verstanden habe erwartet spi.setCS() die Nummer des Pins.
in spi.h steht:
* Default chipselect:
* GNUBLIN: CS = 11
* RASPBERRY PI: CS = 0
* BEAGLEBONE BLACK: CS = 0

in meinem Fall also CS=0..
Der Rückgabewert bleibt aber -1.

Woran könnte das liegen?
/dev/spidev1.0 existiert auf dem BBB.

von kalle (Gast)


Lesenswert?

hast du malden device tree gecheck?

von zibi d. (zibi)


Lesenswert?

Wie kann man den Device tree überprüfen?

Das Overlay wurde wie im gnublinwiki beschrieben durchgeführt.

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.