Forum: Mikrocontroller und Digitale Elektronik GPIO Bitbanging mit ATSAMD51G?


von Shinner (Gast)


Lesenswert?

Hi,

ich habe hier ein etwas spezielles Signal, das wie SPI aussieht, aber 
leider keines ist. Kurz: es gibt ein Sync-Signal und einen Clock. Bei 
jeder positiven Flanke auf Clock sind zwei GPIOs einzulesen (Data). Da 
SYNC leider irgendwo mitten in einem Frame nur für die Dauer eines Clock 
kommt, kann ich kein SPI verwenden. Meine Idee wäre jetzt, einen 120MHz 
ATSAMD51G zu nutzen und den Krempel in Code zu gießen:

CLock und Sync lösen jeweils einen Interrupt aus. Sync kommt eher 
selten, mein Problem ist das Clock-Signal: dieses kommt mit einer 
Frequenz von 2 MHz, also hätte ich bei 120 MHz in der ISR theoretisch 
etwas weniger als 60 Taktzyklen Zeit, um die zwei GPIOs zu lesen, und 
die Bits in je eine Variable zu shiften und um vielleicht noch eine 
Statusvariable zu setzen.

Meiner Meinung nach sollte das aufgehen, sprich 60 Zyklen sollten 
eigentlich genug sein für so ein paar simple Operationen, so dass der 
main-Loop auch noch genügend Rechenzeit abbekommt.

Allerdings: kann diese Rechnung stimmen? wie groß ist der Overhead bei 
einem External Interrupt auf dem ATSAMD51G? Wie viel von meinen 60 
Zyklen geht da allein durch den Interrupt verloren?

von c-hater (Gast)


Lesenswert?

Shinner schrieb:

> Kurz: es gibt ein Sync-Signal und einen Clock. Bei
> jeder positiven Flanke auf Clock sind zwei GPIOs einzulesen (Data). Da
> SYNC leider irgendwo mitten in einem Frame nur für die Dauer eines Clock
> kommt, kann ich kein SPI verwenden.

Huch? Da stimmt doch irgendwas nicht. Wie wird denn ein "Frame" 
definiert, wenn nicht durch den Sync?

Weil: wenn man als Frame betrachtet, was zwischen zwei Syncs liegt, dann 
wird da irgendwie doch ganz normales (double) SPI draus...

> Meine Idee wäre jetzt, einen 120MHz
> ATSAMD51G zu nutzen und den Krempel in Code zu gießen

Ich würde einen RP2040 nehmen. Dessen PIOs sind u.A. genau für sowas 
geschaffen worden: "ungewöhnliche" serielle Protokolle unabhängig von 
den Cores zu implementieren.

Aber das würde ich halt nur dann machen, wenn sich nicht rausstellt, 
dass es sich doch eigentlich um stinknormales SPI handelt.

von 123 (Gast)


Lesenswert?

Hast du dir mal Audio Serial Interface sachen angeschaut? Da kann man 
ggf mehrere der Einheiten mit gemeinsamen clock und Frame betreiben.

Wobei wird bei atmel SPI und I2S/ASI nicht über den gleichen block 
behandelt?

von Bauform B. (bauformb)


Lesenswert?

Shinner schrieb:
> wie groß ist der Overhead bei einem External Interrupt auf dem ATSAMD51G?

Der Werbetext sagt was von 12 Taktzyklen, aber da geht es vor allem um 
Latenz. Den genauen Ablauf findet man hier: Kapitel B1.5.6 Exception 
entry behavior im Arm v7-M Architecture ® Reference Manual¹, aber dabei 
muss man annehmen, dass ein store genau einen Takt braucht. Dazu kommt 
der return, das dürfte noch etwas länger dauern.

Auf jeden Fall muss alles im RAM laufen, Flash kostet noch jede Menge 
wait states. Ich glaube, ohne Interrupts hast du eher eine Chance. 
Vielleicht kann ein Timer per input capture einen DMA Transfer starten, 
der die Pins kopiert. Wobei man den SYNC doch genau wie die Daten 
kopieren/abfragen könnte?

[1] https://developer.arm.com/documentation/ddi0403/ee/

: Bearbeitet durch User
von Frank K. (fchk)


Lesenswert?

Shinner schrieb:

> Allerdings: kann diese Rechnung stimmen? wie groß ist der Overhead bei
> einem External Interrupt auf dem ATSAMD51G? Wie viel von meinen 60
> Zyklen geht da allein durch den Interrupt verloren?

Das Problem ist, dass die gesamte Peripherie bei einem ARM-, MIPS oder 
RISCV-Kern asynchron zum CPU-Takt läuft, und das oft deutlich langsamer. 
Der Grund ist, dass der CPU-Kern ein zugekaufter Legoblock ist, der über 
spezielle interne Busse (AHB, APD, AXI,...) mit dem Rest des Chips (RAM, 
Flash, Peripherie, IO) kommuniziert, und das eben asynchron und unter 
Umständen mit Waitstates und gestallten Pipelines. Ausnahme ist das 
sogenannte TCM (Tightly Coupled Memory), das direkt am Prozessor hängt. 
Nur das läuft synchron mit dem Prozessor und mit der vollen 
Geschwindigkeit.

Bei 8- und 16-Bittern (z.B. dsPIC33) gibt es keine Trennung zwischen 
Core und Peripherie, weil da halt beides aus einer Quelle kommt. Die 
Peripherie ist bei einem dsPIC33 z.B. viel enger an den Kern angebunden 
und läuft immer synchron, und die SFRs (Special Function Registers) 
entsprechen vom Zeitverhalten bei einem Zugriff exakt einem Register- 
oder RAM-Zugriff. Ich hab das jetzt nicht nachgeschaut, aber es würde 
mich nicht wundern, wenn ein 100MHz dsPIC33CK im IO-Handling deutlich 
schneller als Dein 120 MHz ATSAM ist und damit auch weniger Jitter 
aufweist.

Die Betrachtung des Zeitverhaltens ist also viel komplexer als Du es 
vielleicht denkst.

Ich würde dafür ein kleines FPGA nehmen (z.B. ein Lattice MachXO, die 
sind einfach zu handhaben, brauchen nur 3.3V und haben internes 
Konfigurationsflash), und damit Dein Signal in irgendwas umsetzen, das 
der Prozessor direkt verarbeiten kann, z.B. I2S, SPI oder 8-bit breiten 
FIFO. Das ist dann absolut deterministisch, und das ist wichtig hier.

fchk

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.