Hallo Ich habe folgendes Szenario: STM32F105 als SPI Slave. Dieser soll bei erhalt eines Bytes oder mehrere Bytes mittels DMA einen definierten Buffer zurücksenden. Leider klappt das nicht so wie es soll. Es wird immer erst ab dem zweiten Byte das erste des buffers zurückgesendet. Das erste byte welches über SPI zurückgeht ist das letzte welches zuvor gesendet wurde. Der DMA scheint immer ein byte zu benötigen, bis er sich konfiguriert hat. Also sozusagen ein dummy byte bevor die Übetragung beginnt. Ist dies so üblich? Es scheint, als wäre etwas irgendwo im zwischenspeicher. Was mache ich falsch?
:
Bearbeitet durch User
Holger K. schrieb: > Es wird immer erst ab dem zweiten Byte das erste des buffers > zurückgesendet. Ich hab zumindest einige SPI-Bausteine gesehen, die so funktioniert haben. Woher soll er auch wissen, was er zurückgeben soll, bevor er das allererste Byte vollständig empfangen und ausgewertet hat?
Rainer U. schrieb: > Holger K. schrieb: >> Es wird immer erst ab dem zweiten Byte das erste des buffers >> zurückgesendet. > > Ich hab zumindest einige SPI-Bausteine gesehen, die so funktioniert > haben. Woher soll er auch wissen, was er zurückgeben soll, bevor er das > allererste Byte vollständig empfangen und ausgewertet hat? Nein du vestehst das nicht ganz. Ich konfiguriere den DMA BEVOR ich bytes empfange. Bei der Konfiguration teile ich dem DMA mit, was er zu senden hat. Wenn der Master nun ein byte sendet und ich dieses als Slave empfange, so soll bereits beim ersten Bytetransfert der DMA die konfigurierten Daten absenden. Dies tut er jedoch erst beim zweiten emfpangenen byte. Es muss nichts ausgewertet werden.
Hast du das DMA korrekt abgeschaltet nach dem vorherigen Transfer? Ala
1 | DMA1->CCR = 0; // EN bit abschalten! |
2 | while (DMA1->CCR & DMA_CCR_EN); |
Dr. Sommer schrieb: > Hast du das DMA korrekt abgeschaltet nach dem vorherigen Transfer? > AlaDMA1->CCR = 0; // EN bit abschalten! > while (DMA1->CCR & DMA_CCR_EN); Bisher noch nicht. Nun habe ich das angepasst. Aktuell sieht mein Code so aus:
1 | uint8_t dataSendB[4] = {0x14, 0x41, 0x63, 0x20}; |
2 | ...
|
3 | void SPI2_IRQHandler(void) |
4 | {
|
5 | uint8_t cmd; |
6 | |
7 | SPI_I2S_ClearITPendingBit(SPI2,SPI_I2S_IT_RXNE); |
8 | cmd = SPI2->DR; |
9 | |
10 | if(cmd != 0xD8) |
11 | {
|
12 | //DMA Deaktivieren
|
13 | DMA1_Channel5->CCR &= (uint16_t)(~DMA_CCR1_EN); |
14 | while (DMA1_Channel5->CCR & DMA_CCR1_EN); |
15 | |
16 | |
17 | DMA1_Channel5->CMAR = (uint32_t)&dataSendB[0]; |
18 | DMA1_Channel5->CNDTR = 2; |
19 | |
20 | //DMA Aktivieren
|
21 | DMA1_Channel5->CCR |= DMA_CCR1_EN; |
22 | }
|
23 | //Interrupt deaktivieren. Wird beim CS Low->HIGH wieder aktiviert
|
24 | //Dadurch bekomme ich nur das erste Byte (CMD) mit
|
25 | SPI_I2S_ITConfig(SPI2,SPI_I2S_IT_RXNE,DISABLE); |
26 | }
|
Ich empfange das erste byte mittels interrupt. Dann schaue ich mir dieses an und aktiviere den DMA für die nächste übertragung. Anbei ein Bild. Eigentlich müsste dann 0x14 0x41 kommen Jedoch kommt zuerst 0x02. Das ist jenes byte, welches ich an anderer Codestelle zuletzt mit dem DMA übertragen habe.
:
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.