1919
2020#include "video_ctrls.h"
2121#include "video_device.h"
22+ #include "video_stm32_dcmipp.h"
2223
2324#define DT_DRV_COMPAT st_stm32_dcmipp
2425
3637#define STM32_DCMIPP_HAS_PIXEL_PIPES
3738#endif
3839
40+ /* Weak function declaration in order to interface with external ISP handler */
41+ void __weak stm32_dcmipp_isp_vsync_update (DCMIPP_HandleTypeDef * hdcmipp , uint32_t Pipe )
42+ {
43+ }
44+
45+ int __weak stm32_dcmipp_isp_init (DCMIPP_HandleTypeDef * hdcmipp , const struct device * sensor )
46+ {
47+ return 0 ;
48+ }
49+
50+ int __weak stm32_dcmipp_isp_start (void )
51+ {
52+ return 0 ;
53+ }
54+
55+ int __weak stm32_dcmipp_isp_stop (void )
56+ {
57+ return 0 ;
58+ }
59+
3960LOG_MODULE_REGISTER (stm32_dcmipp , CONFIG_VIDEO_LOG_LEVEL );
4061
4162typedef void (* irq_config_func_t )(const struct device * dev );
@@ -152,6 +173,12 @@ void HAL_DCMIPP_PIPE_VsyncEventCallback(DCMIPP_HandleTypeDef *hdcmipp, uint32_t
152173 struct stm32_dcmipp_pipe_data * pipe = dcmipp -> pipe [Pipe ];
153174 int ret ;
154175
176+ /*
177+ * Let the external ISP handler know that a VSYNC happened a new statistics are
178+ * thus available
179+ */
180+ stm32_dcmipp_isp_vsync_update (hdcmipp , Pipe );
181+
155182 if (pipe -> state != STM32_DCMIPP_RUNNING ) {
156183 return ;
157184 }
@@ -529,9 +556,64 @@ static int stm32_dcmipp_set_fmt(const struct device *dev, struct video_format *f
529556 return ret ;
530557}
531558
559+ #if defined(STM32_DCMIPP_HAS_PIXEL_PIPES )
560+ static void stm32_dcmipp_get_isp_decimation (struct stm32_dcmipp_data * dcmipp )
561+ {
562+ DCMIPP_DecimationConfTypeDef ispdec_cfg ;
563+ uint32_t is_enabled ;
564+
565+ is_enabled = HAL_DCMIPP_PIPE_IsEnabledISPDecimation (& dcmipp -> hdcmipp , DCMIPP_PIPE1 );
566+ if (is_enabled == 0 ) {
567+ dcmipp -> isp_dec_hratio = 1 ;
568+ dcmipp -> isp_dec_vratio = 1 ;
569+ } else {
570+ HAL_DCMIPP_PIPE_GetISPDecimationConfig (& dcmipp -> hdcmipp , DCMIPP_PIPE1 , & ispdec_cfg );
571+ dcmipp -> isp_dec_hratio = 1 << (ispdec_cfg .HRatio >> DCMIPP_P1DECR_HDEC_Pos );
572+ dcmipp -> isp_dec_vratio = 1 << (ispdec_cfg .VRatio >> DCMIPP_P1DECR_VDEC_Pos );
573+ }
574+ }
575+ #endif
576+
532577static int stm32_dcmipp_get_fmt (const struct device * dev , struct video_format * fmt )
533578{
534579 struct stm32_dcmipp_pipe_data * pipe = dev -> data ;
580+ #if defined(STM32_DCMIPP_HAS_PIXEL_PIPES )
581+ struct stm32_dcmipp_data * dcmipp = pipe -> dcmipp ;
582+ const struct stm32_dcmipp_config * config = dev -> config ;
583+ static atomic_t isp_init_once ;
584+ int ret ;
585+
586+ /* Initialize the external ISP handling stack */
587+ /*
588+ * TODO - this is not the right place to do that, however we need to know
589+ * the sensor format before calling the isp_init handler hence can't
590+ * do that within the stm32_dcmipp_init function due to unknown
591+ * driver initialization order
592+ *
593+ * Would need an ops that get called when both side of an endpoint get
594+ * initiialized
595+ */
596+ if (atomic_cas (& isp_init_once , 0 , 1 ) &&
597+ (pipe -> id == DCMIPP_PIPE1 || pipe -> id == DCMIPP_PIPE2 )) {
598+ /*
599+ * It is necessary to perform a dummy configuration here otherwise any
600+ * ISP related configuration done by the stm32_dcmipp_isp_init will
601+ * fail due to the HAL DCMIPP driver not being in READY state
602+ */
603+ ret = stm32_dcmipp_conf_parallel (dcmipp -> dev , & stm32_dcmipp_input_fmt_desc [0 ]);
604+ if (ret < 0 ) {
605+ LOG_ERR ("Failed to perform dummy parallel configuration" );
606+ return ret ;
607+ }
608+
609+ ret = stm32_dcmipp_isp_init (& dcmipp -> hdcmipp , config -> sensor_dev );
610+ if (ret < 0 ) {
611+ LOG_ERR ("Failed to initialize the ISP" );
612+ return ret ;
613+ }
614+ stm32_dcmipp_get_isp_decimation (dcmipp );
615+ }
616+ #endif
535617
536618 * fmt = pipe -> fmt ;
537619
@@ -869,6 +951,12 @@ static int stm32_dcmipp_stream_enable(const struct device *dev)
869951 }
870952#endif
871953
954+ /* Initialize the external ISP handling stack */
955+ ret = stm32_dcmipp_isp_init (& dcmipp -> hdcmipp , config -> sensor_dev );
956+ if (ret < 0 ) {
957+ goto out ;
958+ }
959+
872960 /* Enable the DCMIPP Pipeline */
873961 if (config -> bus_type == VIDEO_BUS_TYPE_PARALLEL ) {
874962 ret = HAL_DCMIPP_PIPE_Start (& dcmipp -> hdcmipp , pipe -> id ,
@@ -914,6 +1002,12 @@ static int stm32_dcmipp_stream_enable(const struct device *dev)
9141002 }
9151003 }
9161004
1005+ /* Start the external ISP handling */
1006+ ret = stm32_dcmipp_isp_start ();
1007+ if (ret < 0 ) {
1008+ goto out ;
1009+ }
1010+
9171011 pipe -> state = STM32_DCMIPP_RUNNING ;
9181012 pipe -> is_streaming = true;
9191013 dcmipp -> enabled_pipe ++ ;
@@ -938,6 +1032,12 @@ static int stm32_dcmipp_stream_disable(const struct device *dev)
9381032 goto out ;
9391033 }
9401034
1035+ /* Stop the external ISP handling */
1036+ ret = stm32_dcmipp_isp_stop ();
1037+ if (ret < 0 ) {
1038+ goto out ;
1039+ }
1040+
9411041 /* Disable the DCMIPP Pipeline */
9421042 if (config -> bus_type == VIDEO_BUS_TYPE_PARALLEL ) {
9431043 ret = HAL_DCMIPP_PIPE_Stop (& dcmipp -> hdcmipp , pipe -> id );
0 commit comments