Guten Tag,
Ich versuche gerade eine SPI-Kommunikation zwischen dem ESP32S3 und
einem MKE02 MCU (FRDM_KE02Z40M EVA-Board) herzustellen. Leider verhält
sich das Programm nicht so wie es soll und ich bin mir nicht sicher ob
der Fehler bei mir liegt (vermutlich schon) oder das SPI-Modul auf dem
Board fehlerhaft ist.
Der ESP32S3 sendet als Master 32 Byte an Daten. Das FRDM_KE02Z40M Board
sollte 32 Byte zurück senden.
Allerdings, obwohl die Daten, welche vom ESP32S3 gesendet werden korrekt
beim FRDM Board ankommen, wird nur das erste Byte, welches der MKE02 MCU
schicken soll übertragen. Nach dem ersten Byte erhält der ESP32S3 nur
ein Echo seiner eigenen Nachricht. (Das Freedom Board sollte hier z.B.
zu testzwecken 0xBB 32 mal schicken)
Daten gesendet vom ESP32S3:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
Daten die der MKE02Z (FRDM-Board) schicken sollte:
BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB
BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB
Daten Empfangen vom ESP32S3:
BB 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E
0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E
Der relevante Code der ISR sieht wie folgt aus:
1 | void spi_slave_irq(spi_handle_t *handle){
|
2 | uint8_t flags = spi_getStatusRegister();
|
3 | //Check wether the Transmit Buffer empty flag is set and if so, write the next 8 bit to SPI0_D
|
4 | if(((flags & 0xFFU) & SPI_S_SPTEF_MASK) != 0)
|
5 | {
|
6 | spi_write_shiftregister(*(handle->txData));
|
7 | handle->txData++;
|
8 | handle->txindex++;
|
9 | }
|
10 | //Check wether the Recieve Buffer full flag is set and if so, read the next 8 bit from SPI0_D
|
11 | if(((flags & 0xFFU) & SPI_S_SPRF_MASK) != 0)
|
12 | {
|
13 | *(handle->rxData) = spi_read_shiftregister();
|
14 | handle->rxData++;
|
15 | handle->rxindex++;
|
16 | }
|
17 | ...
|
Es gibt eine RxBuffer und eine TxBuffer Flag, diese werden gesetzt,
sollte der entsprechende mit dem Shiftregister verbundene Buffer
Voll(rx)/Leer(tx) sein.
Das Shiftregister wird zuverlässig alle 8bit in den Buffer kopiert, die
RxBuffer Full Flag wird zuverlässlich während der Übertragung gesetzt,
die ISR gestartet und die Daten aus dem Buffer herauskopiert.
Allerdings wird die TxEmpty Flag während einer Übertragung NIE gesetzt,
die TxFlag wird ausschließlich vor oder nach einer Übertragung gesetzt.
Also wenn der ESP startet, dann wird die TXFlag gesetzt, der Buffer
gefüllt, der Buffer direkt in das Shiftregister kopiert und die Flag
erneut gesetzt. Dann wird das nächste Byte in den Buffer kopiert und das
System idled bis eine Übertragung beginnt.
Ich habe die Vermutung, dass der mit dem Shiftregister verbundene Buffer
während einer übertragung, also während der ss low ist nicht auf das
Shiftregister kopiert wird. [ESP_SPI_MODELL.jpg]
Das würde in sofern Sinn machen, als dass die Daten, welche der ESP32S3
auf das MKE-Shiftregister geshifted hat, bestehen bleiben würden, sollte
der MKE02Z nicht neue Daten auf das Register kopieren. Dass hätte genau
den besagten Effekt, dass das erste nach dem Start auf das Register
kopierte Byte korrekt übertragen wird und jedes weitere Byte eine Kopie
der Daten vom ESP32S3 ist.
Wenn ich die Kommunikation durch den ESP32 nach jedem Byte unterbreche
und für das nächste Byte eine neue Kommunikation starte, werden die
Daten korrekt übertragen. (Logic Analyzer Screenshot, in diesem Test
sendet der ESP32 die Hexzahlen von 0 bis 1F, der MKE sendet diese
ebenfalls)[Workaround.png]
Ich habe versucht eine Skizze der Funktionsweise des SPI-Moduls zu
erstellen, wie ich Sie aus dem Reference Manual herausgelesen habe.
Meiner Ansicht nach, funktioniert wie gesagt das Kopieren des TxBuffers
auf das Shiftregister nicht, während der Slave Select low
ist.[ESP_SPI_MODELL.jpg]
Der beschriebene Fehler tritt mit 2 baugleichen FRDM Evaluation Boards
genau gleich auf. Der Fehler tritt auf, mit meinem selbstgeschriebenen
Treiber, so wie mit dem bereitgestellten Freescale Treiber der Firma NXP
und dem Treiber auf CMSIS Basis (auch von NXP)
Ist euch ein entsprechender Fehler schon einmal vorgekommen? Ist es
möglich, dass ein entsprechender Fehler des SPI-Moduls nicht aufgefallen
wäre?
Ich habe nach Datenblatt und Reference Manual keinen direkten Zugriff
auf den mit dem SPI0_D Register verbundenen Buffer. Ich kann lediglich
auf das "Register" zugreifen.
Ich danke euch vielmals für eure Erfahrung und hoffe ihr könnt mir
erklären, ob der Fehler an mir liegt oder wirklich das verbaute SPI
Modul
einen Funktionsfehler haben könnte.