📄 ddi_display_controller_ssd1339.c
字号:
////////////////////////////////////////////////////////////////////////////////
//! \addtogroup ddi_display
//! @{
//
// Copyright (c) 2004-2005 SigmaTel, Inc.
//
//! \file ddi_display_controller_tl1771.c
//! \brief Structures and code specific to the Tomato LSI TL1771 controller
//! \version 0.1
//! \date 08/2005
//!
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// 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 "..\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 <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 <drivers\ddi_etm.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
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//#define EVK_BOARD
#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 5
#endif
#ifndef DDI_DISPLAY_DATA_HOLD_XCLKS
#define DDI_DISPLAY_DATA_HOLD_XCLKS 5
#endif
#ifndef DDI_DISPLAY_CMD_SETUP_XCLKS
#define DDI_DISPLAY_CMD_SETUP_XCLKS 5
#endif
#ifndef DDI_DISPLAY_CMD_HOLD_XCLKS
#define DDI_DISPLAY_CMD_HOLD_XCLKS 5
#endif
#ifndef DDI_DISPLAY_DEFAULT_SIZE_HORIZONTAL
#define DDI_DISPLAY_DEFAULT_SIZE_HORIZONTAL 128
#endif
#ifndef DDI_DISPLAY_DEFAULT_SIZE_VERTICAL
#define DDI_DISPLAY_DEFAULT_SIZE_VERTICAL 128
#endif
//! Typical contrast value set in hardware
#define TYP_RED_CONTRAST 0x6F
#define TYP_GREEN_CONTRAST 0x58
#define TYP_BLUE_CONTRAST 0x80
//! Minimum contrast value set in hardware
#define MIN_RED_CONTRAST (TYP_RED_CONTRAST - ((TYP_RED_CONTRAST+5)/10)*2)
#define MIN_GREEN_CONTRAST (TYP_GREEN_CONTRAST - ((TYP_GREEN_CONTRAST+5)/10)*2)
#define MIN_BLUE_CONTRAST (TYP_BLUE_CONTRAST - ((TYP_BLUE_CONTRAST+5)/10)*2)
//! Maximum contrast value set in hardware
#define MAX_RED_CONTRAST (TYP_RED_CONTRAST + ((TYP_RED_CONTRAST+5)/10)*2)
#define MAX_GREEN_CONTRAST (TYP_GREEN_CONTRAST + ((TYP_GREEN_CONTRAST+5)/10)*2)
#define MAX_BLUE_CONTRAST (TYP_BLUE_CONTRAST + ((TYP_BLUE_CONTRAST+5)/10)*2)
//! Minimum brightness value set in hardware
#define MIN_BRIGHTNESS 0x03
//! Maximum brightness value set in hardware
#define MAX_BRIGHTNESS 0x09
#ifdef EVK_BOARD
//! Min allowed brightness percentage
#define MIN_BRIGHTNESS_PERCENTAGE 80
//! Alkaline batttery can't support the power needed for high brightness
#define ALKALINE_MIN_BRIGHTNESS_PERCENTAGE 80
//! Max allowed brightness percentage
#define MAX_BRIGHTNESS_PERCENTAGE 100
//! Alkaline batttery can't support the power needed for high brightness
#define ALKALINE_MAX_BRIGHTNESS_PERCENTAGE 100
#define OLED_SHUTDOWN_MUXSEL_MASK (0x00C00000)
#define OLED_SHUTDOWN_PINCTRL_MASK (1<<(11))
#define OLED_SHUTDOWN_MUXSEL_SET HW_PINCTRL_MUXSEL6_SET
#define OLED_SHUTDOWN_DRIVE_CLR HW_PINCTRL_DRIVE3_CLR
#define OLED_SHUTDOWN_DOUT_SET HW_PINCTRL_DOUT3_SET
#define OLED_SHUTDOWN_DOUT_CLR HW_PINCTRL_DOUT3_CLR
#define OLED_SHUTDOWN_DOUT_RD HW_PINCTRL_DOUT3_RD
#define OLED_SHUTDOWN_DOE_SET HW_PINCTRL_DOE3_SET
#else
//! Min allowed brightness percentage
#define MIN_BRIGHTNESS_PERCENTAGE 10
//! 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 80
//! Alkaline batttery can't support the power needed for high brightness
#define ALKALINE_MAX_BRIGHTNESS_PERCENTAGE 20
#define OLED_SHUTDOWN_MUXSEL_MASK (0x0C000000)
#define OLED_SHUTDOWN_PINCTRL_MASK (1<<(29))
#define OLED_SHUTDOWN_MUXSEL_SET HW_PINCTRL_MUXSEL1_SET
#define OLED_SHUTDOWN_DRIVE_CLR HW_PINCTRL_DRIVE0_CLR
#define OLED_SHUTDOWN_DOUT_SET HW_PINCTRL_DOUT0_SET
#define OLED_SHUTDOWN_DOUT_CLR HW_PINCTRL_DOUT0_CLR
#define OLED_SHUTDOWN_DOUT_RD HW_PINCTRL_DOUT0_RD
#define OLED_SHUTDOWN_DOE_SET HW_PINCTRL_DOE0_SET
#endif
#if defined(DDI_DISPLAY_ALL_TX_DRIVERS) && defined(RTOS_THREADX)
//! Defines the frequency of the backlight PWM control signal
#define BACKLIGHT_PWM_FREQ 12000000
#else
//! Defines the CDIV value for OS independent PWM control
#define BACKLIGHT_PWM_CDIV BV_PWMn_PERIOD_CDIV__DIV_1
//! Defines the period in divided clocks for OS independent PWM control
#define BACKLIGHT_PWM_PERIOD 20
#endif
//! Command byte to set the horizontal position register
#define DDI_DISPLAY_HORZ_REGION_CMD 0x15
//! Command byte to set the vertical position register
#define DDI_DISPLAY_VERT_REGION_CMD 0x75
#ifdef EVK_BOARD
//! The first visible row of the display
#define DDI_DISPLAY_START_ROW 0
//! The first visible column of the display
#define DDI_DISPLAY_START_COLUMN 0
#else
//! The first visible row of the display
#define DDI_DISPLAY_START_ROW 0
//! The first visible column of the display
#define DDI_DISPLAY_START_COLUMN 0
#endif
// 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
//todo: check the DDI_DISPLAY_DATA_SWIZZLE
#define DDI_DISPLAY_DATA_SWIZZLE HWD_BYTE_SWAP
#endif
// Max width for the controller
#define DDI_DISPLAY_CONTROLLER_MAX_WIDTH 128
// Max height for the controller
#define DDI_DISPLAY_CONTROLLER_MAX_HEIGHT 128
// 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) / (HW_LCDIF_MAX_DMA_BYTE_COUNT)))
////////////////////////////////////////////////////////////////////////////////
// Prototypes
////////////////////////////////////////////////////////////////////////////////
static void SendControllerOutputEnable(bool bOn);
static void SetPwmBrightness(uint32_t u32Percentage);
////////////////////////////////////////////////////////////////////////////////
// Variables
////////////////////////////////////////////////////////////////////////////////
// variables for alkaline mode since it can't power full brighness
static uint8_t u8MaxBrightnessPercentage;
static uint8_t u8MinBrightnessPercentage;
//TODO: Will remove
bool PicAdjust = FALSE;
int newStartColumn = 0;
int newStartRow = 0;
int newMaxHeight = 0;
int newMaxWidth = 0;
////////////////////////////////////////////////////////////////////////////////
// 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;
////////////////////////////////////////////////////////////////////////////////
// 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
uint32_t i;
u32DelayValue = u32DelayValue*256;
for( i = 0; i < u32DelayValue; i++ )
{
#pragma asm
nop
#pragma endasm
}
#endif
}
////////////////////////////////////////////////////////////////////////////////
//! \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] u8CommandByte - Command or param/data to send
//!
//! This function sends a single byte to the display controller
//!
////////////////////////////////////////////////////////////////////////////////
void WriteDirect(hw_lcdif_CommMode_t eCommMode, uint8_t u8CommandByte)
{
uint32_t u32Command = u8CommandByte;
RtStatus_t ret;
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;
break;
case HWD_SWAP: // Swap half-words
// Move command byte to lower half of upper 16-bit word
u32Command <<= 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;
break;
default:
SystemHalt(); // Programming error
}
ret = ddi_lcdif_WriteDirect(eCommMode, (void *)&u32Command, sizeof(DDI_DISPLAY_WORD_TYPE));
assert(!ret);
}
////////////////////////////////////////////////////////////////////////////////
//! \fn RtStatus_t ddi_display_controller_GetLcdifInitStruct(hw_lcdif_Init_t *pInit, gfx_BitmapTypeEnum_t eBitmapType)
//!
//! \brief Copies the LCDIF init struct that corresponds to the given color format
//!
//! \fntype Function
//!
//! \param[in,out] pInit - Pointer to init struct to copy to
//! \param[in] eBitmapType - Graphics color format specifier
//!
//! \retval SUCCESS No error
//!
//! \retval ERROR_DDI_DISPLAY_CONTROLLER_BITMAP_TYPE_UNSUPPORTED - This
//! controller does not support the given bitmap color type
//!
//! This function is implemented per controller or display. The appropriate
//! LCDIF init parameters are copied to the given init struct pointer according
//! to the type of color format is specified. Not all controllers/displays are
//! capable of all color formats, so this function may return an error
//! indicating that the given color format is not supported.
//!
////////////////////////////////////////////////////////////////////////////////
RtStatus_t ddi_display_controller_GetLcdifInitStruct(hw_lcdif_Init_t *pInit, gfx_BitmapTypeEnum_t eBitmapType)
{
//! Init structure for LCDIF, may be loaded from a resource
hw_lcdif_Init_t LcdifInit =
{
//! No busy line, no byte-swapping, bring LCD module out of reset
false, //! m_bBusyEnable
DDI_DISPLAY_DATA_SWIZZLE, //! m_eDataSwizzle
LCDRESET_HIGH, //! m_eReset
BUSMODE_8080, //! m_eBusMode
DDI_DISPLAY_WORDLENGTH, //! m_eWordLength
//! Bus timing info
//! 1XCLK ~= 168ns
{
DDI_DISPLAY_DATA_SETUP_XCLKS, //! m_u8DataSetup
DDI_DISPLAY_DATA_HOLD_XCLKS, //! m_u8DataHold
DDI_DISPLAY_CMD_SETUP_XCLKS, //! m_u8CmdSetup
DDI_DISPLAY_CMD_HOLD_XCLKS, //! m_u8CmdHold
}
};
#ifdef DDI_LCDIF_WORDLENGTH_16BITS
if( BITMAP_TYPE_16BPP_565 != eBitmapType )
return ERROR_DDI_DISPLAY_CONTROLLER_BITMAP_TYPE_UNSUPPORTED;
#else
if( BITMAP_TYPE_18BPP_666 != eBitmapType &&
BITMAP_TYPE_16BPP_565 != eBitmapType )
return ERROR_DDI_DISPLAY_CONTROLLER_BITMAP_TYPE_UNSUPPORTED;
#endif
memcpy(pInit, &LcdifInit, sizeof(hw_lcdif_Init_t));
return SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -