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