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

📄 ddi_display_controller_hx8347a_20070920.c

📁 sigmatel STMP36XX MP4方案下1289控制器和HX8347控制器
💻 C
📖 第 1 页 / 共 4 页
字号:
////////////////////////////////////////////////////////////////////////////////
//! \addtogroup ddi_display
//! @{
//
// Copyright (c) 2004-2005 SigmaTel, Inc.
//
//! \file ddi_display_controller_ssd1289.c
//! \brief Structures and code specific to the Solomon Systech 1289 controller
//! \date 03/2006
//!
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Includes and external references
////////////////////////////////////////////////////////////////////////////////
#include <types.h>
#include <drivers\ddi_display.h>
#include <stdarg.h>
#include <registers\regspower.h>  // need this to check for alkaline battery 
#include <registers\hw_irq.h>
#include "..\ddi_display_controller.h"
#include <components\gfx.h>
#include <hw\hw_lcdif.h>
#include <hw\hw_gpio.h>
#include <drivers\ddi_gpio.h>
#include <drivers\ddi_pwm.h>
#include <drivers\ddi_lcdif.h>
#include <drivers\ddi_icoll.h>
#include <string.h>
#if defined(RTOS_THREADX)
#include <os\os_thi_api.h>
#endif
#include <registers\regspwm.h>
#include <registers\regspinctrl.h>
#include <hw\vmemory.h>
#include <interrupts.h>
#include <drivers\ddi_etm.h>

#include <drivers\ddi_rtc.h>
////////////////////////////////////////////////////////////////////////////////
// Externs
////////////////////////////////////////////////////////////////////////////////
ddi_display_Rotation_t g_ddi_display_eRotation = DDI_DISPLAY_ROTATION_NONE;
gfx_BitmapTypeEnum_t g_ddi_display_eBitmapType = BITMAP_TYPE_16BPP_565;

#if defined(RTOS_THREADX)
//! Handler for the DMA completion callback
extern void g_ddi_display_DmaCompletionCallback(void *);
#endif
extern bool g_bInitializeLCDController;


////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////

// 16bit interface for TopSun
#define DDI_LCDIF_WORDLENGTH_16BITS 1

#ifndef DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL
#define DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL 2
#endif

#ifndef DDI_DISPLAY_DATA_SETUP_XCLKS 
#define DDI_DISPLAY_DATA_SETUP_XCLKS 2
#endif

#ifndef DDI_DISPLAY_DATA_HOLD_XCLKS
#define DDI_DISPLAY_DATA_HOLD_XCLKS 1
#endif

#ifndef DDI_DISPLAY_CMD_SETUP_XCLKS 
#define DDI_DISPLAY_CMD_SETUP_XCLKS 1
#endif

#ifndef DDI_DISPLAY_CMD_HOLD_XCLKS 
#define DDI_DISPLAY_CMD_HOLD_XCLKS 1
#endif

#ifndef DDI_DISPLAY_DEFAULT_SIZE_HORIZONTAL 
#define DDI_DISPLAY_DEFAULT_SIZE_HORIZONTAL 320
#endif

#ifndef DDI_DISPLAY_DEFAULT_SIZE_VERTICAL
#define DDI_DISPLAY_DEFAULT_SIZE_VERTICAL 240
#endif

//! Min allowed brightness percentage
#define MIN_BRIGHTNESS_PERCENTAGE 0
//! Alkaline batttery can't support the power needed for high brightness
#define ALKALINE_MIN_BRIGHTNESS_PERCENTAGE 10

//! Max allowed brightness percentage
#define MAX_BRIGHTNESS_PERCENTAGE 81
//! Alkaline batttery can't support the power needed for high brightness
#define ALKALINE_MAX_BRIGHTNESS_PERCENTAGE 20


//! Defines the CDIV value for OS independent PWM control
#define BACKLIGHT_PWM_CDIV BV_PWMn_PERIOD_CDIV__DIV_64
//! Defines the period in divided clocks for OS independent PWM control
#define BACKLIGHT_PWM_PERIOD 200

// When the controller is using the LCDIF in 16bit bus mode, command bytes
// cannot be sent in a packed 16 bit word transfer.  Each command byte must 
// be in its own 16-bit word transfer.  Furthermore, the command byte has to
// in the lower byte of the 16-bit word.  In 16bit mode, 2 command bytes
// cannot be packed into 1 16-bit word.
#ifdef DDI_LCDIF_WORDLENGTH_16BITS
#define DDI_DISPLAY_WORD_TYPE uint16_t
#define DDI_DISPLAY_WORDLENGTH WORDLENGTH_16BITS
#define DDI_DISPLAY_DATA_SWIZZLE NO_SWAP
#else
#define DDI_DISPLAY_WORD_TYPE uint8_t
#define DDI_DISPLAY_WORDLENGTH WORDLENGTH_8BITS
#define DDI_DISPLAY_DATA_SWIZZLE HWD_BYTE_SWAP 
#endif

// Max width for the controller
#define DDI_DISPLAY_CONTROLLER_MAX_WIDTH 320

// Max height for the controller
#define DDI_DISPLAY_CONTROLLER_MAX_HEIGHT 240

// Max bytes per pixel
#define DDI_DISPLAY_CONTROLLER_MAX_BYTES_PER_PIXEL 2

//! Specifies how many DMA descriptors are allocated for the display driver.
//! This will determine the maximum size of the frame buffer that can be
//! transferred with one DMA transaction.  Each DMA descriptor is limited to
//! 64k bytes of data.
#define NUM_DMA_DESCRIPTORS (1 + \
    ((DDI_DISPLAY_CONTROLLER_MAX_WIDTH * DDI_DISPLAY_CONTROLLER_MAX_HEIGHT * \
     DDI_DISPLAY_CONTROLLER_MAX_BYTES_PER_PIXEL) / (64 * 1024))) 

//! Gpio configuration for video mode operation
#define GPIO_VSYNC_CONFIG_MASK (GPIO_MASK_SEL3 | GPIO_MASK_INPUT | GPIO_MASK_IRQ_RISING)

//! Interrupt vector for VSYNC
#define GPIO_VSYNC_IRQ_VECTOR VECTOR_IRQ_GPIO1

//! VSYNC interrupt enable/disable bit
#define GPIO_VSYNC_IRQ_BIT (0x00200000) // Bit 21 in GPIO bank 1 (LCD_BUSY)

//! VSYNC interrupt pin
#define GPIO_VSYNC_IRQ_PIN LCD_BUSY

//! Macro to enable the VSYNC interrupt
#define ENABLE_VSYNC_IRQ() HW_PINCTRL_PIN2IRQ1_SET(GPIO_VSYNC_IRQ_BIT) //HW_PINCTRL_IRQEN1_SET(GPIO_VSYNC_IRQ_BIT)

//! Macro to disable the VSYNC interrupt
#define DISABLE_VSYNC_IRQ() HW_PINCTRL_PIN2IRQ1_CLR(GPIO_VSYNC_IRQ_BIT) //HW_PINCTRL_IRQEN1_CLR(GPIO_VSYNC_IRQ_BIT)

//! Macro to check if the VSYNC IRQ status bit is set
#define CHECK_VSYNC_IRQ_STATUS() ( HW_PINCTRL_IRQSTAT1_RD() & GPIO_VSYNC_IRQ_BIT )

//! Macro to clear the VSYNC IRQ status
#define CLEAR_VSYNC_IRQ_STATUS() ( HW_PINCTRL_IRQSTAT1_CLR(GPIO_VSYNC_IRQ_BIT) )

//! Timeout value for the VSYNC signal
#define VSYNC_TIMEOUT_TICKS TX_WAIT_FOREVER

//! Driver output control register of the SSD1289
//! Entry mode register of the HX8347
typedef union _EntryMode 
{
    uint16_t V;
    struct {
        //uint8_t LG:3;
        //uint8_t AM:1;
        //uint8_t ID:2;
        //uint8_t TY:2;
        //uint8_t DMode:2;
        //uint8_t WMode:1;
        //uint8_t OEDef:1;
        //uint8_t TRANS:1;
        //uint8_t DFM:2;
        //uint8_t VSMode:1;
         uint8_t Reserved:3;
	 uint8_t BGR:1;
	 uint8_t ML:1;
	 uint8_t MV:1;
	 uint8_t MX:1;
	 uint8_t MY:1;
	 uint8_t Reserved1:8;
    } B;
} Hx8347aEntryMode;//SSD1289EntryMode;



//! Display control register of the SSD1289
typedef union _Hx8347aDisplayControl
{
    uint16_t V;
    struct {
        //uint8_t D0:1;
        //uint8_t D1:1;
        //uint8_t Reserved:1;
        //uint8_t CM:1;
        //uint8_t DTE:1;
        //uint8_t GON:1;
        //uint8_t Reserved2:2;
        //uint8_t SPT:1;
        //uint8_t VLE:2;
        //uint8_t PT:2;
        //uint8_t Reserved3:3;
         uint8_t Reserved:2;
	 uint8_t D0:1;
	 uint8_t D1:1;
	 uint8_t DTE:1;
	 uint8_t GON:1;
	 uint8_t PT0:1;
	 uint8_t PT1:1;
	 uint8_t Reserved1:8;
    } B;
} Hx8347aDisplayControl;//SSD1289DisplayControl;




////////////////////////////////////////////////////////////////////////////////
// Prototypes
////////////////////////////////////////////////////////////////////////////////

#ifdef RTOS_THREADX     // VSYNC only supported in threadx builds
//! Handler for the VSYNC interrupt
//static void ddi_display_controller_VsyncIsr(void *);
#endif

////////////////////////////////////////////////////////////////////////////////
// Variables
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Globals
////////////////////////////////////////////////////////////////////////////////

//! Current screen width in pixels, modified when display is rotated
uint16_t g_ddi_display_u16ScreenWidth = DDI_DISPLAY_DEFAULT_SIZE_HORIZONTAL;

//! Current screen height in pixels, modified when display is rotated
uint16_t g_ddi_display_u16ScreenHeight = DDI_DISPLAY_DEFAULT_SIZE_VERTICAL;

//! Number of DMA descriptors that the display driver has allocated.  This is
//! calculated with the NUM_DMA_DESCRIPTORS macro.  Even though this will not
//! change during run-time, it is stored as a variable to allow each controller
//! support module to define its own value and build as a lib.
uint8_t g_ddi_display_NumDmaDesc = NUM_DMA_DESCRIPTORS;

//! Array of DMA descriptors.  These descriptors will be chained together as
//! necessary for the amount of data required to transfer for each draw operation
hw_lcdif_DmaDesc_t g_ddi_display_DmaDescChain[NUM_DMA_DESCRIPTORS] __OCRAM_NCNB_DATA;

//! Pointer to the DMA descriptor chain.  Necessary to allow building as a lib
hw_lcdif_DmaDesc_t *g_ddi_display_pDmaDescChain = g_ddi_display_DmaDescChain;

//! Current video mode of the driver.
ddi_display_VideoMode_t g_ddi_display_VideoMode = DDI_DISPLAY_ASYNC_MODE;

#ifdef RTOS_THREADX     // VSYNC only supported in threadx builds
//! Semaphore for video mode operation
//static TX_SEMAPHORE *pVideoSemaphore = NULL;
#endif
////////////////////////////////////////////////////////////////////////////////
// Code
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//! \brief static delay function
//!
//! \fntype Function
//!
//! delay function
//! 
//!
////////////////////////////////////////////////////////////////////////////////
/*
static void delay(uint32_t u32DelayValue)
{
#if defined(DDI_DISPLAY_ALL_TX_DRIVERS) && defined(RTOS_THREADX)
    tx_thread_sleep(OS_MSECS_TO_TICKS(u32DelayValue));
#else
    volatile uint32_t i;
    //u32DelayValue = u32DelayValue*1000; //// *256;
    for( i = 0; i <u32DelayValue; i++ )
    {
#pragma asm
       nop
       nop ; tmptmp
       nop ; tmptmp
       nop ; tmptmp
       nop ; tmptmp
       nop ; tmptmp
       nop ; tmptmp
       nop ; tmptmp
       nop ; tmptmp
       nop ; tmptmp
#pragma endasm        
#endif
}
*/
void delay( uint32_t len )
{
    uint32_t StartTime, EndTime, ElapsedTime;
    StartTime = HW_DIGCTL_MICROSECONDS_RD();
    for( ;; )
      {
         EndTime = HW_DIGCTL_MICROSECONDS_RD(); 
         ElapsedTime = EndTime - StartTime ; 
         if( ElapsedTime >len)
              break;
       }
}

////////////////////////////////////////////////////////////////////////////////
//! \brief Writes a single command or param/data byte to the controller
//!
//! \fntype Function
//!
//! \param[in] eCommMode - CMD_MODE or DATA_MODE specifier
//! \param[in] u16Command- Command or param/data to send
//!
//! This function sends a single byte to the display controller
//!
////////////////////////////////////////////////////////////////////////////////
void WriteDirect(hw_lcdif_CommMode_t eCommMode, uint16_t u16Command)
{
    uint32_t u32Command = u16Command;
#ifdef DEBUG
    RtStatus_t ret1 = SUCCESS;
    RtStatus_t ret2 = SUCCESS;
#endif

    // For 8-bit bus, separate the 16-bit data into two 8-bits 
    uint32_t u32Data0 = u16Command & 0xFF;
    uint32_t u32Data1 = ((u16Command & 0xFF00)>>8);     

    switch( ddi_lcdif_GetDataSwizzle() )
    {
        case NO_SWAP:
            // Leave the data as is
            break;
        case HWD_BYTE_SWAP:    // Swap bytes within each half-word
            // Move command byte to upper half of lower 16-bit word
            u32Command <<= 8;
            u32Data0 <<= 8;
            u32Data1 <<= 8;
            break;
        case HWD_SWAP:         // Swap half-words
            // Move command byte to lower half of upper 16-bit word
            u32Command <<= 16;
            u32Data0 <<= 16;
            u32Data1 <<= 16;
            break;
        case SWAP_ALL_BYTES:   // Swap bytes 0,3 and 1,2
            // Move command byte to upper half of upper 16-bit word
            u32Command <<= 24;
            u32Data0 <<= 24;
            u32Data1 <<= 24;
            break;
        default:
            SystemHalt();      // Programming error
    }

    if(eCommMode==CMD_MODE)
    {
        // 8- and 16-bit bus have same command sizes
    #ifdef DEBUG
        ret1 =
    #endif
	    ddi_lcdif_WriteDirect(eCommMode, (void *)&u32Command, sizeof(DDI_DISPLAY_WORD_TYPE));
    }
    else if(eCommMode==DATA_MODE)
    {
        
        if(WORDLENGTH_8BITS == hw_lcdif_GetWordLength())
        {
            // For 8-bit, we need to send data in two 8 bit parts
    #ifdef DEBUG
        ret1 =
    #endif
            ddi_lcdif_WriteDirect(eCommMode, (void *)&u32Data1, sizeof(DDI_DISPLAY_WORD_TYPE));
    #ifdef DEBUG
        ret2 =
    #endif    
    	    ddi_lcdif_WriteDirect(eCommMode, (void *)&u32Data0, sizeof(DDI_DISPLAY_WORD_TYPE));
        }
        else

⌨️ 快捷键说明

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