Skip to content

Commit d7847ab

Browse files
committed
camera: try to defer init of video objects
This change, removes the automatic starting of the PWM clock on the GIGA, at startup. Instead it starts the clock if/when the sketch calls the Camera::begin method. But to make this work, we also need to not start up the video objects, until after the MCLK has been started. We can do that with marking them as zephyr,deferred-init
1 parent 9b16dea commit d7847ab

4 files changed

Lines changed: 65 additions & 33 deletions

File tree

libraries/Camera/src/camera.cpp

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,73 @@ Camera::Camera() : byte_swap(false), yuv_to_gray(false), vdev(NULL) {
5050
}
5151
}
5252

53+
#if defined(CONFIG_VIDEO)
54+
#include <zephyr/kernel.h>
55+
#include <zephyr/device.h>
56+
#include <zephyr/drivers/clock_control.h>
57+
#include <zephyr/logging/log.h>
58+
59+
int camera_ext_clock_enable(void) {
60+
int ret;
61+
uint32_t rate;
62+
const struct device *cam_ext_clk_dev = DEVICE_DT_GET(DT_NODELABEL(pwmclock));
63+
64+
if (!device_is_ready(cam_ext_clk_dev)) {
65+
return -ENODEV;
66+
}
67+
68+
ret = clock_control_on(cam_ext_clk_dev, (clock_control_subsys_t)0);
69+
if (ret < 0) {
70+
return ret;
71+
}
72+
73+
ret = clock_control_get_rate(cam_ext_clk_dev, (clock_control_subsys_t)0, &rate);
74+
if (ret < 0) {
75+
return ret;
76+
}
77+
78+
return 0;
79+
}
80+
#else
81+
#ERROR "CONFIG_VIDEO is not defined for this variant"
82+
#endif
83+
5384
bool Camera::begin(uint32_t width, uint32_t height, uint32_t pixformat, bool byte_swap) {
5485
#if DT_HAS_CHOSEN(zephyr_camera)
5586
this->vdev = DEVICE_DT_GET(DT_CHOSEN(zephyr_camera));
5687
#endif
5788

58-
if (!this->vdev || !device_is_ready(this->vdev)) {
89+
// start the clock
90+
int ret;
91+
92+
if (!this->vdev) {
5993
return false;
6094
}
6195

96+
camera_ext_clock_enable();
97+
delay(50);
98+
99+
if (!device_is_ready(this->vdev)) {
100+
// device probably has zephyr,deferred-init
101+
// On GIGA and Portenta H7 and probably others starts DCIM object
102+
if ((ret = device_init(this->vdev)) < 0) {
103+
printk("device_init camera(%p) failed:%d\n", this->vdev, ret);
104+
return false;
105+
}
106+
}
107+
108+
// Now see if the actual camera is defined in choosen. And see if it is ready
109+
#if DT_HAS_CHOSEN(zephyr_camera_sensor)
110+
const struct device *camera_sensor = DEVICE_DT_GET(DT_CHOSEN(zephyr_camera_sensor));
111+
if (!device_is_ready(camera_sensor)) {
112+
if ((ret = device_init(camera_sensor)) < 0) {
113+
printk("device_init camera sensor(%p) failed:%d\n", camera_sensor, ret);
114+
return false;
115+
}
116+
}
117+
118+
#endif
119+
62120
switch (pixformat) {
63121
case CAMERA_RGB565:
64122
this->byte_swap = byte_swap;

loader/fixups.c

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -76,38 +76,6 @@ static void zephyr_input_callback(struct input_event *evt, void *user_data) {
7676
INPUT_CALLBACK_DEFINE(NULL, zephyr_input_callback, NULL);
7777
#endif
7878

79-
#if defined(CONFIG_BOARD_ARDUINO_GIGA_R1) && defined(CONFIG_VIDEO)
80-
#include <zephyr/kernel.h>
81-
#include <zephyr/device.h>
82-
#include <zephyr/drivers/clock_control.h>
83-
#include <zephyr/logging/log.h>
84-
85-
int camera_ext_clock_enable(void) {
86-
int ret;
87-
uint32_t rate;
88-
const struct device *cam_ext_clk_dev = DEVICE_DT_GET(DT_NODELABEL(pwmclock));
89-
90-
if (!device_is_ready(cam_ext_clk_dev)) {
91-
return -ENODEV;
92-
}
93-
94-
ret = clock_control_on(cam_ext_clk_dev, (clock_control_subsys_t)0);
95-
if (ret < 0) {
96-
return ret;
97-
}
98-
99-
ret = clock_control_get_rate(cam_ext_clk_dev, (clock_control_subsys_t)0, &rate);
100-
if (ret < 0) {
101-
return ret;
102-
}
103-
104-
return 0;
105-
}
106-
107-
SYS_INIT(camera_ext_clock_enable, POST_KERNEL, CONFIG_CLOCK_CONTROL_PWM_INIT_PRIORITY);
108-
109-
#endif
110-
11179
#if defined(CONFIG_SHARED_MULTI_HEAP)
11280
#include <zephyr/kernel.h>
11381
#include <zephyr/devicetree.h>

variants/arduino_giga_r1_stm32h747xx_m7/arduino_giga_r1_stm32h747xx_m7.overlay

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
gc2145: gc2145@3c {
4646
compatible = "galaxycore,gc2145";
4747
reg = <0x3c>;
48+
zephyr,deferred-init;
4849
reset-gpios = <&gpiod 4 GPIO_ACTIVE_LOW>;
4950
pwdn-gpios = <&gpioa 1 GPIO_ACTIVE_LOW>;
5051

@@ -167,6 +168,7 @@
167168

168169
&dcmi {
169170
status = "okay";
171+
zephyr,deferred-init;
170172
/* ext-sdram = <&sdram1>; */
171173
pinctrl-0 = <&dcmi_hsync_ph8 &dcmi_pixclk_pa6 &dcmi_vsync_pi5
172174
&dcmi_d0_ph9 &dcmi_d1_ph10 &dcmi_d2_ph11 &dcmi_d3_pg11
@@ -339,6 +341,7 @@
339341
/{
340342
chosen {
341343
zephyr,camera = &dcmi;
344+
zephyr,camera-sensor = &gc2145;
342345
zephyr,log-uart = &log_uarts;
343346
/* zephyr,console = &board_cdc_acm_uart; */
344347
};

variants/arduino_portenta_h7_stm32h747xx_m7/arduino_portenta_h7_stm32h747xx_m7.overlay

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
gc2145: gc2145@3c {
4040
compatible = "galaxycore,gc2145";
4141
reg = <0x3c>;
42+
zephyr,deferred-init;
4243
status = "okay";
4344

4445
reset-gpios = <&gpioe 3 GPIO_ACTIVE_LOW>;
@@ -151,6 +152,7 @@
151152

152153
&dcmi {
153154
status = "okay";
155+
zephyr,deferred-init;
154156
/* ext-sdram = <&sdram1>; */
155157
pinctrl-0 = <&dcmi_hsync_pa4 &dcmi_pixclk_pa6 &dcmi_vsync_pi5
156158
&dcmi_d0_ph9 &dcmi_d1_ph10 &dcmi_d2_ph11 &dcmi_d3_ph12
@@ -264,6 +266,7 @@
264266
/ {
265267
chosen {
266268
zephyr,camera = &dcmi;
269+
zephyr,camera-sensor = &gc2145;
267270
zephyr,console = &usart6;
268271
zephyr,shell-uart = &usart6;
269272
zephyr,cdc-acm-uart0 = &usart6;

0 commit comments

Comments
 (0)