SAMD21 DMA auf Pin

Gast #5107153
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 :-)
Gast #5110440
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);
#5110888
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 ;)
Gast #5566448
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren