⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clock_switching.c

📁 ATMEL AT91RM9200开发板配套光盘上的全部示例程序
💻 C
字号:
//*----------------------------------------------------------------------------
//*      ATMEL Microcontroller Software Support  -  ROUSSET  -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name           : clock_switching.c
//* Object              : Driver to switch the clock source in the AT91M55800A
//*
//* 1.0 08/01/01 S.C    : Creation
//* 1.1 05/mar/03/JPP   : Port for new include
//* Note : The switching times are specified in he software.
//*----------------------------------------------------------------------------


/*------------------ Files to be included Definition ------------------------*/

#include "eb55.h"
#include "clock_switching.h"

/*----- Assembler Handler files for SLCKIRQ and APMC interrupt source ----------*/

extern void osc32k_asm_handler (void) 		; //* .asm handler
extern void osc32k_osc16m_asm_handler (void)	; //* .asm handler
extern void osc32k_pll_asm_handler (void)	; //* .asm handler

/*---------------------------- Global Variable ------------------------------*/
char switching_conducted = 0 ; //* Allows to know when the switching is achieved

//*-----------------------------------------------------------------------------
//* --------------------------- Interrupt Function  ----------------------------
//*-----------------------------------------------------------------------------

//*----------------------------------------------------------------------------
//* Function Name       : osc32k_c_handler
//* Object              : C Handler to switch to 32kHz oscillator and stop other
//*                     : sources
//* Input Parameters    : none
//* Output Parameters   : none
//*----------------------------------------------------------------------------
void osc32k_c_handler (void)
{
        AT91PS_APMC pAPMC = AT91C_BASE_APMC;

        //* Shutdown the PLL by default
        pAPMC->APMC_CGMR = (pAPMC->APMC_CGMR & (~MAX_MUL) ) ;

        //* Shutdown the Main Oscillator by default
        pAPMC->APMC_CGMR = (pAPMC->APMC_CGMR & (~APMC_MOSC_EN)) ;

	AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_SLCK); 

        switching_conducted = TRUE ;
}
//*----------------------------------------------------------------------------
//* Function Name       : osc32k_osc16m_c_handler
//* Object              : C Handler to switch to 32k oscillator before to switch
//*						: to 16 MHz and shutdown the PLL.
//* Input Parameters    : none
//* Output Parameters   : none
//*----------------------------------------------------------------------------
void osc32k_osc16m_c_handler (void)
{
    unsigned int apmc_cgmr_status ;
    AT91PS_APMC pAPMC = AT91C_BASE_APMC;

        //* Shutdown the PLL by default
        pAPMC->APMC_CGMR = (pAPMC->APMC_CGMR & (~MAX_MUL) ) ;

        //* APMC_CGMR reading
        apmc_cgmr_status = pAPMC->APMC_CGMR ;

        //* Switching to the HF output oscillator
        pAPMC->APMC_CGMR = ( apmc_cgmr_status | APMC_CSS_MOSC) ;

	AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_SLCK); 

	switching_conducted = TRUE ;
}
//*----------------------------------------------------------------------------
//* Function Name       : osc32k_pll_c_handler
//* Object              : C Handler to switch to 32k oscillator before to switch
//*						: to PLL output.
//* Input Parameters    : none
//* Output Parameters   : none
//*----------------------------------------------------------------------------
void osc32k_pll_c_handler (void)
{
    AT91PS_APMC pAPMC = AT91C_BASE_APMC;
	pAPMC->APMC_CGMR =( pAPMC->APMC_CGMR | APMC_CSS_PLL ) ;

	AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_SLCK); 
	
	switching_conducted = TRUE ;
}

//*-----------------------------------------------------------------------------
//* ---------------------------- External Function  ----------------------------
//*-----------------------------------------------------------------------------

//*----------------------------------------------------------------------------
//* Function Name       : set_Prescaler
//* Object              : Set the Prescaler with Erata
//* Input Parameters    : none
//* Output Parameters   : none
//*----------------------------------------------------------------------------
void set_Prescaler (unsigned int Prescaler)
{
	unsigned int i;
	
    AT91PS_APMC pAPMC = AT91C_BASE_APMC;
    
    
    pAPMC->APMC_CGMR =( pAPMC->APMC_CGMR & (~MASK_PRESCALER) ) | (0X01 << SHIFT_PRESCALER);
    for( i=0; i<64 ;i++){}
    pAPMC->APMC_CGMR =( pAPMC->APMC_CGMR & (~MASK_PRESCALER) )| (Prescaler << SHIFT_PRESCALER) ;
    
}
//*----------------------------------------------------------------------------
//* Function Name       : mck_clock_speed
//* Object              : Driver to choice the clock source and the PLL
//*                       frequency output
//* Input Parameters    :<target_source> clock source
//*                 'source' = 0 : low frequency oscillator output => MCK
//*                 'source' = 1 : main oscillator output => MCK
//*                 'source' = 2 : PLL output =MCK
//*                      <frequency_multiplier> allows to multiply the main
//*                       oscillator frequency ( field B_MUL +1).
//* Output Parameters   : None
//*----------------------------------------------------------------------------
void mck_clock_speed (short target_source, char frequency_multiplier)
{
    unsigned int apmc_cgmr_status ;
    unsigned int switch_choice ;
    AT91PS_APMC pAPMC = AT91C_BASE_APMC;

    	switching_conducted = FALSE ;

	frequency_multiplier = frequency_multiplier - 1 ;

	apmc_cgmr_status = pAPMC->APMC_CGMR ;  //* APMC_CGMR reading NEW

        switch_choice = apmc_cgmr_status & CSS_MASK ;

        switch (switch_choice)
        {
            case APMC_CSS_LF: //* The actual source clock is the LF osc.

                switch (target_source)
                {
                    case TO_LF_OSCILLATOR :								//* It's the actual clock source
                    break ;

                    case TO_HF_OSCILLATOR : //* To the HF osc.(Switching Time = 15.5 ms)

                        apmc_cgmr_status |= APMC_MOSC_EN ;

                        //* Main oscillator start-up
                         pAPMC->APMC_CGMR =( apmc_cgmr_status ) ;
                        
                        /* It's no good to enable interrupt because the handling by interrupt, approximately , cost
                        the same time (32kHz clock) that the oscillator startup */
                        while ((pAPMC->APMC_SR & APMC_MOSCS) == 0) {} ;

                        //* Switching to the HF output oscillator
                        pAPMC->APMC_CGMR = ( apmc_cgmr_status | APMC_CSS_MOSC ) ;

                        break ;

                    case TO_PLL_OUTPUT :								//* To the PLL output ((Switching Time = 18 ms
                        apmc_cgmr_status |= APMC_MOSC_EN ;

                        //* First part : Main oscillator start-up
                        pAPMC->APMC_CGMR =  ( apmc_cgmr_status ) ;

                        while ((pAPMC->APMC_SR & APMC_MOSCS) ==0 ) {} ;

                        //* Second part : PLL starting
			apmc_cgmr_status |= (frequency_multiplier <<B_MUL) ;

                        pAPMC->APMC_CGMR =  ( apmc_cgmr_status ) ;

                        while ((pAPMC->APMC_SR & APMC_PLL_LOCK) ==0 ) {} ;

                        pAPMC->APMC_CGMR =  ( apmc_cgmr_status | APMC_CSS_PLL ) ;
                        break ;
                }
            break ;
            case APMC_CSS_MOSC: //* The actual source clock is the HF osc.
                switch (target_source)
                {
                    case TO_LF_OSCILLATOR : //* To the LF osc.(Switching Time = 14 ms)

                        //* Switching from interrupt event (SLCKIRQ)
			//* open Usart 0 interrupt
			AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_SLCK, MCK_INTERRUPT_LEVEL,AIC_SRCTYPE_EXT_LOW_LEVEL, osc32k_asm_handler); 
			AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_SLCK); 

                        apmc_cgmr_status &= ~CSS_MASK ;

                        //* Switching to the HF output oscillator
                        pAPMC->APMC_CGMR =  ( apmc_cgmr_status ) ;

                        while (switching_conducted != TRUE ) {} ;

                        break ;

                    case TO_HF_OSCILLATOR :								//* It's the actual clock source
                        break ;

                    case TO_PLL_OUTPUT ://* To the PLL output(Switching Time = 5.8 ms with
                        /* First: PLL start-up */
                        apmc_cgmr_status |= (frequency_multiplier << B_MUL) ;

			pAPMC->APMC_CGMR =  ( apmc_cgmr_status ) ;

			while ((pAPMC->APMC_SR & APMC_PLL_LOCK) ==0 ) {} ;

			/* Second: switching to 32 kHz */
			apmc_cgmr_status &= ~CSS_MASK ;
			/* Switching to the LF output oscillator */
			pAPMC->APMC_CGMR = ( apmc_cgmr_status ) ;
  

			AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_SLCK, MCK_INTERRUPT_LEVEL,AIC_SRCTYPE_EXT_LOW_LEVEL, osc32k_pll_asm_handler); 
			AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_SLCK); 

                        while (switching_conducted != TRUE ) {} ;

                        break ;
                }
            break ;
            case APMC_CSS_PLL://* The actual source clock is the internal PLL
                switch (target_source)
                {
                    case TO_LF_OSCILLATOR :                               //* To the LF osc.(Switching Time = 14 ms)
                        /* Switching when the dedicated interrupt occures */
			AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_SLCK, MCK_INTERRUPT_LEVEL,AIC_SRCTYPE_EXT_LOW_LEVEL, osc32k_asm_handler); 
			AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_SLCK); 

                        apmc_cgmr_status &= ~CSS_MASK ;

                        /* Switching to the LF output oscillator */
                        pAPMC->APMC_CGMR =  ( apmc_cgmr_status ) ;

                        while (switching_conducted != TRUE ) {} ;

                        break ;

                    case TO_HF_OSCILLATOR :                              //* To the HF osc.(Switching Time = 7 ms)
                     	//* Switching from interrupt event (32k_mode)
			AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_SLCK, MCK_INTERRUPT_LEVEL,AIC_SRCTYPE_EXT_LOW_LEVEL, osc32k_osc16m_asm_handler); 
			AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_SLCK); 

                        apmc_cgmr_status &= ~CSS_MASK ;

                        //* Switching to the LF output oscillator
                        pAPMC->APMC_CGMR =  ( apmc_cgmr_status ) ;

                        while (switching_conducted != TRUE ) {} ;

                        break ;

                    case TO_PLL_OUTPUT :  //* It's the actual clock source
                        //* Second part : PLL starting
			apmc_cgmr_status = (apmc_cgmr_status & (~MAX_MUL))|(frequency_multiplier <<B_MUL) ;
                        pAPMC->APMC_CGMR =  ( apmc_cgmr_status ) ;
                        break ;
                }
        }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -