Hallo,
ich verwende auf dem STM32F207 das SPI Interface mit DMA. Das Senden von
SPI Frames ohne DMA funktioniert.
Die Daten werden auch korrekt über den RX DMA empfangen. Nun möchte ich
das Senden über den TX DMA realisieren.
Ein Kommando besteht aus zwei 16bit SPI Frames. Je nach Bedarf sollen
zwei 16bit SPI Frames via TX DMA über die SPI Schnittstelle versendet
werden. Hierfür habe ich für den TX DMA einen Puffer bereitgestellt, der
2*16Bit groß ist. Für den RX DMA habe ich einen 64*16Bit Puffer
angelegt. Ja nach Kommando können auch mehr als zwei 16Bit SPi Frames
empfangen werden. Müsste der Puffer für TX DMA ebenfalls 64*16Bit groß
sein ? Wie kann man in der Software veranlassen, dass das dritte und
vierte 16Bit SPI Frame gesendet werden soll ? Gibt es hierfür eine
inkrement Funktion die das ermöglichen kann ?
Die Kommunikation läuft folgendermaßen ab:
STM32 sendet 2 Spi Frames an den Fpga. Fpga löst daraufhin auf dem STm32
einen externen Interrupt aus. In dem externen Interrupt Handler sende
ich nochmals 2 Spi Frames allerdings mit den Dateninhalten NULL. Der
FPGA sendet dann seine Daten entweder 2 Spi Frames oder 64 Spi Frames
zum STM32.
Hi,
der STM ist der Master, d.h. er generiert den Takt für die
Datenübertragung (es wird dabei immer gleichzeitig wird gesendet und
empfangen). Das tut er nur solange er Daten sendet. D.h. wenn du 128
Byte empfangen willst musst du auch 128 Byte hinschicken (können ja
lauter 0'er sein o.ä.).
Viele Grüße,
Narfie
Guten Morgen,
vielen Dank für die Beiträge. Mir geht es eigentlich nur darum, wie kann
man byteweise oder wordweise die Daten im Tx Dma Puffer versenden ? Gibt
es hier eine Inkrementfunktion, die das bewältigen kann ? Wenn ich dich
den Tx Dma aktiviere, swerden alle Daten im Tx Puffer auf einmal
versendet. Dies möchte ich aber nicht.
Beispiel - TxPuffer 8 Byte:
Initialisierung:
TxPuffer[0] = 0;
TxPuffer[1] = 0;
TxPuffer[2] = 0;
TxPuffer[3] = 0;
TxPuffer[4] = 0;
TxPuffer[5] = 0;
TxPuffer[6] = 0;
TxPuffer[7] = 0;
--> TxPuffer[0] und TxPuffer[1] senden
Nächste Aktion:
--> TxPuffer[2] und TxPuffer[3] senden
usw.
Ob es sich lohnt oder nicht. Ich möchte nur wissen, ob es eine Funktion
gibt, mit der man byteweise oder wordweise Daten vom Tx Dma Puffer
senden kann.
Ich habe jetzt mal für das Senden und Empfangen jeweils 2*16Bit
angelegt.
Sobald der external Interrupt ausgelöst wird, werden zum erstenmal die
2*16Bit gesendet. Das funktioniert hier nur einmal. Was müsste ich genau
tun, damit ich nochmals 2*16Bit mit dem Tx Dma senden kann ?
[c]
void main(void)
{
...
...
while (1)
{
if (STM_EVAL_PBGetState(BUTTON_WAKEUP) != 0)
{
while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(SPIx, Command[0]);
__no_operation();
__no_operation();
__no_operation();
__no_operation();
__no_operation();
while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(SPIx, Command[1]);
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, DISABLE);
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, DISABLE);
DMA_Config();
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);
}
}
}
void SPI_DMA_RX_IRQHandler(void)
{
if (SET == DMA_GetITStatus(SPI_RX_DMA_STREAM, SPI_RX_DMA_FLAG_TCIF))
{
/* clear int pending bit */
DMA_ClearITPendingBit(SPI_RX_DMA_STREAM, SPI_RX_DMA_FLAG_TCIF);
RxBuffer[RxCounter] = SPI_MASTER_Buffer_Rx[0];
RxCounter = RxCounter + 1;
RxBuffer[RxCounter] = SPI_MASTER_Buffer_Rx[1];
RxCounter = RxCounter + 1;
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, DISABLE);
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, DISABLE);
DMA_Config();
}
}
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line15) != RESET)
{
/* Clear the EXTI line 15 pending bit */
EXTI_ClearITPendingBit(EXTI_Line15);
SPIx->DR;
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
}
}
Nachdem Du die Kapitel "13 Direct memory access controller (DMA)"
und "25 Serialperipheral interface (SPI)" des
ST Dokuments "RM0008 Reference manual", Doc ID 13902
gelesen hast, sollten alle Deine Fragen beantwortet sein.
Meine Applikation läuft nun fast so wie ich es möchte. Ich habe für den
Tx Dma und auch für den Rx Dma jeweils 2*16bit reserviert. Nun habe ich
noch ein kleines Problem. Nachdem die ersten 2*16bit gesendet werden,
steht im RxPuffer vom Rx Dma NULL drin. Diesen Inhalt möchte ich
verwerfen. Welche Funktion gibt es hierfür ? Ohne Dma müsste ich diese
Codezeile einfügen SPIx->DR bevor ich wieder 2*16bit Daten sende.
Wenn ich ein neues Kommando sende, bestehend aus 2x16Bit, wie kann man
das erste empfangene 16Bit Word ignorieren ? Es sollte nachdem das
Kommando gesendet wurde im SPI_MASTER_Buffer_Rx[0] nichts gespeichert
werden.
>Es sollte nachdem das>Kommando gesendet wurde im SPI_MASTER_Buffer_Rx[0] nichts gespeichert>werden.
Was ist das Problem, ab &SPI_MASTER_Buffer_Rx[2] zu kopieren?
Wenn Dir das zu einfach ist...
Du könntest aber auch Deinen SPI_MASTER_Buffer_Rx
so in's RAM legen, dass die ersten 2 Bytes in's Leere
geschrieben werden.
Ich versuche aktell etwas ähnliches zu realisieren...
Das Einlesend der SPI mittels DMA funktioniert wunderbar mit 8-Bit. Wenn
ich die Paketgrösse jedoch auf 16 Bit erhöhe, so sind die oberen 8 bit
immer 0. Mir scheint da ist noch ein kleines Problem...
Im RM0008 steht unter 25.2 SPI and I2S main features
1-byte transmission and reception buffer with DMA capability: Tx and Rx
requests
Kann es sein dass es gar nicht möglich ist 16 Bit zu übertragen?