Forum: Mikrocontroller und Digitale Elektronik PIC32 SPI Bytereihenfolge ändern


von Mike (Gast)


Lesenswert?

Hallo,

ich versuche gerade, das Filesystem FatFs auf einem PIC32 mit 
SD-Kartenslot zum Laufen zu bringen. Leider hat der PIC kein natives 
SD-Karten Interface, so bin ich auf SPI angewiesen. Um das Ganze etwas 
schneller zu machen, lese ich die Daten in 32-bit Häppchen aus:

1
DWORD *ptr;
2
...
3
for (i=0;i<512/4;i++)
4
{
5
    SPI2BUF = 0xFFFFFFFF;
6
    while(!SPI1STATbits.SPIRBF) {};
7
    *ptr++ = SPI2BUF
8
}

Leider funktioniert es nicht, fatFS erkennt ein ungültiges Dateisystem. 
Der Grund liegt darin, dass die Bytes im Speicher "verwürfelt" abgelegt 
werden:

Wenn SPI2BUF zB. 0x12345678 enthält, gelangt beim Abspeichern 0x78 an 
die erste, 0x12 an die 4te Stelle. Der PIC ist schliesslich eine 
Little-Endian-Maschine. Alle Beispielroutinen verwenden SPI im 8bit 
Modus, was aber zu einer schlechten Performance führt, da das 
Abspeichern der Werte längert dauert als der Empfang eines Bytes. Im 
Oszillogramm ist das als "Lücke" im SPI-Taktsignal sichtbar.
Gibt es eine einfache Möglichkeit, die Bytereihenfolge zu ändern? Im 
Datenblatt habe ich nichts dazu gefunden. Manuelles 
"Auseinanderpfriemeln"
würde wahrscheinlich wieder die Übertragungsgeschwindigkeit in den 
Keller gehen lassen.
 DMA habe ich auch schon versucht, aber keine Methode gefunden, die 
SPI-Übertragung nach jedem empfangenen Datenwort automatisch wieder zu 
starten.

Mike

von Erich (Gast)


Lesenswert?

Wahrscheinlich musst du was mit "union" machen

GOOGLE:  union "little endian" "big endian"

von Andreas H. (ahz)


Lesenswert?

Mike schrieb:
> DMA habe ich auch schon versucht, aber keine Methode gefunden, die
> SPI-Übertragung nach jedem empfangenen Datenwort automatisch wieder zu
> starten.
Such mal im Datenblatt nach SRXISEL. Die zwei Bits stellen den SPI-RX 
Irq ein.

Grüße
Andreas

P.S: Der M4K hat übrigens auch SWL, SWR, ROTR & WSBH Befehle^^

von Mike (Gast)


Lesenswert?

Hallo,

ich habe das little/big endian Problem erst einmal wie folgt gelöst:
1
  union _fatPtr  
2
  {
3
     DWORD d;
4
     struct _b
5
     {
6
        BYTE b0;
7
        BYTE b1;
8
        BYTE b2;
9
        BYTE b3;
10
     } byte;        
11
  } fatWord;
12
13
.....
14
15
    SPI2CONSET = _SPI2CON_MODE32_MASK;//|_SPI2CON_DISSDO_MASK;
16
    SPI2BUF = 0xFFFFFFFF; //start reading - send dummy bytes
17
    for (i=0;i<512/4-1;i++)
18
       {
19
         while (!SPI2STATbits.SPIRBF)
20
            {
21
            //wait for end of transaction
22
            }
23
         fatWord.d = SPI2BUF;  //read from SPI
24
  
25
         SPI2BUF = 0xFFFFFFFF; //trigger SPI transmission 
26
  
27
         *buffer++ = fatWord.byte.b3; //write to buffer in big endian order
28
         *buffer++ = fatWord.byte.b2;
29
         *buffer++ = fatWord.byte.b1;
30
         *buffer++ = fatWord.byte.b0;
31
      }
32
    while (!SPI2STATbits.SPIRBF)
33
         {
34
         //wait for end of transaction
35
         }
36
    fatWord.d = SPI2BUF;  //read from SPI
37
    *buffer++ = fatWord.byte.b3;  // copy last word
38
    *buffer++ = fatWord.byte.b2;
39
    *buffer++ = fatWord.byte.b1;
40
    *buffer   = fatWord.byte.b0;
41
    // reset SPI module to 8 bit transfer
42
    SPI2CONCLR = _SPI2CON_MODE32_MASK;

Das Umkopieren findet statt, während der SPI die nächste 
Datenübertragung durchführt. Trtzdem erscheint mir der Aufwand noch 
recht hoch. Am beesten wäre es, den PIC temporär auf Big Endian 
umzuschalten. Hier 
http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Data/endian.html
steht :"MIPS processors allowed you to select a configuration where it 
would be big or little endian". Doch wie mache ich das?

@Andreas. SRXISEL kann ich leider nicht nutzen, da mein PIC32MX460 
keinen enhanced mode SPI hat.

Im Netz habe ich eine Lösung mit 2 DMA Kanälen gefunden, einer liest die 
Daten aus, der andere füttert den SPI mit einer Serie von 0xFF's. Das 
scheint aber sehr kompliziert zu sein, zumal ich bereits einen DMA 
nutze, der mir die Daten über einen weiteren SPI auf einen 
Digital-Analog-Wandler schickt.

von Andreas H. (ahz)


Lesenswert?

Mike schrieb:
> Hier
> http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/...
> steht :"MIPS processors allowed you to select a configuration where it
> would be big or little endian". Doch wie mache ich das?

Garnicht:
http://support2.microchip.com/KBSearch/KB_StdProb.aspx?ID=SQ6UJ9A00XYOS

Grüße
Andreas

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.