⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fw_epmg.c

📁 ATMEL公司的demo程序,USB驱动程序,与识别片上flash,并进行枚举和操作.
💻 C
📖 第 1 页 / 共 2 页
字号:
  }
  else
  {
    // Data or Status phase
    if(fw_controlData.state == FW_STATE_START)
    {
      if( AT91F_UDP_EpStatus( USBDEV_BASE_UDP, FW_EP_CTRL ) &  USBDEV_UDP_TXCOMP )     // Data sent to host
      {
        // Send the next packet
        _i = fw_writeEndpoint(FW_EP_CTRL, fw_controlData.pData + fw_controlData.wCount,
        min(FW_EP0_MAXPACKET_SIZE,(fw_controlData.wLength - fw_controlData.wCount)));
        if((_i == 0) && (fw_controlData.wLength - fw_controlData.wCount != 0))
        {
        }
        else
        {
          if((fw_controlData.wLength - fw_controlData.wCount) < FW_EP0_MAXPACKET_SIZE) /* No more Data to transmit */
          {
            fw_controlData.state = FW_STATE_END;
            fw_controlData.pData = NULL;
          }
          fw_controlData.wCount += _i;
        }
      }

      if( AT91F_UDP_EpStatus( USBDEV_BASE_UDP, FW_EP_CTRL ) & USBDEV_UDP_RX_DATA_BK0 )  // Data received
      {
        USHORT _Read = 0;

        /* if the size of the transfer is longer than the max packet */
        if( _i >= FW_EP0_MAXPACKET_SIZE)
        {
          _Read = fw_readEndpoint(FW_EP_CTRL, fw_controlData.pData + fw_controlData.wCount);

          if (_Read == 0)
          {
            // End of SetupPhase
            goto EOSP;
          }

          fw_controlData.wCount += FW_EP0_MAXPACKET_SIZE;
        }
        /* last read */
        else
        {
          if( _i != 0)
          {
            _Read=fw_readEndpoint(FW_EP_CTRL, fw_controlData.pData + fw_controlData.wCount);
            if (_Read == 0)
            {
              // End of SetupPhase
              goto EOSP;
            }
            fw_controlData.wCount += _i;

  EOSP:     fw_controlData.wLength = 0;
            fw_controlData.wCount = 0;
            fw_controlData.state = FW_STATE_END;
            fw_controlData.pData = NULL;
          }
        }
      }
    }
    else  // received a OUT status phase
    {
      if( AT91F_UDP_EpStatus( USBDEV_BASE_UDP, FW_EP_CTRL ) & USBDEV_UDP_RX_DATA_BK0 )
      {
        if (fw_readEndpoint(FW_EP_CTRL,_buff)==0)
        {
          // receive a NULL packet, Status Phase
        }
      }
    }
  }
}


/*****************************************************************
*
* ROUTINE         fw_mainRxDone
*
*-----------------------------------------------------------------
*
* Purpose :
*     when something is received on main EP, put the data in the TBs
*
* Input parameters  : NONE
*
* Output parameters : NONE
*
* Global data : fw_TB      : array of the buffer IDs
*               fw_writeTB : TB currently used by the firmware
*
*****************************************************************/
void fw_mainRxDone(void)
{
  ULONG _len = 0;
  structTB *_TB,**_nextTB;

  _nextTB = fw_writeTB + 1;
  if(_nextTB > (fw_TB + (FW_TB_NUM - 1)))
  {
    _nextTB = fw_TB;
  }

  /* Check if two TB are marked not valid to overwrite data */
  if(!(fw_writeTB[0][0].status & FW_VBIT) && !(_nextTB[0][0].status & FW_VBIT))
  {
    /* Read the bytes received */
    _len = fw_readEndpoint(FW_EP_BULK_OUT, databuffer);
    _TB = fw_writeTB[0];
    /* Check if we effectively received data */
    if(_len != 0)
    {
      _len = fw_writeRxData(_len,databuffer);
    }
    else
    {
      if(_TB->length == 0)
      {
        /* If the len received is 0 and the TB is empty get out of the function,
        not to fill an empty TB */
        return;
      }
    }
  }
  /* if we must use the TB pool and it's full */
  else
  {
    /* Some data have been received and we can't write */
    /* So set a flag to retry the reception later */
    fw_deviceState |= FW_DS_TB_FULL | FW_DS_RX;

    TRACE_ERROR( "TB FULL\n\r");
  }

  /* Check if two TB are marked valid */
  if((fw_writeTB[0][0].status & FW_VBIT) || (_nextTB[0][0].status & FW_VBIT))
  {
    /* disable interrupt if we can't receive next time */
    AT91F_UDP_DisableIt( USBDEV_BASE_UDP, AT91C_UDP_EPINT2 ); // EP_BULK_OUT
    /* some data have been received and we can't write */
    /* So set a flag to retry the reception later */
    fw_deviceState |= FW_DS_RX;
  }
  else
  {
    /* enable interrupt we can receive next time */
    AT91F_UDP_EnableIt( USBDEV_BASE_UDP, AT91C_UDP_EPINT2 ); // EP_BULK_OUT
  }
}


/*****************************************************************
*
* ROUTINE   fw_mainTxDone
*
*-----------------------------------------------------------------
*
* Purpose :
*         called when something is transmitted by main EP,
*        pick data in the IN FIFO and transmit it
*
* Input parameters  : NONE
*
* Output parameters : NONE
*
* Global data : fw_fifoId      : ID of the IN FIFO
*               fw_deviceState : bit1 = 1 when TX on EP2
*
*****************************************************************/
void fw_mainTxDone(void)
{
  UCHAR i;

  if(fw_fifoId.NbOctetsLibres != (fw_fifoId.last - fw_fifoId.first))
  {
    for( i=0; i<FW_MAIN_EP_MAXPACKET_SIZE; i++ )
    {
      TxBuffer[i] = 0;
    }

    // Get the data out of the fifo and put them in the endpoint buffer
    fw_lastTxPacket = po_rngBufGet(&fw_fifoId,(char*)TxBuffer,FW_MAIN_EP_MAXPACKET_SIZE);
    fw_lastTxPacket = fw_writeEndpoint(FW_EP_BULK_IN,TxBuffer,fw_lastTxPacket);

    // Test if the FIFO is only 20% full
    if( (fw_deviceState & FW_DS_FIFO_FULL) && (po_rngNBytes(&fw_fifoId) < FW_IN_FIFO_EMPTY) )
    {
      fw_deviceState &= ~FW_DS_FIFO_FULL;
    }
  }
  else
  {
    // End of the transfer
    fw_deviceState &= ~FW_DS_TX;
    USB_TX = 1;
    /* if the last packet is a full packet we must send a zero length packet */
    // TODO
    //if(fw_fifoId.NbOctetsLibres == 0)
    //{
    //  fw_singleTransmit(0, 0);
    //}
  }
}


/*****************************************************************
*
* ROUTINE         fw_writeRxData
*
*-----------------------------------------------------------------
*
* Purpose :
*         write data in a valid TB
*
* Input parameters  : length     : length of data to write
*                     dataBuffer : data to write
*
* Output parameters : NONE
*
* Global data : fw_TB      : array of the buffer IDs
*               fw_writeTB : TB currently used by the firmware
*
*****************************************************************/
int fw_writeRxData(int length,UCHAR *dataBuffer)
{
  structTB *_TB;
  ULONG _i = 0;
  long *_sizeTB,*_indexTB;

  _TB = fw_writeTB[0];
  _indexTB =&_TB->index; /* pointer to the current write position */
  _sizeTB = &_TB->length; /* pointer to the size field */

  /* check if the current TB was Empty */
  if(_TB->status & FW_EBIT)
  {
    _TB->status &= ~FW_EBIT;
  }

  /* if the TB isn't large enough pass to the next TB */
  if(length > (FW_TB_SIZE - *_sizeTB) )
  {
    fw_writeTB++;
    if(fw_writeTB > (fw_TB + (FW_TB_NUM - 1)))
    {
      fw_writeTB = fw_TB;
    }
    /* fill the current TB */
    _i = FW_TB_SIZE - (*_sizeTB);
    po_memcpy(&_TB->data[(*_indexTB)],dataBuffer,_i);

    *_sizeTB = FW_TB_SIZE;
    *_indexTB = 0;
    /* validate the TB */
    _TB->status |= FW_VBIT;
    USB_RX++;
    /* put the other data in the next TB */
    _TB = fw_writeTB[0];
    _indexTB =  &_TB->index;
    _sizeTB = &_TB->length;
    if(!(_TB->status & FW_VBIT))
    {
      fw_writeTB++;
      if(fw_writeTB > (fw_TB + (FW_TB_NUM - 1)))
      {
        fw_writeTB = fw_TB;
      }
      po_memcpy(&_TB->data[(*_indexTB)],(char*)(dataBuffer + _i),(length - _i));
      *_sizeTB = (length - _i);
      *_indexTB = 0;
      _TB->status |= FW_VBIT;
      USB_RX++;
      /* call the driver to update the actual data in the valid TBs
      * TB is full */
    }
    else
    {
      /* we lose data */
      length = _i;
    }
    /* check if the current TB was Empty */
    if(_TB->status & FW_EBIT)
    {
      _TB->status &= ~FW_EBIT;
    }
  }
  else
  {
    fw_writeTB++;
    if(fw_writeTB > (fw_TB + (FW_TB_NUM - 1)))
    {
      fw_writeTB = fw_TB;
    }
    po_memcpy(&_TB->data[*_indexTB],(char*)dataBuffer,length);
    *_sizeTB = length;
    *_indexTB = 0;
    _TB->status |= FW_VBIT;
    USB_RX++;
  }
  return length;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -