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

📄 sdk7a404_startup.c

📁 在sharp 404开发板的串口测试代码
💻 C
📖 第 1 页 / 共 2 页
字号:
 *     of the next segment and return it to the caller. Otherwise, just
 *     return the incremented address to the caller (this has a size
 *     limit of 23Mbytes in the current SDRAM configuration).
 *
 * Parameters:
 *     base_addr : Current address (will find next available address)
 *
 * Outputs: None
 *
 * Returns: The next available word address in SDRAM
 *
 * Notes:
 *     This function is used with the segment copy and clear functions
 *     when initializing segments. A linear segment over 4Mbytes needs
 *     to be copied to multiple non-contiguous areas in SDRAM. (When
 *     the MMU is enabled, the SDRAM segments will become contiguous).
 *
 **********************************************************************/
UNS_32 * sdk7a404_next_address(UNS_32 *base_addr)
{
    INT_32 idx;

    /* Find the segment the address is in */
    idx = 0;
    while (!(((UNS_32) base_addr >= sdram_copy[idx].base_address) &&
        ((UNS_32) base_addr <= (sdram_copy[idx].base_address) +
        sdram_copy[idx].segment_size)))
    {
        /* Try next segment */
        idx++;
    }

    /* Was a match found? */
    if (idx < SDRAM_NUM_SEGS )
    {
        /* Increment address */
        base_addr++;

        /* Does this overflow the segment? */
        if ((UNS_32) base_addr >= (sdram_copy[idx].base_address +
            sdram_copy[idx].segment_size))
        {
            /* Yes, switch to next index value */
            idx++;

            /* If index is valid, get start of next segment */
            if (idx < SDRAM_NUM_SEGS)
            {
                base_addr = (UNS_32 *) sdram_copy[idx].base_address;
            }
        }
    }

    return base_addr;
}

/***********************************************************************
 * Startup code public support functions
 **********************************************************************/

/***********************************************************************
 *
 * Function: sdk7a404_init
 *
 * Purpose: Main startup code entry point, called from reset entry code
 *
 * Processing:
 *     Set the SOC clock speed to 200MHz CPU, 100MHz bus, and 50MHz
 *     peripheral bus. Initialize the asynchronous memory interfaces
 *     with a call to sdk7a404_memory_init(). Initialize the SDRAM
 *     interface with a call to sdk7a404_sdram_init(). Setup the MMU
 *     page tables with a call to sdk7a404_mmu_init(). Copy the image
 *     from FLASH to SDRAM (when the MMU is enabled, the code needs
 *     to be mirrored in SDRAM). Copy the pre-initialized data segment
 *     and zero out the uninitialized data segment.
 *
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void sdk7a404_init(void)
{
    UNS_32 *src, *dst;
    INT_32 bytes;
    UNS_32 basecopy_addr;

    /* Increase the clock speed to 200/100/50 MHz */
    csc_clock_set(CSC_200_100_50);

    /* Initialize memory interfaces */
    sdk7a404_memory_init();

    /* Initialize SDRAM */
    sdk7a404_sdram_init();

    /* Setup MMU page tables */
    sdk7a404_mmu_init();

    /* If the code is linked to execute starting at address 0x0, then
       copy the code to SDRAM */
    basecopy_addr = RO_IMG_COPY_BASE;
    if (basecopy_addr == 0x00000000)
    {
        /* Code will be copied to SDRAM */
        basecopy_addr = SDRAM1_SEG1_ADDR;

        /* Copy the code image in FLASH to the start of SDRAM */
        src = (UNS_32 *) RO_IMG_COPY_BASE;
        dst = (UNS_32 *) (basecopy_addr + RO_IMG_COPY_BASE);
        for (bytes = 0; bytes < RO_IMG_COPY_SIZE; bytes = bytes + 4)
        {
            *dst = *src;
            dst = sdk7a404_next_address(dst);
            src++;
        }
    }
    else
    {
        /* Code is not compiled to be executed from FLASH (and copied
           to SDRAM), so just don't adjust the copy address and don't
           move the code segment. Code compiled with this method can
           be located to execute from any available memory source and
           is good for testing startup code. However, this method may
           not work well with all toolsets. */
        basecopy_addr = 0x00000000;
    }

    /* Zero out an area of memory for the ZI section */
    dst = (UNS_32 *) (basecopy_addr + ZI_IMG_BASE);
    for (bytes = 0; bytes < ZI_IMG_SIZE; bytes = bytes + 4)
    {
        *dst = 0;

        if (basecopy_addr != 0x00000000)
        {
            /* Copy to SDRAM if compiled for a FLASH target */
            dst = sdk7a404_next_address(dst);
        }
        else
        {
            /* Just copy to the linker defined address */
            dst++;
        }
    }

    /* Copy pre-initialized data segment from FLASH to memory */
    src = (UNS_32 *) RW_IMG_COPY_BASE;
    dst = (UNS_32 *) (basecopy_addr + RW_LOAD_COPY_BASE);
    for (bytes = 0; bytes < RW_IMG_COPY_SIZE; bytes = bytes + 4)
    {
        *dst = *src;
        src++;

        if (basecopy_addr != 0x00000000)
        {
            /* Copy to SDRAM if compiled for a FLASH target */
            dst = sdk7a404_next_address(dst);
        }
        else
        {
            /* Just copy to the linker defined address */
            dst++;
        }
    }
}

/***********************************************************************
 *
 * Function: sdk7a404_memory_init
 *
 * Purpose: Memory interfaces initialization
 *
 * Processing:
 *     Initialize the interfaces for chip select 0, 6, and 7.
 *
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void sdk7a404_memory_init(void)
{
    /* Setup BCR for FLASH memory */
    SMC->bcr0 = SMC_BCR0_INIT;

    /* Setup BCR registers for the CPLD device */
    SMC->bcr6 = SMC_BCR6_INIT;
    SMC->bcr7 = SMC_BCR7_INIT;
}

/***********************************************************************
 *
 * Function: sdk7a404_sdram_init
 *
 * Purpose: SDRAM initialization
 *
 * Processing:
 *     Get the current bus clock speed. Wait for 100uS for the SDRAM
 *     devices and clocks to stabilize. Set the SDRAM chip select 0 with
 *     the SDRAM configuration value. Wait another 100uS. Issue NOP
 *     commands the the SDRAM devices for 200uS. Issue a precharge all
 *     command to the SDRAM devices. Perform continuous refresh on the
 *     devices for 10uS. Set the refresh time of the devices based on
 *     the current bus clock speed. Write the mode word to the devices.
 *     Place the SDRAM devices in the normal operating mode.
 *
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void sdk7a404_sdram_init(void)
{
    volatile UNS_32 tmp;
    UNS_32 current_HCLK;

    current_HCLK = csc_get_clock(AHBCLK);

    /* Delay for 100uS to allow SDRAM clocks to settle */
    timer_wait_us(TIMER2, 100);

    /* Configure "device config register" nSDCE0 for proper width */
    SDRAMC->nsdcs0 = SDRAM_CS_CONFIG;

    /* Small delay */
    timer_wait_us(TIMER2, 100);

    /* Issue continuous NOP commands (INIT & MRS set) */
    SDRAMC->global = (SDRAM_GLOBAL_CKE | SDRAM_GLOBAL_NOP);

    /* 200uS delay */
    timer_wait_us(TIMER2, 200);

    /* Issue a "pre-charge all" command */
    SDRAMC->global = (SDRAM_GLOBAL_CKE | SDRAM_GLOBAL_PREALL);

    /* Start with a small refresh delay to allow a few refresh cycles
       to occur on the SDRAM devices */
    SDRAMC->refresh = SDRAM_REFTMR_REFCNT(10);

    /* Small delay for a few refreshes */
    timer_wait_us(TIMER2, 10);

    /* Set recommended refresh delay */
    SDRAMC->refresh = SDRAM_REFTMR_REFCNT((current_HCLK /
        SDRAM_REFRESH_INTERVAL) - 1);

    /* Select mode register update mode */
    SDRAMC->global = (SDRAM_GLOBAL_CKE | SDRAM_GLOBAL_ENAMODE);
     
    /* Perform the SDRAM mode operation - this configures the SDRAM
       devices for CAS2, burst size of 4 words. The shift is needed
       to put the mode word in the correct location on the bus */
    tmp = *((volatile UNS_32 *)(SDRAM_SDCE0_BASE |
        (SDRAM_MODE_WORD << 10)));

    SDRAMC->nsdcs0 = SDRAM_CS_CONFIG;

    /* Place devices in normal operating mode */
    SDRAMC->global = (SDRAM_GLOBAL_CKE | SDRAM_GLOBAL_NORMAL);
}

/***********************************************************************
 *
 * Function: sdk7a404_sdram_refresh_update
 *
 * Purpose: SDRAM refresh frequency update function
 *
 * Processing:
 *     Updates the SDRAM refresh clock based on the passed value of
 *     new_bus_clock (in Hz).
 *
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes:
 *    If the new bus clock speed is faster than the existing speed,
 *    then this function should be called after the bus clock speed is
 *    changed. If the new bus clock speed is slower than the existing
 *    speed, then this function should be called prior to the bus clock
 *    speed change.
 *
 **********************************************************************/
void sdk7a404_sdram_refresh_update(UNS_32 new_bus_clock)
{
    SDRAMC->refresh = SDRAM_REFTMR_REFCNT((new_bus_clock /
        SDRAM_REFRESH_INTERVAL) - 1);
}

/***********************************************************************
 *
 * Function: sdk7a404_mmu_init
 *
 * Purpose: MMU page table initialization
 *
 * Processing:
 *     Calls the cp15_init_mmu_trans_table() function with the addresses
 *     of the MMU translation table and the page mapping table.
 *
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void sdk7a404_mmu_init(void)
{
    cp15_init_mmu_trans_table((TRANSTABLE_T *) MMU_TRANS_TAB_ADDR,
                              tt_init_basic);
}

⌨️ 快捷键说明

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