forked from xuos/xiuos
				
			
		
			
				
	
	
		
			500 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			500 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
/*
 | 
						|
* Copyright (c) 2020 AIIT XUOS Lab
 | 
						|
* XiUOS is licensed under Mulan PSL v2.
 | 
						|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
 | 
						|
* You may obtain a copy of Mulan PSL v2 at:
 | 
						|
*        http://license.coscl.org.cn/MulanPSL2
 | 
						|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
						|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
						|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
						|
* See the Mulan PSL v2 for more details.
 | 
						|
*/
 | 
						|
 | 
						|
/**
 | 
						|
* @file:    test_lcd.c
 | 
						|
* @brief:   a application of dac function
 | 
						|
* @version: 2.0
 | 
						|
* @author:  AIIT XUOS Lab
 | 
						|
* @date:    2022/1/11
 | 
						|
*/
 | 
						|
 | 
						|
#include <transform.h>
 | 
						|
 | 
						|
#ifdef ADD_NUTTX_FETURES
 | 
						|
 | 
						|
#ifdef CONFIG_K210_LCD
 | 
						|
void LcdDemo(void)
 | 
						|
{
 | 
						|
    int lcd_fd = PrivOpen("/dev/lcd_dev",O_RDWR);
 | 
						|
    LcdWriteParam disp_info;
 | 
						|
 | 
						|
    disp_info.type = 0;
 | 
						|
    disp_info.string_info.x_pos = 80;
 | 
						|
    disp_info.string_info.y_pos = 80;
 | 
						|
    disp_info.string_info.width = 250;
 | 
						|
    disp_info.string_info.height = 24;
 | 
						|
    disp_info.string_info.font_size = 24;
 | 
						|
    disp_info.string_info.addr = "wecome test lcd";
 | 
						|
    disp_info.string_info.font_color = GREEN;
 | 
						|
    disp_info.string_info.back_color = BLUE;
 | 
						|
    PrivWrite(lcd_fd, &disp_info, sizeof(LcdWriteParam));
 | 
						|
    PrivTaskDelay(2000);
 | 
						|
 | 
						|
    disp_info.type = 1;
 | 
						|
    lv_color_t redcolor = {
 | 
						|
        .ch = {
 | 
						|
            .red   = 0b11111,
 | 
						|
            .green = 0,
 | 
						|
            .blue  = 0
 | 
						|
        }
 | 
						|
    };
 | 
						|
    disp_info.pixel_info.x_startpos =  0;
 | 
						|
    disp_info.pixel_info.x_endpos =  50;
 | 
						|
    disp_info.pixel_info.y_startpos = 0;
 | 
						|
    disp_info.pixel_info.y_endpos = 50;
 | 
						|
    disp_info.pixel_info.pixel_color = &redcolor;
 | 
						|
    PrivWrite(lcd_fd, &disp_info, sizeof(LcdWriteParam));
 | 
						|
    PrivTaskDelay(2000);
 | 
						|
    
 | 
						|
    disp_info.type = SHOW_TRIANGLE;
 | 
						|
    PrivWrite(lcd_fd, &disp_info, sizeof(LcdWriteParam));
 | 
						|
}
 | 
						|
 | 
						|
#else
 | 
						|
/****************************************************************************
 | 
						|
 * Preprocessor Definitions
 | 
						|
 ****************************************************************************/
 | 
						|
 | 
						|
#define NCOLORS 6
 | 
						|
#define TEST_FB_DEV "/dev/fb0"
 | 
						|
 | 
						|
/****************************************************************************
 | 
						|
 * Private Types
 | 
						|
 ****************************************************************************/
 | 
						|
 | 
						|
struct fb_state_s
 | 
						|
{
 | 
						|
  int fd;
 | 
						|
  struct fb_videoinfo_s vinfo;
 | 
						|
  struct fb_planeinfo_s pinfo;
 | 
						|
#ifdef CONFIG_FB_OVERLAY
 | 
						|
  struct fb_overlayinfo_s oinfo;
 | 
						|
#endif
 | 
						|
  FAR void *fbmem;
 | 
						|
};
 | 
						|
 | 
						|
/****************************************************************************
 | 
						|
 * Private Data
 | 
						|
 ****************************************************************************/
 | 
						|
 | 
						|
static const char g_default_fbdev[] = TEST_FB_DEV;
 | 
						|
 | 
						|
/* Violet-Blue-Green-Yellow-Orange-Red */
 | 
						|
 | 
						|
static const uint32_t g_rgb24[NCOLORS] =
 | 
						|
{
 | 
						|
  RGB24_VIOLET, RGB24_BLUE, RGB24_GREEN,
 | 
						|
  RGB24_YELLOW, RGB24_ORANGE, RGB24_RED
 | 
						|
};
 | 
						|
 | 
						|
static const uint16_t g_rgb16[NCOLORS] =
 | 
						|
{
 | 
						|
  RGB16_VIOLET, RGB16_BLUE, RGB16_GREEN,
 | 
						|
  RGB16_YELLOW, RGB16_ORANGE, RGB16_RED
 | 
						|
};
 | 
						|
 | 
						|
static const uint8_t g_rgb8[NCOLORS] =
 | 
						|
{
 | 
						|
  RGB8_VIOLET, RGB8_BLUE, RGB8_GREEN,
 | 
						|
  RGB8_YELLOW, RGB8_ORANGE, RGB8_RED
 | 
						|
};
 | 
						|
 | 
						|
/****************************************************************************
 | 
						|
 * Private Functions
 | 
						|
 ****************************************************************************/
 | 
						|
 | 
						|
/****************************************************************************
 | 
						|
 * draw_rect
 | 
						|
 ****************************************************************************/
 | 
						|
 | 
						|
static void draw_rect32(FAR struct fb_state_s *state,
 | 
						|
                        FAR struct fb_area_s *area, int color)
 | 
						|
{
 | 
						|
  FAR uint32_t *dest;
 | 
						|
  FAR uint8_t *row;
 | 
						|
  int x;
 | 
						|
  int y;
 | 
						|
 | 
						|
  row = (FAR uint8_t *)state->fbmem + state->pinfo.stride * area->y;
 | 
						|
  for (y = 0; y < area->h; y++)
 | 
						|
    {
 | 
						|
      dest = ((FAR uint32_t *)row) + area->x;
 | 
						|
      for (x = 0; x < area->w; x++)
 | 
						|
        {
 | 
						|
          *dest++ = g_rgb24[color];
 | 
						|
        }
 | 
						|
 | 
						|
      row += state->pinfo.stride;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void draw_rect16(FAR struct fb_state_s *state,
 | 
						|
                        FAR struct fb_area_s *area, int color)
 | 
						|
{
 | 
						|
  FAR uint16_t *dest;
 | 
						|
  FAR uint8_t *row;
 | 
						|
  int x;
 | 
						|
  int y;
 | 
						|
 | 
						|
  row = (FAR uint8_t *)state->fbmem + state->pinfo.stride * area->y;
 | 
						|
  for (y = 0; y < area->h; y++)
 | 
						|
    {
 | 
						|
      dest = ((FAR uint16_t *)row) + area->x;
 | 
						|
      for (x = 0; x < area->w; x++)
 | 
						|
        {
 | 
						|
          *dest++ = g_rgb16[color];
 | 
						|
        }
 | 
						|
 | 
						|
      row += state->pinfo.stride;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void draw_rect8(FAR struct fb_state_s *state,
 | 
						|
                       FAR struct fb_area_s *area, int color)
 | 
						|
{
 | 
						|
  FAR uint8_t *dest;
 | 
						|
  FAR uint8_t *row;
 | 
						|
  int x;
 | 
						|
  int y;
 | 
						|
 | 
						|
  row = (FAR uint8_t *)state->fbmem + state->pinfo.stride * area->y;
 | 
						|
  for (y = 0; y < area->h; y++)
 | 
						|
    {
 | 
						|
      dest = row + area->x;
 | 
						|
      for (x = 0; x < area->w; x++)
 | 
						|
        {
 | 
						|
          *dest++ = g_rgb8[color];
 | 
						|
        }
 | 
						|
 | 
						|
      row += state->pinfo.stride;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void draw_rect1(FAR struct fb_state_s *state,
 | 
						|
                       FAR struct fb_area_s *area, int color)
 | 
						|
{
 | 
						|
  FAR uint8_t *pixel;
 | 
						|
  FAR uint8_t *row;
 | 
						|
  uint8_t color8 = (color & 1) == 0 ? 0 : 0xff;
 | 
						|
  uint8_t lmask;
 | 
						|
  uint8_t rmask;
 | 
						|
  int startx;
 | 
						|
  int endx;
 | 
						|
  int x;
 | 
						|
  int y;
 | 
						|
 | 
						|
  /* Calculate the framebuffer address of the first row to draw on */
 | 
						|
 | 
						|
  row    = (FAR uint8_t *)state->fbmem + state->pinfo.stride * area->y;
 | 
						|
 | 
						|
  /* Calculate the start byte position rounding down so that we get the
 | 
						|
   * first byte containing any part of the pixel sequence.  Then calculate
 | 
						|
   * the last byte position with a ceil() operation so it includes any final
 | 
						|
   * final pixels of the sequence.
 | 
						|
   */
 | 
						|
 | 
						|
  startx = (area->x >> 3);
 | 
						|
  endx   = ((area->x + area->w + 6) >> 3);
 | 
						|
 | 
						|
  /* Calculate a mask on the first and last bytes of the sequence that may
 | 
						|
   * not be completely filled with pixel.
 | 
						|
   */
 | 
						|
 | 
						|
  lmask  = 0xff << (8 - (area->x & 7));
 | 
						|
  rmask  = 0xff >> ((area->x + area->w - 1) & 7);
 | 
						|
 | 
						|
  /* Now draw each row, one-at-a-time */
 | 
						|
 | 
						|
  for (y = 0; y < area->h; y++)
 | 
						|
    {
 | 
						|
      /* 'pixel' points to the 1st pixel the next row */
 | 
						|
 | 
						|
      pixel = row + startx;
 | 
						|
 | 
						|
      /* Special case: The row is less no more than one byte wide */
 | 
						|
 | 
						|
      if (startx == endx)
 | 
						|
        {
 | 
						|
          uint8_t mask = lmask | rmask;
 | 
						|
 | 
						|
          *pixel = (*pixel & mask) | (color8 & ~mask);
 | 
						|
        }
 | 
						|
      else
 | 
						|
        {
 | 
						|
          /* Special case the first byte of the row */
 | 
						|
 | 
						|
          *pixel = (*pixel & lmask) | (color8 & ~lmask);
 | 
						|
          pixel++;
 | 
						|
 | 
						|
          /* Handle all middle bytes in the row */
 | 
						|
 | 
						|
          for (x = startx + 1; x < endx; x++)
 | 
						|
            {
 | 
						|
              *pixel++ = color8;
 | 
						|
            }
 | 
						|
 | 
						|
          /* Handle the final byte of the row */
 | 
						|
 | 
						|
          *pixel = (*pixel & rmask) | (color8 & ~rmask);
 | 
						|
        }
 | 
						|
 | 
						|
      row += state->pinfo.stride;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void draw_rect(FAR struct fb_state_s *state,
 | 
						|
                      FAR struct fb_area_s *area, int color)
 | 
						|
{
 | 
						|
#ifdef CONFIG_FB_UPDATE
 | 
						|
  int ret;
 | 
						|
#endif
 | 
						|
 | 
						|
  switch (state->pinfo.bpp)
 | 
						|
    {
 | 
						|
      case 32:
 | 
						|
        draw_rect32(state, area, color);
 | 
						|
        break;
 | 
						|
 | 
						|
      case 16:
 | 
						|
        draw_rect16(state, area, color);
 | 
						|
        break;
 | 
						|
 | 
						|
      case 8:
 | 
						|
      default:
 | 
						|
        draw_rect8(state, area, color);
 | 
						|
        break;
 | 
						|
 | 
						|
      case 1:
 | 
						|
        draw_rect1(state, area, color);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
#ifdef CONFIG_FB_UPDATE
 | 
						|
  ret = ioctl(state->fd, FBIO_UPDATE,
 | 
						|
              (unsigned long)((uintptr_t)area));
 | 
						|
  if (ret < 0)
 | 
						|
    {
 | 
						|
      int errcode = errno;
 | 
						|
      fprintf(stderr, "ERROR: ioctl(FBIO_UPDATE) failed: %d\n",
 | 
						|
              errcode);
 | 
						|
    }
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
/****************************************************************************
 | 
						|
 * Public Functions
 | 
						|
 ****************************************************************************/
 | 
						|
 | 
						|
/****************************************************************************
 | 
						|
 * fb_main
 | 
						|
 ****************************************************************************/
 | 
						|
 | 
						|
int test_lcd(int argc, FAR char *argv[])
 | 
						|
{
 | 
						|
  FAR const char *fbdev = g_default_fbdev;
 | 
						|
  struct fb_state_s state;
 | 
						|
  struct fb_area_s area;
 | 
						|
  int nsteps;
 | 
						|
  int xstep;
 | 
						|
  int ystep;
 | 
						|
  int width;
 | 
						|
  int height;
 | 
						|
  int color;
 | 
						|
  int x;
 | 
						|
  int y;
 | 
						|
  int ret;
 | 
						|
 | 
						|
  /* There is a single required argument:  The path to the framebuffer
 | 
						|
   * driver.
 | 
						|
   */
 | 
						|
 | 
						|
  if (argc == 2)
 | 
						|
    {
 | 
						|
      fbdev = argv[1];
 | 
						|
    }
 | 
						|
  else if (argc != 1)
 | 
						|
    {
 | 
						|
      fprintf(stderr, "ERROR: Single argument required\n");
 | 
						|
      fprintf(stderr, "USAGE: %s [<fb-driver-path>]\n", argv[0]);
 | 
						|
      return EXIT_FAILURE;
 | 
						|
    }
 | 
						|
 | 
						|
  /* Open the framebuffer driver */
 | 
						|
 | 
						|
  state.fd = open(fbdev, O_RDWR);
 | 
						|
  if (state.fd < 0)
 | 
						|
    {
 | 
						|
      int errcode = errno;
 | 
						|
      fprintf(stderr, "ERROR: Failed to open %s: %d\n", fbdev, errcode);
 | 
						|
      return EXIT_FAILURE;
 | 
						|
    }
 | 
						|
 | 
						|
  /* Get the characteristics of the framebuffer */
 | 
						|
 | 
						|
  ret = ioctl(state.fd, FBIOGET_VIDEOINFO,
 | 
						|
              (unsigned long)((uintptr_t)&state.vinfo));
 | 
						|
  if (ret < 0)
 | 
						|
    {
 | 
						|
      int errcode = errno;
 | 
						|
      fprintf(stderr, "ERROR: ioctl(FBIOGET_VIDEOINFO) failed: %d\n",
 | 
						|
              errcode);
 | 
						|
      close(state.fd);
 | 
						|
      return EXIT_FAILURE;
 | 
						|
    }
 | 
						|
  printf("2022-10-14 Mr. Wang commit LCD\n");
 | 
						|
  printf("VideoInfo:\n");
 | 
						|
  printf("      fmt: %u\n", state.vinfo.fmt);
 | 
						|
  printf("     xres: %u\n", state.vinfo.xres);
 | 
						|
  printf("     yres: %u\n", state.vinfo.yres);
 | 
						|
  printf("  nplanes: %u\n", state.vinfo.nplanes);
 | 
						|
 | 
						|
#ifdef CONFIG_FB_OVERLAY
 | 
						|
  printf("noverlays: %u\n", state.vinfo.noverlays);
 | 
						|
 | 
						|
  /* Select the first overlay, which should be the composed framebuffer */
 | 
						|
 | 
						|
  ret = ioctl(state.fd, FBIO_SELECT_OVERLAY, 0);
 | 
						|
  if (ret < 0)
 | 
						|
    {
 | 
						|
      int errcode = errno;
 | 
						|
      fprintf(stderr, "ERROR: ioctl(FBIO_SELECT_OVERLAY) failed: %d\n",
 | 
						|
              errcode);
 | 
						|
      close(state.fd);
 | 
						|
      return EXIT_FAILURE;
 | 
						|
    }
 | 
						|
 | 
						|
  /* Get the first overlay information */
 | 
						|
 | 
						|
  state.oinfo.overlay = 0;
 | 
						|
  ret = ioctl(state.fd, FBIOGET_OVERLAYINFO,
 | 
						|
                        (unsigned long)((uintptr_t)&state.oinfo));
 | 
						|
  if (ret < 0)
 | 
						|
    {
 | 
						|
      int errcode = errno;
 | 
						|
      fprintf(stderr, "ERROR: ioctl(FBIOGET_OVERLAYINFO) failed: %d\n",
 | 
						|
              errcode);
 | 
						|
      close(state.fd);
 | 
						|
      return EXIT_FAILURE;
 | 
						|
    }
 | 
						|
 | 
						|
  printf("OverlayInfo (overlay 0):\n");
 | 
						|
  printf("    fbmem: %p\n", state.oinfo.fbmem);
 | 
						|
  printf("    fblen: %lu\n", (unsigned long)state.oinfo.fblen);
 | 
						|
  printf("   stride: %u\n", state.oinfo.stride);
 | 
						|
  printf("  overlay: %u\n", state.oinfo.overlay);
 | 
						|
  printf("      bpp: %u\n", state.oinfo.bpp);
 | 
						|
  printf("    blank: %u\n", state.oinfo.blank);
 | 
						|
  printf("chromakey: 0x%08" PRIx32 "\n", state.oinfo.chromakey);
 | 
						|
  printf("    color: 0x%08" PRIx32 "\n", state.oinfo.color);
 | 
						|
  printf("   transp: 0x%02x\n", state.oinfo.transp.transp);
 | 
						|
  printf("     mode: %u\n", state.oinfo.transp.transp_mode);
 | 
						|
  printf("     area: (%u,%u) => (%u,%u)\n",
 | 
						|
                      state.oinfo.sarea.x, state.oinfo.sarea.y,
 | 
						|
                      state.oinfo.sarea.w, state.oinfo.sarea.h);
 | 
						|
  printf("     accl: %" PRIu32 "\n", state.oinfo.accl);
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
  ret = ioctl(state.fd, FBIOGET_PLANEINFO,
 | 
						|
              (unsigned long)((uintptr_t)&state.pinfo));
 | 
						|
  if (ret < 0)
 | 
						|
    {
 | 
						|
      int errcode = errno;
 | 
						|
      fprintf(stderr, "ERROR: ioctl(FBIOGET_PLANEINFO) failed: %d\n",
 | 
						|
              errcode);
 | 
						|
      close(state.fd);
 | 
						|
      return EXIT_FAILURE;
 | 
						|
    }
 | 
						|
 | 
						|
  printf("PlaneInfo (plane 0):\n");
 | 
						|
  printf("    fbmem: %p\n", state.pinfo.fbmem);
 | 
						|
  printf("    fblen: %lu\n", (unsigned long)state.pinfo.fblen);
 | 
						|
  printf("   stride: %u\n", state.pinfo.stride);
 | 
						|
  printf("  display: %u\n", state.pinfo.display);
 | 
						|
  printf("      bpp: %u\n", state.pinfo.bpp);
 | 
						|
 | 
						|
  /* Only these pixel depths are supported.  viinfo.fmt is ignored, only
 | 
						|
   * certain color formats are supported.
 | 
						|
   */
 | 
						|
 | 
						|
  if (state.pinfo.bpp != 32 && state.pinfo.bpp != 16 &&
 | 
						|
      state.pinfo.bpp != 8  && state.pinfo.bpp != 1)
 | 
						|
    {
 | 
						|
      fprintf(stderr, "ERROR: bpp=%u not supported\n", state.pinfo.bpp);
 | 
						|
      close(state.fd);
 | 
						|
      return EXIT_FAILURE;
 | 
						|
    }
 | 
						|
 | 
						|
  /* mmap() the framebuffer.
 | 
						|
   *
 | 
						|
   * NOTE: In the FLAT build the frame buffer address returned by the
 | 
						|
   * FBIOGET_PLANEINFO IOCTL command will be the same as the framebuffer
 | 
						|
   * address.  mmap(), however, is the preferred way to get the framebuffer
 | 
						|
   * address because in the KERNEL build, it will perform the necessary
 | 
						|
   * address mapping to make the memory accessible to the application.
 | 
						|
   */
 | 
						|
 | 
						|
  state.fbmem = mmap(NULL, state.pinfo.fblen, PROT_READ | PROT_WRITE,
 | 
						|
                     MAP_SHARED | MAP_FILE, state.fd, 0);
 | 
						|
  if (state.fbmem == MAP_FAILED)
 | 
						|
    {
 | 
						|
      int errcode = errno;
 | 
						|
      fprintf(stderr, "ERROR: ioctl(FBIOGET_PLANEINFO) failed: %d\n",
 | 
						|
              errcode);
 | 
						|
      close(state.fd);
 | 
						|
      return EXIT_FAILURE;
 | 
						|
    }
 | 
						|
 | 
						|
  printf("Mapped FB: %p\n", state.fbmem);
 | 
						|
 | 
						|
  /* Draw some rectangles */
 | 
						|
 | 
						|
  nsteps = 2 * (NCOLORS - 1) + 1;
 | 
						|
  xstep  = state.vinfo.xres / nsteps;
 | 
						|
  ystep  = state.vinfo.yres / nsteps;
 | 
						|
  width  = state.vinfo.xres;
 | 
						|
  height = state.vinfo.yres;
 | 
						|
 | 
						|
  for (x = 0, y = 0, color = 0;
 | 
						|
       color < NCOLORS;
 | 
						|
       x += xstep, y += ystep, color++)
 | 
						|
    {
 | 
						|
      area.x = x;
 | 
						|
      area.y = y;
 | 
						|
      area.w = width;
 | 
						|
      area.h = height;
 | 
						|
 | 
						|
      printf("%2d: (%3d,%3d) (%3d,%3d)\n",
 | 
						|
             color, area.x, area.y, area.w, area.h);
 | 
						|
 | 
						|
      draw_rect(&state, &area, color);
 | 
						|
      usleep(500 * 1000);
 | 
						|
 | 
						|
      width  -= (2 * xstep);
 | 
						|
      height -= (2 * ystep);
 | 
						|
    }
 | 
						|
 | 
						|
  printf("Test finished\n");
 | 
						|
  munmap(state.fbmem, state.pinfo.fblen);
 | 
						|
  close(state.fd);
 | 
						|
  return EXIT_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
void LcdDemo(void)
 | 
						|
{
 | 
						|
    test_lcd(1, NULL);
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
#endif
 |