Cortex M3: CPU wacht nach _WFI() nicht mehr auf

Gast #3112554
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?
Gast #3113212
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).
Gast #3113272
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren