NanoPi + OV5640 Camera

Needed a board that was capable of delivering at least a 720p videostream and went for the NanoPi Duo2. Which should (theoretically) handle 1080p at 30fps. Spoiler alert. It can’t

Cedrus is a part of the Allwinner SOC which accelerates H264 encoding but is a bit of a trick to set up. Especially on mainline kernels. This tutorial is about how to setup your NanoPi (or other Allwinner H3 boards) to recognize the I2C camera and Cedrus device

The NanoPi Duo2 does not recognize the OV5640 image sensor and Cedrus H264 hardware encoder by default. For this to work we need to enable them by editing the Device Tree. Download the kernel source and extract.

sudo apt update
sudo apt upgrade

sudo apt install build-essential
uname -r //check your current kernel version
sudo apt install linux-source-<your current kernel version>

In my case:
sudo apt install linux-source-5.8.6-current-sunxi

cd /usr/src
sudo tar xf linux-source-5.8.6-sunxi.tar.xz

Now we have an extracted kernel source sitting in /usr/src. The Device Tree files are located in the arch/arm/boot/dts directory. In that directory we need to edit three files. The first one is to enable the OV5640 camera sensor.

sudo nano arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts

In that file insert this inside the “model” braces

    cam_xclk: cam-xclk {
                #clock-cells = <0>;
                compatible = "fixed-clock";
                clock-frequency = <24000000>;
                clock-output-names = "cam-xclk";
        };

        reg_cam_avdd: cam-avdd {
                compatible = "regulator-fixed";
                regulator-name = "cam-avdd";
                regulator-min-microvolt = <2800000>;
                regulator-max-microvolt = <2800000>;
                vin-supply = <&reg_vcc3v3>;
        };

        reg_cam_dovdd: cam-dovdd {
                compatible = "regulator-fixed";
                regulator-name = "cam-dovdd";
                regulator-min-microvolt = <1800000>;
                regulator-max-microvolt = <1800000>;
                vin-supply = <&reg_vcc3v3>;
        };

        reg_cam_dvdd: cam-dvdd {
                compatible = "regulator-fixed";
                regulator-name = "cam-dvdd";
                regulator-min-microvolt = <1500000>;
                regulator-max-microvolt = <1500000>;
                vin-supply = <&reg_vcc3v3>;
        };

And this part at the top level

&csi {
    status = "okay";

    port {
        #address-cells = <1>;
        #size-cells = <0>;

        /* Parallel bus endpoint */
        csi_from_ov5640: endpoint {
            remote-endpoint = <&ov5640_to_csi>;
            bus-width = <8>;
            data-shift = <2>;
            hsync-active = <1>; /* Active high */
            vsync-active = <0>; /* Active low */
            data-active = <1>;  /* Active high */
            pclk-sample = <1>;  /* Rising */
        };
    };
};

&i2c2 {
   status = "okay";

   ov5640: camera@3c {
        compatible = "ovti,ov5640";
        reg = <0x3c>;
        clocks = <&cam_xclk>;
        clock-names = "xclk";

        reset-gpios = <&pio 4 14 GPIO_ACTIVE_LOW>;
        powerdown-gpios = <&pio 4 15 GPIO_ACTIVE_HIGH>;
        /* power_en-gpios = <&pio 3 14 GPIO_ACTIVE_LOW>; */
        AVDD-supply = <&reg_cam_avdd>;
        DOVDD-supply = <&reg_cam_dovdd>;
        DVDD-supply = <&reg_cam_dvdd>;

        port {
            ov5640_to_csi: endpoint {
                remote-endpoint = <&csi_from_ov5640>;
                bus-width = <8>;
                data-shift = <2>;
                hsync-active = <1>; /* Active high */
                vsync-active = <0>; /* Active low */
                data-active = <1>;  /* Active high */
                pclk-sample = <1>;  /* Rising */
            };
        };
    };
};

&i2c2_pins {
   bias-pull-up;
};

Now compile the dts file, copy it and reboot

sudo make dtbs
sudo cp arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dtb /boot/dtb/
sudo reboot
Pages: 1 2 3 4
en_USEnglish