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

📄 usb.c

📁 自己动手做U盘
💻 C
📖 第 1 页 / 共 2 页
字号:

void self_oprate()
{
	
	single_transmit(0, 0);
}


void (*StandardDeviceRequest[])(void) =
{
get_status,
clear_feature,
reserved,
set_feature,
reserved,
set_address,
get_descriptor,
reserved,
get_configuration,
set_configuration,
get_interface,
set_interface,
reserved,
reserved,
reserved,
reserved
};
void (*VendorDeviceRequest[])(void) =
{
self_oprate,
reserved,
reserved,
reserved,
reserved,
reserved,
reserved,
reserved,
reserved,
reserved,
reserved,
reserved,
//read_write_register,
reserved,
reserved,
reserved
};

void control_handler()
{
	unsigned char type, req;
	
	
	type = ControlData.DeviceRequest.bmRequestType & USB_REQUEST_TYPE_MASK;
	req = ControlData.DeviceRequest.bRequest & USB_REQUEST_MASK;
	//help_devreq(type, req); // print out device request
	if (type == USB_STANDARD_REQUEST) 		(*StandardDeviceRequest[req])();
	else if (type == USB_VENDOR_REQUEST)	(*VendorDeviceRequest[req])();
	else
	stall_ep0();
	//end:  ;
}





void bus_reset(void)
{
}


void ep0_rxdone(void)
{
	unsigned char ep_last, i;
	
	ep_last = D12_ReadLastTransactionStatus(0); // Clear interrupt flag
	
		
	if (ep_last & D12_SETUPPACKET) 
	{
		ControlData.wLength = 0;
		ControlData.wCount = 0;
		if( D12_ReadEndpoint(0, (unsigned char *)(&(ControlData.DeviceRequest)),sizeof(ControlData.DeviceRequest)) != sizeof(DEVICE_REQUEST) )
		{			
			D12_SetEndpointStatus(0, 1);
			D12_SetEndpointStatus(1, 1);
			bEPPflags.bits.control_state = USB_IDLE;
			return;
		}
	

	ControlData.DeviceRequest.wValue = SWAP(ControlData.DeviceRequest.wValue);
	ControlData.DeviceRequest.wIndex = SWAP(ControlData.DeviceRequest.wIndex);
	ControlData.DeviceRequest.wLength = SWAP(ControlData.DeviceRequest.wLength);
	D12_AcknowledgeEndpoint(0);
	D12_AcknowledgeEndpoint(1);
	ControlData.wLength = ControlData.DeviceRequest.wLength;
	ControlData.wCount = 0;
	if (ControlData.DeviceRequest.bmRequestType & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
		{
			bEPPflags.bits.setup_packet = 1;
			bEPPflags.bits.control_state = USB_TRANSMIT; /* get command */
		}
	else 
	{
		if (ControlData.DeviceRequest.wLength == 0) 
		{
			bEPPflags.bits.setup_packet = 1;
			bEPPflags.bits.control_state = USB_IDLE; /* set command */
		}
		else 
		{
				if(ControlData.DeviceRequest.wLength > MAX_CONTROLDATA_SIZE) 
				{
					bEPPflags.bits.control_state = USB_IDLE;
					D12_SetEndpointStatus(0, 1);
					D12_SetEndpointStatus(1, 1);
				}
				else 
				{
					bEPPflags.bits.control_state = USB_RECEIVE; /* set command with OUT token */
				}
			} 													// set command with data
		} 

															// else set command
	} 															// if setup packet
	else if (bEPPflags.bits.control_state == USB_RECEIVE) 
	{
		i = D12_ReadEndpoint(0, ControlData.dataBuffer + ControlData.wCount,EP0_PACKET_SIZE);
		ControlData.wCount += i;
		if( i != EP0_PACKET_SIZE || ControlData.wCount >= ControlData.wLength) 
		{
			bEPPflags.bits.setup_packet = 1;
			bEPPflags.bits.control_state = USB_IDLE;
		}
	}
	else 
	{
		bEPPflags.bits.control_state = USB_IDLE;
	}
}


void ep0_txdone(void)
{
	short i = ControlData.wLength - ControlData.wCount;	
	
	
	D12_ReadLastTransactionStatus(1); // Clear interrupt flag
	if (bEPPflags.bits.control_state != USB_TRANSMIT)	return;
	if( i >= EP0_PACKET_SIZE) 
	{
		D12_WriteEndpoint(1, ControlData.pData + ControlData.wCount, EP0_PACKET_SIZE);
		ControlData.wCount += EP0_PACKET_SIZE;
		bEPPflags.bits.control_state = USB_TRANSMIT;
	}
	else if( i != 0) 
	{
		D12_WriteEndpoint(1, ControlData.pData + ControlData.wCount, i);
		ControlData.wCount += i;
		bEPPflags.bits.control_state = USB_IDLE;
	}
	else if (i == 0)
	{
		D12_WriteEndpoint(1, 0, 0); // Send zero packet at the end ??? 
		bEPPflags.bits.control_state = USB_IDLE;
	}
}


void dma_eot(void)
{
	if(bEPPflags.bits.dma_state == DMA_PENDING)    	bEPPflags.bits.setup_dma = 1;
	else   											bEPPflags.bits.dma_state = DMA_IDLE;
	
}
void cbw_answer()
{
	;
}

void ep1_txdone(void)
{
	unsigned char i;
	i=D12_ReadLastTransactionStatus(3); /* Clear interrupt flag */
	UART0_SendByte(0xdc);
}


void ep1_rxdone(void)
{	//unsigned char p[16];
    //unsigned char dataLen;
    //unsigned char i;
	D12_ReadLastTransactionStatus(2); /* Clear interrupt flag */
 /*   dataLen=D12_ReadEndpoint(2,p,16);
    
    if(dataCount==0)        // a new command
    {
      if(*p==2)
       {
        
       }
    }
    else
    {
    
    }
    
	 for(i=0;i<dataLen;i++)
	 	{
	 	 receive_buffer[curStep]=p[i];
	 	 //UART0_SendByte(tempBuf[i]);
	 	 curStep++;
	 	 }
	 //if((receive_buffer[dataLen-4]=='E')&&(receive_buffer[dataLen-3]=='N')&&(receive_buffer[dataLen-2]=='D'))
	 	//analyse();//
	 for(i=0;i<curStep;i++)
	 	UART0_SendByte(receive_buffer[i]);
	 curStep-=1;
	 */
	bEPPflags.bits.ep1_rxdone = 1;
}

void analyse(void)
{	unsigned char *pb;
	unsigned char sendFlag;
	unsigned char tempi;
	unsigned int dlen;
	pb=receive_buffer;
	if(((*pb++)!='S')&&((*pb)!='T'))
		return ;
	pb++;
	sendFlag=(*pb)-48;
	pb++;
	for(tempi=0;tempi<4;tempi++)
		{dlen=dlen*16+(*pb)-48;pb++;}
	//UART0_SendByte(dlen);
	
}
void main_txdone(void)
{
	D12_ReadLastTransactionStatus(5); /* Clear interrupt flag */
	bEPPflags.bits.ep1_rxdone = 1;
}

void main_rxdone(void)
{
	
	unsigned char i;
	
	D12_ReadLastTransactionStatus(4); // Clear interrupt flag
	D12_SelectEndpoint(4);
	Outport_command( 0xF0);
	i=Inport_data();
	i=Inport_data();
	for(i=0;i<64;i++)
		{cbw[i]=Inport_data();}	

   	   	
	if((cbw[0]==0x55)&(cbw[1]==0x53)&(cbw[2]==0x42)&(cbw[3]==0x43))
	{
	    Outport_command(0xf2);
	    csw[0]=0x55;
	    csw[1]=0x53;
	    csw[2]=0x42;
	    csw[3]=0x53;
	    for(i=4;i<8;i++)
	    csw[i]=cbw[i];
	    for(i=8;i<12;i++)
	    csw[i]=0;
	    csw[12]=0; 
		switch(cbw[15])
		{	
			case 0x12:
				{	
				 CSW_transmit((unsigned char *)&inquirydata,36);
				 rr1:	Outport_command(5);
				 i=Inport_data();	
			  	 if(i!=0){goto rr1;}		    
			    
				 CSW_transmit((unsigned char *)&csw,13);					
				}
			   	break;
			case 0x23:
				{	
				  
				 CSW_transmit((unsigned char *)&fcap,12);
				 rr:	Outport_command(5);
				 i=Inport_data();	
			  	 if(i!=0){goto rr;}
			  	 CSW_transmit((unsigned char *)&csw,13);
				}
				break;
			case 0x25:
				{
				
				 CSW_transmit((unsigned char *)&cap,8);
				 rr2:	Outport_command(5);
				 i=Inport_data();	
			  	 if(i!=0){goto rr2;}	
			  	 		    
				 CSW_transmit((unsigned char *)&csw,13);
				}
				break;
			case 0x28:
				{
				 unsigned long int start_page;
				 unsigned long int page_num,n;				
				 start_page=cbw[17];
				 start_page=start_page*256+cbw[18];	 
				 start_page=start_page*256+cbw[19];
				 start_page=start_page*256+cbw[20];
				 page_num=cbw[22];
				 page_num=page_num*256+cbw[23];					 
				 for(n=0;n<page_num;n++)
					 {	
					 	Flash_page_read(start_page);
						CSW_transmit((unsigned char *)&Data_buffer,512);
						rr0:	Outport_command(5);
						i=Inport_data();	
				  		if(i!=0){goto rr0;}    
					    start_page++;
					 }	
				 CSW_transmit((unsigned char *)&csw,13);
				 }
				 break;
			case 0x1a:
				{					 
				 CSW_transmit((unsigned char *)&mode,12);
				 rr4:	Outport_command(5);
				 i=Inport_data();	
			  	 if(i!=0){goto rr4;}
				 CSW_transmit((unsigned char *)&csw,13);
				}
				break;			
			case 0x2a:
				{
					unsigned char j;
					unsigned int h;
					trans_start_page=cbw[17];
					trans_start_page=trans_start_page*256+cbw[18];	 
					trans_start_page=trans_start_page*256+cbw[19];
					trans_start_page=trans_start_page*256+cbw[20];
					trans_num=cbw[22];
					trans_num=trans_num*256+cbw[23];					
					block_addr=trans_start_page/32;
					count=0;
					count1=0;					
					for(j=0;j<32;j++)
							{
								Flash_page_read(block_addr*32+j);
								for(h=0;h<512;h++)
								receive_buffer[j*512+h]=Data_buffer[h];
							}
					Flash_block_erase(block_addr);	
				}
				break;
			default:
				 CSW_transmit((unsigned char *)&csw,13);			
		}
		
	}
	else
	{	unsigned char i;
		unsigned int j;		
		for(i=0;i<64;i++)
		{				
			receive_buffer[(trans_start_page%32)*512+count1]=cbw[i];		
			count1++;	
		}			
		Outport_command(0xf2);	    
		if(trans_start_page%32+trans_num<=32)
		{   
			
			
			if(count1>=(trans_num*512))				
			{ 
			   unsigned long int page=block_addr*32;
			   count1=0;	
			   for(i=0;i<10;i++)
			   {
				  for(j=0;j<512;j++)
				  Data_buffer[j]=receive_buffer[i*512+j];
				  Flash_page_program(page+i);
		       } 
		      CSW_transmit((unsigned char *)&csw,13);
		       for(i=10;i<32;i++)
			   {
				  for(j=0;j<512;j++)
				  Data_buffer[j]=receive_buffer[i*512+j];
				  Flash_page_program(page+i);
		       } 			   	 	  				     			      
			}
		}
		
		else
		{
			
			if((trans_start_page%32+count1/512)>=32)
			{
				 trans_num-=count1/512;
				 count1=0;						
				 for(i=0;i<32;i++)
					{
						for(j=0;j<512;j++)
						Data_buffer[j]=receive_buffer[i*512+j];
						Flash_page_program(block_addr*32+i);
					}			
				block_addr++;
				for(i=0;i<32;i++)
					{
						Flash_page_read(block_addr*32+i);
						for(j=0;j<512;j++)
						receive_buffer[i*512+j]=Data_buffer[j];
					}
				Flash_block_erase(block_addr);	
				trans_start_page=block_addr*32;
			}
		}
		
	}
}	


void USB_mainloop()
{
		if (bEPPflags.bits.bus_reset) 
		{
			DISABLE;
			bEPPflags.bits.bus_reset = 0;
			ENABLE;
		} // if bus reset
		if (bEPPflags.bits.suspend) 
		{
			DISABLE;
			bEPPflags.bits.suspend= 0;
			ENABLE;
			suspend_change();
		} // if suspend change
		if (bEPPflags.bits.setup_packet)
		{
			DISABLE;
			bEPPflags.bits.setup_packet = 0;
			ENABLE;
			control_handler();
		} // if setup_packet
		if(bEPPflags.bits.ep1_rxdone) 
		{
			DISABLE;
			bEPPflags.bits.ep1_rxdone = 0;
			ENABLE;
		} 
		if(bEPPflags.bits.setup_dma) 
		{
			DISABLE;
			bEPPflags.bits.setup_dma = 0;
			ENABLE;
			setup_dma();
		} // if setup_dma 

}

void fn_usb_isr()
{
	unsigned int i_st;
	
	bEPPflags.bits.in_isr = 1;
	i_st = D12_ReadInterruptRegister();
	
	if(i_st != 0)
	{
	    if(i_st & D12_INT_BUSRESET)
		{		
			bus_reset();
			bEPPflags.bits.bus_reset = 1; //StatusLED_ON(1);
		}
		else
		{
			if(i_st & D12_INT_EOT)				dma_eot();
			if(i_st & D12_INT_SUSPENDCHANGE)	bEPPflags.bits.suspend = 1;
			if(i_st & D12_INT_ENDP0IN)			ep0_txdone();
			if(i_st & D12_INT_ENDP0OUT)			ep0_rxdone();
			if(i_st & D12_INT_ENDP1IN)			ep1_txdone();
			if(i_st & D12_INT_ENDP1OUT)			ep1_rxdone();
			if(i_st & D12_INT_ENDP2IN)			main_txdone();
			if(i_st & D12_INT_ENDP2OUT)			main_rxdone();
		}
	}
	bEPPflags.bits.in_isr = 0;
	USB_mainloop();
}



void __irq IRQ_USB_Eint0(void)

{
	DISABLE;  
	fn_usb_isr();
	EXTINT = 0x01;VICVectAddr = 0;
	ENABLE;
}

void Init_USB_inter()
{
    
   	VICIntSelect = 0x00000000;		// 设置所有中断分配为IRQ中断
   	VICVectCntl3 = 0x20|14; 
   	VICVectAddr3 = (int)IRQ_USB_Eint0; // 设置中断服务程序地址
   	EXTINT = 0x01;					// 清除EINT0中断标志	
	USB_INTERRUPT_ON;				// 使能EINT1中断
}  	

void USB_reset()
{	
	
	USBRST_L;
	Delayms(20);
	USBRST_H;
	Delayms(10);
	
}

void USB_init(void)
{

	
	USBRST_H;
	USB_reset();
		
	Outport_command(0xF3);
	Outport_data(0x0E);
	Outport_data(0x03);
	
	Delayms(300);
	
	Outport_command(0xF3);
	Outport_data(0x1E);
	Outport_data(0x03);
				
	Init_USB_inter();
	if(USBMode==0)
    {
     pDeviceDescr=ctl_DeviceDescr;
     pConfigDescr=ctl_ConfigDescr;
    }
  else
    {
     pDeviceDescr=uDisk_DeviceDescr;
     pConfigDescr=uDisk_ConfigDescr;
    }
     
}








⌨️ 快捷键说明

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