Forum: Mikrocontroller und Digitale Elektronik SPI DMA Adresse


von Sebastian Kaulitz (Gast)


Lesenswert?

Es geht um die
1
HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)

Ich würde gerne wissen, warum ich da bei dieser Funktion die Adresse der 
Daten angeben muss.

Die DMA mit der SPI funktioniert ja so:
Der DMA wird die Speicheradresse der Daten angegeben. (Memory)
Bei einem SPI Senderequest wird das TXE-bit gesetzt.
Dann schreibt die DMA die Daten in das SPI Datenregister SPI_DR.
Wenn das abgeschlossen ist, setzt die DMA den TCIF flag im DMA_ISR.

Wozu nun also die Angabe der Daten in der Funktion, wenn doch bei der 
DMA als CMAR sowieso die SPI_BASE plus OFFSET für das Datenregister 
angegeben wird??

von pegel (Gast)


Lesenswert?

Geh doch einfach in die Funktion und sieh nach was er damit macht.

von Harry L. (mysth)


Lesenswert?

Woher sonst sollte der DMA wissen, welche Daten er zum SPI schaufeln 
soll?

von Dr. Sommer (Gast)


Lesenswert?

Sebastian Kaulitz schrieb:
> Wozu nun also die Angabe der Daten in der Funktion, wenn doch bei der
> DMA als CMAR sowieso die SPI_BASE plus OFFSET für das Datenregister
> angegeben wird??

Und die Speicher Adresse der Daten muss auch irgendwo angeben werden:

Sebastian Kaulitz schrieb:
> Der DMA wird die Speicheradresse der Daten angegeben. (Memory)

Und das ist hier pData. Woher soll die Funktion sonst wissen was 
übertragen wird?

von Sebastian Kaulitz (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Sebastian Kaulitz schrieb:
>> Wozu nun also die Angabe der Daten in der Funktion, wenn doch bei der
>> DMA als CMAR sowieso die SPI_BASE plus OFFSET für das Datenregister
>> angegeben wird??
>
> Und die Speicher Adresse der Daten muss auch irgendwo angeben werden:
>
> Sebastian Kaulitz schrieb:
>> Der DMA wird die Speicheradresse der Daten angegeben. (Memory)
>
> Und das ist hier pData. Woher soll die Funktion sonst wissen was
> übertragen wird?

Das geschieht doch mit der folgenden Anweisung:
1
uint32_t spiPeriphAdress = SPI1_BASE + 0x0C; 
2
uint8_t txData[3] = {0,1,2,3,4,5,6,7,8,9};
3
4
  hdma_spi1->Instance->CPAR = spiPeriphAdress;
5
  hdma_spi1->Instance->CMAR = (uint32_t) txData;
6
  hdma_spi1->Init.PeriphInc = DMA_PINC_DISABLE;
7
  hdma_spi1->Init.MemInc = DMA_MINC_ENABLE;

Damit schreibt mir die DMA die Daten vom Buffer data2send in das 
Datenregister SPI_DR.
Sourceadresse ist also data2send und
Zieladresse ist SPI_DR.

Jetzt muss doch die SPI doch nichts mehr wissen. Dass es die Daten in 
seinem eigenen Speicher SPI_DR senden muss, weiss es hoffentlich selbst. 
Das ist nämlich das Interface von dem aus txData gesendet und von dem 
aus ins rxData geschrieben wird.

von Sebastian Kaulitz (Gast)


Lesenswert?

Sebastian Kaulitz schrieb:
> Dr. Sommer schrieb:
>> Sebastian Kaulitz schrieb:

> uint8_t txData[3] = {0,1,2,3,4,5,6,7,8,9};
>


edit
txData[10] natürlich

von Dr. Sommer (Gast)


Lesenswert?

Sebastian Kaulitz schrieb:
> Das geschieht doch mit der folgenden Anweisung:

Die benutzt man aber nicht in Kombination mit der HAL_SPI_Transmit_DMA , 
weil die das alles schon enthält!
Auf IrgendeinHandle->Instance greift man im Normalfall gar nicht direkt 
zu.

von Sebastian Kaulitz (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Sebastian Kaulitz schrieb:
>> Das geschieht doch mit der folgenden Anweisung:
>
> Die benutzt man aber nicht in Kombination mit der HAL_SPI_Transmit_DMA ,
> weil die das alles schon enthält!
> Auf IrgendeinHandle->Instance greift man im Normalfall gar nicht direkt
> zu.

Anders gefragt:
Wenn ich also die DMA beim SPI einsetzen möchte benutze ich nur die 
HAL_SPI_Transmit_DMA Funktion.

Wenn ich nun aber ein Datenarray habe, wo stelle ich dann zB ein, ob 
jetzt die Memoryadresse inkrementiert oder die Peripherieadresse 
inkrementiert wird?
Hier würde ja die Peripherieadresse zu erhöhen keinen Sinn machen, aber 
eingestellt werden muss es ja trotzdem. In der Transmit-Fkt oben finde 
ich es leider nicht. Wird das denn automatisch gemacht?

von Mr. Big (Gast)


Lesenswert?

Also DMA auf dem STM32 ist bis einschliesslich STM32F7 Kinderkram, erst 
ab dem H7 wird es ein bisschen komplexer. Warum setzt Du die Handvoll 
Bits in den Registern nicht selber?

von pegel (Gast)


Lesenswert?

Wenn du schon die HAL Funktionen nutzt, warum dann nicht auch CubeMX?

von Dr. Sommer (Gast)


Lesenswert?

Sebastian Kaulitz schrieb:
> Wenn ich also die DMA beim SPI einsetzen möchte benutze ich nur die
> HAL_SPI_Transmit_DMA Funktion.
Ja.

Sebastian Kaulitz schrieb:
> Wenn ich nun aber ein Datenarray habe, wo stelle ich dann zB ein, ob
> jetzt die Memoryadresse inkrementiert oder die Peripherieadresse
> inkrementiert wird?

Das musst du in der "HAL_SPI_MspInit" machen, welche von der 
HAL_SPI_Init aufgerufen wird. Dort werden diese Parameter an die 
HAL_DMA_Init übergeben. Schau doch einfach in einen Beispiel-Code wie 
das zusammenhängt, oder lass es dir von CubeMX generieren.

von pegel (Gast)


Lesenswert?

Wenn man genau wissen will wie es geht, Beispielcode von 
SPI_FullDuplex_ComDMA
ansehen.

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.