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

📄 lh7a404_csc_driver.c

📁 sharp触摸屏测试代码
💻 C
📖 第 1 页 / 共 2 页
字号:
 *
 * Processing:
 *     Based on the passed argument, read and return the CPU, AHB bus,
 *     or APB bus frequency to the caller.
 *
 * Parameters:
 *     clock : Must be CPUCLK, AHBCLK, or APBCLK
 *
 * Outputs: None
 *
 * Returns: The selected clock speed in Hz
 *
 * Notes: None
 *
 **********************************************************************/
UNS_32 csc_get_clock(CSC_CLOCK_T clock)
{
    UNS_32 clkinhz = 0;
    
    switch (clock)
    {
        case CPUCLK:
            clkinhz = csc_get_cpuclk();
            break;

        case AHBCLK:
            clkinhz = csc_get_hclk();
            break;

        case APBCLK:
            clkinhz = csc_get_pclk();
            break;

        default:
            break;
    }

    return clkinhz;
}

/***********************************************************************
 *
 * Function: csc_clock_set
 *
 * Purpose: Set the CSC CLKSET register
 *
 * Processing:
 *     Get the existing value of the clock setting register. Set the
 *     state of the static memory controller clock in the new clock
 *     setting word to the state from the existing word. If the existing
 *     clock settings have a bus speed that is a divider (not 1) of the
 *     CPU speed, the existing mode is set to SYNC mode and the new
 *     mode is checked to to be FASTBUS or SYNC mode. If the existing
 *     clock settings have a bus speed that is the same as the CPU
 *     speed, the existing mode is set to FASTBUS mode and the new
 *     mode is checked to to be FASTBUS or SYNC mode. If the new and
 *     existing modes are the same, the clock settings are updated
 *     and 5 'No operation' instructions are executed to clear the
 *     pipeline after the clock setting change, as the chip goes into
 *     standby for a short period of time. If the new and existing
 *     modes are not the same and the new mode is FASTBUS mode, then
 *     the set the new clock speed and then set the new bus mode. If
 *     the new and existing modes are not the same and the new mode
 *     is SYNC mode, then set the new bus mode and then set the new
 *     clock speed.
 *
 * Parameters:
 *     clkset_register_setting : Value to program into CLKSET
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes:
 *     There are 4 possible conditions for bus clocking mode management
 *     in this function. The conditions for handling of each condition
 *     are shown below. The bus clocking mode MUST be configured based
 *     on the CPU and AHB bus speeds or data loss will occur. For
 *     clock settings where the CPU and bus speed are the same, the
 *     FASTBUS clocking mode must be used. For clock settings where the
 *     CPU speed is greater then the bus speed, the SYNC clocking mode
 *     must be used.
 *      Condition 1: Present bus mode is fastbus, new mode is sync
 *          For this condition, the target system bus speed is a
 *          divided speed of the CPU speed and the present system bus
 *          speed is the same as the CPU speed. Prior 
 *      Condition 2: Present bus mode is sync, new mode is fastbus
 *      Condition 3: Present bus mode is sync, new mode is sync
 *          For this condition, no bus mode changes are needed.
 *      Condition 4: Present bus mode is fastbus, new mode is fastbus
 *          For this condition, no bus mode changes are needed.
 *
 **********************************************************************/
void csc_clock_set(UNS_32 clkset_register_setting)
{
    UNS_32 smc_clk_mode;

    /* Save state of static memory controller clock in CLKSET word */
    smc_clk_mode = CLKSC->clkset & CSC_SMCROM;

    /* Switch to fastbus mode to put CPU and bus clocks at the same
       speed */
#ifdef __ICCARM__
    {
        UNS_32 new_clk_mode;

        new_clk_mode = __MRC(15, 0, 1, 0, 0);
        new_clk_mode = new_clk_mode & ARM922T_MMU_CONTROL_BUSMASK;
        new_clk_mode = new_clk_mode | ARM922T_MMU_CONTROL_FASTBUS;
        __MCR(15, 0, new_clk_mode, 1, 0, 0);
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
    }
#endif

#ifdef __GNUC__
    asm ("MRC p15, 0, r1, c1, c0, 0");
    asm ("MOV r2, %0" : : "r" (ARM922T_MMU_CONTROL_FASTBUS));
    asm ("AND r1, r1, %0" : : "r" (ARM922T_MMU_CONTROL_BUSMASK));
    asm ("ORR r1, r1, r2");
    asm ("MCR p15, 0, r1, c1, c0, 0");
    asm ("NOP");
    asm ("NOP");
    asm ("NOP");
    asm ("NOP");
    asm ("NOP");
#endif

#ifdef __ghs__
    change_clkbus_mode (ARM922T_MMU_CONTROL_FASTBUS,
        ARM922T_MMU_CONTROL_BUSMASK);
    nops5();
#endif

#ifdef __arm
    __asm
    {
        MRC ARM922T_MMU_CP, 0, r1, ARM922T_MMU_REG_CONTROL, c0, 0
        MOV r2, #ARM922T_MMU_CONTROL_FASTBUS
        AND r1, r1, #ARM922T_MMU_CONTROL_BUSMASK
        ORR r1, r1, r2
        MCR ARM922T_MMU_CP, 0, r1, ARM922T_MMU_REG_CONTROL, c0, 0
        NOP
        NOP
        NOP
        NOP
        NOP
    }
#endif

    /* Set the new clock mode */
    CLKSC->clkset = (clkset_register_setting | smc_clk_mode);

    /* NOPs to clear the pipeline after coming out of standby */
#ifdef __ICCARM__
    __no_operation();
    __no_operation();
    __no_operation();
    __no_operation();
    __no_operation();
#endif

#ifdef __GNUC__
    asm ("NOP");
    asm ("NOP");
    asm ("NOP");
    asm ("NOP");
    asm ("NOP");
#endif

#ifdef __ghs__
    nops5();
#endif

#ifdef __arm
    __asm
    {
        NOP
        NOP
        NOP
        NOP
        NOP
    }
#endif

    /* If the CPU and bus clocks are different, switch to SYNC mode */
    if ((clkset_register_setting & 0x00000003) != 0)
    {
#ifdef __ICCARM__
    {
        UNS_32 new_clk_mode;

        new_clk_mode = __MRC(15, 0, 1, 0, 0);
        new_clk_mode = new_clk_mode & ARM922T_MMU_CONTROL_BUSMASK;
        new_clk_mode = new_clk_mode | ARM922T_MMU_CONTROL_SYNC;
        __MCR(15, 0, new_clk_mode, 1, 0, 0);
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
    }
#endif

#ifdef __GNUC__
        asm ("MRC p15, 0, r1, c1, c0, 0");
        asm ("MOV r2, %0" : : "r" (ARM922T_MMU_CONTROL_SYNC));
        asm ("AND r1, r1, %0" : : "r" \
            (ARM922T_MMU_CONTROL_BUSMASK));
        asm ("ORR r1, r1, r2");
        asm ("MCR p15, 0, r1, c1, c0, 0");
        asm ("NOP");
        asm ("NOP");
        asm ("NOP");
        asm ("NOP");
        asm ("NOP");
#endif

#ifdef __ghs__
        change_clkbus_mode (ARM922T_MMU_CONTROL_SYNC,
            ARM922T_MMU_CONTROL_BUSMASK);
        nops5();
#endif

#ifdef __arm
        __asm
        {
            MRC ARM922T_MMU_CP, 0, r1, ARM922T_MMU_REG_CONTROL, c0, 0
            MOV r2, #ARM922T_MMU_CONTROL_SYNC
            AND r1, r1, #ARM922T_MMU_CONTROL_BUSMASK
            ORR r1, r1, r2
            MCR ARM922T_MMU_CP, 0, r1, ARM922T_MMU_REG_CONTROL, c0, 0
            NOP
            NOP
            NOP
            NOP
            NOP
        }
#endif
    }
}

/***********************************************************************
 *
 * Function: csc_stby_wakeup_enable
 *
 * Purpose: Enable or disable the wakeup signal
 *
 * Processing:
 *     Disable the wakeup signal by setting the wakeup disable bit in
 *     the CSC WRCNT register.
 *
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void csc_stby_wakeup_enable(BOOL_32 enable)
{
    if (enable == TRUE)
    {
        /* Wakeup is enabled */
        CLKSC->pwrcnt &= ~CSC_PWRCNT_WAKEDIS;
    }
    else
    {
        /* Wakeup is disabled */
        CLKSC->pwrcnt |= CSC_PWRCNT_WAKEDIS;
    }
}

/***********************************************************************
 *
 * Function: csc_set_pgmclk_divisor
 *
 * Purpose: Set the PGMCLK divisor (> 1) or disable it (= 0)
 *
 * Processing:
 *     Get the value of the CSC power count register and mask off the
 *     clock program bits. Or in the new clock program bits into the
 *     power count register.
 *
 * Parameters:
 *     div : Program clock divisor value (0 to 254)
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void csc_set_pgmclk_divisor(UNS_8 div)
{
    UNS_32 tmp;

    /* Get register and mask off clock program bits */
    tmp = ((CLKSC->pwrcnt & ~CSC_PWRCNT_PGMCLK(0xFF)) |
        CSC_PWRCNT_PGMCLK(div));
    CLKSC->pwrcnt = tmp;
}

/***********************************************************************
 *
 * Function: csc_enable_dma_clock
 *
 * Purpose: Enable or disable a DMA controller channel clock
 *
 * Processing:
 *     If enable is TRUE, enables a selected DMA channel by setting the
 *     appropriate bit in the CSC PWRCNT register. If enable is FALSE,
 *     the appropriate bit in the CSC PWRCNT register id disabled.
 *
 * Parameters:
 *     channel : Must be of enumeration type CSC_DMA_CHANNEL_T
 *     enable  : Must be TRUE or FALSE
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void csc_enable_dma_clock(CSC_DMA_CHANNEL_T channel, BOOL_32 enable)
{
    CLKSC->pwrcnt |= (CSC_PWRCNT_DMAPCH1 << (INT_32) channel);
}

/***********************************************************************
 *
 * Function: csc_usb_reset
 *
 * Purpose: Issue a USB IO or control reset
 *
 * Processing:
 *     Issues a USB control or IO reset by setting the 
 *
 * Parameters:
 *     reset : Must be USB_IO or USB_CONTROL
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void csc_usb_reset(CSC_USB_RESET_T reset)
{
    CLKSC->usbreset |= (UNS_32) reset;
}

/***********************************************************************
 *
 * Function: csc_compute_divider
 *
 * Purpose:
 *     Compute the closest divider to the passed input frequency and
 *     desired target frequency 
 *
 * Processing:
 *     Start by computing a divider value that will get the closest
 *     frequency just below the desired target, based on the input
 *     frequency. If the divider is 1, just return '1'. Otherwise,
 *     determine if the divider value or the divider value minus 1 is
 *     a closer match to get the target frequency. Return the closest
 *     match divider value.
 *
 * Parameters:
 *     input_freq   : Input frequency (such as AHB bus speed)
 *     desired_freq : Target frequency
 *
 * Outputs: None
 *
 * Returns:
 *     The closest divider value for (Input frequency) divided by
 *     (Target frequency)
 *
 * Notes: None
 *
 **********************************************************************/
INT_32 csc_compute_divider(UNS_32 input_freq,
                           UNS_32 desired_freq)
{
    UNS_32 div_clock, clock_diff1, clock_diff2;
    UNS_32 div = 1;

    /* Strt with a divider of 1 */
    div_clock = input_freq / div;

    /* Try to get the best divider just under the desired frequency */
    while (div_clock > desired_freq)
    {
        div++;
        div_clock = input_freq / div;
    }

    if (div > 1)
    {
        /* Determine if 'div' or 'div - 1' is closer to desired
           frequency */
        if (div_clock > desired_freq)
        {
            clock_diff1 = div_clock - desired_freq;
        }
        else
        {
            clock_diff1 = desired_freq - div_clock;
        }

        div_clock = desired_freq / (div - 1);
        if (div_clock > desired_freq)
        {
            clock_diff2 = div_clock - desired_freq;
        }
        else
        {
            clock_diff2 = desired_freq - div_clock;
        }

        /* If diff1 is greater than diff2, then 'div + 1' is the
           closest divider */
        if ((clock_diff1 > clock_diff2) && (div > 1))
        {
            div--;
        }
    }

    return div;
}

⌨️ 快捷键说明

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