Hallo,
ich habe ein Problem mit der Kommunikation zweier STM32F2 mit SPI.
Ich habe einen Master und einen Slave. NSS habe ich in CubeMX auf
Hardware eingestellt.
Hier die Konfiguration:
Master:
1 | hspi3.Instance = SPI3;
|
2 | hspi3.Init.Mode = SPI_MODE_MASTER;
|
3 | hspi3.Init.Direction = SPI_DIRECTION_2LINES;
|
4 | hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
|
5 | hspi3.Init.CLKPolarity = SPI_POLARITY_HIGH;
|
6 | hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;
|
7 | hspi3.Init.NSS = SPI_NSS_HARD_OUTPUT;
|
8 | hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
|
9 | hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
10 | hspi3.Init.TIMode = SPI_TIMODE_DISABLED;
|
11 | hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLED;
|
12 | hspi3.Init.CRCPolynomial = 10;
|
13 | HAL_SPI_Init(&hspi3);
|
Slave:
1 | hspi3.Instance = SPI3;
|
2 | hspi3.Init.Mode = SPI_MODE_SLAVE;
|
3 | hspi3.Init.Direction = SPI_DIRECTION_2LINES;
|
4 | hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
|
5 | hspi3.Init.CLKPolarity = SPI_POLARITY_HIGH;
|
6 | hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;
|
7 | hspi3.Init.NSS = SPI_NSS_HARD_OUTPUT;
|
8 | hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
|
9 | hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
10 | hspi3.Init.TIMode = SPI_TIMODE_DISABLED;
|
11 | hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLED;
|
12 | hspi3.Init.CRCPolynomial = 10;
|
13 | HAL_SPI_Init(&hspi3);
|
Der Slave macht direkt zum Start ein TransmitReceive_IT
Der Master sendet irgendwann per TransmitReceive 16 byte zum Slave.
Die Daten kommen auf der Slave-Seite gut an und auch der Master empfängt
die am Anfang
fest abgelegte Information.
PROBLEM 1:
Der Slave geht in den HAL_SPITxRxCpltCallback. Dort ist
HAL_SPI_GetError() HAL_SPI_ERROR_NONE was ja auch gut ist. Jedoch
liefert der Aufruf HAL_SPI_GetState() entweder 0x20 oder 0xe0. Beide
Werte sind nicht im entsprechenden enum HAL_SPI_StateTypeDef zu finden.
Jetzt geht es weiter. Der Slave ist zufrieden und schickt ein einzelnes
Byte als Empfangsbestätigung an den Master zurück. Dafür macht der Slave
ein Transmit_IT und zieht einen Pin runter.
Problem 2:
Transmit_IT blockiert, was es nicht tun sollte. Daher habe ich zuerst
den Pin runtergezogen, dann Transmit_IT aufgerufen und der Master wartet
nach dem Pinwechsel jetzt 10us.
Und weiter gehts. Der Master merkt, dass der Pin runtergezogen wird und
macht ein Receive (Nach den erwähnten 10us). Das Byte kommt richtig an.
Der Slave startet ein neues TransmitReceive_IT und setzt den Pin wieder
zurück. Der Master erkennt das Pin Rücksetzen und fährt daraufhin fort,
die nächsten Daten zu senden.
Datensatz 2 wird gesendet. Es sind keine Errors mehr da und der State
ist beim Master aud Ready und beim Slave auf BusyTxRx, weil er ja auf
neue Daten wartet.
Problem 3:
Wieder ist wie nach dem Senden der SPI_State auf 0x20 oder 0xe0 auf
Slave Seite???
Problem 4:
Die im Master gesendeten Daten a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p
kommen so beim Slave an: 0,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o
Meine erste Überlegung: Der Slave war noch nicht bereit. Aber dann hätte
der Empfang bei b angefangen oder alle bits wären verschoben und der
HAL_SPI_TxRxCpltCallback wäre nicht aufgerufen worden, weil die 16 byte
nicht erreicht worden wären.
Weiter liefert HAL_SPI_GetError() ein HAL_SPI_ERROR_NONE.
Warum ist hier nicht zumindest ein CRC Fehler?
Demnach müssen die Daten ja richtig angekommen sein.
Aber warum stehen sie dann nicht im Empfangspuffer?
Hier der Aufruf beim Master:
1 | HAL_SPI_TransmitReceive(&hspi3, transmitData.data, receiveData.data, MessageSize, 1000);
|
Hier der am Anfang stehende Aufruf beim Slave:
1 | HAL_SPI_TransmitReceive_IT(&hspi3, transmitData.data, receiveData.data, MessageSize);
|
Wer kann mir zu den Problemen 1-4 weiterhelfen?
Vielen Dank!