Squashed commit of the following:
apps/graphics/ft80x: Replace polling logic with gentler signal logic when waitinf for the CMD FIFO to become empty. apps/examples/ft80x: Add first co-processor example. apps/graphics: Extend library to manage display lists either in display memory (RAM DL) or provided directly to th co-processor FIFO (RAM CMD). apps/examples/ft80x: Some minor clean-up. Trivial changes for coprocessor support.
This commit is contained in:
parent
2f2fb92ae3
commit
ecfdf073fc
@ -141,16 +141,18 @@ extern "C"
|
||||
/* GPU Primitive display examples */
|
||||
|
||||
#ifndef CONFIG_EXAMPLES_FT80X_EXCLUDE_BITMAPS
|
||||
int ft80x_bitmaps(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
int ft80x_prim_bitmaps(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
#endif
|
||||
int ft80x_points(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
int ft80x_lines(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
int ft80x_linestrip(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
int ft80x_edgestrip_r(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
int ft80x_rectangles(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
int ft80x_prim_points(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
int ft80x_prim_lines(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
int ft80x_prim_linestrip(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
int ft80x_prim_edgestrip_r(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
int ft80x_prim_rectangles(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
|
||||
/* Co-processor display examples */
|
||||
|
||||
int ft80x_coproc_progressbar(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -54,8 +54,322 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name:
|
||||
* Name: ft80x_coproc_progressbar
|
||||
*
|
||||
* Description:
|
||||
* Demonstrate the progress bar command
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_coproc_progressbar(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
{
|
||||
int16_t xoffset;
|
||||
int16_t yoffset;
|
||||
int16_t ydist = FT80X_DISPLAY_WIDTH / 12;
|
||||
int16_t ysz = FT80X_DISPLAY_WIDTH / 24;
|
||||
int ret;
|
||||
|
||||
/* Formatted output chunks */
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
struct ft80x_cmd32_s clearrgb;
|
||||
struct ft80x_cmd32_s clear;
|
||||
struct ft80x_cmd32_s colorrgb;
|
||||
} a;
|
||||
struct
|
||||
{
|
||||
struct ft80x_cmd32_s colorrgb;
|
||||
struct ft80x_cmd_bgcolor_s bgcolor;
|
||||
struct ft80x_cmd_progress_s progress;
|
||||
struct ft80x_cmd32_s colora;
|
||||
struct ft80x_cmd_text_s text;
|
||||
} b;
|
||||
struct
|
||||
{
|
||||
struct ft80x_cmd32_s colorrgb;
|
||||
struct ft80x_cmd_bgcolor_s bgcolor;
|
||||
} c;
|
||||
struct
|
||||
{
|
||||
struct ft80x_cmd_progress_s progress;
|
||||
struct ft80x_cmd_bgcolor_s bgcolor;
|
||||
} d;
|
||||
struct
|
||||
{
|
||||
struct ft80x_cmd_progress_s progress;
|
||||
struct ft80x_cmd_text_s text;
|
||||
} e;
|
||||
struct ft80x_cmd_progress_s progress;
|
||||
} cmds;
|
||||
|
||||
/* Create the hardware display list */
|
||||
|
||||
ret = ft80x_dl_start(fd, buffer, true);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_start failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
cmds.a.clearrgb.cmd = FT80X_CLEAR_COLOR_RGB(64, 64, 64);
|
||||
cmds.a.clear.cmd = FT80X_CLEAR(1 ,1, 1);
|
||||
cmds.a.colorrgb.cmd = FT80X_COLOR_RGB(0xff, 0xff, 0xff);
|
||||
|
||||
/* Copy the commands into the display list */
|
||||
|
||||
ret = ft80x_dl_data(fd, buffer, &cmds.a, sizeof(cmds.a));
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Draw progress bar with flat effect */
|
||||
|
||||
cmds.b.colorrgb.cmd = FT80X_COLOR_RGB(0xff, 0xff, 0xff);
|
||||
|
||||
cmds.b.bgcolor.cmd = FT80X_CMD_BGCOLOR; /* Background color */
|
||||
cmds.b.bgcolor.c = 0x404080;
|
||||
|
||||
cmds.b.progress.cmd = FT80X_CMD_PROGRESS; /* Progress bar */
|
||||
cmds.b.progress.x = 20;
|
||||
cmds.b.progress.y = 10;
|
||||
cmds.b.progress.w = 120;
|
||||
cmds.b.progress.h = 20;
|
||||
cmds.b.progress.options = FT80X_OPT_FLAT;
|
||||
cmds.b.progress.val = 50;
|
||||
cmds.b.progress.range = 100;
|
||||
|
||||
cmds.b.colora.cmd = FT80X_COLOR_A(255); /* Color A */
|
||||
|
||||
cmds.b.text.cmd = FT80X_CMD_TEXT; /* Text */
|
||||
cmds.b.text.x = 20;
|
||||
cmds.b.text.y = 40;
|
||||
cmds.b.text.font = 26;
|
||||
cmds.b.text.options = 0;
|
||||
|
||||
ret = ft80x_dl_data(fd, buffer, &cmds.b, sizeof(cmds.b));
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ft80x_dl_string(fd, buffer, "Flat effect");
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_string failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Draw progress bar with 3d effect */
|
||||
|
||||
cmds.b.colorrgb.cmd = FT80X_COLOR_RGB(0x00, 0xff, 0x00);
|
||||
|
||||
cmds.b.bgcolor.cmd = FT80X_CMD_BGCOLOR; /* Background color */
|
||||
cmds.b.bgcolor.c = 0x800000;
|
||||
|
||||
cmds.b.progress.cmd = FT80X_CMD_PROGRESS; /* Progress bar */
|
||||
cmds.b.progress.x = 180;
|
||||
cmds.b.progress.y = 10;
|
||||
cmds.b.progress.w = 120;
|
||||
cmds.b.progress.h = 20;
|
||||
cmds.b.progress.options = 0;
|
||||
cmds.b.progress.val = 75;
|
||||
cmds.b.progress.range = 100;
|
||||
|
||||
cmds.b.colora.cmd = FT80X_COLOR_A(255); /* Color A */
|
||||
|
||||
cmds.b.text.cmd = FT80X_CMD_TEXT; /* Text */
|
||||
cmds.b.text.x = 180;
|
||||
cmds.b.text.y = 40;
|
||||
cmds.b.text.font = 26;
|
||||
cmds.b.text.options = 0;
|
||||
|
||||
ret = ft80x_dl_data(fd, buffer, &cmds.b, sizeof(cmds.b));
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ft80x_dl_string(fd, buffer, "3D effect");
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_string failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Draw progress bar with 3d effect and string on top */
|
||||
|
||||
cmds.b.colorrgb.cmd = FT80X_COLOR_RGB(0xff, 0x00, 0x00);
|
||||
|
||||
cmds.b.bgcolor.cmd = FT80X_CMD_BGCOLOR; /* Background color */
|
||||
cmds.b.bgcolor.c = 0x000080;
|
||||
|
||||
cmds.b.progress.cmd = FT80X_CMD_PROGRESS; /* Progress bar */
|
||||
cmds.b.progress.x = 30;
|
||||
cmds.b.progress.y = 60;
|
||||
cmds.b.progress.w = 120;
|
||||
cmds.b.progress.h = 30;
|
||||
cmds.b.progress.options = 0;
|
||||
cmds.b.progress.val = 19660;
|
||||
cmds.b.progress.range = 65535;
|
||||
|
||||
cmds.b.colora.cmd = FT80X_COLOR_RGB(0xff, 0xff, 0xff);
|
||||
|
||||
cmds.b.text.cmd = FT80X_CMD_TEXT; /* Text */
|
||||
cmds.b.text.x = 78;
|
||||
cmds.b.text.y = 68;
|
||||
cmds.b.text.font = 26;
|
||||
cmds.b.text.options = 0;
|
||||
|
||||
ret = ft80x_dl_data(fd, buffer, &cmds.b, sizeof(cmds.b));
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ft80x_dl_string(fd, buffer, "3D effect");
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_string failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
xoffset = 20;
|
||||
yoffset = 120;
|
||||
|
||||
cmds.c.colorrgb.cmd = FT80X_COLOR_RGB(0x00, 0xa0, 0x00);
|
||||
|
||||
cmds.c.bgcolor.cmd = FT80X_CMD_BGCOLOR; /* Background color */
|
||||
cmds.c.bgcolor.c = 0x800000;
|
||||
|
||||
ret = ft80x_dl_data(fd, buffer, &cmds.c, sizeof(cmds.c));
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
cmds.d.progress.cmd = FT80X_CMD_PROGRESS; /* Progress bar */
|
||||
cmds.d.progress.x = xoffset;
|
||||
cmds.d.progress.y = yoffset;
|
||||
cmds.d.progress.w = 150;
|
||||
cmds.d.progress.h = ysz;
|
||||
cmds.d.progress.options = 0;
|
||||
cmds.d.progress.val = 10;
|
||||
cmds.d.progress.range = 100;
|
||||
|
||||
cmds.d.bgcolor.cmd = FT80X_CMD_BGCOLOR; /* Background color */
|
||||
cmds.d.bgcolor.c = 0x000080;
|
||||
|
||||
ret = ft80x_dl_data(fd, buffer, &cmds.d, sizeof(cmds.d));
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
yoffset += ydist;
|
||||
|
||||
cmds.d.progress.cmd = FT80X_CMD_PROGRESS; /* Progress bar */
|
||||
cmds.d.progress.x = xoffset;
|
||||
cmds.d.progress.y = yoffset;
|
||||
cmds.d.progress.w = 150;
|
||||
cmds.d.progress.h = ysz;
|
||||
cmds.d.progress.options = 0;
|
||||
cmds.d.progress.val = 40;
|
||||
cmds.d.progress.range = 100;
|
||||
|
||||
cmds.d.bgcolor.cmd = FT80X_CMD_BGCOLOR; /* Background color */
|
||||
cmds.d.bgcolor.c = 0xffff00;
|
||||
|
||||
ret = ft80x_dl_data(fd, buffer, &cmds.d, sizeof(cmds.d));
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
yoffset += ydist;
|
||||
|
||||
cmds.d.progress.cmd = FT80X_CMD_PROGRESS; /* Progress bar */
|
||||
cmds.d.progress.x = xoffset;
|
||||
cmds.d.progress.y = yoffset;
|
||||
cmds.d.progress.w = 150;
|
||||
cmds.d.progress.h = ysz;
|
||||
cmds.d.progress.options = 0;
|
||||
cmds.d.progress.val = 70;
|
||||
cmds.d.progress.range = 100;
|
||||
|
||||
cmds.d.bgcolor.cmd = FT80X_CMD_BGCOLOR; /* Background color */
|
||||
cmds.d.bgcolor.c = 0x808080;
|
||||
|
||||
ret = ft80x_dl_data(fd, buffer, &cmds.d, sizeof(cmds.d));
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
yoffset += ydist;
|
||||
|
||||
cmds.e.progress.cmd = FT80X_CMD_PROGRESS; /* Progress bar */
|
||||
cmds.e.progress.x = xoffset;
|
||||
cmds.e.progress.y = yoffset;
|
||||
cmds.e.progress.w = 150;
|
||||
cmds.e.progress.h = ysz;
|
||||
cmds.e.progress.options = 0;
|
||||
cmds.e.progress.val = 90;
|
||||
cmds.e.progress.range = 100;
|
||||
|
||||
cmds.e.text.cmd = FT80X_CMD_TEXT; /* Text */
|
||||
cmds.e.text.x = xoffset + 180;
|
||||
cmds.e.text.y = 80;
|
||||
cmds.e.text.font = 26;
|
||||
cmds.e.text.options = 0;
|
||||
|
||||
ret = ft80x_dl_data(fd, buffer, &cmds.e, sizeof(cmds.e));
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ft80x_dl_string(fd, buffer, "40% TopBottom");
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_string failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
cmds.progress.cmd = FT80X_CMD_PROGRESS; /* Progress bar */
|
||||
cmds.progress.x = xoffset + 180;
|
||||
cmds.progress.y = 100;
|
||||
cmds.progress.w = ysz;
|
||||
cmds.progress.h = 150;
|
||||
cmds.progress.options = 0;
|
||||
cmds.progress.val = 40;
|
||||
cmds.progress.range = 100;
|
||||
|
||||
ret = ft80x_dl_data(fd, buffer, &cmds.progress, sizeof(cmds.progress));
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
/* And terminate the display list */
|
||||
|
||||
ret = ft80x_dl_end(fd, buffer);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_end failed: %d\n", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -66,34 +66,34 @@ struct ft80x_exampleinfo_s
|
||||
|
||||
/* GPU Primitive display examples. Most primitives are used, but not many of
|
||||
* their various options.
|
||||
*
|
||||
* FUNCTION PRIMITIVE USED DESCRIPTION
|
||||
* ---------------------- --------------- ----------------------------------
|
||||
* ft80x_prim_bitmaps BITMAPS Bitmap drawing primitive
|
||||
* ft80x_prim_points POINTS Point drawing primitive
|
||||
* ft80x_prim_lines LINES Line drawing primitive
|
||||
* ft80x_prim_linestrip LINE_STRIP Line strip drawing primitive
|
||||
* ft80x_prim_edgestrip_r EDGE_STRIP_R Edge strip right side drawing
|
||||
primitive
|
||||
* --None-- EDGE_STRIP_L Edge strip left side drawing
|
||||
primitive
|
||||
* --None-- EDGE_STRIP_A Edge strip above side drawing
|
||||
primitive
|
||||
* --None-- EDGE_STRIP_B Edge strip below side drawing
|
||||
primitive
|
||||
* ft80x_prim_rectangles RECTS Rectangle drawing primitive
|
||||
*/
|
||||
|
||||
static const struct ft80x_exampleinfo_s g_primitives[] =
|
||||
{
|
||||
/* NAME EXAMPLE ENTRY PRIMITIVE */
|
||||
#ifndef CONFIG_EXAMPLES_FT80X_EXCLUDE_BITMAPS
|
||||
{ "Bitmaps", ft80x_bitmaps }, /* BITMAPS Bitmap drawing
|
||||
* primitive */
|
||||
{ "Bitmaps", ft80x_prim_bitmaps },
|
||||
#endif
|
||||
{ "Points", ft80x_points }, /* POINTS Point drawing
|
||||
* primitive */
|
||||
{ "Lines", ft80x_lines }, /* LINES Line drawing */
|
||||
{ "Line Strip", ft80x_linestrip }, /* LINE_STRIP Line strip drawing
|
||||
* primitive */
|
||||
{ "Edge Strip R", ft80x_edgestrip_r }, /* EDGE_STRIP_R Edge strip right
|
||||
* side drawing
|
||||
* primitive */
|
||||
/* EDGE_STRIP_L Edge strip left
|
||||
* side drawing
|
||||
* primitive */
|
||||
/* EDGE_STRIP_A Edge strip above
|
||||
* side drawing
|
||||
* primitive */
|
||||
/* EDGE_STRIP_B Edge strip below
|
||||
* side drawing
|
||||
* primitive */
|
||||
{ "Rectangles", ft80x_rectangles } /* RECTS Rectangle drawing
|
||||
* primitive */
|
||||
{ "Points", ft80x_prim_points },
|
||||
{ "Lines", ft80x_prim_lines },
|
||||
{ "Line Strip", ft80x_prim_linestrip },
|
||||
{ "Edge Strip R", ft80x_prim_edgestrip_r },
|
||||
{ "Rectangles", ft80x_prim_rectangles }
|
||||
};
|
||||
|
||||
#define NPRIMITIVES (sizeof(g_primitives) / sizeof(ft80x_example_t))
|
||||
@ -101,39 +101,36 @@ static const struct ft80x_exampleinfo_s g_primitives[] =
|
||||
/* Co-processor display examples. Only a small, but interesting, subset
|
||||
* here co-processor command are exercised and these with only a few of the
|
||||
* possible options.
|
||||
*
|
||||
* FUNCTION CoProc CMD USED DESCRIPTION
|
||||
* ----------------------- --------------- ----------------------------------
|
||||
* --None-- CMD_TEXT Draw text
|
||||
* --None-- CMD_BUTTON Draw a button
|
||||
* --None-- CMD_CLOCK Draw an analog clock
|
||||
* --None-- CMD_GAUGE Draw a gauge
|
||||
* --None-- CMD_KEYS Draw a row of keys
|
||||
* ft80x_coproc_progressbar CMD_PROGRESS Draw a progress bar
|
||||
* --None-- CMD_SCROLLBAR Draw a scroll bar
|
||||
* --None-- CMD_SLIDER Draw a slider
|
||||
* --None-- CMD_DIAL Draw a rotary dial control
|
||||
* --None-- CMD_TOGGLE Draw a toggle switch
|
||||
* --None-- CMD_NUMBER Draw a decimal number
|
||||
* --None-- CMD_CALIBRATE Execute the touch screen
|
||||
calibration routine
|
||||
* --None-- CMD_SPINNER Start an animated spinner
|
||||
* --None-- CMD_SCREENSAVER Start an animated screensaver
|
||||
* --None-- CMD_SKETCH Start a continuous sketch update
|
||||
* --None-- CMD_SNAPSHOT Take a snapshot of the current
|
||||
screen
|
||||
* --None-- CMD_LOGO Play device log animation
|
||||
*/
|
||||
|
||||
/* CMD_TEXT Draw text */
|
||||
/* CMD_BUTTON Draw a button */
|
||||
/* CMD_CLOCK Draw an analog
|
||||
* clock */
|
||||
/* CMD_GAUGE Draw a gauge */
|
||||
/* CMD_KEYS Draw a row of
|
||||
* keys */
|
||||
/* CMD_PROGRESS Draw a progress
|
||||
* bar */
|
||||
/* CMD_SCROLLBAR Draw a scroll bar */
|
||||
/* CMD_SLIDER Draw a slider */
|
||||
/* CMD_DIAL Draw a rotary
|
||||
* dial control */
|
||||
/* CMD_TOGGLE Draw a toggle
|
||||
* switch */
|
||||
/* CMD_NUMBER Draw a decimal
|
||||
* number */
|
||||
/* CMD_CALIBRATE Execute the touch
|
||||
* screen calibration
|
||||
* routine */
|
||||
/* CMD_SPINNER Start an animated
|
||||
* spinner */
|
||||
/* CMD_SCREENSAVER Start an animated
|
||||
* screensaver */
|
||||
/* CMD_SKETCH Start a continuous
|
||||
* sketch update */
|
||||
/* CMD_SNAPSHOT Take a snapshot
|
||||
* of the current
|
||||
* screen */
|
||||
/* CMD_LOGO Play device logo
|
||||
* animation */
|
||||
static const struct ft80x_exampleinfo_s g_coproc[] =
|
||||
{
|
||||
{ "Progress Bar", ft80x_coproc_progressbar }
|
||||
};
|
||||
|
||||
#define NCOPROC (sizeof(g_primitives) / sizeof(ft80x_example_t))
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
@ -155,7 +152,7 @@ static int ft80x_showname(int fd, FAR struct ft80x_dlbuffer_s *buffer,
|
||||
|
||||
/* Create the display list */
|
||||
|
||||
ret = ft80x_dl_start(fd, buffer);
|
||||
ret = ft80x_dl_start(fd, buffer, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_start failed: %d\n", ret);
|
||||
@ -286,7 +283,11 @@ int ft80x_main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* Perform tests on a few of the FT80x Co-processor functions */
|
||||
#warning missing logic
|
||||
|
||||
for (i = 0; i < NCOPROC; i++)
|
||||
{
|
||||
(void)ft80x_example(fd, buffer, &g_coproc[i]);
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
close(fd);
|
||||
|
@ -62,7 +62,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_EXAMPLES_FT80X_EXCLUDE_BITMAPS
|
||||
int ft80x_bitmaps(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
int ft80x_prim_bitmaps(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
{
|
||||
FAR const struct ft80x_bitmaphdr_s *bmhdr = &g_lenaface_bmhdr;
|
||||
uint32_t cmds[18];
|
||||
@ -119,7 +119,7 @@ int ft80x_bitmaps(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
|
||||
/* Create the hardware display list */
|
||||
|
||||
ret = ft80x_dl_create(fd, buffer, cmds, 18);
|
||||
ret = ft80x_dl_create(fd, buffer, cmds, 18, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_create failed: %d\n", ret);
|
||||
@ -138,7 +138,7 @@ int ft80x_bitmaps(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_points(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
int ft80x_prim_points(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
{
|
||||
uint32_t cmds[15];
|
||||
int ret;
|
||||
@ -169,7 +169,7 @@ int ft80x_points(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
|
||||
/* Create the hardware display list */
|
||||
|
||||
ret = ft80x_dl_create(fd, buffer, cmds, 15);
|
||||
ret = ft80x_dl_create(fd, buffer, cmds, 15, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_create failed: %d\n", ret);
|
||||
@ -187,7 +187,7 @@ int ft80x_points(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_lines(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
int ft80x_prim_lines(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
{
|
||||
uint32_t cmds[14];
|
||||
uint32_t height;
|
||||
@ -224,7 +224,7 @@ int ft80x_lines(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
|
||||
/* Create the hardware display list */
|
||||
|
||||
ret = ft80x_dl_create(fd, buffer, cmds, 14);
|
||||
ret = ft80x_dl_create(fd, buffer, cmds, 14, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_create failed: %d\n", ret);
|
||||
@ -242,7 +242,7 @@ int ft80x_lines(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_linestrip(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
int ft80x_prim_linestrip(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
{
|
||||
uint32_t cmds[7];
|
||||
int ret;
|
||||
@ -261,7 +261,7 @@ int ft80x_linestrip(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
|
||||
/* Create the hardware display list */
|
||||
|
||||
ret = ft80x_dl_create(fd, buffer, cmds, 7);
|
||||
ret = ft80x_dl_create(fd, buffer, cmds, 7, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_create failed: %d\n", ret);
|
||||
@ -279,7 +279,7 @@ int ft80x_linestrip(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_edgestrip_r(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
int ft80x_prim_edgestrip_r(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
{
|
||||
uint32_t cmds[7];
|
||||
int ret;
|
||||
@ -291,14 +291,14 @@ int ft80x_edgestrip_r(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
cmds[2] = FT80X_CLEAR(1 ,1 ,1);
|
||||
cmds[3] = FT80X_BEGIN(FT80X_PRIM_EDGE_STRIP_R);
|
||||
cmds[4] = FT80X_VERTEX2F(16 * 16,16 * 16);
|
||||
cmds[5] = FT80X_VERTEX2F(((FT80X_DISPLAY_WIDTH * 2) / 3 ) * 16,
|
||||
((FT80X_DISPLAY_HEIGHT * 2) / 3 ) * 16);
|
||||
cmds[5] = FT80X_VERTEX2F(((FT80X_DISPLAY_WIDTH * 2) / 3) * 16,
|
||||
((FT80X_DISPLAY_HEIGHT * 2) / 3) * 16);
|
||||
cmds[6] = FT80X_VERTEX2F((FT80X_DISPLAY_WIDTH - 80) * 16,
|
||||
(FT80X_DISPLAY_HEIGHT - 20) * 16);
|
||||
|
||||
/* Create the hardware display list */
|
||||
|
||||
ret = ft80x_dl_create(fd, buffer, cmds, 7);
|
||||
ret = ft80x_dl_create(fd, buffer, cmds, 7, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_create failed: %d\n", ret);
|
||||
@ -316,7 +316,7 @@ int ft80x_edgestrip_r(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_rectangles(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
int ft80x_prim_rectangles(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
{
|
||||
uint32_t cmds[14];
|
||||
uint32_t width;
|
||||
@ -358,7 +358,7 @@ int ft80x_rectangles(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
|
||||
/* Create the hardware display list */
|
||||
|
||||
ret = ft80x_dl_create(fd, buffer, cmds, 14);
|
||||
ret = ft80x_dl_create(fd, buffer, cmds, 14, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_create failed: %d\n", ret);
|
||||
|
@ -20,6 +20,14 @@ config GRAPHICS_FT80X_BUFSIZE
|
||||
This size should be an even multiple of 4 bytes (otherwise, the size
|
||||
will be truncated to the next lower, aligned size).
|
||||
|
||||
config GRAPHICS_FT80X_CMDEMPTY_SIGNAL
|
||||
int "CMDEMPTY event signal"
|
||||
default 18
|
||||
range l 31
|
||||
---help---
|
||||
This is the signal that will be received when the co-processor CMD
|
||||
FIFO becomes empty.
|
||||
|
||||
config GRAPHICS_FT80X_DEBUG_ERROR
|
||||
bool "Enable error output"
|
||||
default y
|
||||
|
@ -40,7 +40,7 @@ include $(APPDIR)/Make.defs
|
||||
# FTDI/BridgeTek FT80x library
|
||||
|
||||
ASRCS =
|
||||
CSRCS = ft80x_dl.c ft80x_ramg.c ft80x_regs.c
|
||||
CSRCS = ft80x_dl.c ft80x_ramg.c ft80x_ramdl.c ft80x_ramcmd.c ft80x_regs.c
|
||||
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
|
@ -114,6 +114,8 @@ extern "C"
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
struct ft80x_dlbuffer_s; /* Forward reference3 */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_getreg8/16/32
|
||||
*
|
||||
@ -156,6 +158,81 @@ int ft80x_putreg8(int fd, uint32_t addr, uint8_t value);
|
||||
int ft80x_putreg16(int fd, uint32_t addr, uint16_t value);
|
||||
int ft80x_putreg32(int fd, uint32_t addr, uint32_t value);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_ramdl_rewind
|
||||
*
|
||||
* Description:
|
||||
* Reset to the start of RAM DL memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor of the FT80x device. Opened by the caller
|
||||
* with write access.
|
||||
* buffer - An instance of struct ft80x_dlbuffer_s allocated by the caller.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. A negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_ramdl_rewind(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_ramdl_append
|
||||
*
|
||||
* Description:
|
||||
* Append new display list data to RAM DL
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor of the FT80x device. Opened by the caller
|
||||
* with write access.
|
||||
* buffer - An instance of struct ft80x_dlbuffer_s allocated by the caller.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. A negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_ramdl_append(int fd, FAR struct ft80x_dlbuffer_s *buffer,
|
||||
FAR const void *data, size_t len);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_ramcmd_append
|
||||
*
|
||||
* Description:
|
||||
* Append new display list data to RAM CMD
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor of the FT80x device. Opened by the caller
|
||||
* with write access.
|
||||
* buffer - An instance of struct ft80x_dlbuffer_s allocated by the caller.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. A negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_ramcmd_append(int fd, FAR struct ft80x_dlbuffer_s *buffer,
|
||||
FAR const void *data, size_t len);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_ramcmd_waitfifoempty
|
||||
*
|
||||
* Description:
|
||||
* Wait until co processor completes the operation and the FIFO is again
|
||||
* empty.
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor of the FT80x device. Opened by the caller
|
||||
* with write access.
|
||||
* buffer - An instance of struct ft80x_dlbuffer_s allocated by the caller.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. A negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_ramcmd_waitfifoempty(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_dl_swap
|
||||
*
|
||||
|
@ -64,6 +64,8 @@
|
||||
*
|
||||
* Input Parameters:
|
||||
* buffer - An instance of struct ft80x_dlbuffer_s allocated by the caller.
|
||||
* data - Data being written.
|
||||
* len - Number of bytes being written
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
@ -71,17 +73,22 @@
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef GRAPHICS_FT80X_DEBUG_INFO
|
||||
static void ft80x_dl_dump(FAR struct ft80x_dlbuffer_s *buffer)
|
||||
static void ft80x_dl_dump(FAR struct ft80x_dlbuffer_s *buffer,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
uint16_t nwords;
|
||||
size_t nwords;
|
||||
int max;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
printf("Write display list: dlsize=%lu dloffset=%lu\n",
|
||||
(unsigned long)buffer->dlsize, (unsigned long)buffer->dloffset);
|
||||
printf("Writing display list:\n");
|
||||
printf(" buffer: dlsize=%lu dloffset=%lu coproc=%u\n",
|
||||
(unsigned long)buffer->dlsize, (unsigned long)buffer->dloffset,
|
||||
buffer->coproc);
|
||||
printf(" write: data=%p length=%lu\n",
|
||||
data, (unsigned long)len);
|
||||
|
||||
nwords = buffer->dloffset >> 2;
|
||||
nwords = len >> 2;
|
||||
for (i = 0; i < nwords; i += 8)
|
||||
{
|
||||
printf(" %04x: ", i << 2);
|
||||
@ -113,8 +120,50 @@ static void ft80x_dl_dump(FAR struct ft80x_dlbuffer_s *buffer)
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define ft80x_dl_dump(b,d,l)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_dl_append
|
||||
*
|
||||
* Description:
|
||||
* Append the display list data to the appropriate memory region.
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor of the FT80x device. Opened by the caller
|
||||
* with write access.
|
||||
* buffer - An instance of struct ft80x_dlbuffer_s allocated by the caller.
|
||||
* data - A pointer to the start of the data to be written.
|
||||
* len - The number of bytes to be written.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ft80x_dl_append(int fd, FAR struct ft80x_dlbuffer_s *buffer,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ft80x_dl_dump(buffer, data, len);
|
||||
if (buffer->coproc)
|
||||
{
|
||||
/* Append data to RAM CMD */
|
||||
|
||||
ret = ft80x_ramcmd_append(fd, buffer, data, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Append data to RAM DL */
|
||||
|
||||
ret = ft80x_ramdl_append(fd, buffer, data, len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -129,25 +178,25 @@ static void ft80x_dl_dump(FAR struct ft80x_dlbuffer_s *buffer)
|
||||
* 2) Set the display list buffer offset to zero
|
||||
* 3) Reposition the VFS so that subsequent writes will be to the
|
||||
* beginning of the hardware display list.
|
||||
* (Only for DL memory commands)
|
||||
* 4) Write the CMD_DLSTART command into the local display list buffer
|
||||
* (REVISIT -- unnecessary)
|
||||
* (Only for co-processor commands)
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor of the FT80x device. Opened by the caller
|
||||
* with write access.
|
||||
* buffer - An instance of struct ft80x_dlbuffer_s allocated by the caller.
|
||||
* coproc - True: Use co-processor FIFO; false: Use DL memory.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. A negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_dl_start(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
int ft80x_dl_start(int fd, FAR struct ft80x_dlbuffer_s *buffer, bool coproc)
|
||||
{
|
||||
#if 0
|
||||
struct ft80x_cmd_dlstart_s dlstart;
|
||||
#endif
|
||||
off_t pos;
|
||||
int ret;
|
||||
|
||||
ft80x_info("fd=%d buffer=%p\n", fd, buffer);
|
||||
DEBUGASSERT(fd >= 0 && buffer != NULL);
|
||||
@ -156,30 +205,49 @@ int ft80x_dl_start(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
* 2) Set the display list buffer offset to zero
|
||||
*/
|
||||
|
||||
buffer->dlsize = 0;
|
||||
buffer->coproc = coproc;
|
||||
buffer->dlsize = 0;
|
||||
buffer->dloffset = 0;
|
||||
buffer->hwoffset = 0;
|
||||
|
||||
/* 3) Reposition the VFS so that subsequent writes will be to the
|
||||
* beginning of the hardware display list.
|
||||
*/
|
||||
|
||||
pos = lseek(fd, 0, SEEK_SET);
|
||||
if (pos < 0)
|
||||
if (!coproc)
|
||||
{
|
||||
int errcode = errno;
|
||||
ft80x_err("ERROR: lseek failed: %d\n", errcode);
|
||||
return -errcode;
|
||||
/* 3) Reposition the VFS so that subsequent writes will be to the
|
||||
* beginning of the hardware display list.
|
||||
*/
|
||||
|
||||
ret = ft80x_ramdl_rewind(fd, buffer);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_ramdl_rewind failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get the initial RAM CMD FIFO offset */
|
||||
|
||||
ret = ft80x_getreg16(fd, FT80X_REG_CMD_READ, &buffer->hwoffset);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_getreg16 failed: %d\n", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 4) Write the CMD_DLSTART command into the local display list
|
||||
* buffer. (Only for co-processor commands)
|
||||
*/
|
||||
|
||||
dlstart.cmd = FT80X_CMD_DLSTART;
|
||||
ret = ft80x_dl_data(fd, buffer, &dlstart,
|
||||
sizeof(struct ft80x_cmd_dlstart_s));
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 /* I believe that this is not necessary */
|
||||
/* 4) Write the CMD_DLSTART command into the local display list buffer. */
|
||||
|
||||
dlstart.cmd = FT80X_CMD_DLSTART;
|
||||
return ft80x_dl_data(fd, buffer, &dlstart,
|
||||
sizeof(struct ft80x_cmd_dlstart_s));
|
||||
#else
|
||||
return OK;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -190,9 +258,13 @@ int ft80x_dl_start(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
*
|
||||
* 1) Add the DISPLAY command to the local display list buffer to finish
|
||||
* the last display
|
||||
* 2) Flush the local display buffer to hardware and set the display list
|
||||
* 2) If using co-processor RAM CMD, add the CMD_SWAP to the DL command
|
||||
* list
|
||||
* 3) Flush the local display buffer to hardware and set the display list
|
||||
* buffer offset to zero.
|
||||
* 3) Swap to the newly created display list.
|
||||
* 4) Swap to the newly created display list (DL memory case only).
|
||||
* 5) For the case of the co-processor RAM CMD, it will also wait for the
|
||||
* FIFO to be emptied.
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor of the FT80x device. Opened by the caller
|
||||
@ -206,7 +278,13 @@ int ft80x_dl_start(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
|
||||
int ft80x_dl_end(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
{
|
||||
struct ft80x_dlcmd_s display;
|
||||
struct
|
||||
{
|
||||
struct ft80x_dlcmd_s display;
|
||||
struct ft80x_cmd32_s swap;
|
||||
} s;
|
||||
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
ft80x_info("fd=%d buffer=%p\n", fd, buffer);
|
||||
@ -216,15 +294,27 @@ int ft80x_dl_end(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
* the last display
|
||||
*/
|
||||
|
||||
display.cmd = FT80X_DISPLAY();
|
||||
ret = ft80x_dl_data(fd, buffer, &display, sizeof(struct ft80x_dlcmd_s));
|
||||
s.display.cmd = FT80X_DISPLAY();
|
||||
size = sizeof(struct ft80x_dlcmd_s);
|
||||
|
||||
/* 2) If using co-processor RAM CMD, add the CMD_SWAP to the DL command
|
||||
* list
|
||||
*/
|
||||
|
||||
if (buffer->coproc)
|
||||
{
|
||||
s.swap.cmd = FT80X_CMD_SWAP;
|
||||
size = sizeof(s);
|
||||
};
|
||||
|
||||
ret = ft80x_dl_data(fd, buffer, &s, size);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_data failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 2) Flush the local display buffer to hardware and set the display list
|
||||
/* 3) Flush the local display buffer to hardware and set the display list
|
||||
* buffer offset to zero.
|
||||
*/
|
||||
|
||||
@ -234,13 +324,30 @@ int ft80x_dl_end(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
ft80x_err("ERROR: ft80x_dl_flush failed: %d\n", ret);
|
||||
}
|
||||
|
||||
/* 3) Swap to the newly created display list. */
|
||||
/* 4) Swap to the newly created display list (DL memory case only). */
|
||||
|
||||
ret = ft80x_dl_swap(fd);
|
||||
if (ret < 0)
|
||||
if (!buffer->coproc)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_swap failed: %d\n", ret);
|
||||
return ret;
|
||||
ret = ft80x_dl_swap(fd);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_swap failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* 5) For the case of the co-processor RAM CMD, it will also wait for the
|
||||
* FIFO to be emptied.
|
||||
*/
|
||||
|
||||
if (buffer->coproc)
|
||||
{
|
||||
ret = ft80x_ramcmd_waitfifoempty(fd, buffer);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_ramcmd_waitfifoempty failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -306,30 +413,28 @@ int ft80x_dl_data(int fd, FAR struct ft80x_dlbuffer_s *buffer,
|
||||
}
|
||||
|
||||
/* Special case: The new data won't fit into our local display list
|
||||
* buffer. Here we can assume the flush above occurred. We can then
|
||||
* work around by writing directly, unbuffered from the caller's
|
||||
* buffer.
|
||||
*/
|
||||
|
||||
if (padlen > FT80X_DL_BUFSIZE)
|
||||
{
|
||||
size_t writelen;
|
||||
size_t nwritten;
|
||||
|
||||
/* Write the aligned portion of the data directly to the FT80x
|
||||
* hardware display list. NOTE: We have inside knowledge that
|
||||
* the write will complete in a single operation so that no
|
||||
* piecewise writes will ever be necessary.
|
||||
* hardware display list.
|
||||
*/
|
||||
|
||||
writelen = datlen & ~3;
|
||||
nwritten = write(fd, data, writelen);
|
||||
if (nwritten < 0)
|
||||
ret = ft80x_dl_append(fd, buffer, data, writelen);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
ft80x_err("ERROR: write failed: %d\n", errcode);
|
||||
return -errcode;
|
||||
ft80x_err("ERROR: ft80x_dl_append failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEBUGASSERT(nwritten == writelen);
|
||||
buffer->dlsize += writelen;
|
||||
|
||||
/* Is there any unaligned remainder? If the original data length
|
||||
* was aligned, then we should have writelen == datlen == padlen.
|
||||
@ -353,23 +458,25 @@ int ft80x_dl_data(int fd, FAR struct ft80x_dlbuffer_s *buffer,
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy the data into the local display list buffer */
|
||||
/* Copy the data into the local display list buffer */
|
||||
|
||||
bufptr = (FAR uint8_t *)buffer->dlbuffer;
|
||||
bufptr += buffer->dloffset;
|
||||
memcpy(bufptr, data, datlen);
|
||||
bufptr = (FAR uint8_t *)buffer->dlbuffer;
|
||||
bufptr += buffer->dloffset;
|
||||
memcpy(bufptr, data, datlen);
|
||||
|
||||
bufptr += datlen;
|
||||
buffer->dloffset += datlen;
|
||||
bufptr += datlen;
|
||||
buffer->dloffset += datlen;
|
||||
|
||||
/* Then append zero bytes as necessary to achieve alignment */
|
||||
|
||||
while (datlen < padlen)
|
||||
{
|
||||
*bufptr++ = 0;
|
||||
buffer->dloffset++;
|
||||
datlen++;
|
||||
}
|
||||
while (datlen < padlen)
|
||||
{
|
||||
*bufptr++ = 0;
|
||||
buffer->dloffset++;
|
||||
datlen++;
|
||||
}
|
||||
|
||||
buffer->dlsize += padlen;
|
||||
}
|
||||
|
||||
return OK;
|
||||
@ -450,30 +557,28 @@ int ft80x_dl_string(int fd, FAR struct ft80x_dlbuffer_s *buffer,
|
||||
}
|
||||
|
||||
/* Special case: The new string won't fit into our local display list
|
||||
* buffer. Here we can assume the flush above occurred. We can then
|
||||
* work around by writing directly, unbuffered from the caller's
|
||||
* buffer.
|
||||
*/
|
||||
|
||||
if (padlen > FT80X_DL_BUFSIZE)
|
||||
{
|
||||
size_t writelen;
|
||||
size_t nwritten;
|
||||
|
||||
/* Write the aligned portion of the string directly to the FT80x
|
||||
* hardware display list. NOTE: We have inside knowledge that the
|
||||
* write will complete in a single operation so that no piecewise
|
||||
* writes will ever be necessary.
|
||||
* hardware display list.
|
||||
*/
|
||||
|
||||
writelen = datlen & ~3;
|
||||
nwritten = write(fd, str, writelen);
|
||||
if (nwritten < 0)
|
||||
ret = ft80x_dl_append(fd, buffer, str, writelen);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
ft80x_err("ERROR: write failed: %d\n", errcode);
|
||||
return -errcode;
|
||||
ft80x_err("ERROR: ft80x_dl_append failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEBUGASSERT(nwritten == writelen);
|
||||
buffer->dlsize += writelen;
|
||||
|
||||
/* There should always be an unaligned remainder If the original
|
||||
* string length was aligned, then we should have writelen == datlen <
|
||||
@ -514,6 +619,7 @@ int ft80x_dl_string(int fd, FAR struct ft80x_dlbuffer_s *buffer,
|
||||
datlen++;
|
||||
}
|
||||
|
||||
buffer->dlsize += padlen;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -536,25 +642,20 @@ int ft80x_dl_string(int fd, FAR struct ft80x_dlbuffer_s *buffer,
|
||||
|
||||
int ft80x_dl_flush(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
{
|
||||
size_t nwritten;
|
||||
int ret;
|
||||
|
||||
ft80x_info("fd=%d buffer=%p\n", fd, buffer);
|
||||
ft80x_info("fd=%d buffer=%p dloffset=%u\n", fd, buffer, buffer->dloffset);
|
||||
DEBUGASSERT(fd >= 0 && buffer != NULL);
|
||||
|
||||
/* Write the content of the local display buffer to hardware. NOTE: We
|
||||
* have inside knowledge that the write will complete in a single
|
||||
* operation so that no piecewise writes will ever be necessary.
|
||||
*/
|
||||
/* Write the content of the local display buffer to hardware. */
|
||||
|
||||
nwritten = write(fd, buffer->dlbuffer, buffer->dloffset);
|
||||
if (nwritten < 0)
|
||||
ret = ft80x_dl_append(fd, buffer, buffer->dlbuffer, buffer->dloffset);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
ft80x_err("ERROR: write failed: %d\n", errcode);
|
||||
return -errcode;
|
||||
ft80x_err("ERROR: ft80x_dl_append failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEBUGASSERT(nwritten == buffer->dloffset);
|
||||
buffer->dloffset = 0;
|
||||
return OK;
|
||||
}
|
||||
@ -576,6 +677,7 @@ int ft80x_dl_flush(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
* buffer - An instance of struct ft80x_dlbuffer_s allocated by the caller.
|
||||
* data - Pointer to a uint32_t array containing the simple display list
|
||||
* nwords - The number of 32-bit words in the array.
|
||||
* coproc - True: Use co-processor FIFO; false: Use DL memory.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. A negated errno value on failure.
|
||||
@ -583,16 +685,18 @@ int ft80x_dl_flush(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_dl_create(int fd, FAR struct ft80x_dlbuffer_s *buffer,
|
||||
FAR const uint32_t *cmds, unsigned int nwords)
|
||||
FAR const uint32_t *cmds, unsigned int nwords,
|
||||
bool coproc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ft80x_info("fd=%d buffer=%p cmds=%p nwords=%u\n", fd, buffer, cmds, nwords);
|
||||
ft80x_info("fd=%d buffer=%p cmds=%p nwords=%u coproc=%u\n",
|
||||
fd, buffer, cmds, nwords, coproc);
|
||||
DEBUGASSERT(fd >= 0 && buffer != NULL && cmds != NULL && nwords > 0);
|
||||
|
||||
/* Create the hardware display list */
|
||||
|
||||
ret = ft80x_dl_start(fd, buffer);
|
||||
ret = ft80x_dl_start(fd, buffer, coproc);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_dl_start failed: %d\n", ret);
|
||||
@ -618,4 +722,4 @@ int ft80x_dl_create(int fd, FAR struct ft80x_dlbuffer_s *buffer,
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
393
graphics/ft80x/ft80x_ramcmd.c
Normal file
393
graphics/ft80x/ft80x_ramcmd.c
Normal file
@ -0,0 +1,393 @@
|
||||
/****************************************************************************
|
||||
* apps/graphics/ft80x/ft80x_ramcmd.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/lcd/ft80x.h>
|
||||
|
||||
#include "graphics/ft80x.h"
|
||||
#include "ft80x.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define FT80X_CMDFIFO_MASK (FT80X_CMDFIFO_SIZE - 1)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_ramcmd_offset
|
||||
*
|
||||
* Description:
|
||||
* Return the offset to next unused location in RAM CMD
|
||||
*
|
||||
* Input Parameters:
|
||||
* buffer - An instance of struct ft80x_dlbuffer_s allocated by the caller.
|
||||
*
|
||||
* Returned Value:
|
||||
* The offset to the next unused location in RAM CMD.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint16_t ft80x_ramcmd_offset(FAR struct ft80x_dlbuffer_s *buffer)
|
||||
{
|
||||
register uint32_t tmp = buffer->dlsize + buffer->hwoffset;
|
||||
return (uint16_t)(tmp & FT80X_CMDFIFO_MASK);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_ramcmd_fifopos
|
||||
*
|
||||
* Description:
|
||||
* Return the current FIFO position RAM CMD
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor of the FT80x device. Opened by the caller
|
||||
* with write access.
|
||||
* pos - Pointer to location to return the FIFO position
|
||||
*
|
||||
* Returned Value:
|
||||
* The current FIFO position in RAM CMD.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline int ft80x_ramcmd_fifopos(int fd, FAR uint16_t *pos)
|
||||
{
|
||||
int ret = ft80x_getreg16(fd, FT80X_REG_CMD_READ, pos);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_getreg16 failed: %d\n", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_ramcmd_freespace
|
||||
*
|
||||
* Description:
|
||||
* Return the free space in RAM CMD memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor of the FT80x device. Opened by the caller
|
||||
* with write access.
|
||||
* buffer - An instance of struct ft80x_dlbuffer_s allocated by the caller.
|
||||
* avail - Pointer to location to return the FIFO free space
|
||||
*
|
||||
* Returned Value:
|
||||
* The (positive) number of free bytes in RAM CMD on success. A negated
|
||||
* errno value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t ft80x_ramcmd_freespace(int fd,
|
||||
FAR struct ft80x_dlbuffer_s *buffer,
|
||||
FAR uint16_t *avail)
|
||||
{
|
||||
uint16_t head;
|
||||
uint16_t tail;
|
||||
int ret;
|
||||
|
||||
/* Index to the next available location in RAM CMD */
|
||||
|
||||
head = ft80x_ramcmd_offset(buffer);
|
||||
|
||||
/* The index to next unconsumed value in RAM CMD */
|
||||
|
||||
ret = ft80x_ramcmd_fifopos(fd, &tail);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_ramcmd_fifopos failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Return the free space in the FIFO. NOTE that 4 bytes are not available */
|
||||
|
||||
*avail = (FT80X_CMDFIFO_SIZE - 4) - ((head - tail) & FT80X_CMDFIFO_MASK);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_ramcmd_append
|
||||
*
|
||||
* Description:
|
||||
* Append new display list data to RAM CMD
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor of the FT80x device. Opened by the caller
|
||||
* with write access.
|
||||
* buffer - An instance of struct ft80x_dlbuffer_s allocated by the caller.
|
||||
* data - A pointer to the start of the data to be written.
|
||||
* len - The number of bytes to be written.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. A negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_ramcmd_append(int fd, FAR struct ft80x_dlbuffer_s *buffer,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
struct ft80x_relmem_s wrdesc;
|
||||
FAR const uint8_t *src;
|
||||
ssize_t remaining = 0;
|
||||
size_t wrsize = 0;
|
||||
uint16_t maxsize;
|
||||
int ret;
|
||||
|
||||
/* Loop until all of the display list commands have been transferred to
|
||||
* FIFO.
|
||||
*/
|
||||
|
||||
src = data;
|
||||
remaining = len;
|
||||
|
||||
do
|
||||
{
|
||||
/* Write the number of bytes remaining to be transferred */
|
||||
|
||||
wrsize = remaining;
|
||||
|
||||
/* Get the amount of free space in the FIFO. */
|
||||
|
||||
maxsize = 0;
|
||||
ret = ft80x_ramcmd_freespace(fd, buffer, &maxsize);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_ramcmd_freespace() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If the FIFO full?
|
||||
*
|
||||
* REVISIT: Will the FIFO be consumed as we generate the display
|
||||
* list? Is it fatal if it becomes full? Or could we wait for space
|
||||
* to free up.
|
||||
*/
|
||||
|
||||
if (maxsize == 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_ramcmd_freespace() failed: %d\n", ret);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
/* Limit the write size to the size of the available FIFO memory */
|
||||
|
||||
if (wrsize > (size_t)maxsize)
|
||||
{
|
||||
wrsize = (size_t)maxsize;
|
||||
}
|
||||
|
||||
/* Perform the transfer */
|
||||
|
||||
wrdesc.offset = ft80x_ramcmd_offset(buffer);
|
||||
wrdesc.nbytes = wrsize;
|
||||
wrdesc.value = (FAR void *)src; /* Discards 'const' qualifier */
|
||||
|
||||
ret = ioctl(fd, FT80X_IOC_PUTRAMCMD,
|
||||
(unsigned long)((uintptr_t)&wrdesc));
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
ft80x_err("ERROR: ioctl() FT80X_IOC_PUTRAMCMD failed: %d\n",
|
||||
errcode)
|
||||
return -errcode;
|
||||
}
|
||||
|
||||
/* Update the command FIFO */
|
||||
|
||||
buffer->dlsize += wrsize;
|
||||
ret = ft80x_putreg16(fd, FT80X_REG_CMD_WRITE,
|
||||
ft80x_ramcmd_offset(buffer));
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_putreg16() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Wait for the FIFO to empty */
|
||||
|
||||
ret = ft80x_ramcmd_waitfifoempty(fd, buffer);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_ramcmd_waitfifoempty() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set up for the next time through the loop */
|
||||
|
||||
remaining -= wrsize;
|
||||
}
|
||||
while (remaining > 0);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_ramcmd_waitfifoempty
|
||||
*
|
||||
* Description:
|
||||
* Wait until co processor completes the operation and the FIFO is again
|
||||
* empty.
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor of the FT80x device. Opened by the caller
|
||||
* with write access.
|
||||
* buffer - An instance of struct ft80x_dlbuffer_s allocated by the caller.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. A negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_ramcmd_waitfifoempty(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
{
|
||||
struct ft80x_notify_s notify;
|
||||
struct timespec timeout;
|
||||
sigset_t set;
|
||||
uint16_t head;
|
||||
uint16_t tail;
|
||||
int ret;
|
||||
|
||||
/* Block the signal so that it will pend if received asynchronously */
|
||||
|
||||
(void)sigemptyset(&set);
|
||||
(void)sigaddset(&set, CONFIG_GRAPHICS_FT80X_CMDEMPTY_SIGNAL);
|
||||
|
||||
ret = pthread_sigmask(SIG_BLOCK, &set, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -errno;
|
||||
ft80x_err("ERROR: pthread_sigmask for signal %d failed: %d\n",
|
||||
CONFIG_GRAPHICS_FT80X_CMDEMPTY_SIGNAL, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
notify.signo = CONFIG_GRAPHICS_FT80X_CMDEMPTY_SIGNAL;
|
||||
notify.pid = getpid();
|
||||
notify.event = FT80X_NOTIFY_CMDEMPTY;
|
||||
notify.enable = false;
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
/* Check if the FIFO is already empty */
|
||||
|
||||
ret = ft80x_getreg16(fd, FT80X_REG_CMD_WRITE, &head);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_getreg16 failed: %d\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = ft80x_getreg16(fd, FT80X_REG_CMD_READ, &tail);
|
||||
if (ret < 0)
|
||||
{
|
||||
ft80x_err("ERROR: ft80x_getreg16 failed: %d\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
if (head == tail)
|
||||
{
|
||||
/* The FIFO is empty... return success */
|
||||
|
||||
ret = OK;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set up to receive a notification when the CMD FIFO becomes empty
|
||||
* NOTE that there is a race condition here between the preceding test
|
||||
* and the time when the event is registered. We catch this with a
|
||||
* timeout below.
|
||||
*/
|
||||
|
||||
notify.enable = true;
|
||||
ret = ioctl(fd, FT80X_IOC_EVENTNOTIFY,
|
||||
(unsigned long)((uintptr_t)¬ify));
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -errno;
|
||||
ft80x_err("ERROR: ioctl(FT80X_IOC_EVENTNOTIFY) failed: %d\n", errcode);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Now wait for the signal event (or a timeout) */
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_nsec = 400 * 1000 * 1000;
|
||||
|
||||
ret = sigtimedwait(&set, NULL, &timeout);
|
||||
|
||||
/* Make sure that the event notification is again disabled */
|
||||
|
||||
notify.enable = false;
|
||||
(void)ioctl(fd, FT80X_IOC_EVENTNOTIFY,
|
||||
(unsigned long)((uintptr_t)¬ify));
|
||||
|
||||
/* Check if the signal was received correctly or if the timeout occurred. */
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
if (errcode != EAGAIN)
|
||||
{
|
||||
ft80x_err("ERROR: ioctl(FT80X_IOC_EVENTNOTIFY) failed: %d\n",
|
||||
errcode);
|
||||
ret = -errcode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(void)pthread_sigmask(SIG_UNBLOCK, &set, NULL);
|
||||
return ret;
|
||||
}
|
136
graphics/ft80x/ft80x_ramdl.c
Normal file
136
graphics/ft80x/ft80x_ramdl.c
Normal file
@ -0,0 +1,136 @@
|
||||
/****************************************************************************
|
||||
* apps/graphics/ft80x/ft80x_ramdl.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/lcd/ft80x.h>
|
||||
|
||||
#include "graphics/ft80x.h"
|
||||
#include "ft80x.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_ramdl_rewind
|
||||
*
|
||||
* Description:
|
||||
* Reset to the start of RAM DL memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor of the FT80x device. Opened by the caller
|
||||
* with write access.
|
||||
* buffer - An instance of struct ft80x_dlbuffer_s allocated by the caller.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. A negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_ramdl_rewind(int fd, FAR struct ft80x_dlbuffer_s *buffer)
|
||||
{
|
||||
off_t pos;
|
||||
|
||||
DEBUGASSERT(fd >= 0 && buffer != NULL);
|
||||
|
||||
/* Reposition the VFSso that subsequent writes will be to the beginning of
|
||||
* the hardware display list.
|
||||
*/
|
||||
|
||||
pos = lseek(fd, 0, SEEK_SET);
|
||||
if (pos < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
ft80x_err("ERROR: lseek failed: %d\n", errcode);
|
||||
return -errcode;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_ramdl_append
|
||||
*
|
||||
* Description:
|
||||
* Append new display list data to RAM DL
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor of the FT80x device. Opened by the caller
|
||||
* with write access.
|
||||
* buffer - An instance of struct ft80x_dlbuffer_s allocated by the caller.
|
||||
* data - A pointer to the start of the data to be written.
|
||||
* len - The number of bytes to be written.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. A negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_ramdl_append(int fd, FAR struct ft80x_dlbuffer_s *buffer,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
size_t nwritten;
|
||||
|
||||
DEBUGASSERT(fd >= 0 && buffer != NULL && data != NULL &&
|
||||
((uintptr_t)data & 3) == 0 && len > 0 && (len & 3) == 0);
|
||||
|
||||
/* Write the aligned data directly to the FT80x hardware display list.
|
||||
*
|
||||
* NOTE: We have inside knowledge that the write will complete in a
|
||||
* single operation so that no piecewise writes will ever be necessary.
|
||||
*/
|
||||
|
||||
nwritten = write(fd, data, len);
|
||||
if (nwritten < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
ft80x_err("ERROR: write failed: %d\n", errcode);
|
||||
return -errcode;
|
||||
}
|
||||
|
||||
DEBUGASSERT(nwritten == len);
|
||||
return OK;
|
||||
}
|
@ -64,8 +64,10 @@
|
||||
|
||||
struct ft80x_dlbuffer_s
|
||||
{
|
||||
bool coproc; /* True: Use co-processor FIFO; false: Use DL memory */
|
||||
uint16_t dlsize; /* Total sizeof the display list written to hardware */
|
||||
uint16_t dloffset; /* The number display list bytes buffered locally */
|
||||
uint16_t hwoffset; /* Initial offset into FIFO memory */
|
||||
uint32_t dlbuffer[FT80X_DL_BUFWORDS];
|
||||
};
|
||||
|
||||
@ -91,20 +93,21 @@ extern "C"
|
||||
* 2) Set the display list buffer offset to zero
|
||||
* 3) Reposition the VFS so that subsequent writes will be to the
|
||||
* beginning of the hardware display list.
|
||||
* 4) Write the CMD_DLSTART command into the local display list buffer.
|
||||
* (REVISIT -- unnecessary)
|
||||
* 4) Write the CMD_DLSTART command into the local display list buffer
|
||||
* (Only for co-processor commands)
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor of the FT80x device. Opened by the caller
|
||||
* with write access.
|
||||
* buffer - An instance of struct ft80x_dlbuffer_s allocated by the caller.
|
||||
* coproc - True: Use co-processor FIFO; false: Use DL memory.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. A negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_dl_start(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
int ft80x_dl_start(int fd, FAR struct ft80x_dlbuffer_s *buffer, bool coproc);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_dl_end
|
||||
@ -114,9 +117,13 @@ int ft80x_dl_start(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
*
|
||||
* 1) Add the DISPLAY command to the local display list buffer to finish
|
||||
* the last display
|
||||
* 2) Flush the local display buffer to hardware and set the display list
|
||||
* 2) If using co-processor RAM CMD, add the CMD_SWAP to the DL command
|
||||
* list
|
||||
* 3) Flush the local display buffer to hardware and set the display list
|
||||
* buffer offset to zero.
|
||||
* 3) Swap to the newly created display list.
|
||||
* 4) Swap to the newly created display list (DL memory case only).
|
||||
* 5) For the case of the co-processor RAM CMD, it will also wait for the
|
||||
* FIFO to be emptied.
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd - The file descriptor of the FT80x device. Opened by the caller
|
||||
@ -220,6 +227,7 @@ int ft80x_dl_flush(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
* buffer - An instance of struct ft80x_dlbuffer_s allocated by the caller.
|
||||
* data - Pointer to a uint32_t array containing the simple display list
|
||||
* nwords - The number of 32-bit words in the array.
|
||||
* coproc - True: Use co-processor FIFO; false: Use DL memory.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success. A negated errno value on failure.
|
||||
@ -227,7 +235,8 @@ int ft80x_dl_flush(int fd, FAR struct ft80x_dlbuffer_s *buffer);
|
||||
****************************************************************************/
|
||||
|
||||
int ft80x_dl_create(int fd, FAR struct ft80x_dlbuffer_s *buffer,
|
||||
FAR const uint32_t *cmds, unsigned int nwords);
|
||||
FAR const uint32_t *cmds, unsigned int nwords,
|
||||
bool coproc);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ft80x_ramg_write
|
||||
@ -249,7 +258,6 @@ int ft80x_dl_create(int fd, FAR struct ft80x_dlbuffer_s *buffer,
|
||||
|
||||
int ft80x_ramg_write(int fd, unsigned int offset, FAR const void *data,
|
||||
unsigned int nbytes);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user