SAMC21 SPI Slave mit DMA

Gast #6362086
Lesenswert?
• ▲
▼
Hallo zusammen,

ich möchte für ein Projekt einen SAMC21 mikrocontroller als SPI Slave 
verwenden. Um die Daten schnell genug, und ohne den Prozessor dabei zu 
stark auszulasten, möchte ich die Daten per DMA an das SPI Modul geben.

Meine Setup Funktion sieht aus wie folgt:
1
static DmacDescriptor dma_descriptor_array[2] __attribute__ ((aligned (16)));
2
static DmacDescriptor dma_writeback_array[2] __attribute__ ((aligned (16)));
3

4
uint8_t dma_rx_buffer[8];
5

6
void hal_init_dma(void) {
7
  
8
  MCLK->AHBMASK.bit.DMAC_ = 1;
9
  
10
  /* perform a software reset before enable DMA controller */
11
  DMAC->CTRL.reg &= ~DMAC_CTRL_DMAENABLE;
12
  DMAC->CTRL.reg = DMAC_CTRL_SWRST;
13
  
14
  /* setup descriptopr base address and write back section base address */
15
  DMAC->BASEADDR.reg =  (uint32_t) &dma_descriptor_array;
16
  DMAC->WRBADDR.reg = (uint32_t) &dma_writeback_array;
17
  
18
  /* enable all priority level at the same time */
19
  DMAC->CTRL.reg = DMAC_CTRL_DMAENABLE | DMAC_CTRL_LVLEN(0xf);
20
  
21
  /* perform a reset for channel 0 */
22
  DMAC->CHID.reg = DMAC_CHID_ID(0);
23
  DMAC->CHCTRLA.reg &= ~DMAC_CHCTRLA_ENABLE;
24
  DMAC->CHCTRLA.reg = DMAC_CHCTRLA_SWRST;  
25
  
26
  DMAC->CHCTRLB.reg = DMAC_CHCTRLB_TRIGACT_BEAT;
27
  DMAC->CTRL.reg =  DMAC_CTRL_LVLEN0 | DMAC_CTRL_DMAENABLE;
28
  
29
  dma_descriptor_array[0].BTCTRL.reg = DMAC_BTCTRL_DSTINC| DMAC_BTCTRL_VALID;
30
  dma_descriptor_array[0].BTCNT.reg = 8;
31
  dma_descriptor_array[0].SRCADDR.reg = (uint32_t) &SERCOM5->SPI.DATA;
32
  dma_descriptor_array[0].DSTADDR.reg = (uint32_t) &dma_rx_buffer[8];
33
  dma_descriptor_array[0].DESCADDR.reg = 0;
34

35
  DMAC->PRICTRL0.reg = 0;  
36
}

Ich würde gerne 8 Byte Daten nach dem Empfangen direkt in den 
dma_rx_buffer schreiben.
Mein aktueller Ansatz wäre es bei einem Chip Select Low Interrupt per 
software-flag einen DMA Transfer zu starten.
Ich habe das SERCOM5 Modul als SPI Slave konfiguriert. Das funktioniert 
auch, konnte ich bereits ohne DMA testen.
1
void SERCOM5_Handler() {
2
  
3
  /* flag is set when nCS pin is going low */
4
  if (SERCOM5->SPI.INTFLAG.bit.SSL && SERCOM5->SPI.INTENSET.bit.SSL) {
5
    SERCOM5->SPI.INTFLAG.reg = SERCOM_SPI_INTFLAG_SSL;
6
    DMAC->CHID.reg = DMAC_CHID_ID(0);
7
DMAC->CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE;
8
  }
9
}

Leider scheint mein Ansatz so nicht zu funktionieren. Kann mir jemand 
mit dem Problem weiterhelfen und ist das überhaupt der richtige Ansatz 
für den Empfang der Daten mit DMA? Habe ich vielleicht einen Fehler in 
der Konfig des DMA Controllers? Danke für eure Hilfe.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.