Hallo.
Ich versuchen gerade mit einem STM32H743 Daten über die I2S
schnittstelle zu senden.
Die SPI3 ist der Slave TX und bekommt von aussen die Taktleitungen (BIT
& Word).
Das ganze hat auf einem STM23F4 noch sauber gearbeitet und ich habe an
den Code nichts geändert Ausser:
DMA Mapping- altes raus neues Mapping rein
CStart gesetzt (sonst passiert nichts)
So komischerweise wird der DMA Interrupt aufgerufen und meine 2 Audio
Puffer werden auch angeblich regelmässig gewechselt (gibt dafür ein
Status flag).
Nur es kommt nichts raus, den Pin habe ich mit einem einfachen Test mal
wackel lassen, der ist also angeschlossen.
Der Code ist zusammen kopiert und hoffentlich auch vollständig:
Wenn ich mir die Register ansehe dann fällt mir eigentlich nur auf das
SPI-?? Dlen = 7 drin steht, aber das soll angeblich nicht ausgewertet
werden.
Vielleicht hat ja jemand eine Idee was falsch ist?
Ich habe das ohne DMA gemacht, erst einmal nur die Polling und dann it
Interrupt Routinen benutzt.
Der Code sieht bei mir wesentlich kürzer aus:
// Clock und Interrupt Init
__HAL_RCC_SPI2_CLK_ENABLE();
HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ (SPI2_IRQn);
// Dann das Handle erzeugen und füllen
memset( & m_HandleI2S,0,sizeof(m_HandleI2S) );
m_HandleI2S.Instance = p_I2SBus;
m_HandleI2S.Init.Mode = I2S_MODE_MASTER_TX;
m_HandleI2S.Init.Standard = I2S_STANDARD_MSB;
m_HandleI2S.Init.DataFormat = I2S_DATAFORMAT_16B;
m_HandleI2S.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;
m_HandleI2S.Init.AudioFreq = I2S_AUDIOFREQ_8K;
m_HandleI2S.Init.CPOL = I2S_CPOL_LOW;
m_HandleI2S.Init.FirstBit = I2S_FIRSTBIT_MSB;
m_HandleI2S.Init.WSInversion = I2S_WS_INVERSION_DISABLE;
m_HandleI2S.Init.Data24BitAlignment = I2S_DATA_24BIT_ALIGNMENT_RIGHT;
m_HandleI2S.Init.MasterKeepIOState =
I2S_MASTER_KEEP_IO_STATE_DISABLE;
m_HandleI2S.Init.AudioFreq = I2S_AUDIOFREQ_22K;
if (HAL_I2S_Init(&m_HandleI2S) != HAL_OK)
{
}
// und letztendlich abspielen
i_Result = HAL_I2S_Transmit_IT( &m_HandleI2S,
(uint16_t*) p_Data,
ui_Size
);
Die Teile sind aus einem größeren Programm entnommen. Aber nur das ist
notwendig.
Vielleicht erst einmal ohne DMA versuchen und wenns geht, erweitern.
Und ich benutze die HAL, die sich dort als sehr praktisch erwiesen hat.
Danke für die Antwort.
Das ist nur leider ein Master.
Fast alle Probleme die ich dazu finde beziehen sich auf Fehler in der
HAL. Gut das ist alles schon etwas älter, aber das ist halt das was man
immer findet.
Mir ist es inzwischen egal unter was das geschrieben ist solange es
funktioniert. Ich hatte mich damals halt für libopencm3 entschieden.
Zurück zum Thema. Spi slave, jemand eine Idee was falsch ist?
Ob Master oder Slave ist eigentlich immer egal ...
Ich hatte und habe da auch meinen Stress auf dem H750.
Die Pins sind aber alle richtig gesetzt?
Ich nehme dazu immer Cube und setze alle Pins mal und kopiere nur
die Init der GPIOs rüber.
Ich vermisse hier den MCLK ...
SCLK - bitclock
FS - wordclock
SD - data
Ansonst schau mal ob du im richtigen Speicherbereich bist.
Genau das war der Grund bei mir.
DMA hat nicht überall Zugriff und ist empfindlich was den Cache angeht.
Man MUSS beim H7 quasi die MPU nutzen sonst geht praktisch garnichts
oder man MUSS den Cache abschalten was ihn arschlahm macht.
ztrr schrieb:> Ich vermisse hier den MCLK ...
Ergänzung:
Auch der Slave brauch den MCLK ..
Es sei denn mal implementiert
einen EXTI zum bitclock und erzeugt intern mit einem Timer das Timing.
Quasi autoMCLK / Pll like
Muss das nicht AF7 sein? AF6 ist laut Datenblatt für PB5 I2C4_SMBA. AF7
dagegen ist SPI3_MOSI/I2S3_SDO, würde also zu Deinen Anforderungen
besser passen.
ztrr schrieb:> Auch der Slave brauch den MCLK
MCLK war nie Teil der I2S-Spezifikationen. Das ist eher ein Relikt aus
frühen Tagen, als die Takterzeugung und -verteilung in Studios zentral
vorgenommen wurde und nicht in jedem kleinen Chip ein komplettes
Taktsystem inklusive PLL(s) eingebaut waren.
Der STM32 braut den Takt als Slave nicht. Im Falle des Masters kann er
ihn als 256fs oder 512fs ausgeben. Es gibt aber auch reichlich Slaves,
die keinen MCLK benötigen. Die erzeugen sich ihren Takt für alle anderen
Komponenten dann gerne mal aus den Bit-Clock. Es gibt auch Slaves, die
das aus dem Word-Clock (Samlerate) machen.
Michael O. schrieb:> Moin,> // Data Out> gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO5);> gpio_set_output_options(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ,> GPIO5);> gpio_set_af(GPIOB, GPIO_AF6, GPIO5);>> Muss das nicht AF7 sein? AF6 ist laut Datenblatt für PB5 I2C4_SMBA. AF7> dagegen ist SPI3_MOSI/I2S3_SDO, würde also zu Deinen Anforderungen> besser passen.
cube sagt hier auch AF7_SPI3
Michael O. schrieb:> Der STM32 braut den Takt als Slave nicht. Im Falle des Masters kann er> ihn als 256fs oder 512fs ausgeben. Es gibt aber auch reichlich Slaves,> die keinen MCLK benötigen. Die erzeugen sich ihren Takt für alle anderen> Komponenten dann gerne mal aus den Bit-Clock. Es gibt auch Slaves, die> das aus dem Word-Clock (Samlerate) machen.
da ich bisher auch nur Master hatte ... gut zu wissen
So dank euch läuft es jetzt.
Port b05 hat natürlich AF7 und nicht wie die anderen AF6.
Aber ich musste noch io swap einschalten.
Den D-Cache habe ich noch nicht angeschaltet, weil ich schon gelesen
hatte das es zu Problemen kommen kann. Der I-Cache ist aber an.
Die mpu muss ich mir mal ansehen, vielleicht kannst du mir da
weiterhelfen. Ich habe freertos laufen und einer der Tasks wird durch
den dma Interrupt getrigger. Der task füllt dann den inaktiven Speicher.
Der Speicher liegt im RAM 1/2/3 also im Bereich der vom dma bearbeitet
werden kann.
Problem ist erst wenn du erwartest das er performanctechnisch
zur Hochform auflaufen soll.
Dann hilft es nur den Speicher komplett aufzuteilen und entsprechend der
sections die MPU zu nutzen.
Ich nutze auch RTOS mit taskNotify im DMA interrupt
nur der Interrupt brauch dann die cachefunktionen
pvPortMalloc nutzt zB nur den DTCM RAM.
Da drin liegt der Stack und eben auch der heap_4
Weil der DTCM seinen eigenen Bus hat und damit unabhängig der Peripherie
arbeiten kann. Ein Taskswitch ist so schneller und sicherer ( DTCM ist
ohne cache )
habe aber H750 .. die Größen müsstest du prüfen
Ja da muss ich wohl erst mal einiges lesen bis ich das richtig verstehe.
Aber das wird mit Sicherheit einfacher sein wie die spi, bei der bin ich
nur am fluchen.
Dirk schrieb:> So dank euch läuft es jetzt.> Port b05 hat natürlich AF7 und nicht wie die anderen AF6.
Ah OK, sehr schön :-)
De D-Cache habe ich bei mir ausgeschaltet. Wie zttr ja schrieb, DTCM ist
sowieso ohne Cache. In Domain 1 nutze ich für die DMA-(Ring-) Buffer und
den externen SDRAM für Grafik-Framebuffer und zwischengespeicherte
Meßwerte aus nem ADC. Da wäre der D-Cache auch kontraproduktiv.
Zu RTOS kann ich nichts beitragen. Ich habe es lieber, wenn ich weiß,
was im Hintergrund so läuft. Von daher ist mein Code bis auf ein paar
Reste der HAL selbst gestrickt als Statemachine. Interrupts gibts bei
mir exakt einen... der für den Timer des Drehencoders ;-)
Der rtos stack liegt bei mir auch im dtcm Bereich und noch ein paar
andere Variablen die schnellen Zugriff brauchen.
Wie langsam das nun ist ohne Cache oder andersherum was man noch raus
holen kann werde ich mal ausprobieren. Aber jetzt muss ich erstmal
andere Sachen fertig machen.