Skip to main content

NXP IMX95LPD5EVK-19CM board TEVS Camera Usage Guide

πŸš€ Introduction​

This article guides you how to get started using TechNexion camera modules on NXP IMX95LPD5EVK-19CM board.


πŸ“Έ Supported Camera Modules​

Camera SeriesProducts
TEVS
TEVS-AR0144
TEVS-AR0145
TEVS-AR0234
TEVS-AR0521
TEVS-AR0522
TEVS-AR0821
TEVS-AR0822
TEVS-AR1335

πŸ”§ Hardware Setup Instructions​

Connect the Adapter Board and Camera Cable​

To set up TechNexion camera, connect the adapter board and camera cable to the MIPI CSI port on the EVK board.


πŸ’» Prepare Yocto demo image for testing TechNexion camera​

To test TechNexion TEVS Series cameras, you need a demo image that includes the required Device Tree Blobs (DTBs) and camera drivers.

πŸ”½ Download and Select the Correct Image for Your EVK​

Prebuilt demo images can be available for download via TechNexion's server.

πŸ”— Supported Release List (Instructions for IMX95LPD5EVK-19CM)


πŸ’Ύ Flashing the Image​

You can flash the image to an SD Card using the following methods:

Boot Mode

Make sure your EVK board is set to boot from SD card.
Refer to the official NXP guide πŸ”— i.MX 95 LPD5 EVK Quick Start Guide

1. For Windows Users​

Use balenaEtcher to write the image to your SD card:

πŸ”—

2. For Linux Users​

Use bmap-tools for a fast and reliable flashing process to the SD card:

sudo apt-get update
sudo apt-get install bmap-tools

πŸ› οΈ Build Yocto​

TechNexion supports building a Yocto-based Linux image tailored for camera modules using the following kernel and branch.

If you are using prebuilt demo image, you can skip this section. Please refer to πŸ“Έ Camera Testing Instructions section for camera testing steps.

πŸ“¦ Supported Linux Kernel​

Linux Kernel VersionYocto Branch
6.6.52tn-imx_6.6.52_2.2.0-stable

πŸ“ Source and Build Instructions​

πŸ”— Fetch Yocto source
πŸ“– Build Yocto (Instructions for IMX95LPD5EVK-19CM)


🐧 Develop Linux kernel​

Fetch and compile Linux kernel.

Build Enviroment
  • Host OS: Ubuntu 20.04
  • Toolchain: aarch64-linux-gnu-gcc 9.4.0

Install cross-compile & dependency tools.​

$ sudo apt update
$ sudo apt install -y gcc-aarch64-linux-gnu libncurses-dev libssl-dev bison flex git make

Clone the Kernel Source​

$ git clone https://github.com/TechNexion/linux-tn-imx.git -b tn-imx_6.6.52_2.2.0-stable

Set cross-compile environment & the kernel config.​

$ export ARCH=arm64
$ export CROSS_COMPILE=/usr/bin/aarch64-linux-gnu-
$ cd linux-tn-imx
~/linux-tn-imx$ make imx_v8_defconfig

Compile the kernel & module driver.​

# compile kernel
~/linux-tn-imx$ make -j$(nproc)
# create kernel module folder
~/linux-tn-imx$ mkdir -p ./modules
# compile module driver
~/linux-tn-imx$ rm -rf ./modules/*
~/linux-tn-imx$ make INSTALL_MOD_PATH=./modules modules_install

Change kernel Image, DTB & modules.​

~/linux-tn-imx/$ cp arch/arm64/boot/Image  <mount_folder>/boot/Image
~/linux-tn-imx/$ cp arch/arm64/boot/dts/freescale/imx95-19x19-evk-tevs-tev-nxp.dts <mount_folder>/boot/
~/linux-tn-imx/$ sudo cp -r ./modules/lib/modules/* <mount_folder>/root/lib/modules/

πŸ“Έ Camera Testing Instructions​

Specify Camera DTBO in U-Boot​

  1. Connect the debug console cable to the baseboard (via USB-C).

  2. Power on the board and interrupt the boot process. Keep pressing Enter when the following message appears: Hit any key to stop autoboot:

  3. Specify the appropriate device tree for your camera using the fdtfile environment variable in U-Boot:

u-boot=> setenv fdtfile imx95-19x19-evk-tevs-tev-nxp.dtb
  1. Save and continue the boot process:
u-boot=> saveenv
u-boot=> boot

Setup the media controller before camera streaming​

To verify that the camera has been properly connected and linked, use the media-ctl command:

$ media-ctl -p

Get the media controller information as follows.

Media controller API version 6.6.23

Media device information

\------------------------

driver mxc-isi

model FSL Capture Media Device

serial

bus info platform:4ad50000.isi

hw revision 0x0

driver version 6.6.23

Device topology

\- entity 1: crossbar (13 pads, 9 links, 8 routes)

type V4L2 subdev subtype Unknown flags 0

device node name /dev/v4l-subdev0

routes:

2/0 -> 5/0 [ACTIVE]

2/0 -> 6/0 [ACTIVE]

2/0 -> 7/0 [ACTIVE]

2/0 -> 8/0 [ACTIVE]

2/0 -> 9/0 [ACTIVE]

2/0 -> 10/0 [ACTIVE]

2/0 -> 11/0 [ACTIVE]

2/0 -> 12/0 [ACTIVE]

pad0: Sink

pad1: Sink

pad2: Sink

[stream:0 fmt:UYVY8_1X16/1920x1080 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]

<\- "4ac10000.syscon:formatter@20":1 [ENABLED,IMMUTABLE]

pad3: Sink

pad4: Sink

pad5: Source

[stream:0 fmt:UYVY8_1X16/1920x1080 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]

-> "mxc_isi.0":0 [ENABLED,IMMUTABLE]

…

\- entity 15: mxc_isi.0 (2 pads, 2 links, 0 routes)

type V4L2 subdev subtype Unknown flags 0

device node name /dev/v4l-subdev1

pad0: Sink

[stream:0 fmt:UYVY8_1X16/1920x1080 field:none colorspace:jpeg xfer:srgb ycbcr:601 quantization:full-range

compose.bounds:(0,0)/1920x1080

compose:(0,0)/1920x1080]

<\- "crossbar":5 [ENABLED,IMMUTABLE]

pad1: Source

[stream:0 fmt:YUV8_1X24/1920x1080 field:none colorspace:jpeg xfer:srgb ycbcr:601 quantization:full-range

crop.bounds:(0,0)/1920x1080

crop:(0,0)/1920x1080]

-> "mxc_isi.0.capture":0 [ENABLED,IMMUTABLE]

\- entity 18: mxc_isi.0.capture (1 pad, 1 link)

type Node subtype V4L flags 0

device node name /dev/video0

pad0: Sink

<\- "mxc_isi.0":1 [ENABLED,IMMUTABLE]

…


\- entity 103: 4ac10000.syscon:formatter@20 (2 pads, 2 links, 1 route)

type V4L2 subdev subtype Unknown flags 0

device node name /dev/v4l-subdev9

routes:

0/0 -> 1/0 [ACTIVE]

pad0: Sink

[stream:0 fmt:UYVY8_1X16/1920x1080 field:none colorspace:smpte170m xfer:709 ycbcr:601 quantization:lim-range]

<\- "csidev-4ad30000.csi":1 [ENABLED,IMMUTABLE]

pad1: Source

[stream:0 fmt:UYVY8_1X16/1920x1080 field:none colorspace:smpte170m xfer:709 ycbcr:601 quantization:lim-range]

-> "crossbar":2 [ENABLED,IMMUTABLE]

\- entity 108: csidev-4ad30000.csi (2 pads, 2 links, 1 route)

type V4L2 subdev subtype Unknown flags 0

device node name /dev/v4l-subdev10

routes:

0/0 -> 1/0 [ACTIVE]

pad0: Sink

[stream:0 fmt:UYVY8_1X16/1920x1080 field:none colorspace:smpte170m xfer:709 ycbcr:601 quantization:lim-range]

<\- "tevs 2-0048":0 []

pad1: Source

[stream:0 fmt:UYVY8_1X16/1920x1080 field:none colorspace:smpte170m xfer:709 ycbcr:601 quantization:lim-range]

-> "4ac10000.syscon:formatter@20":0 [ENABLED,IMMUTABLE]

\- entity 113: tevs 2-0048 (1 pad, 1 link, 0 routes)

type V4L2 subdev subtype Sensor flags 0

device node name /dev/v4l-subdev11

pad0: Source

[stream:0 fmt:UYVY8_1X16/640x480@1/60 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:full-range

crop.bounds:(0,0)/640x480

crop:(0,0)/640x480]

-> "csidev-4ad30000.csi":0 []

Transfer to image that will be easier to understand.

$ media-ctl --print-dot > graph.dot
$ dot -Tpng graph.dot > graph.png
# if you don't have tool, you need to install it as follows.
# sudo apt-get install -y graphviz

Modify the route through the β€œcrossbar” and only keep the channel of video0.

$ media-ctl -R "'crossbar' [2/0 -> 5/0 [1], 2/0 -> 6/0 [0], 2/0 -> 7/0 [0], 2/0 -> 8/0 [0], 2/0 -> 9/0 [0], 2/0 -> 10/0 [0], 2/0 -> 11/0 [0], 2/0 -> 12/0 [0]]"

Enable the link between TEVS and CSI device.

$ media-ctl -l "'tevs 2-0048':0 -> 'csidev-4ad30000.csi':0 [1]"

You can list camera formats, resolutions and frame interval via v4l2 control command.

# formats
$ v4l2-ctl -d /dev/v4l-subdev11 --list-subdev-mbus-codes
ioctl: VIDIOC_SUBDEV_ENUM_MBUS_CODE (pad=0)
0x200f: MEDIA_BUS_FMT_UYVY8_1X16

# resolutions
$ v4l2-ctl -d /dev/v4l-subdev11 --list-subdev-framesize code=0x200f
ioctl: VIDIOC_SUBDEV_ENUM_FRAME_SIZE (pad=0)
Size Range: 640x480 - 640x480
Size Range: 1280x720 - 1280x720
Size Range: 1280x800 - 1280x800

# frame interval of resolution
$ v4l2-ctl -d /dev/v4l-subdev11 --list-subdev-frameintervals width=640,height=480,code=0x200f
ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0)
Interval: 0.017s (60.000 fps)

$ v4l2-ctl -d /dev/v4l-subdev11 --list-subdev-frameintervals width=1280,height=720,code=0x200f
ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0)
Interval: 0.017s (60.000 fps)

$ v4l2-ctl -d /dev/v4l-subdev11 --list-subdev-frameintervals width=1280,height=800,code=0x200f
ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0)
Interval: 0.017s (60.000 fps)

Set the media controller resolution to 1280Γ—720.

$ media-ctl -V "'crossbar':2 [fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601]"
$ media-ctl -V "'mxc_isi.0':0 [fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601]"
$ media-ctl -V "'4ac10000.syscon:formatter@20':0 [fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601]"
$ media-ctl -V "'csidev-4ad30000.csi':0 [fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601]"
$ media-ctl -V "'tevs 2-0048':0 [fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601]"

πŸŽ₯ Start Camera Video Stream via GStreamer​

Launch GStreamer Pipeline​

Specify the capture device you just get and start gstreamer to get video stream on screen.

$ gst-launch-1.0 v4l2src device=/dev/video0 ! "video/x-raw, format=YUY2, width=1280, height=720" ! waylandsink sync=false

🚨 Troubleshooting​

Boot up NXP IMX95LPD5EVK-19CM and check initialization of TEVS driver. If it shows below messages, the driver is initialized correctly.

$ dmesg -t | grep tevs
tevs 1-0048: tevs_probe() device node: tevs@48
tevs 1-0048: Version:24.9.0.1
tevs 1-0048: Product:TEVS-AR0234, HeaderVer:3, MIPI_Rate:800
tevs 1-0048: probe success