1211 lines
32 KiB
C
Executable File
1211 lines
32 KiB
C
Executable File
// Copyright 2020-2021 Beken
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include <stdlib.h>
|
|
#include <common/bk_include.h>
|
|
#include <os/mem.h>
|
|
#include <os/str.h>
|
|
#include <math.h>
|
|
#include "arch_interrupt.h"
|
|
#include "lcd_disp_hal.h"
|
|
#include <driver/lcd.h>
|
|
#include "gpio_driver.h"
|
|
#include <driver/gpio.h>
|
|
#include "gpio_map.h"
|
|
#include <driver/int.h>
|
|
#include "sys_driver.h"
|
|
#include <driver/hal/hal_gpio_types.h>
|
|
#include <driver/hal/hal_lcd_types.h>
|
|
#include <driver/timer.h>
|
|
#include <driver/lcd_spi.h>
|
|
#include <driver/pwm.h>
|
|
#include <driver/gpio.h>
|
|
#include <driver/flash.h>
|
|
#include "driver/lcd.h"
|
|
#include "driver/pwr_clk.h"
|
|
|
|
#if CONFIG_LCD_QSPI
|
|
#include <driver/lcd_qspi.h>
|
|
#include <driver/lcd_qspi_types.h>
|
|
#endif
|
|
|
|
#define TAG "lcd_drv"
|
|
|
|
#if CONFIG_SOC_BK7256XX
|
|
#define MINOOR_ITCM __attribute__((section(".itcm_sec_code ")))
|
|
#else
|
|
#define MINOOR_ITCM
|
|
#endif
|
|
|
|
#if CONFIG_SOC_BK7256XX
|
|
#define LCD_BACKLIGHT_PWM_RGB PWM_ID_1
|
|
#define LCD_BACKLIGHT_PWM_QSPI PWM_ID_2
|
|
#define LCD_BACKLIGHT_GPIO_RGB GPIO_7
|
|
#define LCD_BACKLIGHT_GPIO_QSPI GPIO_8
|
|
#endif
|
|
|
|
#if CONFIG_SOC_BK7236XX
|
|
#define LCD_BACKLIGHT_PWM PWM_ID_1
|
|
#define LCD_BACKLIGHT_GPIO GPIO_7
|
|
#endif
|
|
|
|
#define IO_FUNCTION_ENABLE(pin, func) \
|
|
do { \
|
|
gpio_dev_unmap(pin); \
|
|
gpio_dev_map(pin, func); \
|
|
bk_gpio_enable_output(pin); \
|
|
bk_gpio_set_capacity(pin,GPIO_DRIVER_CAPACITY_1); \
|
|
} while (0)
|
|
|
|
#define IO_FUNCTION_ENABLE_I8080(pin, func) \
|
|
do { \
|
|
gpio_dev_unmap(pin); \
|
|
gpio_dev_map(pin, func); \
|
|
bk_gpio_enable_output(pin); \
|
|
bk_gpio_set_capacity(pin,GPIO_DRIVER_CAPACITY_3); \
|
|
} while (0)
|
|
|
|
//set high impedance
|
|
#define IO_FUNCTION_UNMAP(pin) \
|
|
do { \
|
|
gpio_dev_unmap(pin); \
|
|
} while (0)
|
|
|
|
#define LCD_RETURN_ON_NOT_INIT() do {\
|
|
if (!s_lcd_driver_is_init) {\
|
|
return BK_ERR_LCD_NOT_INIT;\
|
|
}\
|
|
} while(0)
|
|
#define BK_RETURN_ON_NULL(_x) do {\
|
|
if (!(_x)) {\
|
|
BK_LOGE(ERR_TAG, "Null %s\n", __FUNCTION__);\
|
|
return BK_ERR_NULL_PARAM;\
|
|
}\
|
|
} while(0)
|
|
|
|
static bool s_lcd_driver_is_init = false;
|
|
|
|
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
|
|
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
|
|
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
|
|
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
|
|
|
|
extern u64 riscv_get_mtimer(void);
|
|
|
|
typedef struct
|
|
{
|
|
#if (USE_LCD_REGISTER_CALLBACKS == 1) //register callback
|
|
lcd_isr_t lcd_8080_frame_start_handler;
|
|
lcd_isr_t lcd_8080_frame_end_handler;
|
|
lcd_isr_t lcd_rgb_frame_end_handler;
|
|
lcd_isr_t lcd_rgb_frame_start_handler;
|
|
lcd_isr_t lcd_rgb_de_handler;
|
|
lcd_isr_t lcd_rgb_frame_interval_handler;
|
|
#endif
|
|
const lcd_device_t device; /**< lcd device config */
|
|
} lcd_driver_t;
|
|
|
|
static lcd_driver_t s_lcd = {0};
|
|
static const lcd_device_t **devices_list = NULL;
|
|
static uint16_t devices_size = 0;
|
|
|
|
const lcd_device_t **get_lcd_devices_list(void)
|
|
{
|
|
return devices_list;
|
|
}
|
|
|
|
uint32_t get_lcd_devices_num(void)
|
|
{
|
|
return devices_size;
|
|
}
|
|
|
|
const lcd_device_t * get_lcd_device_by_name(char * name)
|
|
{
|
|
uint32_t i;
|
|
|
|
LOGI("%s, devices: %d\n", __func__, devices_size);
|
|
|
|
for (i = 0; i < devices_size; i++)
|
|
{
|
|
if (os_strcmp(devices_list[i]->name, name) == 0)
|
|
{
|
|
LOGI("%s, name: %s\n", __func__, devices_list[i]->name);
|
|
return devices_list[i];
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
const lcd_device_t *get_lcd_device_by_ppi(media_ppi_t ppi)
|
|
{
|
|
uint32_t i;
|
|
|
|
LOGI("%s, devices: %d\n", __func__, devices_size);
|
|
|
|
for (i = 0; i < devices_size; i++)
|
|
{
|
|
if (devices_list[i]->ppi == ppi)
|
|
{
|
|
LOGI("%s, name: %s\n", __func__, devices_list[i]->name);
|
|
return devices_list[i];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const lcd_device_t *get_lcd_device_by_id(lcd_device_id_t id)
|
|
{
|
|
uint32_t i;
|
|
|
|
for (i = 0; i < devices_size; i++)
|
|
{
|
|
if (devices_list[i]->id == id)
|
|
{
|
|
return devices_list[i];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void bk_lcd_set_devices_list(const lcd_device_t **list, uint16_t size)
|
|
{
|
|
devices_list = list;
|
|
devices_size = size;
|
|
}
|
|
|
|
|
|
int32_t lcd_driver_get_spi_gpio(LCD_SPI_GPIO_TYPE_E gpio_type)
|
|
{
|
|
int32_t gpio_value = 0;
|
|
switch(gpio_type)
|
|
{
|
|
case SPI_GPIO_CLK:
|
|
if(s_lcd.device.id == LCD_DEVICE_ST7701S) //480X480
|
|
{
|
|
#if CONFIG_SOC_BK7256XX
|
|
gpio_value = GPIO_35;
|
|
#elif CONFIG_SOC_BK7236XX
|
|
gpio_value = GPIO_0;
|
|
#endif
|
|
}
|
|
else if (s_lcd.device.id == LCD_DEVICE_NT35510) //custom
|
|
{
|
|
gpio_value = GPIO_2;
|
|
}
|
|
else
|
|
{
|
|
#if CONFIG_SOC_BK7256
|
|
gpio_value = GPIO_9;
|
|
#else //bk7258
|
|
gpio_value = GPIO_0;
|
|
#endif
|
|
}
|
|
break;
|
|
case SPI_GPIO_CSX:
|
|
if(s_lcd.device.id == LCD_DEVICE_ST7701S)
|
|
{
|
|
#if CONFIG_SOC_BK7256XX
|
|
gpio_value = GPIO_34;
|
|
#elif CONFIG_SOC_BK7236XX
|
|
gpio_value = GPIO_12;
|
|
#endif
|
|
}
|
|
else if (s_lcd.device.id == LCD_DEVICE_NT35510) //custom
|
|
{
|
|
gpio_value = GPIO_3;
|
|
}
|
|
else
|
|
{
|
|
gpio_value = GPIO_12;
|
|
}
|
|
break;
|
|
case SPI_GPIO_SDA:
|
|
if(s_lcd.device.id == LCD_DEVICE_ST7701S) {
|
|
#if CONFIG_SOC_BK7256XX
|
|
gpio_value = GPIO_36;
|
|
#elif CONFIG_SOC_BK7236XX
|
|
gpio_value = GPIO_1;
|
|
#endif
|
|
} else if (s_lcd.device.id == LCD_DEVICE_NT35510) //custom
|
|
gpio_value = GPIO_4;
|
|
else
|
|
{
|
|
#if CONFIG_SOC_BK7256
|
|
gpio_value = GPIO_8;
|
|
#else
|
|
gpio_value = GPIO_1;
|
|
#endif
|
|
}
|
|
break;
|
|
case SPI_GPIO_RST:
|
|
if(s_lcd.device.id == LCD_DEVICE_ST7701S)
|
|
gpio_value = GPIO_15;
|
|
else
|
|
gpio_value = GPIO_6;
|
|
break;
|
|
default:
|
|
LOGE("%s can't support this gpio type:%d\r\n", __FUNCTION__, __LINE__);
|
|
break;
|
|
}
|
|
|
|
return gpio_value;
|
|
}
|
|
|
|
bk_err_t lcd_mcu_gpio_init(void)
|
|
{
|
|
LOGI("%s\n", __func__);
|
|
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D0_PIN, LCD_MCU_D0_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D1_PIN, LCD_MCU_D1_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D2_PIN, LCD_MCU_D2_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D3_PIN, LCD_MCU_D3_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D4_PIN, LCD_MCU_D4_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D5_PIN, LCD_MCU_D5_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D6_PIN, LCD_MCU_D6_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D7_PIN, LCD_MCU_D7_FUNC);
|
|
#if CONFIG_SOC_BK7236XX
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D8_PIN , LCD_MCU_D8_FUNC );
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D9_PIN , LCD_MCU_D9_FUNC );
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D10_PIN, LCD_MCU_D10_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D11_PIN, LCD_MCU_D11_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D12_PIN, LCD_MCU_D12_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D13_PIN, LCD_MCU_D13_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D14_PIN, LCD_MCU_D14_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D15_PIN, LCD_MCU_D15_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D16_PIN, LCD_MCU_D16_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_D17_PIN, LCD_MCU_D17_FUNC);
|
|
#endif
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_RDX_PIN, LCD_MCU_RDX_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_WRX_PIN, LCD_MCU_WRX_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_RSX_PIN, LCD_MCU_RSX_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_RESET_PIN, LCD_MCU_RESET_FUNC);
|
|
IO_FUNCTION_ENABLE_I8080(LCD_MCU_CSX_PIN, LCD_MCU_CSX_FUNC);
|
|
|
|
return BK_OK;
|
|
}
|
|
|
|
|
|
static bk_err_t lcd_rgb_gpio_init(void)
|
|
{
|
|
LOGI("%s\n", __func__);
|
|
#if CONFIG_SOC_BK7236XX
|
|
IO_FUNCTION_ENABLE(LCD_RGB_R0_PIN, LCD_RGB_R0_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_R1_PIN, LCD_RGB_R1_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_R2_PIN, LCD_RGB_R2_FUNC);
|
|
#endif
|
|
IO_FUNCTION_ENABLE(LCD_RGB_R3_PIN, LCD_RGB_R3_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_R4_PIN, LCD_RGB_R4_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_R5_PIN, LCD_RGB_R5_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_R6_PIN, LCD_RGB_R6_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_R7_PIN, LCD_RGB_R7_FUNC);
|
|
|
|
#if CONFIG_SOC_BK7236XX
|
|
IO_FUNCTION_ENABLE(LCD_RGB_G0_PIN, LCD_RGB_G0_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_G1_PIN, LCD_RGB_G1_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_G2_PIN, LCD_RGB_G2_FUNC);
|
|
#endif
|
|
IO_FUNCTION_ENABLE(LCD_RGB_G3_PIN, LCD_RGB_G3_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_G4_PIN, LCD_RGB_G4_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_G5_PIN, LCD_RGB_G5_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_G6_PIN, LCD_RGB_G6_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_G7_PIN, LCD_RGB_G7_FUNC);
|
|
|
|
#if CONFIG_SOC_BK7236XX
|
|
IO_FUNCTION_ENABLE(LCD_RGB_B0_PIN, LCD_RGB_B0_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_B1_PIN, LCD_RGB_B1_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_B2_PIN, LCD_RGB_B2_FUNC);
|
|
|
|
#endif
|
|
IO_FUNCTION_ENABLE(LCD_RGB_B3_PIN, LCD_RGB_B3_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_B4_PIN, LCD_RGB_B4_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_B5_PIN, LCD_RGB_B5_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_B6_PIN, LCD_RGB_B6_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_B7_PIN, LCD_RGB_B7_FUNC);
|
|
|
|
IO_FUNCTION_ENABLE(LCD_RGB_CLK_PIN, LCD_RGB_CLK_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_DISP_PIN, LCD_RGB_DISP_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_HSYNC_PIN, LCD_RGB_HSYNC_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_VSYNC_PIN, LCD_RGB_VSYNC_FUNC);
|
|
IO_FUNCTION_ENABLE(LCD_RGB_DE_PIN, LCD_RGB_DE_FUNC);
|
|
|
|
return BK_OK;
|
|
}
|
|
|
|
bk_err_t bk_lcd_rgb_io_deinit(void)
|
|
{
|
|
IO_FUNCTION_UNMAP(LCD_SPI_CLK_GPIO);
|
|
IO_FUNCTION_UNMAP(LCD_SPI_CSX_GPIO);
|
|
IO_FUNCTION_UNMAP(LCD_SPI_SDA_GPIO);
|
|
IO_FUNCTION_UNMAP(LCD_SPI_RST);
|
|
return BK_OK;
|
|
}
|
|
|
|
|
|
bk_err_t lcd_driver_backlight_open(void)
|
|
{
|
|
#if (CONFIG_SOC_BK7256XX)
|
|
#if CONFIG_PWM
|
|
BK_LOG_ON_ERR(bk_pwm_driver_init());
|
|
pwm_init_config_t config = {0};
|
|
config.period_cycle = 100;
|
|
config.duty_cycle = 100;
|
|
config.psc = 25;
|
|
if (s_lcd.device.type == LCD_TYPE_QSPI) {
|
|
BK_LOG_ON_ERR(bk_pwm_init(LCD_BACKLIGHT_PWM_QSPI, &config));
|
|
BK_LOG_ON_ERR(bk_pwm_start(LCD_BACKLIGHT_PWM_QSPI));
|
|
} else {
|
|
BK_LOG_ON_ERR(bk_pwm_init(LCD_BACKLIGHT_PWM_RGB, &config));
|
|
BK_LOG_ON_ERR(bk_pwm_start(LCD_BACKLIGHT_PWM_RGB));
|
|
}
|
|
#else
|
|
if (s_lcd.device.type == LCD_TYPE_QSPI) {
|
|
gpio_dev_unmap(LCD_BACKLIGHT_GPIO_QSPI);
|
|
BK_LOG_ON_ERR(bk_gpio_enable_output(LCD_BACKLIGHT_GPIO_QSPI));
|
|
BK_LOG_ON_ERR(bk_gpio_pull_up(LCD_BACKLIGHT_GPIO_QSPI));
|
|
bk_gpio_set_output_high(LCD_BACKLIGHT_GPIO_QSPI);
|
|
} else {
|
|
gpio_dev_unmap(LCD_BACKLIGHT_GPIO_RGB);
|
|
BK_LOG_ON_ERR(bk_gpio_enable_output(LCD_BACKLIGHT_GPIO_RGB));
|
|
BK_LOG_ON_ERR(bk_gpio_pull_up(LCD_BACKLIGHT_GPIO_RGB));
|
|
bk_gpio_set_output_high(LCD_BACKLIGHT_GPIO_RGB);
|
|
}
|
|
#endif
|
|
#elif (CONFIG_SOC_BK7236XX)
|
|
#if CONFIG_PWM
|
|
BK_LOG_ON_ERR(bk_pwm_driver_init());
|
|
pwm_init_config_t config = {0};
|
|
config.period_cycle = 100;
|
|
config.duty_cycle = 100;
|
|
config.psc = 25;
|
|
BK_LOG_ON_ERR(bk_pwm_init(LCD_BACKLIGHT_PWM, &config));
|
|
BK_LOG_ON_ERR(bk_pwm_start(LCD_BACKLIGHT_PWM));
|
|
#else
|
|
gpio_dev_unmap(LCD_BACKLIGHT_GPIO);
|
|
BK_LOG_ON_ERR(bk_gpio_enable_output(LCD_BACKLIGHT_GPIO));
|
|
BK_LOG_ON_ERR(bk_gpio_pull_up(LCD_BACKLIGHT_GPIO));
|
|
bk_gpio_set_output_high(LCD_BACKLIGHT_GPIO);
|
|
#endif
|
|
#endif
|
|
|
|
return BK_OK;
|
|
}
|
|
|
|
bk_err_t lcd_driver_backlight_set(uint8_t percent)
|
|
{
|
|
#if CONFIG_PWM
|
|
pwm_period_duty_config_t config = {0};
|
|
|
|
if (percent > 100)
|
|
{
|
|
percent = 100;
|
|
}
|
|
|
|
config.period_cycle = 100;
|
|
config.duty_cycle = percent;
|
|
|
|
#if CONFIG_SOC_BK7256XX
|
|
if (s_lcd.device.type == LCD_TYPE_QSPI) {
|
|
bk_pwm_set_period_duty(LCD_BACKLIGHT_PWM_QSPI, &config);
|
|
} else {
|
|
bk_pwm_set_period_duty(LCD_BACKLIGHT_PWM_RGB, &config);
|
|
}
|
|
#elif CONFIG_SOC_BK7236XX
|
|
bk_pwm_set_period_duty(LCD_BACKLIGHT_PWM, &config);
|
|
#endif
|
|
#endif
|
|
|
|
return BK_OK;
|
|
}
|
|
|
|
bk_err_t lcd_driver_backlight_close(void)
|
|
{
|
|
#if (CONFIG_SOC_BK7256XX)
|
|
#if CONFIG_PWM
|
|
if (s_lcd.device.type == LCD_TYPE_QSPI) {
|
|
BK_LOG_ON_ERR(bk_pwm_stop(LCD_BACKLIGHT_PWM_QSPI));
|
|
BK_LOG_ON_ERR(bk_pwm_deinit(LCD_BACKLIGHT_PWM_QSPI));
|
|
} else {
|
|
BK_LOG_ON_ERR(bk_pwm_stop(LCD_BACKLIGHT_PWM_RGB));
|
|
BK_LOG_ON_ERR(bk_pwm_deinit(LCD_BACKLIGHT_PWM_RGB));
|
|
}
|
|
#else
|
|
if (s_lcd.device.type == LCD_TYPE_QSPI) {
|
|
BK_LOG_ON_ERR(bk_gpio_pull_down(LCD_BACKLIGHT_GPIO_QSPI));
|
|
bk_gpio_set_output_low(LCD_BACKLIGHT_GPIO_QSPI);
|
|
} else {
|
|
BK_LOG_ON_ERR(bk_gpio_pull_down(LCD_BACKLIGHT_GPIO_RGB));
|
|
bk_gpio_set_output_low(LCD_BACKLIGHT_GPIO_RGB);
|
|
}
|
|
#endif
|
|
#elif (CONFIG_SOC_BK7236XX)
|
|
#if CONFIG_PWM
|
|
BK_LOG_ON_ERR(bk_pwm_stop(LCD_BACKLIGHT_PWM));
|
|
BK_LOG_ON_ERR(bk_pwm_deinit(LCD_BACKLIGHT_PWM));
|
|
#else
|
|
BK_LOG_ON_ERR(bk_gpio_pull_down(LCD_BACKLIGHT_GPIO));
|
|
bk_gpio_set_output_low(LCD_BACKLIGHT_GPIO);
|
|
#endif
|
|
#endif
|
|
|
|
return BK_OK;
|
|
}
|
|
|
|
|
|
#if (USE_LCD_REGISTER_CALLBACKS == 1)
|
|
#if (CONFIG_SOC_BK7236XX)
|
|
__attribute__((section(".iram"))) void lcd_isr();
|
|
#else
|
|
__attribute__((section(".itcm_sec_code"))) void lcd_isr();
|
|
#endif
|
|
|
|
bk_err_t bk_lcd_isr_register(lcd_int_type_t int_type, lcd_isr_t isr)
|
|
{
|
|
if (int_type == I8080_OUTPUT_SOF)
|
|
{
|
|
s_lcd.lcd_8080_frame_start_handler = isr;
|
|
}
|
|
if (int_type == I8080_OUTPUT_EOF)
|
|
{
|
|
s_lcd.lcd_8080_frame_end_handler = isr;
|
|
}
|
|
if (int_type == RGB_OUTPUT_SOF)
|
|
{
|
|
s_lcd.lcd_rgb_frame_start_handler = isr;
|
|
}
|
|
if (int_type == RGB_OUTPUT_EOF)
|
|
{
|
|
s_lcd.lcd_rgb_frame_end_handler = isr;
|
|
}
|
|
if (int_type == DE_INT)
|
|
{
|
|
s_lcd.lcd_rgb_de_handler = isr;
|
|
}
|
|
if (int_type == FRAME_INTERVAL_INT)
|
|
{
|
|
s_lcd.lcd_rgb_frame_interval_handler = isr;
|
|
}
|
|
return BK_OK;
|
|
}
|
|
|
|
|
|
#if (CONFIG_SOC_BK7236XX)
|
|
__attribute__((section(".iram"))) void lcd_isr()
|
|
#else
|
|
__attribute__((section(".itcm_sec_code"))) void lcd_isr()
|
|
#endif
|
|
{
|
|
uint32_t int_status = lcd_hal_int_status_get();
|
|
|
|
if (int_status & RGB_OUTPUT_SOF)
|
|
{
|
|
if (s_lcd.lcd_rgb_frame_start_handler)
|
|
{
|
|
s_lcd.lcd_rgb_frame_start_handler();
|
|
}
|
|
lcd_hal_int_status_clear(RGB_OUTPUT_SOF);
|
|
}
|
|
if (int_status & RGB_OUTPUT_EOF)
|
|
{
|
|
if (s_lcd.lcd_rgb_frame_end_handler)
|
|
{
|
|
s_lcd.lcd_rgb_frame_end_handler();
|
|
}
|
|
lcd_hal_int_status_clear(RGB_OUTPUT_EOF);
|
|
}
|
|
|
|
if (int_status & DE_INT)
|
|
{
|
|
if (s_lcd.lcd_rgb_de_handler)
|
|
{
|
|
s_lcd.lcd_rgb_de_handler();
|
|
}
|
|
//lcd_hal_soft_reset();
|
|
lcd_hal_int_status_clear(DE_INT);
|
|
}
|
|
if (int_status & FRAME_INTERVAL_INT)
|
|
{
|
|
if (s_lcd.lcd_8080_frame_end_handler)
|
|
{
|
|
s_lcd.lcd_rgb_frame_interval_handler();
|
|
}
|
|
lcd_hal_int_status_clear(FRAME_INTERVAL_INT);
|
|
}
|
|
|
|
if (int_status & I8080_OUTPUT_SOF)
|
|
{
|
|
if (s_lcd.lcd_8080_frame_start_handler)
|
|
{
|
|
s_lcd.lcd_8080_frame_start_handler();
|
|
}
|
|
lcd_hal_int_status_clear(I8080_OUTPUT_SOF);
|
|
}
|
|
|
|
if (int_status & I8080_OUTPUT_EOF)
|
|
{
|
|
if (s_lcd.lcd_8080_frame_end_handler)
|
|
{
|
|
s_lcd.lcd_8080_frame_end_handler();
|
|
}
|
|
lcd_hal_int_status_clear(I8080_OUTPUT_EOF);
|
|
}
|
|
}
|
|
#else
|
|
bk_err_t bk_lcd_isr_register(lcd_isr_t lcd_isr)
|
|
{
|
|
bk_int_isr_register(INT_SRC_LCD, lcd_isr, NULL);
|
|
return BK_OK;
|
|
}
|
|
#endif
|
|
|
|
|
|
bk_err_t bk_lcd_driver_deinit(void)
|
|
{
|
|
if (!s_lcd_driver_is_init) {
|
|
LOGE("%s, lcd already deinit. \n", __func__);
|
|
return BK_OK;
|
|
}
|
|
|
|
lcd_hal_soft_reset();
|
|
bk_int_isr_unregister(INT_SRC_LCD);
|
|
if (sys_drv_lcd_close() != 0)
|
|
{
|
|
LOGE("lcd system deinit reg config error \r\n");
|
|
return BK_FAIL;
|
|
}
|
|
s_lcd_driver_is_init = false;
|
|
return BK_OK;
|
|
}
|
|
|
|
//bk_err_t bk_lcd_8080_int_enable(bool is_sof_en, bool is_eof_en)
|
|
//{
|
|
// lcd_hal_8080_int_enable(is_sof_en, is_eof_en);
|
|
// return BK_OK;
|
|
//}
|
|
//
|
|
//bk_err_t bk_lcd_rgb_int_enable(bool is_sof_en, bool is_eof_en)
|
|
//{
|
|
// lcd_hal_rgb_int_enable(is_sof_en, is_eof_en);
|
|
// return BK_OK;
|
|
//}
|
|
|
|
|
|
bk_err_t bk_lcd_driver_init(lcd_clk_t clk)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
if (s_lcd_driver_is_init) {
|
|
LOGE("%s already init. \n", __func__);
|
|
return BK_OK;
|
|
}
|
|
|
|
lcd_hal_soft_reset();
|
|
sys_drv_int_enable(LCD_INTERRUPT_CTRL_BIT);
|
|
|
|
switch (clk)
|
|
{
|
|
#if CONFIG_SOC_BK7256XX
|
|
#if 0
|
|
case LCD_320M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_0, DISP_DIV_H_0, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_160M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_0, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_106M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_0, DISP_DIV_H_1, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_120M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_0, DISP_DIV_H_0, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
#endif
|
|
case LCD_64M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_0, DISP_DIV_H_2, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_60M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_1, DISP_DIV_H_0, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_80M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_1, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_54M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_2, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_45M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_3, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_40M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_0, DISP_DIV_H_1, DSIP_DISCLK_ALWAYS_ON);
|
|
//ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_3, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_35M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_0, DISP_DIV_H_4, DSIP_DISCLK_ALWAYS_ON);
|
|
//ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_3, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_32M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_4, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_30M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_1, DISP_DIV_H_1, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_26M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_5, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_24M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_0, DISP_DIV_H_6, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_22M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_6, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_20M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_7, DSIP_DISCLK_ALWAYS_ON);
|
|
//ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_1, DISP_DIV_H_2, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_17M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_0, DISP_DIV_H_3, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_15M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_1, DISP_DIV_H_3, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_12M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_1, DISP_DIV_H_4, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_10M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_1, DISP_DIV_H_5, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_9M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_0, DISP_DIV_H_6, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_8M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_0, DISP_DIV_H_7, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_7M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_1, DISP_DIV_H_7, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
#else
|
|
case LCD_80M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_0, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_54M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_0, DISP_DIV_H_1, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_60M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_0, DISP_DIV_H_0, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_32M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_0, DISP_DIV_H_2, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_30M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_1, DISP_DIV_H_0, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_40M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_1, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_26M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_2, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_22M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_3, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_20M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_0, DISP_DIV_H_1, DSIP_DISCLK_ALWAYS_ON);
|
|
//ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_3, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_17M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_0, DISP_DIV_H_4, DSIP_DISCLK_ALWAYS_ON);
|
|
//ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_3, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_15M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_1, DISP_DIV_H_1, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_12M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_0, DISP_DIV_H_6, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_10M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_1, DISP_DIV_H_7, DSIP_DISCLK_ALWAYS_ON);
|
|
//ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_1, DISP_DIV_H_2, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
case LCD_8M:
|
|
ret = sys_drv_lcd_set(DISP_CLK_120M, DISP_DIV_L_0, DISP_DIV_H_3, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
#endif
|
|
default:
|
|
ret = sys_drv_lcd_set(DISP_CLK_320M, DISP_DIV_L_0, DISP_DIV_H_4, DSIP_DISCLK_ALWAYS_ON);
|
|
break;
|
|
}
|
|
#if (USE_LCD_REGISTER_CALLBACKS == 1)
|
|
bk_int_isr_register(INT_SRC_LCD, lcd_isr, NULL);
|
|
#endif
|
|
rtos_delay_milliseconds(1);
|
|
|
|
lcd_hal_soft_reset();
|
|
s_lcd_driver_is_init = true;
|
|
return ret;
|
|
}
|
|
/**
|
|
* @brief This API config lcd display x size and y size
|
|
|
|
* @param
|
|
* - width lcd display width
|
|
* - height lcd display height
|
|
*
|
|
* attention 1. int the next version, the width and height deside the transfer number of lcd display.
|
|
* will config with another two register x offset and y offset
|
|
*
|
|
* attention 2. in this sdk version width/height only set once in 8080_init,if you want set twice,should
|
|
set bk_lcd_8080_display_enable(0)
|
|
*/
|
|
bk_err_t bk_lcd_pixel_config(uint16_t x_pixel, uint16_t y_pixel)
|
|
{
|
|
LCD_RETURN_ON_NOT_INIT();
|
|
|
|
lcd_hal_pixel_config(x_pixel, y_pixel);
|
|
return BK_OK;
|
|
}
|
|
|
|
|
|
bk_err_t bk_lcd_8080_send_cmd(uint8_t param_count, uint32_t command, uint32_t *param)
|
|
{
|
|
LCD_RETURN_ON_NOT_INIT();
|
|
|
|
lcd_hal_8080_cmd_send(param_count, command, param);
|
|
return BK_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
bk_err_t bk_lcd_input_pixel_hf_reverse(bool hf_reverse)
|
|
{
|
|
lcd_hal_set_pixel_reverse(hf_reverse);
|
|
return BK_OK;
|
|
}
|
|
|
|
/*
|
|
* rgb input RGB565, rgb888. yuv format
|
|
*/
|
|
bk_err_t bk_lcd_set_yuv_mode(pixel_format_t input_data_format)
|
|
{
|
|
lcd_hal_set_yuv_mode(input_data_format);
|
|
return BK_OK;
|
|
}
|
|
|
|
|
|
pixel_format_t bk_lcd_get_yuv_mode(void)
|
|
{
|
|
uint32_t yuv_mode = lcd_hal_get_display_yuv_sel();
|
|
uint32_t reverse = lcd_hal_get_pixel_reverse();
|
|
pixel_format_t output_data_format = PIXEL_FMT_UNKNOW;
|
|
|
|
if (reverse == 0)
|
|
{
|
|
if (yuv_mode == 0)
|
|
{
|
|
output_data_format = PIXEL_FMT_RGB565_LE;
|
|
}
|
|
else if (yuv_mode == 1)
|
|
{
|
|
output_data_format = PIXEL_FMT_YUYV;
|
|
}
|
|
else if (yuv_mode == 2)
|
|
{
|
|
output_data_format = PIXEL_FMT_UYVY;
|
|
}
|
|
else if (yuv_mode == 3)
|
|
{
|
|
output_data_format = PIXEL_FMT_YYUV;
|
|
}
|
|
else if (yuv_mode == 4)
|
|
{
|
|
output_data_format = PIXEL_FMT_UVYY;
|
|
}
|
|
else if (yuv_mode == 5)
|
|
{
|
|
output_data_format = PIXEL_FMT_VUYY;
|
|
}
|
|
}
|
|
else if (reverse == 1)
|
|
{
|
|
if (yuv_mode == 0)
|
|
{
|
|
output_data_format = PIXEL_FMT_RGB565;
|
|
}
|
|
}
|
|
|
|
return output_data_format;
|
|
}
|
|
|
|
bk_err_t bk_lcd_set_partical_display(bool en, uint16_t partial_clum_l, uint16_t partial_clum_r, uint16_t partial_line_l, uint16_t partial_line_r)
|
|
{
|
|
LCD_RETURN_ON_NOT_INIT();
|
|
lcd_hal_set_partical_display(en, partial_clum_l, partial_clum_r, partial_line_l, partial_line_r);
|
|
return BK_OK;
|
|
}
|
|
|
|
#if CONFIG_FLASH
|
|
void lcd_flash_disable_int(uint32_t enable)
|
|
{
|
|
lcd_hal_rgb_int_enable(0, enable);
|
|
}
|
|
#endif
|
|
|
|
bk_err_t bk_lcd_rgb_init(const lcd_device_t *device)
|
|
{
|
|
BK_RETURN_ON_NULL(device);
|
|
|
|
const lcd_rgb_t *rgb = device->rgb;
|
|
uint16_t x = ppi_to_pixel_x(device->ppi); //lcd size x
|
|
uint16_t y = ppi_to_pixel_y(device->ppi); //lcd size y
|
|
LOGI("%s\n", __func__);
|
|
|
|
lcd_hal_rgb_display_sel(1); //RGB display enable, and select rgb module
|
|
lcd_hal_set_sync_low(rgb->hsync_pulse_width, rgb->vsync_pulse_width);
|
|
lcd_hal_rgb_int_enable(0, 1);
|
|
#if CONFIG_FLASH
|
|
mb_flash_register_op_notify(lcd_flash_disable_int);
|
|
#endif
|
|
lcd_hal_rgb_sync_config(rgb->hsync_back_porch,
|
|
rgb->hsync_front_porch,
|
|
rgb->vsync_back_porch,
|
|
rgb->vsync_front_porch);
|
|
|
|
lcd_hal_set_rgb_clk_rev_edge(rgb->data_out_clk_edge);//output data is in clk doen edge or up adge
|
|
|
|
lcd_hal_disconti_mode(DISCONTINUE_MODE);
|
|
|
|
bk_lcd_pixel_config(x, y); //image xpixel ypixel
|
|
// bk_lcd_set_yuv_mode(device->fmt);
|
|
lcd_hal_set_data_fifo_thrd(DATA_FIFO_WR_THRD, DATA_FIFO_RD_THRD);
|
|
return BK_OK;
|
|
}
|
|
|
|
bk_err_t bk_lcd_8080_init(const lcd_device_t *device)
|
|
{
|
|
BK_RETURN_ON_NULL(device);
|
|
|
|
uint16_t x = ppi_to_pixel_x(device->ppi);
|
|
uint16_t y = ppi_to_pixel_y(device->ppi);
|
|
LOGI("%s\n", __func__);
|
|
lcd_hal_rgb_display_sel(0); //25bit - rgb_on = 0 select 8080 mode
|
|
lcd_hal_disconti_mode(DISCONTINUE_MODE);
|
|
lcd_hal_8080_verify_1ms_count(VERIFY_1MS_COUNT);
|
|
lcd_hal_8080_set_tik(TIK_CNT);
|
|
lcd_hal_set_data_fifo_thrd(DATA_FIFO_WR_THRD, DATA_FIFO_RD_THRD);
|
|
lcd_hal_8080_set_fifo_data_thrd(CMD_FIFO_WR_THRD, CMD_FIFO_RD_THRD);
|
|
lcd_hal_pixel_config(x, y);
|
|
lcd_hal_8080_display_enable(1);
|
|
lcd_hal_8080_int_enable(0, 1); //set eof int enable
|
|
// bk_lcd_set_yuv_mode(config->fmt);
|
|
return BK_OK;
|
|
}
|
|
|
|
bk_err_t bk_lcd_8080_deinit(void)
|
|
{
|
|
LCD_RETURN_ON_NOT_INIT();
|
|
lcd_hal_8080_int_enable(0, 0);
|
|
lcd_hal_8080_display_enable(0);
|
|
lcd_hal_8080_start_transfer(0);
|
|
return BK_OK;
|
|
}
|
|
|
|
bk_err_t bk_lcd_rgb_deinit(void)
|
|
{
|
|
LCD_RETURN_ON_NOT_INIT();
|
|
lcd_hal_rgb_int_enable(0, 0);
|
|
lcd_hal_rgb_display_en(0);
|
|
lcd_hal_rgb_display_sel(0);
|
|
|
|
return BK_OK;
|
|
}
|
|
|
|
bk_err_t bk_lcd_8080_start_transfer(bool start)
|
|
{
|
|
LCD_RETURN_ON_NOT_INIT();
|
|
lcd_hal_8080_start_transfer(start);
|
|
return BK_OK;
|
|
}
|
|
|
|
//to del
|
|
bk_err_t bk_lcd_rgb_display_en(bool en)
|
|
{
|
|
lcd_hal_rgb_display_en(en);
|
|
return BK_OK;
|
|
}
|
|
|
|
bk_err_t lcd_driver_display_disable(void)
|
|
{
|
|
lcd_type_t type;
|
|
type = s_lcd.device.type;
|
|
|
|
if ((type == LCD_TYPE_RGB565) || (type == LCD_TYPE_RGB))
|
|
{
|
|
lcd_hal_rgb_display_en(0);
|
|
} else if (type == LCD_TYPE_MCU8080) {
|
|
lcd_hal_8080_cmd_param_count(0);
|
|
lcd_hal_8080_start_transfer(0);
|
|
}
|
|
|
|
return BK_OK;
|
|
}
|
|
|
|
bk_err_t lcd_driver_display_enable(void)
|
|
{
|
|
lcd_type_t type;
|
|
type = s_lcd.device.type;
|
|
if ((type == LCD_TYPE_RGB565) || (type == LCD_TYPE_RGB))
|
|
{
|
|
lcd_hal_rgb_display_en(1);
|
|
}
|
|
else if (type == LCD_TYPE_MCU8080)
|
|
{
|
|
if(s_lcd.device.id == LCD_DEVICE_NT35510_MCU)
|
|
{
|
|
lcd_hal_8080_start_transfer(0);
|
|
if(s_lcd.device.mcu->set_display_area)
|
|
s_lcd.device.mcu->set_display_area(0, 479, 0, 799);
|
|
if(s_lcd.device.mcu->start_transform)
|
|
s_lcd.device.mcu->start_transform();
|
|
}
|
|
else if(s_lcd.device.id == LCD_DEVICE_ST7789V)
|
|
{
|
|
lcd_hal_8080_start_transfer(0);
|
|
if(s_lcd.device.mcu->set_display_area)
|
|
s_lcd.device.mcu->set_display_area(0+35, 169+35, 0, 319); // special process
|
|
if(s_lcd.device.mcu->start_transform)
|
|
s_lcd.device.mcu->start_transform();
|
|
}
|
|
lcd_hal_8080_start_transfer(1);
|
|
lcd_hal_8080_cmd_param_count(1);
|
|
lcd_hal_8080_write_cmd(0x2c);
|
|
}
|
|
|
|
return BK_OK;
|
|
}
|
|
|
|
bk_err_t lcd_driver_display_continue(void)
|
|
{
|
|
lcd_type_t type;
|
|
type = s_lcd.device.type;
|
|
if (type == LCD_TYPE_RGB565)
|
|
{
|
|
}
|
|
if (type == LCD_TYPE_MCU8080)
|
|
{
|
|
lcd_hal_8080_start_transfer(1);
|
|
if(s_lcd.device.id != LCD_DEVICE_NT35510_MCU)
|
|
{
|
|
lcd_hal_8080_write_cmd(0x3c);
|
|
}
|
|
else
|
|
{
|
|
lcd_hal_8080_start_transfer(0);
|
|
if(s_lcd.device.mcu->continue_transform)
|
|
s_lcd.device.mcu->continue_transform();
|
|
|
|
lcd_hal_8080_cmd_param_count(1);
|
|
lcd_hal_8080_write_cmd(0x2c);
|
|
}
|
|
}
|
|
return BK_OK;
|
|
}
|
|
|
|
bk_err_t lcd_driver_set_display_base_addr(uint32_t disp_base_addr)
|
|
{
|
|
lcd_hal_set_display_read_base_addr(disp_base_addr);
|
|
|
|
return BK_OK;
|
|
}
|
|
|
|
void lcd_driver_ppi_set(uint16_t width, uint16_t height)
|
|
{
|
|
uint16_t x = ppi_to_pixel_x(s_lcd.device.ppi);
|
|
uint16_t y = ppi_to_pixel_y(s_lcd.device.ppi);
|
|
|
|
//bk_lcd_set_partical_display(0, 0, 0, 0, 0);
|
|
lcd_hal_pixel_config(width, height);
|
|
uint16_t start_x = 1;
|
|
uint16_t start_y = 1;
|
|
uint16_t end_x = x;
|
|
uint16_t end_y = y;
|
|
|
|
if (x < width || y < height)
|
|
{
|
|
if (x < width)
|
|
{
|
|
start_x = (width - x) / 2 + 1;
|
|
end_x = start_x + x - 1;
|
|
}
|
|
if (y < height)
|
|
{
|
|
start_y = (height - y) / 2 + 1;
|
|
end_y = start_y + y - 1;
|
|
}
|
|
|
|
LOGD("%s, offset %d, %d, %d, %d\n", __func__, start_x, end_x, start_y, end_y);
|
|
bk_lcd_set_partical_display(1, start_x, end_x, start_y, end_y);
|
|
}
|
|
else if (x == width && y == height)
|
|
{
|
|
bk_lcd_set_partical_display(0, 0, 0, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
bk_lcd_set_partical_display(0, 0, 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
bk_err_t lcd_ldo_power_enable(uint8_t enable)
|
|
{
|
|
#if (CONFIG_LCD_POWER_GPIO_CTRL)
|
|
|
|
if (enable)
|
|
{
|
|
#if (LCD_LDO_CTRL_ACTIVE_LEVEL)
|
|
bk_gpio_ctrl_external_ldo(GPIO_CTRL_LDO_MODULE_LCD, LCD_LDO_CTRL_GPIO, GPIO_OUTPUT_STATE_HIGH);
|
|
#else
|
|
bk_gpio_ctrl_external_ldo(GPIO_CTRL_LDO_MODULE_LCD, LCD_LDO_CTRL_GPIO, GPIO_OUTPUT_STATE_LOW);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
|
|
#if (LCD_LDO_CTRL_ACTIVE_LEVEL)
|
|
bk_gpio_ctrl_external_ldo(GPIO_CTRL_LDO_MODULE_LCD, LCD_LDO_CTRL_GPIO, GPIO_OUTPUT_STATE_LOW);
|
|
#else
|
|
bk_gpio_ctrl_external_ldo(GPIO_CTRL_LDO_MODULE_LCD, LCD_LDO_CTRL_GPIO, GPIO_OUTPUT_STATE_HIGH);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
return BK_OK;
|
|
}
|
|
|
|
bk_err_t lcd_driver_init(const lcd_device_t *device)
|
|
{
|
|
BK_RETURN_ON_NULL(device);
|
|
|
|
int ret = BK_OK;
|
|
LOGI("%s \n", __func__);
|
|
|
|
/// LCD module power
|
|
bk_pm_module_vote_power_ctrl(PM_POWER_SUB_MODULE_NAME_VIDP_LCD, PM_POWER_MODULE_STATE_ON);
|
|
bk_pm_clock_ctrl(PM_CLK_ID_DISP, CLK_PWR_CTRL_PWR_UP);
|
|
#if CONFIG_SOC_BK7256XX
|
|
lcd_ldo_power_enable(1);
|
|
bk_pm_module_vote_cpu_freq(PM_DEV_ID_DISP, PM_CPU_FRQ_320M);
|
|
#else
|
|
bk_pm_module_vote_ctrl_external_ldo(GPIO_CTRL_LDO_MODULE_LCD, LCD_LDO_CTRL_GPIO, GPIO_OUTPUT_STATE_HIGH);
|
|
bk_pm_module_vote_cpu_freq(PM_DEV_ID_DISP, PM_CPU_FRQ_480M);
|
|
#endif
|
|
os_memset(&s_lcd, 0, sizeof(s_lcd));
|
|
os_memcpy((void*)&s_lcd.device, device, sizeof(lcd_device_t));
|
|
|
|
if ((device->type == LCD_TYPE_RGB565) || (device->type == LCD_TYPE_RGB))
|
|
{
|
|
bk_lcd_driver_init(device->rgb->clk);
|
|
lcd_rgb_gpio_init();
|
|
bk_lcd_rgb_init(device);
|
|
lcd_hal_rgb_set_in_out_format(device->src_fmt, device->out_fmt);
|
|
// lcd_hal_int_enable(DE_INT);
|
|
|
|
// lcd_hal_int_enable(FRAME_INTERVAL_INT);
|
|
// lcd_hal_frame_interval_config(1, VSYNC_UNIT, 2);
|
|
}
|
|
else if (device->type == LCD_TYPE_MCU8080)
|
|
{
|
|
bk_lcd_driver_init(device->mcu->clk);
|
|
lcd_mcu_gpio_init();
|
|
bk_lcd_8080_init(device);
|
|
lcd_hal_mcu_set_in_out_format(device->src_fmt, device->out_fmt);
|
|
}
|
|
#if CONFIG_LCD_QSPI
|
|
else if (device->type == LCD_TYPE_QSPI)
|
|
{
|
|
bk_lcd_qspi_disp_open(LCD_QSPI_ID, device);
|
|
}
|
|
#endif
|
|
|
|
uint64_t before, after;
|
|
#if CONFIG_ARCH_RISCV
|
|
before = riscv_get_mtimer();
|
|
#else
|
|
before = 0;
|
|
#endif
|
|
|
|
if (device->init)
|
|
{
|
|
device->init();
|
|
}
|
|
#if CONFIG_ARCH_RISCV
|
|
after = riscv_get_mtimer();
|
|
#else
|
|
after = 0;
|
|
#endif
|
|
LOGI("lcd init time: %lu\n", (after - before) / 26000);
|
|
|
|
return ret;
|
|
}
|
|
|
|
bk_err_t lcd_driver_deinit(void)
|
|
{
|
|
bk_err_t ret = BK_OK;
|
|
|
|
if (s_lcd.device.lcd_off)
|
|
{
|
|
s_lcd.device.lcd_off();
|
|
}
|
|
/* LCD controller */
|
|
if (s_lcd.device.type == LCD_TYPE_RGB565)
|
|
{
|
|
ret = bk_lcd_rgb_deinit();
|
|
if (ret != 0)
|
|
{
|
|
LOGE("lcd system deinit reg config error \r\n");
|
|
ret = BK_FAIL;
|
|
goto out;
|
|
}
|
|
}
|
|
else if (s_lcd.device.type == LCD_TYPE_MCU8080)
|
|
{
|
|
ret = bk_lcd_8080_deinit();
|
|
if (ret != BK_OK)
|
|
{
|
|
LOGE("lcd system deinit reg config error \r\n");
|
|
ret = BK_FAIL;
|
|
goto out;
|
|
}
|
|
}
|
|
#if CONFIG_LCD_QSPI
|
|
else if (s_lcd.device.type == LCD_TYPE_QSPI)
|
|
{
|
|
bk_lcd_qspi_disp_close(LCD_QSPI_ID);
|
|
}
|
|
#endif
|
|
|
|
out:
|
|
bk_lcd_driver_deinit();
|
|
bk_lcd_rgb_io_deinit();
|
|
bk_pm_clock_ctrl(PM_CLK_ID_DISP, CLK_PWR_CTRL_PWR_DOWN);
|
|
bk_pm_module_vote_power_ctrl(PM_POWER_SUB_MODULE_NAME_VIDP_LCD, PM_POWER_MODULE_STATE_OFF);
|
|
bk_pm_module_vote_cpu_freq(PM_DEV_ID_DISP, PM_CPU_FRQ_DEFAULT);
|
|
#if CONFIG_SOC_BK7256XX
|
|
lcd_ldo_power_enable(0);
|
|
#else
|
|
bk_pm_module_vote_ctrl_external_ldo(GPIO_CTRL_LDO_MODULE_LCD, LCD_LDO_CTRL_GPIO, GPIO_OUTPUT_STATE_LOW);
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
|