📄 usbhostslavetb.cpp
字号:
/***************************************************************************
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 + -