This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push: new 00d1a7db29 boards: cxd56xx: Update imageproc driver 00d1a7db29 is described below commit 00d1a7db29034c1f4da1fe8fa8c1887440ccb5cd Author: SPRESENSE <41312067+sprese...@users.noreply.github.com> AuthorDate: Mon Oct 24 18:48:05 2022 +0900 boards: cxd56xx: Update imageproc driver Fix raster operation bug in non-scaling case, and change the type of return value to int with error code for some functions. --- boards/arm/cxd56xx/common/src/cxd56_imageproc.c | 89 ++++++++++++++++------ .../cxd56xx/spresense/include/cxd56_imageproc.h | 12 ++- 2 files changed, 74 insertions(+), 27 deletions(-) diff --git a/boards/arm/cxd56xx/common/src/cxd56_imageproc.c b/boards/arm/cxd56xx/common/src/cxd56_imageproc.c index ca3e7e9ca7..92f112a84b 100644 --- a/boards/arm/cxd56xx/common/src/cxd56_imageproc.c +++ b/boards/arm/cxd56xx/common/src/cxd56_imageproc.c @@ -149,7 +149,7 @@ struct aligned_data(16) ge2d_copycmd_s uint32_t reserved[3]; }; -/* Raster operation (ROP) command (48 bytes) */ +/* Raster operation (ROP) command (32 bytes + scaling OP 16 bytes) */ struct aligned_data(16) ge2d_ropcmd_s { @@ -168,7 +168,10 @@ struct aligned_data(16) ge2d_ropcmd_s uint16_t patpitch; /* 0x1c */ uint8_t pathoffset; /* 0x1e */ uint8_t patvoffset; /* 0x1f */ +}; +struct aligned_data(16) ge2d_ropcmd_scaling_s +{ uint16_t desth; /* 0x20 */ uint16_t destv; /* 0x22 */ uint16_t ratioh; /* 0x24 */ @@ -205,6 +208,7 @@ struct aligned_data(16) ge2d_abcmd_s * Private Data ****************************************************************************/ +static bool g_imageprocinitialized = false; static sem_t g_rotwait; static mutex_t g_rotlock; static mutex_t g_gelock; @@ -291,6 +295,7 @@ static void *set_rop_cmd(void *cmdbuf, uint16_t patcolor) { struct ge2d_ropcmd_s *rc = (struct ge2d_ropcmd_s *)cmdbuf; + struct ge2d_ropcmd_scaling_s *sc; uint16_t rv; uint16_t rh; uint16_t cmd = ROPCMD; @@ -341,17 +346,34 @@ static void *set_rop_cmd(void *cmdbuf, rc->daddr = CXD56_PHYSADDR(destaddr) | MSEL; rc->spitch = srcpitch - 1; rc->dpitch = destpitch - 1; - rc->desth = destwidth - 1; - rc->destv = destheight - 1; - rc->ratiov = rv - 1; - rc->ratioh = rh - 1; - rc->hphaseinit = 1; - rc->vphaseinit = 1; - rc->intpmode = 0; /* XXX: HV Linear interpolation */ + + /* Shift to next command area */ + + cmdbuf = (void *)((uintptr_t)cmdbuf + sizeof(struct ge2d_ropcmd_s)); + + /* Set scaling information */ + + if (cmd & SCALING) + { + sc = (struct ge2d_ropcmd_scaling_s *)cmdbuf; + + sc->desth = destwidth - 1; + sc->destv = destheight - 1; + sc->ratiov = rv - 1; + sc->ratioh = rh - 1; + sc->hphaseinit = 1; + sc->vphaseinit = 1; + sc->intpmode = 0; /* XXX: HV Linear interpolation */ + + /* Shift to next command area */ + + cmdbuf = (void *)((uintptr_t)cmdbuf + + sizeof(struct ge2d_ropcmd_scaling_s)); + } /* return next command area */ - return (void *)((uintptr_t) cmdbuf + sizeof(struct ge2d_ropcmd_s)); + return cmdbuf; } static void *set_ab_cmd(void *cmdbuf, void *srcaddr, void *destaddr, @@ -393,22 +415,27 @@ static void *set_halt_cmd(void *cmdbuf) return (void *)((uintptr_t) cmdbuf + 16); } -static void imageproc_convert_(int is_yuv2rgb, - uint8_t * ibuf, - uint32_t hsize, - uint32_t vsize) +static int imageproc_convert_(int is_yuv2rgb, + uint8_t *ibuf, + uint32_t hsize, + uint32_t vsize) { int ret; + if (!g_imageprocinitialized) + { + return -EPERM; + } + if ((hsize & 1) || (vsize & 1)) { - return; + return -EINVAL; } ret = nxmutex_lock(&g_rotlock); if (ret) { - return; + return ret; } /* Image processing hardware want to be set horizontal/vertical size @@ -437,6 +464,8 @@ static void imageproc_convert_(int is_yuv2rgb, nxsem_wait_uninterruptible(&g_rotwait); nxmutex_unlock(&g_rotlock); + + return 0; } static void get_rect_info(imageproc_imginfo_t *imginfo, @@ -516,6 +545,13 @@ static void *get_blendarea(imageproc_imginfo_t *imginfo, int offset) void imageproc_initialize(void) { + if (g_imageprocinitialized) + { + return; + } + + g_imageprocinitialized = true; + nxmutex_init(&g_rotlock); nxsem_init(&g_rotwait, 0, 0); nxmutex_init(&g_gelock); @@ -535,6 +571,11 @@ void imageproc_initialize(void) void imageproc_finalize(void) { + if (!g_imageprocinitialized) + { + return; + } + up_disable_irq(CXD56_IRQ_ROT); irq_detach(CXD56_IRQ_ROT); @@ -549,20 +590,22 @@ void imageproc_finalize(void) nxmutex_destroy(&g_rotlock); nxmutex_destroy(&g_gelock); nxmutex_destroy(&g_ablock); + + g_imageprocinitialized = false; } -void imageproc_convert_yuv2rgb(uint8_t * ibuf, - uint32_t hsize, - uint32_t vsize) +int imageproc_convert_yuv2rgb(uint8_t *ibuf, + uint32_t hsize, + uint32_t vsize) { - imageproc_convert_(1, ibuf, hsize, vsize); + return imageproc_convert_(1, ibuf, hsize, vsize); } -void imageproc_convert_rgb2yuv(uint8_t * ibuf, - uint32_t hsize, - uint32_t vsize) +int imageproc_convert_rgb2yuv(uint8_t *ibuf, + uint32_t hsize, + uint32_t vsize) { - imageproc_convert_(0, ibuf, hsize, vsize); + return imageproc_convert_(0, ibuf, hsize, vsize); } void imageproc_convert_yuv2gray(uint8_t * ibuf, uint8_t * obuf, size_t hsize, diff --git a/boards/arm/cxd56xx/spresense/include/cxd56_imageproc.h b/boards/arm/cxd56xx/spresense/include/cxd56_imageproc.h index 3788f5bfa1..a0671849c2 100644 --- a/boards/arm/cxd56xx/spresense/include/cxd56_imageproc.h +++ b/boards/arm/cxd56xx/spresense/include/cxd56_imageproc.h @@ -107,20 +107,24 @@ extern "C" * [in,out] ibuf: image * [in] hsize: Horizontal size * [in] vsize: Vertical size + * + * return 0 on success, otherwise error code. */ - void imageproc_convert_yuv2rgb(uint8_t * ibuf, uint32_t hsize, - uint32_t vsize); + int imageproc_convert_yuv2rgb(uint8_t * ibuf, uint32_t hsize, + uint32_t vsize); /* Convert color format (RGB to YUV) * * [in,out] ibuf: image * [in] hsize: Horizontal size * [in] vsize: Vertical size + * + * return 0 on success, otherwise error code. */ - void imageproc_convert_rgb2yuv(uint8_t * ibuf, uint32_t hsize, - uint32_t vsize); + int imageproc_convert_rgb2yuv(uint8_t * ibuf, uint32_t hsize, + uint32_t vsize); /* Convert color format (YUV to grayscale) *