- 2024-11-03
-
加入了学习《2024得捷电子设计大赛-时光照相机》,观看 时光照相机
-
回复了主题帖:
时光照相机
秦天qintian0303 发表于 2024-11-2 23:28
使用NAS的情况下,可以很好存储下每天的信息,时间长了文件也不小啊,如何处理呢
大哥,你NAS又不是手机,还能没几个T吗
- 2024-11-01
-
加入了学习《基于树莓派5的工业智能网关视频》,观看 得捷2024大赛基于树莓派5的智能工业网关视频
-
发表了主题帖:
时光照相机
本帖最后由 eew_7QI3Yq 于 2024-11-3 23:27 编辑
时光照相机
作者:eew_7QI3Yq
一、作品简介
本次作品主要是记录生活的,把我们的日常记录下来,时间过的很快,外界变化通过相机可以完美的记录下来,前面有相机延时摄影记录,我自己也做一个,而且价格上很便宜,同时集成很多功能,可以访问我的NAS,把每天记录的保存下来,同时我加了一个系统自动生成每天的一个延时摄影之后的图片生成的视频。同时视频中图片增加上每天的时间水印,温度,湿度,大气压的水印。同时我为其搭建了可以远程访问的服务,实时画面我也做到显示上了,这样远程还能作为监控使用了。
二、系统框图
硬件框图,主要使用树莓派,外接的是USB摄像头,当然也可以选择CSI摄像头,但是不便于拓展,USB可以延长很远,BME280是硬件设备,采集外部温湿度,大气压。
主要记录当时的各种环境参数。
三、各部分功能说明
首先这是我的软件界面,软件上有实时显示窗口,有摄像头设备选择,摄像头的信息是直接显示的,也是自动打开的,他是支持热插拔,这样好处就是在断开后也可以自己连接打开,下方的间隔采样,是间隔多长时间保存下图片,可以自己设置,这样就可以根据自己需求保存,每天记录的图片再第二天开始时对前一天的的图片做视频处理,输出一个简短的视频。
首先是这个,设备监测,QT5有完整的摄像头类可以直接使用,监听变化看是否是拔出还是插入,插入后就直接默认打开第一个摄像头。
之后就是打开摄像头的,我们增加QVideoProbe类进行探测摄像头的操作,主要就是给其增加水印,下面的是设置摄像头输出的格式,分辨率。
摄像头的YUYV格式没法直接处理,需要转换为RGB进行处理,添加水印,和保存。
从这里增加,文件夹创建,同时可以对前一天摄像头采集图片数据进行一个视频转换输出。
通过时间判断,是否过了第二天,然后启动线程输出视频文件。线程好处就是主界面不会卡住,还照样是实时画面。
视频输出中使用FFMpeg来进行,同时用image2pipe,因为我们存的图片原因,所以我们只能通过这种方式才能输出有效的视频。
看看我们通过rustDesk创建的远程连接,rustDesk比较简单,直接下载安装包安装即可。需要自己搭建一个服务器。
这是安装包。
视频播放用内置的VLC播放器即可。
四、作品源码
五、作品功能演示视频
六、项目总结
本次通过树莓派搭建的这个系统,在使用NAS的情况下,可以很好存储下每天的信息,同时生成简要视频概览,可以自己直接查看了,每天记录下这些信息可以看到变化,同时我们有代码可以非常方便的,生成月记录,年记录,从每天图片抽出来即可,后面可以继续优化他,这样方便用户自定义使用。
七、其他
本次项目基于QT5,本来里面还打算用openCV的,同时源码中也是做了,树莓派中直接用案例会很方便,WIN端也可以编译运行,同时后期可以在win端加上FFMpeg这样就可以直接WIN调试了。
- 2024-08-30
-
发表了主题帖:
【瑞萨RA8D1开发板,基于M85内核的图形MCU测评】+摄像头和显示屏结合
上次我们通过开发板进行了摄像头测试,关键我们只能通过仿真然后进内存中查看里面的图像数据,还有点掉帧,所以我们结合我们的屏幕进行测试直接显示到LCD上。
我们在摄像头的基础上增加我们的RGB LCD的配置。之前都是现成的所以拿来用下即可。
把关键的引脚初始化好,相关的配置设置好。即可。
我们都知道摄像头的数据都是存储在内存中的,所以我们去找相关内存数据给其刷新到LCD上即可。
也就是我自己定义的一个函数,主要是按照图片大小来进行刷新。
关键的是我们要给其数组进行拼接,因为RGB565是16位的数据为一个颜色。
#include "hal_data.h"
#include "ceu.h"
#include "ov5640.h"
#include "board_sdram.h"
#include "glcdc_ep.h"
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
extern uint32_t g_image_width;
extern uint32_t g_image_height;
extern uint8_t * gp_image_buffer;
extern sensor_reg_t const * gp_ov5640_resolution;
extern capture_instance_t const * gp_ceu_instance;
/* Variables to store resolution information */
uint16_t g_hz_size, g_vr_size;
/* Variables used for buffer usage */
uint32_t g_buffer_size;
uint8_t * g_p_single_buffer, * g_p_double_buffer;
#define RESET_VALUE (0x00)
static void screen_display(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint32_t color);
static void color_band_display(void);
static void show_img_display(void);
/*******************************************************************************************************************//**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
void hal_entry(void)
{
/* TODO: add your own code here */
// fsp_pack_version_t version = {RESET_VALUE};
fsp_err_t err = FSP_SUCCESS;
/* Initialize SDRAM */
bsp_sdram_init();
/* Initialize GPT module */
// err = R_GPT_Open(&g_timer_periodic_ctrl, &g_timer_periodic_cfg);
// handle_error(err, " ** R_GPT_Open API FAILED ** \r\n");
/* Start GPT module to provide the 24MHz clock frequency output for the camera clock source */
// err = R_GPT_Start(&g_timer_periodic_ctrl);
// handle_error(err, " ** R_GPT_Start API FAILED ** \r\n");
/* Initialize IIC module */
err = R_SCI_B_I2C_Open(&g_sci_i2c_master_for_ov5640_ctrl, &g_sci_i2c_master_for_ov5640_cfg);
// handle_error(err, " ** R_IIC_MASTER_Open API FAILED ** \r\n");
/* Initialize OV3640 sensor with output format as YUV422 */
err = ov5640_open();
// handle_error(err, " ** ov3640_open FAILED ** \r\n");
/* Get LCDC configuration */
g_hz_size = (g_display_cfg.input[0].hsize);
g_vr_size = (g_display_cfg.input[0].vsize);
/* Initialize buffer pointers */
g_buffer_size = (uint32_t) (g_hz_size * g_vr_size * BYTES_PER_PIXEL);
g_p_single_buffer = (uint8_t *) g_display_cfg.input[0].p_base;
/* Double buffer for drawing color bands with good quality */
g_p_double_buffer = g_p_single_buffer + g_buffer_size;
/* Initialize GLCDC driver */
err = R_GLCDC_Open(&g_display_ctrl, &g_display_cfg);
/* Handle error */
// if(FSP_SUCCESS != err)
// {
// /* GLCDC initialization failed */
// APP_ERR_PRINT("\r\n ** GLCDC driver initialization FAILED ** \r\n");
// APP_ERR_TRAP(err);
// }
/* Start GLCDC display output */
err = R_GLCDC_Start(&g_display_ctrl);
/* Handle error */
// if(FSP_SUCCESS != err)
// {
// /* GLCDC initialization failed */
// APP_ERR_PRINT("\r\n ** GLCDC driver start FAILED ** \r\n");
// APP_ERR_TRAP(err);
// }
/* Clear LCD screen using appropriate co-ordinates */
screen_display((uint16_t)X1_CO_ORDINATE, (uint16_t)Y1_CO_ORDINATE, g_hz_size, g_vr_size, YELLOW);
/* Display color bands on LCD screen */
// color_band_display();
/* Main loop */
while(true)
{
/* User selects type of memory to store image and resolution of image */
selection_menu();
/* Set camera resolution specified by ov3640 array pointer */
err = ov5640_set_resolution(gp_ov5640_resolution);
// handle_error(err, " ** ov3640_set_resolution FAILED ** \r\n");
/* Perform CEU operation specified by ceu instance pointer and store image in buffer specified by image buffer pointer */
err = ceu_operation(gp_ceu_instance, gp_image_buffer, g_image_width, g_image_height);
show_img_display();
// screen_display((uint16_t)X1_CO_ORDINATE, (uint16_t)Y1_CO_ORDINATE, g_hz_size, g_vr_size, &gp_image_buffer);
// handle_error(err, " ** ceu_operation FAILED ** \r\n");
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
/*******************************************************************************************************************//**
* This function is called at various points during the startup process. This implementation uses the event that is
* called right before main() to set up the pins.
*
* @param[in] event Where at in the start up process the code is currently at
**********************************************************************************************************************/
void R_BSP_WarmStart(bsp_warm_start_event_t event)
{
if (BSP_WARM_START_RESET == event)
{
#if BSP_FEATURE_FLASH_LP_VERSION != 0
/* Enable reading from data flash. */
R_FACI_LP->DFLCTL = 1U;
/* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
* C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
#endif
}
if (BSP_WARM_START_POST_C == event)
{
/* C runtime environment and system clocks are setup. */
/* Configure pins. */
R_IOPORT_Open (&IOPORT_CFG_CTRL, &IOPORT_CFG_NAME);
#if BSP_CFG_SDRAM_ENABLED
/* Setup SDRAM and initialize it. Must configure pins first. */
R_BSP_SdramInit(true);
#endif
}
}
#if BSP_TZ_SECURE_BUILD
FSP_CPP_HEADER
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();
/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
{
}
FSP_CPP_FOOTER
#endif
static void screen_display(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint32_t color)
{
/*Declare local variables */
uint16_t start_x, start_y, display_length, display_height;
uint32_t start_addr;
/* Assign co-ordinate values and calculate start address */
start_x = x1;
start_y = y1;
start_addr = (uint32_t)((start_x * BYTES_PER_PIXEL) + (start_y * g_hz_size* BYTES_PER_PIXEL));
/* Calculate display box length and height */
display_length = (uint16_t)((x2 - x1) * BYTES_PER_PIXEL);
display_height = (y2 - y1);
/* Display required color band */
for(uint16_t ver_value = Y1_CO_ORDINATE; ver_value < (display_height - INC_DEC_VALUE); ver_value++)
{
for(uint32_t hor_value = start_addr; hor_value < (start_addr + display_length); hor_value += BYTES_PER_PIXEL)
{
*(uint32_t *) (g_p_single_buffer + hor_value) = color;
*(uint32_t *) (g_p_double_buffer + hor_value) = color;
}
start_addr = (uint32_t)(start_addr + (g_hz_size * BYTES_PER_PIXEL));
}
}
static void color_band_display(void)
{
uint16_t color[COLOR_BAND_COUNT]= {RED, GREEN, BLUE, BLACK, WHITE, YELLOW, MAGENTA, CYAN};
uint16_t width = g_vr_size/COLOR_BAND_COUNT;
for (uint8_t display_count = RESET_VALUE; display_count < COLOR_BAND_COUNT; display_count++)
{
screen_display((uint16_t)X1_CO_ORDINATE, (display_count * width), g_hz_size, (uint16_t)(((display_count * width) + width) + INC_DEC_VALUE), color[display_count]);
}
}
static void show_img_display(void)
{
// uint16_t color[COLOR_BAND_COUNT]= {RED, GREEN, BLUE, BLACK, WHITE, YELLOW, MAGENTA, CYAN};
// uint16_t width = g_vr_size/COLOR_BAND_COUNT;
uint32_t gp_image_buffer_count = 0;
for (uint16_t y_count = 0; y_count < g_image_height; y_count++)
{
for (uint16_t x_count = 0; x_count < g_image_width; x_count++)
{
screen_display((uint16_t)x_count, (uint16_t)y_count , (uint16_t)x_count+1, (uint16_t)(y_count + 2), ((gp_image_buffer[gp_image_buffer_count+1])<<8|(gp_image_buffer[gp_image_buffer_count])));
gp_image_buffer_count = gp_image_buffer_count + 2;
}
}
}
这样显示出我们天花板的图像了,刷新还比较慢,后期应该可以通过其他方式给他加速。
- 2024-08-29
-
回复了主题帖:
【瑞萨RA8D1开发板,基于M85内核的图形MCU测评】+摄像头功能测试
本来以为和我以前的一个便宜的摄像头是兼容的管脚,OV7670,结果是不匹配的。只能后期改板兼容,然后增加网口功能。
-
发表了主题帖:
【瑞萨RA8D1开发板,基于M85内核的图形MCU测评】+摄像头功能测试
我在最初制作板子的时候就已经对摄像头部分进行了预留,因为我们的拓展板接口丰富是完全可以加这些的,所以我们通过案例进行测试。像这种我们可以先参照EK-RA8D1的板卡。
在这款开发板上他接的是OV3640摄像头,我们需要换成我们预留的OV5640。
同时注意就是有些摄像头自己不带晶振需要通过管脚给其供始终信号,所以就是可以看到官方例程中是带了一个IO口输出时钟的频率的。
看下我的配置,需要配置两个IO口进行控制,然后就是CEU的配置,SDRAM的配置。
最紧张的是看错了管脚图,把串口看成了IIC,好在对上了,是可以用的串口。
不是原生的IIC,是通过SCI这种口拓展的。不过把案例的发送函数给修改掉就可以,通信测试没问题。
我就搞了两个功能,一个是SCI_IIC,一个是CEU的显示,官方是给了两种显示模式,一个VGA一个是sxga。
就是两个图片规格,不过我们用的OV5640例程出的是的RGB565的,所以初始化一个即可,想要这种格式应该要配置,看手册啥的。
其他工程就是复制,我们没用RTT的打印功能,所以要屏蔽许多的打印函数。
我们案例例程给的初始化,这里用IIC是因为摄像头的协议是SCCB总线和IIC协议十分类似,实际就是配置摄像头输出数据参数的,以及一些控制,曝光,对焦,这些,ecu相当于是读数据的,所以配置简单很多。我们直接看输出效果。
每个OV摄像头模块应该都可以配置一个彩条输出测试,我们一个测试关了,一个测试彩条输出。
这是第一个效果,输出仿真有些黑色条纹,不知道是不是画板的干扰,还是没有配置好。在摄像头采集时候也是有的。
看下实时输出的效果吧。
看读取的ID是正确的。
看实时图像也是对的,那个黑条纹应该是刷新太快的原因,暂停下来后一会就正常了。
注意格式我们的是RGB的,和官方有出入。
- 2024-08-25
-
发表了主题帖:
【瑞萨RA8D1开发板,基于M85内核的图形MCU测评】+另一串口很奇怪的问题
我们拓展有一个独立的串口,他那个I2C0实际接到了我们的J-LINK口的调试串口,所以需要重新进行对串口定义。然后就出现问题了。
从我新建工程选择的编译器来看是GCC ARM的,串口重定向和在KEIL中不一样的。
重定向一个 wirte函数。然后会报错。
编译器设置下,给里面float打印也使能。
后配置下通道,然后回调函数。
管脚配置。后面写函数发送测试,发现发送和接收到的完全不一样。很懵不清楚啥问题。
测试函数发一个hello然后也是有问题。
仿真调试,我们把断电打在后面,然后看寄存器数值。
寄存器数值是对应的第一个,到发送这边就不对了。
显示为F4,就这里很奇怪,关键这个管脚确实没有和其他相连。
仿真下一个更为清楚的,展示了我们的寄存器数值,可打印出来的还是不正确的。有没有人知道怎么回事。
- 2024-08-24
-
发表了主题帖:
【瑞萨RA8D1开发板,基于M85内核的图形MCU测评】+MIPI接口屏幕测试
Mipi接口实际要是比我们的RGB接口复杂多了,关键目前我们MIPI接口就2lane导致很多的屏幕是选择不了的,所以官方这种用MIPI已经是为我们测试过了。接下来就跟着我们踩坑吧。
我们先看下框图,实际就是在GLCDC的基础上拓展了一个MIPI芯片,所以开始初始化就得初始化我们的GLCDC的管脚,所以这些管脚外接功能就不能使用了,实际就是内部连接了。
实际我们初始化的,我还是只初始化了我们引出的管脚,其他的管脚我未使用,我们其实无所谓这些,到mipi这边简化了。我理解565,666,888这些都能驱动屏幕。
之后还是要注意初始化SDRAM不然例程还是会有问题的。
踩坑第一就是这个电源电压,我理解的一般MIPI屏幕都是1.8V通信,所以我先接的1.8V的电阻,然后不亮,才发现是要接3.3V。
厂家原理图里面给的接口是3.3V。
接下来还是要修改里面的内容。首先还是得要厂家的驱屏参数。
输入用的RGB888模式。
输出参数需要对应屏幕参数。
输出这边我们就不用管大小端了,模式注意下我们最高666输出,目前根据屏幕配置的RGB565。
Mipi的配置简单点,基本都是默认,然后注意自己生成了一个回调函数,我们需要进行编写。
原本官方例程给了一个低功耗的操作,我这里直接删除,所以魔改了很多。
然后就是配置这里,我们需要问屏厂要这个资料,所以说配置麻烦的很,尤其是这个你要对比多次在你驱动不起来的情况下。
那个回调函数就是用来确定配置表是否发送到屏了。
成功驱动后的样子给看下:
后面还有摄像头接口,屏幕也是加了触摸,我们还可以做很多东西。
主要代码给下:
/***********************************************************************************************************************
* File Name : mipi_dsi_ep.c
* Description : Contains data structures and functions setup LCD used in hal_entry.c.
**********************************************************************************************************************/
/***********************************************************************************************************************
* Copyright (c) 2023 - 2024 Renesas Electronics Corporation and/or its affiliates
*
* SPDX-License-Identifier: BSD-3-Clause
***********************************************************************************************************************/
//#include "gt911.h"
#include "mipi_dsi_ep.h"
#include "r_mipi_dsi.h"
#include "hal_data.h"
//#include "common_utils.h"
#include "board_sdram.h"
#define RESET_VALUE (0x00)
/*******************************************************************************************************************//**
* @addtogroup mipi_dsi_ep
* @{
**********************************************************************************************************************/
/* User defined functions */
static void display_draw (uint32_t * framebuffer);
//static uint8_t mipi_dsi_set_display_time (void);
//static uint8_t process_input_data(void);
//void handle_error (fsp_err_t err, const char * err_str);
//void touch_screen_reset(void);
//static fsp_err_t wait_for_mipi_dsi_event (mipi_dsi_phy_status_t event);
//static void mipi_dsi_ulps_enter(void);
//static void mipi_dsi_ulps_exit(void);
/* Variables to store resolution information */
uint16_t g_hz_size, g_vr_size;
/* Variables used for buffer usage */
uint32_t g_buffer_size, g_hstride;
uint32_t * gp_single_buffer = NULL;
uint32_t * gp_double_buffer = NULL;
uint32_t * gp_frame_buffer = NULL;
uint8_t read_data = RESET_VALUE;
uint16_t period_sec = RESET_VALUE;
volatile mipi_dsi_phy_status_t g_phy_status;
//timer_info_t timer_info = { .clock_frequency = RESET_VALUE, .count_direction = RESET_VALUE, .period_counts = RESET_VALUE };
volatile bool g_vsync_flag = RESET_FLAG;
volatile bool g_message_sent = RESET_FLAG;
volatile bool g_ulps_flag = RESET_FLAG;
volatile bool g_irq_state = RESET_FLAG;
volatile bool g_timer_overflow = RESET_FLAG;
//coord_t touch_coordinates[5];
/* This table of commands was adapted from sample code provided by FocusLCD
* Page Link: https://focuslcds.com/product/4-5-tft-display-capacitive-tp-e45ra-mw276-c/
* File Link: https://focuslcds.com/content/E45RA-MW276-C_init_code.txt
*/
const lcd_table_setting_t g_lcd_init_focuslcd[] =
{
{6, {0xFF, 0x77, 0x01, 0x00, 0x00, 0x13}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Change to Page 1 CMD
{2, {0xEF, 0x08}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Output SDA
// {2, {0x21, 0x01}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // DE = 1 Active
{6, {0xFF, 0x77, 0x01, 0x00, 0x00, 0x10}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER},
{3, {0xC0, 0x63, 0x00}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Resolution setting 480 X 800
{3, {0xC1, 0x10, 0x02}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Inversion setting
{3, {0xC2, 0x31, 0x02}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // BT 15
{2, {0xCC, 0x10}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // VGL=DDVDL+VCL-VCIP,VGH=2DDVDH-DDVDL
{17, {0xB0, 0xC0, 0x0C, 0x92, 0x0C, 0x10, 0x05, 0x02, 0x0D, 0x07, 0x21, 0x04, 0x53, 0x11, 0x6A, 0x32, 0x1F}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // avdd +5.2v,avee-5.2v
{17, {0xB1, 0xC0, 0x87, 0xCF, 0x0C, 0x10, 0x06, 0x00, 0x03, 0x08, 0x1D, 0x06, 0x54, 0x12, 0xE6, 0xEC, 0x0F}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // avdd +5.2v,avee-5.2v
{6, {0xFF, 0x77, 0x01, 0x00, 0x00, 0x11}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // VGL=DDVDL+VCL-VCIP,VGH=2DDVDH-DDVDL
{2, {0xB0, 0x5D}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Set VGH clamp level
{2, {0xB1, 0x62}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Set VGL clamp level
{2, {0xB2, 0x82}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Set VREG1
{2, {0xB3, 0x80}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Set VREG2
{2, {0xB5, 0x42}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Flicker MSB
{2, {0xB7, 0x85}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Flicker LSB
{2, {0xB8, 0x20}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Timing Adjust
{2, {0xC0, 0x09}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Timing Adjust
{2, {0xC1, 0x78}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Timing Adjust
{2, {0xC2, 0x78}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Timing Adjust
{2, {0xD0, 0x88}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Positive Gamma Control 1
{2, {0xEE, 0x42}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Positive Gamma Control 2
{100, {0}, MIPI_DSI_DISPLAY_CONFIG_DATA_DELAY_FLAG, (mipi_dsi_cmd_flag_t)0}, // Delay 5msec
{4, {0xE0, 0x00, 0x00, 0x02}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Positive Gamma Control 3
{12, {0xE1, 0x04, 0xA0, 0x06, 0xA0, 0x05, 0xA0, 0x07, 0xA0, 0x00, 0x44, 0x44}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Positive Gamma Control 4
{13, {0xE2, 0x00, 0x00, 0x33, 0x33, 0x01, 0xA0, 0x00, 0x00, 0x01, 0xA0, 0x00, 0x00}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Positive Gamma Control 4
{5, {0xE3, 0x00, 0x00, 0x33, 0x33}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Positive Gamma Control 5
{3, {0xE4, 0x44, 0x44}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Positive Gamma Control 6
{17, {0xE5, 0x0C, 0x30, 0xA0, 0xA0, 0x0E, 0x32, 0xA0, 0xA0, 0x08, 0x2C, 0xA0, 0xA0, 0x0A, 0x2E, 0xA0, 0xA0}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Positive Gamma Control 7
{5, {0xE6, 0x00, 0x00, 0x33, 0x33}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Positive Gamma Control 8
{3, {0xE7, 0x44, 0x44}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Positive Gamma Control 9
{17, {0xE8, 0x0D, 0x31, 0xA0, 0xA0, 0x0F, 0x33, 0xA0, 0xA0, 0x09, 0x2D, 0xA0, 0xA0, 0x0B, 0x2F, 0xA0, 0xA0}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Positive Gamma Control 10
{7, {0xEB, 0x00, 0x01, 0xE4, 0x44, 0x88, 0x00}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Positive Gamma Control 11
{17, {0xED, 0xFF, 0xF5, 0x47, 0x6F, 0x0B, 0xA1, 0xA2, 0xBF, 0xFB, 0x2A, 0x1A, 0xB0, 0xF6, 0x74, 0x5F, 0xFF}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Positive Gamma Control 12
{7, {0xEF, 0x08, 0x08, 0x08, 0x40, 0x3F, 0x64}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Positive Gamma Control 13
{6, {0xFF, 0x77, 0x01, 0x00, 0x00, 0x13}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Positive Gamma Control 14
{3, {0xE8, 0x00, 0x0E}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER},
{6, {0xFF, 0x77, 0x01, 0x00, 0x00, 0x00}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER},
{2, {0x11, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_0_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Positive Gamma Control 15
{200, {0}, MIPI_DSI_DISPLAY_CONFIG_DATA_DELAY_FLAG, (mipi_dsi_cmd_flag_t)0}, // Delay 5msec
{6, {0xFF, 0x77, 0x01, 0x00, 0x00, 0x13}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER},
{3, {0xE8, 0x00, 0x0C}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 1
{10, {0}, MIPI_DSI_DISPLAY_CONFIG_DATA_DELAY_FLAG, (mipi_dsi_cmd_flag_t)0}, // Delay 5msec
{3, {0xE8, 0x00, 0x00}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 1
{6, {0xFF, 0x77, 0x01, 0x00, 0x00, 0x00}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 1
{2, {0x3A, 0x70}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 1
{2, {0x29, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_0_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},// Display on
{50, {0}, MIPI_DSI_DISPLAY_CONFIG_DATA_DELAY_FLAG, (mipi_dsi_cmd_flag_t)0},
{0x00, {0}, MIPI_DSI_DISPLAY_CONFIG_DATA_END_OF_TABLE, (mipi_dsi_cmd_flag_t)0}, // End of table
// {2, {0xc1, 0x04}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 2
// {2, {0xc2, 0x0b}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 3
// {2, {0xc3, 0x0f}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 4
// {2, {0xc4, 0x09}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 5
// {2, {0xc5, 0x18}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 6
// {2, {0xc6, 0x07}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 7
// {2, {0xc7, 0x08}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 8
// {2, {0xc8, 0x05}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 9
// {2, {0xc9, 0x09}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 10
// {2, {0xca, 0x07}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 11
// {2, {0xcb, 0x05}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 12
// {2, {0xcc, 0x0c}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 13
// {2, {0xcd, 0x2d}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 14
// {2, {0xce, 0x28}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 15
// {2, {0xcf, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Negative Gamma Correction 16
//
// {6, {0xFF, 0xFF, 0x98, 0x06, 0x04, 0x06}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Change to Page 6 CMD for GIP timing
// {2, {0x00, 0x21}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x01, 0x09}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x02, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x03, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x04, 0x01}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x05, 0x01}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x06, 0x80}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x07, 0x05}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x08, 0x02}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x09, 0x80}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x0a, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x0b, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x0c, 0x0a}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x0d, 0x0a}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x0e, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x0f, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x10, 0xe0}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x11, 0xe4}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x12, 0x04}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x13, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x14, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x15, 0xc0}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x16, 0x08}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x17, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x18, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x19, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x1a, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x1b, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x1c, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
// {2, {0x1d, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 1
//
// {2, {0x20, 0x01}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 2
// {2, {0x21, 0x23}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 2
// {2, {0x22, 0x45}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 2
// {2, {0x23, 0x67}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 2
// {2, {0x24, 0x01}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 2
// {2, {0x25, 0x23}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 2
// {2, {0x26, 0x45}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 2
// {2, {0x27, 0x67}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 2
//
// {2, {0x30, 0x01}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
// {2, {0x31, 0x11}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
// {2, {0x32, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
// {2, {0x33, 0xee}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
// {2, {0x34, 0xff}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
// {2, {0x35, 0xcb}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
// {2, {0x36, 0xda}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
// {2, {0x37, 0xad}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
// {2, {0x38, 0xbc}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
// {2, {0x39, 0x76}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
// {2, {0x3a, 0x67}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
// {2, {0x3b, 0x22}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
// {2, {0x3c, 0x22}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
// {2, {0x3d, 0x22}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
// {2, {0x3e, 0x22}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
// {2, {0x3f, 0x22}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
// {2, {0x40, 0x22}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GIP Control 3
//
// {2, {0x53, 0x10}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GOUT VGLO Control
// {2, {0x54, 0x10}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // GOUT VGHO Control
//
// {6, {0xFF, 0xFF, 0x98, 0x06, 0x04, 0x07}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Change to Page 7 CMD for Normal command
// {2, {0x18, 0x1d}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // VREG1/2OUT ENABLE
// {2, {0x26, 0xb2}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
// {2, {0x02, 0x77}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
// {2, {0xe1, 0x79}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},
// {2, {0x17, 0x22}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // VGL_REG Disable
//
// {6, {0xFF, 0xFF, 0x98, 0x06, 0x04, 0x00}, MIPI_DSI_CMD_ID_DCS_LONG_WRITE, MIPI_DSI_CMD_FLAG_LOW_POWER}, // Change to Page 0 CMD for Normal command
// {120, {0}, MIPI_DSI_DISPLAY_CONFIG_DATA_DELAY_FLAG, (mipi_dsi_cmd_flag_t)0}, // Sleep out command may not be issued within 120 ms of GPIO HW reset. Wait to ensure timing maintained.
// {2, {0x11, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_0_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},// Sleep-Out
// {5, {0}, MIPI_DSI_DISPLAY_CONFIG_DATA_DELAY_FLAG, (mipi_dsi_cmd_flag_t)0}, // Delay 5msec
// {2, {0x29, 0x00}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_0_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER},// Display on
// {2, {0x3a, 0x70}, MIPI_DSI_CMD_ID_DCS_SHORT_WRITE_1_PARAM, MIPI_DSI_CMD_FLAG_LOW_POWER}, // 24-bit / pixel
//
// {0x00, {0}, MIPI_DSI_DISPLAY_CONFIG_DATA_END_OF_TABLE, (mipi_dsi_cmd_flag_t)0}, // End of table
};
/*******************************************************************************************************************//**
* [url=home.php?mod=space&uid=159083]@brief[/url] Initialize LCD
*
* @param[in] table LCD Controller Initialization structure.
* @retval None.
**********************************************************************************************************************/
void mipi_dsi_push_table (const lcd_table_setting_t *table)
{
fsp_err_t err = FSP_SUCCESS;
const lcd_table_setting_t *p_entry = table;
while (MIPI_DSI_DISPLAY_CONFIG_DATA_END_OF_TABLE != p_entry->cmd_id)
{
mipi_dsi_cmd_t msg =
{
.channel = 0,
.cmd_id = p_entry->cmd_id,
.flags = p_entry->flags,
.tx_len = p_entry->size,
.p_tx_buffer = p_entry->buffer,
};
if (MIPI_DSI_DISPLAY_CONFIG_DATA_DELAY_FLAG == msg.cmd_id)
{
R_BSP_SoftwareDelay (table->size, BSP_DELAY_UNITS_MILLISECONDS);
}
else
{
g_message_sent = false;
/* Send a command to the peripheral device */
err = R_MIPI_DSI_Command (&g_mipi_dsi0_ctrl, &msg);
// handle_error(err, "** MIPI DSI Command API failed ** \r\n");
/* Wait */
while (!g_message_sent);
}
p_entry++;
}
}
/*******************************************************************************************************************//**
* @brief Start video mode and draw color bands on the LCD screen
*
* @param[in] None.
* @retval None.
**********************************************************************************************************************/
void mipi_dsi_start_display(void)
{
fsp_err_t err = FSP_SUCCESS;
/* Get LCDC configuration */
g_hz_size = (g_display_cfg.input[0].hsize);
g_vr_size = (g_display_cfg.input[0].vsize);
g_hstride = (g_display_cfg.input[0].hstride);
/* Initialize buffer pointers */
g_buffer_size = (uint32_t) (g_hz_size * g_vr_size * BYTES_PER_PIXEL);
gp_single_buffer = (uint32_t*) g_display_cfg.input[0].p_base;
/* Double buffer for drawing color bands with good quality */
gp_double_buffer = gp_single_buffer + g_buffer_size;
/* Get timer information */
// err = R_GPT_InfoGet (&g_timer0_ctrl, &timer_info);
/* Handle error */
// handle_error(err, "** GPT InfoGet API failed ** \r\n");
/* Start video mode */
err = R_GLCDC_Start(&g_display_ctrl);
/* Handle error */
// handle_error(err, "** GLCDC Start API failed ** \r\n");
/* Enable external interrupt */
// err = R_ICU_ExternalIrqEnable(&g_external_irq_ctrl);
/* Handle error */
// handle_error(err, "** ICU ExternalIrqEnable API failed ** \r\n");
/* Swap the active framebuffer */
gp_frame_buffer = (gp_frame_buffer == gp_single_buffer) ? gp_double_buffer : gp_single_buffer;
/* Display color bands on LCD screen */
display_draw (gp_frame_buffer);
/* Now that the framebuffer is ready, update the GLCDC buffer pointer on the next Vsync */
err = R_GLCDC_BufferChange (&g_display_ctrl, (uint8_t*) gp_frame_buffer, DISPLAY_FRAME_LAYER_1);
while (true)
{
// handle_error (err, "** GLCD BufferChange API failed ** \r\n");
// uint8_t StatusRegister = RESET_VALUE;
// bool touch_flag = RESET_FLAG;
//
// /* User selects time to enter ULPS */
// err = mipi_dsi_set_display_time ();
// handle_error (err, "** mipi_dsi_set_display_time function failed ** \r\n");
//
// if (g_irq_state)
// {
// g_irq_state = RESET_FLAG;
// /* Get buffer status from gt911 device */
// memset(touch_coordinates, 0, sizeof(touch_coordinates));
// err = gt911_get_status (&StatusRegister, &touch_coordinates[0],
// sizeof(touch_coordinates)/sizeof(touch_coordinates[0]));
// handle_error (err, "** gt911_get_status function failed ** \r\n");
//
// if (StatusRegister & GT911_BUFFER_STATUS_READY)
// {
// touch_flag = SET_FLAG;
//
// /* Reset display time when touch is detected */
// err = R_GPT_Reset (&g_timer0_ctrl);
// g_timer_overflow = RESET_FLAG;
// handle_error (err, "** GPT Reset API failed ** \r\n");
// }
// }
// if (g_ulps_flag)
// {
// if (touch_flag)
// {
// /* Exit Ultra-low Power State (ULPS) and turn on the backlight */
// mipi_dsi_ulps_exit();
// }
// }
// else
// {
// if (!g_timer_overflow)
// {
// /* Swap the active framebuffer */
// gp_frame_buffer = (gp_frame_buffer == gp_single_buffer) ? gp_double_buffer : gp_single_buffer;
//
// /* Display color bands on LCD screen */
// display_draw (gp_frame_buffer);
//
// /* Now that the framebuffer is ready, update the GLCDC buffer pointer on the next Vsync */
// err = R_GLCDC_BufferChange (&g_display_ctrl, (uint8_t*) gp_frame_buffer, DISPLAY_FRAME_LAYER_1);
// handle_error (err, "** GLCD BufferChange API failed ** \r\n");
//
// /* Wait for a Vsync event */
// g_vsync_flag = RESET_FLAG;
// while (RESET_FLAG == g_vsync_flag);
// }
// else
// {
// /* Enter Ultra-low Power State (ULPS) and turn off the backlight */
// mipi_dsi_ulps_enter();
// }
// }
}
}
/*******************************************************************************************************************//**
* @brief User-defined function to draw the current display to a framebuffer.
*
* @param[in] framebuffer Pointer to frame buffer.
* @retval None.
**********************************************************************************************************************/
static void display_draw (uint32_t * framebuffer)
{
/* Draw buffer */
uint32_t color[COLOR_BAND_COUNT]= {BLUE, LIME, RED, BLACK, WHITE, YELLOW, AQUA, MAGENTA};
uint16_t bit_width = g_hz_size / COLOR_BAND_COUNT;
for (uint32_t y = 0; y < g_vr_size; y++)
{
for (uint32_t x = 0; x < g_hz_size; x ++)
{
uint32_t bit = x / bit_width;
framebuffer[x] = color [bit];
}
framebuffer += g_hstride;
}
}
/*******************************************************************************************************************//**
* @brief This function is used initialize related module and start display operation.
*
* @param[in] none
* @retval none
**********************************************************************************************************************/
void mipi_dsi_entry(void)
{
fsp_err_t err = FSP_SUCCESS;
fsp_pack_version_t version = {RESET_VALUE};
/* version get API for FLEX pack information */
// R_FSP_VersionGet(&version);
/* Project information printed on the Console */
// APP_PRINT(BANNER_INFO, EP_VERSION, version.version_id_b.major, version.version_id_b.minor, version.version_id_b.patch);
// APP_PRINT(EP_INFO);
// APP_PRINT(MIPI_DSI_MENU);
/* Initialize SDRAM. */
bsp_sdram_init();
/* Initialize GLCDC module */
err = R_GLCDC_Open(&g_display_ctrl, &g_display_cfg);
/* Handle error */
// handle_error(err, "** GLCDC driver initialization FAILED ** \r\n");
/* Initialize GPT module */
// err = R_GPT_Open(&g_timer0_ctrl, &g_timer0_cfg);
/* Handle error */
// handle_error(err, "** R_GPT_Open API failed ** \r\n");
/* LCD reset */
// touch_screen_reset();
/* Initialize IIC MASTER module */
// err = R_IIC_MASTER_Open(&g_i2c_master_ctrl, &g_i2c_master_cfg);
/* Handle error */
// handle_error(err, "** IIC MASTER Open API failed ** \r\n");
/* Initialize LCD. */
mipi_dsi_push_table(g_lcd_init_focuslcd);
/* Initialize ICU module */
// err = R_ICU_ExternalIrqOpen(&g_external_irq_ctrl, &g_external_irq_cfg);
/* Handle error */
// handle_error(err, "** ICU ExternalIrqOpen API failed ** \r\n");
/* Start display 8-color bars */
mipi_dsi_start_display();
}
void mipi_dsi0_callback(mipi_dsi_callback_args_t *p_args)
{
switch (p_args->event)
{
case MIPI_DSI_EVENT_SEQUENCE_0:
{
if (MIPI_DSI_SEQUENCE_STATUS_DESCRIPTORS_FINISHED == p_args->tx_status)
{
g_message_sent = SET_FLAG;
}
break;
}
case MIPI_DSI_EVENT_PHY:
{
g_phy_status |= p_args->phy_status;
break;
}
default:
{
break;
}
}
}
/*******************************************************************************************************************//**
* @} (end addtogroup mipi_dsi_ep)
**********************************************************************************************************************/
-
回复了主题帖:
【瑞萨RA8D1开发板,基于M85内核的图形MCU测评】+测试RGB屏幕
秦天qintian0303 发表于 2024-8-24 10:01
这测试板比软件更加费劲
都难,硬件花时间规划,想啥都加,软件就是要深入去了解。
- 2024-08-23
-
回复了主题帖:
【瑞萨RA8D1开发板,基于M85内核的图形MCU测评】+测试RGB屏幕
代码工程
-
发表了主题帖:
【瑞萨RA8D1开发板,基于M85内核的图形MCU测评】+测试RGB屏幕
底板绘制好了,然后我们可以开始测试我们的接口了,先测试下我们的50P的RGB接口。
看下我们的接口我们默认的TCON是随便接的。然后我们现在只能是RGB666模式,有低位两个接地了。
看手册,我们是RGB666的大端接法,程序中不要错了。我们看下框架吧,我对RGB的驱动还是比较陌生的。
我理解Graphics 1和Graphics 2,两个是负责图像数据处理的,两个数据应该可以叠加显示,但目前我看都是用一个,只需要往Graphics 的data buffer里面填充数据,然后他就能刷新到我们屏幕上。
接下来就是进入e2 studio里面创建工程,实际我感觉用会e2 studio要方便很多。配置工程要用到的管脚。
配置有一个方便的功能,可以选择AB,这样下面的管脚选错就会报出来,我们用到的都是LCD_B的管脚,在管脚说明上也是有的。
然后配置下外部的SDRAM,不使用外部的SDRAM主要应该是怕缓存不够。
输入这里选择RGB565或者RGB888这种只是输入图像的数据,这里就决定了我们的图像到时候怎么拼接,送到我们的Graphics 的data buffer中。宽高和我们显示屏一致。
输出这里我们要配置我们屏幕的时序,然后什么样类型数据,是RGB格式还是BGR,因为存在这种比较方便我们布线,还有大小端。我们自然要配置大端RGB格式。
之后就是程序了,这里我用了下RA8D1的官方例程,每次实际就是用指针对里面数据进行更新。加人我们用的SDRAM驱动。同时控制背光脚,我们先不配置为PWM方式,我们改成直接IO输出方便测试。
直接上电就为高,方便测试。
接上屏幕可以直接看到显示,通过仿真我们也是可以看到图像数据的,主要就是那个buff。
仿真也是可以看到里面的数据。
主要代码:
#include "hal_data.h"
#include "glcdc_ep.h"
#include "board_sdram.h"
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
/* Variables to store resolution information */
uint16_t g_hz_size, g_vr_size;
/* Variables used for buffer usage */
uint32_t g_buffer_size;
uint8_t * g_p_single_buffer, * g_p_double_buffer;
#define RESET_VALUE (0x00)
static void screen_display(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint32_t color);
static void color_band_display(void);
/*******************************************************************************************************************//**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
void hal_entry(void)
{
fsp_err_t err = FSP_SUCCESS;
/* TODO: add your own code here */
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
bsp_sdram_init();
/* Get LCDC configuration */
g_hz_size = (g_display_cfg.input[0].hsize);
g_vr_size = (g_display_cfg.input[0].vsize);
/* Initialize buffer pointers */
g_buffer_size = (uint32_t) (g_hz_size * g_vr_size * BYTES_PER_PIXEL);
g_p_single_buffer = (uint8_t *) g_display_cfg.input[0].p_base;
/* Double buffer for drawing color bands with good quality */
g_p_double_buffer = g_p_single_buffer + g_buffer_size;
/* Initialize GLCDC driver */
err = R_GLCDC_Open(&g_display_ctrl, &g_display_cfg);
/* Initialize GLCDC driver */
err = R_GLCDC_Open(&g_display_ctrl, &g_display_cfg);
/* Handle error */
// if(FSP_SUCCESS != err)
// {
// /* GLCDC initialization failed */
// APP_ERR_PRINT("\r\n ** GLCDC driver initialization FAILED ** \r\n");
// APP_ERR_TRAP(err);
// }
/* Start GLCDC display output */
err = R_GLCDC_Start(&g_display_ctrl);
/* Handle error */
// if(FSP_SUCCESS != err)
// {
// /* GLCDC initialization failed */
// APP_ERR_PRINT("\r\n ** GLCDC driver start FAILED ** \r\n");
// APP_ERR_TRAP(err);
// }
/* Clear LCD screen using appropriate co-ordinates */
screen_display((uint16_t)X1_CO_ORDINATE, (uint16_t)Y1_CO_ORDINATE, g_hz_size, g_vr_size, BLACK);
/* Display color bands on LCD screen */
color_band_display();
}
/*******************************************************************************************************************//**
* This function is called at various points during the startup process. This implementation uses the event that is
* called right before main() to set up the pins.
*
* @param[in] event Where at in the start up process the code is currently at
**********************************************************************************************************************/
void R_BSP_WarmStart(bsp_warm_start_event_t event)
{
if (BSP_WARM_START_RESET == event)
{
#if BSP_FEATURE_FLASH_LP_VERSION != 0
/* Enable reading from data flash. */
R_FACI_LP->DFLCTL = 1U;
/* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
* C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
#endif
}
if (BSP_WARM_START_POST_C == event)
{
/* C runtime environment and system clocks are setup. */
/* Configure pins. */
R_IOPORT_Open (&IOPORT_CFG_CTRL, &IOPORT_CFG_NAME);
#if BSP_CFG_SDRAM_ENABLED
/* Setup SDRAM and initialize it. Must configure pins first. */
R_BSP_SdramInit(true);
#endif
}
}
static void screen_display(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint32_t color)
{
/*Declare local variables */
uint16_t start_x, start_y, display_length, display_height;
uint32_t start_addr;
/* Assign co-ordinate values and calculate start address */
start_x = x1;
start_y = y1;
start_addr = (uint32_t)((start_x * BYTES_PER_PIXEL) + (start_y * g_hz_size* BYTES_PER_PIXEL));
/* Calculate display box length and height */
display_length = (uint16_t)((x2 - x1) * BYTES_PER_PIXEL);
display_height = (y2 - y1);
/* Display required color band */
for(uint16_t ver_value = Y1_CO_ORDINATE; ver_value < (display_height - INC_DEC_VALUE); ver_value++)
{
for(uint32_t hor_value = start_addr; hor_value < (start_addr + display_length); hor_value += BYTES_PER_PIXEL)
{
*(uint32_t *) (g_p_single_buffer + hor_value) = color;
*(uint32_t *) (g_p_double_buffer + hor_value) = color;
}
start_addr = (uint32_t)(start_addr + (g_hz_size * BYTES_PER_PIXEL));
}
}
static void color_band_display(void)
{
uint16_t color[COLOR_BAND_COUNT]= {RED, GREEN, BLUE, BLACK, WHITE, YELLOW, MAGENTA, CYAN};
uint16_t width = g_vr_size/COLOR_BAND_COUNT;
for (uint8_t display_count = RESET_VALUE; display_count < COLOR_BAND_COUNT; display_count++)
{
screen_display((uint16_t)X1_CO_ORDINATE, (display_count * width), g_hz_size, (uint16_t)(((display_count * width) + width) + INC_DEC_VALUE), color[display_count]);
}
}
#if BSP_TZ_SECURE_BUILD
FSP_CPP_HEADER
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();
/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
{
}
FSP_CPP_FOOTER
#endif
- 2024-08-21
-
回复了主题帖:
【瑞萨RA8D1开发板,基于M85内核的图形MCU测评】+底板拓展板设计
秦天qintian0303 发表于 2024-8-21 08:44
这屏是多大的,什么分辨率的?
3.5寸480*800分辨率
- 2024-08-20
-
发表了主题帖:
【瑞萨RA8D1开发板,基于M85内核的图形MCU测评】+底板拓展板设计
我们板子上面预留的2.54接口还是比较少的,主要集中在底部的两个接口上。所以还是需要制作一款底板的。
根据其接口我们进行制作底板。
在其说明中给到了底板需要的座子型号,这样可以方便我们购买和画封装,我们选择使用立创EDA进行绘制,给到了这款底座的封装。
本次板子主要测试其驱屏以及摄像头驱动。所以优化了很多功能,不过有第一版经验,后续在弄也简单了。
我做了两个屏幕兼容,一种是50P的RGB还有一个是mipi和RGB兼容的屏幕。
最终是这样的。其中他给了一个DXF文件,立创可以导入这样可以确定板子的尺寸位置。
新的屏幕也到了。
- 2024-08-12
-
回复了主题帖:
【瑞萨RA8D1开发板,基于M85内核的图形MCU测评】+需要制作底板,进行其他功能测试
Jacktang 发表于 2024-8-12 07:24
淘宝找的几个2Lane的屏幕应该是可以用的
很难找
- 2024-08-11
-
发表了主题帖:
【瑞萨RA8D1开发板,基于M85内核的图形MCU测评】+需要制作底板,进行其他功能测试
实际到测试阶段,板载功能还是不太能够满足我们测试需求了,所以我们需要制作拓展板进行测试其他功能。下面就参考下案例,简单介绍下底板要求。
首先就是其接口目前都标注了功能,我们的LCD目前是RGB666和MIPI 2Lane的。RGB屏幕好弄,不行就是去掉几个高位接地就行,色彩上的偏差,MIPI 2Lane其实还是比较鸡肋了,他注定是驱动不了大的屏幕的。
我在淘宝找了几个2Lane的屏幕。
基本上驱动芯片的是ST7701S的,这种支持2Lane通信。回头可以按照此接口进行测试。
官方其实给了一个表,进行配置功能,底板也不能兼容太多功能,网口和摄像头是不能共用的。你可以按照你的需要进行配置然后测试。
之后就是按照说明,底座也是给了型号,绘制想要测试的功能,此版我只想引出测试屏幕的接口,和一些外设功能接口,其他的可以再做其他板子测试。
标注了灰色的接口是尽量不要使用的,是和核心板进行复用的,他特意挑选了SDRAM中的不重要信号进行了底板复用,QSPI也是留出来了,因为其本身内部Flash是够用的,看你自己取舍。除开核心板的SD卡槽,还有多余一路可以接SD wifi设备,可以考虑连接一个。
其余的主板的高速USB口比较值得研究。
案例中可以看到有很多例程。
- 2024-08-09
-
发表了主题帖:
【2024 DigiKey 创意大赛】树莓派开箱
树莓派5,4G版本,后续等内存便宜了再买内存扩容下。
必选物料选择的是BME280温湿度计,和一款磁编码位置传感器。
- 2024-07-21
-
发表了主题帖:
【瑞萨RA8D1开发板,基于M85内核的图形MCU测评】+瑞萨软件探索
瑞萨目前有了自己的IDE,在Git上也有开源的软件,所以有点迷惑,今天探索在win下瑞萨软件的下载配置。
https://github.com/renesas/fsp/releases
我们先看下git上发布的,基本上就是三个东西,一个是FSP的包,下面的是包含最新FSP的 e2 stuido的包和一个ra smart配置的包。基本上第一个是你安装了e2 Stuido的时候可以用,他用于升级e2 studio内部的FSP支持包,第二个是本身就带了e2 Studio时候,安装完可以直接打开使用,第三个就是外部配置工程用的,可以生成Keil和IAR的工程。
所有软件包是默认安装在C盘下的Renesas里面。独立安装e2 studio的话会有一个单独的文件夹,其他的都是在RA目录下。
如安装后两个exe就是如上,这时候在e2 stuido,这个开头的里面就是安装好了FSP的最新版本,里面也有一个e2 stuido软件打开既可使用。
一般情况都是单独安装e2 stuido,然后更新他,这时候就用第一个FSP pack这个东西,把他安装到e2 stuido路径下既可。
这样完成后,我们再进IDE就会有新的FSP支持出来。
他给的多了一个单独的,所以挺迷惑的,两种方式都能更新到最新的FSP,所以都可以用。
- 2024-07-11
-
发表了主题帖:
【瑞萨RA8D1开发板,基于M85内核的图形MCU测评】+开箱点灯
开箱
拿到板子有段时间了,先开箱下吧,先说明下,这款小板子实际是野火为瑞萨设计的,目前应该是有两版硬件的存在,我手上的是最开始的版本,第一版,硬件有所区别,主要是SD卡部分。
核心板是单独有个包装盒的,另外的一个盒子附赠了,USB-C的线,因为板载是有调试口的,同时两个C口,所以附赠了一跟C口线。还有一些螺丝柱的东西,他是有拓展的接口的,后期我们制作底板给引出一些其他功能。
这是板子正面,是包含了调试器,一个外置的sdram。一个flash芯片,按键和指示灯。
板子所用核心是这系列中最高的规格的,内置就有2M的Flash大小。
点灯环境
这里面我们要用到RA Smart配置工具,他可以为我们生成三种开发工具的工程,一个是KEIL,一个IAR,一个他们自己的E2 Studio。
我就先配置了一个LED灯的。
然后在生成工程中进行修改。
增加灯闪烁的功能。
这些配置可能都没有,需要填入进去,不然无法下载。之后通过J-link口就可以下载了。
- 2024-06-26
-
回复了主题帖:
测评入围名单: 瑞萨RA8D1开发板,基于M85内核的图形MCU
个人信息无误,确认可以完成测评分享计划