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.
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:
1
EX_INTERRUPT_HANDLER(SPI0_DMA_ISR)
2
{
3
// pSPI0_DMA_INT:
4
// 0x0001 => Interrupt on Completion
5
// 0x0002 => DMA Interrupt on Error
6
// 0x0004 => Bus Error
7
8
if(*pSPI0_DMA_INT&0x0001)// Interrupt on Completion
@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.
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)?
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.
}
}
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:
1
HRM page 9-6:
2
3
[...] With each transfer, the DMA address (stored in the DMA Start
4
Address registers) increments relative to the data size. The address
5
increments by 1 for 8-bit data transfers, by 2 for 16-bit transfers,
6
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.
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.