raspberrypi / rpicam-apps

BSD 2-Clause "Simplified" License
361 stars 205 forks source link

[BUG] Arducam ov7251 showing as not available #235

Closed amcelroy closed 1 year ago

amcelroy commented 2 years ago

Describe the bug libcamera-hello reports that no cameras are available

Bug report See attached

Additional context I'm trying to use the Arducam ov7251 with a Raspberry Pi Zero W 2. The camera works great at 133fps in Buster on a Raspberry Pi 4 with the library and utilities found: https://github.com/ArduCAM/MIPI_Camera. I reported the issue on the Arducam forum and was directed to checkout the Bullseye upgraded libcamera support which looks to have ov7251 support.

I'm an experienced embedded systems C programmer but in over my head in the Linux kernel space and MIPI camera protocol, but would he happy to run, compile, probe, or assist in any way possible.

Thank you very much for looking at this.

bug.txt

6by9 commented 2 years ago

ov7251 does not have a tuning file or camera_helper file in libcamera, so it won't be detected. The libcamera project has a requirement for all supported platforms to be running (or theoretically runnable) with mainline Linux kernels. The ov7251 driver isn't in mainline. Technically neither are imx477 or ov9281, but there is either a commitment or contract in place for that to happen.

amcelroy commented 2 years ago

ov7251 does not have a tuning file or camera_helper file in libcamera, so it won't be detected. The libcamera project has a requirement for all supported platforms to be running (or theoretically runnable) with mainline Linux kernels. The ov7251 driver isn't in mainline. Technically neither are imx477 or ov9281, but there is either a commitment or contract in place for that to happen.

Ah, ok, so it probably won't happen anytime soon. I saw the ov7251.c files the Linux kernel space and was hopeful. Thank you for the quick response. Should I close out the issue?

6by9 commented 2 years ago

My apologies, ov7251 is in mainline - https://github.com/torvalds/linux/blob/master/drivers/media/i2c/ov7251.c

There are 2 small patches on top of that that aren't necessary for the sensor to work, but should be acceptable to upstream without significant issue.

e1ced9cc34b7 media: i2c: ov7251: Make the enable GPIO optional.
e3524023692d media: i2c: ov7251: Add fwnode properties controls

(I think libcamera will object if the fwnode properties aren't present)

I do have an ov7251 on my desk here, so could ask @davidplowman to do a tuning (it's only a mono sensor so not too involved). I suspect that the camera helper will be the same as ov9281.

amcelroy commented 2 years ago

That is great news! For learning purposes, how did you find the additional patches? How would I apply these? I'd be happy to help if pointed in the right direction.

6by9 commented 2 years ago

I wrote the additional patches :-) https://github.com/raspberrypi/linux/commits/rpi-5.10.y/drivers/media/i2c/ov7251.c They're already built into any Pi kernel since December 2021 (apt should be more recent than that now).

The commit hashes don't match as I looked on an rpi-5.15.y branch, and that is currently being rebased against mainline instead of having merge commits.

For libcamera support you will need to enable the Media Controller API for the sensor. The easiest way at present would be to use dtoverlay=ov7251,media-controller=1 in config.txt. When support is merged into libcamera we'll change the default.

naushir commented 2 years ago

Looking at the bug report, there may be more work needed in the driver to be usable with libcamera:

[0:20:38.073481713] [877] ERROR CameraSensor camera_sensor.cpp:272 'ov7251 10-0060': Mandatory V4L2 control 0x009e0902 not available
[0:20:38.073527494] [877] ERROR CameraSensor camera_sensor.cpp:272 'ov7251 10-0060': Mandatory V4L2 control 0x009e0901 not available

This corresponds to HBLANK and VBLANK. The former is not important (for control, but still needed otherwise libcamera core will fail to run), but the latter will be.

naushir commented 2 years ago

There also might be a configuration issue with the kernel driver? It fails to probe the device:

[  933.012074] ov7251 10-0060: ov7251_write_reg: write reg error -121: reg=103, val=1
[  933.012091] ov7251 10-0060: could not set init registers
[ 1237.565248] ov7251 10-0060: ov7251_write_reg: write reg error -121: reg=103, val=1
[ 1237.565266] ov7251 10-0060: could not set init registers
6by9 commented 2 years ago

I don't have a datasheet for OV7251, but will see if I can sort out data for VBLANK and HBLANK. I suspect it'll be the same as OV9281 in 0x380e/f, which indeed are even commented in the init sequence as /* total vertical timing [high|low] */ and 0x380c/d as /* total horiz timing high */

It also doesn't have selection API implemented for active array size. Those numbers can be made up as long as the active area is correct, but otherwise it needs the datasheet.

6by9 commented 2 years ago

It streams fine for me without MC using v4l2-ctl. Pi4. No kernel errors logged. There was a rework to the overlays as part of using GPIOs or not, and the fix for the 02W fixups. The firmware and kernel versions look all up to date though, so there shouldn't be a difference there.

amcelroy commented 2 years ago

It streams fine for me without MC using v4l2-ctl. Pi4. No kernel errors logged. There was a rework to the overlays as part of using GPIOs or not, and the fix for the 02W fixups. The firmware and kernel versions look all up to date though, so there shouldn't be a difference there.

OMG you are right! I was able to use, "v4l2-ctl --set-fmt-video=width=640,height=480,pixelformat=Y10 --stream-mmap --stream-to=output.raw --stream-count=1" to capture a frame after setting the FPS to 90. Need to talk to the optical engineer if 90FPS will work vs. the 133 on the Pi 4.

I have the ov7251 manual and could maybe add a new reg_value for a higher FPS. Is there any reading you would recommend to help? I think the process would be to fork the ov7251.c file, add the correct register values for the higher FPS, compile the new ov7251.c as a kernel module, then do a pull request?

I'll close out the bug report since there is a working solution in v4l2. Thank you for looking into this so promptly and in depth.

6by9 commented 2 years ago

Using VBLANK and HBLANK controls is the correct way to control the frame rate. They set VTS and HTS registers in the sensor respectively.

If you want to make the relevant changes then it would be very welcome. If you look at https://github.com/raspberrypi/linux/commits/rpi-5.10.y/drivers/media/i2c/imx290.c there are similar commits in the history there. Otherwise it's probably quicker for me to do it than try and explain.

amcelroy commented 2 years ago

I'm trying to think of a way to say, "I would like to do it but my lack of Linux kernel experience is so lacking I feel it would take days / weeks to come up to speed," without sounding lame but can't. I use Linux daily and do bare metal C daily but have never done a kernel patch or rolled one into the master branch.

6by9 commented 2 years ago

:-) I'll have a look then.

@naushir Could you reopen this as we may as well add official support for it.

6by9 commented 2 years ago

Hmm, ov7251 implements the set frame interval ioctl, which is not appropriate for raw sensors - https://www.kernel.org/doc/html/latest/driver-api/media/camera-sensor.html#frame-interval-configuration Mainline may go either way on retaining support for that, or implementing VBLANK/HBLANK appropriately. It should be possible to have the frame interval code set VBLANK appropriately, but is just more stuff to handle.

You made a good call on not trying to implement it!

amcelroy commented 2 years ago

You made a good call on not trying to implement it!

Ha, yeah, I got the feeling it would be over my head. If you have any good books or reading on the topic of kernel modules and how to manage them it would be great opportunity for me to fill in a large knowledge gap.

6by9 commented 2 years ago

Kernel driver changes done for OV7251 - https://github.com/raspberrypi/linux/pull/4897 I copied the OV9281 cam_helper and tuning json file, and ov7251 has just run for me via libcamera.

Exposure time does appear to be calibrated correctly. I'm assuming gain follows the same formula as OV9281, and that appears to work fine.

amcelroy commented 2 years ago

That is awesome! Thank you! I can't wait to review the code and see how things were addressed and learn more about the correct way to tackle a kernel level change like this. What frame rates can are we able to run the ov7251 at?

6by9 commented 2 years ago

I've allowed VBLANK to be configured up to the 90.43fps that the old driver supported. It may be possible to go faster than that, but I haven't validated the minimum vertical blanking over and above the height of the image. The Omnivision product brief says VGA@120fps, QVGA@180fps, or QQVGA@360fps. I'm not planning on adding the extra modes, but someone else may do so.

6by9 commented 2 years ago

An empirical test says that VBLANK can go down to 41 with the sensor still behaving, giving a frame rate of 99.31fps. Reducing to 40 drops the frame rate to 55.48fps. I'll update the PR accordingly.

There are other parameters that can be changed in the configuration that can increase the frame rate. The HTS registers (0x380c/d) are the obvious ones that will amend the horizontal timing. The current config sets them to 0x3a0 / 928, which seems quite high considering the active frame is only 640 pixels wide. Reducing it generally seems to give a corrupted frame, so there may be other dependencies there. 0x340 / 832 seems to work to give a max rate of 110.75fps, but we're starting to tread on dodgy ground here, and need to amend the handling for frame_intervals again.

That testing has just shown up that setting the exposure range based on VTS is incorrect for VBLANK values below 45 - the max value doesn't get adjusted.

@kbingham Seeing as you've reacted to the above post, I don't suppose you have a datasheet for this sensor? It'd be nice to have the crop areas correct based on a datasheet, and know what registers 0x3016, 0x3017, 0x3018, 0x301a, 0x301b, and 0x301c do.

6by9 commented 2 years ago

An empirical test says that VBLANK can go down to 41 with the sensor still behaving, giving a frame rate of 99.31fps. Reducing to 40 drops the frame rate to 55.48fps. I'll update the PR accordingly.

Too slow - Phil's merged the changes. 90fps will do for now.

kbingham commented 2 years ago

@kbingham Seeing as you've reacted to the above post, I don't suppose you have a datasheet for this sensor? It'd be nice to have the crop areas correct based on a datasheet, and know what registers 0x3016, 0x3017, 0x3018, 0x301a, 0x301b, and 0x301c do.

0x3016-0x301c is SC_CLKRST0 to SC_CLKRST6

6by9 commented 2 years ago

Awesome. Many thanks Kieran. The normal level of detail from Omnivision I see :-/

Looking at the defaults, HTS is set to 0x0304 / 772. Another test would be to run the sensor on defaults and see what we get. Not a priority for me at present though.

naushir commented 2 years ago

I'll close this down now, as https://github.com/raspberrypi/linux/pull/4897 has been merged.

6by9 commented 2 years ago

We do need a camera_helper and basic tuning for OV7251 still - I've passed the sensor over to @davidplowman to deal with that side (just copying the ov9281 files works).

naushir commented 2 years ago

Ah yes, sorry forgot about that. Will re-open until that is merged.

6by9 commented 2 years ago

Minor note. The OV7251 gain register varies based on revision of the sensor. Using the OV9281 algorithm (gain = val/16) is only valid for revisions 1C to 1F. The driver assumes that in setting 0x3509 [4] to 1, but doesn't fail to probe on earlier revisions (it does read the rev code).

Datasheet is on our internal server, or at https://datasheetspdf.com/pdf-file/1252891/OmniVision/OV7750/1 (OV7750 is the colour version of OV7251). See reg 0x350B for gain definition (page 82).

tewarid commented 2 years ago

OMG you are right! I was able to use, "v4l2-ctl --set-fmt-video=width=640,height=480,pixelformat=Y10 --stream-mmap --stream-to=output.raw --stream-count=1" to capture a frame after setting the FPS to 90.

In my case, I had to add a space in the format name like so v4l2-ctl --set-fmt-video=width=640,height=480,pixelformat='Y10 ' --stream-mmap --stream-to=output.raw --stream-count=1. I am wondering about how to view the raw file though.

6by9 commented 2 years ago

In my case, I had to add a space in the format name like so v4l2-ctl --set-fmt-video=width=640,height=480,pixelformat='Y10 ' --stream-mmap --stream-to=output.raw --stream-count=1. I am wondering about how to view the raw file though.

Yes V4L2 have inserted spaces in some of the 4CCs, just to be awkward.

Y10 is 10bit samples packed into the low bits of 16bit words. I tend to use Vooya under Linux to view these sorts of images (or most RGB or YUV images for that matter).

tewarid commented 2 years ago

Y10 is 10bit samples packed into the low bits of 16bit words. I tend to use Vooya under Linux to view these sorts of images (or most RGB or YUV images for that matter).

I went with using yuview because it is available on Raspbian with sudo apt install yuview. To view raw image I set Width to 640, Height to 480, and a custom YUV format with Chroma Subsampling set to 4:0:0, Bit depth set to 10, and Endianness set to Little Endian.

tewarid commented 2 years ago

Using the the OV9281 cam_helper and tuning json file, ov7251 is working for me with kernel version 5.15.34-v71. I am however getting a highly overexposed image with the following command

libcamera-still --verbose --thumb none --immediate -o test.jpg

The following command that starts with lores capture step produces a "normal" image

libcamera-still --verbose --thumb none  -o test.jpg

Any thoughts on why image without lowres capture step is overexposed?

naushir commented 2 years ago

Using the the OV9281 cam_helper and tuning json file, ov7251 is working for me with kernel version 5.15.34-v71. I am however getting a highly overexposed image with the following command

libcamera-still --verbose --thumb none --immediate -o test.jpg

Using the --immediate flag stops the AE/AGC algorithm from running and returns an image as quickly as possible. You should only use this flag if you specify manual exposure/gain values.

tewarid commented 2 years ago

Using the --immediate flag stops the AE/AGC algorithm from running and returns an image as quickly as possible. You should only use this flag if you specify manual exposure/gain values.

~If I read you correctly, applying AE/AGC algorithm is causing over exposure/gain with ov7251. Is there anything I can do to fix that?~

Is there a way to skip ~lowres~ viewfinder step without using --immediate but also use AE/AGC?

naushir commented 2 years ago

Using the --immediate flag stops the AE/AGC algorithm from running and returns an image as quickly as possible. You should only use this flag if you specify manual exposure/gain values.

If I read you correctly, applying AE/AGC algorithm is causing over exposure/gain with ov7251. Is there anything I can do to fix that?

No, essentially the opposite. --immediate stops the AE from converging to the correct value. So you should not use that flag.

naushir commented 2 years ago

Is there a way to skip lowres step without using --immediate but also use AE/AGC?

I'm not sure what you mean by skip lowres here? --immediate has no bearing on the resolution of the output.

tewarid commented 2 years ago

I'm not sure what you mean by skip lowres here? --immediate has no bearing on the resolution of the output.

I'd like to capture a still image without having to go through the viewfinder/preview start/stop. Apparently --immediate does that but then AE/AGC does not chip in. Also tried -n or --nopreview but viewfinder step is still executed. I'll check if the latter may be a known issue.

naushir commented 2 years ago

Would you be able to specify a manual exposure/gain value? Doing this with the --immediate flag should get you what you need.

tewarid commented 2 years ago

Would you be able to specify a manual exposure/gain value? Doing this with the --immediate flag should get you what you need.

Sure - will try that. Thanks!

naushir commented 1 year ago

Closing this due to inactivity.

6by9 commented 1 year ago

I'm about to deal with upstreaming our patches for OV7251 (and OV9281) and add external sync support.

Is it worth throwing a duplicate of the OV9281 cam_helper and tuning files at the list to provide some support? I'll check the datasheet to ensure that gain and exposure delays and gain calcs are all the same as OV9281.

naushir commented 1 year ago

Sure, I see no harm in doing that to start with.

shizhaohui commented 1 year ago

Kernel driver changes done for OV7251 - raspberrypi/linux#4897 I copied the OV9281 cam_helper and tuning json file, and ov7251 has just run for me via libcamera.

Exposure time does appear to be calibrated correctly. I'm assuming gain follows the same formula as OV9281, and that appears to work fine.

Hi, @6by9 I am a beginner in Linux. Thanks for help.

My raspberry pi is CM4, which has two CSI Interfaces. I add "dtoverlay=ov9281,cam1" and "dtoverlay=ov9281,cam0" in config.txt, then use libcamera-hello --camera 1 or libcamera-hello --camera 0, both the camera works well.

I want to use two arducam ov7251 cameras. I have used rpi-update command to update my CM4, now the version is Linux raspberrypi 5.15.72-v7l+ #1591 SMP Wed Oct 5 12:05:33 BST 2022 armv7l GNU/Linux.

Then I add "dtoverlay=ov7251,cam1" and "dtoverlay=ov7251,cam0" in config.txt. video0 and video1 are founded in /dev. I use libcamera-hello --camera 1 or libcamera-hello --camera 0, but neither the camera works.

cm4@raspberrypi:~ $ libcamera-hello --camera 0 Made X/EGL preview window [0:23:26.583997802] [1932] INFO Camera camera_manager.cpp:293 libcamera v0.0.0+3544-22656360 [0:23:26.610316224] [1933] WARN CameraSensorProperties camera_sensor_properties.cpp:163 No static properties available for 'ov7251' [0:23:26.610377477] [1933] WARN CameraSensorProperties camera_sensor_properties.cpp:165 Please consider updating the camera sensor properties database [0:23:26.610414991] [1933] ERROR CameraSensor camera_sensor.cpp:591 'ov7251 0-0060': Camera sensor does not support test pattern modes. [0:23:26.620944349] [1933] ERROR IPAProxy ipa_proxy.cpp:149 Configuration file 'ov7251.json' not found for IPA module 'raspberrypi' [0:23:26.621015989] [1933] ERROR IPARPI raspberrypi.cpp:192 Could not create camera helper for ov7251 [0:23:26.621051745] [1933] ERROR RPI raspberrypi.cpp:1236 Failed to load a suitable IPA library [0:23:26.621197564] [1933] ERROR RPI raspberrypi.cpp:1167 Failed to register camera ov7251 0-0060: -22 ERROR: no cameras available

cm4@raspberrypi:~ $ libcamera-hello --camera 0 Made X/EGL preview window [0:23:26.583997802] [1932] INFO Camera camera_manager.cpp:293 libcamera v0.0.0+3544-22656360 [0:23:26.610316224] [1933] WARN CameraSensorProperties camera_sensor_properties.cpp:163 No static properties available for 'ov7251' [0:23:26.610377477] [1933] WARN CameraSensorProperties camera_sensor_properties.cpp:165 Please consider updating the camera sensor properties database [0:23:26.610414991] [1933] ERROR CameraSensor camera_sensor.cpp:591 'ov7251 0-0060': Camera sensor does not support test pattern modes. [0:23:26.620944349] [1933] ERROR IPAProxy ipa_proxy.cpp:149 Configuration file 'ov7251.json' not found for IPA module 'raspberrypi' [0:23:26.621015989] [1933] ERROR IPARPI raspberrypi.cpp:192 Could not create camera helper for ov7251 [0:23:26.621051745] [1933] ERROR RPI raspberrypi.cpp:1236 Failed to load a suitable IPA library [0:23:26.621197564] [1933] ERROR RPI raspberrypi.cpp:1167 Failed to register camera ov7251 0-0060: -22 ERROR: no cameras available

Is version 5.15.72 already involve the new ov7251 driver you have modified?

6by9 commented 1 year ago

The driver is already in 5.15.72, but there is no tuning file or cam_helper in libcamera, exactly as the app has told you

[0:23:26.620944349] [1933] ERROR IPAProxy ipa_proxy.cpp:149 Configuration file 'ov7251.json' not found for IPA module 'raspberrypi'
[0:23:26.621015989] [1933] ERROR IPARPI raspberrypi.cpp:192 Could not create camera helper for ov7251

I've just pushed the necessary commit to https://github.com/6by9/libcamera/tree/master, but haven't got time right this minute to submit it to the main libcamera list for review.

anonymouslojz commented 1 year ago

just point ov9281 turnign files it will works. No need too many changes. The ov7251 is a 0.3mp global shutter camera with external mode. Suggest our https://github.com/INNO-MAKER/cam-mipiov7251-trigger ov9281 with already set up dtb and free samples.

6by9 commented 1 year ago

I'm afraid I won't recommend the Innomaker OV7251 driver as it misses out several parts that are critical to libcamera being able to use it (V4L2_CID_HBLANK and VIDIOC_G_SELECTION to name 2). It is also selecting Y8 vs Y10 via a module parameter rather than userspace.

Mainline already has a driver for OV7251, and the Pi kernel already addressed any missing features of that. The only bit that isn't supported is external trigger.

anonymouslojz commented 1 year ago

well, the ov7251 module support raspberry pi os driver too, for those who want to use external trigger they can choos vender's driver

It cost less than other processor platform by using raspberry pi and external trigger mipi camera if actual application scenario requires.

So the vender's driver is not conflict with raspberry pi build in driver.

It's hard and impossible realize external trigger and other functions together at the same time

6by9 commented 1 year ago

Worth noting that the external trigger code in that vendor driver relies on a secondary microcontroller on the Innomaker OV7251 board, which obviously won't be present on any other board.

https://github.com/raspberrypi/linux/pull/5260 adds external trigger to the main Pi kernel via a module parameter (independent of sensor mode and microcontroller).

6by9 commented 1 year ago

The one bit I can't get to work is getting the FSIN/VSYNC pin to work as VSYNC. Any assistance welcome. It's not helped by the fact that the Innomaker modules add an opto-isolator on the assumption it will only ever be used as FSIN :-(

amcelroy commented 1 year ago

Kernel driver changes done for OV7251 - raspberrypi/linux#4897 I copied the OV9281 cam_helper and tuning json file, and ov7251 has just run for me via libcamera. Exposure time does appear to be calibrated correctly. I'm assuming gain follows the same formula as OV9281, and that appears to work fine.

Hi, @6by9 I am a beginner in Linux. Thanks for help.

My raspberry pi is CM4, which has two CSI Interfaces. I add "dtoverlay=ov9281,cam1" and "dtoverlay=ov9281,cam0" in config.txt, then use libcamera-hello --camera 1 or libcamera-hello --camera 0, both the camera works well.

I want to use two arducam ov7251 cameras. I have used rpi-update command to update my CM4, now the version is Linux raspberrypi 5.15.72-v7l+ #1591 SMP Wed Oct 5 12:05:33 BST 2022 armv7l GNU/Linux.

Then I add "dtoverlay=ov7251,cam1" and "dtoverlay=ov7251,cam0" in config.txt. video0 and video1 are founded in /dev. I use libcamera-hello --camera 1 or libcamera-hello --camera 0, but neither the camera works.

cm4@raspberrypi:~ $ libcamera-hello --camera 0 Made X/EGL preview window [0:23:26.583997802] [1932] INFO Camera camera_manager.cpp:293 libcamera v0.0.0+3544-22656360 [0:23:26.610316224] [1933] WARN CameraSensorProperties camera_sensor_properties.cpp:163 No static properties available for 'ov7251' [0:23:26.610377477] [1933] WARN CameraSensorProperties camera_sensor_properties.cpp:165 Please consider updating the camera sensor properties database [0:23:26.610414991] [1933] ERROR CameraSensor camera_sensor.cpp:591 'ov7251 0-0060': Camera sensor does not support test pattern modes. [0:23:26.620944349] [1933] ERROR IPAProxy ipa_proxy.cpp:149 Configuration file 'ov7251.json' not found for IPA module 'raspberrypi' [0:23:26.621015989] [1933] ERROR IPARPI raspberrypi.cpp:192 Could not create camera helper for ov7251 [0:23:26.621051745] [1933] ERROR RPI raspberrypi.cpp:1236 Failed to load a suitable IPA library [0:23:26.621197564] [1933] ERROR RPI raspberrypi.cpp:1167 Failed to register camera ov7251 0-0060: -22 ERROR: no cameras available

cm4@raspberrypi:~ $ libcamera-hello --camera 0 Made X/EGL preview window [0:23:26.583997802] [1932] INFO Camera camera_manager.cpp:293 libcamera v0.0.0+3544-22656360 [0:23:26.610316224] [1933] WARN CameraSensorProperties camera_sensor_properties.cpp:163 No static properties available for 'ov7251' [0:23:26.610377477] [1933] WARN CameraSensorProperties camera_sensor_properties.cpp:165 Please consider updating the camera sensor properties database [0:23:26.610414991] [1933] ERROR CameraSensor camera_sensor.cpp:591 'ov7251 0-0060': Camera sensor does not support test pattern modes. [0:23:26.620944349] [1933] ERROR IPAProxy ipa_proxy.cpp:149 Configuration file 'ov7251.json' not found for IPA module 'raspberrypi' [0:23:26.621015989] [1933] ERROR IPARPI raspberrypi.cpp:192 Could not create camera helper for ov7251 [0:23:26.621051745] [1933] ERROR RPI raspberrypi.cpp:1236 Failed to load a suitable IPA library [0:23:26.621197564] [1933] ERROR RPI raspberrypi.cpp:1167 Failed to register camera ov7251 0-0060: -22 ERROR: no cameras available

Is version 5.15.72 already involve the new ov7251 driver you have modified?

Were you able to resolve this? We just got a new Pi 4 and ov7251 to make a 2nd unit and are running into this issue, except with just a single camera.