STM32 SPI Interrupt Ringpuffer verliert Zeichen

OP #3241475
Hallo ich habe Probleme mit einem SPI Ringpuffer für den STM32F103. Das 
Senden und Empfangen funktioniert ohne Interrupt. Auch mit einem 
Interrupt funktioniert es. In dieser Implementation mit Ringpuffer wird 
der letzte Wert nicht empfangen. Also zum Beispiel sende ich 6 Zeichen 
empfange aber nur 5. Wenn ich im nachhinein schaue, ist das 
SPI_I2S_FLAG_RXNE Bit sogar gesetzt, ich bekomme jedoch keinen 
Interrupt. Wieso nicht? Seltsam ist, dass wenn ich
1
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);
auskommentiere nichts mehr funktioniert.

Habt ihr eine Idee hier ist meine ISR, vielleicht sehr ihr ja was da 
falsch läuft.
Danke
1
void SPI2_IRQHandler(void){
2

3
  // Receive
4
  if(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == SET){
5
    
6
    if(inCurrent != bufferPos){
7
      // Data in Receive Buffer
8
      inBuffer[inCurrent] = SPI2->DR; // save data
9
      inCurrent = (inCurrent + 1) % FLA_BUFFER_SIZE;
10

11
    }else{ // all data received  disable RX Interrupt
12
      SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE | SPI_I2S_IT_RXNE, DISABLE);
13
    }
14
    SPI_I2S_ClearITPendingBit(SPI2, SPI_I2S_IT_RXNE);
15
    DEBUG_YELLOW_OFF;
16
    
17
  // Transmit
18
  }else if(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == SET){
19
    
20
    DEBUG_YELLOW_ON;
21
    if(outCurrent != bufferPos){ // Transmit buffer contains data to send
22
      SPI2->DR = outBuffer[outCurrent]; // send data
23
      outCurrent = (outCurrent + 1) % FLA_BUFFER_SIZE;
24
    }else{ // Transmit buffer empty
25
      SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);
26
    }
27
    SPI_I2S_ClearITPendingBit(SPI2, SPI_I2S_IT_TXE);
28
  }
29
}
OP
mein Ringpuffer ist 16 Zeichen lang. Ich schreibe in einem Beispel 6 
Zeichen und bekomme über SPI nur 5 zurück. Gleiches passiert, wenn ich 
nur ein Zeichen sende. Dann bekomme ich kein Zeichen zurück.

Die Variable bufferPos gibt die aktuelle Position des Schreibzeigers an. 
Also wenn ich Daten senden will erhöht sich bufferPos. Wenn sie gesendet 
wurden, rückt outCurrent nach und wenn ich ein Zeichen zurück bekomme, 
wird inCurrent erhöht.
Gast
Also nochmal zu bufferPos:
Wenn xxxCurrent noch nicht gleich bufferPos, dann existieren noch Daten, 
die gesendet, empfangen werden. Wenn es gleich ist (else) wurde alles 
gesendet/empfangen. Ist doch egal wie rum man es dreht ... oder etwa 
nicht? :/
1
||||||||||||||||||||| ... |||| <- Daten
2
       |  |         |
3
       |  |         bufferPos
4
       |  |         
5
       |  outCurrent         
6
       |  
7
       inCurrent
Wenn Daten hinzukommen wird auch bufferPos erhöht. outCurrent und 
inCurrent werden erst erhöht, wenn Daten gesendet/empfangen wurden.
Sorry, ich sehe nur das inCurrent und outCurrent verändert werden.
Wo bufferPos geändert wird sagt mir selbst meine Glaskugel nicht.

So wie Du es beschreibst und so wie Dein Code es darstellt, kann es 
passieren, inCurrent outCurrent überholt...

Vielleicht solltest Du mal Deinen ganzen Code zeigen...

Gruß
Frank
OP
1
void Send(uint8_t d){
2
  outBuffer[bufferPos] = d;
3
  bufferPos = (bufferPos+ 1) % FLA_BUFFER_SIZE;
4
}
5

6
void ClearBuffer(){
7
  for (uint8_t i = 0; i < FLA_BUFFER_SIZE; i++){
8
    inBuffer[i]  = 0x00;
9
    outBuffer[i] = 0x00;
10
  }
11
  inCurrent = 0;
12
  outCurrent = 0;
13
  bufferPos= 0;
14
}


Also ich hoffe es ist klar geworden, dass nur bufferPos manuell gesetzt 
wird. inCurrent und ourCurrent sind also die beiden "Read" Zeiger in 
Ringpuffer sprache. Ich dachte, dass ich bei SPI immer so verfahren 
kann, da ich pro gesendetem Zeichen auch eines zurückbekomme.
Nochmals meine Bitte, zeig Deinen kompletten Code oder reduziere ihn auf 
ein lauffähiges Stück Code mit dem das ganze nachvollzogen werden kann.

So ist meine antwort "42" weil die paar Zeilen aus Deinem letzten 
Posting helfen nicht weiter.

Gruß
Frank

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.