Forum: Mikrocontroller und Digitale Elektronik CC430 - Core-Spannung erhöhen funktioniert nicht


von Rangi J. (rangi)


Lesenswert?

Hallo Forum,
mal wieder ein Frage zum MSP (CC430). Der Core kann mit 4 verschiedenen 
Spannungen berieben werden, 1.4V, 1.6V, 1,8V und 1.9V. In abhängigkeit 
der Core-Frequenz benötige ich Level 2 (1,8V) oder Level 3 (1.9V). Nach 
Datenblatt müssen die Level schrittweise durchgegangen werden und die 
neue CPU-Frequenz erst am Ende gesetzt werden.
Soweit so gut, wäre da nicht ein Errata-Sheet SLAZ052J von TI in dem es 
heisst "If the SVM low side is enabled, a change in the VCORE voltage 
level (an increase in the VCORE level) may cause the currently executed 
read operation from flash to be incorrect and may lead to unexpected 
code execution or incorrect data."
Es gibt dazu auch einen Beispiel-Code. Jedoch funktioniert das bei mir 
nicht so richtig.
Fehlerbeschreibung: selten, im Debugger läuft das Programm nicht los, 
drücke ich dann Pause steht der Programmzeiger irgendwo in der Botanik. 
Ein einfaches Reset durch den Debugger behebt das Problem.
Immer, wenn ich einen POR-Reset auslöse mit
1
 PMMCTL0 = PMMPW | PMMSWPOR;  /*software power on reset*/
 schmiert der Debugger kompett ab und der Controller kommt nicht wieder. 
Nur Power Off/On hilft dann.
Wenn ich die Core-Spannung nicht erhöhe funktioniert alles bestens. 
Darum bin ich der Meinung, es kann nur am SetVCore liegen.
Was mache ich falsch?

Hier noch der BeispielCode den ich verwende:
1
//****************************************************************************//
2
// Set VCore
3
//****************************************************************************//
4
unsigned int SetVCore (unsigned char level)
5
{
6
  unsigned int actlevel;
7
  unsigned int status = 0;
8
  level &= PMMCOREV_3;                       // Set Mask for Max. level
9
  actlevel = (PMMCTL0 & PMMCOREV_3);         // Get actual VCore
10
  while (((level != actlevel) && (status == 0)) || (level < actlevel))    // step by step increase or decrease
11
  {
12
    if (level > actlevel)
13
      status = SetVCoreUp(++actlevel);
14
    else
15
      status = SetVCoreDown(--actlevel);
16
  }
17
  return status;
18
}
19
20
//****************************************************************************//
21
// Set VCore Up
22
//****************************************************************************//
23
unsigned int SetVCoreUp (unsigned char level)
24
{
25
  unsigned int PMMRIE_backup,SVSMHCTL_backup;
26
  // Open PMM registers for write access
27
  PMMCTL0_H = 0xA5;
28
  // Disable dedicated Interrupts to prevent that needed flags will be cleared
29
  PMMRIE_backup = PMMRIE;
30
  PMMRIE &= ~(SVSMHDLYIE | SVSMLDLYIE | SVMLVLRIE | SVMHVLRIE | SVMHVLRPE);
31
  // Set SVM highside to new level and check if a VCore increase is possible
32
  SVSMHCTL_backup = SVSMHCTL;
33
  PMMIFG &= ~(SVMHIFG | SVSMHDLYIFG);
34
  SVSMHCTL = SVMHE | SVMHFP | (SVSMHRRL0 * level);
35
  // Wait until SVM highside is settled
36
  while ((PMMIFG & SVSMHDLYIFG) == 0);
37
  // Disable full-performance mode to save energy
38
  SVSMHCTL &= ~_HAL_PMM_SVSFP ;
39
  // Check if a VCore increase is possible
40
  if ((PMMIFG & SVMHIFG) == SVMHIFG){      //-> Vcc is to low for a Vcore increase
41
    // recover the previous settings
42
    PMMIFG &= ~SVSMHDLYIFG;
43
    SVSMHCTL = SVSMHCTL_backup;
44
    // Wait until SVM highside is settled
45
    while ((PMMIFG & SVSMHDLYIFG) == 0);
46
    // Clear all Flags
47
    PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);
48
    // backup PMM-Interrupt-Register
49
    PMMRIE = PMMRIE_backup;
50
    // Lock PMM registers for write access
51
    PMMCTL0_H = 0x00;
52
    return PMM_STATUS_ERROR;                       // return: voltage not set
53
  }
54
  // Set also SVS highside to new level      //-> Vcc is high enough for a Vcore increase
55
  SVSMHCTL |= SVSHE | (SVSHRVL0 * level);
56
  // Set SVM low side to new level
57
  SVSMLCTL = SVMLE | SVMLFP | (SVSMLRRL0 * level);
58
  // Wait until SVM low side is settled
59
  while ((PMMIFG & SVSMLDLYIFG) == 0);
60
  // Clear already set flags
61
  PMMIFG &= ~(SVMLVLRIFG | SVMLIFG);
62
  // Set VCore to new level
63
  PMMCTL0_L = PMMCOREV0 * level;
64
  // Wait until new level reached
65
  if (PMMIFG & SVMLIFG)
66
  while ((PMMIFG & SVMLVLRIFG) == 0);
67
  // Set also SVS/SVM low side to new level
68
  PMMIFG &= ~SVSMLDLYIFG;
69
  SVSMLCTL |= SVSLE | (SVSLRVL0 * level);
70
  // wait for lowside delay flags
71
  while ((PMMIFG & SVSMLDLYIFG) == 0);
72
// Disable SVS/SVM Low
73
// Disable full-performance mode to save energy
74
  SVSMLCTL &= ~(_HAL_PMM_DISABLE_SVSL_+_HAL_PMM_DISABLE_SVML_+_HAL_PMM_SVSFP );
75
  // Clear all Flags
76
  PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);
77
  // backup PMM-Interrupt-Register
78
  PMMRIE = PMMRIE_backup;
79
  // Lock PMM registers for write access
80
  PMMCTL0_H = 0x00;
81
  return PMM_STATUS_OK;                               // return: OK
82
}
83
84
//****************************************************************************//
85
// Set VCore down (Independent from the enabled Interrupts in PMMRIE)
86
//****************************************************************************//
87
unsigned int SetVCoreDown (unsigned char level)
88
{
89
  unsigned int PMMRIE_backup;
90
  // Open PMM registers for write access
91
  PMMCTL0_H = 0xA5;
92
  // Disable dedicated Interrupts to prevent that needed flags will be cleared
93
  PMMRIE_backup = PMMRIE;
94
  PMMRIE &= ~(SVSMHDLYIE | SVSMLDLYIE | SVMLVLRIE | SVMHVLRIE | SVMHVLRPE);
95
  // Set SVM high side and SVM low side to new level
96
  PMMIFG &= ~(SVMHIFG | SVSMHDLYIFG | SVMLIFG | SVSMLDLYIFG);
97
  SVSMHCTL = SVMHE | SVMHFP | (SVSMHRRL0 * level);
98
  SVSMLCTL = SVMLE | SVMLFP | (SVSMLRRL0 * level);
99
  // Wait until SVM high side and SVM low side is settled
100
  while ((PMMIFG & SVSMHDLYIFG) == 0 || (PMMIFG & SVSMLDLYIFG) == 0);
101
  // Set VCore to new level
102
  PMMCTL0_L = PMMCOREV0 * level;
103
  // Set also SVS highside and SVS low side to new level
104
  PMMIFG &= ~(SVSHIFG | SVSMHDLYIFG | SVSLIFG | SVSMLDLYIFG);
105
  SVSMHCTL |= SVSHE | SVSHFP | (SVSHRVL0 * level);
106
  SVSMLCTL |= SVSLE | SVSLFP | (SVSLRVL0 * level);
107
  // Wait until SVS high side and SVS low side is settled
108
  while ((PMMIFG & SVSMHDLYIFG) == 0 || (PMMIFG & SVSMLDLYIFG) == 0);
109
  // Disable full-performance mode to save energy
110
  SVSMHCTL &= ~_HAL_PMM_SVSFP;
111
// Disable SVS/SVM Low
112
// Disable full-performance mode to save energy
113
  SVSMLCTL &= ~(_HAL_PMM_DISABLE_SVSL_+_HAL_PMM_DISABLE_SVML_+_HAL_PMM_SVSFP );
114
  // Clear all Flags
115
  PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);
116
  // backup PMM-Interrupt-Register
117
  PMMRIE = PMMRIE_backup;
118
  // Lock PMM registers for write access
119
  PMMCTL0_H = 0x00;
120
  if ((PMMIFG & SVMHIFG) == SVMHIFG)
121
    return PMM_STATUS_ERROR;             // Highside is still to low for the adjusted VCore Level
122
  else return PMM_STATUS_OK;            // Return: OK
123
}

von Rangi J. (rangi)


Lesenswert?

niemand ein idee?

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.