Forum: Mikrocontroller und Digitale Elektronik [xmega128a1] SPI Slave DMA RX TX


von Markus C. (ljmarkus)


Lesenswert?

Hallo,

per SPI Slave DMA kann ich Daten empfangen. Nur wie sieht es aus, mit 
dem zurücksenden?

per DMA werden die Daten in "Rx_Buf" geschrieben. Die Daten in "Tx_Buf" 
sollen gesendet werden.

Hat einer eine Idee?

Viele Grüße,
Markus
1
ISR (PORTA_INT0_vect) // Sync with SS-Pin
2
{
3
  DMA.CH0.CTRLA |= (1<<DMA_CH_ENABLE_bp);
4
}
5
6
int main(void)
7
{
8
  
9
  // init SPI
10
  PORTC.DIR = 0x41;
11
  SPIC.CTRL = (0<<SPI_CLK2X_bp)
12
            | (1<<SPI_ENABLE_bp)
13
        | (0<<SPI_DORD_bp)
14
        | (0<<SPI_MASTER_bp)
15
        | SPI_MODE_0_gc;
16
        
17
  SPIC.INTCTRL = SPI_INTLVL_OFF_gc;
18
  
19
  
20
  // init DMA Controller
21
  DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_SPIC_gc;
22
  
23
  DMA.CH0.TRFCNT = 2048;    // Data length
24
  DMA.CH0.REPCNT = 0;
25
  
26
  DMA.CH0.SRCADDR0  = (((uint16_t) &SPIC.DATA) >> 0*8) & 0xff;
27
  DMA.CH0.SRCADDR1  = (((uint16_t) &SPIC.DATA) >> 1*8) & 0xFF;
28
  DMA.CH0.SRCADDR2  = 0;
29
  
30
  DMA.CH0.DESTADDR0 = (((uint16_t) Rx_Buf) >> 0*8) & 0xff;
31
  DMA.CH0.DESTADDR1 = (((uint16_t) Rx_Buf) >> 1*8) & 0xFF;
32
  DMA.CH0.DESTADDR2 = 0;
33
  
34
  
35
  DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_NONE_gc
36
                   | DMA_CH_SRCDIR_FIXED_gc
37
           | DMA_CH_DESTRELOAD_TRANSACTION_gc
38
           | DMA_CH_DESTDIR_INC_gc;
39
           
40
           
41
  DMA.CH0.CTRLB = DMA_CH_ERRINTLVL_OFF_gc
42
                | DMA_CH_TRNINTLVL_HI_gc;
43
          
44
          
45
  DMA.CH0.CTRLA = (1<<DMA_CH_ENABLE_bp)
46
                | (0<<DMA_CH_RESET_bp)
47
          | (0<<DMA_CH_REPEAT_bp)
48
          | (0<<DMA_CH_TRFREQ_bp)
49
          | (1<<DMA_CH_SINGLE_bp)
50
          | DMA_CH_BURSTLEN_1BYTE_gc;
51
          
52
          
53
  
54
  
55
  
56
  DMA.CTRL = (1<<DMA_CH_ENABLE_bp)
57
           | (0<<DMA_CH_RESET_bp)
58
       | (0<<DMA_DBUFMODE_gp)
59
       | (0<<DMA_PRIMODE_gp);
60
       
61
  
62
PORTA.INT0MASK = PIN4_bm;
63
PORTA.PIN4CTRL = PORT_OPC_WIREDANDPULL_gc | PORT_ISC_FALLING_gc;
64
PORTA.INTCTRL |= PORT_INT0LVL_HI_gc;
65
66
PMIC.CTRL |= PMIC_HILVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm;    
67
sei();
68
69
while(1)
70
 {
71
 .......
72
 }
73
}
74
75
ISR( DMA_CH0_vect)
76
{
77
  DMA.INTFLAGS |= (1<<DMA_CH0TRNIF_bp);
78
  //DMA.CH0.CTRLA |= (1<<DMA_CH_ENABLE_bp);
79
  
80
  PORTC.OUTTGL = 0x01;
81
}

von Basti M. (counterfeiter)


Lesenswert?

mit SPI gar nicht... mit UART in SPI Mode wie im Datenblatt schon 
eher...

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

SPI empfängt und sendet doch immer gleichzeitig. Daher musst Du die 
Daten aus dem Slave über Dummybytes vom Master holen. Du empfängst im 
Slave ein Kommando. Daraufhin bereitest Du die Antwort vor, indem Du das 
betreffende Byte in das SPI-Datenregister schreibst. Wenn der Master nun 
sein Dummy sendet wird das Datenbyte gleich mit herausgeschoben und der 
Master kann es einlesen. Daraufhin bereitst Du ggf. das nächste Byte 
vor. Dies kann auch über DMA erledigt werden, wenn Du Dir einen 
passenden Trigger für einen 2. Kanal baust.

Basti M. schrieb:
> mit SPI gar nicht... mit UART in SPI Mode wie im Datenblatt schon
> eher...

Unsinn. Slave SPI ist interruptfähig und kann somit das DMA triggern. 
Master-SPI ist nicht DMA-fähig. Dafür nimmt man dann lieber ein UART.

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.