Forum: Mikrocontroller und Digitale Elektronik Fast External Interrupts XC164 Infineon


von Rogger R. (manta)


Lesenswert?

Hallo zusammen!

Ich habe unlängst versucht die Fast External Interrupts von meinem XC164 
von Infineon zu verwenden. Allerdings funktioniert das ganze nicht so 
richtig.
Falls es hilfreich ist, ich verwende die Software Keil zum 
programmieren!

Hier mal mein anfänglicher Code:
1
void extISR(void) interrupt 0x18
2
{
3
  counter = counter +1;
4
}
5
6
void main(void){
7
//Pin Konfig
8
DP1H_P0 = 0;
9
DP1H_P4 = 0;
10
  
11
//Mode Register auf Capture setzen
12
CC2_M4 |= 0x0200;
13
14
//ConRegister auf falling edge setzen
15
EXICON |= 0x0002; 
16
  
17
//Interrupt LVL und GVL setzen
18
CC1_CC8IC = 0x0059;
19
20
//
21
...
22
//
23
24
PSW_IEN = 1;
25
26
//
27
...
28
//
29
30
}


Nach einigen Recherchen bin ich schließlich draufgekommen, dass das 
Register EXICON schreibgeschützt ist und das ich das ganze mit einem 
"unlock modul" betreiben muss...dieses sollte so aussehen:
1
//****************************************************************************
2
// @Function      void MAIN_vUnlockProtecReg(void) 
3
//
4
//----------------------------------------------------------------------------
5
// @Description   This function makes it possible to write one protected 
6
//                register. After calling of this function and write on the 
7
//                protected register is the security level set to low 
8
//                protected mode.
9
//
10
//----------------------------------------------------------------------------
11
// @Returnvalue   None
12
//
13
//----------------------------------------------------------------------------
14
// @Parameters    None
15
//
16
//----------------------------------------------------------------------------
17
// @Date          27.02.2009
18
//
19
//****************************************************************************
20
void MAIN_vUnlockProtecReg(void)
21
{
22
  uword uwPASSWORD;
23
24
  if((SCUSLS & 0x1800) == 0x0800)      // if low protected mode
25
  {
26
27
    uwPASSWORD = SCUSLS & 0x00FF;
28
    uwPASSWORD = (~uwPASSWORD) & 0x00FF;
29
    SCUSLC = 0x8E00 | uwPASSWORD;      // command 4
30
31
  }  // end if low protected mode
32
33
  if((SCUSLS & 0x1800) == 0x1800)      // if write protected mode
34
  {
35
    SCUSLC = 0xAAAA;                   // command 0
36
    SCUSLC = 0x5554;                   // command 1
37
38
    uwPASSWORD = SCUSLS & 0x00FF;
39
    uwPASSWORD = (~uwPASSWORD) & 0x00FF;
40
41
    SCUSLC = 0x9600 | uwPASSWORD;      // command 2
42
    SCUSLC = 0x0800;                   // command 3; new PASSWOR is 0x00
43
44
    uwPASSWORD = SCUSLS & 0x00FF;
45
    uwPASSWORD = (~uwPASSWORD) & 0x00FF;
46
    SCUSLC = 0x8E00 | uwPASSWORD;      // command 4
47
48
  }  // end if write protected mode
49
50
} //  End of function MAIN_vUnlockProtecReg


So das ganze ist ja gut und schön, nur wie verwende ich diese "unlock 
Routine"? Wichitg für mich ist der command 4. Nach diesem sollte ich 
Schreibzugriff haben. Aber ich komm beim besten Willen nicht drauf, wie 
ich das Ding verwende :S
Aja und ich will keine Komplettlösung! Ich steh komplett auf der 
Leitung...Ich bräuchte nur einen Schubs in die richtige Richtung!

lg + danke
Manta

von Guido (Gast)


Lesenswert?

Ich würde das eins zu eins aus der Dokumentation übernehmen.Es macht
wohl wenig Sinn sich Gedanken darüber zu machen. Wie der Keil das
umsetzt, wissen eh nur die Götter.

1
Programming Examples
2
3
EXTR #4 ;Sequence to change the security level
4
MOV SCUSLC, #0AAAAH ;Command0
5
MOV SCUSLC, #05554H ;Command1
6
MOV SCUSLC, #096FFH ;Command2: current password = 00H
7
MOV SCUSLC, #008EDH ;Command3: level = 01, new password = EDH
8
9
EXTR #1 ;Access sequence in secured mode
10
MOV SCUSLC, #8E12H ;Command4: current password = EDH
11
MOV register, data ;Access enabled by the preceding Command4

von B73 (Gast)


Lesenswert?

Hallo manta,
ich kenne nur den XC167, aber vielleicht ist es ja beim XC164 genauso. 
Wenn Du Dir eine Beispielapplikation mit DAVE2 erzeugst, dann wird die 
Unlock-Funktion unmittelbar vor jedem Zugriff (exakt eine Zeile vorher) 
auf das geschützte Register in den Quellcode geschrieben. Danach ist das 
Register für einen Schreibzugriff geöffnet. Wenn Du nochmal schreiben 
möchtest, vorher nochmal Unlock aufrufen. Hope it helps.
Gruß,
B73
P.S. CC8 ist beim XC167 an P2.8 gebunden. Willst Du den IRQ beim 
Capture-Ereignis in CC8 oder bei einem Flankenwechsel am Eingang P2.8?

von Rogger R. (manta)


Lesenswert?

Danke mal für die Antworten!

Davor die Routine aufrufen und dann verwenden! Danke das hat gefunzt!
(Es ist immer einfacher als man probiert ^^)

B73 schrieb:
> P.S. CC8 ist beim XC167 an P2.8 gebunden. Willst Du den IRQ beim
> Capture-Ereignis in CC8 oder bei einem Flankenwechsel am Eingang P2.8?

In den User Manuals steht bei den External Interrupts, dass das 
CC1_CC8IC das entsprechende Controlregister ist -> das stimmt ;)

---

Wenn wir gleich mal dabei sind hätte ich noch eine weitere Frage die 
sich mir stellt:

Wenn ich jetzt nicht nur External Interrupts verwenden möchte, sondern 
auch Fast External Interrupts, dann muss ich diese entsprechend Keil 
deklarieren (das passt, das weiß ich wie es geht). Aber wo krieg ich die 
Adresse von den Dingern her? Machts hier ein einfacher Pointer auf die 
entsprechende Funktion?

Was ich gefunden habe, was so herumkusiert ist folgendes:
1
//Defines/oder eher Macros
2
#define SEG(func) (unsigned int)(((unsigned long)((void (far *) (void))func) >> 16))
3
#define SOF(func) (unsigned int)(((void (far *) (void))func))
4
5
//Globals
6
unsigned int counter = 0;
7
8
//ISR - zählt hier nur die globalvar counter rauf
9
void extISR(void) interrupt hsync=CACHED
10
{
11
  counter = counter +1;
12
}
13
14
//MAIN
15
void main(void){
16
  
17
  //Initialisiere Fast Interrupts damit sie auch "fast" sind
18
  //Schreibe in den Cache zu deutsch
19
  FINT0CSP   = SEG(extISR) | 0x8C00;
20
  FINT0ADDR  = SOF(extISR);
21
  
22
  //Pin Konfig
23
  DP1H_P0 = 0;
24
  
25
  //Schreiben erlauben
26
  MAIN_vUnlockProtecReg();
27
  //External Interrupts setzen
28
  EXICON |= 0x0002; // Falling edge EXI0
29
  
30
  //Interrupt Controlregister
31
  CC1_CC8IC = 0x0059;
32
33
  //Global IEN setzen
34
  PSW_IEN = 1;
35
  
36
  while(1);
37
}

Bei den beiden:

FINT0CSP   = SEG(extISR) | 0x8C00;
FINT0ADDR  = SOF(extISR);

muss die entsprechende ISRRoutine eingetragen werden, sprich die 
Adresse. Ich habs bereits mit einem Pointer auf die Funktion extISR 
versucht, aber da mekert Keil nur!

Mit den oben angeführten Macros (die kommen von der Keil Homepage) kann 
ich zwar ohne Fehler compilieren, aber das Ding tut nichts ...

von Rogger R. (manta)


Lesenswert?

So ich denk ich habs selbst gelöst:

Die Macros von Keil.com sind richitg (warum auch nicht?:)
Das Problem an der Verwendung war folgendes:

Wenn man Fast External Interrupts verwenden will, dann müssen die LVL 
und GVL der Interrupts sowohl in den normalen Interrupt Registern, als 
auch bei den Fast Interrupts zusammenstimmen:
1
  
2
  FINT0CSP   = SEG(extISR) | 0x8C00;
3
  FINT0ADDR  = SOF(extISR);
4
  
5
  //
6
  ...
7
  //
8
  
9
  //Interrupt Controlregister
10
  CC1_CC8IC = 0x007C; --> Fehler lag hier...LVL und GVL muss gleich sein wie oben!

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.