FX3是一款USB 3.2 Gen 1 Peripheral Controller,适用于工业摄像机、医疗和机器视觉摄像机-D和1080p全高清和 4K超高清(UHD)摄像机。文件和指纹扫描仪、视频会议和数据采集系统HDMI转换器、协议和逻辑分析仪USB测试工具和软件设计无线电(SDR)等待应用场景。
SuerSpeed Explorer Kit为支持FX3开发的开发板提供了方便访问FX3.方便接口,如GPIF II, I2C, SPI, UART, I2S,80引脚的GPIF II对接其他单板很方便,比如FPGAs、cpld、图像传感器或微控制器等。
1.供电方式的选择,2,供电电压的选择,3,I2C EEPROM、RAM、USB引导启动的选择boot mode
配套工具有Cypress EZ USB Suite
FX3是USB3.0外设控制器,FX3完全符合USB3.0 V1.0规范,也向后兼容USB2.0.它还兼容电池充电规范BCV1.1和USB2.0 OTG系统框图如下:
USB3.0是USB下一阶段的技术。其主要目标是提供相同的易用性、灵活性和热插拔功能,但数据速率较高。USB3.0的另一个主要目标是电源管理。这对于需要权衡功能以换取电池寿命的同步和运行应用程序非常重要。USB3.除物理外,0接口USB2.在0总线外,还有一条物理超高速总线。USB3.0标准定义为5gbits/s的速率传输的双单形信号机制。
USB3.0规范中的一个重要修改是用单播代替广播。
在USB3.另一个重要的另一个重要修改与中断传输有关。在USB2.无论设备是否准备好传输,主机都会在每个服务间隔内中断传输。但是,超速中断端点可以发送一个ERDY/NRDY,以换取自主机的中断传输/请求。若设备返回ERDY,主机将继续在每个服务间隔内中断设备端点。若设备返回NRDY,在设备异步(不是由主机发起的)通知之前,主机将停止中断请求或传输到端点ERDY。
提供双单工总线系统结构USB3.0协议的最大优势之一是可以在不等待另一侧确认包的情况下,在一个方向上启动多个包,否则会导致半双工总线的争议。这种能力被用来形成一个新的协议,指示数据包发送数据包,以便任何丢失或不利的确认可以用来触发由数据包识别的丢失数据包的重传输。
USB3.0的另一个显著特征是流协议,可用于批量传输。
就开发而言,无非是硬件和软件。
要注意硬件:CPU、基于AHB外部结构,存储Memory、中断、JTAG调试接口,外设(I2C、I2S、SPI、UART、GPIF II、GPIO、存储接口、MIPI-CSI2)、DMA、引导枚举和时钟复位Clock、供电Power以及功耗状态切换等。
有配套的软件SDK开发工具IDE(集成了ARM的compiler, linker, assembler, and JTAG debugger),可使用固件框架和样例库(源代码),由第三方提供OS,建立良好的环境可以关注用户应用程序的开发,基本结构如下:
固件的初始化过程包括:Device Configuration、Clock Setup、MMU and Cache management、Stack initiation、Interrupt management。
后基于提供的框架framework,基于API可以开发各种库USB应用。
经过多次初始化,进入Application代码。main()函数是C语言的入口点,会执行设备初始化(设置CPU时钟,初始化VIC、配置GCTL和PLL)、设备缓存配置,I/O这包括矩阵配置GPIF和串行接口(SPI、I2C、I2S、GPIO和UART)、调用操作系统(初始化)OS、配置OS Timer、启动任务调度)。在OS启动激活后,将创建应用功能线程:
/* Allocate the memory for the thread */ ptr = CyU3PMemAlloc (CY_FX_SLFIFO_THREAD_STACK); /* Create the thread for the application */ retThrdCreate = CyU3PThreadCreate (&slFifoAppThread, /* Slave FIFO app thread structure */ "21:Slave_FIFO_sync", /* Thread ID and thread name */ SlFifoAppThread_Entry, /* Slave FIFO app thread entry function */ 0, /* No input parameter to thread */ ptr, /* Pointer to the allocated thread stack */ CY_FX_SLFIFO_THREAD_STACK, /* App Thread stack size */ CY_FX_SLFIFO_THREAD_PRIORITY, /* App Thread priority */ CY_FX_SLFIFO_THREAD_PRIORITY, /* App Thread pre-emption threshold */ CYU3P_NO_TIME_SLICE, /* No time slice for the application thread */ CYU3P_AUTO_START /* Start the thread immediately */ );
应用代码将首先初始化与应用程序相关的应用程序,然后当收到它时USBSET_CONFIGURATION请求时,调用CyFxSlFifoAppln并设置启动功能USB<->GPIF数据传输所需的端点和DMA通道。当检测到USB禁止复位或断开USB端点并释放DMA调用通道时CyFxSlFlFifoApplnStop功能。
USB初始化如下:
/* Start the USB functionality */ 初始化FX3库 apiRetStatus = CyU3PUsbStart(); /* The fast enumeration is the easiest way to setup a USB connection, * where all enumeration phase is handled by the library. Only the * class/vendor requests need to be handled by the application. */ CyU3PUsbRegisterSetupCallback (CyFxSlFifoApplnUSBSetupCB, CyTrue); /* Setup the callback to handle the USB events. */ 注册回调函数 CyU3PUsbRegisterEventCallback (CyFxSlFifoApplnUSBEventCB); /* Set the USB Enumeration descriptors */ /* Device Descriptor */ 设置USB枚举描述符 apiRetStatus = CyU3PUsbSetDesc (CY_U3P_USB_SET_HS_DEVICE_DESCR, NULL, (uint8_t *)CyFxUSB20DeviceDscr); ... /* Connect the USB Pins */连接USB Pin脚 /* Enable Super Speed operation */ apiRetStatus = CyU3PConnectState(CyTrue, CyTrue); CyU3PUSBSpeed_t usbSpeed = CyU3PUsbGetSpeed(); /* First identify the usb speed. Once that is identified, * create a DMA channel and start the transfer on this. * Based on the Bus Speed configure the endpoint packet size. */ 接收端点SET_CONFIGURATION配置请求时。 switch (usbSpeed) { case CY_U3P_FULL_SPEED: size = 64; break; case CY_U3P_HIGH_SPEED: size = 512; break; case CY_U3P_SUPER_SPEED: size = 1024; break; default: CyU3PDebugPrint (4, "Error! Invalid USB speed.\n"); CyFxAppErrorHandler (CY_U3P_ERROR_FAILURE); break; } CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof (epCfg)); epCfg.enable = CyTrue; epCfg.epType = CY_U3P_USB_EP_BULK; epCfg.burstLen = 1; epCfg.streams = 0; epCfg.pcktSize = size; /* Producer endpoin configuration */
apiRetStatus = CyU3PSetEpConfig(CY_FX_EP_PRODUCER, &epCfg);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyU3PSetEpConfig failed, \
Error code = %d\n", apiRetStatus);
CyFxAppErrorHandler (apiRetStatus);
}
/* Consumer endpoint configuration */
apiRetStatus = CyU3PSetEpConfig(CY_FX_EP_CONSUMER, &epCfg);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyU3PSetEpConfig failed, \
Error code = %d\n", apiRetStatus);
CyFxAppErrorHandler (apiRetStatus);
}
配置USB回调函数,当FX3固件框架中的USB驱动程序需要应用程序响应USB控制请求(安装命令)时,将调用此回调函数。由于使用了快速枚举模型,因此应用程序只需要处理针对接口或端点的特定请求以及类和供应商的标准请求。
CyBool_t
CyFxSlFifoApplnUSBSetupCB (uint32_t setupdat0,
uint32_t setupdat1)
{
/* Fast enumeration is used. Only class, vendor and unknown
* requests are received by this function. These are not
* handled in this application. Hence return CyFalse. */
return CyFalse;
}
感兴趣的USB事件包括:设置配置、重置和断开连接。
/* This is the callback function to handle the USB events. */
void CyFxSlFifoApplnUSBEventCB (CyU3PUsbEventType_t evtype,
uint16_t evdata)
{
switch (evtype)
{
case CY_U3P_USB_EVENT_SETCONF:
/* Stop the application before re-starting. */
if (glIsApplnActive)
{
CyFxSlFifoApplnStop ();
}
/* Start the loop back function. */
CyFxSlFifoApplnStart ();
break;
case CY_U3P_USB_EVENT_RESET:
case CY_U3P_USB_EVENT_DISCONNECT:
/* Stop the loop back function. */
if (glIsApplnActive)
{
CyFxSlFifoApplnStop ();
}
break;
default:
break;
}
}
从FIFO应用程序使用2个DMA手动通道。一旦从USB主机接收到集合配置,就会设置这些通道。
/* Create a DMA MANUAL channel for U2P transfer.
* DMA size is set based on the USB speed. */
dmaCfg.size = size;
dmaCfg.count = CY_FX_SLFIFO_DMA_BUF_COUNT;
dmaCfg.prodSckId = CY_FX_PRODUCER_USB_SOCKET;
dmaCfg.consSckId = CY_FX_CONSUMER_PPORT_SOCKET;
dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
/* Enabling the callback for produce event. */
dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT;
dmaCfg.cb = CyFxSlFifoUtoPDmaCallback;
dmaCfg.prodHeader = 0;
dmaCfg.prodFooter = 0;
dmaCfg.consHeader = 0;
dmaCfg.prodAvailCount = 0;
apiRetStatus = CyU3PDmaChannelCreate (&glChHandleSlFifoUtoP,
CY_U3P_DMA_TYPE_MANUAL, &dmaCfg);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, \
Error code = %d\n", apiRetStatus);
CyFxAppErrorHandler(apiRetStatus);
}
/* Create a DMA MANUAL channel for P2U transfer. */
dmaCfg.prodSckId = CY_FX_PRODUCER_PPORT_SOCKET;
dmaCfg.consSckId = CY_FX_CONSUMER_USB_SOCKET;
dmaCfg.cb = CyFxSlFifoPtoUDmaCallback;
apiRetStatus = CyU3PDmaChannelCreate (&glChHandleSlFifoPtoU,
CY_U3P_DMA_TYPE_MANUAL, &dmaCfg);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, \
Error code = %d\n", apiRetStatus);
CyFxAppErrorHandler(apiRetStatus);
}
/* Set DMA Channel transfer size */
apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleSlFifoUtoP,
CY_FX_SLFIFO_DMA_TX_SIZE);
/* Set DMA Channel transfer size */
apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleSlFifoPtoU,
CY_FX_SLFIFO_DMA_TX_SIZE);