Troubleshooting

If the device is not detected or does not operate correctly, the following checks can help identify the problem.

I2C

If the device is not probing

i2cdetect -y 11

You should see:

3c

If not → hardware / DT problem.

Device Tree Overlay

Check that the overlay is installed in the firmware overlays directory (/boot/firmware/overlays on newer systems, /boot/overlays on older systems):

ls -l /boot/firmware/overlays | grep 'epc670'

Expected output:

-rwxr-xr-x 1 root root   9221 Mar  4 10:34 epc670_tofhat.dtbo

Verify that the overlay is referenced in the configuration file:

cat /boot/firmware/config.txt

You should see:

# Added by epc670-tofhat
dtoverlay=epc670_tofhat.dtbo

Dynamic Kernel Module Support

Driver modules are managed by DKMS. First verify that the modules cam-epc670 and clk-si5351 are installed.

dkms status

You should see something similar to:

cam-epc670/0.1.7, 6.12.47+rpt-rpi-2712, aarch64: installed (Original modules exist)
clk-si5351/0.1.4, 6.12.47+rpt-rpi-2712, aarch64: installed

Also check that the driver sources exist:

ls -l /usr/src | grep 'cam-epc670\|clk-si5351'

Expected output:

drwxr-xr-x 3 root root 4096 Mar  4 10:33 cam-epc670-0.1.7
drwxr-xr-x 3 root root 4096 Mar  4 10:33 clk-si5351-0.1.4

Drivers

The epc670 ToF HAT+ requires three kernel modules:

  • cam-epc670

  • clk-si5351

  • mtdblock

Check whether the modules are loaded:

lsmod | grep 'cam_epc670\|clk_si5351\|mtdblock'

Check the kernel log for errors:

dmesg | grep epc670

SPI Flash

Check MTD devices:

cat /proc/mtd

Expected output:

mtd0: 00800000 00010000 "data"

Then check device nodes:

ls -l /dev/mtd*

You should see:

/dev/mtd0
/dev/mtdblock0

If /dev/mtdblock0 does not exist, verify that the module is loaded:

lsmod | grep mtdblock

Automount

Verify the systemd automount unit:

systemctl status mnt-spi_flash.automount

Expected state:

Active: active (waiting)

Check the mount unit (it should not be active until first access):

systemctl status mnt-spi_flash.mount

Likely:

Inactive (dead)

Trigger the mount:

ls /mnt/spi_flash

Then check again:

mount | grep spi_flash

or

systemctl status mnt-spi_flash.mount

It should now be:

Active: active (mounted)

If it fails, inspect the logs:

journalctl -u mnt-spi_flash.mount

Device Nodes

Check whether the device node was created:

ls -l /dev/ | grep epc670

Expected output:

lrwxrwxrwx   1 root       root          11 Mar  4 10:34 epc670_subdev -> v4l-subdev2

You can also inspect the node with:

udevadm info -n /dev/epc670_subdev

Three runtime nodes are created:

  • /run/epc670/media

  • /run/epc670/video

  • /run/epc670/subdev

Check them with:

ls -l /run/epc670

Example output:

lrwxrwxrwx 1 root root 11 Mar  4 11:19 media -> /dev/media1
lrwxrwxrwx 1 root root 11 Mar  4 11:19 video -> /dev/video0
lrwxrwxrwx 1 root root 11 Mar  4 11:19 subdev -> /dev/epc670_subdev

The exact media and video device numbers may change after reboot. However, the /run/epc670/media and /run/epc670/video links should always exist. The configuration service creates /run/epc670/subdev -> /dev/epc670_subdev link as well, for the sake of user convenience.

If they are missing, the services responsible for creating them may have failed. A simple reboot might be an easy solution.

Services

Five oneshot services handle GPIO initialization, first-boot setup, flash sync, and media pipeline configuration.

epc670-tofhat-gpio-boot.service

Runs on every boot and sets the initial GPIO pin states for the ToF HAT hardware:

  • EN_LED_1 (GPIO12) — LED 1 enable, driven high

  • EN_LED_2 (GPIO5) — LED 2 enable, driven high

  • EN_I2C_PU (GPIO6) — I2C pull-ups enable, driven high

  • ID_WP (GPIO26) — EEPROM write protect, released (high-Z)

It should be active (exited) after a successful boot.

Check its status:

systemctl status epc670-tofhat-gpio-boot.service

If it failed, inspect the log:

journalctl -u epc670-tofhat-gpio-boot.service

To re-trigger manually without rebooting:

systemctl restart epc670-tofhat-gpio-boot.service

To override a pin state without affecting the service:

pinctrl set EN_LED_1 op dl

epc670-tofhat-firstboot.service

Runs once, on the first boot after installation. It builds and installs the DKMS modules against the running kernel, loads them, and brings up the full hardware stack. It is permanently skipped on subsequent boots once the stamp file /var/lib/epc670/firstboot.done exists.

Check its status:

systemctl status epc670-tofhat-firstboot.service

If it did not complete successfully, the stamp file will be absent. Inspect the log:

journalctl -u epc670-tofhat-firstboot.service

To re-trigger on next boot:

rm /var/lib/epc670/firstboot.done
reboot

To re-run immediately without rebooting:

/usr/lib/epc670/epc670-finalize --now

epctofcam-spi_flash-sync.service

Runs on every boot and copies the contents of /mnt/spi_flash into /usr/local/share/epctofcam/. It should be active (exited) after a successful boot.

Check its status:

systemctl status epctofcam-spi_flash-sync.service

If it failed, inspect the log:

journalctl -u epctofcam-spi_flash-sync.service

To re-trigger manually without rebooting:

systemctl stop epctofcam-spi_flash-sync.service
systemctl start epctofcam-spi_flash-sync.service

epc670-tofhat-nodes.service and epc670-tofhat-config.service

Run on every boot and create the runtime device nodes. They should be:

  • enabled

  • successfully executed once after boot

  • inactive after completion

Check their status:

systemctl status epc670-tofhat-nodes.service
systemctl status epc670-tofhat-config.service

If errors occurred, inspect the logs:

journalctl -u epc670-tofhat-nodes.service
journalctl -u epc670-tofhat-config.service

Global Headers

Verify that the global headers were installed:

ls -l /usr/include/epc/

Example output:

-rw-r--r-- 1 root root 1183 Feb 18 16:07 epc_v4l2_ctrls.h
-rw-r--r-- 1 root root 1476 Jan 29 10:05 epc_error.h