Forum: Mikrocontroller und Digitale Elektronik SAMD21 DMA auf Pin


von Frank17 (Gast)


Lesenswert?

Hallo,

ich denke mir gerade einen Knoten in den Kopf, und vielleicht kennt 
jemand die einfache Lösung.
Ich möchte am SAMD21 per DMA an einem Pin eine bestimmte Sequenz von 
High und Low erzeugen.
Klar ist, dass ein Timer den DMA triggert, und die Sequenz entsprechend 
vorbereitet im Speicher liegt.
Aber wie schaffe ich es, dass nicht alle Pins des Ports geändert werden?
Und wie schaffe ich es eine Sequenz wie 11000010011001111 auszugeben 
(damit schließen sich ja die SET und CLEAR Reister als DMA Ziel aus?

Würde mich über einen Tipp freuen :-)

von Marco H. (damarco)


Lesenswert?

Geht nicht da du immer nur 32bit an den PIO Controller in die Register 
übergeben kannst. Man kann das aber über den PWM Controller realisieren. 
Allerdings wird der Datenballast dadurch größer.

: Bearbeitet durch User
von Marco H. (damarco)


Lesenswert?

Es geht auch anders, in dem du die PIO Zugriffe über einen eigenen 
Händler organisiert. Also setPin() wirkt nicht mehr auf die PIO sondern 
auf deinen Handler. Der dann die Daten beim nächsten DMA zugriff mit 
rein schreibt.

von asdfasd (Gast)


Lesenswert?

Kannst du nicht einen SPI-Port nehmen?

von Christoph (gizmo)


Lesenswert?

Du könntest auch das Toggle Register als Ziel nehmen. Musst die Daten 
halt anderst vorbereiten.

Aus
11000010011001111
wird dann
10100011010101000

: Bearbeitet durch User
von maxima (Gast)


Lesenswert?

Hätte nun vorgeschlagen das ASF Beispiel von Atmel zu nehmen
http://asf.atmel.com/docs/3.16.0/samd21/html/asfdoc_sam0_sercom_usart_dma_use_case.html
aber dies führt bei mir hier zu einem "Bus error"

Vielleicht sieht ja wer den Fehler
1
#define DATA_LENGTH (256)
2
COMPILER_ALIGNED(16)
3
static uint32_t source_memory[DATA_LENGTH];
4
static volatile bool transfer_is_done = false;
5
COMPILER_ALIGNED(16)
6
DmacDescriptor example_descriptor SECTION_DMAC_DESCRIPTOR;
7
8
9
10
static void configure_dma_resource(struct dma_resource *resource)
11
{
12
  struct dma_resource_config config;
13
  dma_get_config_defaults(&config);
14
  dma_allocate(resource, &config);
15
}
16
17
static void setup_transfer_descriptor(DmacDescriptor *descriptor )
18
{
19
  struct dma_descriptor_config descriptor_config;
20
  dma_descriptor_get_config_defaults(&descriptor_config);
21
  descriptor_config.block_transfer_count = sizeof(source_memory)/4;
22
  descriptor_config.source_address = (uint32_t)source_memory + sizeof(source_memory);
23
  descriptor_config.destination_address =  0x41004480 + 0x1C;
24
  descriptor_config.beat_size =   DMA_BEAT_SIZE_WORD;
25
  descriptor_config.dst_increment_enable = false;
26
  dma_descriptor_create(descriptor, &descriptor_config);
27
}
28
29
30
31
32
33
configure_dma_resource(&example_resource);
34
setup_transfer_descriptor(&example_descriptor);
35
dma_add_descriptor(&example_resource, &example_descriptor);
36
dma_register_callback(&example_resource, transfer_done,  DMA_CALLBACK_TRANSFER_DONE);
37
dma_enable_callback(&example_resource, DMA_CALLBACK_TRANSFER_DONE);
38
39
40
dma_start_transfer_job(&example_resource);
41
dma_trigger_transfer(&example_resource);

von Frank17 (Gast)


Lesenswert?

Ich kann das Verhalten bei dir NAchbauen maxima, sehe aber auch keine 
Lösung :-(

von Frank17 (Gast)


Lesenswert?

PS: weiß jemand was der Callback-Error bedeutet? also was falsch läuft?

von Marco H. (damarco)


Lesenswert?

DMA_CALLBACK_TRANSFER_DONE übergibt eine Funktionspointer auf eine 
Funktion die aufgerufen wird wenn der Transfer beendet ist.

Der Code im ASF Beispiel ist ja deutlich länger, Problem ist meist bei 
diesen Beispielen das man wissen muss was hinter den Macros sich 
verbirgt. Wenn man nicht das Beispiel mit dem dort verwendeten Board als 
Projekt benutzt.

DMA_CALLBACK_TRANSFER_DONE ist ein Macros hinter dem ein Ausdruck steht 
der die Funktion veranlasst gewissen Sachen auszulösen.
1
dma_register_callback(&example_resource, transfer_done,  DMA_CALLBACK_TRANSFER_DONE);

Funktion übergeben
1
dma_enable_callback(&example_resource, DMA_CALLBACK_TRANSFER_DONE);

Funktion aktivieren

Muss schon verstehen was da passiert ;)

von Tecno-World (Gast)


Lesenswert?

Ich antworte mal, obwohl es schon ne Weile her ist, aber ich suchte auch 
eine Lösung (und habe sie gefunden).
Nun, der DMAC kann nur dort schreiben, wo er auch mit dem BUS verbunden 
ist.
Beim D21 ist leider der BUS der IO-Gruppe NICHT mit dem DMAC verbunden, 
deswegen kann man auch nichts ausgeben.

https://microchip.secure.force.com/microchipknowledge/articles/en_US/FAQ/Control-IO-port-using-DMAC-for-Cortex-M0--devices/?q=dma+port&l=en_US&fs=Search&pn=1

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.