Forum: Mikrocontroller und Digitale Elektronik UART als "Layer" auf SPI?


von Mampf F. (mampf) Benutzerseite


Lesenswert?

Guten Mittag,

hat jemand zufällig schon mal ein Protokoll mit Source gebastelt, mit 
dem man quasi UART als layer auf SPI aufsetzen kann?

Bevor jemand schreit - mir ist schon klar, dass SPI synchron und UART 
asynchron ist - es geht mir eigentlich nur darum, mit möglichst wenig 
Aufwand eine Firmware, die per UART kommuniziert, jetzt per SPI 
kommunizieren zu lassen, ohne dass viel am (UART-)Protokoll* geändert 
werden muss :)

Großartig wäre natürlich, wenn es auf Master-Seite (Raspi) gleich eine 
entsprechende Lib in zB Python geben würde - aber ich vermute, das muss 
man sich dann selbst bauen :)

Viele Grüße,
Mampf


*: Es werden eigentlich nur JSON-enkodierte Daten (als jeweils eine 
Zeile mit \n terminiert) hin und hergeschickt. Nach Empfang werden die 
JSON-Daten verarbeitet und es kann ein paar Sekunden dauern, bis die 
Antwort fertig ist, die dann als JSON zurückgeschickt wird.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Man könnte sich eine riesen super-duper Lib schreiben, welche sämtliche 
UART-Protokolle auf der ganzen Welt versteht (Baudrate, Timeouts, 
Handshake, 5..9 Datenbits, Parity, Break usw.).
Oder man schreibt eine einfache Lib für das UART-Protokoll, welches man 
konkret verwenden will.

von Gute Frage (Gast)


Lesenswert?

Das größte Problem ist denke ich dass spi  ein Master/Slave System ist 
während bei Uart einfach jeder senden kann wenn er grad Lust hat.

Das heißt der SPI Master muss zyklisch immer wieder nach Daten pollen.

Finde ich keine sexy Lösung um ehrlich zu sein...

von Frank K. (fchk)


Lesenswert?

Der größere Unterschied ist, dass es bei SPI Master und Slave gibt. Wenn 
Du aber ohnehin ein Request-Resonse-Protikoll fährst, ist das einfach:

Der Master schickt dem Request und ab dann einfach nur 0-Bytes und 
wartet darauf, dass irgendwann mal was anderes als 0-Bytes zurück kommen 
und liest die Antwort bis zum nächsten 0-Byte ein und stoppt dann. Da es 
ja ASCII ist, wäre das eine einfache Möglichkeit.

Oder Du hängst das hier

https://www.nxp.com/docs/en/data-sheet/SC16IS752_SC16IS762.pdf

oder einen entsprechend programmierten PIC an den Slave und bleibst bei 
Deiner UART-Kommunikation.

Fertigen Source habe ich nicht - ich hatte dieses Problem bis jetzt noch 
nicht gehabt.

fchk

von c-hater (Gast)


Lesenswert?

Mampf F. schrieb:

> Bevor jemand schreit - mir ist schon klar, dass SPI synchron und UART
> asynchron ist

Das ist nicht das Problem. Das ist vielmehr, das man bei UART zwei 
völlig unabhängige Signalpfade hat und zwei gleichberechtigte Peers. 
Jeder von beiden kann prinzipiell senden, wann immer er möchte.

Das ist bei SPI NICHT so, da gibt es einen Boss (master) und einen 
Befehlsempfänger (slave). Ausschließlich der Boss kann eine 
Kommunikation initiieren.

Um sowas wie eine UART-Kommunikation darüber zu implementieren, wird 
also im Minimum eine zusätzliche Leitung benötigt, mit der der Slave dem 
Master Kommunikationsbedarf signalisieren kann.

Hat man diese zusätzliche Leitung, ist es nicht mehr sehr schwer, eine 
"Dreidraht"-UART durch SPI zu "tunneln". Ein sehr einfach gestricktes 
Software-Protokoll macht das dann möglich.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

c-hater schrieb:
> Das ist bei SPI NICHT so, da gibt es einen Boss (master) und einen
> Befehlsempfänger (slave). Ausschließlich der Boss kann eine
> Kommunikation initiieren.

Hmm jaaaa, aber ... Du hast schon recht, allerdings ist meine 
Uart-Kommunikation eh nur halb-duplex. Der Master weiß eigentlich, wenn 
was zurückkommen sollte, insofern wird die Eigenschaft der 
gleichberechtigten Peers nicht genutzt.

Ich glaub ich weiß, wie ich es mache ... Schröööcklich ineffizient aber 
stupid simple.

1. Fall: Slave wartet auf Daten

Master sendet daten - terminiert mit einem "\n".

Slave arbeitet, währenddessen sendet Master 0x00 oder 0xff als Polling. 
Ist der Slave beschäftigt, shiften die 0x00/0xff durch das SPI und 
werden wieder an den Master gesendet. Der verwirft sie einfach, weil sie 
schlicht heißen "Keine Daten.

2. Fall: Slave will senden

Master pollt fleißig. Slave pusht Daten (ASCII-Zeichen) in den 
SPI-Puffer und Master empfängt dann andere Daten als 0x00/0xff. Die 
werden im Empfangspuffer gespeichert und mit \n terminiert.

Ich denke simpler geht es dann nicht mehr :thinking:

Zugegeben, das ist jetzt schon stark auf meinen Anwendungsfall 
zugeschnitten.

Mit einem schnellen Polling - vlt interrupt-driven - könnte man doch 
locker eine asynchronen UART mit 115kBaud emulieren.

Echt erstaunlich, dass es sowas noch nicht gibt ... Google war da 
absolut unergiebig.

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Mampf F. schrieb:

> Slave arbeitet, währenddessen sendet Master 0x00 oder 0xff als Polling.
[...]
> Master pollt fleißig.

Unnützes Pollen ist mindestens ugly. Meistens ist es aber komplett 
idiotisch.

von c-hater (Gast)


Lesenswert?

c-hater schrieb:

> Unnützes Pollen ist mindestens ugly. Meistens ist es aber komplett
> idiotisch.

Im konkreten Fall natürlich selbsterklärend dadurch, das während des 
Polling der SPI-Bus für andere Aktivitäten unbenutzbar ist...

von Mampf F. (mampf) Benutzerseite


Lesenswert?

c-hater schrieb:
> c-hater schrieb:
>
>> Unnützes Pollen ist mindestens ugly. Meistens ist es aber komplett
>> idiotisch.

Ich bin mehr der Pragmatiker und weniger der Ästhetiker ¯\_(ツ)_/¯

>
> Im konkreten Fall natürlich selbsterklärend dadurch, das während des
> Polling der SPI-Bus für andere Aktivitäten unbenutzbar ist...

Natürlich^^ Und wenn ich jetzt behaupten würde, der Bus würde sonst für 
nichts anderes benutzt werden? Wäre es dann immer noch idiotisch? ;-)

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Mampf F. schrieb:

> Natürlich^^ Und wenn ich jetzt behaupten würde, der Bus würde sonst für
> nichts anderes benutzt werden? Wäre es dann immer noch idiotisch? ;-)

Naja, zumindest wäre es "ugly". Denn es schließt zukünftige Nutzungen 
des Bus aus. Ohne jede Not...

Also wohl doch zumindest stark in der Nähe von Idiotie. Der einzige 
nachvollziehbare Grund wäre, das eben jener eine IO-Pin wirklich nicht 
mehr verfügbar ist. Was allerdings meiner Erfahrung nach praktisch nie 
der Fall ist, wenn C'ler Libs zusammenleimen...
Da bleiben in aller Regel mehr genug Pins, die sich sharen ließen, um 
einen für wirklich wichtige Aufgaben freizumachen, z.B. die Nutzbarkeit 
eines kompletten Bus...

von Mampf F. (mampf) Benutzerseite


Lesenswert?

c-hater schrieb:
> Der einzige
> nachvollziehbare Grund wäre, das eben jener eine IO-Pin wirklich nicht
> mehr verfügbar ist. Was allerdings meiner Erfahrung nach praktisch nie
> der Fall ist, wenn C'ler Libs zusammenleimen...

Jau, da hast du recht.

Ich mache die Anpassungen für einen Bekannten, dem ich geraten habe, in 
seinem Platinen-Layout eine zusätzliche I/O-Leitung zu meinem Modul zu 
ziehen, damit der main-µC benachrichtigt werden kann, wenn der Slave 
Daten senden möchte.

Wahrscheinlich werde ich die dann auch benutzen.

Vielen Dank für eure Antworten!
Mampf

von Dieter R. (drei)


Lesenswert?

Mampf F. schrieb:

> 2. Fall: Slave will senden
>
> Master pollt fleißig.

Nach deinen einleitenden Worten zur Aufgabenstellung:

"Nach Empfang werden die JSON-Daten verarbeitet und es kann ein paar 
Sekunden dauern, bis die Antwort fertig ist, die dann als JSON 
zurückgeschickt wird."

muss er nicht fleißig pollen, sondern bloß mal gelegentlich. Wenn er das 
z. B. alle 100 ms tut, dann ist das keine merkbare Belastung. Also kein 
Grund, über weiteren Aufwand nachzudenken.

von Pandur S. (jetztnicht)


Lesenswert?

Ich wuerde die Funktionalitaet ueber das UART Uebertragen. Denn 
offensichtlich sitzt auf der anderen Seite des Uarts ein Controller.
Also ReadADC(), WriteDAC(u), usw und mich nicht um unterliegende Details 
kuemmern.

von Toby P. (Gast)


Lesenswert?

Mampf F. schrieb:
> hat jemand zufällig schon mal ein Protokoll mit Source gebastelt, mit
> dem man quasi UART als layer auf SPI aufsetzen kann?

Leider nicht, sollte aber theoretisch kein Problem sein.

Die SPI muss nur schneller laufen als die UART Baudrate-. Der Master 
muss dann dauernd senden damit Empfangsdaten auch eingelesen werden.

von сорок две (Gast)


Lesenswert?

Es gibt 16C550-artige UARTs mit SPI Anbindung in Hardware, z.B. 
SC16IS752.

сорок две

von Dieter R. (drei)


Lesenswert?

сорок две schrieb:
> Es gibt 16C550-artige UARTs mit SPI Anbindung in Hardware, z.B.
> SC16IS752.
>
> сорок две

Das ist aber SPI als Layer auf UART.

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.