From 80686e6bc4cb17e9d856647084725203fa63ebe6 Mon Sep 17 00:00:00 2001
From: guowenxue <guowenxue@gmail.com>
Date: Mon, 19 Aug 2024 16:47:42 +0800
Subject: [PATCH] Add LCD API examples

---
 hal/lcd/drm/drm_test.c |  154 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 154 insertions(+), 0 deletions(-)

diff --git a/hal/lcd/drm/drm_test.c b/hal/lcd/drm/drm_test.c
new file mode 100644
index 0000000..e3cf6ca
--- /dev/null
+++ b/hal/lcd/drm/drm_test.c
@@ -0,0 +1,154 @@
+#define _GNU_SOURCE
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <time.h>
+#include <unistd.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+struct buffer_object {
+    
+	uint32_t width;
+	uint32_t height;
+	uint32_t pitch;
+	uint32_t handle;
+	uint32_t size;
+	uint32_t *vaddr;
+	uint32_t fb_id;
+};
+
+struct buffer_object buf[3];
+
+static int modeset_create_fb(int fd, struct buffer_object *bo, uint32_t color)
+{
+    
+	struct drm_mode_create_dumb create = {
+    };
+ 	struct drm_mode_map_dumb map = {
+    };
+	uint32_t i;
+
+	create.width = bo->width;
+	create.height = bo->height;
+	create.bpp = 32;
+	drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);
+
+	bo->pitch = create.pitch;
+	bo->size = create.size;
+	bo->handle = create.handle;
+	drmModeAddFB(fd, bo->width, bo->height, 24, 32, bo->pitch,
+			   bo->handle, &bo->fb_id);
+
+	map.handle = create.handle;
+	drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map);
+
+	bo->vaddr = mmap(0, create.size, PROT_READ | PROT_WRITE,
+			MAP_SHARED, fd, map.offset);
+
+	for (i = 0; i < (bo->size / 4); i++)
+		bo->vaddr[i] = color;
+
+	return 0;
+}
+
+static void modeset_destroy_fb(int fd, struct buffer_object *bo)
+{
+    
+	struct drm_mode_destroy_dumb destroy = {
+    };
+
+	drmModeRmFB(fd, bo->fb_id);
+
+	munmap(bo->vaddr, bo->size);
+
+	destroy.handle = bo->handle;
+	drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy);
+}
+
+int main(int argc, char **argv)
+{
+	char             *dri_card="/dev/dri/card0";
+	int               fd;
+	uint32_t          conn_id;
+	uint32_t          crtc_id;
+	drmModeConnector *conn;
+	drmModeRes       *res;
+
+	if( argc != 2 )
+	{
+		printf("Usage: %s /dev/dri/card0\n", argv[0]);
+		return 1;
+	}
+	else
+	{
+		dri_card = argv[1];
+	}
+
+	fd = open(dri_card, O_RDWR | O_CLOEXEC);
+	if( fd < 0)
+	{
+		printf("Open '%s' failure: %s\n", dri_card, strerror(errno));
+		return 0;
+	}
+
+	res = drmModeGetResources(fd);
+	if( !res )
+	{
+		printf("drmModeGetResources() failure\n");
+		return 0;
+	}
+
+	crtc_id = res->crtcs[0];
+	conn_id = res->connectors[0];
+
+	conn = drmModeGetConnector(fd, conn_id);
+	if( !conn )
+	{
+		printf("drmModeGetConnector() failure\n");
+		return 0;
+	}
+
+	buf[0].width = conn->modes[0].hdisplay;
+	buf[0].height = conn->modes[0].vdisplay;
+	buf[1].width = conn->modes[0].hdisplay;
+	buf[1].height = conn->modes[0].vdisplay;
+	buf[2].width = conn->modes[0].hdisplay;
+	buf[2].height = conn->modes[0].vdisplay;
+
+	printf("DRM create framebuffer now.\n");
+	modeset_create_fb(fd, &buf[0], 0xff0000);
+	modeset_create_fb(fd, &buf[1], 0x00ff00);
+	modeset_create_fb(fd, &buf[2], 0x0000ff);
+
+	printf("Show red screen on LCD.\n");
+	drmModeSetCrtc(fd, crtc_id, buf[0].fb_id, 0, 0, &conn_id, 1, &conn->modes[0]);
+	getchar();
+
+	printf("Show green screen on LCD.\n");
+	drmModeSetCrtc(fd, crtc_id, buf[1].fb_id, 0, 0, &conn_id, 1, &conn->modes[0]);
+	getchar();
+
+	printf("Show blue screen on LCD.\n");
+	drmModeSetCrtc(fd, crtc_id, buf[2].fb_id, 0, 0, &conn_id, 1, &conn->modes[0]);
+	getchar();
+
+	printf("DRM destroy framebuffer now.\n");
+	modeset_destroy_fb(fd, &buf[0]);
+	modeset_destroy_fb(fd, &buf[1]);
+	modeset_destroy_fb(fd, &buf[2]);
+
+	drmModeFreeConnector(conn);
+	return 0;
+	drmModeFreeResources(res);
+
+	close(fd);
+
+	return 0;
+}
+

--
Gitblit v1.9.1