在使用FPGA(发送端)与DSP(接收端)通信,在配置
void UppReload( Uint32 UPP_LINE_SIZE )
{
/*启动UPP DMA传输*/
upp_reg_hdl->UPID0 = (Uint32)upp_buffer_a; //这个是指UPP的地址
upp_reg_hdl->UPID1 = ((Uint32)Upp_Line_Num << 16) | (Uint32)UPP_LINE_SIZE*sizeof(Int16);
upp_reg_hdl->UPID2 = (Uint32)UPP_LINE_SIZE*sizeof(Int16);
}
中的Upp_Line_Num 为宏定义,固定为32,当配置该函数唯一的参数为20000的时候,是能够进入upp_end of window中断的,但是收到的数是错的,但是将该函数唯一的参数设置为16000的时候,既能够进入中断,并且接收的数据都是对的。此外,如果Upp_Line_Num 为宏定义,固定为64 ,UPP_LINE_SIZE 改为其他值收到的数据都不对。由于要传输的数据量较大,不得不提高UPP的行数,因为UPP_LINE_SIZE 不能超过32767。请问是什么原因,以下附上所有upp配置及调用,恳请指导,谢谢!
配置的函数以及调用的情况如下所示(使用了csl库):
调用以及宏定义如下:
#pragma DATA_SECTION(upp_buffer_a,".RXUPP")
short upp_buffer_a[upp_frame_size];//接收FPGA通过UPP发送来的大批量数据,初定为240064个short。
#pragma DATA_ALIGN(upp_buffer_a,8);//2015.12.29
extern volatile int upp_interrupt_count; //为1的话,表示upp搬运(接收到)指定数据量的数据
extern volatile int upp_error_count;
// inline functions
#define upp_int_clear(a) upp_reg_hdl->UPIER = a
#define upp_int_status() upp_reg_hdl->UPIER
#define upp_int_enable(a) upp_reg_hdl->UPIES = a
#define upp_int_disable(a) upp_reg_hdl->UPIEC = a
// configuration macros
#define upp_line_size (20000) //其实是30000个short,这个值不能超过32767
#define upp_line_count (16) //qishiwei8
#define upp_frame_size (upp_line_size * upp_line_count)
#define upp_line_offset (upp_line_size)
#define UPP_CLOCK_DIV (1) //分频
extern short upp_buffer_a[upp_frame_size];//接收FPGA通过UPP发送来的大批量数据,初定为240064个short。
#define upp_isr_bit_eolq (CSL_UPP_UPISR_EOLQ_MASK)
#define upp_isr_bit_eowq (CSL_UPP_UPISR_EOWQ_MASK)
#define upp_isr_bit_errq (CSL_UPP_UPISR_ERRQ_MASK)
#define upp_isr_bit_uorq (CSL_UPP_UPISR_UORQ_MASK)
#define upp_isr_bit_dpeq (CSL_UPP_UPISR_DPEQ_MASK)
#define upp_isr_bit_eoli (CSL_UPP_UPISR_EOLI_MASK)
#define upp_isr_bit_eowi (CSL_UPP_UPISR_EOWI_MASK)
#define upp_isr_bit_erri (CSL_UPP_UPISR_ERRI_MASK)
#define upp_isr_bit_uori (CSL_UPP_UPISR_UORI_MASK)
#define upp_isr_bit_dpei (CSL_UPP_UPISR_DPEI_MASK)
#define upp_isr_bit_all (upp_isr_bit_eolq | upp_isr_bit_eowq | \
upp_isr_bit_errq | upp_isr_bit_uorq | \
upp_isr_bit_dpeq | upp_isr_bit_eoli | \
upp_isr_bit_eowi | upp_isr_bit_erri | \
upp_isr_bit_uori | upp_isr_bit_dpei)
#define Upp_Line_Num 32
UPPPinMuxSetup();
UPPReset();
UPPInit();
UPPInterruptInit();
UPPEnable();
UppReload( Adcp_Upp.adcp_upp_line );
这些函数为:
void UPPPinMuxSetup(void)
{
unsigned int savePinmux13 = 0;//在本项目中只用到4个CHA的信号配置,以及16个DATA,只用到了PIN13、PIN14、PIN15、PIN16
unsigned int savePinmux14 = 0;
unsigned int savePinmux15 = 0;
unsigned int savePinmux16 = 0;
/* all pins (channel A, channel B, DATA, and XDATA)*/
savePinmux13 = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(13)) & 0x0000FFFF);
savePinmux14 = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(14)) & 0x000000FF);
savePinmux15 = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(15)) & 0x00000000);
savePinmux16 = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(16)) & 0xFFFFFF00);
// savePinmux17 = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(17)) & 0x00000000);
// savePinmux18 = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(18)) & 0xFF000000);
HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(13)) = (0x44440000 | savePinmux13);//这四个引脚都是UPPA的四个控制信号
HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(14)) = (0x44444400 | savePinmux14);//
HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(15)) = (0x44444444 | savePinmux15);
HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(16)) = (0x00000044 | savePinmux16);
// HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(17)) = (0x44444444 | savePinmux17);
// HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(18)) = (0x00444444 | savePinmux18);
}
void UPPReset(void)
{
// toggle reset with short delay
CSL_FINST(upp_reg_hdl->UPPCR, UPP_UPPCR_SWRST, RESET);
Delay(0xfff);
CSL_FINST(upp_reg_hdl->UPPCR, UPP_UPPCR_SWRST, RUNNING);
}
void UPPInit(void)
{
unsigned int temp_reg = 0;
// configure registers: CTL, ICR, IVR
/***************************** 1. CTL************************/
// Channel B params
// CSL_FINST(temp_reg, UPP_UPCTL_DPFB, LJZF); //Left-justified, zero filled
// CSL_FINST(temp_reg, UPP_UPCTL_IWB, 8BIT); //8-bit interface
// CSL_FINST(temp_reg, UPP_UPCTL_DPWB, FULL); //Channel B bit width = 8
// CSL_FINST(temp_reg, UPP_UPCTL_DRB, SINGLE); //Single data rate
// Channel A params //这边写错了,应该是Channel A params~~~
CSL_FINST(temp_reg, UPP_UPCTL_DPFA, LJZF); //Left-justified, zero filled
CSL_FINST(temp_reg, UPP_UPCTL_IWA, 16BIT); //16-bit interface~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CSL_FINST(temp_reg, UPP_UPCTL_DPWA, FULL); //Channel A bit width = 16 这边有点不确定!!!!!
CSL_FINST(temp_reg, UPP_UPCTL_DRA, SINGLE); //Single data rate
CSL_FINST(temp_reg, UPP_UPCTL_CHN, ONE); //Channel A is active!!!!!!!!!!!
CSL_FINST(temp_reg, UPP_UPCTL_MODE, RECEIVE); //Operating mode Duplex Mode 0.//这个要注意哦~~~~~~~~
upp_reg_hdl->UPCTL = temp_reg;
temp_reg = 0;
/****************** 2. ICR*********************/
// Channel A params
CSL_FINST(temp_reg, UPP_UPICR_TRISA, ENABLE); //Channel A data pins are in a high-impedance state while idle
CSL_FINS(temp_reg, UPP_UPICR_CLKDIVA, UPP_CLOCK_DIV); //Clock divisor,其实这个只是用来发送!!!
CSL_FINST(temp_reg, UPP_UPICR_STARTA, ENABLE); //Channel A START Signal Enable.
CSL_FINST(temp_reg, UPP_UPICR_ENAA, ENABLE); //Channel A ENABLE Signal Enable
// Channel B params
// CSL_FINS(temp_reg, UPP_UPICR_CLKDIVB, UPP_CLOCK_DIV);
// CSL_FINST(temp_reg, UPP_UPICR_STARTB, ENABLE); //Channel B START Signal Enable.
// CSL_FINST(temp_reg, UPP_UPICR_ENAB, ENABLE); //Channel B ENABLE Signal Enable
// apply all fields in one shot
upp_reg_hdl->UPICR = temp_reg;
temp_reg = 0;
//个人感觉这个不需要了,因为Idle只针对发送!!!!!
// /******************************** 3. IVR******************************/
// CSL_FINS(temp_reg, UPP_UPIVR_VALB, 0x7b7b); //Channel B idle value
// CSL_FINS(temp_reg, UPP_UPIVR_VALA, 0x7f7f); //Channel A idle value
// apply all fields in one shot
// upp_reg_hdl->UPIVR = temp_reg;
}
void UPPInterruptInit(void)
{
// Initialize interrupt
// upp_int_enable(upp_isr_bit_eolq);
// upp_int_enable(upp_isr_bit_eowq);
// upp_int_enable(upp_isr_bit_eoli);
upp_int_enable(upp_isr_bit_eowi);
IntRegister(C674X_MASK_INT5,uPPIsr);
IntEventMap(C674X_MASK_INT5, SYS_INT_UPP_INT);
IntEnable(C674X_MASK_INT5);
}
void UPPEnable(void)
{
// turn on peripheral
CSL_FINST(upp_reg_hdl->UPPCR, UPP_UPPCR_EN, ENABLE);
}
void UppReload( Uint32 UPP_LINE_SIZE )
{
/*启动UPP DMA传输*/
upp_reg_hdl->UPID0 = (Uint32)upp_buffer_a; //这个是指UPP的地址
upp_reg_hdl->UPID1 = ((Uint32)Upp_Line_Num << 16) | (Uint32)UPP_LINE_SIZE*sizeof(Int16);
upp_reg_hdl->UPID2 = (Uint32)UPP_LINE_SIZE*sizeof(Int16);
}
void uPPIsr(void)
{
Uint32 intr_status = upp_int_status();
while (intr_status != 0)
{
if (intr_status & upp_isr_bit_eoli)
{
upp_int_clear(upp_isr_bit_eoli);
}
if (intr_status & upp_isr_bit_eowi) //这个才算一次数据接收完成~~~~
{
upp_int_clear(upp_isr_bit_eowi);
upp_interrupt_count++;
/*
GPIOPinWrite(SOC_GPIO_0_REGS, 3, GPIO_PIN_LOW); // D10 灭 GPIO0[2]
GPIOPinWrite(SOC_GPIO_0_REGS, 1, GPIO_PIN_LOW); // D7 灭 GPIO0[0]
GPIOPinWrite(SOC_GPIO_0_REGS, 6, GPIO_PIN_LOW); // D6 灭 GPIO0[5]
GPIOPinWrite(SOC_GPIO_0_REGS, 2, GPIO_PIN_LOW); // D9 亮 GPIO0[1]
*/
}
if (intr_status & upp_isr_bit_erri) //这个算错误
{
upp_int_clear(upp_isr_bit_erri);
upp_error_count++;
}
if (intr_status & upp_isr_bit_uori) //这个算错误
{
upp_int_clear(upp_isr_bit_uori);
upp_error_count++;
}
if (intr_status & upp_isr_bit_dpei) //这个算错误
{
upp_int_clear(upp_isr_bit_dpei);
upp_error_count++;
}
// make sure all interrupts are handled
intr_status = upp_int_status();
}
// finally: write 0 to EOI register
upp_reg_hdl->UPEOI = 0;
}
Tony Tang:
贴子写这么长,还不如把源码文件贴到附件里。
victor sun1
#pragma DATA_SECTION(upp_buffer_a,".RXUPP")short upp_buffer_a[upp_frame_size];//接收FPGA通过UPP发送来的大批量数据,初定为240064个short。
#pragma DATA_ALIGN(upp_buffer_a,8);//2015.12.29
后面这个DATA_ALIGN应该写到upp_buffer_a定义之前。
victor sun1Upp_Line_Num 为宏定义,固定为32,当配置该函数唯一的参数为20000的时候,是能够进入upp_end of window中断的,但是收到的数是错的,但是将该函数唯一的参数设置为16000的时候,既能够进入中断,并且接收的数据都是对的。此外,如果Upp_Line_Num 为宏定义,固定为64 ,UPP_LINE_SIZE 改为其他值收到的数据都不对。由于要传输的数据量较大,不得不提高UPP的行数,因为UPP_LINE_SIZE 不能超过32767。请问是什么原因,以下附上所有upp配置及调用,恳请指导,谢谢!
可以话,看一下数据错误的特点,是丢了数据而偏移了,还是别的。
不过我估计是丢数据了。你检查一下Underrun or Overflow (UOR) Event状态是不是置位了。
然后按TRM的33.2.6.3节做一下调整。
Victorsunhao:
回复 Tony Tang:
您好,upp部分内容是在TRM的31章吧,33讲的是usb相关驱动呀