|
14 | 14 | from libarchive.read import fd_reader |
15 | 15 | from libcamera import Rectangle, Size |
16 | 16 | from tqdm import tqdm |
17 | | -from v4l2 import (VIDIOC_S_CTRL, VIDIOC_S_EXT_CTRLS, v4l2_control, |
18 | | - v4l2_ext_control, v4l2_ext_controls) |
| 17 | +from v4l2 import (VIDIOC_G_EXT_CTRLS, VIDIOC_S_CTRL, VIDIOC_S_EXT_CTRLS, |
| 18 | + v4l2_control, v4l2_ext_control, v4l2_ext_controls) |
19 | 19 |
|
20 | 20 | from picamera2 import CompletedRequest, Picamera2 |
21 | 21 |
|
|
27 | 27 | FW_MAIN_STAGE = 1 |
28 | 28 | FW_NETWORK_STAGE = 2 |
29 | 29 |
|
| 30 | +GET_DEVICE_ID_CTRL_ID = 0x00982902 |
30 | 31 | NETWORK_FW_FD_CTRL_ID = 0x00982901 |
31 | 32 | ROI_CTRL_ID = 0x00982900 |
32 | 33 |
|
@@ -372,6 +373,36 @@ def convert_inference_coords(self, coords: tuple, metadata: dict, picam2: Picame |
372 | 373 | out = self.__get_obj_scaled(obj, isp_output_size, scaler_crop, sensor_output_size) |
373 | 374 | return out.to_tuple() |
374 | 375 |
|
| 376 | + def get_device_id(self) -> str: |
| 377 | + """Get IMX500 Device ID""" |
| 378 | + ret = None |
| 379 | + imx500_device_id = "" |
| 380 | + |
| 381 | + r = (ctypes.c_uint32 * 4)() |
| 382 | + r[0] = 0x0 |
| 383 | + r[1] = 0x0 |
| 384 | + r[2] = 0x0 |
| 385 | + r[3] = 0x0 |
| 386 | + |
| 387 | + c = (v4l2_ext_control * 1)() |
| 388 | + c[0].p_u32 = r |
| 389 | + c[0].id = GET_DEVICE_ID_CTRL_ID |
| 390 | + c[0].size = 16 |
| 391 | + |
| 392 | + ctrl = v4l2_ext_controls() |
| 393 | + ctrl.count = 1 |
| 394 | + ctrl.controls = c |
| 395 | + |
| 396 | + try: |
| 397 | + fcntl.ioctl(self.device_fd, VIDIOC_G_EXT_CTRLS, ctrl) |
| 398 | + for i in range(4): |
| 399 | + ret = ctrl.controls[0].p_u32[i] |
| 400 | + imx500_device_id += "%08X" % ret |
| 401 | + except OSError as err: |
| 402 | + print(f'IMX500: Unable to get device ID from device driver: {err}') |
| 403 | + |
| 404 | + return imx500_device_id |
| 405 | + |
375 | 406 | def get_fw_upload_progress(self, stage_req) -> tuple: |
376 | 407 | """Returns the current progress of the fw upload in the form of (current, total).""" |
377 | 408 | progress_block = 0 |
@@ -621,14 +652,25 @@ def __ni_from_network(self, network_filename: str): |
621 | 652 | (magic, size) = struct.unpack('>4sI', fw[:8]) |
622 | 653 | if not magic == b'9464': |
623 | 654 | break |
624 | | - fw = fw[size + 60:] |
| 655 | + |
| 656 | + # Parse flags |
| 657 | + fw = fw[8:] |
| 658 | + flags = struct.unpack('8B', fw[:8]) |
| 659 | + device_lock_flag = flags[6] |
| 660 | + fw = fw[(size + 60 - 8):] # jump to footer |
| 661 | + |
625 | 662 | # Ensure footer is as expected |
626 | 663 | (magic,) = struct.unpack('4s', fw[:4]) |
627 | 664 | if not magic == b'3695': |
628 | 665 | raise RuntimeError(f'No matching footer found in firmware file {network_filename}') |
629 | 666 | fw = fw[4:] |
630 | 667 | cpio_offset += size + 64 |
631 | 668 |
|
| 669 | + if ((device_lock_flag & 0x01) == 1): |
| 670 | + # skip forward 32 bytes if device_lock_flag.bit0 == 1 |
| 671 | + fw = fw[32:] |
| 672 | + cpio_offset += 32 |
| 673 | + |
632 | 674 | cpio_fd = os.open(network_filename, os.O_RDONLY) |
633 | 675 | os.lseek(cpio_fd, cpio_offset, os.SEEK_SET) |
634 | 676 |
|
|
0 commit comments