[xmega] USART RX ISR umstellen auf DMA

OP #3152077
Lesenswert?
• ▲
▼
Hallo,

ich würde gerne meine ISR für den USART_RX auf DMA umstellen.

CPU: XMEGA32A4

Es werden immer 600 Byte vom PC gesendet. Als Startflag für 600 Byte 
wird per ISR Pin Rising Edge gemacht.

Wer kann mir helfen es auf DMA umzustellen?



Derzeit schaut es so aus:
--------------------------
1
volatile uint16_t buffer_counter;
2
volatile uint8_t buffer_in[600];
3

4
/****************************************************************************/
5
ISR (USARTC0_RXC_vect)
6
{
7
  buffer_in[buffer_counter] = USARTC0.DATA;
8
  buffer_counter++;
9
}
10

11
/****************************************************************************/
12
ISR (PORTA_INT0_vect)
13
{
14
  buffer_counter = 0;
15
}
16

17
/****************************************************************************/
18
void init_usartC0(void)
19
{
20
  PORTC.DIRSET = PIN3_bm;  // PC3 (TXC0) as output.
21
  PORTC.DIRCLR = PIN2_bm; // PC2 (RXC0) as input.
22
    
23
  
24
  // 32 Mhz - B460800
25
  USARTC0.BAUDCTRLA = 107;
26
  USARTC0.BAUDCTRLB = 0b10110000;  
27
  
28
  
29
  USARTC0.CTRLA = USART_RXCINTLVL_HI_gc;
30
  USARTC0.CTRLB = USART_RXEN_bm | USART_TXEN_bm;
31
  USARTC0.CTRLC = USART_CMODE_ASYNCHRONOUS_gc | USART_CHSIZE_8BIT_gc | USART_PMODE_DISABLED_gc;
32
}
33

34
/****************************************************************************/
35
int main(void)
36
{
37
  
38
  system_clocks_init(4);  // 8Mhz * 4 = 32Mhz
39
  
40
  
41
  PORTA.DIRSET = PIN5_bm;  // Output
42
  PORTA.DIRSET = PIN6_bm;  // Output
43
  PORTA.DIRSET = PIN7_bm;  // Output
44
  PORTB.DIRSET = PIN0_bm;  // Output
45
  
46
  
47
  //PORTA.OUTCLR = PIN5_bm;
48
  PORTA.OUTSET = PIN5_bm;  // OFF
49
  PORTA.OUTSET = PIN6_bm;  // OFF
50
  PORTA.OUTSET = PIN7_bm;  // OFF
51

52
  
53
  // PORTA PIN 4 Interrupt einstellen steigende flanke
54
  PORTA.INT0MASK = PIN4_bm;
55
  PORTA.PIN4CTRL = PORT_OPC_PULLDOWN_gc | PORT_ISC_RISING_gc;  // Pull Down einschalten, ISR steigende Flanke
56
  PORTA.INTCTRL |= PORT_INT0LVL_HI_gc;    // High Level Interrupt
57

58

59
  init_usartC0();
60
  
61
  
62
  // Enable Interrupts
63
  PMIC.CTRL |= PMIC_HILVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm;    
64
  sei();
65
  
66

67
  while(1)
68
    {
69
    PORTA.OUTTGL = PIN5_bm;
70
    }
71
}

Danke, Markus
OP #3152889
Lesenswert?
• ▲
▼
Guten Morgen,

mit Hilfe AppNode AVR1510 habe ich den DMA soweit ans laufen bekommen.
Nur mit dem "Restart" des DMA komme ich nicht klar.
Derzeit löse ich es wie in der "ISR (PORTA_INT0_vect)".

Würde aber gerne auf die ISR verzichten und dem DMA einen Restart 
beibringen.

Hat von euch einer eine Idee?

1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include "clksys_driver.h"
4
#include "dma_driver.h"
5

6

7
#define data_size  600
8

9
static uint8_t Rx_Buf[data_size];
10

11
#define DMA_RX_Channel &DMA.CH0
12

13
/****************************************************************************/
14
ISR (PORTA_INT0_vect)
15
{
16
  SetupReceiveChannel();
17
  DMA_EnableChannel( DMA_RX_Channel );
18
}
19

20
/****************************************************************************/
21
void init_usartC0(void)
22
{
23
  PORTC.DIRSET = PIN3_bm;  // PC3 (TXC0) as output.
24
  PORTC.DIRCLR = PIN2_bm; // PC2 (RXC0) as input.
25
  
26
  // 32 Mhz - B460800
27
  USARTC0.BAUDCTRLA = 107;
28
  USARTC0.BAUDCTRLB = 0b10110000;  
29
  
30
  //USARTC0.CTRLA = USART_RXCINTLVL_HI_gc;
31
  USARTC0.CTRLB = USART_RXEN_bm | USART_TXEN_bm;
32
  USARTC0.CTRLC = USART_CMODE_ASYNCHRONOUS_gc | USART_CHSIZE_8BIT_gc | USART_PMODE_DISABLED_gc;
33
}
34

35
/****************************************************************************/
36
void SetupReceiveChannel(void)
37
{
38
  DMA_SetupBlock(
39
          DMA_RX_Channel,
40
          (void *) &USARTC0.DATA,
41
          DMA_CH_SRCRELOAD_NONE_gc,
42
          DMA_CH_SRCDIR_FIXED_gc,
43
          Rx_Buf,
44
          DMA_CH_DESTRELOAD_NONE_gc,
45
          DMA_CH_DESTDIR_INC_gc,
46
          data_size,
47
          DMA_CH_BURSTLEN_1BYTE_gc,
48
          0, // Perform once
49
          true
50
          );
51
          
52
  DMA_EnableSingleShot(DMA_RX_Channel);
53
  // USART Trigger source, Receive complete
54
  DMA_SetTriggerSource(DMA_RX_Channel, DMA_CH_TRIGSRC_USARTC0_RXC_gc);
55
}
56

57
/****************************************************************************/
58
int main(void)
59
{
60
  system_clocks_init(4);  // 8Mhz * 4 = 32Mhz
61
  
62
  
63
  PORTA.DIRSET = PIN5_bm;  // Output
64
  PORTA.DIRSET = PIN6_bm;  // Output
65
  PORTA.DIRSET = PIN7_bm;  // Output
66
  PORTB.DIRSET = PIN0_bm;  // Output
67
  
68
  
69
  //PORTA.OUTCLR = PIN5_bm;
70
  PORTA.OUTSET = PIN5_bm;  // OFF
71
  PORTA.OUTSET = PIN6_bm;  // OFF
72
  PORTA.OUTSET = PIN7_bm;  // OFF
73
  
74
  _delay_ms(500);
75
  
76
  
77
  // PORTA PIN 4 Interrupt einstellen steigende flanke
78
  PORTA.INT0MASK = PIN4_bm;
79
  PORTA.PIN4CTRL = PORT_OPC_PULLDOWN_gc | PORT_ISC_RISING_gc;  // Pull Down einschalten, ISR steigende Flanke
80
  PORTA.INTCTRL |= PORT_INT0LVL_HI_gc;    // Low Level Interrupt
81

82

83
  init_usartC0();
84
  
85
  DMA_Enable();
86
  //SetupReceiveChannel();
87
  //DMA_EnableChannel( DMA_RX_Channel );
88
  
89
  
90
  // Enable Interrupts
91
  PMIC.CTRL |= PMIC_HILVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm;    
92
  sei();
93
  
94
  
95
  while(1)
96
    {
97
    PORTA.OUTTGL = PIN5_bm;
98
    }
99
}

Danke,
Markus

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.