打印

求助:GPIF固件中FIFO读的问题。急急。在线等。

[复制链接]
3811|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fshuangy|  楼主 | 2011-10-10 09:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
固件中有段代码如下:

// GPIF address pins update when GPIFADRH/L written
  SYNCDELAY;                    //
  GPIFADRH = 0x00;    // bits[7:1] always 0
  SYNCDELAY;                    //
  GPIFADRL = 0x00;    // point to PERIPHERAL address 0x0000

上面的意思是说指向了外设的地址0000。
固件中将端点6配置为了AUTO IN模式,每次从外设中读512个BYTE的数据,但调试过程中发现,512个数据都是地址0000上的数据,数据线的电平也没变化,地址没有自动加1.  将地址改为0001之后,读到的512个数据都是0001上的 。

请教:我理解在AUTO IN情况下,应该能读到连续地址上的数据,为什么现在只能读  到单个地址上的数据?

相关帖子

沙发
dqyubsh| | 2011-10-10 10:40 | 只看该作者
程序太短了,看不出哪是哪。

使用特权

评论回复
板凳
fshuangy|  楼主 | 2011-10-10 10:49 | 只看该作者
2# dqyubsh
这段是初始化GPIF模式
void GpifInit( void )
{
  BYTE i;

  // Registers which require a synchronization delay, see section 15.14
  // FIFORESET        FIFOPINPOLAR
  // INPKTEND         OUTPKTEND
  // EPxBCH:L         REVCTL
  // GPIFTCB3         GPIFTCB2
  // GPIFTCB1         GPIFTCB0
  // EPxFIFOPFH:L     EPxAUTOINLENH:L
  // EPxFIFOCFG       EPxGPIF标志寄存器SEL
  // PINFLAGSxx       EPxFIFOIRQ
  // EPxFIFOIE        GPIFIRQ
  // GPIFIE           GPIFADRH:L
  // UDMACRCH:L       EPxGPIFTRIG
  // GPIFTRIG
  
  // Note: The pre-REVE EPxGPIFTCH/L register are affected, as well...
  //      ...these have been replaced by GPIFTC[B3:B0] registers

  // 8051 doesn't have access to waveform memories 'til
  // the part is in GPIF mode.

  IFCONFIG = 0xCE;
  // IFCLKSRC=1   , FIFOs executes on internal clk source
  // xMHz=1       , 48MHz internal clk rate
  // IFCLKOE=0    , Don't drive IFCLK pin signal at 48MHz
  // IFCLKPOL=0   , Don't invert IFCLK pin signal from internal clk
  // ASYNC=1      , master samples asynchronous
  // GSTATE=1     , Drive GPIF states out on PORTE[2:0], debug WF
  // IFCFG[1:0]=10, FX2 in GPIF master mode

  GPIFABORT = 0xFF;  // abort any waveforms pending

  GPIFREADYCFG = InitData[ 0 ];
  GPIFCTLCFG = InitData[ 1 ];
  GPIFIDLECS = InitData[ 2 ];
  GPIFIDLECTL = InitData[ 3 ];
  GPIFWFSELECT = InitData[ 5 ];
  GPIFREADYSTAT = InitData[ 6 ];

  // use dual autopointer feature...
  AUTOPTRSETUP = 0x07;          // inc both pointers,
                                // ...warning: this introduces pdata hole(s)
                                // ...at E67B (XAUTODAT1) and E67C (XAUTODAT2)
  
  // source
  AUTOPTR1H = MSB( &WaveData );
  AUTOPTR1L = LSB( &WaveData );
  
  // destination
  AUTOPTRH2 = 0xE4;
  AUTOPTRL2 = 0x00;

  // transfer
  for ( i = 0x00; i < 128; i++ )
  {
    EXTAUTODAT2 = EXTAUTODAT1;
  }

// Configure GPIF Address pins, output initial value,
  PORTCCFG = 0xFF;    // [7:0] as alt. func. GPIFADR[7:0]
  OEC = 0xFF;         // and as outputs
  PORTECFG |= 0x80;   // [8] as alt. func. GPIFADR[8]
  OEE |= 0x80;        // and as output

// ...OR... tri-state GPIFADR[8:0] pins
//  PORTCCFG = 0x00;  // [7:0] as port I/O
//  OEC = 0x00;       // and as inputs
//  PORTECFG &= 0x7F; // [8] as port I/O
//  OEE &= 0x7F;      // and as input

// GPIF address pins update when GPIFADRH/L written
  SYNCDELAY;                    //
  GPIFADRH = 0x00;    // bits[7:1] always 0
  SYNCDELAY;                    //
  GPIFADRL = 0x00;    // point to PERIPHERAL address 0x0000

// Configure GPIF FlowStates registers for Wave 0 of WaveData
  FLOWSTATE = FlowStates[ 0 ];
  FLOWLOGIC = FlowStates[ 1 ];
  FLOWEQ0CTL = FlowStates[ 2 ];
  FLOWEQ1CTL = FlowStates[ 3 ];
  FLOWHOLDOFF = FlowStates[ 4 ];
  FLOWSTB = FlowStates[ 5 ];
  FLOWSTBEDGE = FlowStates[ 6 ];
  FLOWSTBHPERIOD = FlowStates[ 7 ];


这段是读的功能:

  if(in_enable)                             // if IN transfers are enabled
  {
    if ( GPIFTRIG & 0x80 )                  // if GPIF interface IDLE
    {
      if ( EXTFIFONOTEMPTY )                // if external FIFO is not empty
   {
     if ( !( EP68FIFO标志寄存器S & 0x01 ) )     // if EP6 FIFO is not full
  {      
          if(enum_high_speed)
    {
         SYNCDELAY;   
            GPIFTCB1 = 0x01;                // setup transaction count (512 bytes/2 for word wide -> 0x0100)
            SYNCDELAY;
            GPIFTCB0 = 0x00;
            SYNCDELAY;
    }
    else
    {
      SYNCDELAY;
      GPIFTCB1 = 0x00;                // setup transaction count (64 bytes/2 for word wide -> 0x20)
            SYNCDELAY;
      GPIFTCB0 = 0x20;
      SYNCDELAY;
    }
  
       Setup_FLOWSTATE_Read();           // setup FLOWSTATE registers for FIFO Read operation
          SYNCDELAY;
          GPIFTRIG = GPIFTRIGRD | GPIF_EP6; // launch GPIF FIFO READ Transaction to EP6 FIFO
       SYNCDELAY;
       while( !( GPIFTRIG & 0x80 ) )     // poll GPIFTRIG.7 GPIF Done bit
          {
            ;
          }

void Setup_FLOWSTATE_Read ( void )
{
   FLOWSTATE = FlowStates[18];  // 1000 0011b - FSE=1, FS[2:0]=003
   SYNCDELAY;
   FLOWEQ0CTL = FlowStates[20]; // CTL1/CTL2 = 0 when flow condition equals zero (data flows)
   SYNCDELAY;
   FLOWEQ1CTL = FlowStates[21]; // CTL1/CTL2 = 1 when flow condition equals one (data does not flow)
   SYNCDELAY;
}
}

使用特权

评论回复
地板
dqyubsh| | 2011-10-10 11:37 | 只看该作者
初始化中的设置GPIFADRH/L语句仅有示范作用,是把16条数据总线ADR15:0都写成0,具体的意义要与你的外设对应。

不知道你后边的接的什么外设,这个时序和次序要符合外设的要求。它可能对应外设的地址端口,也可能对应外设的数据端口,使用时要区别对待。如果这16条线是固定的,你可以不变,如果不是,你要及时更改它。

在循环中写的比较象了,但是,还是不地道,你仔细对照cypess给例子,照样扒下来就可以了。测试的方法,也依照官方的手法。

GPIFTCB寄存器的长度是启动波形的次数(不确定了,有点忘了), =0X100,是256次,这个长度可能没有完全填充FIFO,FIFO没满,这是不好的,你至少要变成512字节(或者倍数),或者用废数据填满,或者强制完成。

这里要提醒的是,初始化GPIF的时候,特别注意你接了16位总线还是8位总线,这个一定要正确。

至于FLOWSTAT,我理解,那些流状态管脚,不用你去设置,是根据GPIF波形自动生成的。你用示波器监视这几个管脚,就可以知道固件当前运行的是哪个GPIF波形。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

75

帖子

2

粉丝