upp单通道2个DMA乒乓操作接收fpga数据,程序只进入一次upp中断就不再进入,并没有切换到另一个DMA的buffer。
void upp_init(void)
{
// uPP 外设初始化
OmaplFpgauPPSetup();
transposeParA.WindowAddress = (unsigned int *)((int)(upp_buffer_a));
transposeParA.LineCount = upp_line_count;
transposeParA.ByteCount = (upp_line_size*sizeof(unsigned short));
transposeParA.LineOffsetAddress = (upp_line_offset*sizeof(unsigned short));
transposeParB.WindowAddress = (unsigned int *)((int)(upp_buffer_b));
transposeParB.LineCount = upp_line_count;
transposeParB.ByteCount = (upp_line_size*sizeof(unsigned short));
transposeParB.LineOffsetAddress = (upp_line_offset*sizeof(unsigned short));
uPPDMATransfer(SOC_UPP_0_REGS, uPP_DMA_CHI, &transposeParA);
uPPDMATransfer(SOC_UPP_0_REGS, uPP_DMA_CHQ, &transposeParB);
}
void OmaplFpgauPPSetup(void)
{
// 外设使能
PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UPP, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
// 引脚复用配置
uPPPinMuxSetup(uPP_CHA_8BIT);
// uPP复位
uPPReset(SOC_UPP_0_REGS);
// 数据格式配置
uPPDataFmtConfig(SOC_UPP_0_REGS, uPP_CHA, uPP_DataPackingFmt_LJZE | uPP_DataPacking_FULL
| uPP_InterfaceWidth_8BIT | uPP_DataRate_SINGLE);
// 通道配置
uPPChannelConfig(SOC_UPP_0_REGS, uPP_DDRDEMUX_DISABLE | uPP_SDRTXIL_ENABLE | uPP_CHN_ONE
| uPP_ALL_RECEIVE);
// 引脚配置
uPPPinConfig(SOC_UPP_0_REGS, uPP_CHA, uPP_PIN_TRIS | uPP_PIN_ENABLE |uPP_PIN_START);
// 中断使能
uPPIntEnable(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_EOW);
uPPIntEnable(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_EOW);
// 中断映射
IntRegister(C674X_MASK_INT5, uPPIsr);
IntEventMap(C674X_MASK_INT5, SYS_INT_UPP_INT);
IntEnable(C674X_MASK_INT5);
// uPP使能
uPPEnable(SOC_UPP_0_REGS);
}
void uPPIsr(void)
{
GPIOPinWrite(SOC_GPIO_0_REGS, 20, GPIO_PIN_HIGH);
int k;
unsigned int intr_dmai_status, intr_dmaq_status;
// 取得 DMA 中断状态
intr_dmai_status = uPPIntStatus(SOC_UPP_0_REGS, uPP_DMA_CHI);
intr_dmaq_status = uPPIntStatus(SOC_UPP_0_REGS, uPP_DMA_CHQ);
while(intr_dmai_status != 0 /*|| intr_dmaq_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);
upp_interrupt_flag=1;
}
if (intr_dmai_status && uPP_INT_ERR)
{
uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_ERR);
}
if (intr_dmai_status && uPP_INT_UOR)
{
uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_UOR);
}
if (intr_dmai_status && uPP_INT_DPE)
{
uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_DPE);
//upp_interrupt_flag++;
}
if (intr_dmaq_status & uPP_INT_EOL)
{
uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_EOL);
}
if (intr_dmaq_status & uPP_INT_EOW)
{
uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_EOW);
}
if (intr_dmaq_status & uPP_INT_ERR)
{
uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_ERR);
}
if (intr_dmaq_status & uPP_INT_UOR)
{
uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_UOR);
}
if (intr_dmaq_status & uPP_INT_DPE)
{
uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_DPE);
}
// uPP 中断将多个事件组合为同一中断源
// 判断是否全部事情被处理完毕
intr_dmai_status = uPPIntStatus(SOC_UPP_0_REGS, uPP_DMA_CHI);
intr_dmaq_status = uPPIntStatus(SOC_UPP_0_REGS, uPP_DMA_CHQ);
}
// 通知 CPU uPP 中断处理完毕以便后续事件可以产生
uPPEndOfInt(SOC_UPP_0_REGS);
GPIOPinWrite(SOC_GPIO_0_REGS, 20, GPIO_PIN_LOW);
}
Tony Tang:
user5377263uPPDMATransfer(SOC_UPP_0_REGS, uPP_DMA_CHI, &transposeParA); uPPDMATransfer(SOC_UPP_0_REGS, uPP_DMA_CHQ, &transposeParB);
这两个之间要加:
Reprogram the DMA as necessary (checking that the PEND bit in the uPP DMA channel status register (UPxS2) is 0).