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 :-)
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
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.
Du könntest auch das Toggle Register als Ziel nehmen. Musst die Daten halt anderst vorbereiten. Aus 11000010011001111 wird dann 10100011010101000
:
Bearbeitet durch User
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); |
Ich kann das Verhalten bei dir NAchbauen maxima, sehe aber auch keine Lösung :-(
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 ;)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.