Forum: Mikrocontroller und Digitale Elektronik STM32F373 16 bit an 8 Bit SPI per DMA - Erstes Datenpaket immer beschnitten


von Gerrit G. (gerrito)


Lesenswert?

Moin!

Ich komme nicht weiter und hab keine Ideen mehr...

Ich habe ein uint16_t array, dass ich mit der SPI und DMA übertragen 
muss. Die SPI überträgt 8 Bit.

Ich habe das Problem, dass vom ersten Eintrag immer die ersten 8 Bit 
fehlen, aber nur, wenn ich das Paket mit DMA übertrage. Ohne DMA 
funktioniert es einwandfrei.
1
//erste Paket immer beschnitten
2
HAL_SPI_Transmit_DMA(&hspi3, (uint8_t *) buffer, BUFFER_SIZE*2);
3
4
//funktioniert 
5
HAL_SPI_Transmit(&hspi3, (uint8_t *) buffer, BUFFER_SIZE*2, 10);
1
Beispielergebnis mit DMA (buffer[]):
2
911
3
998
4
1093
5
...
6
7
übertrage wurde:
8
143
9
998
10
1093
11
...

DMA ist auf Byte (periphery) und half_word mit incremet adress (memory) 
eingestellt.

Ist das Ding hier irgendwie verbuggt, oder habe ich was übersehen?

Vielen Dank vorab!

von Rbx (rcx)


Lesenswert?

Gerrit G. schrieb:
> Ist das Ding hier irgendwie verbuggt, oder habe ich was übersehen?

So auf den ersten Blick sieht das ganze eher aus wie ein typisches 
C-Problem ;)

von Harald K. (kirnbichler)


Lesenswert?

Hast Du Dir mal die Startadresse Deines Array angesehen? Vielleicht ist 
das ja nicht an einer WORD/DWORD-Grenze ausgerichtet.

von Sum S. (sumsum)


Lesenswert?

Ja das sieht ganz sicher nach einen Problem aus.
Ganz Sicher! ... oder könnte es ein anderes Problem sein?

von Gerrit G. (gerrito)


Lesenswert?

Die Startadresse aus dem Speicher wird sauber in hspi -> pTxBuffPtr 
übertragen. Genau wie die Größe usw. Ist in beiden Funktionen identisch 
aufgebaut.
Hab die Adresse auch schon mal um 16 bit, bzw. 8 Bit verschoben, dann 
wird das erste Paket sauber übertrage - ist dann aber der 2. Wert und 
der erste ist Müll.

: Bearbeitet durch User
von N. M. (mani)


Lesenswert?

Schau halt Mal ins Erata...

von Rbx (rcx)


Lesenswert?

Sum S. schrieb:
> Ja das sieht ganz sicher nach einen Problem aus.
> Ganz Sicher! ... oder könnte es ein anderes Problem sein?

Ich denke schon, dass Ungenauigkeit hier eine gewisse Rolle spielt.

von Harald K. (kirnbichler)


Lesenswert?

Gerrit G. schrieb:
> Die Startadresse aus dem Speicher wird sauber in hspi -> pTxBuffPtr
> übertragen.

"Sauber", was auch immer das sein mag. Aber liegt sie auf einer 
WORD/DWORD-Grenze?

Zeig' doch mal konkret so eine Startadresse als Hexzahl.

von Wastl (hartundweichware)


Lesenswert?

Gerrit G. schrieb:
> Ist das Ding hier irgendwie verbuggt, oder habe ich was übersehen?

Ja. Du hast es verpasst einen Quellcode zu zeigen wo alle
beteiligten Code-Teile zu sehen sind.

von Gerrit G. (gerrito)


Lesenswert?

Hab gerade mal das Skope drangehangen und geschaut. Die Daten werden 
sauber übertragen. Beim Zurücklesen antwortet der Speicher beim ersten 
Byte einfach nicht. Problem... CS wird nicht deaktiviert und somit gibt 
es beim folgenden Auslesen logischerweise einen Fehler.

Ich deaktiviere CS in der CallbackFunction. Beim debuggen stelle ich 
jetzt aber fest, dass diese Funktion überhaupt nicht aufgerufen wird.
1
void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma_spi3_tx) {
2
  StopWriting();    //wird nicht ausgeführt! Daher bleib CS aktiv
3
}

Und noch eine Frage... Wieso werden die Daten eigentlich rückwärts 
zerlegt übertragen?

Also... 43981 (AB CD) wird über die SPI als CD AB gesendet.

: Bearbeitet durch User
von Harald K. (kirnbichler)


Lesenswert?

Gerrit G. schrieb:
> Wieso werden die Daten eigentlich rückwärts
> zerlegt übertragen?

LittleEndian/BigEndian.

Ist ein Darstellungsding.

von Wastl (hartundweichware)


Lesenswert?

Gerrit G. schrieb:
> Wieso werden die Daten eigentlich rückwärts zerlegt übertragen?

Es wird wohl so übertragen wie deine SPI-Konfiguration
es festgelegt hat.

von Εrnst B. (ernst)


Lesenswert?

Gerrit G. schrieb:
> Ich deaktiviere CS in der CallbackFunction. Beim debuggen stelle ich
> jetzt aber fest, dass diese Funktion überhaupt nicht aufgerufen wird.

Kontrolliere, ob USE_HAL_SPI_REGISTER_CALLBACKS definiert und nicht "0" 
ist...

Ansonsten kannst du die globale "weak" HAL_SPI_TxCpltCallback 
überschreiben.
1
extern "C" void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef* hspi);
2
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef* hspi) {
3
  if (hspi == der_spi_der_gemeint_ist) {
4
     StopWriting();
5
...

von Gerrit G. (gerrito)


Lesenswert?

Danke Εrnst!
1
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef* hspi3) {
2
    StopWriting();
3
  }

funktioniert... auch wenn es nicht aktiviert ist?!
1
...
2
#define  USE_HAL_SPI_REGISTER_CALLBACKS         0U /* SPI register callback disabled       */
3
...

Die Callbackfunction SPI_DMATransmitCplt bekomme ich aber irgendwie 
nicht ans laufen. Aber egal... so läuft jetzt alles wunderbar! :)

von Εrnst B. (ernst)


Lesenswert?

Gerrit G. schrieb:
> funktioniert... auch wenn es nicht aktiviert ist?!

weil es nicht aktiviert ist.

mit dem #define auf 1 läuft der globale default-Handler für 
SPI_TX_Complete (und andere), schaut nach, welches SPI den IRQ ausgelöst 
hat, und schaut dann in dessen Config nach, ob eine Callback-Funktion 
eingetragen ist. Die wird dann aufgerufen.

mit den #define auf 0 musst du dich selber darum kümmern, d.H. 
HAL_SPI_TxCpltCallback selber implementieren.

von Gerrit G. (gerrito)


Lesenswert?

Das habe ich ja getan. Ich nutze die callbackfunction in der main wie 
oben beschrieben. Und ja, die läuft auch... In der hal_conf sind aber 
alle deaktiviert.

Bei der spi_dma callbackfunction passiert aber nichts - egal ob 
aktiviert oder nicht. 🤷🏼‍♂️

Ich setze mich am Montag noch mal dran und tüftel weiter.

Schönes Wochenende! :)

von J. S. (jojos)


Lesenswert?

Für diese callbacks gibt es afaik eine Hilfsfunktion zum registrieren 
der Funktion.

Wenn man mit CubeMX arbeitet sollte die Einstellung in den 
Projectsettings geändert werden, siehe

https://community.st.com/t5/stm32cubeide-mcus/stmcubeide-use-hal-register-callbacks-definition/td-p/385607/page/3

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.