针对使用FX3通过从FIFO模式向DSP传输数据时出现的首字丢失和末端数据错位问题,以下是分步解决方案:
DMA缓冲区配置优化
CyU3PDmaChannelSetXfer前增加100ms延时,确保DSP完成初始化#define DMA_BUF_SIZE 1024 // 必须为1024倍数
#define DMA_BUF_COUNT 8
ret = CyU3PDmaMultiChannelSetXfer(&glChHandleSlvFifo, DMA_BUF_SIZE*DMA_BUF_COUNT);GPIF II接口时序校准
STATE_ACQUIRE:
IF (FLAGB == 1) JUMP STATE_WRITE; // FLAGB表示DSP准备好
ELSE DELAY 10ns;
STATE_WRITE:
WRITE DATA[1:0] WITH SLWR=edge;
IF (FLAGB == 0) JUMP STATE_WAIT; // FIFO将满时暂停
STATE_WAIT:
DELAY 50ns; // 增加等待周期DSP端FIFO接口处理增强
void USB_FIFO_ISR(void) {
static uint16_t buffer[512];
static int idx = 0;
if(FX3_SLWR == ACTIVE) {
buffer[idx++] = FX3_DATA_PORT;
if(idx >= 512) {
DMA_Submit(buffer, 512);
idx = 0;
}
}
// 每接收256字节发送硬件ACK
if(idx % 256 == 0) {
SET_GPIO(ACK_PIN, 1);
DELAY_US(1);
SET_GPIO(ACK_PIN, 0);
}
}FX3固件关键修改点
CyU3PReturnStatus_t
CyFxSlaveFifoApplnStart(void) {
// 增加DMA通道复位
CyU3PDmaChannelReset(&glChHandleSlvFifo);
CyU3PThreadSleep(100); // 等待100ms
// 修改DMA模式为MANUAL模式
dmaCfg.size = 0; // 手动控制提交
dmaCfg.count = 0;
// 配置GPIO握手信号
CyU3PGpioSetSimpleConfig(ACK_GPIO, CY_U3P_GPIO_TYPE_INT,
CY_U3P_GPIO_INT_RISING_EDGE, 1);
}数据传输流程优化
[0xAA55][SEQ][DATA...][CRC16]调试诊断措施
def OnDataReceived(data):
logging.debug(f"Received {len(data)} bytes: {data[:4]}...")
if len(data) % 1024 != 0:
logging.warning("Unexpected packet size!")Trigger条件:SLWR上升沿 && DATA[15:0] == 0x0000
监测信号:SLCS, SLWR, DATA[15:0], FLAGA, FLAGB根本原因分析:
数据丢失问题主要由DMA缓冲区切换时的时序竞争导致。当FX3的DMA引擎在缓冲区边界切换时,DSP端的FIFO控制器未能及时检测到数据有效窗口,导致首字被覆盖。末端数据错位是由于USB控制中心的文件传输机制未正确处理短包(short packet)标记,导致最后一个数据包滞留缓冲区。
验证方法:
注意事项:
通过上述优化,数据传输的稳定性应得到显著提升。建议使用Cypress提供的Streamer示例程序作为基础进行二次开发,其内置的差错控制机制可有效预防此类问题。
举报
更多回帖