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

📄 usbhost.c

📁 RDC R2886 USB Ehci ohc测试源码,paradigm c++上运行测试
💻 C
📖 第 1 页 / 共 3 页
字号:
						q=buf4;
						for(i=0;i<sizeof(buf4);i++)
							*p++ = *q++;
						*p++ = 10;
						*p++ = 13;
						UART_SendData(buf, sizeof(buf));
					
						g_OHCIAttach = 0;
						OHCI_DeviceAttach_Init = FALSE;
						HighSpeed_Owner = TRUE;
					}
				}
				DWordWrite(&ohci_regs->portstatus1, RH_PS_CSC);
			}
		}
	}
	}
Exit_INTB_ISR:
	DWordWrite(&ohci_regs->intrstatus, ints);



Exit_INTA_ISR:
	outp(INT_EOI,INTA_TYPE);    // ;;write to EOI
}

void _interrupt OHCI_Isr()
{
 	u32 ints, rhs, rhpt1s;
 	static char buf[32];
 	char buf3[28]={"Full Speed device attach..."};
 	char buf4[28]={"Full Speed device detach..."};
 	char *p, *q;
 	int i;
	uint32 pci_int_status;

	ints=inport(INT_INSERV);    //read in-service register

	p=buf;
	q=buf3;
	for(i=0;i<sizeof(buf3);i++)
		*p++ = *q++;
	*p++ = 10;
	*p++ = 13;
	
	//OHCI ++++++++++++++++++ For ALI +++++++++++++++++++++++++++++++++++++++++++++++++++
	//Check Interrupt Status
	ints = DWordRead(&ohci_regs->intrstatus);

	if (ints == ~(u32)0)
		goto Exit_INTB_ISR;

	if (ints & OHCI_INTR_UE) {
	//In application, need to modify the unrecoverable Error
	}

	//Write back DoneHead
	if (ints & OHCI_INTR_WDH) {
		DWordWrite(&ohci_regs->intrdisable, OHCI_INTR_WDH);
		DH_Status = dl_done_list();
		DWordWrite(&ohci_regs->intrenable, OHCI_INTR_WDH);
	}

  	//Scheduling Overrun
	if (ints & OHCI_INTR_SO) {
		DWordWrite(&ohci_regs->intrstatus, OHCI_INTR_SO);
	}

	//Start of frame
	if (ints & OHCI_INTR_SF) {
		DWordWrite(&ohci_regs->intrstatus, OHCI_INTR_SF);
	}

	//Frame number overflow
	if (ints & OHCI_INTR_FNO) { 
		DWordWrite(&ohci_regs->intrstatus, OHCI_INTR_FNO);
	}

	//Root hub status change, Port status change
	if (ints & OHCI_INTR_RHSC) { 
		//Root hub status change
		if((rhs = DWordRead(&ohci_regs->status)) != 0) {
			rhs = rhs;
		}
		//Port status change, just handle port 1
		else if((rhpt1s = DWordRead(&ohci_regs->portstatus1)) != 0) {
			if(rhpt1s & RH_PS_PRSC) {	//Port reset status change
				DWordWrite(&ohci_regs->portstatus1, RH_PS_PRSC);
				if(rhpt1s & RH_PS_PESC)
					DWordWrite(&ohci_regs->portstatus1, RH_PS_PESC);
				if(rhpt1s & RH_PS_CSC)
					DWordWrite(&ohci_regs->portstatus1, RH_PS_CSC);
				rhpt1s = DWordRead(&ohci_regs->portstatus1);
				if((rhpt1s & RH_PS_CCS) == RH_PS_CCS){	//Check is connect
					g_OHCIAttach = 1;
				}
			}
			if(rhpt1s & RH_PS_CSC){		//Port connect status change
				if(rhpt1s & RH_PS_CCS) {
					DWordWrite(&ohci_regs->portstatus1, RH_PS_PES);	//Port1 Status, set port enable
					UART_SendData(buf, sizeof(buf));
					g_OHCIAttach = 1;
				}
				else if(rhpt1s & RH_PS_PESC) {
					DWordWrite(&ohci_regs->portstatus1, RH_PS_PESC);
					if((rhpt1s & RH_PS_CCS) == RH_PS_CCS){
						UART_SendData(buf, sizeof(buf));
						g_OHCIAttach = 1;
					}
					else{
						p=buf;
						q=buf4;
						for(i=0;i<sizeof(buf4);i++)
							*p++ = *q++;
						*p++ = 10;
						*p++ = 13;
						UART_SendData(buf, sizeof(buf));
					
						g_OHCIAttach = 0;
						OHCI_DeviceAttach_Init = FALSE;
						HighSpeed_Owner = TRUE;
					}
				}
				DWordWrite(&ohci_regs->portstatus1, RH_PS_CSC);
			}
		}
	}
Exit_INTB_ISR:
	DWordWrite(&ohci_regs->intrstatus, ints);

   // Sten PCI NIC Interrupt --------------------------------  
   pci_int_status = InPortD(dec_info.io_base+CR5_ADDR);
   OutPortD(dec_info.io_base+CR5_ADDR, pci_int_status);
   if ((uint16)pci_int_status & 0x0001) pci_tx_handler((DEC_STRU far *)&dec_info);
   if ((uint16)pci_int_status & 0x0040) pci_rx_handler((DEC_STRU far *)&dec_info);
   //--------------------------------------------------------

	outp(INT_EOI,INTB_TYPE);    // ;;write to EOI
}

void _interrupt UartIsr()
{
 	u16 status, temp;
 	static char buf[30];
 	char buf1[26]={"Doing Control transfer..."};
 	char buf2[26]={"Doing SCSI Command......."};
 	char buf3[26]={"Doing Bulk Loop.........."};
 	char *p, *q;
 	int i;
 	
	status=inport(INT_INSERV);    //read in-service register
	
	//Check Interrupt Status
	status = inport(PCBBase+LSR);
	
	if(status & 0x01)
	{
		temp = inport(PCBBase+RBR);
		if(temp !=13) 
		{
			outport(PCBBase+THR, temp);
			
			UartBuf[UartCnt] = temp;
			UartCnt++;
		}
		else 
		{
			outport(PCBBase+THR, 10);
			outport(PCBBase+THR, 13);
			
			if(UartBuf[0] == 's')
			{
				if(UartBuf[1] == '1')
					DoTest_Mode(1);
				if(UartBuf[1] == '2')
					DoTest_Mode(2);
				if(UartBuf[1] == '3')
					DoTest_Mode(3);
				if(UartBuf[1] == '4')
					DoTest_Mode(4);
				if(UartBuf[1] == '5')
					DoTest_Mode(5);
			}
			else if(UartBuf[0] == 'e')
				EndTest_Mode();
			else if(UartBuf[0] == 'c')
			{
				if(UartBuf[1] == 's' && UartBuf[2] == 't')
				{
					p=buf;
					q=buf1;
					for(i=0;i<sizeof(buf1);i++)
						*p++ = *q++;
					*p++ = 10;
					*p++ = 13;
					UART_SendData(buf, sizeof(buf));
					ControlCnt = 0;
					ControlStart = TRUE;
				}
				else if(UartBuf[1] == 's' && UartBuf[2] == 'p')
					if(ControlStart == TRUE)
					{
						ControlStart = FALSE;
						SendDesc2UART();
					}
			}
			else if(UartBuf[0] == 'b')
			{
				if(UartBuf[1] == 's' && UartBuf[2] == 's' && UartBuf[3] == 't'){
					if((dev_des->idVendor != 0x1463) && (dev_des->idProduct != 0x05CB))	//Normal bulk SCSI command
						q=buf2;
					else
						q=buf3;
					
					p=buf;
					for(i=0;i<sizeof(buf2);i++)
						*p++ = *q++;
					*p++ = 10;
					*p++ = 13;
					UART_SendData(buf, sizeof(buf));
					SCSICnt = 0;
					SCSIStart = TRUE;
				}
				else if(UartBuf[1] == 's' && UartBuf[2] == 's' && UartBuf[3] == 'p'){
					if(SCSIStart == TRUE){
						SCSIStart = FALSE;
						SendSCSI2UART();
					}
				}
			}
			
			for(i=0;i<10;i++)
				UartBuf[i] = 0;
			UartCnt = 0;
		}
	}
		
//Exit_UART1_ISR:	
	temp = temp;
	outp(INT_EOI,UART1_TYPE);    // ;;write to EOI
}

void Init_PCINic(DEC_STRU far * mac_info)
{
	char far	*buf_ptr, far *dec_memory_ptr;
   DEC_DESCRIPTOR far *dec_desc_ptr;

   /* Allocate DEC information structure */
   dec_memory_ptr = (char far *)malloc(0x400 + BUF_SIZE * DESC_COUNT + 16);
   dec_memory_ptr = (char far *) (((unsigned long)dec_memory_ptr + 0xf) & ~0xf);

   /* Init PCI NIC */
   dec_desc_ptr = (DEC_DESCRIPTOR far *) dec_memory_ptr;
   buf_ptr = (char far *) (dec_memory_ptr + 0x400);
   init_dec_desc(mac_info, dec_desc_ptr, buf_ptr);

   /* Activate PCI NIC */
   DEC_Regs_Init(mac_info);

 return;
}

/* Linear address to physical address */
uint32 linear_to_real(uint32 linear_addr)
{
	uint32 real_addr;

   real_addr = (linear_addr & 0xffff0000L) >> 8;
   real_addr += (linear_addr & 0x0000ffffL);
   return real_addr;
}

void init_dec_desc(DEC_STRU far *dec_ipr, DEC_DESCRIPTOR far *desc_ptr, char far *buf_ptr)
{
	uint32 r_desc_addr, r_buf_addr, r_buf_addr_t;
	char far * buf_tmp;
	int	i;

   dec_ipr->tx_insert_ptr = desc_ptr;
   dec_ipr->tx_remove_ptr = desc_ptr;
   dec_ipr->rx_insert_ptr = (desc_ptr + DESC_COUNT);
   dec_ipr->rx_remove_ptr = dec_ipr->rx_insert_ptr;
   r_desc_addr = linear_to_real((uint32)desc_ptr);
   r_buf_addr = linear_to_real((uint32)buf_ptr);

   /* Init TX descriptor: Don't allocate TX buffer */
   dec_ipr->txd_raddr = r_desc_addr;
   r_buf_addr_t = r_buf_addr;
   buf_tmp = buf_ptr;
   for (i = 0; i < DESC_COUNT; i++) {
      desc_ptr->status = 0;
      desc_ptr->len = 0;
      desc_ptr->own = 0;
      desc_ptr->ctrl = 0xE100;
      desc_ptr->buf_ptr = r_buf_addr;
      desc_ptr->vbuf_ptr = buf_ptr;
      desc_ptr->ndesc_ptr = r_desc_addr + DEC_DESC_SIZE;
      desc_ptr->vndesc_ptr = desc_ptr + 1;
      r_desc_addr += DEC_DESC_SIZE;
      r_buf_addr += BUF_SIZE;
      buf_ptr = (buf_ptr + BUF_SIZE);
      desc_ptr = desc_ptr + 1;
   }
   (desc_ptr - 1)->ndesc_ptr = dec_ipr->txd_raddr;
   (desc_ptr - 1)->vndesc_ptr = dec_ipr->tx_insert_ptr;

   /* Init RX descriptor: Allocate RX buffer */
   r_buf_addr = r_buf_addr_t;
   buf_ptr = buf_tmp;
   dec_ipr->rxd_raddr = r_desc_addr;
   for (i = 0; i < DESC_COUNT; i++) {
      desc_ptr->len = 0x0620;
      desc_ptr->own = 0x8000;
      desc_ptr->ctrl = 0xE100;
      desc_ptr->buf_ptr = r_buf_addr;
      desc_ptr->ndesc_ptr = r_desc_addr + DEC_DESC_SIZE;
      desc_ptr->vbuf_ptr = buf_ptr;
      desc_ptr->vndesc_ptr = (desc_ptr + 1);
      desc_ptr->status = 0x0000;
      r_desc_addr += DEC_DESC_SIZE;
      r_buf_addr += BUF_SIZE;
      desc_ptr += 1;
      buf_ptr = (buf_ptr + BUF_SIZE);
   }
   (desc_ptr - 1)->ndesc_ptr = dec_ipr->rxd_raddr;
   (desc_ptr - 1)->vndesc_ptr = dec_ipr->rx_insert_ptr;
}

void DEC_Regs_Init(DEC_STRU far * dec_ipr)
{
	uint32 temp;
	int io_base = dec_ipr->io_base;

	OutPortD(io_base, 0x1);
	while(inport(io_base)&0x1);

	//Init CR6 (Operation Control)
	temp = (uint32)dec_ipr->cr6_datah << 16;
	temp += (uint32)((dec_ipr->cr6_datal)&(~0x2002));	//bit1:RXE, bit13:TXE
	OutPortD((io_base+CR6_ADDR), temp);

	//Clear CR5
        temp = InPortD(io_base+CR5_ADDR);
        OutPortD((io_base+CR5_ADDR), temp);

        /*Init TX/RX descriptor*/
        OutPortD(io_base + CR4_ADDR, dec_ipr->txd_raddr);
        OutPortD(io_base + CR3_ADDR, dec_ipr->rxd_raddr);

        /*Init CR0*/
        OutPortD(io_base, ((uint32)dec_ipr->cr0_datah<<16)+dec_ipr->cr0_datal);

        /*Init CR7 (Interrupt Mask)*/
        OutPortD(io_base + CR7_ADDR,(unsigned long)0x00010041);

        /*Init CR6 (Operation Control)*/
        temp = (uint32)dec_ipr->cr6_datah << 16;
	temp += (uint32)(dec_ipr->cr6_datal | (0x2002 | (DUPLEX_MODE*0x200)));	//bit1:RXE, bit13:TXE
	OutPortD((io_base+CR6_ADDR), temp);

	/*Clear CR5*/
	temp = InPortD(io_base+CR5_ADDR);
        OutPortD((io_base+CR5_ADDR), temp);
}

void OutPortD(uint16 addr, uint32 data)
{
	asm{pushf};
   asm{cli};
	outport(0xff00, addr);
	outport(0xff02, 0x0);
	outport(0xff04, (uint16)(data&0x0000ffffL));
	outport(0xff06, (uint16)((data&0xffff0000L)>>16));
   asm{popf};
}

uint32 InPortD(uint16 addr)
{
	uint16 temp;
	uint32 data;

	asm{pushf};
   asm{cli};
	outport(0xff00, addr);
	outport(0xff02, 0x0);
	temp = inport(0xff04);
	data = (uint32)inport(0xff06) << 16;
	data += (uint32)temp;
   asm{popf};

	return data;
}

/* PCI TX interrupt handler */
void pci_tx_handler(DEC_STRU far * dec_ipr)
{
   int io_base = dec_ipr->io_base;
   DEC_DESCRIPTOR far *txd_ptr = dec_ipr->tx_remove_ptr;
   DEC_DESCRIPTOR far *rxd_ptr = dec_ipr->rx_insert_ptr;

   while(dec_ipr->TxFreeDesc < DESC_COUNT) {
   	//if (txd_ptr->status & 0x8000) break;
   	if (txd_ptr->own & 0x8000) break;


      //dec_ipr->TxSuccCounter++;

      /* Re-use RX desciptor */
		rxd_ptr->own = 0x8000;
		//rxd_ptr->status = 0;
      outport(io_base + CR2_ADDR, txd_ptr->own);	/* Trigger MAC increase RX descriptor count */
      dec_ipr->TxFreeDesc++;
      dec_ipr->RxFreeDesc++;
      rxd_ptr = rxd_ptr->vndesc_ptr;
      txd_ptr = txd_ptr->vndesc_ptr;
	}
   dec_ipr->tx_remove_ptr = txd_ptr;
   dec_ipr->rx_insert_ptr = rxd_ptr;
}

/* MAC RX interrupt handler */
void pci_rx_handler(DEC_STRU far * dec_ipr)
{
	int io_base = dec_ipr->io_base;
   DEC_DESCRIPTOR far *rxd_ptr = dec_ipr->rx_remove_ptr;
   DEC_DESCRIPTOR far *txd_ptr = dec_ipr->tx_insert_ptr;

   while(dec_ipr->RxFreeDesc) {
   	if (rxd_ptr->own & 0x8000) break;
   
      /*Packet Received*/
      if(rxd_ptr->status&0x8000)
      	 dec_ipr->RxErrL ++;

      /* Another MAC send */
      //txd_ptr->buf_ptr = rxd_ptr->buf_ptr;
      if(rxd_ptr->own<=64)
      	rxd_ptr->own = 64;
      else if(rxd_ptr->own>=1518)
        rxd_ptr->own = 1518;

      //txd_ptr->len = 0x3c;//(rxd_ptr->own&0x3fff) - 4;		/* Skip 4 byte CRC */
      txd_ptr->len = rxd_ptr->own - 4;
      txd_ptr->own = 0x8000;
      outport(io_base + CR1_ADDR, txd_ptr->len);
      dec_ipr->RxFreeDesc--;
      dec_ipr->TxFreeDesc--;

      /* Next descriptor */
      rxd_ptr = rxd_ptr->vndesc_ptr;
      txd_ptr = txd_ptr->vndesc_ptr;
   }
   dec_ipr->rx_remove_ptr = rxd_ptr;
   dec_ipr->tx_insert_ptr = txd_ptr;
}


⌨️ 快捷键说明

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