Moin... gähn Ich suche mich in meinem Projekt tot, warum "auf einmal" das Backup Ram seinen Inhalt verliert, wenn ich die Stromversorgung wegnehme. Klar, 3V Batterie ist dran an Vbat, Platine ist umgelötet. Alles auch nachgemessen, an Vbar liegen die 3V. Die RTC läuft auch einwandfrei weiter, wenn ich den USB Stecker abziehe. Es lief auch mal aber jetzt eben nicht mehr nachdem das Programm erweitert wurde. Damit wird es aktiviert. /* Enable SRAM Backup Register */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // Power für RTC/Backup RAM RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE); // Backup RAM mit Clock versorgen PWR_BackupAccessCmd(ENABLE); Und das bleibt auch so. Im Debugger auch alles gecheckt, schaltet man bei einigen DISABLE ein, "verschwindet" das Backup RAM auch wieder, beim ersten Befehl bleibt auch die Uhr stehen. Druck auf RESET Knopf lässt alles wie es ist, das RAM behält seine Inhalte, die Anwendung erkennt das auch, da ich eine ID im Ram abgelegt habe, die abgefragt wird. Mir fällt nichts mehr ein.... wieso kann das RAM seinen Inhalt noch verlieren? Das lief doch vorher :-( Oder habe ich durch 1000 Mal flashen die CPU geschossen? Leider kein Ersatzboard derzeit. Bin drauf und dran ein E2PROM einzubauen oder einen Sektor des Flash als E2PROM zu missbrauchen, da weiss man wenigstens was man hat.
Idee dazu: - Brown-Out Detection vom Prozessor benutzt, damit dieser im letzten Moment keinen Blödsinn macht? - gibt es einen Write-Enable Pin, den man an einen Prozessorpin legen könnte. Beim Reset bzw. BrownOut würde dann sofort per internen Pull-Up an den IOs ein weiteres Schreiben verhindert.
Ah, OK - internes RAM. Also kein WriteEnable Signal. Die BrownOut Idee bleibt aber.
Harald schrieb: > Idee dazu: > - Brown-Out Detection vom Prozessor benutzt, damit dieser im letzten > Moment keinen Blödsinn macht? > - gibt es einen Write-Enable Pin, den man an einen Prozessorpin legen > könnte. Beim Reset bzw. BrownOut würde dann sofort per internen Pull-Up > an den IOs ein weiteres Schreiben verhindert. Verstehe ich nicht ganz. Habe zu dem Thema gegoogelt, es passierte einigen schon auch hier. Es kann ja nicht sein, dass die Uhr einwandfrei weiterläuft, auch deren Backup Register 00 bis 0x19 überleben einwandfrei die Wegnahme der CPU Spannung und nur das 4K Backup Ram ist gelöscht. Ich warte mal auf das neue Board, evtl. ist ja die CPU auch beschädigt worden bei dem Rumbasteln.
Christian J. schrieb: > nur das 4K Backup Ram ist gelöscht Was verstehst du denn darunter? Nachher 4096 mal 00? Georg
Georg schrieb: > Was verstehst du denn darunter? Nachher 4096 mal 00? Nein, Zufallszahlen, alles durcheinander. Nur die RTC Register sind wie vorher, also Strom hat der Hobel.
Das Backup RAM hat einen eigenen Low Power Spannungsregler den man extra einschalten muss. Der wird nur bei Batteriebetrieb benutzt, im normalen Betrieb wird das RAM vom Core versorgt. Wenn du verraten würdest, welchen F4xx du hast, könnte man im Reference Manual nach dem passenden Bit suchen...
eagle user schrieb: > Wenn du verraten würdest, welchen F4xx du hast, könnte man im Reference > Manual nach dem passenden Bit suchen... STM32F407VG
Reicht das nicht? /* Enable SRAM Backup Register */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // Power für RTC/Backup RAM RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE); // Backup RAM mit Clock versorgen PWR_BackupAccessCmd(ENABLE); Ab dem 2.ten Befehl sieht man im Debugger das RAM sofort.
Ich meinte das Bit BRE (Bit 9) im PWR_CSR Register. Nachdem man nicht weiß, was PWR_BackupAccessCmd(ENABLE) macht (oder ob irgendwer das Bit zurücksetzt) solltest du mal direkt das PWR_CSR kontrollieren. Genau genommen muss auch das Bit BRR "Backup Regulator Ready" (Bit 3) gesetzt sein. Solange der Debugger verbunden ist, wird das Backup RAM direkt versorgt, nicht über diesen Backup Spannungsregler, deshalb geht's dann immer.
eagle user schrieb: > Ich meinte das Bit BRE (Bit 9) im PWR_CSR Register. Nachdem man nicht > weiß, was PWR_BackupAccessCmd(ENABLE) macht (oder ob irgendwer das Bit > zurücksetzt) solltest du mal direkt das PWR_CSR kontrollieren. Genau > genommen muss auch das Bit BRR "Backup Regulator Ready" (Bit 3) gesetzt > sein. > > Solange der Debugger verbunden ist, wird das Backup RAM direkt versorgt, > nicht über diesen Backup Spannungsregler, deshalb geht's dann immer. Dank dir für den Tip. Grad reingeschaut, das ist ja ein Krampf mit den ganzen Bits da drin. Hatten die nichts zu tun bei ST oder gibts pro Bit-Erfindung ne Prämie? Heute abend mal reinschauen, ob die Bits alle so rumtoggeln wie sie sollen... Sind die Register direkt zugänglich, ohne dass ich die StdperophLib verwenden muss, also zb PWR_CS->BRE = .... oder PWR_CS | = (1 << BRE) oder ähnlich?
Nett, wenn man per ftp von der Arbeit zu Hause was holen kann :-) Da haben wir sie ja schon.... /******************* Bit definition for PWR_CSR register ********************/ #define PWR_CSR_WUF ((uint32_t)0x00000001) /*!< Wakeup Flag */ #define PWR_CSR_SBF ((uint32_t)0x00000002) /*!< Standby Flag */ #define PWR_CSR_PVDO ((uint32_t)0x00000004) /*!< PVD Output */ #define PWR_CSR_BRR ((uint32_t)0x00000008) /*!< Backup regulator ready */ #define PWR_CSR_WUPP ((uint32_t)0x00000080) /*!< WKUP pin Polarity */ #define PWR_CSR_EWUP ((uint32_t)0x00000100) /*!< Enable WKUP pin */ #define PWR_CSR_BRE ((uint32_t)0x00000200) /*!< Backup regulator enable */ #define PWR_CSR_VOSRDY ((uint32_t)0x00004000) /*!< Regulator voltage scaling output selection ready */ #define PWR_CSR_ODRDY ((uint32_t)0x00010000) /*!< Over Drive generator ready */ #define PWR_CSR_ODSWRDY ((uint32_t)0x00020000) /*!< Over Drive Switch ready */ #define PWR_CSR_UDSWRDY ((uint32_t)0x000C0000) /*!< Under Drive ready */
Sooo....... Dann kommt hier mal die Auflösung, an der wahrscheinlich schon mancher graue Haare bekommen hat...tatatataaaa. Um das Backup Ram zu benutzen muss folgende Sequenz herhalten bei Verwendung der StdPeripLib 1.6.1
1 | /* Enable SRAM Backup Register */ |
2 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); |
3 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE); |
4 | PWR_MainRegulatorModeConfig(PWR_Regulator_Voltage_Scale1); |
5 | PWR_WakeUpPinCmd(ENABLE); |
6 | PWR_BackupRegulatorCmd(ENABLE); |
7 | while(PWR_GetFlagStatus(PWR_FLAG_BRR) == RESET); |
8 | PWR_BackupAccessCmd(ENABLE); |
BRE laesst sich erst setzen, wenn das EWUP Bit gesetzt wurde. Zufall dass ich das rausgefunden habe. Und dann ist der BKRAM Inhalt beim Power Off/on auch wieder da :-)))) Danke Dir !
Christian J. schrieb: > BRE laesst sich erst setzen, wenn das EWUP Bit gesetzt wurde. Zufall > dass ich das rausgefunden habe. Warum sollte das so sein? Steht das irgendwo im Datenblatt?. Waere ja unpraktisch, wenn man den WKUP-Pin nicht braucht (oder PA0 fuer was anderes braucht).
Tassilo H. schrieb: > Warum sollte das so sein? Steht das irgendwo im Datenblatt?. Waere ja > unpraktisch, wenn man den WKUP-Pin nicht braucht (oder PA0 fuer was > anderes braucht). k.A. Ist jedenfalls so, BRE lässt sich bei mir nur setzen, wenn vorher EWUP gesetzt worden ist. Tja... Sag mal, gibt es da ein Standardverfahren diese Bits zu setzen, außer den PeriphLib Funktionen?
Also bei mir sieht das für die RTC so aus wie unten gezeigt, Backup-RAM ist noch nicht verwendet, soll aber noch, deshalb bin ich auf diesen Thread aufmerksam geworden. Ich verwende direkten Registerzugriff (abgesehen vom clock enable, anfangs hab' ich noch die Lib verwendet, bis mir aufgefallen ist, daß das für viele Dinge unübersichtlicher ist als direkter Registerzugriff und auch nicht portabler). So kann ich den Code wenigstens mit dem Datenblatt abgleichen. Ob es Probleme mit dem Backup RAM gibt, weiß ich nicht, das wird (noch) nicht verwendet (daher auch das etwas sinnlose DBUP an/aus und der Backup Regulator wird noch nicht eingeschaltet).
1 | void clockSetRTCWriteProtection(bool enable) |
2 | {
|
3 | if (enable) { |
4 | RTC->WPR = 0xFF; |
5 | PWR->CR &= ~PWR_CR_DBP; |
6 | } else { |
7 | PWR->CR |= PWR_CR_DBP; |
8 | RTC->WPR = 0xCA; |
9 | RTC->WPR = 0x53; |
10 | }
|
11 | }
|
12 | |
13 | void clockSetInitializationMode(bool enable) |
14 | {
|
15 | if (enable) { |
16 | RTC->ISR |= RTC_ISR_INIT; |
17 | systickSetIOTimeout(3); |
18 | while ( ((RTC->ISR & RTC_ISR_INITF) == 0) && (!systickIOTimeoutExpired()) ); |
19 | } else { |
20 | // clear init flag and also the RSF flag
|
21 | RTC->ISR &= ~(RTC_ISR_INIT | RTC_ISR_RSF); |
22 | }
|
23 | }
|
24 | |
25 | void clockInit() |
26 | {
|
27 | uint32_t v; |
28 | |
29 | if ( (RCC->BDCR & (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_1 | RCC_BDCR_RTCSEL_0 | RCC_BDCR_LSEBYP | RCC_BDCR_LSEON)) |
30 | != (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_0 | RCC_BDCR_LSEON) ) { |
31 | // initialization needed
|
32 | // reset Backup domain
|
33 | RCC->BDCR |= RCC_BDCR_BDRST; |
34 | RCC->BDCR &= ~RCC_BDCR_BDRST; |
35 | // enable write access to BDCR
|
36 | PWR->CR |= PWR_CR_DBP; |
37 | // clear all the RTC relevant bits
|
38 | v = RCC->BDCR & (~(RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_1 | RCC_BDCR_RTCSEL_0 | RCC_BDCR_LSEBYP | RCC_BDCR_LSEON)); |
39 | v |= (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_0 | RCC_BDCR_LSEON); |
40 | RCC->BDCR = v; |
41 | // ok, RTC clock selected and enabled, set it up
|
42 | clockSetRTCWriteProtection(false); |
43 | RTC->CR &= 0xFF000000; // clear all non-reserved bits |
44 | RTC->ISR &= 0xFFFE8000; // clear all non-reserved bits |
45 | clockSetInitializationMode(true); |
46 | RTC->PRER = 255; // sync divider by 256 |
47 | RTC->PRER |= 127<<16; // async divider by 128 |
48 | clockSetInitializationMode(false); |
49 | clockSetRTCWriteProtection(true); |
50 | clockTimeAvailable = false; |
51 | } else { |
52 | clockTimeAvailable = true; |
53 | // enable write access to Backup Domain
|
54 | PWR->CR |= PWR_CR_DBP; |
55 | }
|
56 | // enable backup sram
|
57 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE); |
58 | PWR->CR &= ~PWR_CR_DBP; |
59 | |
60 | ... etc. |
Tassilo H. schrieb: > Ich verwende direkten Registerzugriff (abgesehen vom clock enable, > anfangs hab' ich noch die Lib verwendet, bis mir aufgefallen ist, daß > das für viele Dinge unübersichtlicher ist als direkter Registerzugriff > und auch nicht portabler). Naja, das erinnert mich an meine schlimmsten LPC2368 Zeiten, wo ich die PLL etc auch so gesetzt habe. Ich könnte keine Zeile intuitiv lesen so wie das da steht. Ich habe grad nochmal rumprobiert, jetzt lässt sich BRE auch so setzen. Vorher aber defintiv nicht. Warum weiss ich nicht, das Bit blieb 0. Ich schalte EWUPO jetzt wieder ab nachdem alles gesetzt ist und belasse es dabei. Nachher geht das wieder nicht. Ok, auf jeden Fall sind wir etwas weiter. Ich finde es nur echt blöd, dass die StdPeriphLib kein pdf als Manual hat, diese chm Datei finde ich voll daneben. PS: Wo steht das denn alles drin? Automatische Ergänzung funzt nicht. PWR->CR |= PWR_CR_DBP; CMSIS? PS: Mit dem BRE Bit hat es irgendwas auf sich, jetzt lässt es sich nicht mehr zurücksetzen im Debugger. Seltsam....
Christian J. schrieb: > PS: Wo steht das denn alles drin? Automatische Ergänzung funzt nicht. > > PWR->CR |= PWR_CR_DBP; stm32f4xx.h Da ist alles drin nach dem Schema [Peripheriename aus dem Datenblatt]->[Registername aus dem Datenblatt] Diese Headerdatei kam mit der CooCox IDE, aber nach den Kommentaren ist sie von ST und gehört zu CMSIS.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.