Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions examples/imx500/imx500_get_device_id.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/python3

from picamera2 import Picamera2
from picamera2.devices.imx500 import IMX500

model = "/usr/share/imx500-models/imx500_network_mobilenet_v2.rpk"

# startup imx500 / picamera2
imx500 = IMX500(model)
picam2 = Picamera2()
config = picam2.create_preview_configuration()
picam2.start(config, show_preview=False)

# get device_id
device_id = imx500.get_device_id()
print("IMX500 Device ID =", device_id)
48 changes: 45 additions & 3 deletions picamera2/devices/imx500/imx500.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
from libarchive.read import fd_reader
from libcamera import Rectangle, Size
from tqdm import tqdm
from v4l2 import (VIDIOC_S_CTRL, VIDIOC_S_EXT_CTRLS, v4l2_control,
v4l2_ext_control, v4l2_ext_controls)
from v4l2 import (VIDIOC_G_EXT_CTRLS, VIDIOC_S_CTRL, VIDIOC_S_EXT_CTRLS,
v4l2_control, v4l2_ext_control, v4l2_ext_controls)

from picamera2 import CompletedRequest, Picamera2

Expand All @@ -27,6 +27,7 @@
FW_MAIN_STAGE = 1
FW_NETWORK_STAGE = 2

GET_DEVICE_ID_CTRL_ID = 0x00982902
NETWORK_FW_FD_CTRL_ID = 0x00982901
ROI_CTRL_ID = 0x00982900

Expand Down Expand Up @@ -372,6 +373,36 @@ def convert_inference_coords(self, coords: tuple, metadata: dict, picam2: Picame
out = self.__get_obj_scaled(obj, isp_output_size, scaler_crop, sensor_output_size)
return out.to_tuple()

def get_device_id(self) -> str:
"""Get IMX500 Device ID"""
ret = None
imx500_device_id = ""

r = (ctypes.c_uint32 * 4)()
r[0] = 0x0
r[1] = 0x0
r[2] = 0x0
r[3] = 0x0

c = (v4l2_ext_control * 1)()
c[0].p_u32 = r
c[0].id = GET_DEVICE_ID_CTRL_ID
c[0].size = 16

ctrl = v4l2_ext_controls()
ctrl.count = 1
ctrl.controls = c

try:
fcntl.ioctl(self.device_fd, VIDIOC_G_EXT_CTRLS, ctrl)
for i in range(4):
ret = ctrl.controls[0].p_u32[i]
imx500_device_id += "%08X" % ret
except OSError as err:
print(f'IMX500: Unable to get device ID from device driver: {err}')

return imx500_device_id

def get_fw_upload_progress(self, stage_req) -> tuple:
"""Returns the current progress of the fw upload in the form of (current, total)."""
progress_block = 0
Expand Down Expand Up @@ -621,14 +652,25 @@ def __ni_from_network(self, network_filename: str):
(magic, size) = struct.unpack('>4sI', fw[:8])
if not magic == b'9464':
break
fw = fw[size + 60:]

# Parse flags
fw = fw[8:]
flags = struct.unpack('8B', fw[:8])
device_lock_flag = flags[6]
fw = fw[(size + 60 - 8):] # jump to footer

# Ensure footer is as expected
(magic,) = struct.unpack('4s', fw[:4])
if not magic == b'3695':
raise RuntimeError(f'No matching footer found in firmware file {network_filename}')
fw = fw[4:]
cpio_offset += size + 64

if ((device_lock_flag & 0x01) == 1):
# skip forward 32 bytes if device_lock_flag.bit0 == 1
fw = fw[32:]
cpio_offset += 32

cpio_fd = os.open(network_filename, os.O_RDONLY)
os.lseek(cpio_fd, cpio_offset, os.SEEK_SET)

Expand Down