Hallo Ich möchte den internen stm adc an einem fpga nutzen. Datenkommunikation über SPI (fpga spi slave). Da 1 msps sollte dies am besten per DMA geschehen. Wie? zudem 2. Frage: ist es möglich ins spi frame ebenfalls ohne cpu Aufwand einen crc anzuhängen?
Wenn ich mich korrekt erinnere, kann der DMA des STM32 nur - Memory to Memory - Memory to Peripheral - Peripheral to Memmory, jedoch nicht Peripheral to Peripheral. Insofern wird es ohne CPU-Eingriff nicht gehen und mit ihr läßt sich dann auch ein CRC anhängen. U.U. lässt sich die Aufgabe mit zwei DMAs lösen, dann aber wieder ziemlich sicher nur ohne CRC. Ein Timer müsste einerseits den Transfer Memory to SCI triggern, andererseits den ADC starten, dessen EOC wiederum den Peripheral to Memroy Transfer des zweiten DMA. Man müsste den den ersten DMA etwas verzögert starten oder in Kauf nehmen, dass der erste Wert noch nicht vom ADC kommt. Mit dem SCI hab' ich noch nicht gearbeitet - bin mir nicht sicher, ob damit ein kontinuierlicher Stream per DMA erzeugt werden kann oder ob nur Pakete einer bestimmten Länge aufgesetzt werden können - vielleicht kann das ein anderer hier beantworten.
Danke für die ausführliche Antwort. Hätte schon grosse lust dies über DMA zu lösen, da 1 MHz ISR frequenz. CRC berechnung+paket zusammenbauen wird vermutlich auch einige instruktionen benötigen. Habe ich es korrekt verdstanden, dass mit deiner vorgeschlagenen timer methode die zusätzliche latenz von 1us vermieden werden kann? Also erster DMA getriggert auf den EOC und dann einige 10ns danach den selben Datenwert mit dem timer DMA ins SPI register schreiben und SPI übertragung starten?
fpga schrieb: > Danke für die ausführliche Antwort. > Hätte schon grosse lust dies über DMA zu lösen, da 1 MHz ISR frequenz. > CRC berechnung+paket zusammenbauen wird vermutlich auch einige > instruktionen benötigen. > Habe ich es korrekt verdstanden, dass mit deiner vorgeschlagenen timer > methode die zusätzliche latenz von 1us vermieden werden kann? Also > erster DMA getriggert auf den EOC und dann einige 10ns danach den selben > Datenwert mit dem timer DMA ins SPI register schreiben und SPI > übertragung starten? Noch 2 Sachen habe ich vergessen: 1. CRC ist nicht zwingend erforderlich; für eine DMA lösung würde ich CRC opfern. 2. Gibt der 1. DMA ein signal bei transferabschluss auf welches der 2. DMA getriggert werden kann?
Man könnte überlegen mit einem DMA das Ergebnis des ADC auf RAM zu schaffen. Ist wahrscheinlich 4-12 Clocks für den ADC und 1 Clock für den Transfer. Der End-DMA-ISR Triggert dann die CRC Engine. Ich meine dass die pro Byte 1 Clock braucht aus dem RAM. Die CRC Engine müsste dann wiederum nach Beendigung wiederum einen neuen DMA triggern der die CRC und die Daten in die SPI Puffer kopiert. Dann brauchst du wahrscheinlich noch irgend eine Art Doppelpuffer für den Ausgangspuffer damit du dir während der Übertragung nicht die Daten überschreibst. Ich würde die Daten ohne Anfrage rausballern. Der Rest muss der FPGA richten. Der könnte sich dann noch überlegen zwischen 2 Punkten zu inter/extrapolieren auf einen anderen Zeitpunkt hin falls notwendig.
N. M. schrieb: > Dann brauchst du wahrscheinlich noch irgend eine Art Doppelpuffer für > den Ausgangspuffer damit du dir während der Übertragung nicht die Daten > überschreibst. Das sollte inkeitisch sein, der SPI würde ich einfach genügend schnell laufen lassen; damit die Übertragung schneller als der ADC ist (1MSPS). N. M. schrieb: > Ich würde die Daten ohne Anfrage rausballern. Der Rest muss der FPGA > richten. Der könnte sich dann noch überlegen zwischen 2 Punkten zu > inter/extrapolieren auf einen anderen Zeitpunkt hin falls notwendig. Genau FPGA ist als SPI slave vorgesehen. N. M. schrieb: > End-DMA-ISR Hmm also hier ISR? Nun CRC ist nicht zwingend; wenns ohne CRC ohne ISR geht ist das ein guter tradeoff. OT: Wie kann ich im cube genau feststellen, wie lange die ISR dauert? (also nicht nur Anzahl Instruktionen sondern wirklich Anzahl Systemclk)
PittyJ schrieb: > Wäre es nicht einfacher, einen SPI-ADC direkt am FPGA zu > betreiben? Doch :-) Vielleicht hat er einen STM Überschuss.
PittyJ schrieb: > Wäre es nicht einfacher, einen SPI-ADC direkt am FPGA zu > betreiben? Ja, sind aber extra kosten; STM32 ist schon da
N. M. schrieb: > Vielleicht hat er einen STM Überschuss. OT: Ne auch Mangel, unser EMS hat noch ca. 180stk lagernd. Viele EMS Kunden giengen wegen STM mangel zu renesas (nun sind die auch ausverkauft). Anyway für neue designs wurde uns renesas empfohlen, da die Verfügbarkeit etwas besser ausschaut als bei ST. Anyway dies hier ist ein kleineres projekt mit weniger al 1k stk daher STM.
fpga schrieb: > Nun CRC ist nicht zwingend; wenns ohne CRC ohne ISR geht ist das ein > guter tradeoff. Das sollte doch ganz einfach funktionieren, ohne Interrupts und ohne Zwischenpuffer? Zumindest mit den STM32L4? SPI wird als Master, nur TX, 8 oder 16 Bit, kein DMA konfiguriert. Beim ADC wird DMA eingeschaltet, Peripheral to Memory, Cyclic Mode, 16-Bit lesen und schreiben und als Ziel wird das SPI-TX-FIFO eingetragen. Das geht, weil alles Memory Mapped ist. Der Slave Select Ausgang wird und bleibt dabei aktiv, sobald SPI eingeschaltet wird. Evt. kann man zwischen den einzelnen Datenworten einen Impuls erzeugen, indem man das NSSP Bit setzt. Wenn mehr als ein Kanal gewandelt wird, kann der SPI-Slave nur mitzählen... Die Länge eines DMA-Transfers (CNDTR) ist eigentlich genau 1, aber wenn man hier einen größeren Wert einträgt, könnte man Interrupts mit entsprechend niedrigerer Frequenz erzeugen. Der ADC kann in Hardware den Mittelwert über 2,4,8... Wandlungen bilden. Wenn die Timer knapp werden, kann man den ADC frei laufen lassen und das Abtastintervall per Vorteiler plus Sample Time plus Kanalzahl einstellen. fpga schrieb: > Wie kann ich im cube genau feststellen, wie lange die ISR dauert? > (also nicht nur Anzahl Instruktionen sondern wirklich Anzahl Systemclk) Garnicht, dazu müsste cube wissen, wie der Compiler optimiert. Auf einen einzelnen Taktzyklus genau geht es sowieso nicht, weil DMA, Flash Cache und andere Interruptroutinen dazwischen funken können. Auch, wenn die eine niedrigere Priorität haben, brauchen die einige wenige unteilbare Zyklen. Man kann Interruptroutinen ein wenig optimieren, indem man sie auf eine runde Adresse linkt. Bei den kleineren Chips reicht ALIGN(8), weil das Flash nur 64 Bit breit ist; aber es gibt breitere.
> Hätte schon grosse lust dies über DMA zu lösen, da 1 MHz ISR frequenz. > CRC berechnung+paket zusammenbauen wird vermutlich auch einige > instruktionen benötigen. Üblicherweise wird ja auch nicht nach jedem Sample ein Interrupt ausgelöst, sondern per DMA z.B. 1024 Samples ins RAM geschrieben und dann ein Interrupt für den gesamten Block. Erst dann macht ja auch eine Paket mit CRC und Pipapo Sinn. Das Paket wird dann wiederum per DMA auf SPI rausgeschoben. Bandbreite bleibt die gleiche, nur die Latency ist höher.
fpga schrieb: > OT: Wie kann ich im cube genau feststellen, wie lange die ISR dauert? > (also nicht nur Anzahl Instruktionen sondern wirklich Anzahl Systemclk) Ab CM3 kannst du z.B. DWT->CYCCNT als watch nutzen.
Hmmm habe grade im cobe entdeckt, dass die SPI cores bereits jeweils einen integrierten CRC core haben. Damit sollte doch Timer controlled ADC (1msps)-> MEM DMA Timer controlled ca. 100us phasenverschoben(wie ichs verstanden habe ist dma ende nicht direkt mit dma start verlinkbar) MEM DMA -> SPI tx register Im SPI core ist dann der CRC aktiviert und SPI speed so eingestellt, das TX (inkl. CRC) unter 1us dauert.
fpga schrieb: > Hmmm habe grade im cobe entdeckt, dass die SPI cores bereits > jeweils einen integrierten CRC core haben. > Damit sollte doch Timer controlled ADC (1msps)-> MEM DMA > Timer controlled ca. 100us phasenverschoben(wie ichs verstanden habe ist > dma ende nicht direkt mit dma start verlinkbar) MEM DMA -> SPI tx > register > Im SPI core ist dann der CRC aktiviert und SPI speed so eingestellt, das > TX (inkl. CRC) unter 1us dauert. *100ns
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.