From e8935a0d712f86ded11000ecb35bf1bec171a759 Mon Sep 17 00:00:00 2001 From: Derek Snell Date: Mon, 22 Jul 2024 13:51:24 -0400 Subject: [PATCH 1/5] boards: nxp: mimxrt1060_evkb: enable dvp_fpc24_mt9m114 shield Enable camera shield. Tested with samples/subsys/video/capture. Signed-off-by: Derek Snell --- boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dts | 9 +++++++++ .../dvp_fpc24_mt9m114/boards/mimxrt1060_evkb.overlay | 9 +++++++++ 2 files changed, 18 insertions(+) create mode 100644 boards/shields/dvp_fpc24_mt9m114/boards/mimxrt1060_evkb.overlay diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dts b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dts index 47f4901a22389..e091de3c29026 100644 --- a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dts +++ b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dts @@ -193,6 +193,11 @@ zephyr_udc0: &usb1 { tx-cal-45-dm-ohms = <6>; }; +&csi { + pinctrl-0 = <&pinmux_csi>; + pinctrl-names = "default"; +}; + &flexpwm2_pwm3 { status = "okay"; pinctrl-0 = <&pinmux_flexpwm2_3>; @@ -297,3 +302,7 @@ arduino_spi: &lpspi1 { &pit0 { status = "okay"; }; + +dvp_fpc24_i2c: &lpi2c1 {}; + +dvp_fpc24_interface: &csi {}; diff --git a/boards/shields/dvp_fpc24_mt9m114/boards/mimxrt1060_evkb.overlay b/boards/shields/dvp_fpc24_mt9m114/boards/mimxrt1060_evkb.overlay new file mode 100644 index 0000000000000..a4aa7a273080d --- /dev/null +++ b/boards/shields/dvp_fpc24_mt9m114/boards/mimxrt1060_evkb.overlay @@ -0,0 +1,9 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dvp_fpc24_interface { + source = <&mt9m114>; +}; From 4a0b39a3c7ad32a08f4d74b145a3dfbde53a725e Mon Sep 17 00:00:00 2001 From: Derek Snell Date: Mon, 22 Jul 2024 16:34:54 -0400 Subject: [PATCH 2/5] boards: nxp: mimxrt1064_evk: enable PXP Enable PXP in board devicetree for display samples. Signed-off-by: Derek Snell --- boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts b/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts index 7b1a0d0a7d41c..43bc30b682d65 100644 --- a/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts +++ b/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts @@ -336,6 +336,10 @@ zephyr_udc0: &usb1 { pinctrl-names = "default"; }; +&pxp { + status = "okay"; +}; + dvp_fpc24_i2c: &lpi2c1 {}; dvp_fpc24_interface: &csi {}; From 233f587aa4a2ba11107ce9f6fa5b5c8f55d093e6 Mon Sep 17 00:00:00 2001 From: Derek Snell Date: Mon, 22 Jul 2024 16:20:44 -0400 Subject: [PATCH 3/5] drivers: dma: dma_mcux_pxp: Add flip feature PXP can flip an image in input buffer horizontally, vertically, or both. Signed-off-by: Derek Snell --- drivers/dma/dma_mcux_pxp.c | 24 +++++++++++++++++++++-- include/zephyr/drivers/dma/dma_mcux_pxp.h | 18 ++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/drivers/dma/dma_mcux_pxp.c b/drivers/dma/dma_mcux_pxp.c index 88f8f39f34b3d..64f3154807c32 100644 --- a/drivers/dma/dma_mcux_pxp.c +++ b/drivers/dma/dma_mcux_pxp.c @@ -1,5 +1,5 @@ /* - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * All rights reserved. * * SPDX-License-Identifier: Apache-2.0 @@ -57,6 +57,7 @@ static int dma_mcux_pxp_configure(const struct device *dev, uint32_t channel, pxp_output_buffer_config_t output_buffer_cfg; uint8_t bytes_per_pixel; pxp_rotate_degree_t rotate; + pxp_flip_mode_t flip; ARG_UNUSED(channel); if (config->channel_direction != MEMORY_TO_MEMORY) { @@ -107,6 +108,25 @@ static int dma_mcux_pxp_configure(const struct device *dev, uint32_t channel, default: return -ENOTSUP; } + /* + * Use the DMA linked_channel value to get the flip settings. + */ + switch ((config->linked_channel & DMA_MCUX_PXP_FLIP_MASK) >> DMA_MCUX_PXP_FLIP_SHIFT) { + case DMA_MCUX_PXP_FLIP_DISABLE: + flip = kPXP_FlipDisable; + break; + case DMA_MCUX_PXP_FLIP_HORIZONTAL: + flip = kPXP_FlipHorizontal; + break; + case DMA_MCUX_PXP_FLIP_VERTICAL: + flip = kPXP_FlipVertical; + break; + case DMA_MCUX_PXP_FLIP_BOTH: + flip = kPXP_FlipBoth; + break; + default: + return -ENOTSUP; + } DCACHE_CleanByRange((uint32_t)config->head_block->source_address, config->head_block->block_size); @@ -139,7 +159,7 @@ static int dma_mcux_pxp_configure(const struct device *dev, uint32_t channel, PXP_SetProcessSurfacePosition(dev_config->base, 0U, 0U, output_buffer_cfg.width, output_buffer_cfg.height); /* Setup rotation */ - PXP_SetRotateConfig(dev_config->base, kPXP_RotateProcessSurface, rotate, kPXP_FlipDisable); + PXP_SetRotateConfig(dev_config->base, kPXP_RotateProcessSurface, rotate, flip); dev_data->ps_buf_addr = config->head_block->source_address; dev_data->ps_buf_size = config->head_block->block_size; diff --git a/include/zephyr/drivers/dma/dma_mcux_pxp.h b/include/zephyr/drivers/dma/dma_mcux_pxp.h index 7cddab2c3ef36..47082a947462c 100644 --- a/include/zephyr/drivers/dma/dma_mcux_pxp.h +++ b/include/zephyr/drivers/dma/dma_mcux_pxp.h @@ -1,5 +1,5 @@ /* - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -38,4 +38,20 @@ #define DMA_MCUX_PXP_FMT_RGB888 1 #define DMA_MCUX_PXP_FMT_ARGB8888 2 +#define DMA_MCUX_PXP_FLIP_MASK 0x3 +#define DMA_MCUX_PXP_FLIP_SHIFT 0x0 + +/* + * In order to configure the PXP to flip, the user should + * supply a flip setting as the DMA linked_channel parameter, like so: + * linked_channel |= DMA_MCUX_PXP_FLIP(DMA_MCUX_PXP_FLIP_HORIZONTAL) + */ + +#define DMA_MCUX_PXP_FLIP(x) ((x << DMA_MCUX_PXP_FLIP_SHIFT) & DMA_MCUX_PXP_FLIP_MASK) + +#define DMA_MCUX_PXP_FLIP_DISABLE 0 +#define DMA_MCUX_PXP_FLIP_HORIZONTAL 1 +#define DMA_MCUX_PXP_FLIP_VERTICAL 2 +#define DMA_MCUX_PXP_FLIP_BOTH 3 + #endif /* ZEPHYR_INCLUDE_DRIVERS_DMA_MCUX_PXP_H_ */ From 0859b8ec4260fbe8fcdbdcaf42b35c0b49276546 Mon Sep 17 00:00:00 2001 From: Derek Snell Date: Mon, 22 Jul 2024 16:23:50 -0400 Subject: [PATCH 4/5] drivers: display: display_mcux_elcdif: Add PXP flip feature display_write() can leverage PXP to flip the image. Signed-off-by: Derek Snell --- drivers/display/Kconfig.mcux_elcdif | 29 ++++++++++++++++++++++++++- drivers/display/display_mcux_elcdif.c | 21 ++++++++++++++----- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/drivers/display/Kconfig.mcux_elcdif b/drivers/display/Kconfig.mcux_elcdif index 44510e4bc3006..6cfc98bc25723 100644 --- a/drivers/display/Kconfig.mcux_elcdif +++ b/drivers/display/Kconfig.mcux_elcdif @@ -1,4 +1,4 @@ -# Copyright 2019,2023 NXP +# Copyright 2019,2023-2024 NXP # Copyright (c) 2022, Basalte bv # SPDX-License-Identifier: Apache-2.0 @@ -105,6 +105,33 @@ config MCUX_ELCDIF_PXP_ROTATE_270 endchoice +choice MCUX_ELCDIF_PXP_FLIP_DIRECTION + default MCUX_ELCDIF_PXP_FLIP_DISABLE + prompt "Flip direction of PXP" + help + Set flip direction of PXP. The ELCDIF cannot detect the correct + rotation angle based on the call to display_write, so the user should + configure it here. In order for PXP flip to work, calls to + display_write MUST supply a framebuffer equal in size to screen width + and height (without flip applied). Note that the width and + height settings of the screen in devicetree should not be modified + from their values in the default screen orientation when using this + functionality. + +config MCUX_ELCDIF_PXP_FLIP_DISABLE + bool "Do not flip display" + +config MCUX_ELCDIF_PXP_FLIP_HORIZONTAL + bool "Flip display horizontally" + +config MCUX_ELCDIF_PXP_FLIP_VERTICAL + bool "Flip display vertically" + +config MCUX_ELCDIF_PXP_FLIP_BOTH + bool "Flib display both horizontally and vertically" + +endchoice + endif # MCUX_ELCDIF_PXP endif # DISPLAY_MCUX_ELCDIF diff --git a/drivers/display/display_mcux_elcdif.c b/drivers/display/display_mcux_elcdif.c index 9c5785342d956..828fcf4314ec8 100644 --- a/drivers/display/display_mcux_elcdif.c +++ b/drivers/display/display_mcux_elcdif.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-23, NXP + * Copyright 2019-24, NXP * Copyright (c) 2022, Basalte bv * * SPDX-License-Identifier: Apache-2.0 @@ -54,7 +54,7 @@ struct mcux_elcdif_data { /* Tracks index of next active driver framebuffer */ uint8_t next_idx; #ifdef CONFIG_MCUX_ELCDIF_PXP - /* Given to when PXP completes rotation */ + /* Given to when PXP completes operation */ struct k_sem pxp_done; #endif }; @@ -138,12 +138,12 @@ static int mcux_elcdif_write(const struct device *dev, const uint16_t x, const u #ifdef CONFIG_MCUX_ELCDIF_PXP if (full_fb) { - /* Configure PXP using DMA API, and rotate frame */ + /* Configure PXP using DMA API, and rotate/flip frame */ struct dma_config pxp_dma = {0}; struct dma_block_config pxp_block = {0}; /* Source buffer is input to display_write, we will - * place rotated output into a driver framebuffer. + * place modified output into a driver framebuffer. */ dev_data->active_fb = dev_data->fb[dev_data->next_idx]; pxp_block.source_address = (uint32_t)buf; @@ -171,6 +171,17 @@ static int mcux_elcdif_write(const struct device *dev, const uint16_t x, const u pxp_dma.dma_slot |= DMA_MCUX_PXP_CMD(DMA_MCUX_PXP_CMD_ROTATE_0); } + /* DMA linked_channel sets the flip direction */ + if (IS_ENABLED(CONFIG_MCUX_ELCDIF_PXP_FLIP_HORIZONTAL)) { + pxp_dma.linked_channel |= DMA_MCUX_PXP_FLIP(DMA_MCUX_PXP_FLIP_HORIZONTAL); + } else if (IS_ENABLED(CONFIG_MCUX_ELCDIF_PXP_FLIP_VERTICAL)) { + pxp_dma.linked_channel |= DMA_MCUX_PXP_FLIP(DMA_MCUX_PXP_FLIP_VERTICAL); + } else if (IS_ENABLED(CONFIG_MCUX_ELCDIF_PXP_FLIP_BOTH)) { + pxp_dma.linked_channel |= DMA_MCUX_PXP_FLIP(DMA_MCUX_PXP_FLIP_BOTH); + } else { + pxp_dma.linked_channel |= DMA_MCUX_PXP_FLIP(DMA_MCUX_PXP_FLIP_DISABLE); + } + pxp_dma.channel_direction = MEMORY_TO_MEMORY; pxp_dma.source_data_size = desc->width * dev_data->pixel_bytes; pxp_dma.dest_data_size = config->rgb_mode.panelWidth * dev_data->pixel_bytes; @@ -191,7 +202,7 @@ static int mcux_elcdif_write(const struct device *dev, const uint16_t x, const u } k_sem_take(&dev_data->pxp_done, K_FOREVER); } else { - LOG_WRN("PXP rotation will not work correctly unless a full sized " + LOG_WRN("PXP rotation/flip will not work correctly unless a full sized " "framebuffer is provided"); } #endif /* CONFIG_MCUX_ELCDIF_PXP */ From 5c0fc87391aefd11b98e6879a9954316f9052419 Mon Sep 17 00:00:00 2001 From: Derek Snell Date: Mon, 22 Jul 2024 16:40:58 -0400 Subject: [PATCH 5/5] samples: video: capture: leverage PXP to flip image PXP can flip image written to the frame buffer. Provide a mirror image on the display by flipping the camera image horizontally. Enabled on boards mimxrt1066_evk and mimxrt1060_evkb. Signed-off-by: Derek Snell --- samples/subsys/video/capture/boards/mimxrt1060_evkb.conf | 4 ++++ samples/subsys/video/capture/boards/mimxrt1064_evk.conf | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 samples/subsys/video/capture/boards/mimxrt1060_evkb.conf create mode 100644 samples/subsys/video/capture/boards/mimxrt1064_evk.conf diff --git a/samples/subsys/video/capture/boards/mimxrt1060_evkb.conf b/samples/subsys/video/capture/boards/mimxrt1060_evkb.conf new file mode 100644 index 0000000000000..55ff96ee215a5 --- /dev/null +++ b/samples/subsys/video/capture/boards/mimxrt1060_evkb.conf @@ -0,0 +1,4 @@ +# Leverage PXP to mirror image by flipping +CONFIG_DMA=y +CONFIG_MCUX_ELCDIF_PXP=y +CONFIG_MCUX_ELCDIF_PXP_FLIP_HORIZONTAL=y diff --git a/samples/subsys/video/capture/boards/mimxrt1064_evk.conf b/samples/subsys/video/capture/boards/mimxrt1064_evk.conf new file mode 100644 index 0000000000000..55ff96ee215a5 --- /dev/null +++ b/samples/subsys/video/capture/boards/mimxrt1064_evk.conf @@ -0,0 +1,4 @@ +# Leverage PXP to mirror image by flipping +CONFIG_DMA=y +CONFIG_MCUX_ELCDIF_PXP=y +CONFIG_MCUX_ELCDIF_PXP_FLIP_HORIZONTAL=y