mikrocontroller.net

Forum: Compiler & IDEs AT91SAM7S + PLL


Autor: B. Lan (blan)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include "AT91SAM7.h"

AT91PS_PIO    pPio   = AT91C_BASE_PIOA;
AT91PS_PMC    pPMC   = AT91C_BASE_PMC;
AT91PS_USART  pUSART = AT91C_BASE_US0;
AT91PS_PDC    pPDC   = AT91C_BASE_PDC_US0;
AT91PS_MC     pMC    = AT91C_BASE_MC;
AT91PS_AIC    pAic   = AT91C_BASE_AIC;

#define nop()  __asm__ __volatile__("nop")
#define LED_A      (1U<<18)   /* PA0, pin 48 */
#define LED_B      (1U<<17)   /* PA1, pin 47 */

void InitFrec(void)
{
  //Watchdog Disable
  AT91C_BASE_WDTC->WDTC_WDMR= AT91C_WDTC_WDDIS;

  //Enabling the Main Oscillator:
  //SCK = 1/32768 = 30.51 uSecond
  //Start up time = 8 * 6 / SCK = 56 * 30.51 = 1,46484375 ms
  pPMC->PMC_MOR = (( AT91C_CKGR_OSCOUNT & (0x06 <<8) | AT91C_CKGR_MOSCEN ));

  //Wait the startup time
  while(!(pPMC->PMC_SR & AT91C_PMC_MOSCS));

  //Setting PLL and divider:
  //- div by 5 Fin = 3,6864 =(18,432 / 5)
  //- Mul 25+1: Fout =  95,8464 =(3,6864 *26)
  //for 96 MHz the erroe is 0.16%
  //Field out NOT USED = 0
  //PLLCOUNT pll startup time estimate at : 0.844 ms
  //PLLCOUNT 28 = 0.000844 /(1/32768)

  pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 3) | (AT91C_CKGR_PLLCOUNT & (28<<8)) | (AT91C_CKGR_MUL & (24<<16)));

  // Wait the startup time
  while(!(pPMC->PMC_SR & AT91C_PMC_LOCK));
  while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));

  //Selection of Master Clock and Processor Clock
  //select the PLL clock divided by 2
  pPMC->PMC_MCKR = AT91C_PMC_CSS_PLL_CLK | AT91C_PMC_PRES_CLK_2 ;

  while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));
}

int main(void)
{
  InitFrec();
  
  pPio->PIO_PER = LED_A | LED_B;
  // Enable outputs for LED pins. 
  pPio->PIO_OER = LED_A | LED_B;
  // Set outputs HIGH to turn LEDs off. 
  pPio->PIO_SODR = LED_A | LED_B;
  
  pPio->PIO_CODR = LED_A;
  pPio->PIO_CODR = LED_B;
  
  while( 1 );
  
  return(0);
}

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

Danke!

Autor: B. Lan (blan)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weiss wirklich niemand wo der fehler liegt? brauch die schaltung 
wirklich dringend. :(

mfg blan

Autor: Martin Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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).
//-----------------------------------------------------------------------------
//         ATMEL Microcontroller Software Support  -  ROUSSET  -
//-----------------------------------------------------------------------------
// DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
// DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------
// File Name           : Cstartup_SAM7.c
// Object              : Low level initialisations written in C for Tools
//                       For AT91SAM7S with 2 flash plane
// Creation            : JPP  09-May-2006
//-----------------------------------------------------------------------------

// slightly modified by Martin Thomas:
// - Disable Watchdog first
// - project.h -> board.h
// - modified parentheses for AT91C_BASE_PMC->PMC_MOR to avoid compiler warning

///// board.h ersetzt
// #include "board.h"
#define __inline static inline
#include "AT91SAM7S256.h"
#include "lib_AT91SAM7S256.h"

///// AIC init auskommentiert fuer Beispiel
#if 0
//  The following functions must be write in ARM mode this function called
// directly by exception vector
extern void AT91F_Spurious_handler(void);
extern void AT91F_Default_IRQ_handler(void);
extern void AT91F_Default_FIQ_handler(void);
#endif

//*----------------------------------------------------------------------------
//* \fn    AT91F_LowLevelInit
//* \brief This function performs very low level HW initialization
//*        this function can use a Stack, depending the compilation
//*        optimization mode
//*----------------------------------------------------------------------------
void AT91F_LowLevelInit(void)
{
    unsigned char i;

    ///////////////////////////////////////////////////////////////////////////
    //  Disable Watchdog (write once register)
    ///////////////////////////////////////////////////////////////////////////
    AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;

    ///////////////////////////////////////////////////////////////////////////
    // EFC Init
    ///////////////////////////////////////////////////////////////////////////
    AT91C_BASE_MC->MC_FMR = AT91C_MC_FWS_1FWS ;

    ///////////////////////////////////////////////////////////////////////////
    // Init PMC Step 1. Enable Main Oscillator
    // Main Oscillator startup time is board specific:
    // Main Oscillator Startup Time worst case (3MHz) corresponds to 15ms
    // (0x40 for AT91C_CKGR_OSCOUNT field)
    ///////////////////////////////////////////////////////////////////////////
    AT91C_BASE_PMC->PMC_MOR = ( AT91C_CKGR_OSCOUNT & (0x40 <<8)) | AT91C_CKGR_MOSCEN;
    // Wait Main Oscillator stabilization
    while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS));

    ///////////////////////////////////////////////////////////////////////////
    // Init PMC Step 2.
    // Set PLL to 96MHz (96,109MHz) and UDP Clock to 48MHz
    // PLL Startup time depends on PLL RC filter: worst case is choosen
    // UDP Clock (48,058MHz) is compliant with the Universal Serial Bus
    // Specification (+/- 0.25% for full speed)
    ///////////////////////////////////////////////////////////////////////////
    AT91C_BASE_PMC->PMC_PLLR = AT91C_CKGR_USBDIV_1           |
                               (16 << 8)                     |
                               (AT91C_CKGR_MUL & (72 << 16)) |
                               (AT91C_CKGR_DIV & 14);
    // Wait for PLL stabilization
    while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK) );
    // Wait until the master clock is established for the case we already
    // turn on the PLL
    while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) );

    ///////////////////////////////////////////////////////////////////////////
    // Init PMC Step 3.
    // Selection of Master Clock MCK equal to (Processor Clock PCK) PLL/2=48MHz
    // The PMC_MCKR register must not be programmed in a single write operation
    // (see. Product Errata Sheet)
    ///////////////////////////////////////////////////////////////////////////
    AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
    // Wait until the master clock is established
    while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) );

    AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;
    // Wait until the master clock is established
    while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) );


#if 0
    ///////////////////////////////////////////////////////////////////////////
    //  Init AIC: assign corresponding handler for each interrupt source
    ///////////////////////////////////////////////////////////////////////////
    AT91C_BASE_AIC->AIC_SVR[0] = (int) AT91F_Default_FIQ_handler ;
    for (i = 1; i < 31; i++) {
        AT91C_BASE_AIC->AIC_SVR[i] = (int) AT91F_Default_IRQ_handler ;
    }
    AT91C_BASE_AIC->AIC_SPU = (unsigned int) AT91F_Spurious_handler;
#endif
}

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

Autor: B. Lan (blan)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Martin Thomas (mthomas) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.