Forum: Mikrocontroller und Digitale Elektronik EFM32 UART DMA


von bubi_00 (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich habe hier vor mir ein EFM32 DVK liegen.
Aktuell versuch ich den DMA-Controller für ein UART Protokoll zum laufen 
zu kriegen. Das ganze läuft in einer RTX Umgebung und demnach in Keil 
µVision.

Aufgabe:

Ich schicke ein Startzeichen (0x1F) und starte danach einen DMA Transfer 
mit fester Länge (6 Bytes immo) und disable den UART Interupt. In der 
Callback-Function, löse ich ein Event aus und der Task verarbeitet die 
Daten. Danach aktiviere ich wieder den UART Interrupt und warte auf das 
Startzeichen. Funktioniert soweit auch schon.

Mein Problem ist, dass nach dem ersten Telegram:
-der UART Interrupt kommt
-das Startzeichen erkannt wird
-der DMA Transfer gestartet wird
-die Daten im Speicher landen (mit Debugger)
-der DMA_IRQ für vollständigen Transfer ausgelöst wird
-ABER NICHT die Callback-Function angesprungen wird...Die Adresse im 
CB-Descriptor ändert sich!

Ich konnte mittels Debugger folgendes feststellen:

aus der efm32_dma.h und dort ein Teil aus dem IRQ Handler
1
        /* Normally, no point in enabling interrupt without callback, but */
2
        /* check if callback is defined anyway. Callback info is always */
3
        /* located in primary descriptor. */
4
        cb = (DMA_CB_TypeDef *)(descr[channel].USER);
5
        if (cb)
6
        {
7
          /* Toggle next-descriptor indicator always prior to invoking */
8
          /* callback (in case callback reconfigurs something) */
9
          primaryCpy   = cb->primary;
10
          cb->primary ^= 1;
11
          if (cb->cbFunc)
12
          {
13
            cb->cbFunc(channel, (bool) primaryCpy, cb->userPtr);
14
          }
15
        }
16
      }

der CB Descriptor zeigt auf die richtige Adresse:
(beim ersten Aufruf, wo der Sprung zur CallBackfuntion geht)

cb:
-> 0x20001234
cbFunc:
->0x00002011 (Im Treiber im Anhang ist das die DMA_checkByte Routine)

beim zweiten Aufruf wo es nicht mehr geht:
cb:
->0x20001234
cbFunc:
->0x0000182D

Im Speicher kann ich sehen das sich die Adresse beim Sprung in die 
Callback Funktion ändert...das heißt wenn ich im Singelstep das Programm 
durchlaufe, bewirkt die erste Aktion in der cbFunction eine änderung des 
Pointers...obwohl ich sowas natürlich nicht will...

Woran scheiterts?
Ich hoffe es kann mir wer weiterhelfen

von bubi_00 (Gast)


Lesenswert?

Was ich vergessen habe:

0x00002010 B570      PUSH     {r4-r6,lr}
0x00002012 4604      MOV      r4,r0
0x00002014 460D      MOV      r5,r1
0x00002016 4616      MOV      r6,r2

Das steht dort an der Adresse!

r4: 0x20001234
r5: 0x00000000
r6: 0x00000001
lr: 0x0000182D !!!!!!!!!!!

Was macht das Ding hier? :(

von bubi_00 (Gast)


Lesenswert?

Selbstgespräch, Frage im Startpost ändert sich in:

Wenn ich "cb" als static definiere...warum gehts dann?
(...das heißt es geht jetzt, wüsste aber noch gerne warum)

Schöne Grüße

von Tante Käthe (Gast)


Lesenswert?

Schon mal hier versucht?
Meine letzte Frage wurde in 1 Tag beantwortet.

http://support.energymicro.com/home

Viel Erfolg ...

TK

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.