Forum: Compiler & IDEs AT91SAM7S + PLL


von B. L. (blan)


Lesenswert?

hallo,

ich versuche wie blöd das PLL von meinem AT91SAM7S256 zu konfigurieren 
aber bekomm es einfach nicht hin. Ich hab mir ein Beispiel Code für das 
PLL für den AT91SAM7S64 geholt aber das funktioniert einfach nicht.

Hier der gesamte Code:
1
#include "AT91SAM7.h"
2
3
AT91PS_PIO    pPio   = AT91C_BASE_PIOA;
4
AT91PS_PMC    pPMC   = AT91C_BASE_PMC;
5
AT91PS_USART  pUSART = AT91C_BASE_US0;
6
AT91PS_PDC    pPDC   = AT91C_BASE_PDC_US0;
7
AT91PS_MC     pMC    = AT91C_BASE_MC;
8
AT91PS_AIC    pAic   = AT91C_BASE_AIC;
9
10
#define nop()  __asm__ __volatile__("nop")
11
#define LED_A      (1U<<18)   /* PA0, pin 48 */
12
#define LED_B      (1U<<17)   /* PA1, pin 47 */
13
14
void InitFrec(void)
15
{
16
  //Watchdog Disable
17
  AT91C_BASE_WDTC->WDTC_WDMR= AT91C_WDTC_WDDIS;
18
19
  //Enabling the Main Oscillator:
20
  //SCK = 1/32768 = 30.51 uSecond
21
  //Start up time = 8 * 6 / SCK = 56 * 30.51 = 1,46484375 ms
22
  pPMC->PMC_MOR = (( AT91C_CKGR_OSCOUNT & (0x06 <<8) | AT91C_CKGR_MOSCEN ));
23
24
  //Wait the startup time
25
  while(!(pPMC->PMC_SR & AT91C_PMC_MOSCS));
26
27
  //Setting PLL and divider:
28
  //- div by 5 Fin = 3,6864 =(18,432 / 5)
29
  //- Mul 25+1: Fout =  95,8464 =(3,6864 *26)
30
  //for 96 MHz the erroe is 0.16%
31
  //Field out NOT USED = 0
32
  //PLLCOUNT pll startup time estimate at : 0.844 ms
33
  //PLLCOUNT 28 = 0.000844 /(1/32768)
34
35
  pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 3) | (AT91C_CKGR_PLLCOUNT & (28<<8)) | (AT91C_CKGR_MUL & (24<<16)));
36
37
  // Wait the startup time
38
  while(!(pPMC->PMC_SR & AT91C_PMC_LOCK));
39
  while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));
40
41
  //Selection of Master Clock and Processor Clock
42
  //select the PLL clock divided by 2
43
  pPMC->PMC_MCKR = AT91C_PMC_CSS_PLL_CLK | AT91C_PMC_PRES_CLK_2 ;
44
45
  while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));
46
}
47
48
int main(void)
49
{
50
  InitFrec();
51
  
52
  pPio->PIO_PER = LED_A | LED_B;
53
  // Enable outputs for LED pins. 
54
  pPio->PIO_OER = LED_A | LED_B;
55
  // Set outputs HIGH to turn LEDs off. 
56
  pPio->PIO_SODR = LED_A | LED_B;
57
  
58
  pPio->PIO_CODR = LED_A;
59
  pPio->PIO_CODR = LED_B;
60
  
61
  while( 1 );
62
  
63
  return(0);
64
}

sobald ich die Quelle auf Slow Clock oder Main Clock schalte 
funktioniert es. Findet jemand einen Fehler?

Danke!

von B. L. (blan)


Lesenswert?

weiss wirklich niemand wo der fehler liegt? brauch die schaltung 
wirklich dringend. :(

mfg blan

von Martin Thomas (Gast)


Lesenswert?

Eventuell greifen die Warteschleifen nicht, da die eigenen Hilfspointer 
auf Stukturen nicht "volatile" sind. Disassembly angeschaut? Werden die 
Warteschleifen wegoptimiert?
Ein leicht modifizierter Code von Atmel, der ohne "Hilfpointer" 
auskommt, hatte beim letzten Test mit SAM7S256 funktioniert (AIC Init 
auskommentiert, board.h ersetzt).
1
//-----------------------------------------------------------------------------
2
//         ATMEL Microcontroller Software Support  -  ROUSSET  -
3
//-----------------------------------------------------------------------------
4
// DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
5
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
6
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
7
// DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
8
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
10
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
11
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
12
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
13
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
//-----------------------------------------------------------------------------
15
// File Name           : Cstartup_SAM7.c
16
// Object              : Low level initialisations written in C for Tools
17
//                       For AT91SAM7S with 2 flash plane
18
// Creation            : JPP  09-May-2006
19
//-----------------------------------------------------------------------------
20
21
// slightly modified by Martin Thomas:
22
// - Disable Watchdog first
23
// - project.h -> board.h
24
// - modified parentheses for AT91C_BASE_PMC->PMC_MOR to avoid compiler warning
25
26
///// board.h ersetzt
27
// #include "board.h"
28
#define __inline static inline
29
#include "AT91SAM7S256.h"
30
#include "lib_AT91SAM7S256.h"
31
32
///// AIC init auskommentiert fuer Beispiel
33
#if 0
34
//  The following functions must be write in ARM mode this function called
35
// directly by exception vector
36
extern void AT91F_Spurious_handler(void);
37
extern void AT91F_Default_IRQ_handler(void);
38
extern void AT91F_Default_FIQ_handler(void);
39
#endif
40
41
//*----------------------------------------------------------------------------
42
//* \fn    AT91F_LowLevelInit
43
//* \brief This function performs very low level HW initialization
44
//*        this function can use a Stack, depending the compilation
45
//*        optimization mode
46
//*----------------------------------------------------------------------------
47
void AT91F_LowLevelInit(void)
48
{
49
    unsigned char i;
50
51
    ///////////////////////////////////////////////////////////////////////////
52
    //  Disable Watchdog (write once register)
53
    ///////////////////////////////////////////////////////////////////////////
54
    AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
55
56
    ///////////////////////////////////////////////////////////////////////////
57
    // EFC Init
58
    ///////////////////////////////////////////////////////////////////////////
59
    AT91C_BASE_MC->MC_FMR = AT91C_MC_FWS_1FWS ;
60
61
    ///////////////////////////////////////////////////////////////////////////
62
    // Init PMC Step 1. Enable Main Oscillator
63
    // Main Oscillator startup time is board specific:
64
    // Main Oscillator Startup Time worst case (3MHz) corresponds to 15ms
65
    // (0x40 for AT91C_CKGR_OSCOUNT field)
66
    ///////////////////////////////////////////////////////////////////////////
67
    AT91C_BASE_PMC->PMC_MOR = ( AT91C_CKGR_OSCOUNT & (0x40 <<8)) | AT91C_CKGR_MOSCEN;
68
    // Wait Main Oscillator stabilization
69
    while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS));
70
71
    ///////////////////////////////////////////////////////////////////////////
72
    // Init PMC Step 2.
73
    // Set PLL to 96MHz (96,109MHz) and UDP Clock to 48MHz
74
    // PLL Startup time depends on PLL RC filter: worst case is choosen
75
    // UDP Clock (48,058MHz) is compliant with the Universal Serial Bus
76
    // Specification (+/- 0.25% for full speed)
77
    ///////////////////////////////////////////////////////////////////////////
78
    AT91C_BASE_PMC->PMC_PLLR = AT91C_CKGR_USBDIV_1           |
79
                               (16 << 8)                     |
80
                               (AT91C_CKGR_MUL & (72 << 16)) |
81
                               (AT91C_CKGR_DIV & 14);
82
    // Wait for PLL stabilization
83
    while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK) );
84
    // Wait until the master clock is established for the case we already
85
    // turn on the PLL
86
    while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) );
87
88
    ///////////////////////////////////////////////////////////////////////////
89
    // Init PMC Step 3.
90
    // Selection of Master Clock MCK equal to (Processor Clock PCK) PLL/2=48MHz
91
    // The PMC_MCKR register must not be programmed in a single write operation
92
    // (see. Product Errata Sheet)
93
    ///////////////////////////////////////////////////////////////////////////
94
    AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
95
    // Wait until the master clock is established
96
    while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) );
97
98
    AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;
99
    // Wait until the master clock is established
100
    while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) );
101
102
103
#if 0
104
    ///////////////////////////////////////////////////////////////////////////
105
    //  Init AIC: assign corresponding handler for each interrupt source
106
    ///////////////////////////////////////////////////////////////////////////
107
    AT91C_BASE_AIC->AIC_SVR[0] = (int) AT91F_Default_FIQ_handler ;
108
    for (i = 1; i < 31; i++) {
109
        AT91C_BASE_AIC->AIC_SVR[i] = (int) AT91F_Default_IRQ_handler ;
110
    }
111
    AT91C_BASE_AIC->AIC_SPU = (unsigned int) AT91F_Spurious_handler;
112
#endif
113
}

>brauch die schaltung wirklich dringend. :(
Ja, es eilt immer...

von B. L. (blan)


Lesenswert?

seeehr vielen dank - es funktioniert!

kleine frage am rande:
wenn ich ein register mit einem wert lade kann ich diesen wert bei den 
AT91SAM7SXXX nie wieder "sicher" aus diesem register rausholen oder? 
dazu benötige ich dann immer diese Status-Register?

das würde nähmlich das beschreiben von registern wie zB "pPMC_PCER = 
..." statt "pPMC_PCER |= ..." erklären.

blan

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Kann man nicht allgemein sagen. Gibt viele Bits in der Hardware, die in 
jeweils eigenen Registern gesetzt, gelöscht und abgefragt werden werden. 
Sieht aufwendig aus, ist aber eine ziemlich sichere Sache betr. 
Interrupt/Thread-"Festigkeit" (v.a. bei AIC, 
Interrupt-Einstellung/Status von internen Funktionen und GPIO). Es gibt 
aber auch Bits, die in einem einzigen Hardwaregister verwaltet werden, 
in dem man dann per "Bitmanipulation" löscht, setzt und abfragt. Das 
Datenblatt/User-Manual sollte darüber ausreichend Information liefern.

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.