STM32G0 SPI RXNE hängt sporadisch

OP #7420894
Lesenswert?

Hallo,

ich habe ein sporadisches Problem mit der SPI-Schnittstelle vom STM32 G0. Die Schnittstelle wird manuell betrieben und dient der Kommunikation mit einem MCP3561. Im Betrieb und auf der normalen Platine funktioniert alles einwandfrei. Für Hardware-in-the-Loop Tests ersetzen wir den MCP3561 mit einem SPI-Slave. Bevor wir diesen aber durchtesten können, haben wir das Problem, dass unsere Sende/Empfangsroutine hängen bleibt. Da wir den SPI im Master betreiben, sollte eigentlich im schlimmsten Falle irgendein Müll eingelesen werden, aber hauptsache irgendwas wird eingelesen? Hier der Code:

1
uint8_t mySPITransmitReceiveBlocking(uint8_t *tx_data, uint8_t *rx_data, uint16_t size){
2
  uint8_t crcerror = 0;
3
  //  if CRC is enabled, reset CRC registers
4
  if(SPI2->CR1 & SPI_CR1_CRCEN){
5
    SPI2->CR1 &= ~SPI_CR1_CRCEN;
6
    SPI2->CR1 |= SPI_CR1_CRCEN;
7
  }
8
  __disable_irq();
9
  SPI2->CR1 |= SPI_CR1_SPE;  //  enable SPI
10
  for(int i = 1; i <= size; i++){
11
    while(!(SPI2->SR & SPI_SR_TXE));
12
    *((__IO uint8_t *)&SPI2->DR) = (uint8_t) *tx_data;
13
    tx_data++;
14
    if(i == size){  //  if CRC is enabled, send CRC next if transmission is finished
15
      if(SPI2->CR1 & SPI_CR1_CRCEN){
16
        SPI2->CR1 |= SPI_CR1_CRCNEXT;
17
      }
18
    }
19
    while(!(SPI2->SR & SPI_SR_RXNE));
20
    *rx_data = (*((__IO uint8_t *)&SPI2->DR));
21
    rx_data++;
22
  }
23
  //  CRC CHECK
24
  if(SPI2->CR1 & SPI_CR1_CRCEN){
25
    //  16 bit CRC is sent automatic, but must be read!
26
    while(!(SPI2->SR & SPI_SR_RXNE));
27
    uint8_t dummy = (*((__IO uint8_t *)&SPI2->DR));
28
    while(!(SPI2->SR & SPI_SR_RXNE));
29
    dummy = (*((__IO uint8_t *)&SPI2->DR));
30
    (void)dummy;  //  remove warning of ununsed variable
31

32
    //  check crc flag
33
    if(SPI2->SR & SPI_SR_CRCERR){
34
      //  wrong crc value
35
      SPI2->SR &= ~SPI_SR_CRCERR;
36
      crcerror = 1;
37
    }
38
  }
39
  __enable_irq();
40
  while(SPI2->SR & SPI_SR_BSY);
41
  SPI2->CR1 &= ~SPI_CR1_SPE;  //  disable SPI
42
  return crcerror;
43
}

Hier bleibt er ab und zu bei "while(!(SPI2->SR & SPI_SR_RXNE));" hängen. Auf der bestückten Platine tut er das Ganze nicht. Kann das Ganze am Slave liegen? Oder übersehe ich irgendetwas, als Master sollte ja nach jedem Rausschicken auch irgendetwas im Empfangsregister sein.

Viele Grüße

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