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

📄 ddi_display_controller_hx8347a_20070920.c

📁 sigmatel STMP36XX MP4方案下1289控制器和HX8347控制器
💻 C
📖 第 1 页 / 共 4 页
字号:
//! \fn static RtStatus_t WaitForControllerVsync(void)
//! 
//! \brief Blocks until the next valid VSYNC edge
//!
//! \fntype Function
//!
//! In VSYNC mode, this command will block the calling thread until the next
//! valid VSYNC edge or until the timeout period has elapsed.
//!
////////////////////////////////////////////////////////////////////////////////
/*
static RtStatus_t WaitForControllerVsync(void)
{
    RtStatus_t ret = SUCCESS;
    uint32_t u32Ret;

    if( ddi_etm_IsPresent() ) {
        return SUCCESS;
    }

    // Check if our semaphore was created
    if( g_ddi_display_VideoMode == DDI_DISPLAY_VSYNC_MODE && pVideoSemaphore )
    {
        // Enable the interrupt vector
        hw_icoll_EnableVector(GPIO_VSYNC_IRQ_VECTOR, true);    

        // Now enable the VSYNC ISR, it will put the binary semaphore on the
        // next VSYNC edge
        ENABLE_VSYNC_IRQ();

        // Block on the VSYNC signal
        u32Ret = tx_semaphore_get(pVideoSemaphore, VSYNC_TIMEOUT_TICKS);
        if( u32Ret )
        {
            ret = CONVERT_TX_RTCODE(u32Ret);
            if( ERROR_OS_KERNEL_TX_NO_INSTANCE == ret )
            {
                // There was an error with the VSYNC signal reception
                ret = ERROR_DDI_DISPLAY_CONTROLLER_VSYNC;
            }
        }
    }
    else
    {
        // Not our ISR, we're not configured for VSYNC mode
        ret = ERROR_DDI_DISPLAY_CONTROLLER_VSYNC;
    }

    return ret;
}
*/
////////////////////////////////////////////////////////////////////////////////
//! \fn static RtStatus_t SendControllerVideoMode(ddi_display_VideoMode_t VideoMode)
//! 
//! \brief Sets up the controller for the desired video mode 
//!
//! \fntype Function
//!
//! \param[in] VideoMode The desired mode of operation for the display driver
//!
//! This function sets up the necessary hardware for the desired video mode of
//! operation.  The default is \ref DDI_DISPLAY ASYNC_MODE which will have no 
//! synchronization with the controller video RAM refresh.  When using 
//! \ref DDI_DISPLAY_VSYNC_MODE, calls to \ref ddi_display_Draw will block the 
//! calling thread until the next rising edge of the VSYNC signal.
//!
//! \note Future implementations (Piano) will include a DDI_DISPLAY_DOTCLK_MODE 
//! which will use the VSYNC/HSYNC/DOTCLK/DEN signals to transfer video.
//!
////////////////////////////////////////////////////////////////////////////////
/*
static RtStatus_t SendControllerVideoMode(ddi_display_VideoMode_t VideoMode)
{
    RtStatus_t ret = SUCCESS;
    SSD1289LCDDrivingWaveformControl LCDDrivingWaveformControl = { 0x0600 };
    SSD1289FrameCycleControl FrameCycleControl = {0};
    SSD1289VerticalPorch VerticalPorch = {0x0003};

    if( DDI_DISPLAY_VSYNC_MODE == VideoMode && DDI_DISPLAY_VSYNC_MODE != g_ddi_display_VideoMode )
    {
        ddi_gpio_Cfg_t GpioConfig;
        void (*pGpioVsyncHandler)(void*);

        // Check if someone else has registered a GPIO handler for our vector
        pGpioVsyncHandler = ddi_icoll_GetHandlerFunction(GPIO_VSYNC_IRQ_VECTOR);

        // If no handler has been registered it will be the ddi_icoll_DefaultIsr
        // If this function is called after we have already registered, it will ddi_display_controller_VsyncIsr
        if( pGpioVsyncHandler != ddi_icoll_DefaultIsr && pGpioVsyncHandler != ddi_display_controller_VsyncIsr )
        {
            // Someone else has installed a GPIO handler function
            // Until the GPIO driver has the proper interrupt chaining
            // implemented to support multiple interrupts on a single GPIO
            // bank, we will not be able to use VSYNC mode.  This needs to be
            // corrected, so we're going to halt here until it is
            SystemHalt();
        }

        // Now register our interrupt handler
        ddi_icoll_RegisterIrqHandler(GPIO_VSYNC_IRQ_VECTOR, ddi_display_controller_VsyncIsr, NULL, IRQ_HANDLER_DIRECT, PRIORITY_VIDEO_ISR);

        // Create the video semaphore if not already created
        if( !pVideoSemaphore )
        {
            // Create semaphore without priority inheritence.  
            // Only one thread ever will be trying to access this.
            ret = os_txi_SemaphoreAllocate(&pVideoSemaphore, DMI_MEM_SOURCE_DONTCARE, "video", false);

            // Return an error if couldn't create semaphore
            if( ret )
                return ret;
        }

        // Setup GPIO VSYNC signal
        GpioConfig.mask = GPIO_VSYNC_CONFIG_MASK | GPIO_MASK_IRQ_ENABLED;

        // Attempt to reserve and configure the pin
        ret = ddi_gpio_LockAndLoadPin(GPIO_VSYNC_IRQ_PIN, GpioConfig);

        // Check for failure
        if( ret )
        {
            if( pVideoSemaphore )
            {
                // Free the video semaphore due to error
                os_txi_SemaphoreRelease(pVideoSemaphore);
                // Set it to NULL again so we can check for the semaphore later
                pVideoSemaphore = NULL;
            }

            return ret;
        }
        
        // Enable the vector
        hw_icoll_EnableVector(GPIO_VSYNC_IRQ_VECTOR, true);    

        // Now setup the display controller to output the sync signal
        LCDDrivingWaveformControl.B.ENWS = 1;  // Enable sync
        WriteDirect(CMD_MODE, 0x02);    // LCD Driving Waveform Control
        WriteDirect(DATA_MODE, LCDDrivingWaveformControl.V); // Enable sync output

        // Adjust these settings to get desired frame rate
        FrameCycleControl.B.SDIV = 1;
        FrameCycleControl.B.DIV = 0;
        WriteDirect(CMD_MODE, 0x0b);    // Frame Cycle Control
        WriteDirect(DATA_MODE, FrameCycleControl.V);

        WriteDirect(CMD_MODE, 0x17);    // Vertical Porch
        WriteDirect(DATA_MODE, VerticalPorch.V);

        g_ddi_display_VideoMode = DDI_DISPLAY_VSYNC_MODE;

        // Wait for the first VSYNC pulse
        WaitForControllerVsync();
    }
    else if( DDI_DISPLAY_ASYNC_MODE == VideoMode && DDI_DISPLAY_ASYNC_MODE != g_ddi_display_VideoMode )
    {
        // Disable the vector
        hw_icoll_EnableVector(GPIO_VSYNC_IRQ_VECTOR, false);

        // Release the GPIO
        ddi_gpio_UnlockPin(GPIO_VSYNC_IRQ_PIN);

        WriteDirect(CMD_MODE, 0x0b);    // Frame Cycle Control
        WriteDirect(DATA_MODE, 0);
        // Stop the controller from generating the VSYNC signal
        WriteDirect(CMD_MODE, 0x02);    // LCD Driving Waveform Control
        WriteDirect(DATA_MODE, LCDDrivingWaveformControl.V); // Disable sync output

        g_ddi_display_VideoMode = DDI_DISPLAY_ASYNC_MODE;
    }
    else
    {
        ret = ERROR_DDI_DISPLAY_CONTROLLER_VIDEO_MODE_UNSUPPORTED;
    }

    return ret;
}
#endif
*/
////////////////////////////////////////////////////////////////////////////////
//! \fn static void SendControllerOutputEnable(bool bOn)
//! 
//! \brief Turns the display on or off
//!
//! \fntype Function
//!
//! \param[in] bOn - true to turn on the display, false to turn it off
//!
//! This function sends commands to the controller to enable the output of the
//! display.
//!
////////////////////////////////////////////////////////////////////////////////
static void SendControllerOutputEnable(bool bOn)
{
     Hx8347aDisplayControl DisplayControl = { 0x003C };

    if( bOn )
    {
        WriteDirect(CMD_MODE, 0x26);    // Display Control
        WriteDirect(DATA_MODE, DisplayControl.V); // Enable output
    }
    else
    {
	DisplayControl.B.D1 = 0 ;        //diable diaplay
        WriteDirect(CMD_MODE, 0x26);    // Display Control
        WriteDirect(DATA_MODE, DisplayControl.V); // Disable output
    }


    // Enable or disable the backlight PWM as necessary
    if( bOn )
        HW_PWM_CTRL_SET(1 << DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL);
    else
        HW_PWM_CTRL_CLR(1 << DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL);
}


////////////////////////////////////////////////////////////////////////////////
//! \brief Enters/exits low power mode
//!
//! \fntype Function
//!
//! \param[in] bOn - true to set low power mode, false to exit low power mode
//!
//! When entering low power mode, the LCDIF block is put into reset.  This
//! should make the display controller go into reset as well.  The backlight is
//! also disabled at this time.  When exiting low power mode, the LCDIF is
//! reinitialized and the controller init sequence is sent again.  The
//! application code must set the brightness and output enable after coming out
//! of low power mode.
//!
////////////////////////////////////////////////////////////////////////////////
static void SetControllerLowPowerMode(bool bOn)
{
    if( bOn )
    {
        SendControllerOutputEnable(false);
        ddi_lcdif_Shutdown(true);
    }
    else
    {
#ifdef DEBUG
	RtStatus_t ret = SUCCESS;
#endif
        hw_lcdif_Init_t LcdifInit;

        // Get the LCDIF init struct to send to the LCDIF DDI init function
#ifdef DEBUG
        ret =
#endif
	    ddi_display_controller_GetLcdifInitStruct(&LcdifInit, g_ddi_display_eBitmapType);
#ifdef DEBUG
        assert(!ret);
#endif

        // Run the low level init on the LCDIF
#ifdef DEBUG
        ret =
#endif
	    ddi_lcdif_Init(&LcdifInit, g_ddi_display_pDmaDescChain, g_ddi_display_NumDmaDesc);
#ifdef DEBUG
        assert(!ret);
#endif

#if defined(RTOS_THREADX)
        ddi_lcdif_RegisterCompletionCallback(&g_ddi_display_DmaCompletionCallback);
#endif
        // Init the display controller, use last set width/height
#ifdef DEBUG
        ret =
#endif
	    ddi_display_controller_SendCommand(DDI_DISPLAY_CONTROLLER_INIT, 
                                                 g_ddi_display_eBitmapType,
                                                 g_ddi_display_u16ScreenWidth,
                                                 g_ddi_display_u16ScreenHeight);
#ifdef DEBUG
        assert(!ret);
#endif

    }
}

////////////////////////////////////////////////////////////////////////////////
//! \fn static void SetPwmBrightness(uint32_t u32Percentage)
//!
//! \brief Sets the specified brightness percentage on the display
//!
//! \fntype Function
//!
//! \param[in] u32Percentage - Percent total brightness from 0 -> 100
//!
//! Sets the PWM backlight control channel according to the given brightness
//! percentage value.
//!
////////////////////////////////////////////////////////////////////////////////
static void SetPwmBrightness(uint32_t u32Percentage)
{
    uint32_t u32InactivePeriod;

    // Set the raw values in the PWM registers
    if( u32Percentage > 100 )
        u32Percentage = 100;

    // Calc the pulse width
    u32InactivePeriod = ((BACKLIGHT_PWM_PERIOD * MIN_BRIGHTNESS_PERCENTAGE)/100) + 
        (( ((BACKLIGHT_PWM_PERIOD * (MAX_BRIGHTNESS_PERCENTAGE - MIN_BRIGHTNESS_PERCENTAGE))/100)
            * u32Percentage)/100);

    // Scale the range 0->100% down to 0->70% to protect the hardware
    BF_CS2n(PWMn_ACTIVE, DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL, 
            ACTIVE, 0,// BACKLIGHT_PWM_PERIOD, 
            INACTIVE, u32InactivePeriod);

    // Have to write the period register to apply the changes
    HW_PWMn_PERIOD_SET(DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL, 0);
}


////////////////////////////////////////////////////////////////////////////////
//! \fn static RtStatus_t SendControllerRegion(uint32_t u32XDst, uint32_t u32YDst, uint32_t *pu32Width, uint32_t *pu32Height, ddi_display_Rotation_t eRotation)
//!
//! \brief Sets up the region on the controller where pixels are to be placed
//!
//! \fntype Function
//!
//! \param[in] u32XDst - X coordinate of upper left corner of the destination region
//! \param[in] u32YDst - Y coordinate of upper left corner of the destination region
//! \param[in] pu32Width - Width of the destination region
//! \param[in] pu32Height - Height of the destination region
//! \param[in] eRotation - Desired orientation of the display
//!
//! This function sends commands to the controller to set up the destination
//! region (or "box") where pixels are to be placed.  The rotation is specified
//! here as well as with the SendControllerRotation function because some
//! controllers handle rotation on a per region basis.
//!
//! \retval SUCCESS No error
//!
//! \retval ERROR_DDI_DISPLAY_CONTROLLER_ROTATION - The specified rotation is
//!         not supported by the controller
//!
//! \retval ERROR_DDI_DISPLAY_PLACEMENT - There was an error placing the given
//!         region on the display that clipping could not compensate for.
//!
////////////////////////////////////////////////////////////////////////////////
static RtStatus_t SendControllerRegion(uint32_t u32XDst, uint32_t u32YDst, 
                                       uint32_t *pu32Width, uint32_t *pu32Height,
                                       ddi_display_Rotation_t eRotation)
{
    uint32_t u32TotalWidth = g_ddi_display_u16ScreenWidth;
    uint32_t u32TotalHeight = g_ddi_display_u16ScreenHeight;
    RtStatus_t ret = SUCCESS;

    uint16_t u16SourceWinStart_high;
    uint16_t u16SourceWinStart_low;
    uint16_t u16SourceWinStop_high;
    uint16_t u16SourceWinStop_low;

    uint16_t u16GateWinStart_high;
    uint16_t u16GateWinStart_low;
    uint16_t u16GateWinStop_high;
    uint16_t u16GateWinStop_low;

    // Check for zero sized region
    if( !*pu32Width || !*pu32Height 
        || u32XDst >= u32TotalWidth
        || u32YDst >= u32TotalHeight )
    {
        return ERROR_DDI_DISPLAY_PLACEMENT;
    }

    // Check for clipping
    if( u32XDst + *pu32Width > u32TotalWidth)
    {
        // FIXME - Must do a DrawRegion type xfer for this
        // since the clipped pixels will not be contiguous
        return ERROR_DDI_DISPLAY_PLACEMENT;
    }

    // Check for clipping
    if( u32YDst + *pu32Height > u32TotalHeight )
    {
        // Fix clipping region
        *pu32Height = u32TotalHeight - u32YDst;
    }

⌨️ 快捷键说明

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