19
19
20
20
#include "video_ctrls.h"
21
21
#include "video_device.h"
22
+ #include "video_stm32_dcmipp.h"
22
23
23
24
#define DT_DRV_COMPAT st_stm32_dcmipp
24
25
36
37
#define STM32_DCMIPP_HAS_PIXEL_PIPES
37
38
#endif
38
39
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
+
39
60
LOG_MODULE_REGISTER (stm32_dcmipp , CONFIG_VIDEO_LOG_LEVEL );
40
61
41
62
typedef void (* irq_config_func_t )(const struct device * dev );
@@ -152,6 +173,12 @@ void HAL_DCMIPP_PIPE_VsyncEventCallback(DCMIPP_HandleTypeDef *hdcmipp, uint32_t
152
173
struct stm32_dcmipp_pipe_data * pipe = dcmipp -> pipe [Pipe ];
153
174
int ret ;
154
175
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
+
155
182
if (pipe -> state != STM32_DCMIPP_RUNNING ) {
156
183
return ;
157
184
}
@@ -529,9 +556,64 @@ static int stm32_dcmipp_set_fmt(const struct device *dev, struct video_format *f
529
556
return ret ;
530
557
}
531
558
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
+
532
577
static int stm32_dcmipp_get_fmt (const struct device * dev , struct video_format * fmt )
533
578
{
534
579
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
535
617
536
618
* fmt = pipe -> fmt ;
537
619
@@ -869,6 +951,12 @@ static int stm32_dcmipp_stream_enable(const struct device *dev)
869
951
}
870
952
#endif
871
953
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
+
872
960
/* Enable the DCMIPP Pipeline */
873
961
if (config -> bus_type == VIDEO_BUS_TYPE_PARALLEL ) {
874
962
ret = HAL_DCMIPP_PIPE_Start (& dcmipp -> hdcmipp , pipe -> id ,
@@ -914,6 +1002,12 @@ static int stm32_dcmipp_stream_enable(const struct device *dev)
914
1002
}
915
1003
}
916
1004
1005
+ /* Start the external ISP handling */
1006
+ ret = stm32_dcmipp_isp_start ();
1007
+ if (ret < 0 ) {
1008
+ goto out ;
1009
+ }
1010
+
917
1011
pipe -> state = STM32_DCMIPP_RUNNING ;
918
1012
pipe -> is_streaming = true;
919
1013
dcmipp -> enabled_pipe ++ ;
@@ -938,6 +1032,12 @@ static int stm32_dcmipp_stream_disable(const struct device *dev)
938
1032
goto out ;
939
1033
}
940
1034
1035
+ /* Stop the external ISP handling */
1036
+ ret = stm32_dcmipp_isp_stop ();
1037
+ if (ret < 0 ) {
1038
+ goto out ;
1039
+ }
1040
+
941
1041
/* Disable the DCMIPP Pipeline */
942
1042
if (config -> bus_type == VIDEO_BUS_TYPE_PARALLEL ) {
943
1043
ret = HAL_DCMIPP_PIPE_Stop (& dcmipp -> hdcmipp , pipe -> id );
0 commit comments