Hallo,
das Thema ist im Netz leider nur recht verwirrend dargestellt und teils
sogar falsch, daher frage ich mal.
Ich möchte bei meinem F103 in den Stop oder StandbyMode und er soll per
RTC Sekunden Interrupt wieder rauskommen.
Nur wie? Die Modes sind nicht debugbar. Einmal drin kann ich den Chip
erstmal löschen und vorher Reset drücken, damit er wieder durch den
st-link beschreibar wird. Und dann finden sich noch so Dinge wie
void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)
void PWR_EnterSTANDBYMode(void)
aber auch
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState)
die damit etwas zu tun haben zu scheinen. In einer App Note wird zudem
gesagt, dass ein EXTI auf die NVIC Line 17 gelegt werden soll. Aber den
RTC Alarm nutze ich nicht.
Wie sieht das denn nun ganz einfach aus? Mehr ein paar Codezeilen
dürften da ja nicht sein, den durch den RTC Int aufwachen zu lassen. Bei
meinen Versuchen weckte der Systick die CPU auf, schalte ich den ab
wacht sie nicht mehr auf.
EXTI->PR = 0xFFFFFFFF;
PWR_ClearFlag(PWR_FLAG_WU);
PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFE);
SystemInit();
Gruss,
Christian
Chris J. schrieb:> das Thema ist im Netz leider nur recht verwirrend dargestellt und teils> sogar falsch, daher frage ich mal.
Im "Netz" vagabundiert halt vieles herum. Und??? Es soll (rein
gerüchtehalber ...) ein Reference Manual geben, das man sich angeblich
bei ST kostenlos herunter laden kann.
> Ich möchte bei meinem F103 in den Stop oder StandbyMode und er soll per> RTC Sekunden Interrupt wieder rauskommen.
Hm, in besagten Manual (Figure 179. RTC simplified block diagram) ist
klar beschrieben, dass RTC_Second nur nach RTC_CR geht, und da steht
ausdrücklich "not powered in Standby" drunter. Im Standby ist's also
nix.
Steht auch in "Table 15. Standby mode". Also jede Sekunde den Alarm für
die nächste Sekunde setzen ...
Zum Stop-Mode siehe "Table 14. Stop mode".
> Wie sieht das denn nun ganz einfach aus? Mehr ein paar Codezeilen> dürften da ja nicht sein, den durch den RTC Int aufwachen zu lassen.
Und wenn man gründlich im Reference Manual liest, findet man auch
heraus, wie die ggf. aussehen müssen. Aber eine fertige Copy-And-Paste
Lösung gibt's halt nicht.
Selber machen macht Spass - und gibt hinterher ein echtes
Erfolgserlebnis. ;-)
A. B. schrieb:> ein Reference Manual geben, das man sich angeblich> bei ST kostenlos herunter laden kann.
Sorry, aber ich stelle hier nur was ein, wenn ich absolut nicht mehr
weiter weiss und alle Quellen zur Rate gezogen habe. Der INT springt
nicht an, auch im Stop Mode nicht und auch so wird kein Alarm Int
erzeugt. Der benutzt ja wohl die gleiche Routine wie die anderen RTC
Ints und wird nur über sein Bit unterschieden... einen EXTI_17 Handler
gibt es nicht.
Die Schose spielt einwandfrei
Habs schon...
Das Zauberwort hiess: PWR_BackupAccessCmd(ENABLE);
Ohne das geht nix mit der RTC.
Und dieser aus dem Netz abgeschrieben Code läuft auch nicht, da da
unbedingt ein RTC_WaitForLastTask() zwischen die beiden Operationen
muss,
sonst wird die AL Time nicht gesetzt.
FALSCH:
RTC_SetAlarm(RTC_GetCounter() + 3);
RICHTIG:
PWR_BackupAccessCmd(ENABLE);
RTC_WaitForSynchro();
RTC_WaitForLastTask();
uint32_t val = RTC_GetCounter();
RTC_WaitForLastTask();
RTC_SetAlarm(val + 3);
RTC_WaitForLastTask();
PWR_BackupAccessCmd(DISABLE);
Ob das nötig ist weiss ich nicht, es spielt mit und ohne in der ISR
EXTI_ClearITPendingBit(EXTI_Line17); // Remove LINE interrupt flag bit
Das Aufwachen aus dem Stoop läuft leider immer noch nicht, weder mit WFI
noch mit WFE und im Release rennt er sogar in den Hardfault Handler :-(
Funzt nicht :-(
Das Ding geht und geht nicht in den Sleep Mode, die anderen Modes
brauche ich nicht. Und das ewige manuelle Um-Jumpern und Löschen, weil
die swd Schnittstelle sich aufhängt nervt auch.
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; /* Enable deepsleep */
SetRedLED(ENABLE);
__WFI(); /* Enter sleep mode */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
SetRedLED(DISABLE);
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI(); /* Enter sleep mode */
pegel schrieb:> Deshalb liebe ich HAL. :)
Damit fange ich nicht mehr an, diese Klicki-Bunti CubeMX Welt ist mir
suspekt, das Alte tut es ja auch ;-) Ging aber auch so, habs mal
zusammen geschrieben im Code Bereich.
Ich hab zwar keine Ahnung, aber bei SLEEPDEEP würde ich auf Stop oder
Standby-Mode tippen. Und dann wäre noch zu klären, wo nach Beendigung
eines Ereignisses die Ausführung weiter geht.
Da du die SPL nutzt, würde ich dir raten mal in die zahlreichen Examples
zu schauen. Damit habe ich den Stop- und Standby-Mode in kurzer Zeit
lauffähig bekommen, allerdings mit EXTI zum aufwecken.
Das ist vielleicht eine bessere Quelle zum abtippen, als irgendwas aus
dem "Netz"
Auch wenn Du den RTC jetzt am laufen hast, kleiner Tip am Rande: Du
kannst den RTC Interrupt auch ohne Sleep/Standby debuggen. Mach erstmal
das RTC Krams mit dem Debugger rund und dann, wenn der Alarm
funktioniert, gehst Du in den Sleep.
Vor dem Sleep deaktiviere ich Systick, danach aktiviere ich ihn wieder
und setze ich die Clock neu. (Bei mir passte der HAL_Delay sonst
nicht). Du solltest auch I2C usw. deaktivieren, sonst bleibt der
Verbrauch relativ hoch.
Noch ein Tip: Nach einem Reset lasse ich den Controller mindestens 5
Sekunden wach (lasse LED blinken, dann seh' ich es). Währenddessen kann
man mit dem Debugger neu aufspielen. Dann reicht es Reset zu drücken,
dann Debug in der IDE.
...Alex
noreply@noreply.com schrieb:> Ich hab zwar keine Ahnung, aber bei SLEEPDEEP würde ich auf Stop oder> Standby-Mode tippen.
Nee.... das ist wirklch SLEEP Mode, der hat nur diverse Modi.
Ich schrieb:> Da du die SPL nutzt, würde ich dir raten mal in die zahlreichen Examples> zu schauen.
Ja, nach 7 Stunden fiel mir ein, dass ich die irgendwo mal kopiert hatte
und das Vergessene, nämlich der EXTI17 fiel vom Himmel. Nicht aber, dass
dann plötzlich ein anderer Handler angesprungen wird als vorher.
Es laufe nur SLEEP und STOP, aus Standby kommt er nur mit einem echten
Pin Int wieder raus und startet dann komplett neu per Reset, zumindest
bei mir.
Alexander B. schrieb:> Mach erstmal> das RTC Krams mit dem Debugger rund und dann, wenn der Alarm> funktioniert, gehst Du in den Sleep.
Genauso habe ich es gemacht, dass der Sleep und Stop funktionieren sah
ich auch nur an den Blinki-LEDs. Nur sagt einem keiner, dass bei allen
Modi SysClock und SysTick neu konfiguriert werden müssen, ebenso die
Clock fürs ADC und SPI etc. Alle gelöscht, watt ein Mist :-( Und dass
Systick auch den Sleep sofort beendet und daher abgeschaltet werden
muss. Eigentlich kann man den Systick sogar dafür nehmen, wenn man mit
24 Bit zufrieden ist.
Und der Watchdog funkt einem auch noch dazwischen, den juckt das nämlich
nicht, wenn der abläuft wird resettet.
Mühsam, mühsam.... dabei will ich nur von den 50mA, die das Board normal
braucht auf ca 5-6, damit der 18650 Akku etwas länger hält. Echte Low
Power Anwendungen habe ich lieber mit dem Attiny 84 gemacht an der
Arduino IDE, direkt an eine Mignon mit DC/DC Step up (200uA) da hält ne
Mignon fast 1/2 Jahr für den Sensor und Funkmodul.
> Nach einem Reset lasse ich den Controller mindestens 5> Sekunden wach (lasse LED blinken, dann seh' ich es). Währenddessen kann> man mit dem Debugger neu aufspielen. Dann reicht es Reset zu drücken,> dann Debug in der IDE
Auf die Idee kam ich auch später, vorher artig immer umgestöpselt und
mit ST Utility gelöscht, bis das so nervig wurde, dass ich auch auf
diese Idee kam.
Ist zwar HAL, aber ich teile mal meinen Code:
https://gist.github.com/alexbrickwedde/21bd84693f0749a6ac8121bb72026dd1
Ich lasse den Controller max 10 Sekunden schlafen und bediene dann den
IWDG. Über den Tageswechsel erkenne ich dann recht einfach, dass der
Sleep beendet sein soll. Egal, ob und wie oft er vorher durch irgendwas
anderes aufwacht.
I2C, SPI usw. (de)aktivieren fehlt hier noch (ist in der DoSomeAction).