Skip to content

Commit f3a7fd9

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 c2014ad commit f3a7fd9

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
@@ -87,38 +87,6 @@ static void zephyr_input_callback(struct input_event *evt, void *user_data) {
8787
INPUT_CALLBACK_DEFINE(NULL, zephyr_input_callback, NULL);
8888
#endif
8989

90-
#if defined(CONFIG_BOARD_ARDUINO_GIGA_R1) && defined(CONFIG_VIDEO)
91-
#include <zephyr/kernel.h>
92-
#include <zephyr/device.h>
93-
#include <zephyr/drivers/clock_control.h>
94-
#include <zephyr/logging/log.h>
95-
96-
int camera_ext_clock_enable(void) {
97-
int ret;
98-
uint32_t rate;
99-
const struct device *cam_ext_clk_dev = DEVICE_DT_GET(DT_NODELABEL(pwmclock));
100-
101-
if (!device_is_ready(cam_ext_clk_dev)) {
102-
return -ENODEV;
103-
}
104-
105-
ret = clock_control_on(cam_ext_clk_dev, (clock_control_subsys_t)0);
106-
if (ret < 0) {
107-
return ret;
108-
}
109-
110-
ret = clock_control_get_rate(cam_ext_clk_dev, (clock_control_subsys_t)0, &rate);
111-
if (ret < 0) {
112-
return ret;
113-
}
114-
115-
return 0;
116-
}
117-
118-
SYS_INIT(camera_ext_clock_enable, POST_KERNEL, CONFIG_CLOCK_CONTROL_PWM_INIT_PRIORITY);
119-
120-
#endif
121-
12290
#if defined(CONFIG_SHARED_MULTI_HEAP)
12391
#include <zephyr/kernel.h>
12492
#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
@@ -38,6 +38,7 @@
3838
gc2145: gc2145@3c {
3939
compatible = "galaxycore,gc2145";
4040
reg = <0x3c>;
41+
zephyr,deferred-init;
4142
reset-gpios = <&gpiod 4 GPIO_ACTIVE_LOW>;
4243
pwdn-gpios = <&gpioa 1 GPIO_ACTIVE_LOW>;
4344

@@ -154,6 +155,7 @@
154155

155156
&dcmi {
156157
status = "okay";
158+
zephyr,deferred-init;
157159
/* ext-sdram = <&sdram1>; */
158160
pinctrl-0 = <&dcmi_hsync_ph8 &dcmi_pixclk_pa6 &dcmi_vsync_pi5
159161
&dcmi_d0_ph9 &dcmi_d1_ph10 &dcmi_d2_ph11 &dcmi_d3_pg11
@@ -326,6 +328,7 @@
326328
/{
327329
chosen {
328330
zephyr,camera = &dcmi;
331+
zephyr,camera-sensor = &gc2145;
329332
zephyr,log-uart = &log_uarts;
330333
/* zephyr,console = &board_cdc_acm_uart; */
331334
};

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
@@ -26,6 +26,7 @@
2626
gc2145: gc2145@3c {
2727
compatible = "galaxycore,gc2145";
2828
reg = <0x3c>;
29+
zephyr,deferred-init;
2930
status = "okay";
3031

3132
reset-gpios = <&gpioe 3 GPIO_ACTIVE_LOW>;
@@ -138,6 +139,7 @@
138139

139140
&dcmi {
140141
status = "okay";
142+
zephyr,deferred-init;
141143
/* ext-sdram = <&sdram1>; */
142144
pinctrl-0 = <&dcmi_hsync_pa4 &dcmi_pixclk_pa6 &dcmi_vsync_pi5
143145
&dcmi_d0_ph9 &dcmi_d1_ph10 &dcmi_d2_ph11 &dcmi_d3_ph12
@@ -251,6 +253,7 @@
251253
/ {
252254
chosen {
253255
zephyr,camera = &dcmi;
256+
zephyr,camera-sensor = &gc2145;
254257
zephyr,console = &usart6;
255258
zephyr,shell-uart = &usart6;
256259
zephyr,cdc-acm-uart0 = &usart6;

0 commit comments

Comments
 (0)