Forum: Projekte & Code 8 UART's mit asm_pio / PIO / DMA / Micropython auf dem PI PICO


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Michael S. (Gast)


Angehängte Dateien:

Lesenswert?

8 UART's mit asm_pio  PIO  DMA / Micropython auf dem PI PICO

Worum geht es hier ?

Der PI PICO verfügt von Haus aus über 2 integrierte UART-Schnittstellen, 
von denen eine meist für die Programmierung genutzt wird.

Mit den PIO's kann man bis zu 8 zusätzliche UART-Schnittstellen 
(alternativ als Transmitter oder Receiver) an frei wählbaren Pins des PI 
PICO einrichten - zusätzlich zu den vorhandenen beiden Schnittstellen.

Es folgen drei Versionen der Schnittstelle, die ersten beiden entstanden 
bereits im Zusammenhang mit meinen "Spielereien mit asm_pio + 
Micropython auf dem PI PICO".
Hier ging es darum auszuprobieren, was man mit den PIO's anstellen kann.

Die dritte und neue Version nutzt DMA für den Datentransfer mit den 
PIO's.

Version 1 sendet bis zu 9 Byte nonblocking.
Der Empfang wird per Interrupt abgewickelt:
nach jedem empfangenen Byte wird eine ISR ausgeführt, die das empfangene 
Byte abholt.
Die Software muss selbst erkennen, wann ein Datentransfer abgeschlossen 
ist.

Eine weitere Variante erkennt das Übertragungsende (am Ausbleiben eines 
weiteren Startbits).

Das Problem dieses Konzeptes ist, dass viele Interrupts ausgelöst 
werden.
Micropython kann diese aber bei höheren Baud-Raten nicht mehr schnell 
genug bedienen, so dass irgendwann Datenverluste drohen und auch das 
laufende Programm ausgebremst wird.
Für moderate Baud-Raten und wenig zeitkritische Anwendungen funktoniert 
das aber zufrieden stellend.


Ansatz der 2. Version war, die 32-Bit-Fifos der Statemachines als Puffer 
zum Senden und Empfangen besser zu nutzen und damit die Anzahl der 
erforderlich Interrupts zu reduzieren.
Die Beschränkung liegt hier im 32-Byte-Limit.
Der asm_pio-Code des Receivers belegt das gesamt Insturktion-Memory. Und 
die Nachbereitung der empfangenen Daten ist etwas mühsam.


Zwischenzeitlich gibt es diverse Beiträge im Web, die aufzeigen, wie 
PICO's DMA auch unter Micropython nutzbar ist.
DMA bietet den Vorteil, dass nicht nur die Statemachines, sondern auch 
der Datentransfer im Hintergrund ablaufen..
Der Programmcode sieht auf den ersten Blick aufwändiger aus - aber das 
täuscht.

Wenn Interesse besteht - weitere Erläuterung gibt's in der Anlage in der 
readme.pdf.

Michael S.

von Michael S. (Gast)


Angehängte Dateien:

Lesenswert?

Hier noch ein kleiner Nachtrag:

Es hatte mich einen guten ganzen Tag gekostet, ein unerwartetes 
Verhalten der Statemachines zu beseitigen, leider zunächst ohne die 
Ursache zu verstehen:

Immer dann, wenn mehrere Instanzen eines Receivers gestartet werden 
sollten, arbeitete nie mehr als eine einzige Instanz auf jedem 
PIO-Block.
Das heißt, manchmal schon - aber nicht mehr nach einem Reset.

Ein Blick in die Register zeigte merkwürdige Unterschied in den 
Registern
- SMx_ADDR Register
- SMx_INSTR Register

Bei den nicht funktionierenden Statemachines waren die Register nicht 
gesetzt.
Kopieren der Registerinhalte von der arbeitenden SM auf die anderen 
brachte keine Veränderung.

Erst durch den Vergleich des Programmcodes mit meinen funktionierenden 
Beispielen in  den "Spielereien" entpuppte sich am Ende als Verursacher 
das "statemachine.restart()".

Ohne selbiges funktionierte alles wie erwartet.

Ich habe mir das heute noch einmal genauer angesehen und das restart() 
ohne Micropython durch Setzen der entsprechenden Bits in den 
Controll-Registern ausgeführt.

Das funktioniert.

Sollte da ein Bug im "restart()" stecken ?

Den Programmcode meines Testes füge ich mal an Anlage bei.


Michael S.

23.07.2022

von c-hater (Gast)


Lesenswert?

Michael S. schrieb:

> Der PI PICO verfügt von Haus aus über 2 integrierte UART-Schnittstellen,
> von denen eine meist für die Programmierung genutzt wird.

Ähem, nein, warum sollte man das tun? Es gibt doch SWD. Darüber kann man 
dann auch debuggen und nicht nur programmieren.

von Christoph M. (mchris)


Lesenswert?

Interssantes Projekt. Leider gibt es hier immer zu wenig Leute, die sich 
für ein spezielles Thema interessieren. An deiner Stelle würde ich es 
auf GitHub hochladen, dann kannst du auch sehen, wie viele Zugriffe es 
gibt.
Das gab es hier im Forum auch mal, aber leider haben sie es abgestellt.

von Michael S. (Gast)


Angehängte Dateien:

Lesenswert?

Noch ein letzter Nachtrag zu den UART-DMA-Varianten.

Mit dem Inline-Assembler hatte ich bislang noch nicht gearbeitet - und 
so ist mir anfangs nicht aufgefallen, dass man in einigen Instruktionen 
Konstanten verwenden kann (z.B. beim Shiften und Addieren).
Damit werden einige mov's überflüssig.

Bei der Gelegenheit habe ich auch die DMA_BASE-Adressen, die bislang per 
Parameter übergeben wurden, direkt in den Programmcode eingebaut.

Die (interne) Funktion "bit_reverse_8()" unterscheidet zwischen Source- 
und Targetadresse. Das Wechseln zwischen zwei unterschiedlichen 
Empfangsarrays kann dadurch entfallen.

Diese Änderungen betreffen nur Objekt-Interna, nach außen bleibt alles 
gleich.

Michael S.

25.07,2022

von Michael S. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

häufig denkt man komplizierter als erforderlich.

So war meine schlaue Überlegung gewesen:

Will man ein empfangenes Byte in ein Register der Statemachine 
schreiben,
dann shiftet man es normalerweise von links nach rechts rein.
1
8-Bit        32-Bit Register                    
2
8765_4321 -> 8765_4321-0000_0000-0000_0000-0000_0000

Um die Daten per DMA abzuholen, benöitgt man daher ein Array aus 32-Bit 
Variablem.
Das ist wenig effizient.

Um Platz zu sparen, habe ich die Bits von rechs nach links in das
niedrigstweritige Byte geshiftet - und konnte es so mit 8-Bit Variablen
auslesen:
1
             32-Bit Register                            8-Bit
2
             0000_0000-0000_0000-0000_0000-1234_5678 <- 1234_5678

Dummerweise wird dabei die Bit-Reihenfolge verdreht.
Das musste eine Inline-Assembler-Routine richten.

Dabei geht es viel einfacher.

Die Statemachine kennt keine direkte Instruktion zum Shiften.
Aber man kann aus einer beliebigen Quelle Bits ins ISR shiften.

Ausgangspunkt (8 Bit empfangen):
1
8-Bit        32-Bit Register                          
2
8765_4321 -> 8765_4321-0000_0000-0000_0000-0000_0000

Mit "in_(x, 24)" werden 24 (zufällige) Bits z.B, aus dem X-Register
hinterher geschoben - und schon passt die Byte-Position und die 
Bit-Reihenfolge.
1
-> 24 Bit -> xxxx_xxxx-xxxx_xxxx-xxxx_xxxx-8765_4321

Was im "x" steht, das interessiert nicht, es wird ja nicht ausgelesen.
Mit Hilfe von "autopush" bleibt sogar die Anzahl der benötigten 
Instruktionen unverändert.
Und das Invertieren der Bitreihenfolge entfällt.

Einfach ist eben einfach einfacher.

Michael S.

04.08.2022

von Cartman (Gast)


Lesenswert?

> Dabei geht es viel einfacher.

Ja, z.B. mit einen ARM aus der TI TIVA Serie.
Die haben von Haus aus max. 8 serielle Schnittstellen.

von Friedmann (Gast)


Lesenswert?

Cooles Projekt, das wunderbar zeigt, wie MicroPython,  ARM- und 
PIO-Assembler zusammenarbeiten. Habe eine Menge gelernt aus Deinem 
Programm.

von Transputer (Gast)


Lesenswert?

Interessantes Projekt! Ich hatte bisher den PI pico als "Spielzeug" 
abgetan. Nachdem ich mich nun genauer mit deinen Quelldateien und dem 
Datenblatt beschäftigt habe wird mir dieser immer sympathischer. Es kann 
gut sein, dass wir unsere STM32F0 durch den PI pico ersetzen. Vor allem 
sind diese lieferbar.

von Cartman (Gast)


Lesenswert?

Wenn etwas in der heutigen Zeit im Status:
> Vor allem sind diese lieferbar.
ist, wuerde ich eher von einer gewissen "Zurueckhaltung"
bei der Verwendung ausgehen.
Der Bastlermarkt macht den Kohl eben nicht fett.
Und in der Industrie scheint er, aus was fuer Gruenden auch immer,
nicht anzukommen.

von Jack V. (jackv)


Lesenswert?

Cartman schrieb:
> Und in der Industrie scheint er, aus was fuer Gruenden auch immer,
> nicht anzukommen.

Mag noch kommen – und sei’s eben nur aufgrund der Marktlage. Die 
interessante Frage ist: sollte das kommen, können sie dann die Nachfrage 
bedienen? Was jetzt zu haben ist, ist ja nur deswegen zu haben, weil es 
[noch] keine große Nachfrage aus dem kommerziellen Bereich gibt, in dem 
ordentliche Mengen umgesetzt werden.

von Transputer (Gast)


Lesenswert?

Cartman schrieb:
> Und in der Industrie scheint er, aus was fuer Gruenden auch immer,
> nicht anzukommen.

Liegt vermutlich am nicht integrierten FLASH. Das war bei mir bisher der 
Grund. Der vermeintliche Nachteil kann aber auch vorteilhaft sein. 
Erstens ist externer QSPI-Speicher in der Regel günstiger und es müssen 
nicht verschiedene µC-Derivate vorgehalten werden. Es wird einfach der 
benötigte FLASH dazu bestückt. Der interne RAM ist bei PI pico eher 
üppig.

von c-hater (Gast)


Lesenswert?

Cartman schrieb:

> Und in der Industrie scheint er, aus was fuer Gruenden auch immer,
> nicht anzukommen.

Oh' doch. Aber Entwicklung braucht halt Zeit, insbesondere, wenn man von 
einer unnötig fetten MCU-Sau mit lausig hingerotzter "mir gehört die 
Welt"-Software auf was Schlankeres migrieren muss.

Zu "alten Zeiten" war sowas nicht durchsetzbar. Jetzt werden die BWLer 
durch die Umstände dazu gezwungen, auch über sowas nachzudenken. Naja, 
und auf einmal geht dann doch was.

Worauf sich die BWLer aber noch nicht so richtig eingestellt haben, ist 
die wenig überraschende Tatsache, dass der Entwicklungsaufwand deutlich 
hochgeht, wenn die Resourcen knapp werden. Aber: noch'n Winter und auch 
die kommen dahinter...

von Jan V. (janv)


Lesenswert?

Michael S. schrieb:
> Der PI PICO verfügt von Haus aus über 2 integrierte UART-Schnittstellen,
> von denen eine meist für die Programmierung genutzt wird.

Falsch. Beide UARTs sind frei, die Programmierung erfolgt auf separatem 
Wege über USB.

Transputer schrieb:
> Ich hatte bisher den PI pico als "Spielzeug" abgetan

Naja, Micropython in seinem aktuellen Status würde ich diesen Status 
durchaus verpassen. Das Zeug läuft trotz vieler guter Ansätze 
zeitverschwenderisch code-interpretierend, meist single-threaded und 
noch lange nicht ausgereift und robust.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.