erik_wolfram
06.08.2015, 23:10
Hallo,
seid geraumer Zeit bin ich nun auf einen STM32 umgestiegen, nachdem ich einen ATXMEGA maximal ausgereizt habe.
Mit dem ATXMEGA (32 MHz) habe ich zwei 16-Bit ADCs mit 200 kHz erfolgreich ausgelesen. Damit war ich an der absoluten Obergrenze.
Nun möchte ich das gleiche (angepasste) Programm auf den STM übertragen. Timer, SPI und DMA bekomme ich zum laufen, aber durch die erhöhten Anforderungen (meinerseits) komme ich schon wieder an Grenzen.
Nun möchte ich die gleichen zwei ADC's (Daisy-Chain) mit 400 kHz auslesen können!
Zum Ablauf:
Ein PWM-Signal erzeugt mit das Start-Signal CONVST für eine einzelne ADC-Wandlung. 1,4 µs später kann der ADC mittels SPI (4 Dummy-Bytes = 2 x 16 Bit) angesprochen werden und gibt seine Daten simultan aus. (Die MOSI-Leitung wird nicht verwendet - die Ausgabe dient lediglich dem Erzeugen des SCK-Taktes). Ein weiterer DMA-Kanal speichert mit die empfangenen Daten.
Auf dem ATXMEGA konnte ich denvollständigen Ausleseprozess mittels DMA, Event-Manager und SPI ohne zusätzliche Rechenleitsung umsetzten.
Leider fehlt mir bei der Umsetzung auf den STM32 das Event-System und ich suche nach Alternativen.
Mein bisheriger Ansatz für den STM:
Ein Timer generiert mir einen 2,5 µs-Takt der per Interrupt den DMA auslöst. Dieser DMA "füttert" mir den SPI mit 4 Bytes mit voller Geschwindigkeit (keine Verzögerung zwischen den einzelnen Bytes). Nach der Beendigung der Übertragung Deaktiviert mir das DMA-Interrupt den entsprechenden DMA. Beim nächsten Takt des Timers wird der DMA wieder aktiviert und überträgt wieder 4 Bytes.
Mit dem Auslesen des SPIs habe ich mich noch nicht näher beschäftigt, hier vermute ich aber keine Probleme.
Leider hat diese Lösung aber ein Problem: das Interrupt des Timers hat eine Latenz von ca. 480 ns mit denen ich nicht leben kann (woher sie kommen ist mir klar).
Nun möchte ich das umgehen. Ich habe versuch mit "Gewalt" das Enable-Flag mit einem weiteren DMA zu setzten um das Timer-Interrupt zu umgehen - leider zeigt das keine Wirkung! Gibt es auf dem STM etwas vergleichbares wie das Event-System von Atmel? Ich bin leider nicht fündig geworden...
Ich möchte hier nicht explizit auf den Code eingehen sondern einen Ansatz finden. Daher poste ich hier auch nicht den bisherigen Code.
Das Problem sollte (?!) auch ohne Code disskutierbar sein.
Ich danke für die Hilfe!
Gruß Erik
seid geraumer Zeit bin ich nun auf einen STM32 umgestiegen, nachdem ich einen ATXMEGA maximal ausgereizt habe.
Mit dem ATXMEGA (32 MHz) habe ich zwei 16-Bit ADCs mit 200 kHz erfolgreich ausgelesen. Damit war ich an der absoluten Obergrenze.
Nun möchte ich das gleiche (angepasste) Programm auf den STM übertragen. Timer, SPI und DMA bekomme ich zum laufen, aber durch die erhöhten Anforderungen (meinerseits) komme ich schon wieder an Grenzen.
Nun möchte ich die gleichen zwei ADC's (Daisy-Chain) mit 400 kHz auslesen können!
Zum Ablauf:
Ein PWM-Signal erzeugt mit das Start-Signal CONVST für eine einzelne ADC-Wandlung. 1,4 µs später kann der ADC mittels SPI (4 Dummy-Bytes = 2 x 16 Bit) angesprochen werden und gibt seine Daten simultan aus. (Die MOSI-Leitung wird nicht verwendet - die Ausgabe dient lediglich dem Erzeugen des SCK-Taktes). Ein weiterer DMA-Kanal speichert mit die empfangenen Daten.
Auf dem ATXMEGA konnte ich denvollständigen Ausleseprozess mittels DMA, Event-Manager und SPI ohne zusätzliche Rechenleitsung umsetzten.
Leider fehlt mir bei der Umsetzung auf den STM32 das Event-System und ich suche nach Alternativen.
Mein bisheriger Ansatz für den STM:
Ein Timer generiert mir einen 2,5 µs-Takt der per Interrupt den DMA auslöst. Dieser DMA "füttert" mir den SPI mit 4 Bytes mit voller Geschwindigkeit (keine Verzögerung zwischen den einzelnen Bytes). Nach der Beendigung der Übertragung Deaktiviert mir das DMA-Interrupt den entsprechenden DMA. Beim nächsten Takt des Timers wird der DMA wieder aktiviert und überträgt wieder 4 Bytes.
Mit dem Auslesen des SPIs habe ich mich noch nicht näher beschäftigt, hier vermute ich aber keine Probleme.
Leider hat diese Lösung aber ein Problem: das Interrupt des Timers hat eine Latenz von ca. 480 ns mit denen ich nicht leben kann (woher sie kommen ist mir klar).
Nun möchte ich das umgehen. Ich habe versuch mit "Gewalt" das Enable-Flag mit einem weiteren DMA zu setzten um das Timer-Interrupt zu umgehen - leider zeigt das keine Wirkung! Gibt es auf dem STM etwas vergleichbares wie das Event-System von Atmel? Ich bin leider nicht fündig geworden...
Ich möchte hier nicht explizit auf den Code eingehen sondern einen Ansatz finden. Daher poste ich hier auch nicht den bisherigen Code.
Das Problem sollte (?!) auch ohne Code disskutierbar sein.
Ich danke für die Hilfe!
Gruß Erik