Forum: Mikrocontroller und Digitale Elektronik lpc ssp dma-transfer verketten


von Grundschüler (Gast)


Lesenswert?

ich versuche per dma daten vom lpc1768 auf sd-karte zu übertragen. wenn 
ich die einzelnen dma-transfers im Hauptprogramm nacheinander aufrufe 
klappt es, so dass ich die Daten korrekt von der sd-karte zurücklesen 
kann. Verlagere ich die Ausführungskontrolle in den irq_handler, scheint 
die Übertragung im 16bit-modus statt im eingestellten 8bit-Modus zu 
verlaufen. Aus 0,1,2,3,4 wird 0,0,0,1,0,2,0,3 etc. Ich vermute den 
Fehler in der DMA-config, kann ihn aber nicht finden.

Merkwürdig ist auch, dass ich den dma-transfer nicht aufteilen kann. 
token+512 Datenbyte geht. Nur token per DMA und dann 512Byte per DMA 
geht nicht.
1
void DMA0_512bytes_transfer_to_SSP0(u32 buf_offset,uint32 count){
2
LPC_SSP0->DMACR=3;// ->DMACR=2;//tx en//176x
3
LPC_SC->DMAREQSEL = 0;// SC_DMASEL_timer0_MATCH1_notUART0rx;//i.V.m. DMAC_SRC_PERIP(9)LPC_GPDMACH0->DMACCConfig
4
LPC_SC->PCONP |= (1<<29);//Enable clock to DMA controller
5
LPC_GPDMA->DMACConfig=DMAC_CTRL_ENABLE;
6
7
LPC_GPDMACH0->DMACCSrcAddr = buffer+(buf_offset);
8
LPC_GPDMACH0->DMACCDestAddr =  &(LPC_SSP0->DR);
9
LPC_GPDMACH0->DMACCControl =(0
10
     |DMAC_CHAN_INT_TC_EN
11
     |DMAC_CHAN_SRC_AUTOINC
12
     |DMAC_CHAN_SRC_WIDTH_8
13
     |DMAC_CHAN_SRC_BURST_1
14
//     |DMAC_CHAN_DEST_AUTOINC
15
     |DMAC_CHAN_DEST_WIDTH_8
16
     |DMAC_CHAN_DEST_BURST_1
17
     |DMAC_CHAN_TRANSFER_SIZE(count)
18
     );
19
20
    LPC_GPDMACH0->DMACCConfig =(0
21
      | DMA_CHAN_IE_ITC_EN
22
 //      | DMAC_CHAN_FLOW_D_M2M
23
      | DMAC_CHAN_FLOW_D_M2P
24
//      | DMAC_CHAN_FLOW_D_P2M
25
//      | DMAC_SRC_PERIP(DMA_REQUEST_SSP0_TX)
26
//      | DMAC_SRC_PERIP(9)
27
//      | DMAC_SRC_PERIP(DMA_REQUEST_SSP0_RX)
28
      | DMAC_DEST_PERIP(DMA_REQUEST_SSP0_TX)
29
//      | DMAC_DEST_PERIP(DMA_REQUEST_SSP0_RX)
30
      );
31
}
32
33
34
35
v u32 DMATCCount=0,DMAErrCount,DMA_STATUS;
36
void DMA_IRQHandler(void)
37
{
38
  uint32_t regVal;
39
40
  regVal = LPC_GPDMA->DMACIntStat;
41
  if ( regVal )//not error
42
  {
43
  DMATCCount++;
44
  LPC_GPDMA->DMACIntTCClear = regVal;
45
46
  if ( regVal & (0x01<<0) )//channel0 ready 512Datenbytes
47
  {
48
    DMA_STATUS = 1;
49
    DMA3_transfer_from_SSP0(16);//rxfifo leeren
50
  }
51
  else if ( regVal & (0x01<<3) )//rxfifo leeren
52
  {
53
    DMA_STATUS = 2;
54
    DMA2_3bytes_transfer_to_SSP0();//++++++ crc, response
55
56
  }
57
  else if ( regVal & (0x01<<2) )//++++++ crc, response
58
  {
59
    DMA_STATUS = 3;
60
  }
61
  else if ( regVal & (0x01<<3) )
62
  {
63
    DMA_STATUS = 4;
64
  }
65
  }
66
67
  regVal = LPC_GPDMA->DMACIntErrStat;
68
  if ( regVal )
69
  {
70
  DMAErrCount++;
71
  LPC_GPDMA->DMACIntErrClr = regVal;
72
  }
73
  return;
74
}
75
76
77
78
static
79
int xmit_datablock_kk (  /* 1:OK, 0:Failed */
80
  const BYTE *buff,  /* Ponter to 512 byte data to be sent */
81
  BYTE token      /* Token */){
82
u32 zl;
83
  UINT n = 512,btx=512;
84
  WORD d;
85
  BYTE resp,tmp;
86
//  if (!wait_ready(500)) return 0;    /* Wait for card ready */
87
  DMA_STATUS=0;
88
  while(tmp!=0xff){tmp=xchg_spi(0xff);zl++;}
89
xchg_spi(token);          /* Send token */
90
91
92
//DMA1_1bytes_transfer_to_SSP0();
93
//while(!(LPC_GPDMA->DMACIntTCStat && (1<<1)));
94
95
96
//++++++ Datentransfer
97
//SSPxCR0 = 0x000F;        /* Select 16-bit mode */
98
SSPxCR0 = 0x0007;      /* Select 8-bit mode */
99
  DMA0_512bytes_transfer_to_SSP0(0,512); //buffer_offset,Anzahl_bytes
100
  while(!(LPC_GPDMA->DMACIntTCStat && (1<<0)));
101
/*  for (n = 0; n < 512; n++) {  // Push 8 frames into pipeline
102
      d = *buff++;
103
      SSPxDR = d;
104
      while ((SSPxSR & SSPSR_isBSY)) ;//0,55
105
  }*/
106
107
//++++++ rx_fifo leeren, 8 frames, bei DMA 16 frames
108
DMA3_transfer_from_SSP0(16);
109
while(!(LPC_GPDMA->DMACIntTCStat && (1<<3)));
110
/*for (n = 0; n < 8; n++) {
111
//      while (!(SSPxSR & SSPSR_RNE)) ;
112
      while ((SSPxSR & SSPSR_isBSY)) ;//0,55
113
      tmp=SSPxDR;
114
    }
115
*/
116
117
//++++++ crc, response
118
DMA2_3bytes_transfer_to_SSP0();
119
while(!(LPC_GPDMA->DMACIntTCStat && (1<<2)));
120
/*      xchg_spi(0xFF);
121
    xchg_spi(0xFF);  // Dummy CRC
122
    xchg_spi(0xFF);        // Receive data resp
123
*/
124
//  return 1;
125
lgi(6,1,zl);
126
}

von Grundschüler (Gast)


Lesenswert?

1.gefundener Fehler:
void DMA4_transfer_from_SSP0(u8 count){
LPC_SSP0->DMACR=3;// ->DMACR=2;//tx en//176x

tx und rx DMA sind gleichzeitig aktiviert

lässt sich durch die Verwendung von Definitionen vermeiden:
#define SSPxDMAdisable  0
#define SSPxRxDMAenable 1
#define SSPxTxDMAenable 2

von Lehrer (Gast)


Lesenswert?

Erstaunlich, was man heute in der Grundschule schon so alles macht...

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.