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

📄 usbhostslavetb.cpp

📁 包括USB
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************
                          usbHostSlaveTB.cpp  -  description
                             -------------------
    begin                : Mon Sep 25 2006
    copyright            : (C) 2006 by Steve Fielding
    email                : sfielding@base2designs.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
#include "condCompileFlags.h"

#ifdef SYSTEMC_TB
#include "systemc.h"
#include "transactor.h"
#else
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#ifdef UCLINUX_TB
#else
#include "altera_avalon_pio_regs.h"
#include "hw_address_defines.h"
#include "system.h"
#endif
#include "bus_if.h"
#endif

#include "usbHostSlaveTB.h"
#include "usbHostSlaveMemMap.h"
#include "usbSIEConstants.h"
#include "usbFifoConstants.h"

#define VERBOSE_PRINT
#ifdef VERBOSE_PRINT
#define PRT(stuff...)   cout << stuff
#else
#define PRT(stuff...)   do{}while(0)
#endif

/* ------------------------------- main ---------------------------------- */
void usbHostSlaveTB::main()
{
  int i;
  int tempDataFromHost;
  int tempDataFromHost2;
  int USBEndPoint;
  int USBAddress;
  int dataPacketSize;
  int versionNum;
  int fullSpeedRate;
  int firstFrameNumMSB;
  int firstFrameNumLSB;
  int expectedFrameNum;

  cout << "-------- usbHostSlave TestBench ---------\n";
  systemRstCtrl();
  usbLineControl(SE0);       //set default line state
  waitUSBClockTicks(30);     //allow time for reset to propagate, especially re-sync'd resets
  hostBusRead(versionNum, RA_HOST_SLAVE_VERSION);
  printf("Host Version number = %2d.%1d\n", (versionNum >> 4) & 0xf, versionNum & 0xf);
  slaveBusRead(versionNum, RA_HOST_SLAVE_VERSION);
  printf("Slave Version number = %2d.%1d\n", (versionNum >> 4) & 0xf, versionNum & 0xf);


  cout << "Register write/read test...\n";
  hostBusWrite(1, HOST_SLAVE_CONTROL_BASE);  //set host mode
  slaveBusWrite(0, HOST_SLAVE_CONTROL_BASE);  //set slave mode
  writeXCReg(HOST, 0x18, TX_LINE_CONTROL_REG);  //full speed polarity and bit rate, direct control off, line state don't care
  writeXCReg(SLAVE, 0x30, SC_CONTROL_REG);  //full speed polarity and bit rate, direct control off, line state don't care, global enable off
  waitUSBClockTicks(2);
  readXCReg(HOST, tempDataFromHost, HOST_SLAVE_CONTROL_BASE, 1, 0xff);
  readXCReg(HOST, tempDataFromHost, TX_LINE_CONTROL_REG, 0x18, 0xff);
  readXCReg(SLAVE, tempDataFromHost, SC_CONTROL_REG, 0x30, 0xff);
  
  cout << "Reset register test...\n";
  hostBusWrite(2, HOST_SLAVE_CONTROL_BASE);  //reset first usbhostslave instance
  slaveBusWrite(2, HOST_SLAVE_CONTROL_BASE);  //reset second usbhostslave instance
  waitUSBClockTicks(30);  //allow time for logic to reset
  readXCReg(HOST, tempDataFromHost, HOST_SLAVE_CONTROL_BASE, 0, 0xff);
  readXCReg(HOST, tempDataFromHost, TX_LINE_CONTROL_REG, 0x0, 0xff);
  readXCReg(SLAVE, tempDataFromHost, SC_CONTROL_REG, 0x00, 0xff);
  
  //Configure usbhostslave instances as host and slave 
  hostBusWrite(1, HOST_SLAVE_CONTROL_BASE);  //set host mode
  writeXCReg(HOST, 0x18, TX_LINE_CONTROL_REG);  //full speed polarity and bit rate, direct control off, line state don't care
  slaveBusWrite(0, HOST_SLAVE_CONTROL_BASE); //set slave mode
  writeXCReg(SLAVE, 0x30, SC_CONTROL_REG);  //full speed polarity and bit rate, direct control off, line state don't care, global enable off

  //disconnect
  cout << "\nDisconnecting...\n";
  connection(SE0, DISCONNECT_WAIT_TIME*32, 0, 0);     //set default line state to single ended zero, ie disconnect

  //connect low speed
  cout << "\nConnecting low speed...\n";
  connection(ZERO_ONE, CONNECT_WAIT_TIME*32, 1, 1);     //set default line state to ZERO_ONE, ie connect low speed

  //disconnect
  cout << "\nDisconnecting...\n";
  connection(SE0, DISCONNECT_WAIT_TIME*32, 1, 1);     //set default line state to single ended zero, ie disconnect

  //connect full speed
  cout << "\nConnecting full speed...\n";
  connection(ONE_ZERO, CONNECT_WAIT_TIME*4, 1, 1);     //set default line state to ONE_ZERO, ie connect full speed

  //host forces a reset
  cout << "\nHost forcing reset...\n";
  writeXCReg(HOST, 0x1c, TX_LINE_CONTROL_REG);  //full speed polarity and bit rate, direct control on, line state SE0
  waitUSBClockTicks(DISCONNECT_WAIT_TIME*4+100);
  readXCReg(SLAVE, tempDataFromHost, SC_INTERRUPT_STATUS_REG, (1 << SC_RESET_EVENT_BIT), 0xff);
  readXCReg(SLAVE, tempDataFromHost2, SC_LINE_STATUS_REG, DISCONNECT, 0xff);
  printf("SISR = 0x%0x, slave line state = 0x%0x \n", tempDataFromHost, tempDataFromHost2);
  cout << "Cancel reset event interrupt\n";

  cancelInterrupt(SLAVE, SC_RESET_EVENT_BIT);

  //re-connect at full speed
  writeXCReg(HOST, 0x18, TX_LINE_CONTROL_REG);  //full speed polarity and bit rate, direct control off, line state don't care
  cout << "Reconnecting at full speed...\n";
  connection(ONE_ZERO, CONNECT_WAIT_TIME*4, 0, 1);     //set default line state to ONE_ZERO, ie connect full speed

  //slave forces a disconnect
  cout << "\nSlave forcing disconnect...\n";
  writeXCReg(SLAVE, 0x38, SC_CONTROL_REG);  //full speed polarity and bit rate, direct control on, line state SE0, global enable off
  waitUSBClockTicks(DISCONNECT_WAIT_TIME*4+100);
  readXCReg(HOST, tempDataFromHost, INTERRUPT_STATUS_REG, (1 << CONNECTION_EVENT_BIT), 0xff);
  readXCReg(HOST, tempDataFromHost2, RX_CONNECT_STATE_REG, DISCONNECT, 0xff);
  printf("HISR =  0x%0x, host line state = 0x%0x\n", tempDataFromHost, tempDataFromHost2);
  cout << "Cancel host interrupt\n";
  cancelInterrupt(HOST, CONNECTION_EVENT_BIT);

  //re-connect at full speed
  writeXCReg(SLAVE, 0x30, SC_CONTROL_REG);  //full speed polarity and bit rate, direct control off, line state don't care, global enable off
  cout << "Reconnecting at full speed...\n";
  connection(ONE_ZERO, CONNECT_WAIT_TIME*4+100, 1, 0);     //set default line state to ONE_ZERO, ie connect full speed

  //Enable host SOF transmission (forces a resume)
  //Note that the resume transmission mechanism is different for host and slave
  //Notably when the host transmits resume, it will transmit 'RESUME_LEN' KBits
  //without any time progression (ie within delta cycles), whereas the slave
  //transmits resume as a direct line control at a rate of one byte per fake timing event
  cout << "\nEnabling host SOF transmission\n";
  writeXCReg(HOST, 0x1, TX_SOF_ENABLE_REG); //enable SOF transmission
  waitUSBClockTicks(RESUME_WAIT_TIME*32+100);
  cout << "Checking for resume interrupt...\n";
  readXCReg(SLAVE, tempDataFromHost2, SC_INTERRUPT_STATUS_REG, (1 << SC_RESUME_INT_BIT), 0xff);  //check for resume interrupt
  printf("HISR =  0x%0x, SISR = 0x%0x\n" ,tempDataFromHost, tempDataFromHost2);
  cancelInterrupt(SLAVE, SC_RESUME_INT_BIT);
  cout << "Checking for SOF packets...\n";
  for (i=0;i<=1;i++) {
    slaveBusRead(tempDataFromHost, SCREG_BASE + SC_INTERRUPT_STATUS_REG);
    while ( tempDataFromHost == 0) {
      waitUSBClockTicks(SOF_TX_TIME*4);
      slaveBusRead(tempDataFromHost, SCREG_BASE + SC_INTERRUPT_STATUS_REG);
    }
    cancelInterrupt(SLAVE, SC_SOF_RECEIVED_BIT);
    if (i == 0) {
      readXCReg(SLAVE, tempDataFromHost, SC_FRAME_NUM_MSP, ((i % 2048) / 256) , 0x00);
      readXCReg(SLAVE, tempDataFromHost2, SC_FRAME_NUM_LSP, (i % 256), 0x00);
      firstFrameNumMSB = tempDataFromHost;
      firstFrameNumLSB = tempDataFromHost2;
    }
    else {
      expectedFrameNum = i + (firstFrameNumMSB * 256) + firstFrameNumLSB; 
      readXCReg(SLAVE, tempDataFromHost, SC_FRAME_NUM_MSP, ((expectedFrameNum % 2048) / 256) , 0xff);
      readXCReg(SLAVE, tempDataFromHost2, SC_FRAME_NUM_LSP, (expectedFrameNum % 256), 0xff);
    } 
    printf("SOF Frame count %d = 0x%0x\n", i, (tempDataFromHost * 256) + tempDataFromHost2);
    readXCReg(HOST, tempDataFromHost, SOF_TIMER_MSB_REG, 0x0, 0x0);
    printf("Host SOF Timer MSB = 0x%0x\n", tempDataFromHost);
  }
  cout << "Disabling SOF transmission\n";
  writeXCReg(HOST, 0x0, TX_SOF_ENABLE_REG); //disable SOF transmission
  waitUSBClockTicks(RESUME_LEN*4+100); //wait for last SOF to be flushed out
  cout << "For slave, cancel resume interrupt, and SOF received interrupt\n";
  cout << "For host, cancel SOF sent interrupt\n";
  readXCReg(HOST, tempDataFromHost, INTERRUPT_STATUS_REG, (1 << SOF_SENT_BIT) , 0xff);
  cancelInterrupt(HOST, SOF_SENT_BIT);
  cancelInterrupt(SLAVE, SC_RESUME_INT_BIT);
  cancelInterrupt(SLAVE, SC_SOF_RECEIVED_BIT);

  //Slave forces resume
  cout << "\nSlave forcing resume...\n";
  writeXCReg(SLAVE, 0x3a, SC_CONTROL_REG);  //full speed polarity and bit rate, direct control on, line state ZERO_ONE (full speed resume), global enable off
  waitUSBClockTicks(RESUME_WAIT_TIME*32+100);

  readXCReg(HOST, tempDataFromHost, INTERRUPT_STATUS_REG, (1 << RESUME_INT_BIT), 0xff);
  readXCReg(HOST, tempDataFromHost2, RX_CONNECT_STATE_REG, FULL_SPEED_CONNECT, 0xff);
  printf("HISR = 0x%0x , host line state = 0x%0x \n", tempDataFromHost, tempDataFromHost2);
  cout << "Cancel resume interrupt\n";
  cancelInterrupt(HOST, RESUME_INT_BIT);
  writeXCReg(SLAVE, 0x30, SC_CONTROL_REG);  //full speed polarity and bit rate, direct control off, line state don't care, global enable off
  waitUSBClockTicks(10*4); //wait for some idle bits to be sent
  readXCReg(HOST, tempDataFromHost, RX_CONNECT_STATE_REG, FULL_SPEED_CONNECT, 0xff);
  printf("Resume recovery check , host line state = 0x%0x\n", tempDataFromHost);

  cout << "\nTransaction tests...\n";
  //set up some variables and pointers used for send transaction tests
  writeXCReg(SLAVE, 0x31, SC_CONTROL_REG);  //full speed polarity and bit rate, direct control off, line state don't care, global enable on
  fullSpeedRate = 1;
    
  for (USBAddress = 0; USBAddress <=127; USBAddress = USBAddress + 127) {
  //for (USBAddress = 0; USBAddress <=127; USBAddress = USBAddress + 1) {
    writeXCReg(SLAVE, USBAddress, SC_ADDRESS);       //set slave usb address
    for (dataPacketSize = 0; dataPacketSize <= SMALLEST_FIFO_SIZE; dataPacketSize = dataPacketSize+64) {
    //for (dataPacketSize = 1; dataPacketSize <= SMALLEST_FIFO_SIZE; dataPacketSize = dataPacketSize+1) {
      for (USBEndPoint = 0; USBEndPoint <=3; USBEndPoint++) {
        PRT("\n------------------------------------\n");
        //PRT("USBAddress = %d  USBEndPoint = %d \n", USBAddress, USBEndPoint);
        PRT("USBAddress = " << USBAddress << " USBEndPoint = " << USBEndPoint << endl);
        PRT("------------------------------------\n");

        //SETUP - NAK'd
        PRT("\nNAK'd SETUP\n");
        sendTransaction(USBAddress, USBEndPoint, SETUP_TRANS, dataPacketSize, RAND_GEN, 1, (1 << ENDPOINT_ENABLE_BIT), fullSpeedRate);

        //SETUP - ACK'd
        PRT("\nACK'd SETUP\n");
        sendTransaction(USBAddress, USBEndPoint, SETUP_TRANS, dataPacketSize, RAND_GEN, 1, 0x3, fullSpeedRate);

        //SETUP - STALL'd
        PRT("\nSTALL'd SETUP\n");
        sendTransaction(USBAddress, USBEndPoint, SETUP_TRANS, dataPacketSize, SEQ_GEN, 1, 0xb, fullSpeedRate);

        //SETUP - timed out
        PRT("\nTimed out SETUP\n");
        sendTransaction(USBAddress, USBEndPoint, SETUP_TRANS, dataPacketSize, RAND_GEN, 1, 0x0, fullSpeedRate);

        //OUTDATA0 - ACK'd
        PRT("\nACK'd OUTDATA0\n");
        sendTransaction(USBAddress, USBEndPoint, OUTDATA0_TRANS, dataPacketSize, RAND_GEN, 1, 0x3, fullSpeedRate);

        //OUTDATA1 - ACK'd
        PRT("\nACK'd OUTDATA1\n");
        sendTransaction(USBAddress, USBEndPoint, OUTDATA1_TRANS, dataPacketSize, RAND_GEN, 1, 0x3, fullSpeedRate);

        //OUTDATA1 - NAK'd
        PRT("\nNAK'd OUTDATA1\n");
        sendTransaction(USBAddress, USBEndPoint, OUTDATA1_TRANS, dataPacketSize, RAND_GEN, 1, (1 << ENDPOINT_ENABLE_BIT), fullSpeedRate);

        //INDATA (DATA0) - ACK'd
        PRT("\nACK'd INDATA (DATA0)\n");
        rxTransaction(USBAddress, USBEndPoint, IN_TRANS, dataPacketSize, RAND_GEN, 1, 0x3);

        //INDATA (DATA1) - ACK'd
        PRT("\nACK'd INDATA (DATA1)\n");

        rxTransaction(USBAddress, USBEndPoint, IN_TRANS, dataPacketSize, RAND_GEN, 1, 0x7);

        //INDATA (DATA0) - NAK'd
        PRT("\nNAK'd INDATA (DATA0)\n");
        rxTransaction(USBAddress, USBEndPoint, IN_TRANS, dataPacketSize, RAND_GEN, 1, (1 << ENDPOINT_ENABLE_BIT));

        //INDATA (DATA0) - Timed out
        PRT("\nTimed out INDATA (DATA0)\n");
        rxTransaction(USBAddress, USBEndPoint, IN_TRANS, dataPacketSize, RAND_GEN, 1, 0x0);
      }
    }
  }

#define TEST_ISO_MODE
#ifdef TEST_ISO_MODE
  writeXCReg(SLAVE, 0, SC_ADDRESS);       //set slave usb address
  //OUT0 - ISO
  cout << "\nISO OUT0\n";
  sendTransaction(0, 0, OUTDATA0_TRANS, 64, RAND_GEN, 1, 0x13, 1); 

#endif

#define DEBUG_LS
#ifdef DEBUG_LS
  //disconnect
  cout << "\nDisconnecting...\n";
  connection(SE0, DISCONNECT_WAIT_TIME*4, 1, 1);
  //connect low speed
  cout << "\nConnecting low speed...\n";
  connection(ZERO_ONE, CONNECT_WAIT_TIME*32, 1, 1);     //set default line state to ONE_ZERO, ie connect low speed
  writeXCReg(SLAVE, 0x1, SC_CONTROL_REG);  //low speed polarity and bit rate, direct control off, line state don't care, global enable on
  writeXCReg(HOST, 0x0, TX_LINE_CONTROL_REG);  //low speed polarity and bit rate, direct control off, line state don't care

⌨️ 快捷键说明

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