Forum: Mikrocontroller und Digitale Elektronik STM32G030J6 CubeMX SPI OpenDrain output


von Markus M. (adrock)


Lesenswert?

Hi,

wieder einmal wollte ich CubeMX eine Chance geben... für ein aktuelles 
Projekt benötige ich einen SPI-Output auf 5V Level auf einem 
STM32G030J6.

Mit einem OpenDrain-Output und Pullup sollte das ja kein Problem sein, 
der Pin am µC ist jedenfalls 5V tolerant und MOSI als Alternate Function 
mit OD-Ausgang ist auch dokumentiert.

Nur leider bietet mir CubeMX nicht die Möglichkeit AF+OD auf dem Pin zu 
konfigurieren.

Hat jmd. eine Idee warum das so ist? Ich verstehe es nicht...

Ansonsten schmeiße ich das ganze CubeMX-Zeug wieder weg und versuche es 
nächstes Jahr nochmal damit und mache es jetzt mal wieder ohne. Nur die 
Clock-Config ist etwas ekelig, leider gibt es auch keinen Generator für 
den Clock-Config Code mehr wie für den STM32F0. Das wird jetzt alles 
über HAL Calls gemacht...

Gruß
Markus

von jo mei (Gast)


Lesenswert?

Markus M. schrieb:
> Mit einem OpenDrain-Output und Pullup sollte das ja kein Problem sein

... aber doch irgendwie Pfusch da du für den High Pegel immer
einen schwächeren Treiber Pegel bekommst als für Low. Das
wird nicht für alle Clockfrequenzen ausreichen.

Markus M. schrieb:
> Hat jmd. eine Idee warum das so ist?

Weil aus der Sicht der Prozessor-Designer Open Drain und SPI
zusammen keinen Sinn macht, die Timings können dann nicht
garantiert werden.

Hänge doch einfach aussen einen 5V-Treiber in die MOSI-Leitung.

von Markus M. (adrock)


Lesenswert?

jo mei schrieb:

> Weil aus der Sicht der Prozessor-Designer Open Drain und SPI
> zusammen keinen Sinn macht, die Timings können dann nicht
> garantiert werden.

Okay, dass das Tool soweit "mitdenkt" hätte ich nicht vermutet. Aber ist 
m.E. mal wieder ein Fall von "Bevormundung". Sie hätten es auch erlauben 
können und dann eine Warnung ausgeben.

Das Signal hat 1MHz und muss genau einen CMOS-Eingang (WS2812 LED) 5mm 
entfernt treiben, ich nehme an das sollte funktionieren, wenn man den 
Pullup nicht zu groß macht.

: Bearbeitet durch User
von jo mei (Gast)


Lesenswert?

Markus M. schrieb:
> Okay, dass das Tool soweit "mitdenkt" hätte ich nicht vermutet.

Das wird nichts mit dem "Tool" zu tun haben sondern die
Hardware ist einfach so gestrickt dass sie das nicht kann.
Die Schaltmatrix hinter dem Ein/Ausgangspin erlaubt das nicht.

von jo mei (Gast)


Lesenswert?

Markus M. schrieb:
> ich nehme an das sollte funktionieren, wenn man den
> Pullup nicht zu groß macht.

Ja aber nicht so dass es allgemein Datenblatt-tauglich wäre.

Du solltest diesen einfach umzusetzenden Vorschlag beherzigen.

jo mei schrieb:
> Hänge doch einfach aussen einen 5V-Treiber in die MOSI-Leitung.

von pegel (Gast)


Lesenswert?

Was passiert, wenn ich im "Extended Mode" dem MOSI Pin zusätzlich ein 
GPIO_Output zuweise und diesen als Open Drain einstelle?
Ist der Pin dann OD oder PP?

von pegel (Gast)


Lesenswert?

Ich denke das könnte man mit ein Oszi testen.
Mit externem PU gegen 5V sollten sich andere Signalformen bei 
zusätzlichem GPIO_Output ergeben.

von m.n. (Gast)


Lesenswert?

Markus M. schrieb:
> Ansonsten schmeiße ich das ganze CubeMX-Zeug wieder weg und versuche es
> nächstes Jahr nochmal damit und mache es jetzt mal wieder ohne. Nur die
> Clock-Config ist etwas ekelig, leider gibt es auch keinen Generator für
> den Clock-Config Code mehr wie für den STM32F0.

Nimm doch CubeMX nur für die Takteinstellung in main(). In Deinem 
Programm kannst Du dann anschließend direkt auf die IO-Register 
zugreifen.

von pegel (Gast)


Lesenswert?

m.n. schrieb:
> In Deinem
> Programm kannst Du dann anschließend direkt auf die IO-Register
> zugreifen.

Und wieso geht das bei einem Programm das mit CubeMX erstellt wurde 
nicht mehr?

von pegel (Gast)


Lesenswert?

Entschuldigung.
Habe ich falsch gedeutet!

von jo mei (Gast)


Lesenswert?

m.n. schrieb:
> In Deinem
> Programm kannst Du dann anschließend direkt auf die IO-Register
> zugreifen.

Wenn es die Hardware nicht hergibt kannst du direkt in den
Registern ohne CubeMX herumfummeln wie du willst, da wird
es auch nicht besser.

von jo mei (Gast)


Lesenswert?

Markus M. schrieb:
> Das Signal hat 1MHz und muss genau einen CMOS-Eingang (WS2812 LED) 5mm
> entfernt treiben, ich nehme an das sollte funktionieren, wenn man den
> Pullup nicht zu groß macht.

Die SPI-Maschinerie wirst du nicht verwenden können, aber nachdem
deine Anforderungen "gering" sind kannst du dir selbst einen
kleinen SPI-Treiber schreiben und damit den Open Drain Pin benutzen.

Damit bleibt der Betonkopf befriedigt der keinen 5V-Treiber
einbauen will.

von Andreas W. (andreasw) Benutzerseite


Lesenswert?

Markus M. schrieb:
> Das Signal hat 1MHz und muss genau einen CMOS-Eingang (WS2812 LED) 5mm
> entfernt treiben, ich nehme an das sollte funktionieren, wenn man den
> Pullup nicht zu groß macht.

Bei den aktuellen WS2812 braucht man dies nicht mehr, da der High-Pegel 
bei >=2,7V liegt.

https://learn.watterott.com/de/kb/ws281x/#hinweise

von A. B. (Gast)


Lesenswert?

jo mei schrieb:
> Markus M. schrieb:
>
> Das wird nichts mit dem "Tool" zu tun haben sondern die
> Hardware ist einfach so gestrickt dass sie das nicht kann.
> Die Schaltmatrix hinter dem Ein/Ausgangspin erlaubt das nicht.

Oh doch, s. RM 0454, 6.3 "
• Alternate function push-pull with pull-up or pull-down capability
• Alternate function open-drain with pull-up or pull-down capability"

Fig. 13, Table 26, und "
• Peripheral alternate function:
– Connect the I/O to the desired AFx in one of the GPIOx_AFRL or 
GPIOx_AFRH
register.
– Select the type, pull-up/pull-down and output speed via the 
GPIOx_OTYPER,
GPIOx_PUPDR and GPIOx_OSPEEDER registers, respectively.
– Configure the desired I/O as an alternate function in the GPIOx_MODER 
register."

von A. B. (Gast)


Lesenswert?

Markus M. schrieb:
> Mit einem OpenDrain-Output und Pullup sollte das ja kein Problem sein,
> der Pin am µC ist jedenfalls 5V tolerant und MOSI als Alternate Function
> mit OD-Ausgang ist auch dokumentiert.

Die Pins sind NICHT 5V tolerant! Die Spec. sagt nur, dass max. VCC + 
4V zulässig ist. Gerade wenn der Pin mit einer anderen Baugruppe 
verbunden ist, muss man einkalkulieren, dass event. diese versorgt wird, 
der uC selbst aber nicht. Das "5V-tolerant" sollte man also nicht zu 
wörtlich nehmen.

Und insbesondere die verschämte Fußnote "2. To sustain a voltage higher 
than 4 V the internal pull-up/pull-down resistors must be disabled." bei 
Table 18 im Datenblatt beachten.

von Dieter Graef (Gast)


Lesenswert?

Markus M. schrieb:
Nur leider bietet mir CubeMX nicht die Möglichkeit AF+OD auf dem Pin zu
konfigurieren

In CubeMX im Fenster mit dem Chipbild von Pinout view auf System view 
wechseln, dort GPIO wählen, den entsprechenden Pin und dort bei GPIO 
Pull-up/ Pull-down die Einstellung ändern

m.f.G.
Dieter Graef

von Markus M. (adrock)


Lesenswert?

Andreas W. schrieb:
> Bei den aktuellen WS2812 braucht man dies nicht mehr, da der High-Pegel
> bei >=2,7V liegt.

Danke für den Hinweis, es sind allerdings WS2812(C?)-2020.

Auch davon gibt es wohl verschiedene Versionen mit 5mA und 15mA pro 
Kanal, aber für beide Versionen ist im Datenblatt für Vih min. 0.7*Vdd 
angegeben. Das wären 3.5V.

Allerdings fällt mir gerade auf, dass meine Schaltung (mit der neueren 
5mA Version) auf dem Steckbrett ohne PullUp/OpenDrain funktioniert. 
Evtl. hat sich das Problem tatsächlich erledigt - das wäre ja zu schön.

von Markus M. (adrock)


Lesenswert?

A. B. schrieb:

> Die Pins sind NICHT 5V tolerant! Die Spec. sagt nur, dass max. VCC +
> 4V zulässig ist. Gerade wenn der Pin mit einer anderen Baugruppe
> verbunden ist, muss man einkalkulieren, dass event. diese versorgt wird,
> der uC selbst aber nicht. Das "5V-tolerant" sollte man also nicht zu
> wörtlich nehmen.

Okay, das ist allerdings unschön, grummel. Gut, die LEDs und der µC 
werden aus der gleichen Quelle versorgt, somit werden die LEDs den 
Stützkondensator vor dem LDO vermutlich schneller leersaugen als dass 
die Spannung am µC weg ist. Aber ich werde mir das wohl mal anschauen 
müssen.

> Und insbesondere die verschämte Fußnote "2. To sustain a voltage higher
> than 4 V the internal pull-up/pull-down resistors must be disabled." bei
> Table 18 im Datenblatt beachten.

Danke, schön dass sie das so versteckt erwähnen.

Ich sehe schon, es  wird dann wohl auf einen 74LV1T125 an geeigneter 
Stelle hinauslaufen, falls die LEDs mit den 3.3V Vih doch nicht 
klarkommen.

: Bearbeitet durch User
von Christopher J. (christopher_j23)


Lesenswert?

A. B. schrieb:
> Und insbesondere die verschämte Fußnote "2. To sustain a voltage higher
> than 4 V the internal pull-up/pull-down resistors must be disabled." bei
> Table 18 im Datenblatt beachten.

Aus meiner Sicht klingt das doch eigentlich sehr logisch.
Wenn ich einen externen pull-up mit 5V habe und dazu noch den internen 
mit 3,3V zuschalte, zieht mir doch der interne den externen runter, oder 
habe ich da was falsch verstanden?

Eine andere Möglichkeit die WS2812 zu steuern ist übrigens per Timer und 
DMA. Das wird auch bei der Wordclock-Firmware so gemacht, die du hier 
sicher irgendwo im Forum findest. Kannst du sozusagen 1:1 übernehmen.

von A. B. (Gast)


Lesenswert?

Christopher J. schrieb:
> Aus meiner Sicht klingt das doch eigentlich sehr logisch.
> Wenn ich einen externen pull-up mit 5V habe und dazu noch den internen
> mit 3,3V zuschalte, zieht mir doch der interne den externen runter, oder
> habe ich da was falsch verstanden?

Das wäre aber eher harmlos. Die Gefahr ist wohl genau anders herum: 
Darüber würde die Versorgung des STM32 hoch gezogen, ggf. über 4V, was 
für den tödlich ausgehen könnte. Je nach Betriebszustand kommt der uC 
durchaus mit sehr geringen Strom aus, selbst an einem hochohmigen 
Pull-up fällt da also entsprechend nur eine geringe Spannung ab.

Diese Fußnote steht nicht ohne Grund unter "Absolute maximum ratings". 
Sprich, wenn nicht eingehalten, dann u. U. hinüber. Das Wort "sustain" 
sagt ja auch klar genug, was es meint.

Das ist schon recht kritisch, einmal ein falscher Wert ins Register 
geschrieben und schon ist das Ding kaputt. Also besser nicht machen oder 
zumindest direkt nach Reset die Ports konfigurieren und dann sofort die 
GPIO-Konfigurationsregister verriegeln ...

von Andreas W. (andreasw) Benutzerseite


Lesenswert?

Markus M. schrieb:
> Andreas W. schrieb:
>> Bei den aktuellen WS2812 braucht man dies nicht mehr, da der High-Pegel
>> bei >=2,7V liegt.
>
> Danke für den Hinweis, es sind allerdings WS2812(C?)-2020.
>
> Auch davon gibt es wohl verschiedene Versionen mit 5mA und 15mA pro
> Kanal, aber für beide Versionen ist im Datenblatt für Vih min. 0.7*Vdd
> angegeben. Das wären 3.5V.

Wenn es World-Semi WS2812C-2020 sind, dann ist Vih min 2.7V:
http://www.world-semi.com/Certifications/details-139-4.html

: Bearbeitet durch User
von Markus M. (adrock)


Lesenswert?

Andreas W. schrieb:
> Markus M. schrieb:
>> Andreas W. schrieb:
>>> Bei den aktuellen WS2812 braucht man dies nicht mehr, da der High-Pegel
>>> bei >=2,7V liegt.
>>
>> Danke für den Hinweis, es sind allerdings WS2812(C?)-2020.
>>
>> Auch davon gibt es wohl verschiedene Versionen mit 5mA und 15mA pro
>> Kanal, aber für beide Versionen ist im Datenblatt für Vih min. 0.7*Vdd
>> angegeben. Das wären 3.5V.
>
> Wenn es World-Semi WS2812C-2020 sind, dann ist Vih min 2.7V:
> http://www.world-semi.com/Certifications/details-139-4.html

Danke, sehr gut! WS und ihre Datenblätter ist ein gewisses Chaos. Es 
sollten die C sein.

Meine Tests ohne Pullup/OD haben auch funktioniert bisher, ohne 
"Fehlfarben" oder ähnliche Effekte. Umso besser, dann kann ich den 
Pullup weglassen.

Ich hatte es auch mit Pullup/OpenDrain getestet - der SPI-Ausgang lässt 
sich natürlich so konfigurieren, nur CubeMX mag es nicht. Habe es jetzt 
komplett ohne HAL implementiert, auch die Clock-Config war nur halb so 
schlimm wenn man die Werte bereits berechnet hatte. Am Ende nur ca. 20 
Zeilen Code und wieder was gelernt.

Es hat auch mit Pullup/OpenDrain funktioniert, allerdings sah die 
steigende Flanke mit 1k Pullup nicht mehr so gut aus, mit größeren 
Werten (10k) noch mieser natürlich. Nur für sehr langsame Signale 
brauchbar (wenn überhaupt, Einschränkungen wurden ja hier diskutiert).

Ich kann es also definitiv NICHT empfehlen mit Pullup - lesson 
learned.

Da habe ich ja Glück gehabt das die 2812C-2020 schon so spezifiziert 
sind, denn die fertigen Boards sind schon auf dem Weg von China zu mir 
und nachträgliches Gefrickel sieht immer unschön aus ;-)

Nochmal DANKE für euren Input.

von m.n. (Gast)


Lesenswert?

Markus M. schrieb:
> Habe es jetzt
> komplett ohne HAL implementiert, auch die Clock-Config war nur halb so
> schlimm wenn man die Werte bereits berechnet hatte. Am Ende nur ca. 20
> Zeilen Code und wieder was gelernt.

Das hast Du sehr gut gemacht ;-)

von Markus M. (adrock)


Lesenswert?

m.n. schrieb:
> Markus M. schrieb:
>> Habe es jetzt
>> komplett ohne HAL implementiert, auch die Clock-Config war nur halb so
>> schlimm wenn man die Werte bereits berechnet hatte. Am Ende nur ca. 20
>> Zeilen Code und wieder was gelernt.
>
> Das hast Du sehr gut gemacht ;-)

Es ist dadurch natürlich nicht portabel, aber da ich sowieso nicht 
zwischen sovielen Familien hin-und her switche geht es noch. Versuche 
jeweils eine Familie für einfache Sachen (war STM32F0xx ist jetzt 
STM32G0xx) und größere Sachen (STM32F4xx) zu verwenden und dazwischen 
eher nichts.

Hier noch der Clock Initcode, kann man natürlich noch mit Konstanten 
aufhübschen:
1
    // Set Flash wait states to 0, wait until set
2
3
    MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY_Msk, (0<<FLASH_ACR_LATENCY_Pos));
4
    while((READ_REG(FLASH->ACR)&FLASH_ACR_LATENCY_Msk) != (0<<FLASH_ACR_LATENCY_Pos));
5
6
    // Wait until HSI is stable
7
8
    while(!READ_BIT(RCC->CR, RCC_CR_HSIRDY_Msk));
9
10
    // Configure & enable PLL
11
    // SysClk == HSI/PLLM*PLLN/PLLR == 16MHz/1*12/8 == 24MHz
12
13
    MODIFY_REG(RCC->PLLCFGR,
14
        RCC_PLLCFGR_PLLSRC_Msk|RCC_PLLCFGR_PLLM_Msk|RCC_PLLCFGR_PLLN_Msk|
15
        RCC_PLLCFGR_PLLP_Msk|RCC_PLLCFGR_PLLR_Msk,
16
        RCC_PLLCFGR_PLLSRC_HSI|         // PLLM = 1, PLLSRC = HSI
17
        (12<<RCC_PLLCFGR_PLLN_Pos)|     // PLLN = 12
18
        RCC_PLLCFGR_PLLP_0|             // PLLP = 2
19
        (7<<RCC_PLLCFGR_PLLR_Pos)|      // PLLR = 8
20
        RCC_PLLCFGR_PLLREN);
21
22
    SET_BIT(RCC->CR, RCC_CR_PLLON);     // Enable PLL
23
24
    while(!READ_BIT(RCC->CR, RCC_CR_PLLRDY_Msk)); // Wait 'til ready
25
 
26
    // Configure system clocks
27
28
    // AHB and APB at default == 1, SW == PLLRCLT
29
30
    MODIFY_REG(RCC->CFGR, RCC_CFGR_SW_Msk, RCC_CFGR_SW_1);
31
32
    // Wait until switched
33
34
    while(READ_BIT(RCC->CFGR, RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_1); 
35
36
    // Whoooopie, clock is up! Update SystemCoreClock variable
37
38
    SystemCoreClockUpdate();

von Christopher J. (christopher_j23)


Lesenswert?

A. B. schrieb:
> Das wäre aber eher harmlos. Die Gefahr ist wohl genau anders herum:
> Darüber würde die Versorgung des STM32 hoch gezogen, ggf. über 4V, was
> für den tödlich ausgehen könnte. Je nach Betriebszustand kommt der uC
> durchaus mit sehr geringen Strom aus, selbst an einem hochohmigen
> Pull-up fällt da also entsprechend nur eine geringe Spannung ab.

Ah ok, jetzt verstehe ich. Das wäre etwa kritisch wenn der uC weniger 
als 1mA verbraucht aber über einen 4,7k Pullup an 5V "fremdgespeist" 
würde.

Markus M. schrieb:
> Ich hatte es auch mit Pullup/OpenDrain getestet - der SPI-Ausgang lässt
> sich natürlich so konfigurieren, nur CubeMX mag es nicht. Habe es jetzt
> komplett ohne HAL implementiert, auch die Clock-Config war nur halb so
> schlimm wenn man die Werte bereits berechnet hatte. Am Ende nur ca. 20
> Zeilen Code und wieder was gelernt.

Wichtig ist vor allem die Erkenntnis, dass es trotzdem geht, auch wenn 
es mit HAL nicht gehen würde ;)

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.