mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STM32 DMA neustarten


Autor: Holger K. (holgerkraehe)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag

Ich versuche den DMA bei einem STM32 welcher als SPI fungiert, während 
der SPI Übertragung neuzustarten.

Das sieht wie folgt aus:

CS ------|____________________|--------
SCK       |||| |||| |||| ||||
DMA         |-----------------

Ein SCK Grüppchen |||| entspricht 8 Clocks bzw. einem Byte
Ich triggere intern auf die 5te Flanke des ersten Bytes und möchte ab da 
für die folgenden Bytes den DMA parat haben, so dass dieser die nächsten 
Bytes sendet.

Dazu habe ich folgenden Code getestet:

 void DMA_Config(void)
 {
   DMA_InitTypeDef  DMA_InitStructure;

   DMA_DeInit(DMA1_Channel5);
   DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI2->DR;   //0x4000380C;
   DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&dataSendA[0];
   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
   DMA_InitStructure.DMA_BufferSize = 3;
   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
   DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
   DMA_Init(DMA1_Channel5, &DMA_InitStructure);

   //DMA_ITConfig(DMA1_Channel5,DMA_IT_TC,ENABLE);

   DMA_Cmd(DMA1_Channel5, DISABLE);


   //DMA_ITConfig(DMA1_Channel5,DMA_IT_TC,ENABLE);
   SPI_I2S_DMACmd(SPI2,SPI_I2S_DMAReq_Tx,ENABLE);
 }





.....
//Neustarten:

  //DMA Deaktivieren
  DMA1_Channel5->CCR &= (uint16_t)(~DMA_CCR1_EN);

  //Adresse
  DMA1_Channel5->CMAR = (uint32_t)&dataSendA[0];

        //DMA Counter auf 3 Bytes
  DMA1_Channel5->CNDTR = 3;

        //SPI TX DMA Kanal aktivieren
  SPI2->CR2 |= SPI_I2S_DMAReq_Tx;

  //DMA Aktivieren
  DMA1_Channel5->CCR |= DMA_CCR1_EN;


Leider funktioniert dies nicht wie gewünscht.
Das erste Byte ist willkürlich. das zweite stimmt dann das dritte ist 0.

Hat jemand eine Idee?

Autor: Reginald L. (Firma: HS Ulm) (reggie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vergiss nicht ungelesene Bytes aus dem spi auszulesen, sonst wird sofort 
der dma bei der nächsten Aktivierung getriggert.
Such mal nach meinen Beiträgen zu spi und dma, da hatte ich ein 
ähnliches Problem.

: Bearbeitet durch User
Autor: Holger K. (holgerkraehe)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Reginald L. schrieb:
> Vergiss nicht ungelesene Bytes aus dem spi auszulesen

Hab ich...


Hier ist die vollständige routine:
void TIM1_CC_IRQHandler(void)
{

  uint8_t cmd;
  TIM1->SR = (uint16_t)~TIM_IT_CC1;
  //cmd = SPI2->DR;

  //DMA Deaktivieren
  DMA1_Channel5->CCR &= (uint16_t)(~DMA_CCR1_EN);

  //Adresse
  DMA1_Channel5->CMAR = (uint32_t)&dataSendA[0];
  DMA1_Channel5->CNDTR = 3;

  SPI2->CR2 |= SPI_I2S_DMAReq_Tx;

  //delay(2);

  //DMA Aktivieren
  DMA1_Channel5->CCR |= DMA_CCR1_EN;

  GPIOC->ODR = 0xFF;
  GPIOC->ODR = 0x00;
}


Im Anhang das Bild.
Es zeigt, dass ich 0x81, 0x75, 0x27 und 0x03 empfange.
Mein Buffer ist jedoch:
uint8_t  dataSendA[10] = {0x75, 0x33, 0x81, 0x01, 0x77, 0x14, 0x41, 0x63, 0x20, 0xAA};

Eine Merkwürdigkeit ist noch, dass wenn ich das Programm mehrmals 
hintereinander flashe, sich der DMA unterschiedlich verhält.
Manchmal sendet der SPI Slave nur 0x00 und dies immer, dann wieder 
0x81,0x75,0x27,0x03

: Bearbeitet durch User
Autor: Reginald L. (Firma: HS Ulm) (reggie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> GPIOC->ODR = 0xFF;
>   GPIOC->ODR = 0x00;
Guck doch nochmal über deinen Code drüber, vllt übersiehst du was ;)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.