STM32F373 16 bit an 8 Bit SPI per DMA - Erstes Datenpaket immer beschnitten

Gast #7720851
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!

Gast #7720880
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.

Gast #7720906
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.

#7720926
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
...
Gast #7720982
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! :)

#7721014
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.

Gast #7721260
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! :)

Gast #7721379
Lesenswert?

Das ist korrekt... Auch das habe ich dort geändert... Dennoch... Bei spi-dma läuft es trotzdem nicht. Wie gesagt... Montag geht's weiter. Wenn ich was rausfinden sollte, werde ich mich noch mal melden.

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