diff --git a/boards/arduino/nicla_vision/arduino_nicla_vision_stm32h747xx_m7.dts b/boards/arduino/nicla_vision/arduino_nicla_vision_stm32h747xx_m7.dts index 0028128f8e23..e9f39b173aef 100644 --- a/boards/arduino/nicla_vision/arduino_nicla_vision_stm32h747xx_m7.dts +++ b/boards/arduino/nicla_vision/arduino_nicla_vision_stm32h747xx_m7.dts @@ -225,7 +225,7 @@ zephyr_udc0: &usbotg_hs { port { gc2145_ep_out: endpoint { - remote-endpoint = <&dcmi_ep_in>; + remote-endpoint-label = "dcmi_ep_in"; }; }; @@ -240,19 +240,13 @@ zephyr_udc0: &usbotg_hs { pinctrl-names = "default"; status = "okay"; - sensor = <&gc2145>; - bus-width = <8>; - hsync-active = <0>; - vsync-active = <0>; - pixelclk-active = <0>; - capture-rate = <1>; - dmas = <&dma1 0 38 (STM32_DMA_PERIPH_TO_MEMORY | STM32_DMA_PERIPH_NO_INC | - STM32_DMA_MEM_INC | STM32_DMA_PERIPH_8BITS | STM32_DMA_MEM_32BITS | - STM32_DMA_PRIORITY_HIGH) STM32_DMA_FIFO_1_4>; - port { dcmi_ep_in: endpoint { - remote-endpoint = <&gc2145_ep_out>; + remote-endpoint-label = "gc2145_ep_out"; + bus-width = <8>; + hsync-active = <0>; + vsync-active = <0>; + pclk-sample = <0>; }; }; }; diff --git a/boards/shields/st_b_cams_omv_mb1683/boards/stm32h7b3i_dk.overlay b/boards/shields/st_b_cams_omv_mb1683/boards/stm32h7b3i_dk.overlay index c6e629d23425..19b9aaa6eaf2 100644 --- a/boards/shields/st_b_cams_omv_mb1683/boards/stm32h7b3i_dk.overlay +++ b/boards/shields/st_b_cams_omv_mb1683/boards/stm32h7b3i_dk.overlay @@ -17,10 +17,6 @@ &dcmi_d0_pc6 &dcmi_d1_pc7 &dcmi_d2_pg10 &dcmi_d3_pc9 &dcmi_d4_pc11 &dcmi_d5_pd3 &dcmi_d6_pb8 &dcmi_d7_pb9>; pinctrl-names = "default"; - - dmas = <&dma1 0 75 (STM32_DMA_PERIPH_TO_MEMORY | STM32_DMA_PERIPH_NO_INC | - STM32_DMA_MEM_INC | STM32_DMA_PERIPH_8BITS | STM32_DMA_MEM_32BITS | - STM32_DMA_PRIORITY_HIGH) STM32_DMA_FIFO_1_4>; }; &dma1 { diff --git a/boards/shields/st_b_cams_omv_mb1683/st_b_cams_omv_mb1683.overlay b/boards/shields/st_b_cams_omv_mb1683/st_b_cams_omv_mb1683.overlay index 0ffb5669dadf..06b4ac0f9f7e 100644 --- a/boards/shields/st_b_cams_omv_mb1683/st_b_cams_omv_mb1683.overlay +++ b/boards/shields/st_b_cams_omv_mb1683/st_b_cams_omv_mb1683.overlay @@ -33,17 +33,14 @@ &st_cam_dvp { status = "okay"; - sensor = <&ov5640>; - - bus-width = <8>; - hsync-active = <0>; - vsync-active = <0>; - pixelclk-active = <1>; - capture-rate = <1>; port { dcmi_ep_in: endpoint { remote-endpoint-label = "ov5640_ep_out"; + bus-width = <8>; + hsync-active = <0>; + vsync-active = <0>; + pclk-sample = <1>; }; }; }; diff --git a/boards/shields/weact_ov2640_cam_module/boards/mini_stm32h743.overlay b/boards/shields/weact_ov2640_cam_module/boards/mini_stm32h743.overlay index e99237276078..80e3dbc96203 100644 --- a/boards/shields/weact_ov2640_cam_module/boards/mini_stm32h743.overlay +++ b/boards/shields/weact_ov2640_cam_module/boards/mini_stm32h743.overlay @@ -44,12 +44,6 @@ }; }; -&zephyr_camera_dvp { - dmas = <&dma1 0 75 (STM32_DMA_PERIPH_TO_MEMORY | STM32_DMA_PERIPH_NO_INC | - STM32_DMA_MEM_INC | STM32_DMA_PERIPH_8BITS | STM32_DMA_MEM_32BITS | - STM32_DMA_PRIORITY_HIGH) STM32_DMA_FIFO_1_4>; -}; - &dma1 { status = "okay"; }; diff --git a/boards/shields/weact_ov2640_cam_module/weact_ov2640_cam_module.overlay b/boards/shields/weact_ov2640_cam_module/weact_ov2640_cam_module.overlay index bc8c6ebddb28..5b0eb2abdbb4 100644 --- a/boards/shields/weact_ov2640_cam_module/weact_ov2640_cam_module.overlay +++ b/boards/shields/weact_ov2640_cam_module/weact_ov2640_cam_module.overlay @@ -21,7 +21,7 @@ port { ov2640_ep_out: endpoint { - remote-endpoint = <&zephyr_camera_dvp_in>; + remote-endpoint-label = "zephyr_camera_dvp_in"; }; }; }; @@ -29,16 +29,14 @@ &zephyr_camera_dvp { status = "okay"; - sensor = <&ov2640>; - bus-width = <8>; - hsync-active = <0>; - vsync-active = <0>; - pixelclk-active = <1>; - capture-rate = <1>; port { zephyr_camera_dvp_in: endpoint { - remote-endpoint = <&ov2640_ep_out>; + remote-endpoint-label = "ov2640_ep_out"; + bus-width = <8>; + hsync-active = <0>; + vsync-active = <0>; + pclk-sample = <1>; }; }; }; diff --git a/doc/releases/migration-guide-4.2.rst b/doc/releases/migration-guide-4.2.rst index 4d6aabf58ac0..028b3dad45ce 100644 --- a/doc/releases/migration-guide-4.2.rst +++ b/doc/releases/migration-guide-4.2.rst @@ -501,6 +501,13 @@ Video ``VIDEO_PIX_FMT_GRBG8`` becomes ``VIDEO_PIX_FMT_SGRBG8`` ``VIDEO_PIX_FMT_RGGB8`` becomes ``VIDEO_PIX_FMT_SRGGB8`` +* On STM32 devices, the DCMI driver (:dtcompatible:`st,stm32-dcmi`) now relies on endpoint based + video-interfaces.yaml bindings for sensor interface properties (such as bus width and + synchronization signals). + Also the ``capture-rate`` property has been replaced by the usage of the frame interval API + :c:func:`video_set_frmival`. + See (:github:`89627`). + Other subsystems **************** diff --git a/drivers/video/video_stm32_dcmi.c b/drivers/video/video_stm32_dcmi.c index 53afb33c0b51..70de70e6d4be 100644 --- a/drivers/video/video_stm32_dcmi.c +++ b/drivers/video/video_stm32_dcmi.c @@ -41,12 +41,9 @@ struct video_stm32_dcmi_data { const struct device *dev; DCMI_HandleTypeDef hdcmi; struct video_format fmt; + int capture_rate; struct k_fifo fifo_in; struct k_fifo fifo_out; - uint32_t pixel_format; - uint32_t height; - uint32_t width; - uint32_t pitch; struct video_buffer *vbuf; }; @@ -127,7 +124,7 @@ static int stm32_dma_init(const struct device *dev) /* * DMA configuration - * Due to use of QSPI HAL API in current driver, + * Due to use of DMA HAL API in current driver, * both HAL and Zephyr DMA drivers should be configured. * The required configuration for Zephyr DMA driver should only provide * the minimum information to inform the DMA slot will be in used and @@ -179,7 +176,6 @@ static int stm32_dcmi_enable_clock(const struct device *dev) { const struct video_stm32_dcmi_config *config = dev->config; const struct device *dcmi_clock = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); - int err; if (!device_is_ready(dcmi_clock)) { LOG_ERR("clock control device not ready"); @@ -187,10 +183,15 @@ static int stm32_dcmi_enable_clock(const struct device *dev) } /* Turn on DCMI peripheral clock */ - err = clock_control_on(dcmi_clock, (clock_control_subsys_t *) &config->pclken); - if (err < 0) { - LOG_ERR("Failed to enable DCMI clock. Error %d", err); - return err; + return clock_control_on(dcmi_clock, (clock_control_subsys_t *)&config->pclken); +} + +static inline int video_stm32_dcmi_is_fmt_valid(uint32_t pixelformat, uint32_t pitch, + uint32_t height) +{ + if (video_bits_per_pixel(pixelformat) / BITS_PER_BYTE == 0 || + pitch * height > CONFIG_VIDEO_BUFFER_POOL_SZ_MAX) { + return -EINVAL; } return 0; @@ -202,25 +203,24 @@ static int video_stm32_dcmi_set_fmt(const struct device *dev, { const struct video_stm32_dcmi_config *config = dev->config; struct video_stm32_dcmi_data *data = dev->data; - unsigned int bpp = video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE; + int ret; - if (bpp == 0 || (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL)) { + if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { return -EINVAL; } - if ((fmt->pitch * fmt->height) > CONFIG_VIDEO_BUFFER_POOL_SZ_MAX) { - return -EINVAL; + ret = video_stm32_dcmi_is_fmt_valid(fmt->pixelformat, fmt->pitch, fmt->height); + if (ret < 0) { + return ret; } - data->pixel_format = fmt->pixelformat; - data->pitch = fmt->pitch; - data->height = fmt->height; - data->width = fmt->width; - - if (video_set_format(config->sensor_dev, ep, fmt)) { - return -EIO; + ret = video_set_format(config->sensor_dev, ep, fmt); + if (ret < 0) { + return ret; } + data->fmt = *fmt; + return 0; } @@ -230,33 +230,44 @@ static int video_stm32_dcmi_get_fmt(const struct device *dev, { struct video_stm32_dcmi_data *data = dev->data; const struct video_stm32_dcmi_config *config = dev->config; + int ret; if (fmt == NULL || (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL)) { return -EINVAL; } - if (!video_get_format(config->sensor_dev, ep, fmt)) { - /* align DCMI with sensor fmt */ - return video_stm32_dcmi_set_fmt(dev, ep, fmt); + /* Align DCMI format with the one provided by the sensor */ + ret = video_get_format(config->sensor_dev, ep, fmt); + if (ret < 0) { + return ret; } - fmt->pixelformat = data->pixel_format; - fmt->height = data->height; - fmt->width = data->width; - fmt->pitch = data->pitch; + ret = video_stm32_dcmi_is_fmt_valid(fmt->pixelformat, fmt->pitch, fmt->height); + if (ret < 0) { + return ret; + } + + data->fmt = *fmt; return 0; } +#define STM32_DCMI_GET_CAPTURE_RATE(capture_rate) \ + ((capture_rate) == 1 ? DCMI_CR_ALL_FRAME : \ + (capture_rate) == 2 ? DCMI_CR_ALTERNATE_2_FRAME : \ + (capture_rate) == 4 ? DCMI_CR_ALTERNATE_4_FRAME : \ + DCMI_CR_ALL_FRAME) + static int video_stm32_dcmi_set_stream(const struct device *dev, bool enable) { - int err; struct video_stm32_dcmi_data *data = dev->data; const struct video_stm32_dcmi_config *config = dev->config; + int err; if (!enable) { - if (video_stream_stop(config->sensor_dev)) { - return -EIO; + err = video_stream_stop(config->sensor_dev); + if (err < 0) { + return err; } err = HAL_DCMI_Stop(&data->hdcmi); @@ -278,6 +289,10 @@ static int video_stm32_dcmi_set_stream(const struct device *dev, bool enable) return -ENOMEM; } + /* Set the frame control */ + data->hdcmi.Instance->CR &= ~(DCMI_CR_FCRC_0 | DCMI_CR_FCRC_1); + data->hdcmi.Instance->CR |= STM32_DCMI_GET_CAPTURE_RATE(data->capture_rate); + err = HAL_DCMI_Start_DMA(&data->hdcmi, DCMI_MODE_CONTINUOUS, (uint32_t)data->vbuf->buffer, data->vbuf->bytesused / 4); if (err != HAL_OK) { @@ -285,11 +300,7 @@ static int video_stm32_dcmi_set_stream(const struct device *dev, bool enable) return -EIO; } - if (video_stream_start(config->sensor_dev)) { - return -EIO; - } - - return 0; + return video_stream_start(config->sensor_dev); } static int video_stm32_dcmi_enqueue(const struct device *dev, @@ -297,7 +308,7 @@ static int video_stm32_dcmi_enqueue(const struct device *dev, struct video_buffer *vbuf) { struct video_stm32_dcmi_data *data = dev->data; - const uint32_t buffer_size = data->pitch * data->height; + const uint32_t buffer_size = data->fmt.pitch * data->fmt.height; if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { return -EINVAL; @@ -339,7 +350,6 @@ static int video_stm32_dcmi_get_caps(const struct device *dev, struct video_caps *caps) { const struct video_stm32_dcmi_config *config = dev->config; - int ret = -ENODEV; if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { return -EINVAL; @@ -349,9 +359,120 @@ static int video_stm32_dcmi_get_caps(const struct device *dev, caps->min_line_count = caps->max_line_count = LINE_COUNT_HEIGHT; /* Forward the message to the sensor device */ - ret = video_get_caps(config->sensor_dev, ep, caps); + return video_get_caps(config->sensor_dev, ep, caps); +} + +static int video_stm32_dcmi_enum_frmival(const struct device *dev, enum video_endpoint_id ep, + struct video_frmival_enum *fie) +{ + const struct video_stm32_dcmi_config *config = dev->config; + int ret; + + if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + + ret = video_stm32_dcmi_is_fmt_valid(fie->format->pixelformat, fie->format->pitch, + fie->format->height); + if (ret < 0) { + return ret; + } - return ret; + ret = video_enum_frmival(config->sensor_dev, ep, fie); + if (ret < 0) { + return ret; + } + + /* Adapt the interval in order to report the frame drop capabilities */ + if (fie->type == VIDEO_FRMIVAL_TYPE_DISCRETE) { + struct video_frmival discrete = fie->discrete; + + fie->type = VIDEO_FRMIVAL_TYPE_STEPWISE; + fie->stepwise.max = discrete; + fie->stepwise.min.denominator = discrete.denominator; + fie->stepwise.min.numerator = discrete.numerator * 4; + fie->stepwise.step.denominator = discrete.denominator; + fie->stepwise.step.numerator = discrete.numerator * 2; + } else { + fie->stepwise.min.numerator *= 4; + fie->stepwise.step.numerator *= 2; + } + + return 0; +} + +#define STM32_DCMI_MAX_FRAME_DROP 4 +static int video_stm32_dcmi_set_frmival(const struct device *dev, enum video_endpoint_id ep, + struct video_frmival *frmival) +{ + const struct video_stm32_dcmi_config *config = dev->config; + struct video_stm32_dcmi_data *data = dev->data; + struct video_frmival_enum fie = { + .format = &data->fmt, + }; + struct video_frmival best_sensor_frmival; + uint64_t best_diff_nsec = INT32_MAX; + uint64_t diff_nsec = 0, a, b; + int best_capture_rate = 1; + + if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + + /* + * Try to figure out a frameinterval setting allow to reach as close as + * possible to the request. At first without relying on DCMI frame control, + * then enabling it + */ + for (int capture_rate = 1; capture_rate <= STM32_DCMI_MAX_FRAME_DROP; capture_rate *= 2) { + /* + * Take into consideration the drop done by the DCMI hence multiply + * denominator by the rate introduced by the DCMI + */ + fie.discrete.numerator = frmival->numerator; + fie.discrete.denominator = frmival->denominator * capture_rate; + + a = video_frmival_nsec(&fie.discrete); + video_closest_frmival(config->sensor_dev, ep, &fie); + b = video_frmival_nsec(&fie.discrete); + diff_nsec = a > b ? a - b : b - a; + if (diff_nsec < best_diff_nsec) { + best_diff_nsec = diff_nsec; + best_sensor_frmival = fie.discrete; + best_capture_rate = capture_rate; + } + if (diff_nsec == 0) { + break; + } + } + + /* + * Give back the achieved frame interval achieved, ensuring to take into + * consideration the DCMI frame control + */ + frmival->numerator = best_sensor_frmival.numerator * best_capture_rate; + frmival->denominator = best_sensor_frmival.denominator; + + data->capture_rate = best_capture_rate; + + return video_set_frmival(config->sensor_dev, ep, &best_sensor_frmival); +} + +static int video_stm32_dcmi_get_frmival(const struct device *dev, enum video_endpoint_id ep, + struct video_frmival *frmival) +{ + const struct video_stm32_dcmi_config *config = dev->config; + struct video_stm32_dcmi_data *data = dev->data; + int ret; + + ret = video_get_frmival(config->sensor_dev, ep, frmival); + if (ret < 0) { + return ret; + } + + frmival->numerator *= data->capture_rate; + + return 0; } static DEVICE_API(video, video_stm32_dcmi_driver_api) = { @@ -361,6 +482,9 @@ static DEVICE_API(video, video_stm32_dcmi_driver_api) = { .enqueue = video_stm32_dcmi_enqueue, .dequeue = video_stm32_dcmi_dequeue, .get_caps = video_stm32_dcmi_get_caps, + .enum_frmival = video_stm32_dcmi_enum_frmival, + .set_frmival = video_stm32_dcmi_set_frmival, + .get_frmival = video_stm32_dcmi_get_frmival, }; static void video_stm32_dcmi_irq_config_func(const struct device *dev) @@ -392,12 +516,6 @@ static void video_stm32_dcmi_irq_config_func(const struct device *dev) PINCTRL_DT_INST_DEFINE(0); -#define STM32_DCMI_GET_CAPTURE_RATE(capture_rate) \ - ((capture_rate) == 1 ? DCMI_CR_ALL_FRAME : \ - (capture_rate) == 2 ? DCMI_CR_ALTERNATE_2_FRAME : \ - (capture_rate) == 4 ? DCMI_CR_ALTERNATE_4_FRAME : \ - DCMI_CR_ALL_FRAME) - #define STM32_DCMI_GET_BUS_WIDTH(bus_width) \ ((bus_width) == 8 ? DCMI_EXTEND_DATA_8B : \ (bus_width) == 10 ? DCMI_EXTEND_DATA_10B : \ @@ -417,16 +535,19 @@ static struct video_stm32_dcmi_data video_stm32_dcmi_data_0 = { .Instance = (DCMI_TypeDef *) DT_INST_REG_ADDR(0), .Init = { .SynchroMode = DCMI_SYNCHRO_HARDWARE, - .PCKPolarity = (DT_INST_PROP(0, pixelclk_active) ? - DCMI_PCKPOLARITY_RISING : DCMI_PCKPOLARITY_FALLING), - .HSPolarity = (DT_INST_PROP(0, hsync_active) ? - DCMI_HSPOLARITY_HIGH : DCMI_HSPOLARITY_LOW), - .VSPolarity = (DT_INST_PROP(0, vsync_active) ? - DCMI_VSPOLARITY_HIGH : DCMI_VSPOLARITY_LOW), - .CaptureRate = STM32_DCMI_GET_CAPTURE_RATE( - DT_INST_PROP(0, capture_rate)), + .PCKPolarity = DT_PROP_OR(DT_INST_ENDPOINT_BY_ID(n, 0, 0), + pclk_sample, 0) ? + DCMI_PCKPOLARITY_RISING : + DCMI_PCKPOLARITY_FALLING, + .HSPolarity = DT_PROP_OR(DT_INST_ENDPOINT_BY_ID(n, 0, 0), + hsync_active, 0) ? + DCMI_HSPOLARITY_HIGH : DCMI_HSPOLARITY_LOW, + .VSPolarity = DT_PROP_OR(DT_INST_ENDPOINT_BY_ID(n, 0, 0), + vsync_active, 0) ? + DCMI_VSPOLARITY_HIGH : DCMI_VSPOLARITY_LOW, .ExtendedDataMode = STM32_DCMI_GET_BUS_WIDTH( - DT_INST_PROP(0, bus_width)), + DT_PROP_OR(DT_INST_ENDPOINT_BY_ID(n, 0, 0), + bus_width, 8)), .JPEGMode = DCMI_JPEG_DISABLE, .ByteSelectMode = DCMI_BSM_ALL, .ByteSelectStart = DCMI_OEBS_ODD, @@ -436,7 +557,7 @@ static struct video_stm32_dcmi_data video_stm32_dcmi_data_0 = { }, }; -#define SOURCE_DEV(n) DEVICE_DT_GET(DT_INST_PHANDLE(n, sensor)) +#define SOURCE_DEV(n) DEVICE_DT_GET(DT_NODE_REMOTE_DEVICE(DT_INST_ENDPOINT_BY_ID(n, 0, 0))) static const struct video_stm32_dcmi_config video_stm32_dcmi_config_0 = { .pclken = { @@ -473,12 +594,13 @@ static int video_stm32_dcmi_init(const struct device *dev) err = stm32_dcmi_enable_clock(dev); if (err < 0) { LOG_ERR("Clock enabling failed."); - return -EIO; + return err; } data->dev = dev; k_fifo_init(&data->fifo_in); k_fifo_init(&data->fifo_out); + data->capture_rate = 1; /* Run IRQ init */ config->irq_config(dev); diff --git a/dts/arm/st/h7/stm32h7.dtsi b/dts/arm/st/h7/stm32h7.dtsi index 409d0bb1edf3..635f859b3225 100644 --- a/dts/arm/st/h7/stm32h7.dtsi +++ b/dts/arm/st/h7/stm32h7.dtsi @@ -1086,6 +1086,9 @@ interrupts = <78 0>; interrupt-names = "dcmi"; clocks = <&rcc STM32_CLOCK(AHB2, 0U)>; + dmas = <&dma1 0 75 (STM32_DMA_PERIPH_TO_MEMORY | STM32_DMA_PERIPH_NO_INC | + STM32_DMA_MEM_INC | STM32_DMA_PERIPH_8BITS | STM32_DMA_MEM_32BITS | + STM32_DMA_PRIORITY_HIGH) STM32_DMA_FIFO_1_4>; status = "disabled"; }; }; diff --git a/dts/bindings/video/st,stm32-dcmi.yaml b/dts/bindings/video/st,stm32-dcmi.yaml index 567b8d0efa8c..41da6c7659f9 100644 --- a/dts/bindings/video/st,stm32-dcmi.yaml +++ b/dts/bindings/video/st,stm32-dcmi.yaml @@ -11,23 +11,18 @@ description: | &dcmi { status = "okay"; - sensor = <&ov2640>; pinctrl-0 = <&dcmi_hsync_pa4 &dcmi_pixclk_pa6 &dcmi_vsync_pb7 &dcmi_d0_pc6 &dcmi_d1_pc7 &dcmi_d2_pe0 &dcmi_d3_pe1 &dcmi_d4_pe4 &dcmi_d5_pd3 &dcmi_d6_pe5 &dcmi_d7_pe6>; pinctrl-names = "default"; - bus-width = <8>; - hsync-active = <0>; - vsync-active = <0>; - pixelclk-active = <1>; - capture-rate = <1>; - dmas = <&dma1 0 75 (STM32_DMA_PERIPH_TO_MEMORY | STM32_DMA_PERIPH_NO_INC | - STM32_DMA_MEM_INC | STM32_DMA_PERIPH_8BITS | STM32_DMA_MEM_32BITS | - STM32_DMA_PRIORITY_HIGH) STM32_DMA_FIFO_1_4>; port { dcmi_ep_in: endpoint { - remote-endpoint = <&ov2640_ep_out>; + remote-endpoint-label = "ov2640_ep_out"; + bus-width = <8>; + hsync-active = <0>; + vsync-active = <0>; + pclk-sample = <1>; }; }; }; @@ -40,78 +35,6 @@ properties: interrupts: required: true - sensor: - required: true - type: phandle - description: phandle of connected sensor device - - bus-width: - type: int - required: true - enum: - - 8 - - 10 - - 12 - - 14 - default: 8 - description: | - Number of data lines actively used, valid for the parallel busses. - - hsync-active: - type: int - required: true - enum: - - 0 - - 1 - description: | - Polarity of horizontal synchronization (DCMI_HSYNC_Polarity). - 0 Horizontal synchronization active Low. - 1 Horizontal synchronization active High. - - For example, if DCMI_HSYNC_Polarity is programmed active high: - When HSYNC is low, the data is valid. - When HSYNC is high, the data is not valid (horizontal blanking). - - vsync-active: - type: int - required: true - enum: - - 0 - - 1 - description: | - Polarity of vertical synchronization (DCMI_VSYNC_Polarity). - 0 Vertical synchronization active Low. - 1 Vertical synchronization active High. - - For example, if DCMI_VSYNC_Polarity is programmed active high: - When VSYNC is low, the data is valid. - When VSYNC is high, the data is not valid (vertical blanking). - - pixelclk-active: - type: int - required: true - enum: - - 0 - - 1 - description: | - Polarity of pixel clock (DCMI_PIXCK_Polarity). - 0 Pixel clock active on Falling edge. - 1 Pixel clock active on Rising edge. - - capture-rate: - type: int - enum: - - 1 - - 2 - - 4 - default: 1 - description: | - The DCMI can capture all frames or alternate frames. If it is not specified, - the default is all frames. - 1 Capture all frames. - 2 Capture alternate frames. - 4 Capture one frame every 4 frames. - dmas: required: true description: | @@ -122,3 +45,7 @@ properties: dmas = <&dma1 0 75 (STM32_DMA_PERIPH_TO_MEMORY | STM32_DMA_PERIPH_NO_INC | STM32_DMA_MEM_INC | STM32_DMA_PERIPH_8BITS | STM32_DMA_MEM_32BITS | STM32_DMA_PRIORITY_HIGH) STM32_DMA_FIFO_1_4>; + +child-binding: + child-binding: + include: video-interfaces.yaml diff --git a/tests/drivers/build_all/video/testcase.yaml b/tests/drivers/build_all/video/testcase.yaml index 57e74e801686..8b356bb4f75e 100644 --- a/tests/drivers/build_all/video/testcase.yaml +++ b/tests/drivers/build_all/video/testcase.yaml @@ -22,3 +22,9 @@ tests: drivers.video.mcux_smartdma.build: platform_allow: - frdm_mcxn947/mcxn947/cpu0 + drivers.video.stm32_dcmi.build: + platform_allow: + - stm32h7b3i_dk/stm32h7b3xx + - arduino_nicla_vision/stm32h747xx/m7 + extra_args: + - platform:stm32h7b3i_dk/stm32h7b3xx:SHIELD=st_b_cams_omv_mb1683