使用 UPP接口乒乓接收ADC采集的数据,接收到的数据buffer1,buffer2接口处的数据不连续,会丢4个数,但是其他部分是好的
我估计是乒乓切换的时候重新配置dma时候丢了数,请问这种情况怎么解决?
Tony Tang:
有可能是,看一下你的这部分代码才好评论。
chen wei53:
回复 Tony Tang:
void OmaplFpgauPPSetup(void) { PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UPP, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
uPPPinMuxSetup(uPP_CHA_8BIT);
uPPReset(SOC_UPP_0_REGS);
uPPDataFmtConfig(SOC_UPP_0_REGS, uPP_CHA, uPP_DataPackingFmt_LJZE | uPP_DataPacking_FULL | uPP_InterfaceWidth_8BIT | uPP_DataRate_DOUBLE);
uPPChannelConfig(SOC_UPP_0_REGS, uPP_DDRDEMUX_DISABLE | uPP_SDRTXIL_DISABLE | uPP_CHN_ONE | uPP_ALL_RECEIVE);
uPPPinConfig(SOC_UPP_0_REGS, uPP_CHA, uPP_PIN_TRIS | uPP_PIN_WAIT | uPP_PIN_ENABLE | uPP_PIN_START);
uPPClkConfig(SOC_UPP_0_REGS, uPP_CHB, 57000000, 228000000, uPP_PIN_PHASE_NORMAL);
uPPIntEnable(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_EOW);
uPPIntRegister(C674X_MASK_INT7 );
uPPEnable(SOC_UPP_0_REGS);}
void uppCfg(unsigned int buff_num) { if(0 == buff_num) transposeParA.WindowAddress = (unsigned int *)((int)ad8568_buffer1 ); else transposeParA.WindowAddress = (unsigned int *)((int)ad8568_buffer2 );
transposeParA.LineCount = upp_line_count; transposeParA.ByteCount = (upp_line_size*sizeof(char)) ; transposeParA.LineOffsetAddress = (upp_line_offset*sizeof(char)) ;
uPPDMATransfer(SOC_UPP_0_REGS, uPP_DMA_CHI, &transposeParA);}
/*void main_tmp(void) { OmaplFpgauPPSetup();
uppCfg(buff_num);
while(1) { }}*/
void uPPIntRegister(unsigned int cpuINT ) { Hwi_Handle hwi; Hwi_Params hwiParams; Error_Block eb;
Error_init(&eb);
Hwi_Params_init(&hwiParams); hwiParams.eventId = SYS_INT_UPP_INT; hwiParams.arg = NULL; hwiParams.enableInt = FALSE;
hwi = Hwi_create(cpuINT, uPPIsr, &hwiParams, &eb); if (hwi == NULL) System_abort("Hwi2 create failed");
Hwi_enableInterrupt(cpuINT);}
void uPPIsr(void){ unsigned int intr_dmai_status;
intr_dmai_status = uPPIntStatus(SOC_UPP_0_REGS, uPP_DMA_CHI);
while (intr_dmai_status != 0) { if (intr_dmai_status & uPP_INT_EOL) { uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_EOL); }
if (intr_dmai_status & uPP_INT_EOW) { uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_EOW); receiveOK = 1; }
/*if (intr_dmai_status & uPP_INT_ERR) { uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_ERR); upp_error_count++; }
if (intr_dmai_status & uPP_INT_UOR) { uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_UOR); upp_error_count++; }
if (intr_dmai_status & uPP_INT_DPE) { uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_DPE); upp_error_count++; }*/
intr_dmai_status = uPPIntStatus(SOC_UPP_0_REGS, uPP_DMA_CHI); }
uPPEndOfInt(SOC_UPP_0_REGS);
uppCfg(buff_num); buff_num = !buff_num;}
Tony Tang:
回复 chen wei53:
没看到第一次配uPP传输在什么地方。有一个有点像的main_tmp被注释掉了。
就以main_tmp大致说一下吧:
main_tmp(void) { OmaplFpgauPPSetup();
uppCfg(buff_num);
while(1) { }
}
应该改成:
main_tmp(void) { OmaplFpgauPPSetup();
uppCfg(buff_num); //ping
check pending bit here, then configure Pong DMA parameter.
uppCfg(buff_num); //pong
while(1) { }
}
这样在ISR处理时,PONG在继续接收数据。否则在ISR里配DMA之前这段时间,数据就丢了。
chen wei53:
回复 Tony Tang:
那段的确是不用的,第一次是在syslink启动配置里面配置的 如下
Server *server_new() {Server *server = (Server *)calloc(1, sizeof(Server));
/* Syslink/IPC init */server->service = syslink_service_new("HOST");server->ad_started = false;server->quit = false;server->last = 0;
OmaplFpgauPPSetup();uppCfg(buff_num);
return server;
}
Tony Tang:
回复 chen wei53:
那就把这一段照着前面说的改一下。
chen wei53:
回复 Tony Tang:
请问check pending bit here, then configure Pong DMA parameter.具体什么操作
还有我出现的错误不只是第一次,而是每次两个buffer切换的时候,这里只是开始的时候的配置,后续的数据都是通过中断触发dma配置然后传输的,照你的以后以后的错误还是无法避免呀。
Tony Tang:
回复 chen wei53:
TRM手册:
chen wei53:
回复 Tony Tang:
你好,我一直没有找到pend位检测的那部分代码,你知道pend位检测该怎么写吗?
Tony Tang:
回复 chen wei53:
手册写的看不懂?
while(UPQS2r->bits.PEND == 1){};
chen wei53:
回复 Tony Tang:
谢谢,我试一试。