Skip to content

Commit e39c928

Browse files
committed
video: hm01b0: 324->326. orientation, bayer
Changed 324 to 326 as that is what the camera is returning with current settings. Now image output over USB shows correctly on Arducam test app on windows Added BAYER format for the color camera added hflip/vflip controls to support orientation. Signed-off-by: Kurt Eckhardt <kurte@rockisland.com
1 parent 218d245 commit e39c928

File tree

1 file changed

+98
-8
lines changed

1 file changed

+98
-8
lines changed

drivers/video/hm01b0.c

Lines changed: 98 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <zephyr/sys/util.h>
1717

1818
#include "video_device.h"
19+
#include "video_ctrls.h"
1920
#include "video_common.h"
2021

2122
LOG_MODULE_REGISTER(hm01b0, CONFIG_VIDEO_LOG_LEVEL);
@@ -27,6 +28,7 @@ LOG_MODULE_REGISTER(hm01b0, CONFIG_VIDEO_LOG_LEVEL);
2728
#define HM01B0_REG8(addr) ((addr) | VIDEO_REG_ADDR16_DATA8)
2829
#define HM01B0_REG16(addr) ((addr) | VIDEO_REG_ADDR16_DATA16_BE)
2930
#define HM01B0_CCI_ID HM01B0_REG16(0x0000)
31+
#define HM01B0_CCI_IMG_ORIENTATION HM01B0_REG8(0x0101)
3032
#define HM01B0_CCI_STS HM01B0_REG8(0x0100)
3133
#define HM01B0_CCI_RESET HM01B0_REG8(0x0103)
3234
#define HM01B0_CCI_GRP_PARAM_HOLD HM01B0_REG8(0x0104)
@@ -40,6 +42,9 @@ LOG_MODULE_REGISTER(hm01b0, CONFIG_VIDEO_LOG_LEVEL);
4042
#define HM01B0_CCI_BIT_CONTROL HM01B0_REG8(0x3059)
4143
#define HM01B0_CCI_OSC_CLOCK_DIV HM01B0_REG8(0x3060)
4244

45+
#define HM01B0_SET_HMIRROR(r, x) ((r & 0xFE) | ((x & 1) << 0))
46+
#define HM01B0_SET_VMIRROR(r, x) ((r & 0xFD) | ((x & 1) << 1))
47+
4348
#define HM01B0_CTRL_VAL(data_bits) \
4449
((data_bits) == 8 ? 0x02 : \
4550
(data_bits) == 4 ? 0x42 : \
@@ -49,8 +54,12 @@ enum hm01b0_resolution {
4954
RESOLUTION_160x120,
5055
RESOLUTION_320x240,
5156
RESOLUTION_320x320,
52-
RESOLUTION_324x244,
53-
RESOLUTION_324x324,
57+
RESOLUTION_164x122,
58+
RESOLUTION_326x244,
59+
RESOLUTION_326x324,
60+
RESOLUTION_164x122_BAYER,
61+
RESOLUTION_326x244_BAYER,
62+
RESOLUTION_326x324_BAYER,
5463
};
5564

5665
struct video_reg hm01b0_160x120_regs[] = {
@@ -84,11 +93,21 @@ struct video_reg *hm01b0_init_regs[] = {
8493
[RESOLUTION_160x120] = hm01b0_160x120_regs,
8594
[RESOLUTION_320x240] = hm01b0_320x240_regs,
8695
[RESOLUTION_320x320] = hm01b0_320x320_regs,
87-
[RESOLUTION_324x244] = hm01b0_320x240_regs,
88-
[RESOLUTION_324x324] = hm01b0_320x320_regs,
96+
[RESOLUTION_164x122] = hm01b0_160x120_regs,
97+
[RESOLUTION_326x244] = hm01b0_320x240_regs,
98+
[RESOLUTION_326x324] = hm01b0_320x320_regs,
99+
[RESOLUTION_164x122_BAYER] = hm01b0_160x120_regs,
100+
[RESOLUTION_326x244_BAYER] = hm01b0_320x240_regs,
101+
[RESOLUTION_326x324_BAYER] = hm01b0_320x320_regs,
102+
};
103+
104+
struct hm01b0_ctrls {
105+
struct video_ctrl hflip;
106+
struct video_ctrl vflip;
89107
};
90108

91109
struct hm01b0_data {
110+
struct hm01b0_ctrls ctrls;
92111
struct video_format fmt;
93112
};
94113

@@ -119,8 +138,12 @@ static const struct video_format_cap hm01b0_fmts[] = {
119138
HM01B0_VIDEO_FORMAT_CAP(160, 120, VIDEO_PIX_FMT_GREY),
120139
HM01B0_VIDEO_FORMAT_CAP(320, 240, VIDEO_PIX_FMT_GREY),
121140
HM01B0_VIDEO_FORMAT_CAP(320, 320, VIDEO_PIX_FMT_GREY),
122-
HM01B0_VIDEO_FORMAT_CAP(324, 244, VIDEO_PIX_FMT_GREY),
123-
HM01B0_VIDEO_FORMAT_CAP(324, 324, VIDEO_PIX_FMT_GREY),
141+
HM01B0_VIDEO_FORMAT_CAP(164, 122, VIDEO_PIX_FMT_GREY),
142+
HM01B0_VIDEO_FORMAT_CAP(326, 244, VIDEO_PIX_FMT_GREY),
143+
HM01B0_VIDEO_FORMAT_CAP(326, 324, VIDEO_PIX_FMT_GREY),
144+
HM01B0_VIDEO_FORMAT_CAP(164, 122, VIDEO_PIX_FMT_SBGGR8),
145+
HM01B0_VIDEO_FORMAT_CAP(326, 324, VIDEO_PIX_FMT_SBGGR8),
146+
HM01B0_VIDEO_FORMAT_CAP(326, 244, VIDEO_PIX_FMT_SBGGR8),
124147
{0},
125148
};
126149

@@ -252,9 +275,74 @@ static int hm01b0_soft_reset(const struct device *dev)
252275
return ret;
253276
}
254277

278+
static int hm01b0_init_controls(const struct device *dev)
279+
{
280+
int ret;
281+
struct hm01b0_data *drv_data = dev->data;
282+
struct hm01b0_ctrls *ctrls = &drv_data->ctrls;
283+
284+
ret = video_init_ctrl(&ctrls->hflip, dev, VIDEO_CID_HFLIP,
285+
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0});
286+
if (ret) {
287+
return ret;
288+
}
289+
290+
return video_init_ctrl(&ctrls->vflip, dev, VIDEO_CID_VFLIP,
291+
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0});
292+
}
293+
294+
static int hm01b0_set_ctrl(const struct device *dev, uint32_t id)
295+
{
296+
const struct hm01b0_config *config = dev->config;
297+
struct hm01b0_data *drv_data = dev->data;
298+
struct hm01b0_ctrls *ctrls = &drv_data->ctrls;
299+
300+
int ret;
301+
uint32_t data;
302+
303+
switch (id) {
304+
case VIDEO_CID_HFLIP:
305+
ret = video_read_cci_reg(&config->i2c, HM01B0_CCI_IMG_ORIENTATION, &data);
306+
if (ret < 0) {
307+
return ret;
308+
}
309+
ret = video_write_cci_reg(&config->i2c, HM01B0_CCI_IMG_ORIENTATION,
310+
HM01B0_SET_HMIRROR(data, ctrls->hflip.val));
311+
if (ret < 0) {
312+
return ret;
313+
}
314+
ret = video_write_cci_reg(&config->i2c, HM01B0_CCI_GRP_PARAM_HOLD, 0x01);
315+
if (ret < 0) {
316+
return ret;
317+
}
318+
break;
319+
case VIDEO_CID_VFLIP:
320+
ret = video_read_cci_reg(&config->i2c, HM01B0_CCI_IMG_ORIENTATION, &data);
321+
if (ret < 0) {
322+
return ret;
323+
}
324+
ret = video_write_cci_reg(&config->i2c, HM01B0_CCI_IMG_ORIENTATION,
325+
HM01B0_SET_VMIRROR(data, ctrls->vflip.val));
326+
if (ret < 0) {
327+
return ret;
328+
}
329+
ret = video_write_cci_reg(&config->i2c, HM01B0_CCI_GRP_PARAM_HOLD, 0x01);
330+
if (ret < 0) {
331+
return ret;
332+
}
333+
break;
334+
default:
335+
return -ENOTSUP;
336+
}
337+
338+
return 0;
339+
}
340+
341+
255342
static DEVICE_API(video, hm01b0_driver_api) = {
256343
.set_format = hm01b0_set_fmt,
257344
.get_format = hm01b0_get_fmt,
345+
.set_ctrl = hm01b0_set_ctrl,
258346
.set_stream = hm01b0_set_stream,
259347
.get_caps = hm01b0_get_caps,
260348
};
@@ -310,7 +398,7 @@ static bool hm01b0_try_reset_pwdn_pins(const struct device *dev, uint8_t iter)
310398

311399
static int hm01b0_init(const struct device *dev)
312400
{
313-
const struct hm01b0_config *config = dev->config;
401+
const struct hm01b0_config __maybe_unused *config = dev->config;
314402
int ret;
315403

316404
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(pwdn_gpios) || DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
@@ -376,7 +464,9 @@ static int hm01b0_init(const struct device *dev)
376464
return ret;
377465
}
378466

379-
return 0;
467+
468+
/* Initialize controls */
469+
return hm01b0_init_controls(dev);
380470
}
381471

382472
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)

0 commit comments

Comments
 (0)