📄 usbhostslavetb.cpp
字号:
writeXCReg(SLAVE, 0, SC_ADDRESS); //set slave usb address
//SETUP - ACK'd
cout << "\nLow Speed ACK'd SETUP\n";
sendTransaction(0, 0, SETUP_TRANS, 64, RAND_GEN, 1, 0x3, 0);
#endif
cout << "\n-----------------------------------------------\n";
cout << "USBHostSlave verification completed successfully\n";
quit(0);
}
/* ------------------------------- connection ---------------------------------- */
void usbHostSlaveTB::connection(int lineState, int waitTime, int hostInterruptExpected, int slaveInterruptExpected)
{
int tempDataFromHost;
int tempDataFromHost2;
int expectedData;
int expectedConnectState;
if (lineState == ZERO_ONE) {
expectedConnectState = LOW_SPEED_CONNECT;
writeXCReg(HOST, 0x00, TX_LINE_CONTROL_REG); //low speed polarity and bit rate, direct control off, line state don't care
writeXCReg(SLAVE, 0x00, SC_CONTROL_REG); //low speed polarity and bit rate, direct control off, line state don't care, global enable off
}
else if (lineState == ONE_ZERO) {
expectedConnectState = FULL_SPEED_CONNECT;
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
}
else if (lineState == SE0) expectedConnectState = DISCONNECT;
else expectedConnectState = DISCONNECT;
usbLineControl(lineState); //set default line state
waitUSBClockTicks(waitTime+100); //allow 'waitTime' samples to be clocked through
if (hostInterruptExpected)
expectedData = (1 << CONNECTION_EVENT_BIT);
else
expectedData = 0x0;
readXCReg(HOST, tempDataFromHost, INTERRUPT_STATUS_REG, expectedData, (1 << CONNECTION_EVENT_BIT) );
readXCReg(HOST, tempDataFromHost2, RX_CONNECT_STATE_REG, expectedConnectState, 0xff);
printf("Host interrupt status reg (HISR) = 0x%0x , host line state = 0x%0x \n", tempDataFromHost, tempDataFromHost2);
if (slaveInterruptExpected)
expectedData = (1 << SC_RESET_EVENT_BIT);
else
expectedData = 0x0;
readXCReg(SLAVE, tempDataFromHost, SC_INTERRUPT_STATUS_REG, expectedData , (1 << SC_RESET_EVENT_BIT) );
readXCReg(SLAVE, tempDataFromHost2, SC_LINE_STATUS_REG, expectedConnectState, 0xff );
printf("Slave interrupt status reg (SISR) = 0x%0x , slave line state = 0x%0x \n", tempDataFromHost, tempDataFromHost2);
cout << "Cancel interrupts\n";
cancelInterrupt(HOST, CONNECTION_EVENT_BIT);
cancelInterrupt(SLAVE, SC_RESET_EVENT_BIT);
}
/* ------------------------------- cancelInterrupt ---------------------------------- */
void usbHostSlaveTB::cancelInterrupt(int hostSlaveSel, int interruptBit)
{
int tempDataFromHost;
if (hostSlaveSel == HOST) {
writeXCReg(HOST, 1 << interruptBit, INTERRUPT_STATUS_REG);
readXCReg(HOST, tempDataFromHost, INTERRUPT_STATUS_REG, 0x0, (1 << interruptBit) );
}
else {
writeXCReg(SLAVE, 1 << interruptBit, SC_INTERRUPT_STATUS_REG);
readXCReg(SLAVE, tempDataFromHost, SC_INTERRUPT_STATUS_REG, 0x0, (1 << interruptBit) );
}
}
/* ------------------------------- readXCRegNoQuit ---------------------------------- */
void usbHostSlaveTB::readXCRegNoQuit(int hostSlaveSel, int &rxedData, int regOffset, int expectedData, int rxDataMask, int &errorDetected)
{
if (hostSlaveSel == HOST) {
hostBusRead(rxedData, HCREG_BASE + regOffset);
if ( (rxedData & rxDataMask) != expectedData) {
errorDetected = 1;
printf("HCReg[0x%0x] & mask = (0x%0x & 0x%0x) = 0x%0x , expecting 0x%0x \n", regOffset, rxedData, rxDataMask, (rxedData & rxDataMask), expectedData);
}
}
else {
slaveBusRead(rxedData, SCREG_BASE + regOffset);
if ( (rxedData & rxDataMask) != expectedData) {
errorDetected = 1;
printf("SCReg[0x%0x] & mask = (0x%0x & 0x%0x) = 0x%0x , expecting 0x%0x \n", regOffset, rxedData, rxDataMask, (rxedData & rxDataMask), expectedData);
}
}
}
/* ------------------------------- readXCReg ---------------------------------- */
void usbHostSlaveTB::readXCReg(int hostSlaveSel, int &rxedData, int regOffset, int expectedData, int rxDataMask)
{
if (hostSlaveSel == HOST) {
hostBusRead(rxedData, HCREG_BASE + regOffset);
if ( (rxedData & rxDataMask) != expectedData) {
printf("HCReg[0x%0x] & mask = (0x%0x & 0x%0x) = 0x%0x , expecting 0x%0x \n", regOffset, rxedData, rxDataMask, (rxedData & rxDataMask), expectedData);
quit(1);
}
}
else {
slaveBusRead(rxedData, SCREG_BASE + regOffset);
if ( (rxedData & rxDataMask) != expectedData) {
printf("SCReg[0x%0x] & mask = (0x%0x & 0x%0x) = 0x%0x , expecting 0x%0x \n", regOffset, rxedData, rxDataMask, (rxedData & rxDataMask), expectedData);
quit(1);
}
}
}
/* ------------------------------- writeXCReg ---------------------------------- */
void usbHostSlaveTB::writeXCReg(int hostSlaveSel, int data, int regOffset)
{
if (hostSlaveSel == HOST)
hostBusWrite(data, HCREG_BASE + regOffset);
else
slaveBusWrite(data, SCREG_BASE + regOffset);
}
/* ------------------------------- sendTransaction ---------------------------------- */
void usbHostSlaveTB::sendTransaction(int USBAddress, int USBEndPoint, int transType, int dataSize, int dataGenType, int waitTime, int endPControlReg, int fullSpeedRate)
{
int i;
int endPointStatusRegAddress;
int endPointControlRegAddress;
int endPointTransTypeRegAddress;
int endPointNAKTransTypeRegAddress;
int tempDataFromHost;
int tempDataFromHost2;
int fifoBaseAddress;
int expectedTransTypeAtSlave;
int numOfElementsInRXFifo;
int data [LARGEST_FIFO_SIZE];
int dataSeqeunceBit;
int expectedDataCnt;
int errorDetected;
errorDetected = 0;
switch (dataGenType)
{
case NO_GEN:
//data payload provided by caller. Do nothing
break;
case SEQ_GEN:
for (i=0;i<dataSize;i++)
data[i] = i;
break;
case RAND_GEN:
for (i=0;i<dataSize;i++)
data[i] = rand() & 0xff;
break;
default:
printf("(sendTransaction) dataGenType = 0x%0x not a valid type\n", dataGenType);
quit(1);
break;
}
dataSeqeunceBit = 0;
switch (transType)
{
case SETUP_TRANS:
PRT("SETUP");
expectedTransTypeAtSlave = SC_SETUP_TRANS;
break;
case OUTDATA1_TRANS:
dataSeqeunceBit = 1 << SC_DATA_SEQUENCE_BIT;
PRT("OUTDATA1");
expectedTransTypeAtSlave = SC_OUTDATA_TRANS;
break;
case OUTDATA0_TRANS:
PRT("OUTDATA0");
expectedTransTypeAtSlave = SC_OUTDATA_TRANS;
break;
default:
printf("sendTransaction - Invalid transactionType 0x%0x aborting\n", transType);
quit(1);
break;
}
PRT(" transaction, with a " << dataSize << " byte data packet\n");
switch (USBEndPoint)
{
case 0:
fifoBaseAddress = EP0_RX_FIFO_BASE;
break;
case 1:
fifoBaseAddress = EP1_RX_FIFO_BASE;
break;
case 2:
fifoBaseAddress = EP2_RX_FIFO_BASE;
break;
case 3:
fifoBaseAddress = EP3_RX_FIFO_BASE;
break;
default:
printf("Invalid endpoint %d \n", USBEndPoint);
quit(1);
break;
}
endPointControlRegAddress = (NUM_OF_REGISTERS_PER_ENDPOINT * USBEndPoint) + ENDPOINT_CONTROL_REG;
endPointStatusRegAddress = (NUM_OF_REGISTERS_PER_ENDPOINT * USBEndPoint) + ENDPOINT_STATUS_REG;
endPointTransTypeRegAddress = (NUM_OF_REGISTERS_PER_ENDPOINT * USBEndPoint) + ENDPOINT_TRANSTYPE_STATUS_REG;
endPointNAKTransTypeRegAddress = (NUM_OF_REGISTERS_PER_ENDPOINT * USBEndPoint) + NAK_TRANSTYPE_STATUS_REG;
writeXCReg(SLAVE, endPControlReg, endPointControlRegAddress);
writeXCReg(HOST, USBAddress, TX_ADDR_REG);
writeXCReg(HOST, USBEndPoint, TX_ENDP_REG);
writeXCReg(HOST, transType, TX_TRANS_TYPE_REG);
for (i=0; i<dataSize; i++)
hostBusWrite(data[i], HOST_TX_FIFO_BASE + FIFO_DATA_REG);
if ((endPControlReg & (1 << ENDPOINT_ISO_ENABLE_BIT)) == 0) //if not iso mode
writeXCReg(HOST, (1 << TRANS_REQ_BIT), TX_CONTROL_REG); //then
else
//writeXCReg(HOST, (1 << TRANS_REQ_BIT) & (1 << ISO_ENABLE_BIT), TX_CONTROL_REG);
writeXCReg(HOST, 0x9, TX_CONTROL_REG);
if (fullSpeedRate == 1)
waitUSBClockTicks(500+dataSize*100); //suspend test bench so that DUT can process the packet
else
waitUSBClockTicks(20000+dataSize*4000); //suspend test bench so that DUT can process the packet
readXCReg(HOST, tempDataFromHost, INTERRUPT_STATUS_REG, (1 << TRANS_DONE_BIT), 0xff);
expectedDataCnt = 0;
if ( (endPControlReg & (1 << ENDPOINT_ENABLE_BIT) ) != 0) {
if ( (endPControlReg & (1 << ENDPOINT_READY_BIT) ) != 0) {
expectedDataCnt = dataSize;
readXCReg(SLAVE, tempDataFromHost, SC_INTERRUPT_STATUS_REG, (1 << SC_TRANS_DONE_BIT), 0xff);
readXCReg(SLAVE, tempDataFromHost, endPointTransTypeRegAddress, expectedTransTypeAtSlave, 0xff); //expecting 'expectedTransTypeAtSlave' transaction
}
else {
readXCReg(SLAVE, tempDataFromHost, SC_INTERRUPT_STATUS_REG, (1 << SC_NAK_SENT_INT_BIT), 0xff);
readXCReg(SLAVE, tempDataFromHost, endPointNAKTransTypeRegAddress, expectedTransTypeAtSlave, 0xff); //expecting 'expectedTransTypeAtSlave' transaction
}
}
slaveBusRead(tempDataFromHost, fifoBaseAddress + FIFO_DATA_COUNT_MSB);
slaveBusRead(tempDataFromHost2, fifoBaseAddress + FIFO_DATA_COUNT_LSB);
numOfElementsInRXFifo = (tempDataFromHost * 256) + tempDataFromHost2;
PRT("Slave EndPoint " << USBEndPoint << " RX FIFO has " << numOfElementsInRXFifo << " elements\n");
if (expectedDataCnt != numOfElementsInRXFifo) {
cout << "Data packet incorrect size. Expected " << expectedDataCnt << " bytes, received " << numOfElementsInRXFifo << " bytes\n";
errorDetected = 1;
}
for (i=0;i<numOfElementsInRXFifo;i++) {
slaveBusRead(tempDataFromHost, fifoBaseAddress + FIFO_DATA_REG);
if (tempDataFromHost != data[i]) {
printf("Data mismatch. TX data [0x%0x] = 0x%0x RX data[0x%0x] = 0x%0x. Aborting\n", i, data[i], i, tempDataFromHost);
errorDetected = 1;
}
}
if (numOfElementsInRXFifo > 0 && errorDetected == 0)
PRT("RX packet matches TX packet\n");
cancelInterrupt(SLAVE, SC_TRANS_DONE_BIT);
cancelInterrupt(SLAVE, SC_NAK_SENT_INT_BIT);
cancelInterrupt(HOST, TRANS_DONE_BIT);
switch (endPControlReg & 0xf)
{
case 0x0: //endpoint disabled
case 0x2: //endpoint ready, but disabled. Not a valid control state, but disable should pre-dominate
readXCReg(HOST, tempDataFromHost, RX_STATUS_REG, (1 << RX_TIME_OUT_BIT), 0xff); //expecting host to receive time out
//expecting no response from host
break;
case 0x1: //endpoint enabled, but not ready
readXCReg(SLAVE, tempDataFromHost, endPointStatusRegAddress, (1 << SC_NAK_SENT_BIT), (1 << SC_NAK_SENT_BIT)); //expecting slave to send NAK
readXCReg(HOST, tempDataFromHost, RX_STATUS_REG, (1 << NAK_RXED_BIT), 0xff); //expecting NAK at host
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -