Skip navigation
Home > All Places > USB > USB Superspeed Peripherals > Blog > 2019 > February
2019

根据 基于CX3的UVC摄像头应用学习笔记-一(CX3 简介) ,用户可以选择一款适用于CX3的Image sensor 或者 Image ISP。本篇文章讨论如何利用 EZ-USB SDK 内置的CX3配置工具生成新的工程模板。

 

CX3 配置向导是一个图形化的工具,用户不需要写任何代码,即可从0开始建立一个可用的UVC工程。下面介绍详细的步骤。

  • 在SDK中点击相应的图标,如下图所示。

  • 在弹出的对话框中,选择Create a Configuration with Basic Settings 并输入相应的工程名称。

  • 点击 Finish。这时用户可以看到 内容为空的 Image sensor 配置窗口。

  • 在 Image sensor configuration 标签页,输入所需要的参数。这里,示例输入 Sensor 名称 为 OV5640,输入的MIPI信号为YUY2,CX3内部采用 16 bit接口传输。分辨率为1920*1080,帧率 30 fps。MIPI CSI clock 是315 MHz, 采用  2 lane传输。 用户可以根据实际情况输入或选择相应的参数。

 

  • 输入以上的sensor相关的参数后,点击 CX3 Receiver configuraion 标签页,将会看到 如下的窗口。从这里可以看到,刚才输入的参数位于窗口的左侧并且为灰色不可改。如果需要修改,则需要返回到上一标签页进行更改,本页只能编辑 CX3 MIPI 模块相关的参数。这里,用户需要参考 CX3 TRM 了解CX3内部的PLL的构成。这里,配置工具会根据输入的 sensor 参数,判断用户配置的参数是否合理,如果不合理,则会出现报错信息。用户需要调整参数以确认没有报错信息。

  • 在输入所有必须的参数,并且工具没有报错信息以后。依次点击右侧的标签保存生成的几个文件。

  • 保存后,可以在左侧的工程浏览器中看到,相应的文件已经保存并且包含到工程下。下图中,cyu3imagesensor.c 及其相应的.h文件用于具体实现对sensor 的配置。或者是说,这两个文件提供了配置sensor所必需的接口函数的实现。但是,具体的配置内容是空缺的。此时用户需要将sensor的配置参数填充到  cyu3imagesensor.c 中相应的结构体中。当然,这里用户同样需要修改默认的I2C设备地址为实际的地址。

BaiduShurufa_2019-2-22_11-32-21.png

BaiduShurufa_2019-2-22_11-32-10.png

  • 此处需要注意,按照以上的流程产生的工程,默认引用了 cy_ov5640.a 的库。如果工程中定义的配置分辨率的函数名又恰好与 OV5640.a 中已定义的函数重名,则CX3会执行库中的实现,而并非执行cyu3imagesensor.c 定义。因此,这里建议用户取消 对 cy_ov5640.a 的引用。

BaiduShurufa_2019-2-22_11-14-29.png

  • 完成以上的步骤后,编译工程。正常的话,会得到相应的Img文件。

在用户安装完成 EZ-USB SDK 后,可以在安装目录下看到,Cypress 已经预置了基于四种不同型号的 Image sensor 应用代码。用户可以在这些工程的基础上进行研究和修改,在对固件有了一定的掌握后,可以选择其他型号的 Image Sensor 或者 ISP。本篇文章讨论如何选取适配于 CX3 的 Image sensor,或者 Image ISP 等。

 

根据 CX3 的数据手册(请从https://www.cypress.com/part/cyusb3065-bzxi  获取最新版本的数据手册),CX3 为一款支持 MIPI CSI-2 协议的 USB3.0 接口的设备端控制芯片。MIPI 模块工作在 RX 模式,即 CX3 从 MIPI 接口接收数据,外部的 image sensor 或者 ISP 工作在 MIPI TX 模式,将数据传送给 CX3.

 

判断一款 Image sensor 或者 Image ISP 是否与 CX3 适配,需要考察以下几点

  • MIPI CSI-2 PHY类型

MIPI CSI-2 协议中定义了 PHY 层的规范,目前已有三种类型,包括 D-PHY,C-PHY 和 M-PHY 。CX3 支持 MIPI D-PHY,因为 D-PHY 和 C-PHY 以及 M-PHY不兼容,所以首先需要确认 Image sensor 是否支持 D-PHY。

  • 关于数据速率

目前 CX3 支持的最大数据吞吐速率为 2.4 Gbps,单 lane 的最大速率为 1 Gbps。即,当使用 1 lane时,每lane 1 Gbps 共计 1 Gbps. 当使用 2 lane时,每lane 1 Gbps共计 2 Gbps。当使用 3 lane 时,每 lane 800 Mbps 共计 2.4 Gbps。当使用 4 lane 时,每 lane 600 Mbps 共计 2.4 Gbps。用户需要计算,CX3 是否满足应用场景所要求的数据传输速率。

  • 关于支持的格式

CX3 的数据手册和 TRM 中都有介绍了 CX3 所支持的输入格式,用户可以查看对应的章节以确认。

 

一般来说,符合以上几点的 Image sensor 或者 ISP 可以与CX3 对接,实现 UVC的应用。

Objective:

To summarize the firmware and host utility that demonstrates fail-safe firmware update in FX3 from external EEPROM.

 

Flow-chart:

The sequence of steps involved in the boot-loading and firmware update is attached (FlowChart.pdf)

 

EEPROM Memory organization:

START ADDRESS

CONTENT

0x0000

Second Stage Boot-loader image

0x6000

Primary Firmware image

0x23000

Secondary Firmware image

0x3FFFF(Single Byte)

Firmware Update Byte (0x00 – Primary FW, 0xFF – Secondary FW)

 

Firmware:

  • Main application firmware is based on the USBBulkSourceSink example that comes with the FX3 SDK.
  • Second Stage boot-loader firmware is based on the Fx3BootAppGcc example that comes with the FX3 SDK.
  • The firmware source files and the IMGs are attached.
  • Release mode builds of firmware occupy lesser size than the debug builds and are hence preferred.

 

Key points to be noted in main application firmware:

 

1.    I2C block functionality is added and a DMA channel is created between CPU Producer socket and I2C Consumer socket. The firmware update is carried out over this DMA channel.

 

status = CyU3PI2cInit();

if(status == CY_U3P_SUCCESS)

{

CyU3PMemSet ((uint8_t *)&i2cConfig, 0, sizeof(i2cConfig));

i2cConfig.bitRate    = 100000;

i2cConfig.busTimeout = 0xFFFFFFFF;

i2cConfig.dmaTimeout = 0xFFFF;

i2cConfig.isDma      = CyTrue;

 

CyU3PI2cSetConfig (&i2cConfig, NULL);

}

apiRetStatus = CyU3PDmaChannelCreate (&glChHandleI2cTxHandle,

CY_U3P_DMA_TYPE_MANUAL_OUT, &dmaCfg);

 

2.    Vendor command inclusions

 

a. 0xFF:

This command performs the actual firmware update over the DMA channel between CPU Producer and the I2C Consumer sockets.

 

case 0xFF:

CyU3PUsbAckSetup ();

i2cAddr = 0xA0 | ((wValue & 0x0007) << 1);

status  = CyU3PUsbGetEP0Data(wLength, glEp0Buffer, NULL);

if (status == CY_U3P_SUCCESS)

{

CyFxFlashProgI2cTransfer (wIndex, i2cAddr, wLength,

                                    glEp0Buffer, CyFalse);

}

break;

 

b. 0xFB:

This command reads the content of EEPROM at address 0x3FFFF to know the currently running firmware.

 

case 0xFB:

CyU3PMemSet ((uint8_t *)&i2cConfig, 0, sizeof(i2cConfig));

i2cConfig.bitRate    = 100000;

i2cConfig.busTimeout = 0xFFFFFFFF;

i2cConfig.dmaTimeout = 0xFFFF;

i2cConfig.isDma      = CyFalse;

CyU3PI2cSetConfig (&i2cConfig, NULL);

 

preamble.length    = 4;

preamble.buffer[0] = 0xA6;

preamble.buffer[1] = (0xFF);

preamble.buffer[2] = (0xFF);

preamble.buffer[3] = (0xA7);

preamble.ctrlMask  = 0x0004;

status = CyU3PI2cReceiveBytes(&preamble, buffer, 1, 0);

glEp0Buffer[0] = buffer[0];

if(buffer[0] == 0x00)

      FW_ID = 0x00AA00AA;// Any FW_ID can be used here

else if (buffer[0] == 0xFF)

      FW_ID = 0xFFBBFFBB;// Any FW_ID can be used here

glEp0Buffer[1] = (FW_ID & 0xFF);

glEp0Buffer[2] = ((FW_ID >> 8) & 0xFF);

glEp0Buffer[3] = ((FW_ID >> 16) & 0xFF);

glEp0Buffer[4] = ((FW_ID >> 24) & 0xFF);

 

CyU3PUsbSendEP0Data (5, glEp0Buffer);

 

CyU3PMemSet ((uint8_t *)&i2cConfig, 0, sizeof(i2cConfig));

i2cConfig.bitRate    = 100000;

i2cConfig.busTimeout = 0xFFFFFFFF;

i2cConfig.dmaTimeout = 0xFFFF;

i2cConfig.isDma      = CyTrue;

CyU3PI2cSetConfig (&i2cConfig, NULL);

break;

 

c. 0xFA:

This command toggles the content of EEPROM at address 0x3FFFF. This vendor command is to be called after the completion of the firmware update to update the EEPROM data at 0x3FFFF indicating the newest firmware.

 

case 0xFA:

CyU3PUsbAckSetup ();

preamble.length    = 4;

preamble.buffer[0] = 0xA6;

preamble.buffer[1] = (0xFF);

preamble.buffer[2] = (0xFF);

preamble.buffer[3] = (0xA7);

preamble.ctrlMask  = 0x0004;

CyU3PMemSet ((uint8_t *)&i2cConfig, 0, sizeof(i2cConfig));

i2cConfig.bitRate    = 100000;

i2cConfig.busTimeout = 0xFFFFFFFF;

i2cConfig.dmaTimeout = 0xFFFF;

i2cConfig.isDma      = CyFalse;

CyU3PI2cSetConfig (&i2cConfig, NULL);

status = CyU3PI2cReceiveBytes(&preamble, buffer, 1, 0);

if(buffer[0] == 0x00)

     buffer[0] = 0xFF;

else if(buffer[0] == 0xFF)

     buffer[0] = 0x00;

preamble.length    = 3;

preamble.buffer[0] = 0xA6;

preamble.buffer[1] = (0xFF);

preamble.buffer[2] = (0xFF);

preamble.ctrlMask  = 0x0000;

CyU3PI2cTransmitBytes(&preamble, buffer, 1, 0);

 

CyU3PMemSet ((uint8_t *)&i2cConfig, 0, sizeof(i2cConfig));

i2cConfig.bitRate    = 100000;

i2cConfig.busTimeout = 0xFFFFFFFF;

i2cConfig.dmaTimeout = 0xFFFF;

i2cConfig.isDma      = CyTrue;

CyU3PI2cSetConfig (&i2cConfig, NULL);

break;

 

NOTE: Vendor commands 0xFB and 0xFA use the I2C block in register mode and not in DMA mode. This is because the DMA channel was created only between CPU Producer and I2C Consumer. Since these vendor requests involve transactions of only a few bytes, it is sufficient to use the register mode access. However, the I2C block must be reconfigured to DMA mode after these I2C transactions are completed.

 

3.    Primary firmware and secondary firmware start addresses in the EEPROM are hard-coded as 0x6000 and 0x23000 respectively. Firmware IDs of 0x00AA00AA and 0xFFBBFFBB are defined based on the running firmware and can be obtained using the 0xFB vendor command. These IDs are just place holders and can always be replaced as there is no dependency on these IDs from the host application.

 

Key Points to be noted in second stage boot-loader firmware:

1.    I2C boot is enabled in the second stage boot-loader.

#define I2C_BOOT

2.    The FwUpdateCheck() function decides the start address of the main firmware to be loaded based on the FW update byte of the EEPROM (0x3FFFF).

          o    If this byte is 0x00, primary firmware image is loaded into the FX3 SRAM.

          o    If this byte is 0xFF, secondary firmware image is loaded into the FX3 SRAM.

 

Host Application:

There are two host applications (binary and the source) included with this memo.

1.    To generate the combined firmware image file with the inputs as the second stage boot-loader and the main firmware. This command line utility generates the combined firmware image with the second stage boot-loader image and two copies of the main firmware image. The procedure to use the utility is mentioned in the readme.txt file in the project folder.

NOTE: Refer to IMGCombine utility.

2.    To perform the firmware update over the vendor interface of FX3 by issuing appropriate vendor commands. The tool also displays the currently running firmware.

NOTE: Refer to Fx3FirmwareUpdate utility

SrinathS_16

FX3 DMA Socket Suspend

Posted by SrinathS_16 Moderator Feb 2, 2019

Objective:

To understand the functionality of CyU3PDmaChannelSetSuspend() API of FX3 through firmware example implementation.

 

Related APIs:

CyU3PDmaChannelResume()

CyU3PDmaChannelGetBuffer()

CyU3PDmaChannelCommitBuffer()

 

API Usage:

The CyU3PDmaChannelSetSuspend() API can be used to suspend either the PRODUCER or the CONSUMER socket of a particular DMA channel. When a socket is suspended, further write (to a PRODUCER socket) or read (from the CONSUMER socket) cannot be performed until it is resumed. This API can be helpful when the data needs to be modified before being committed to the CONSUMER socket. In case of MANUAL channels, this API is not much helpful since the data has to be manually committed each time. But, in the case of AUTO channels, this API can be used to modify the data before being committing it to the CONSUMER.

 

API Prototype:

CyU3PReturnStatus_t

CyU3PDmaChannelSetSuspend (

        CyU3PDmaChannel *handle,                /**< Handle to the channel to be modified. */

        CyU3PDmaSckSuspType_t prodSusp,         /**< Suspend option for the producer socket. */

        CyU3PDmaSckSuspType_t consSusp          /**< Suspend option for the consumer socket. */

        );

 

API functionality:

- The CyU3PDmaChannel identifies the DMA channel of which the socket is to be suspended.

- The CyU3PDmaSckSuspType_t determines the nature in which the socket is suspended. The different options available are:

     1. CY_U3P_DMA_SCK_SUSP_NONE               -     Socket will not be suspended and will be in normal mode of operation.

     2. CY_U3P_DMA_SCK_SUSP_EOP                -     Socket will be suspended whenever the EOP bit in the buffer is set.

     3. CY_U3P_DMA_SCK_SUSP_CUR_BUF            -     Socket will be suspended after the current buffer is processed.

     4. CY_U3P_DMA_SCK_SUSP_CONS_PARTIAL_BUF   -     Socket will be suspended whenever there is a short packet from the PRODUCER socket.

 

Firmware Implementation:

The USBBulkSourceSink firmware and the GpifToUsb firmware that comes with the FX3 SDK have been modified with additional vendor commands to implement the socket suspend on DMA channel. Also, in the GpifToUsb firmware, the GPIF II state machine has been modified to include the COMMIT action. This generates an EOP condition on the buffer.

Vendor request handling is as follows. 0xFA implements a consumer socket suspend when there is an EOP condition, 0xFB implements a consumer socket suspend after the current buffer is completed and 0xFC implements a consumer socket suspend when there is a partial buffer, 0xFD gets the buffer and fills it with a known set of bytes (0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF in the attached examples), commits the buffer to the consumer and then resumes the consumer socket.

 

NOTE 1: When the socket suspend option is set to CY_U3P_DMA_SCK_SUSP_EOP, the socket will be suspended after handling any buffer with the EOP bit set. Typically the EOP bit will be set on any data buffers that are wrapped up on the PIB (GPIF) side through a COMMIT action. The DMA buffer with the EOP bit set would have been handled before the socket gets suspended, meaning that it is not possible to make changes to the contents of that data packet.

 

NOTE 2: When using the mentioned vendor commands, set the wLength field ('Bytes to Transfer' box in Control Center) to 0.

 

Case 1: CY_U3P_DMA_SCK_SUSP_EOP

Test Procedure:
- Program the GpifToUsb firmware into the FX3 using the Cypress USB Control Center.

- Use Cypress USB Control Center to read data from the 0x81 BULK IN endpoint. Since the state machine has been modified, 24 bytes of data will be received on the Control Center window for each IN transfer.

- From the Cypress USB Control Center, issue the 0xFA vendor command. This sets up the DMA channel consumer to be suspended after handling a buffer with EOP bit set.

- Perform the next BULK IN transfer on the 0x81 endpoint. This transfer will be successful (Refer NOTE 1).

- On the next BULK IN transaction from 0x81 endpoint, there will be an error on the Control Center. This indicates that the socket is now suspended.

- From the Cypress USB Control Center, issue the 0xFD vendor command. The buffer is obtained, filled with known bytes of data and committed to the consumer. The socket suspend is removed and the channel is resumed.

- Perform an IN data transfer from the Cypress USB Control Center. The known bytes of data that was manually committed will be seen on the display window.

- On subsequent reads from the 0x81 BULK IN endpoint, 24 bytes of data will be received continuously.

 

Case 2: CY_U3P_DMA_SCK_SUSP_CUR_BUF:

Test Procedure:

- Program the USBBulkLoopAutoEnum firmware into the FX3 using the Cypress USB Control Center.

- Use the Bulkloop application from the FX3 SDK to perform OUT and IN transactions with the corresponding endpoints. The application shows 'Successes' on the transactions.

- From the Cypress USB Control Center, issue the 0xFB vendor command. This suspends the consumer socket after the current buffer is processed. The suspension of the socket will be evident from the Bulkloop application which now starts showing 'Failures'. Stop the transactions on the Bulkloop application.

- From the Cypress USB Control Center, issue the 0xFD vendor command. The buffer is obtained, filled with known bytes of data and committed to the consumer. The socket suspend is removed and the channel is resumed.

- Perform an IN data transfer from the Cypress USB Control Center. The known bytes of data that was manually committed will be seen on the display window.

- Bulkloop application can again be started which now shows 'Successes' indicating resumption of the channel socket.

 

Case 3: CY_U3P_DMA_SCK_SUSP_CONS_PARTIAL_BUF

Test Procedure:

- Program the USBBulkLoopAutoEnum firmware into the FX3 using the Cypress USB Control Center.

- Use the Bulkloop application from the FX3 SDK to perform OUT and IN transactions with the corresponding endpoints. The application shows 'Successes' on the transactions.

- From the Cypress USB Control Center, issue the 0xFB vendor command. This sets up the consumer socket to be suspended after it receives a short packet. The Bulkloop application continues to show 'Successes' indicating that the socket is not yet suspended.

- From the Cypress USB Control Center, send a smaller number of bytes of data (say 10 bytes) over the BULK OUT endpoint. This generates a partial buffer from the PRODUCER socket which in turn generates a suspend condition on the consumer socket. The suspension of the socket will be evident from the Bulkloop application which now starts showing 'Failures'. Stop the transfers on the Bulkloop application.

- From the Cypress USB Control Center, issue the 0xFD vendor command. The buffer is obtained, filled with known bytes of data and committed to the consumer. The socket suspend is removed and the channel is resumed.

- Perform an IN data transfer from the Cypress USB Control Center. The known bytes of data that was manually committed will be seen on the display window.

- Bulkloop application can again be started which now shows 'Successes' indicating resumption of the channel socket.