📄 ddi_display_controller_ssd1339.c
字号:
////////////////////////////////////////////////////////////////////////////////
//! \fn static void InitPwmBacklight(void)
//!
//! \brief Sets up the PWM backlight control signal
//!
//! \fntype Function
//!
//! Inits the PWM hardware block and sets up the GPIOs for PWM mode.
//! The initial backlight frequency is set, but the duty cycle is set to zero
//!
////////////////////////////////////////////////////////////////////////////////
static void InitPwmBacklight(void)
{
// variables for alkaline mode since it can't power full brighness
#if defined(DDI_DISPLAY_ALL_TX_DRIVERS) && defined(RTOS_THREADX)
RtStatus_t ret;
#endif
// Check for boost mode configuration
if(BF_RD(POWER_STS, MODE)==3)
{
u8MinBrightnessPercentage = ALKALINE_MIN_BRIGHTNESS_PERCENTAGE;
u8MaxBrightnessPercentage = ALKALINE_MAX_BRIGHTNESS_PERCENTAGE;
}
else
{
u8MinBrightnessPercentage = MIN_BRIGHTNESS_PERCENTAGE;
u8MaxBrightnessPercentage = MAX_BRIGHTNESS_PERCENTAGE;
}
if( !(ddi_etm_IsPresent()) ) {
//** configure OLED shutdown GPIO **
// set MUX to GPIO
OLED_SHUTDOWN_MUXSEL_SET(OLED_SHUTDOWN_MUXSEL_MASK);
// set drive current to 4mA
OLED_SHUTDOWN_DRIVE_CLR(OLED_SHUTDOWN_PINCTRL_MASK);
// set output value 0 to turn off step-up
OLED_SHUTDOWN_DOUT_CLR(OLED_SHUTDOWN_PINCTRL_MASK);
// enable output value to drive pin
OLED_SHUTDOWN_DOE_SET(OLED_SHUTDOWN_PINCTRL_MASK);
}
#if defined(DDI_DISPLAY_ALL_TX_DRIVERS) && defined(RTOS_THREADX)
// Grab PWM for backlight use
// Assume GPIO driver has already been initialized
ret = ddi_pwm_ChLock(1<<DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL);
assert(!ret);
// Set the initial params, 0% duty cycle
ret = ddi_pwm_ChSetConfig((hw_pwm_Channel_t)DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL,
PWM_STATE_HIGH,
PWM_STATE_LOW,
BACKLIGHT_PWM_FREQ, 0);
assert(!ret);
ddi_pwm_ChOutputEnable(1<<DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL, true);
#else
// Do a raw init of the PWM GPIO
if( !(ddi_etm_IsPresent()) ) {
HW_PINCTRL_MUXSEL6_CLR(0x00300000 << (2*DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL));
}
// Set up the backlight
BF_CLR(PWM_CTRL, SFTRST);
BF_CLR(PWM_CTRL, CLKGATE);
HW_PWMn_ACTIVE_WR(DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL, 0);
BF_CS5n(PWMn_PERIOD, DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL,
MATT, 0,
CDIV, BACKLIGHT_PWM_CDIV,
INACTIVE_STATE, BV_PWMn_PERIOD_INACTIVE_STATE__0,
ACTIVE_STATE, BV_PWMn_PERIOD_ACTIVE_STATE__1,
PERIOD, BACKLIGHT_PWM_PERIOD);
HW_PWM_CTRL_CLR(1 << DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL);
#endif
}
////////////////////////////////////////////////////////////////////////////////
//! \fn static void SendControllerInitSeq(gfx_BitmapTypeEnum_t eBitmapType, uint32_t u32Width, uint32_t u32Height)
//!
//! \brief Sends commands to initialize the controller from reset
//!
//! \fntype Function
//!
//! \param[in] eBitmapType - Graphics color format specifier
//! \param[in] u32Width - Desired screen width setting
//! \param[in] u32Height - Desired screen height setting
//!
//! This function sends commands to initialize the controller after it has
//! been taken out of reset.
//!
//! \retval SUCCESS No error
//!
//! \retval ERROR_DDI_DISPLAY_CONTROLLER_BITMAP_TYPE_UNSUPPORTED - This
//! controller does not support the given bitmap color type
//!
//! \retval ERROR_DDI_DISPLAY_CONTROLLER_SCREEN_SIZE - This
//! controller does not support the given screen dimensions
//!
////////////////////////////////////////////////////////////////////////////////
static void SendControllerInitSeq(gfx_BitmapTypeEnum_t eBitmapType, uint32_t u32Width, uint32_t u32Height)
{
//Init command
WriteDirect(CMD_MODE, 0xAE); // Display off
WriteDirect(CMD_MODE, 0xCA); // Set MUX ratio = 1/128 duty
WriteDirect(DATA_MODE, 0x7F);
WriteDirect(CMD_MODE, 0xA1); // Display start line = 0
WriteDirect(DATA_MODE, 0x00);
WriteDirect(CMD_MODE, 0xA2); // Display offset = 0
WriteDirect(DATA_MODE, 0x80);
WriteDirect(CMD_MODE, 0xA0); // Set Re-Map = 65K color 16bit
WriteDirect(DATA_MODE, 0x74);
WriteDirect(CMD_MODE, 0xC7); // Master current control
WriteDirect(DATA_MODE, MIN_BRIGHTNESS); // 0x03 for low brightness
// 0x06 for typical brightness
// 0x09 for high brightness
WriteDirect(CMD_MODE, 0xC1); // contrast level for R,G,B
WriteDirect(DATA_MODE, TYP_RED_CONTRAST); // Red contrast set
WriteDirect(DATA_MODE, TYP_GREEN_CONTRAST); // Green contrast set
WriteDirect(DATA_MODE, TYP_BLUE_CONTRAST); // Blue contrast set
WriteDirect(CMD_MODE, 0xB1); // Phase adjust
WriteDirect(DATA_MODE, 0x1F);
#ifdef UNIVISION
WriteDirect(CMD_MODE, 0xBE); // Phase adjust
WriteDirect(DATA_MODE, 0x40);
#endif
WriteDirect(CMD_MODE, 0xB3); // Frame rate = 85Hz
#ifdef UNIVISION
WriteDirect(DATA_MODE, 0x60);
#else
WriteDirect(DATA_MODE, 0x10);
#endif
WriteDirect(CMD_MODE, 0xBB); // Set pre-charge level for R,G,B
WriteDirect(DATA_MODE, 0x00); // red
WriteDirect(DATA_MODE, 0x00); // green
WriteDirect(DATA_MODE, 0x00); // blue
WriteDirect(CMD_MODE, 0xAD); // master configuration
WriteDirect(DATA_MODE, 0x8E);
WriteDirect(CMD_MODE, 0xB0); // Current saving
#ifdef UNIVISION
WriteDirect(DATA_MODE, 0x00);
WriteDirect(CMD_MODE, 0xb8); // Current saving
WriteDirect(DATA_MODE, 1);
WriteDirect(DATA_MODE, 3);
WriteDirect(DATA_MODE, 5);
WriteDirect(DATA_MODE, 7);
WriteDirect(DATA_MODE, 11);
WriteDirect(DATA_MODE, 16);
WriteDirect(DATA_MODE, 22);
WriteDirect(DATA_MODE, 26);
WriteDirect(DATA_MODE, 31);
WriteDirect(DATA_MODE, 36);
WriteDirect(DATA_MODE, 41);
WriteDirect(DATA_MODE, 46);
WriteDirect(DATA_MODE, 51);
WriteDirect(DATA_MODE, 56);
WriteDirect(DATA_MODE, 61);
WriteDirect(DATA_MODE, 66);
WriteDirect(DATA_MODE, 71);
WriteDirect(DATA_MODE, 76);
WriteDirect(DATA_MODE, 81);
WriteDirect(DATA_MODE, 86);
WriteDirect(DATA_MODE, 91);
WriteDirect(DATA_MODE, 96);
WriteDirect(DATA_MODE, 101);
WriteDirect(DATA_MODE, 104);
WriteDirect(DATA_MODE, 107);
WriteDirect(DATA_MODE, 110);
WriteDirect(DATA_MODE, 113);
WriteDirect(DATA_MODE, 116);
WriteDirect(DATA_MODE, 119);
WriteDirect(DATA_MODE, 122);
WriteDirect(DATA_MODE, 123);
WriteDirect(DATA_MODE, 125);
#else
WriteDirect(DATA_MODE, 0x05);
#endif
WriteDirect(CMD_MODE, 0xA6); // Normal display
#if 0
WriteDirect(CMD_MODE, 0x9e);
WriteDirect(CMD_MODE, 0x96);
WriteDirect(DATA_MODE, 0);
WriteDirect(DATA_MODE, 0);
WriteDirect(DATA_MODE, 127);
WriteDirect(DATA_MODE, 0);
WriteDirect(DATA_MODE, 1);
WriteDirect(CMD_MODE, 0x9f);
#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)
{
if( bOn )
{
if( !( OLED_SHUTDOWN_DOUT_RD() & OLED_SHUTDOWN_PINCTRL_MASK ) )
{
// turn on Vcc step-up
OLED_SHUTDOWN_DOUT_SET(OLED_SHUTDOWN_PINCTRL_MASK);
delay(20);
WriteDirect(CMD_MODE, 0xAF); // Display On
}
}
else
{
if( ( OLED_SHUTDOWN_DOUT_RD() & OLED_SHUTDOWN_PINCTRL_MASK ) )
{
WriteDirect(CMD_MODE, 0xAE); // Display off
delay(1);
// turn off Vcc step-up
OLED_SHUTDOWN_DOUT_CLR(OLED_SHUTDOWN_PINCTRL_MASK);
delay(20);
}
}
// Enable or disable the backlight PWM as necessary
#if defined(DDI_DISPLAY_ALL_TX_DRIVERS) && defined(RTOS_THREADX)
ddi_pwm_ChOutputEnable(1<<DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL, bOn);
#else
if( bOn )
HW_PWM_CTRL_SET(1 << DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL);
else
HW_PWM_CTRL_CLR(1 << DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL);
#endif
}
////////////////////////////////////////////////////////////////////////////////
//! \brief Enters/exits low power mode
//!
//! \fntype Function
//!
//! \param[in] bOn - true to set low power mode, false to exit low power mode
//!
//! FIXME!!! comment me
//!
////////////////////////////////////////////////////////////////////////////////
static void SetControllerLowPowerMode(bool bOn)
{
if( bOn )
{
SendControllerOutputEnable(false);
ddi_lcdif_Shutdown(true);
}
else
{
RtStatus_t ret = SUCCESS;
hw_lcdif_Init_t LcdifInit;
// Get the LCDIF init struct to send to the LCDIF DDI init function
ret = ddi_display_controller_GetLcdifInitStruct(&LcdifInit, g_ddi_display_eBitmapType);
assert(!ret);
// Run the low level init on the LCDIF
ret = ddi_lcdif_Init(&LcdifInit, g_ddi_display_pDmaDescChain, 1);
assert(!ret);
#if defined(RTOS_THREADX)
ddi_lcdif_RegisterCompletionCallback(&g_ddi_display_DmaCompletionCallback);
#endif
// Init the display controller, use last set width/height
ret = ddi_display_controller_SendCommand(DDI_DISPLAY_CONTROLLER_INIT,
g_ddi_display_eBitmapType,
g_ddi_display_u16ScreenWidth,
g_ddi_display_u16ScreenHeight);
assert(!ret);
}
}
////////////////////////////////////////////////////////////////////////////////
//! \fn static void SendControllerContrast(uint32_t u32Percentage)
//!
//! \brief Sets the specified contrast percentage on the display
//!
//! \fntype Function
//!
//! \param[in] u32Percentage - Percent total contrast from 0 -> 100
//!
//! This function sends commands to the controller to set the desired contrast
//! percentage.
//!
////////////////////////////////////////////////////////////////////////////////
static void SendControllerContrast(uint32_t u32Percentage)
{
DDI_DISPLAY_WORD_TYPE Contrast;
WriteDirect(CMD_MODE, 0xC1);
Contrast = MIN_RED_CONTRAST + (((MAX_RED_CONTRAST-MIN_RED_CONTRAST)*u32Percentage )/100);
WriteDirect(DATA_MODE, Contrast);
Contrast = MIN_GREEN_CONTRAST + (((MAX_GREEN_CONTRAST-MIN_GREEN_CONTRAST)*u32Percentage )/100);
WriteDirect(DATA_MODE, Contrast);
Contrast = MIN_BLUE_CONTRAST + (((MAX_BLUE_CONTRAST-MIN_BLUE_CONTRAST)*u32Percentage )/100);
WriteDirect(DATA_MODE, Contrast);
}
////////////////////////////////////////////////////////////////////////////////
//! \fn static void SetPwmBrightness(uint32_t u32Percentage)
//!
//! \brief Sets the specified brightness percentage on the display
//!
//! \fntype Function
//!
//! \param[in] u32Percentage - Percent total contrast from 0 -> 100
//!
//! Sets the PWM backlight control channel according to the given brightness
//! percentage value.
//!
////////////////////////////////////////////////////////////////////////////////
static void SetPwmBrightness(uint32_t u32Percentage)
{
#if defined(DDI_DISPLAY_ALL_TX_DRIVERS) && defined(RTOS_THREADX)
RtStatus_t ret = SUCCESS;
uint8_t u8Value;
if( u32Percentage > 100 )
u32Percentage = 100;
u8Value = MIN_BRIGHTNESS + (((MAX_BRIGHTNESS-MIN_BRIGHTNESS)*u32Percentage )/100);
WriteDirect(CMD_MODE, 0xC7);
WriteDirect(DATA_MODE, u8Value);
ret = ddi_pwm_ChSetDutyCycle((hw_pwm_Channel_t)DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL,
PWM_STATE_HIGH,
PWM_STATE_LOW,
u8MinBrightnessPercentage +
(( u32Percentage *
(u8MaxBrightnessPercentage - u8MinBrightnessPercentage))/100 ));
assert(!ret);
#else
uint32_t u32InactivePeriod;
uint8_t u8Value;
// Set the raw values in the PWM registers
if( u32Percentage > 100 )
u32Percentage = 100;
u8Value = MIN_BRIGHTNESS + (((MAX_BRIGHTNESS-MIN_BRIGHTNESS)*u32Percentage )/100);
WriteDirect(CMD_MODE, 0xC7);
WriteDirect(DATA_MODE, u8Value);
u32InactivePeriod = ((BACKLIGHT_PWM_PERIOD * u8MinBrightnessPercentage)/100) +
(( ((BACKLIGHT_PWM_PERIOD * (u8MaxBrightnessPercentage - u8MinBrightnessPercentage))/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);
HW_PWMn_PERIOD_SET(DDI_DISPLAY_BACKLIGHT_PWM_CHANNEL, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -