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

📄 bsp.c

📁 uCOS-II 2.8和uC-TCP/IP在ATMEL AT91SAM9261上移植
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
*********************************************************************************************************
*                                            Atmel AT91SAM9261
*                                         Board Support Package
*
*                              (c) Copyright 2004, Micrium, Inc., Weston, FL
*                                          All Rights Reserved
*
*
* File : BSP.C
* By   : Eric Shufro
*********************************************************************************************************
*/

#include  <includes.h>

/*
*********************************************************************************************************
*                                              CONSTANTS
*********************************************************************************************************
*/

#define  SLOW_CLK_FRQ                                         32768UL       /* Slow oscillator clock frequency in Hz                    */
#define  MAIN_CLK_FRQ                                      18432000UL       /* Main oscillator clock frequency (crystal frequency) Hz   */

#define  BSP_RAM_REMAP_TEST_BYTE        (*(CPU_INT08U  *)0x00000030UL)

/*
*********************************************************************************************************
*                                               DATA TYPES
*********************************************************************************************************
*/

typedef  void  (*BSP_FNCT_PTR)(void);

/*
*********************************************************************************************************
*                                              PROTOTYPES
*********************************************************************************************************
*/

static  void    BSP_DummyISR_Handler(void);
static  void    BSP_IntCtrlInit(void);
static  void    PLL_Init(void);

#if  BSP_EXT_MEM_INIT
static  void    ExtMemory_Init(void);
#endif

static  void    Tmr_TickInit(void);
static  void    Tmr_TickISR_Handler(void);
        void    Sys_Int_Handler(void);


/*
*********************************************************************************************************
*                                           DUMMY IRQ HANDLER
*
* Description : This function is called to handle invalid IRQs
*
* Arguments   : none
*********************************************************************************************************
*/

static  void  BSP_DummyISR_Handler (void)
{
    CPU_INT32U  irq_id;
    
    
    irq_id = AT91C_BASE_AIC->AIC_ISR & 0x1F;                                /* Retrieve the ID of the interrupting source               */
    AT91C_BASE_AIC->AIC_ICCR  =  (1 << irq_id);                             /* Clear the current interrupt                              */
}


/*
*********************************************************************************************************
*                                          BSP INITIALIZATION
*
* Description : This function should be called by your application code before you make use of any of the
*               functions found in this module.
*
* Arguments   : none
*********************************************************************************************************
*/

void  BSP_Init (void)
{
    AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;                          /* Disable the Watchdog Timer                               */

    AT91C_BASE_RSTC->RSTC_RMR   = ((0x01 << 8) & AT91C_RSTC_ERSTL)
                                | AT91C_RSTC_KEY;
    AT91C_BASE_RSTC->RSTC_RCR   = AT91C_RSTC_EXTRST                         /* Assert the NRST pin to reset the peripherals             */
                                | AT91C_RSTC_KEY;                           /* Provide the correct KEY                                  */

    while ((AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL) == 0) {           /* Wait for reset to complete                               */
        ;
    } 
    
    LED_Init();                                                             /* Initialize the I/Os for the LEDs                         */
    PLL_Init();                                                             /* Initialize PLLA and select it for MCLK                   */

    BSP_IntCtrlInit();                                                      /* Initialize the Interrupt Controller                      */
    Tmr_TickInit();                                                         /* Initialize uC/OS-II's Tick Rate                          */
    
#if  BSP_EXT_MEM_INIT                                                       /* ExtMemoryInit is not necessary when using a boot loader  */
    ExtMemory_Init();                                                       /* Initialize External Memories                             */
#endif
    
}

/*
*********************************************************************************************************
*                                          PLL INITIALIZATION
*
* Description : This function initializes the AT91SAM9261 PLLB which controlls the main processor
*               and USB clock.
*
* Arguments   : none
*
* Notes       : 1) PLLB was chosen over PLLA since it also controls the USB clock, as opposed to having
*                  to initialize both PLLA for the MCLK and PLLB for the USB clock.
*
*               2) The PLL input reference clock is #defined above as MAIN_CLK_FRQ = 18.432MHz. To
*                  generate the PLL output frequency, the equation is:
*
*                       (MAIN_CLK_FRQ / DIV) * MULT + 1, where (MAIN_CLK_FRQ / DIV) > 1MHz
*********************************************************************************************************
*/

static  void  PLL_Init (void)
{                            
    CPU_INT32U  reg_val;
    
                                                                            /* Enable the Main Oscillator                               */
    AT91C_BASE_CKGR->CKGR_MOR   =   AT91C_CKGR_OSCOUNT | AT91C_CKGR_MOSCEN;

                                                                            /* Wait for the Main Oscillator to start up                 */
    while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS) == 0) {
        ;
    }

    AT91C_BASE_PMC->PMC_PLLBR   =  0x20913F0E;                              /* Conf PLLB assuming input frq BSP_XTAL_FREQ               */
                                                                            /* Summary: PLLB CLK: 192MHZ, USB CLKS: 48MHZ               */
                                                                            /* [07:00]  Divider     =  14                               */
                                                                            /* [13:08]  PLLBCount startup dly: 63 SCLKs                 */
                                                                            /* [26:16]  Multiplier  = (145 + 1) = 146                   */
                                                                            /* [29:28]  USB Divider =  4                                */

    while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKB) == 0) {               /* Wait for the PLL to start up                             */
        ;                                                                   
    }

    reg_val                     =   AT91C_BASE_PMC->PMC_MCKR;               /* Read the current Master Clock configuration              */
    reg_val                    &=  ~AT91C_PMC_MDIV;                         /* Clear the Master Divider bits                            */
    reg_val                    &=  ~AT91C_PMC_PRES;                         /* Clear the prescaler bits                                 */
    reg_val                    |=   AT91C_PMC_MDIV_2;                       /* Configure a Master clock divider of 2                    */
    reg_val                    |=   AT91C_PMC_PRES_CLK;                     /* Set a processor clock (PCK) divider of 1                 */
    
    AT91C_BASE_PMC->PMC_MCKR    =   reg_val;                                /* Write new prescaler of 2, do not change CSS field.       */
                                                                            /* MCK must be less than 119MHz, therefore (PLLB / 2) is ok */
    
    while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) == 0) {              /* Wait ready bit to become set before switching to PLLB    */
        ;
    }
    
    reg_val                    &=  ~AT91C_PMC_CSS;                          /* Clear the CSS field bits                                 */
    reg_val                    |=   AT91C_PMC_CSS_PLLB_CLK;                 /* Configure CSS field, do not modify the PRES field        */
    
    AT91C_BASE_PMC->PMC_MCKR   |=   reg_val;                                /* Switch to the PLLB                                       */

    while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) == 0) {              /* Wait for the Master Clock (MCK) to start up              */
        ;
    }
}


/*
*********************************************************************************************************
*                                    DETERMINE AND RETURN CPU OPERATING FREQUENCY
*
* Description : This function is called by OSView_c.c : OSView_GetCPUName().
*               and will return the processor clock frequency (PCK) in Hz
*
* Arguments   : none
*
* Returns     : The CPU frequency (PCK)in Hz, 0 on error
*********************************************************************************************************
*/

CPU_INT32U  BSP_PCK_Frq (void)
{
    CPU_INT08U  pres;
    CPU_INT08U  css;
    CPU_INT32U  pll_mult;
    CPU_INT32U  pll_div;
    CPU_INT32U  sel_clk_frq;
    CPU_INT32U  pck_frq;


    css                     =  (AT91C_BASE_PMC->PMC_MCKR & 0x03);           /* Get the Clock Selection Source field                     */
    pres                    =  (AT91C_BASE_PMC->PMC_MCKR >>   2) & 0x07;    /* Get the selected clock prescaler setting                 */
    pres                    =  (1 << pres);                                 /* Convert 0-7 into 1, 2, 4, 8, 16, 32, or 64               */

    switch (css) {
        case 0x00:                                                          /* Slow clock currently selected                            */
             sel_clk_frq    =   SLOW_CLK_FRQ;                               /* Get the Slow Clock frequency in Hz                       */
             break;

        case 0x01:                                                          /* Main Clock currently selected                            */
            sel_clk_frq     =   MAIN_CLK_FRQ;                               /* Get the Main Clock frequency in Hz                       */
             break;

        case 0x02:                                                          /* PLLA currently selected                                  */
             pll_mult       =  (AT91C_BASE_CKGR->CKGR_PLLAR & 0x07FF0000) >> 16;
             pll_div        =  (AT91C_BASE_CKGR->CKGR_PLLAR & 0x000000FF) >>  0;
             sel_clk_frq    =  (MAIN_CLK_FRQ / pll_div) * (pll_mult + 1);
             break;

        case 0x03:                                                          /* PLLB currently selected                                  */
             pll_mult       =  (AT91C_BASE_CKGR->CKGR_PLLBR & 0x07FF0000) >> 16;
             pll_div        =  (AT91C_BASE_CKGR->CKGR_PLLBR & 0x000000FF) >>  0;
             sel_clk_frq    =  (MAIN_CLK_FRQ / pll_div) * (pll_mult + 1);
             break;
    }

    pck_frq                 =   sel_clk_frq / pres;                         /* Determine the peripheral clock frequency which feeds MCK */

    return (pck_frq);
}

/*
*********************************************************************************************************
*                                    DETERMINE AND RETURN CPU OPERATING FREQUENCY
*
* Description : This function is called by varous modules for determine the peripheral clock
*               frequency (MCK, Master Clock).
* Arguments   : none
*
* Returns     : The CPU frequency (MCK)in Hz, 0 on error
*********************************************************************************************************
*/

CPU_INT32U  BSP_MCK_Frq (void)
{
    CPU_INT08U  mdiv;
    CPU_INT32U  mck_frq;
    CPU_INT32U  pck_frq;


    pck_frq                 =   BSP_PCK_Frq();                              /* Get the processor clock frequency                        */
    mdiv                    =  (AT91C_BASE_PMC->PMC_MCKR >>   8) & 0x03;    /* Get the Master Clock (MCK) Divider field                 */    
    
    if (mdiv  != 3) {                                                       /* Ensure that the MCLK divider is not the reserved value   */
        mdiv                =  (1 << mdiv);                                 /* If not reserved, convert 0-3 into 1, 2, 4                */
    } else {
        return (0);                                                         /* Return 0 if MDIV is set to the reserved value            */
    }
    
    mck_frq                 =   pck_frq  / mdiv;                            /* Determine the Master Clock (MCK) frequency in Hz         */

⌨️ 快捷键说明

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