lpc ssp dma-transfer verketten

Gast #3683402
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
}
Gast #3683860
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren