Using CSI camera on the DragonBoard 820c

Hello,

I have purchased a DragonBoard820c and the MIPI Adapter Mezzanine (V2.1) and I was hoping to be able to use the MIPI CSI channels with OV5645 camera modules. I’ve been working through the process of building debian for the 820c from source with changes to the kernel/aarch/arm64/boot/dts/qcom/apq8016-sbc.dtsi file, changing the status of ov5645 mipi drivers from “diabled” to “okay”.

The issue I’ve had is in cross-compiling debian. Following the instructions here: Building Linux Kernel for Dragonboard-820c - 96Boards

I’m downloading the toolchain from:
https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz

The issue I’m having is that after creating the boot image and flashing it to the 820c, the board won’t boot. I am able to flash the provided boot image (DragonBoard 820c Debian - 96Boards) and boot everything just fine, but when I try to flash the compiled boot image I get nothing. I am using the provided alip rootfs from the above link with it, and I’m not sure on whether that needs extra configuration.

At this point any help on building from source for the dragonboard820c would be greatly appreciated.
Thank you

It doesn’t sounds like this is related to the CSI Camera interface.

The point is that there is no release for 820c, only snapshot. The latest snapshot you flashed is based on kernel 5.4 whereas instructions is for 4.14. So, it’s very likely you flash your compiled 4.14 kernel with a rootfs containing 5.4 modules, causing incomplete boot.

I would suggest to try flashing an older rootfs with 4.14 modules: http://snapshots.linaro.org/96boards/dragonboard820c/linaro/debian/428

You can also change your kernel version to 5.4 but AFAIR, 4.14 is more stable for 820c and has predefined ov5645 nodes.

@Loic: 5.4 is dramatically more stable for db820c. 4.14 is a total disaster and only successfully boots up around half the time.

However, I don’t know if the linaro repo has pulled in all the necessary parts for frequency scaling and related.

I’ve got a few branches in this repository with all the needed parts in; AOSP-Automotive / dragonboard-kernel-src · GitLab

For debian, best would be to grab it from the last commit before the first with “android” in the subject, since everything from that point onward will be either for Android, or for custom hardware.

Thanks @doitright, are you aware about any effort to push these missing commits to the upstream?

Not specifically.
I tried to get my stuff added to upstream, but after a couple of rounds stopped getting any kind of responses or feedback from upstream. Similar fate fell on the clock commits authored by Ilia Lin.

@Loic @doitright Thank you for the direction. I tried flashing the older (4.14) rootfs to no avail.
Similarly, I tried using commit e2e8f9f3, but that didn’t work either, the 820c still doesn’t boot after flashing.

I can flash the provided images just fine, but I don’t think I’m building from source correctly.
I’m researching what I can but I haven’t been able to boot from any image I build myself. Any advice in that process would be very helpful.

@simson You are right the specific issue I’m having is further down the line.

My reasoning for building from source is because I believe it will allow me to use the cameras I have with the board. Following that solution, I run into trouble with building from source

However, if there is a different solution out there that would let me use the CSI interface with OV5645 sensors, I wouldn’t need to build from source.

I assume that you don’t have a UART interface, since I’m sure you would be posting boot logs if you had one. My suggestion is that if you’re messing around with the kernel, you need to have UART console. There is simply no alternative.

This will do the job for you, and is apparently now only $0.08 each?
https://www.arrow.com/en/products/114990332/seeed-technology-limited

Edit:
I just ordered 10 of them, because its too good a deal to pass up, but I suspect ts an error and I’m not too greedy. With volume discount comes to $0.91 canadian with $8.69 shipping and $0.72 tax delivery to my USA address because shipping to canada is $65 and therefore not worth it. Order confirmation has been received.

… Now if only they’d come up with a deal like that on the dragonboard 820c.

Flash snapshot 428 (boot and rootfs):
http://snapshots.linaro.org/96boards/dragonboard820c/linaro/debian/428/

Then from 820c console:

# install device tree compiler
sudo apt-get install device-tree-compiler

# install tool to extract blob from boot partition
git clone https://github.com/96boards/dt-update.git
cd dt-update && make
sudo make install

# Extract devicetree blob from boot partition into 820c.dtb
dbootimg /dev/disk/by-partlabel/boot -x dtb > 820c.dtb

# decompile dtb into 820.dts
dtc 820c.dtb -O dts -o 820.dts

# edit the devicetree source
vim 820c.dts
# e.g. enable (status="okay") sensor(s) (e.g. camera_board@39)
# and coresponding cci endpoint(s) (e.g. port@1/endpoint)

# compile devicetree source into devicetree blob
dtc 820c.dts -O dtb -o 820c.dtb

# Update boot partition with the update devicetree blob
dbootimg /dev/disk/by-partlabel/boot -u dtb 820c.dtb
sync

# reboot
reboot

Then check your camera is enabled after reboot, dmesg | grep ov5645 should not show any error.

Loic, thanks for the walkthrough for this process. I’ve been able to edit and recompile the devicetree source, but I’m still having issues with accessing the camera. When I boot with a single camera plugged in (for now, later I’ll want two plugged in), I get the following error message from dmesg | grep -C 3 ov5645:

[    8.869629] msm-snd-apq8096 sound: error getting cpu dai name
[    8.869751] msm-snd-apq8096 sound: Error parsing OF data
[    8.873940] ov5645 3-0039: ov5645_write_reg_to: write reg error -5 on addr 0x3c: reg=0x3100, val=0x72
[    8.881089] ov5645 3-0039: could not change i2c address
[    8.890180] ov5645 3-0039: could not power up OV5645
[    8.895568] ov5645: probe of 3-0039 failed with error -5
[    8.896852] msm-snd-apq8096 sound: error getting cpu dai name
[    8.906717] msm-snd-apq8096 sound: Error parsing OF data
[    8.915674] msm-snd-apq8096 sound: error getting cpu dai name
--
[    8.974886] i2c-qcom-cci a0c000.cci: cci i2c xfer error -5
[    8.980684] msm-snd-apq8096 sound: Error parsing OF data
[    8.986753] ath10k_pci 0000:01:00.0: enabling device (0000 -> 0002)
[    8.991280] ov5645 3-003a: ov5645_write_reg_to: write reg error -5 on addr 0x3c: reg=0x3100, val=0x74
[    8.997702] ath10k_pci 0000:01:00.0: pci irq msi oper_irq_mode 2 irq_mode 0 reset_mode 0
[    9.002747] ov5645 3-003a: could not change i2c address
[    9.002773] ov5645 3-003a: could not power up OV5645
[    9.025478] ov5645: probe of 3-003a failed with error -5
[    9.063030] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[    9.063088] [drm] Driver supports precise vblank timestamp query.
[    9.069795] [drm] Initialized msm 1.3.0 20130625 for 900000.mdss on minor 0

What does the -5 error mean and do you have any suggestions on how I could remedy it?
Thanks

Which mezzanine do you use exactly, the default devicetree node have been tested with D3 and airstarvision mipi mezzanines, but mayber yours is not one of them? link? Also copy all the debug output so that we can see earlier cci error messages (using e.g. pastebin). From the output it seems nothing ack the I2C transfer, which means either the camera is not on defined cci bus or not powered on.

The Mezzanine I’m using is the Aistarvision one.

The version that I have is v2.1, and its schematic is here:

For the header row J13 I have jumpers connecting pin 19 to 20, and connecting pin 21 to 22 (the I2C for CAM1)

Here is the full dmesg output:

The mezzanine 96boards link: MIPI Adapter Mezzanine - 96Boards

[    8.962755] i2c-qcom-cci a0c000.cci: Master 0 error 0x08000000
[    8.969208] i2c-qcom-cci a0c000.cci: master 0 queue 0 error -5

This is an I2C nack error, no device acked the I2C/CCI address.

For the header row J13 I have jumpers connecting pin 19 to 20, and connecting pin 21 to 22 (the I2C for CAM1)

At first glance, it seems correct. CAM1 corresponds to camera_reat in the devicetree, which is by default configured for ov7251… you may want to modify the compatible string to “ovti,ov5645” and use something like the following for the enabe/reset gpios:

enable-gpios = <&msmgpio 26 GPIO_ACTIVE_HIGH>;
reset-gpios = <&msmgpio 25 GPIO_ACTIVE_LOW>;

Thanks. Unfortunately when I try to use dtc to compile the 820c.dts file I get an “Unable to parse input tree” error if I change the enable-gpios and reset-gpios settings. The decompiled 820c.dts just had hex values in there.

Could we just try to use one of camera_front or camera_board that are seperately part of the dts file?

Well if you use the decompiled dts, then replace &msmgpio by its phandle value, it should be the same as for other sensor -gpios, gpio offset by its hex value, GPIO_ACTIVE_HIGH is 0 and GPIO_ACTIVE_LOW is 1.

An other way woul be to build the dtb from kernel:

git clone https://git.linaro.org/landing-teams/working/qualcomm/kernel.git
git checkout release/qcomlt-4.14
/* aplly changes in arch/arm64/boot/dts/apq8096-db820c.dtsi */
ARCH=arm64 make defconfig
ARCH=arm64 make dtbs

Copy the generated apq8096-db820c.dtb to your device and inject it to the boot partition.

I’m building the dtb from kernel now, but I’m still not having any success.

Looking at the Github for the AISTARVISION MIPI Adapter Board, I see this folder:

It looks like this is a configuration for a DragonBoard410c for this board. Is there any way I could use this to determine what my .dtsi file for db820c needs to look like? I’m still getting the same dmesg errors that seem to stem from the i2c communication, so I’m wondering if the issue is there.

Does this seem like something I’ll be able to solve by building the dtb correctly, or will there be other kernel files that need to be changed to work with the db820c?

Thanks

It seems to be a devicetree issue only, check the schematics and that the sensor you enable use the correct pins/gpios, then I would suggest to try probing the camera lines for power/reset with a multimeter and I2C with a scope/logic-analyzer (compatible with 1.8V I/O).

I’ve been using an Oscilloscope to look at the pwdn/reset lines and the I2C lines. The power and reset lines behave as expected according to the ov5645 datasheet (pwdn, then rst go high and stay high until the i2c communication happens and fails). I can clearly see the I2C attempt to communicate with the image sensor on the SCL and SDA lines. The slave address specified is the 7 bit 0x3C, the R/W bit is 0, and the ACK space is left high, which I’m pretty sure means the ov5645 is not acknowledging the byte.

In the ov5645 datasheet I have, it looks like it describes the default value of the SCCB_ID address as 0x78 (which is 0x3C shifted left once). Looking at kernel/drivers/media/i2c/ov5645.c in the version of the kernel we’ve been looking at, the value written to the ov5645 to start is 0x3C:
(Lines 772-776 of kernel/drivers/media/i2c/ov5645.c)

ret = ov5645_write_reg_to(ov5645, 0x3100,
	ov5645->i2c_client->addr << 1, 0x3c);
if (ret < 0) {
	dev_err(ov5645->dev,
		"could not change i2c address\n");

This is the error message we have been seeing in dmesg.

My guess is that either the driver is sending the wrong slave address, or there is something going wrong with my image sensor. Is that a good reading of my results? What other things should I look at to confirm that the image sensor should be acknowledging the i2c transaction and that there isn’t another glaring issue?

It is possible that I have a bad image sensor. While I was troubleshooting earlier, I plugged the camera module in backwards, as its connector also fits in upside down. Could this have killed the image sensor?