www.mikrocontroller.net

Forum: Digitale Signalverarbeitung / DSP Problem mit Blackfin SPI-DMA


Autor: Benjamin S. (recycler)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Gemeinde,
ich verwende beim Datentransfer mit einem BF535 das SPI-Protokoll. Damit 
beschreibe ich einen MAX3421E USB-Controller, was auch alles 
funktioniert.
Jetzt will ich auf den DMA-Modus wechseln.
Bei MAX3421 muss als erstes ein Byte gesendet werden, welches das 
Register des Controller beinhaltet und gleich anschließend die Daten für 
das Register. Dabei darf das Chipselect nicht auf high gehen. Wenn der 
Transfer abgeschlossen ist [1 Byte (Register) + 1-64Byte (Daten)] soll 
#CS wieder auf high gehen. Deshalb habe ich mich für eine SoftwareCS 
Leitung entschieden, welche nach Abschluss des Transfers in einer ISR 
gesetzt wird. Allerdings passiert das schon viel zu früh, wie auf dem 
Ausdruck im Anhang zu sehen (rote Linie ist die Solllinie)
Oberes Signal: Chipselect
Unteres Signal: SCK

Für Anregungen bin ich gerne offen.

Autor: Benjamin S. (recycler)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier der Quellcode

Autor: T. H. (pumpkin) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein erster Verdacht war, dass dein Interrupt auf DMA completion kommt. 
Und in der Tat, alle Indizien sprechen dafür:

Page 10-6 im HRM [1]:

Interrupt Behavior
------------------

The behavior of the SPI interrupt signal depends on the transfer initiation
mode bit field (TIMOD) in the SPI Control register. In DMA mode, the
interrupt can be generated upon completion of a DMA multiword transfer
or upon an SPI error condition (MODF, TXE when TRAN = 0, or RBSY when
TRAN = 1). When not using DMA mode, an interrupt is generated when
the SPI is ready to accept new data for a transfer. The TXE and RBSY error
conditions do not generate interrupts in these modes. An interrupt is also
generated in a master when the mode fault error occurs.

For more information about this interrupt output, see the discussion of
the TIMOD bits in “SPIx Control Register (SPIx_CTL)” on page 10-9.

Also wie sich das ließt, bekommst du einen Interrupt nur auf Error oder 
DMA completion...

[1] 
http://www.analog.com/static/imported-files/proces...

Autor: T. H. (pumpkin) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oha, wie es aussieht, hat das SPI des 535er garkeinen DMA FIFO Buffer! 
(Ich kenne das anders vom 537er.) Das sollte in der Tat bedeuten, dass 
der DMA completion Interrupt erst dann kommt, wenn das letzte Byte raus 
ist. Du prüfst in der Interruptroutine nicht, um welchen Interrupttyp es 
sich handelt. Versuch' das hier:

EX_INTERRUPT_HANDLER(SPI0_DMA_ISR)
{
  // pSPI0_DMA_INT:
  // 0x0001 => Interrupt on Completion
  // 0x0002 => DMA Interrupt on Error
  // 0x0004 => Bus Error

  if(*pSPI0_DMA_INT & 0x0001) // Interrupt on Completion
  {
    // CS high
    *fio_set_reg   = (unsigned short)0x0400;
    // Ack
    *pSPI0_DMA_INT = 0x0001;
  }
  else
  {
    // Fehlerbehandlung
  }
}

Autor: Olaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal abgesehen von den anderen PRoblem, glaubst du nicht das deine
Daten etwas viel Dreck auf deiner CS Leitung hinterlassen?

Olaf

Autor: Benjamin S. (recycler)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
@Olaf: ich denke, das kommt von den langen Messleitungen. Ich hatte 
nichts anderes zur Hand.

@pumpkin: Danke für die Hilfe, die Überprüfung führe ich durch. Den else 
Teil habe ich abgeschnitten.
Das komische ist, wenn ich in der ISR einen Breakpoint bevor das #CS auf 
high gesetzt wird, das die Daten übertragen werden. Dies sehe ich, weil 
ich mit dem Code einen Binärzähler realisiert habe. Wenn ich keinen 
Breakpointsetzte bzw. nach dem CS-high, dann funktioniert das ganze 
nicht mehr und die Daten werden nicht übertragen.
Laut Anhang hat er die Daten (Word Count = 0) abgearbeitet und keine 
Fehler (Config und Status) gefunden. Das ist was mich stutzig macht.

Autor: T. H. (pumpkin) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Benjamin Schrödl wrote:
> @pumpkin: Danke für die Hilfe, die Überprüfung führe ich durch. Den else
> Teil habe ich abgeschnitten.

So wie ich vorgeschlagen habe?

> Das komische ist, wenn ich in der ISR einen Breakpoint bevor das #CS auf
> high gesetzt wird, das die Daten übertragen werden. Dies sehe ich, weil
> ich mit dem Code einen Binärzähler realisiert habe. Wenn ich keinen
> Breakpointsetzte bzw. nach dem CS-high, dann funktioniert das ganze
> nicht mehr und die Daten werden nicht übertragen.

Das ist allerdings merkwürdig. Steht das Hochsetzen in der if-Abfrage 
nach dem Acknowledge? Wenn nicht: Versuch macht schlau.

> Laut Anhang hat er die Daten (Word Count = 0) abgearbeitet und keine
> Fehler (Config und Status) gefunden. Das ist was mich stutzig macht.

Ist der "TX Buffer" oben im Bild der vom SPI0? Sollte der leer sein wenn 
die Übertragung abgeschlossen ist (finde auf Schlag nichts im HRM)?

Autor: Benjamin S. (recycler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich hab das CS-high schon wo anders hingesetzt, aber das bring nix.
der TX buffer beinhaltet den letzten Wert als 2xByte die identisch 
buffer[i] sind

Hier meine ISR:
EX_INTERRUPT_HANDLER(SPI0_DMA_ISR)
 {
  // pSPI0_DMA_INT:
  // 0x0001 => Interrupt on Completion
  // 0x0002 => DMA Interrupt on Error
  // 0x0004 => Bus Error


//Wenn hier breakpoint, dann funktioniert die Übertragung
  *pSPI0_FLG = FLS5 | FLG5;


  if(*pSPI0_DMA_INT & 0x0001) // Interrupt on Completion
   {


    // Puffer fertig abgearbeitet
    if(1 != 0) //*pbuffer = buffer8k)
     {

      buffer8k[1]++;
      c = buffer8k[1];
     }
    else
     {
      // Disable PF_INT

     }

    *pSPI0_DMA_INT         = 0x0001;
   }
  else
   {
    unsigned short e;
    e = 1; // hier 2. Breakpoint, der nie angesprungen wird.
   }
 }

Autor: T. H. (pumpkin) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Benjamin Schrödl wrote:
> Hier meine ISR:

Augenkrebs!

Ist ja klar, dass die Übertragung dann funktioniert. Dein CS bleibt für 
immer low. Du musst mal klären, ob der DMA completion Interrupt wirklich 
nach Abschluss des Multiword-Transfers kommt. Und ob das SPI erst das 
erste Wort sendet und die DMA erst dann das zweite Wort schreibt.


Mir ist was aufgefallen:

HRM page 9-6:

[...] With each transfer, the DMA address (stored in the DMA Start 
Address registers) increments relative to the data size. The address
increments by 1 for 8-bit data transfers, by 2 for 16-bit transfers, 
or by 4 for 32-bit transfers.

Dein Zähler ist auf 2, deine Größe auf 8Bit. Dein Buffer ist 2 mal 
16Bit. Aber das wird nicht im Zusammenhang mit dem Fehler stehen.

Autor: Benjamin S. (recycler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich habe im blackfin.org Forum gelesen, dass der BF da ein wenig eigen 
ist und teilweise nicht aufhört bzw. der IRQ zu früh kommt. Genauso ist 
es bei mir. Werde morgen mal den Autobuffermodus verwenden.

Ich habe noch zwei andere Fragen:
- Wenn ich im Descriptormodus das Controllwörd auf 900D setze (8 Bit, 
DMA owner, IRQ on Completion, DMA_EN) dann kann ich den Dma über 
Spi_config | = 0x0001 starten. Bei 900C im Descriptor aber nicht. Weil 
im BF HRM 9-8 steht:

"If the descriptor block is the last one in a linked list or the
only one (that is, a standalone transfer sequence), the Next
Descriptor Pointer within the descriptor block must point
to a memory location that contains a data value with bit 15
set to 0 (0xxx xxxx xxxx xxxx). If bit 0 is a 1 (0xxx xxxx xxxx
xxx1), the DMA channel is still enabled, but stalled, and the
remaining FIFO values are not discarded. This allows the
DMA engine to finish transferring the remaining values in
the FIFO."

Punkt 1 habe ich erledigt. Aber wie ist es mit Punkt 2 (Bit 0 => 0)



- Am Ende des Descriptors soll er auf einen Wert von 0x0001 (Base+0 vgl 
HRM Bild 9-4) zeigen. Wenn ich das aber mache, kann ich den DMA nicht 
wieder starten.


------------
Vlt weiß einer noch was zu dieser späten Stunde - bis morgen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.