STM32 SPI Interrupt Ringpuffer verliert Zeichen

OP #3241475
Lesenswert?

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 #3241618
Lesenswert?

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 #3242328
Lesenswert?

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.
#3242396
Lesenswert?

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 #3242437
Lesenswert?

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.

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