FPGA 非常适合低延迟、高吞吐量的成像应用。最好使用直接与 FPGA 接口的相机(而不是 USB/网络相机)来实现这一点。然而,对于业余爱好者、修补匠和小型初创企业来说,可用的相机模块选项数量有限,而且并非所有可用选项都便宜(相对而言)。最重要的是,许多都有自己的物理接口,所以通常你只能将相机与它的开发套件一起使用。没有相当大的努力,就是这样。
然而,由于具有 15 针 FFC 摄像头接口 (MIPI-CSI) 的 Raspberry Pi 等低成本单板计算机的普及,情况正在好转。随着时间的推移,RPi 相机接口变得非常流行,如今许多单板计算机都可以使用相同的相机连接器(Jetson 套件、RPi 替代板等)。甚至一些 FPGA 板现在也配备了相同的 15 针连接器(Zybo-Z7、Kria 等)。由于受欢迎程度,现在可以从各种供应商(RPi 基金会、Arducam、VEYE 等)处获得许多低成本图像传感器。
不幸的是,一旦我们开始将这些图像传感器之一与我们的 FPGA 一起使用,我们就会遇到一个大问题:大多数图像传感器的数据表都是不公开的!
您会看到,在使用任何现代图像传感器之前,您需要根据您的用例对其进行配置。虽然高吞吐量数据通过 MIPI-CSI 等协议传输,但配置通常通过 I2C 进行。然而,要知道通过 I2C 接口发送什么命令需要知道传感器的寄存器映射,以及这些寄存器的每一位的功能。但如果没有公开的数据表,这是一个大问题。在某些情况下,如果您足够幸运,您将能够在互联网上找到您的特定图像传感器的泄露数据表,但情况并非总是如此。例如,在撰写本文时(2021 年 9 月),RPi“高质量”相机没有公开的数据表。
有时即使有数据表,事情也不会太乐观。现代图像传感器是复杂的硅片,配置大多数图像传感器需要正确设置数百个寄存器,然后才能开始以正确格式输出正确的图像数据。有时钟/PLL 配置、分辨率、binning、曝光、增益、白平衡、输出接口格式等设置。至少获得参考或起点不是很好吗?
“嗅探”或“窃听”是软件/硬件黑客中常用的一种技术。这个想法是监听两个设备之间的通信,而不干扰原始对话,并保持细致的记录以备后用。我们可能不明白对话的每个部分的含义是什么,但有时我们可以重播相同的序列,并设法欺骗目标设备给我们需要的东西。
在这种特殊情况下,我有一个我之前购买的Zybo-z7-20板,以及PCAM-5C板相机。使用Digilent 提供的运行“baremetal”的演示项目,我能够非常快速地让两者一起工作。但是,对于未来的项目,我希望有更多的相机选项,而不仅仅是 PCAM-5C。许多与 RPi 接口兼容的传感器都带有自己的 Linux 驱动程序。我希望能够在运行裸机时使用相同的传感器。
我的计划如下:
对于这个特定的实验,我将使用我已经拥有的:- Raspberry Pi v2.1 相机- RaspberryPi 4B 作为“本机”平台- Saleae Logic 16 pro 作为我的逻辑分析仪- Zybo-Zy-20 作为我的“目标” FPGA板。
让我们开始吧……!
N. 从电路板的示意图中检查引脚配置和电压电平。
我们可以看到连接器将为连接的相机提供 3.3V 电压,并且 I2C 也在 3.3V 下工作。
接下来,我们看一下摄像头模块。从 RPi v2.1 摄像头模块的示意图中,我们可以验证引脚配置和电压确实匹配。
您可能会注意到上拉电压为 1.8V 而不是 3.3V,但这没关系,因为组件 Q1 正在执行电压电平转换。Ctrl+C退出。注意上面使用 gstreamer 管道,这是上述命令正常工作的先决条件。
现在我们有了一个工作系统,下一步是嗅探 RPi 和图像传感器之间的 I2C 通信。首先,我使用烙铁将三根细跳线连接到 FFC 上的接地、SDA、SCL 引脚,然后用 Kapton 胶带覆盖以作为连接线的机械释放。我这样做是因为与在焊接过程中弄乱 RPi 或摄像头板相比,FFC 电缆便宜且易于更换。此外,这给了我一根“间谍电缆”,我也可以将其重新用于其他相机/平台。
在此之后,我将这些电线与我的逻辑分析仪连接起来。在这一步中,我使用 USB“逻辑分析仪”来嗅探 I2C 通道上的通信。我使用的是 Saleae Logic 16 pro,因为这是我所拥有的,但任何便宜的逻辑分析仪都可以解决这个问题(I2C 的数据速率相当慢)。最后,我为 I2C 解码配置了逻辑分析仪并点击了开始按钮。
现在我们有一些捕获的数据。
现在我们有了一些捕获的数据,我们需要清理和准备数据,然后才能将其与 FPGA 板一起使用。由于我遵循的确切过程非常具体到我所拥有的设置,因此我将详细说明每个步骤的意图以供读者理解。
我注意到的第一件事是有一个初始的命令突发(左),然后是另一个密集的命令突发(中),然后经过一段时间的延迟后,每隔约 15 毫秒就会有一个 I2C 命令(右)。
每 ~15ms 的命令对应于 60fps 帧之间的时间。此外,这些命令被发送到相同的 I2C 地址,并且都是写命令。
因此,经过一些实验后,我得出结论,这些必须是从 ISP 到相机的命令,以便在处理每一帧后根据不断变化的照明条件(自动增益/曝光控制,可能还有自动白平衡)进行调整。这也意味着,就目前而言,我可以删除在这些命令的第一个实例之后发送的任何数据数据,因为发送一次曝光命令就足以开始了。另外,请注意这些重复的命令被发送到 I2C 地址 0x10。因此我们可以推断出我们相机的 I2C 地址是 0x10 。
接下来,我查看了修剪后的数据,注意到开头有一些读命令,还有一些写到 I2C 地址 0x71 的命令。
由于我们不知道如何处理从读取命令返回的数据,因此保留它们没有意义,因此我删除了它们。
寻址到 0x71 的命令很可能用于位于 Rpi V2.1 cam 上的 EEPROM,Raspberry pi 固件使用它来查看是否连接了正版相机,因此我们也不需要保留它们。因此我也删除了它们。
对于转储的数据,我将仅提及一些细分。让我们随机选择一行转储数据:
write to 0x10 ack data: 0x01 0x62 0x0D 0xE8
在这一行中,0x10 是相机的 I2C 地址,0x0162 是寄存器地址,0x0D、0xE8 是数据字节。通常一个寄存器是一个字节长,因此由于大多数传感器中的 I2C 地址自动递增功能,第二个字节实际上会转到下一个寄存器地址 (0x1063)。
无论如何,在此之后,我将剩余的修剪数据复制到 Excel 表中,删除除 I2C 数据之外的所有文本并对其进行格式化(通过一些手动操作),以便稍后在 Xilinx 内部将其用作 C 中的数组开发工具包。其中一部分包括在每行中添加一个包含 I2C 字节数的列,因为转储数据中的不同行发送的 I2C 字节数不同。
现在,要使用我们的 FPGA 板测试我们的数据,我需要一个 Vivado &SDK 项目。幸运的是,我已经从 Adam Taylor 的优秀帖子中下载了一个 Vivado 项目,它为我提供了一个工作系统,以 720p60 分辨率从 PCAM-5C 相机获取数据并通过 HDMI 输出显示。
接下来,我为此访问了 SDK 项目,并添加了一个包含先前步骤中转储和格式化的 I2C 数据的数组,并将其设置为在启动后发送到 v2 相机 I2C 地址 (0x10)。其余什么都不需要更改,事实上我什至将以前的 PCAM-5C 代码留在了文件中,因为当该地址上没有设备响应时,该地址的命令会被简单地忽略。我还将 Adam 的 vivado 项目配置为使用 CSI 输入(而不是 HDMI IN)作为源。包含所有修改的完整项目链接在帖子末尾。
完成软件修改后,剩下要做的就是将 RPi v2.1 摄像头连接到 Zybo-Z7 上的 MIPI 连接器,将 HDMI 电缆从 HDMI TX 端口连接到显示器,然后上传代码。
。
我愿意称之为成功。这证明这里采用的概念也适用于其他可用的传感器(尽管有一些警告),并且应该为我们提供更多 MIPI 图像传感器选项以用于 FPGA 项目。这意味着,如果其中一个传感器是与 FPGA 一起使用,那么我们将需要在 FPGA 中自己处理这些功能。通过在受控的光照条件变化下查看每帧后发送到相机的数据,应该可以找到相关的寄存器。另一方面,一些摄像头模块还带有板载 ISP,在这种情况下,这不是问题。(看看一些来自 Arducam、VEYE 的传感器)
希望你喜欢阅读和跟随。下次我们可能会尝试不同的 MIPI 传感器(RPi HQ 相机?),看看效果如何。
如果您发现这有用(或没有),请在下面的评论部分分享您的评论/想法!
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !