Forum: Mikrocontroller und Digitale Elektronik STM32 SPI Slave DMA mit HAL


von Oz z. (ozzy)


Lesenswert?

Hallo,

   ich arbeite gerade an einem Projekt, in dem 2 STM32F4 über SPI 
miteinander kommunizieren sollen (Full Duplex). Der Master schickt 
hierfür jede ms ein Paket raus (9 words, Prescaler 16, software CS, 
16Bit) mit einer Checksumme im letzten word. Der Slave (gleiche Taktrate 
wie der Master, soft-NSS) soll dann seine Daten über die MISO-Leitung an 
den Master schicken. Der Slave macht bei mir leider gerade Probleme, 
vielleicht mache ich aber auch etwas grundsätzlich falsch: es sieht so 
aus, als wären die Daten alle um 1 word geshifted, also statt
0 1 2 3 4 5 6 7 8 9
empfange ich
9 0 1 2 3 4 5 6 7 8
Das hat für mich keinen Sinn gemacht (DMA ist auf normal, nicht auf 
circular eingestellt), die Checksumme stimmte aber. Allerdings hatte ich 
die TX Daten auch nie wirklich verändert, deshalb habe ich mal einen 
Framecounter in das erste word eingefügt und siehe da, der 
Checksummenabgleich beim Slave schlägt immer fehl. Es sieht also so aus, 
als wäre das erste word das ich lese, eigentlich noch aus der letzten 
Übertragung gewesen... Wo ist nun also mein Fehler? Ich habe einen 
Interrupt (EXTi) auf das CS Signal, welches bei mir die DMA-Übertragung 
starten soll:
void spi_startDMATransfer( void )
{
  HAL_StatusTypeDef status;
  status = HAL_SPI_TransmitReceive_DMA(&hspi1, (uint8_t*)SPISlaveTXdata, 
(uint8_t*)SPISlaveRXdata, SPI_PACKET_SIZE);
  if ( status != HAL_OK )
  {
    HAL_SPI_DMAStop(&hspi1);
  }
}

Wie gesagt, ich laufe ja auch in den HAL_SPI_TxRxCpltCallback Callback, 
aber die Daten stimmen eben nicht.

Habt Ihr da eine Idee zu?

von Oz z. (ozzy)


Angehängte Dateien:

Lesenswert?

Ok,

gerade noch einmal mit dem Scope geschaut, das macht es auch deutlich! 
In blau ist das Clock-Signal des Masters zu sehen, rot geht auf high, 
wenn ich in die ISR reingehe, und wieder auf low, wenn ich mit dem 
HAL_SPI_TransmitReceive_DMA Befehl durch bin:

  HAL_GPIO_WritePin(SPI_DEBUG_GPIO_Port, SPI_DEBUG_Pin, GPIO_PIN_SET );
  status = HAL_SPI_TransmitReceive_DMA(&hspi1, (uint8_t*)SPISlaveTXdata, 
(uint8_t*)SPISlaveRXdata, SPI_PACKET_SIZE);
  HAL_GPIO_WritePin(SPI_DEBUG_GPIO_Port, SPI_DEBUG_Pin, GPIO_PIN_RESET 
);

Da verpasse ich natürlich einiges!!!

Ich weiß, viele hier hassen die HAL, aber seht Ihr eine Möglichkeit, das 
noch zu retten? Oder habt Ihr vielleicht eine gute Quelle für mich für 
DMA-SPI ohne die HAL?

von NameHierEinfügen (Gast)


Lesenswert?

Es gibt neben der HAL auch noch die LL.

Was passiert mit dem Speicherbereich der sich hinter  SPISlaveTXdata 
verbirgt, nachdem du die HAL_SPI_TransmitReceive_DMA(..) aufrufst? 
Bearbeitest du diesen, noch bevor die DMA-Übertragung abgeschlossen ist?

Hatte mal so ein ähnliches Problem, nur mit UART. Telegramme kamen ab 
und zu geshiftet an. Lag daran, dass ich nicht lang genug gewartet 
habe/nicht gecheckt habe ob die DMA-Daten schon wirklich raus waren, 
bevor ich in einer nachfolgenden Funktion den Tx-Speicherbereich wieder 
bearbeitet habe.

von Oz z. (ozzy)


Lesenswert?

Hallo,

   ne, ich modifiziere die Daten erst, nachdem der ReceiveTransmit 
Callback aufgerufen wurde.

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.