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.
Mein erster Verdacht war, dass dein Interrupt auf DMA completion kommt. Und in der Tat, alle Indizien sprechen dafür:
1 | Page 10-6 im HRM [1]: |
2 | |
3 | Interrupt Behavior |
4 | ------------------ |
5 | |
6 | The behavior of the SPI interrupt signal depends on the transfer initiation |
7 | mode bit field (TIMOD) in the SPI Control register. In DMA mode, the |
8 | interrupt can be generated upon completion of a DMA multiword transfer |
9 | or upon an SPI error condition (MODF, TXE when TRAN = 0, or RBSY when |
10 | TRAN = 1). When not using DMA mode, an interrupt is generated when |
11 | the SPI is ready to accept new data for a transfer. The TXE and RBSY error |
12 | conditions do not generate interrupts in these modes. An interrupt is also |
13 | generated in a master when the mode fault error occurs. |
14 | |
15 | For more information about this interrupt output, see the discussion of |
16 | 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/processor_manuals/365066229ADSP_BF535_HRM.pdf
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 |
9 | {
|
10 | // CS high
|
11 | *fio_set_reg = (unsigned short)0x0400; |
12 | // Ack
|
13 | *pSPI0_DMA_INT = 0x0001; |
14 | }
|
15 | else
|
16 | {
|
17 | // Fehlerbehandlung
|
18 | }
|
19 | }
|
Mal abgesehen von den anderen PRoblem, glaubst du nicht das deine Daten etwas viel Dreck auf deiner CS Leitung hinterlassen? Olaf
@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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.