Forum: Mikrocontroller und Digitale Elektronik Cortex M3: CPU wacht nach _WFI() nicht mehr auf


von Bronco (Gast)


Lesenswert?

Hallo zusammen,

ich mache gerade meine ersten Schritte mit einem Cortex-M3 (CPU-Kern in 
einem SmartFusion FPGA) und versteh da was nicht:
Ich will die CPU in der Hauptschleife schlafen legen und zyklisch über 
einen Timer aufwecken, um ein festes Zeitraster zu erhalten (das hab ich 
schon erfolgreich auf AVR, PIC & Co gemacht).
1
main()
2
{
3
  ...
4
  while( 1 )
5
  {
6
    while (stTimer1Flag_u8 == 0)
7
    {
8
      __WFI();
9
    }
10
    stTimer1Flag_u8 = 0;
11
    ...
12
  }
13
}
14
15
void Timer1_IRQHandler(void)
16
{
17
  stTimer1Flag_u8 = 0x01;
18
  MSS_TIM1_clear_irq();
19
}

Ohne das _WFI() funktioniert alles wie gewünscht: LEDs blinken, UART tut 
usw.
Mit _WFI() stoppt die CPU und nichts geht mehr, auch der Timer-Interrupt 
scheint nicht zu kommen.

Ich vermute grundlegenes ARM-Unwissen als Fehlerursache.
Hat jemand einen Tip?

von Jim M. (turboj)


Lesenswert?

> Cortex-M3 (CPU-Kern in einem SmartFusion FPGA)

Gibt es da ein Datenblstt für?

> Ohne das _WFI() funktioniert alles wie gewünscht [...]

Ist das SLEEPDEEP Bit gesetzt? Dann wird meistens der Takt mit 
ausgeschaltet.

von Bronco (Gast)


Lesenswert?

Jim Meba schrieb:
>> Cortex-M3 (CPU-Kern in einem SmartFusion FPGA)
> Gibt es da ein Datenblstt für?
Gibt's hier (40MB):
http://www.actel.com/documents/SmartFusion2_CortexM3_UG.pdf

>> Ohne das _WFI() funktioniert alles wie gewünscht [...]
>
> Ist das SLEEPDEEP Bit gesetzt? Dann wird meistens der Takt mit
> ausgeschaltet.

Gibt es einen generellen Weg, wie man auf Register wie SystemControl 
zugreifen kann? Ich konnte in der CSMIS-Doku dazu nichts finden (wie 
gesagt: erste Schritte).

von Achim S. (Gast)


Lesenswert?

Der Registerzugriff erfolgt per Zeiger auf die Speicheradresse des 
Registers. Die Register sind also über den selben Adressraum erreichbar 
wie der Arbeitsspeicher, nur die Adressbereiche unterscheiden sich.

Im Normalfall bindest du eine Include-Datei ein, die den entsprechenden 
Adressen deines µC sinnvolle Namen gibt. Ein Beispiel:

In der LPC122x.h ist die Basisadresse des Registerblocks für die GPIO0 
festgelegt:

#define LPC_GPIO0_BASE            (0x50000000)

Auf diese Basisadresse wird in der selben Datei ein struct gelegt, mit 
dem der Offset der einzelnen Register dieses Blocks definiert wird:

#define LPC_GPIO0       ((LPC_GPIO_Type   *) LPC_GPIO0_BASE)

In meinem Code greife ich dann auf ein Element des structs zu:

LPC_GPIO0->SET = XLAT; //XLAT-Pin auf high

Findest du diese inculde-Datei nicht (was eigentlich nicht vorkommen 
sollte), musst du selbst einen Zeiger auf die entsprechende Adresse 
legen.

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.