This repository has been archived on 2023-07-17. You can view files and clone it, but cannot push or open issues or pull requests.
bl_mcu_sdk/bsp/common/lcd/mipi_dpi/gc9503v_dpi.c
2023-02-24 21:33:36 +08:00

223 lines
8.4 KiB
C

/**
* @file gc9503v_dpi.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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 "../lcd.h"
#if defined(LCD_DPI_GC9503V)
#include "gc9503v_dpi.h"
#include "bl_mipi_dpi_pec.h"
#include "bflb_mtimer.h"
#include "bflb_gpio.h"
/* mipi dpi (RGB) paramant */
static lcd_mipi_dpi_init_t dpi_para = {
.width = GC9503V_DPI_W, /* LCD Active Width */
.height = GC9503V_DPI_H, /* LCD Active Height */
/* Total Width = HSW + HBP + Active_Width + HFP */
.hsw = 10, /* LCD HSW (Hsync Pulse Width) */
.hbp = 10, /* LCD HBP (Hsync Back Porch) */
.hfp = 10, /* LCD HFP (Hsync Front Porch) */
/* Total Height = VSW + VBP + Active_Height + VFP */
.vsw = 3, /* LCD VSW (Vsync Pulse Width) */
.vbp = 12, /* LCD VBP (Vsync Back Porch) */
.vfp = 14, /* LCD VFP (Vsync Front Porch) */
.frame_rate = 60, /* Maximum refresh frame rate per second, Used to automatically calculate the clock frequency */
#if (GC9503V_DPI_PIXEL_FORMAT == 1)
.pixel_format = LCD_MIPI_DPI_PIXEL_FORMAT_RGB565,
#endif
.frame_buff = NULL,
};
#if (GC9503V_DPI_INIT_INTERFACE == 1)
static struct bflb_device_s *gc9503v_gpio;
/* gpio spi init */
static void gc9503v_soft_spi_init(void)
{
/* gpio24 spi clk init */
/* gpio25 spi mosi init */
/* gpio12 spi cs init */
gc9503v_gpio = bflb_device_get_by_name("gpio");
bflb_gpio_init(gc9503v_gpio, GC9503V_DPI_SPI_CS_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
bflb_gpio_init(gc9503v_gpio, GC9503V_DPI_SPI_CLK_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
bflb_gpio_init(gc9503v_gpio, GC9503V_DPI_SPI_DAT_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
GC9503V_SPI_CS_HIGH;
GC9503V_SPI_CLK_HIGH;
GC9503V_SPI_MOSI_HIGH;
}
/* gpio spi send byte */
static ATTR_TCM_SECTION void spi_send_byte(uint8_t data)
{
for (uint32_t i = 0; i < 8; i++) {
GC9503V_SPI_CLK_LOW;
if (data & 0x80) {
GC9503V_SPI_MOSI_HIGH;
} else {
GC9503V_SPI_MOSI_LOW;
}
GC9503V_SPI_CLK_HIGH;
data <<= 1;
DUMMY_DELAY;
}
}
/* spi write cmd */
static ATTR_TCM_SECTION int gc9503v_spi_write_cmd(uint8_t cmd)
{
GC9503V_SPI_CLK_LOW;
GC9503V_SPI_CS_LOW;
GC9503V_SPI_MOSI_LOW;
GC9503V_SPI_CLK_HIGH;
spi_send_byte(cmd);
GC9503V_SPI_CLK_LOW;
GC9503V_SPI_CS_HIGH;
GC9503V_SPI_MOSI_HIGH;
return 0;
}
/* spi write data */
static ATTR_TCM_SECTION int gc9503v_spi_write_data_byte(uint8_t data)
{
GC9503V_SPI_CLK_LOW;
GC9503V_SPI_CS_LOW;
GC9503V_SPI_MOSI_HIGH;
GC9503V_SPI_CLK_HIGH;
spi_send_byte(data);
GC9503V_SPI_CLK_LOW;
GC9503V_SPI_CS_HIGH;
GC9503V_SPI_MOSI_HIGH;
return 0;
}
#endif
static const gc9503v_dpi_init_cmd_t gc9503v_dpi_mode_init_cmds[] = {
{ 0x10, NULL, 0 }, /* enter sleep mode */
{ 0xF0, "\x55\xAA\x52\x08\x00", 5 },
{ 0xF6, "\x5A\x87", 2 },
{ 0xC1, "\x3F", 1 },
{ 0xC2, "\x0E", 1 },
{ 0xC6, "\xF8", 1 },
{ 0xC9, "\x10", 1 },
{ 0xCD, "\x25", 1 },
{ 0xF8, "\x8A", 1 },
{ 0xAC, "\x45", 1 },
{ 0xA0, "\xDD", 1 },
{ 0xA7, "\x47", 1 },
{ 0xFA, "\x00\x00\x00\x04", 4 },
{ 0xA3, "\xEE", 1 },
{ 0xFD, "\x28\x28\x00", 3 },
{ 0x71, "\x48", 1 },
{ 0x72, "\x48", 1 },
{ 0x73, "\x00\x44", 2 },
{ 0x97, "\xEE", 1 },
{ 0x83, "\x93", 1 },
{ 0x9A, "\x72", 1 },
{ 0x9B, "\x5A", 1 },
{ 0x82, "\x2C\x2C", 2 },
{ 0xB1, "\x10", 1 },
{ 0x6D, "\x00\x1F\x19\x1A\x10\x0E\x0C\x0A\x02\x07\x1E\x1E\x1E\x1E\x1E\x1E\x1E\x1E\x1E\x1E\x1E\x1E\x08\x01\x09\x0B\x0D\x0F\x1A\x19\x1F\x00", 32 },
{ 0x64, "\x38\x05\x01\xDB\x03\x03\x38\x04\x01\xDC\x03\x03\x7A\x7A\x7A\x7A", 16 },
{ 0x65, "\x38\x03\x01\xDD\x03\x03\x38\x02\x01\xDE\x03\x03\x7A\x7A\x7A\x7A", 16 },
{ 0x66, "\x38\x01\x01\xDF\x03\x03\x38\x00\x01\xE0\x03\x03\x7A\x7A\x7A\x7A", 16 },
{ 0x67, "\x30\x01\x01\xE1\x03\x03\x30\x02\x01\xE2\x03\x03\x7A\x7A\x7A\x7A", 16 },
{ 0x68, "\x00\x08\x15\x08\x15\x7A\x7A\x08\x15\x08\x15\x7A\x7A", 13 },
{ 0x60, "\x38\x08\x7A\x7A\x38\x09\x7A\x7A", 8 },
{ 0x63, "\x31\xE4\x7A\x7A\x31\xE5\x7A\x7A", 8 },
{ 0x6B, "\x07", 1 },
{ 0x7A, "\x08\x13", 2 },
{ 0x7B, "\x08\x13", 2 },
{ 0xD1, "\x00\x00\x00\x04\x00\x12\x00\x18\x00\x21\x00\x2A\x00\x35\x00\x47\x00\x56\x00\x90\x00\xE5\x01\x68\x01\xD5\x01\xD7\x02\x36\x02\xA6\x02\xEE\x03\x48\x03\xA0\x03\xBA\x03\xC5\x03\xD0\x03\xE0\x03\xEA\x03\xFA\x03\xFF", 52 },
{ 0xD2, "\x00\x00\x00\x04\x00\x12\x00\x18\x00\x21\x00\x2A\x00\x35\x00\x47\x00\x56\x00\x90\x00\xE5\x01\x68\x01\xD5\x01\xD7\x02\x36\x02\xA6\x02\xEE\x03\x48\x03\xA0\x03\xBA\x03\xC5\x03\xD0\x03\xE0\x03\xEA\x03\xFA\x03\xFF", 52 },
{ 0xD3, "\x00\x00\x00\x04\x00\x12\x00\x18\x00\x21\x00\x2A\x00\x35\x00\x47\x00\x56\x00\x90\x00\xE5\x01\x68\x01\xD5\x01\xD7\x02\x36\x02\xA6\x02\xEE\x03\x48\x03\xA0\x03\xBA\x03\xC5\x03\xD0\x03\xE0\x03\xEA\x03\xFA\x03\xFF", 52 },
{ 0xD4, "\x00\x00\x00\x04\x00\x12\x00\x18\x00\x21\x00\x2A\x00\x35\x00\x47\x00\x56\x00\x90\x00\xE5\x01\x68\x01\xD5\x01\xD7\x02\x36\x02\xA6\x02\xEE\x03\x48\x03\xA0\x03\xBA\x03\xC5\x03\xD0\x03\xE0\x03\xEA\x03\xFA\x03\xFF", 52 },
{ 0xD5, "\x00\x00\x00\x04\x00\x12\x00\x18\x00\x21\x00\x2A\x00\x35\x00\x47\x00\x56\x00\x90\x00\xE5\x01\x68\x01\xD5\x01\xD7\x02\x36\x02\xA6\x02\xEE\x03\x48\x03\xA0\x03\xBA\x03\xC5\x03\xD0\x03\xE0\x03\xEA\x03\xFA\x03\xFF", 52 },
{ 0xD6, "\x00\x00\x00\x04\x00\x12\x00\x18\x00\x21\x00\x2A\x00\x35\x00\x47\x00\x56\x00\x90\x00\xE5\x01\x68\x01\xD5\x01\xD7\x02\x36\x02\xA6\x02\xEE\x03\x48\x03\xA0\x03\xBA\x03\xC5\x03\xD0\x03\xE0\x03\xEA\x03\xFA\x03\xFF", 52 },
{ 0x3A, "\x66", 1 }, /* pixel format set 16bits:0x55;18bits:0x66 */
{ 0x11, NULL, 0 }, /* sleep out */
{ 0xFF, NULL, 200 }, /* delay 200ms */
{ 0x29, NULL, 0 }, /* display on */
{ 0xFF, NULL, 30 }, /* delay 30ms */
};
int ATTR_TCM_SECTION gc9503v_dpi_init(gc9503v_dpi_color_t *screen_buffer)
{
#if (GC9503V_DPI_INIT_INTERFACE == 1)
/* spi init */
gc9503v_soft_spi_init();
for (uint16_t i = 0; i < (sizeof(gc9503v_dpi_mode_init_cmds) / sizeof(gc9503v_dpi_init_cmd_t)); i++) {
if ((gc9503v_dpi_mode_init_cmds[i].cmd == 0xFF) && (gc9503v_dpi_mode_init_cmds[i].data == NULL) && (gc9503v_dpi_mode_init_cmds[i].databytes)) {
bflb_mtimer_delay_ms(gc9503v_dpi_mode_init_cmds[i].databytes);
} else {
/* send register address */
gc9503v_spi_write_cmd(gc9503v_dpi_mode_init_cmds[i].cmd);
bflb_mtimer_delay_us(22);
/* send register data */
for (uint8_t j = 0; j < (gc9503v_dpi_mode_init_cmds[i].databytes); j++) {
gc9503v_spi_write_data_byte(gc9503v_dpi_mode_init_cmds[i].data[j]);
bflb_mtimer_delay_us(22);
}
}
}
#endif
/* mipi dpi init */
if (screen_buffer == NULL) {
return -1;
}
dpi_para.frame_buff = (void *)screen_buffer;
return lcd_mipi_dpi_init(&dpi_para);
}
int gc9503v_dpi_screen_switch(gc9503v_dpi_color_t *screen_buffer)
{
return lcd_mipi_dpi_screen_switch((void *)screen_buffer);
}
gc9503v_dpi_color_t *gc9503v_dpi_get_screen_using(void)
{
return (gc9503v_dpi_color_t *)lcd_mipi_dpi_get_screen_using();
}
int gc9503v_dpi_frame_callback_register(uint32_t callback_type, void (*callback)(void))
{
if (callback_type == FRAME_INT_TYPE_CYCLE) {
lcd_mipi_dpi_frame_callback_register(LCD_MIPI_DPI_FRAME_INT_TYPE_CYCLE, callback);
} else if (callback_type == FRAME_INT_TYPE_SWAP) {
lcd_mipi_dpi_frame_callback_register(LCD_MIPI_DPI_FRAME_INT_TYPE_SWAP, callback);
}
return 0;
}
#endif