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

📄 int_d12.h

📁 一个使用USB下载51单片机程序的源程序
💻 H
字号:
CONTROL_XFER ControlData;
BYTE control_state;
bit configuration;

void Init_D12(void)
{
	*D12_Comm=0xF3;							// D12_SetMode
	*D12_Data=D12_NOLAZYCLOCK;  *D12_Data=D12_SETTOONE | D12_CLOCK_4M;
	Delay_ms(10);
	*D12_Comm=0xFB;							// D12_SetDMA
	*D12_Data=D12_ENDP4INTENABLE | D12_ENDP5INTENABLE;
	*D12_Comm=0xF3;							// D12_SetMode
	*D12_Data=D12_NOLAZYCLOCK|D12_SOFTCONNECT;  *D12_Data=D12_SETTOONE | D12_CLOCK_4M;
}

void D12_SetEndpointStatus(unsigned char bEndp, unsigned char bStalled)
{
	*D12_Comm=0x40+bEndp;
	*D12_Data=bStalled;
}

unsigned char D12_ReadEndpoint(unsigned char endp, unsigned char len, unsigned char *buf)
{
 	unsigned char i, j;
	*D12_Comm=endp;
	if((D12_Data[0]&D12_FULLEMPTY)==0){
 		return 0;
 	}
	*D12_Comm=0xF0;
	j=D12_Data[0];
	j=D12_Data[0];
 	if(j > len)
 		j = len;
 	for(i=0; i<j; i++)
		buf[i] = D12_Data[0];
	*D12_Comm=0xF2;
 	return j;
}

unsigned char D12_WriteEndpoint(unsigned char endp, unsigned char len, unsigned char * buf)
{
 	unsigned char i;
	*D12_Comm=endp;
	i=D12_Data[0];
	*D12_Comm=0xF0;
	*D12_Data=0;
	*D12_Data=len;
 	for(i=0; i<len; i++)
		*D12_Data=buf[i];
	*D12_Comm=0xFA;
 	return len;
}

void stall_ep0(void)
{
	D12_SetEndpointStatus(0, 1);
	D12_SetEndpointStatus(1, 1);
}

void init_unconfig(void)
{
	*D12_Comm=0xD8;		// D12_SetEndpointEnable(0)
	*D12_Data=0;
}

void init_config(void)
{
	*D12_Comm=0xD8;
	*D12_Data=1;			// D12_SetEndpointEnable(1)
}

void single_transmit(unsigned char *buf, unsigned char len)
{
	if(len <= EP0_PACKET_SIZE){
		D12_WriteEndpoint(1, len, buf);
	}
}

void code_transmit(BYTE code *pRomData, BYTE len)
{
	ControlData.wCount = 0;
	if(ControlData.wLength > len)
		ControlData.wLength = len;
	ControlData.pData = pRomData;
	if(ControlData.wLength >= EP0_PACKET_SIZE){
		D12_WriteEndpoint(1, EP0_PACKET_SIZE, ControlData.pData);
		ControlData.wCount += EP0_PACKET_SIZE;
		control_state = USB_TRANSMIT;
	}else{
		D12_WriteEndpoint(1, ControlData.wLength, pRomData);
		ControlData.wCount += ControlData.wLength;
		control_state = USB_IDLE;
	}
}

void get_status(void)
{
	unsigned char endp, txdat[2];
	unsigned char bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
	unsigned char c;
	if(bRecipient == USB_RECIPIENT_DEVICE){
		txdat[0] = 1;
		txdat[1]=0;
		single_transmit(txdat, 2);
	}else if(bRecipient == USB_RECIPIENT_INTERFACE){
		txdat[0]=0;
		txdat[1]=0;
		single_transmit(txdat, 2);
	}else if(bRecipient == USB_RECIPIENT_ENDPOINT){
		endp = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if(ControlData.DeviceRequest.wIndex & (unsigned char)USB_ENDPOINT_DIRECTION_MASK){
			*D12_Comm=endp*2+1;  c=D12_Data[0];		// D12_SelectEndpoint(endp*2+1) Control-in
		}else{
			*D12_Comm=endp*2;  c=D12_Data[0];		// D12_SelectEndpoint(endp*2) Control-out
		}
		if(c & D12_STALL)
			txdat[0] = 1;
		else
			txdat[0] = 0;
		txdat[1] = 0;
		single_transmit(txdat, 2);
	}else
		stall_ep0();
}

void clear_feature(void)
{
	unsigned char endp;
	unsigned char bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
	if(bRecipient == USB_RECIPIENT_DEVICE && ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP){
		single_transmit(0, 0);
	}else if(bRecipient == USB_RECIPIENT_ENDPOINT && ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL){
		endp = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if(ControlData.DeviceRequest.wIndex & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
			/* clear TX stall for IN on EPn. */
			D12_SetEndpointStatus(endp*2 + 1, 0);
		else
			/* clear RX stall for OUT on EPn. */
			D12_SetEndpointStatus(endp*2, 0);
		single_transmit(0, 0);
	}else
		stall_ep0();
}

void set_feature(void)
{
	BYTE endp;
	BYTE bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
	if(bRecipient == USB_RECIPIENT_DEVICE && ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP){
		single_transmit(0, 0);
	}else if(bRecipient == USB_RECIPIENT_ENDPOINT
		&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL){
		endp = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if(ControlData.DeviceRequest.wIndex & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
			// clear TX stall for IN on EPn
			D12_SetEndpointStatus(endp*2 + 1, 1);
		else
			// clear RX stall for OUT on EPn
			D12_SetEndpointStatus(endp*2, 1);
		single_transmit(0, 0);
	}else
		stall_ep0();
}

void set_address(void)
{
	*D12_Comm=0xD0;		// D12_SetAddressEnable
	*D12_Data=(ControlData.DeviceRequest.wValue & DEVICE_ADDRESS_MASK)|0x80;
	single_transmit(0, 0);
}

void get_descriptor(void)
{
	BYTE bDescriptor, idx;
	bDescriptor = MSB(ControlData.DeviceRequest.wValue);
	if(bDescriptor == USB_DEVICE_DESCRIPTOR_TYPE){
		code_transmit(DeviceDescr, sizeof(DeviceDescr));
	}else if(bDescriptor == USB_CONFIGURATION_DESCRIPTOR_TYPE){
		code_transmit(ConfigDescr, sizeof(ConfigDescr));
	}else if(bDescriptor == USB_CONFIGURATION_HIDREPORT_TYPE){
		code_transmit(ReportDescriptor, sizeof(ReportDescriptor));
	}else if(bDescriptor == USB_STRING_DESCRIPTOR_TYPE){
		idx=ControlData.DeviceRequest.wValue;
		if(idx==0)
			code_transmit(String_0, String_0[0]);
		else if(idx==1)
			code_transmit(String_1, String_1[0]);
		else if(idx==2)
			code_transmit(String_2, String_2[0]);
		else if(idx==3)
			code_transmit(String_3, String_3[0]);
		else
			stall_ep0();
	}else{
		stall_ep0();
	}
}

void get_configuration(void)
{
	unsigned char c = configuration;
	single_transmit(&c, 1);
}

void set_configuration(void)
{
	if(ControlData.DeviceRequest.wValue == 0){	// put device in unconfigured state
		single_transmit(0, 0);
		configuration = 0;
		init_unconfig();
	}else if(ControlData.DeviceRequest.wValue == 1){	// Configure device
		single_transmit(0, 0);
		init_unconfig();
		init_config();
		configuration = 1;
	}else
		stall_ep0();
}

void get_interface(void)
{
	unsigned char txdat = 0;				// Only/Current interface = 0
	single_transmit(&txdat, 1);
}

void set_interface(void)
{
	if(ControlData.DeviceRequest.wValue == 0 && ControlData.DeviceRequest.wIndex == 0)
		single_transmit(0, 0);
	else
		stall_ep0();
}

void control_handler()
{
	BYTE type, req;
	type = ControlData.DeviceRequest.bmRequestType & USB_REQUEST_TYPE_MASK;
	req = ControlData.DeviceRequest.bRequest & USB_REQUEST_MASK;
	if(type == USB_STANDARD_REQUEST){
		if(req==0){
			get_status();
		}else if(req==1){
			clear_feature();
		}else if(req==3){
			set_feature();
		}else if(req==5){
			set_address();
		}else if(req==6){
			get_descriptor();
		}else if(req==8){
			get_configuration();
		}else if(req==9){
			set_configuration();
		}else if(req==10){
			get_interface();
		}else if(req==11){
			set_interface();
		}else
			stall_ep0();
	}else
		stall_ep0();
}

void ep0_rxdone(void)
{
	unsigned char ep_last;
	*D12_Comm=0x40;  ep_last=D12_Data[0];			// Clear Interrupt flag
	if(ep_last & D12_SETUPPACKET){
		ControlData.wLength = 0;
		ControlData.wCount = 0;
		if(D12_ReadEndpoint(0, sizeof(ControlData.DeviceRequest),
			(unsigned char *)(&(ControlData.DeviceRequest))) != sizeof(DEVICE_REQUEST)){
			D12_SetEndpointStatus(0, 1);
			D12_SetEndpointStatus(1, 1);
			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);
		// Acknowledge setup here to unlock in/out endp
		*D12_Comm=0;  *D12_Comm=0xF1;  *D12_Comm=0xF2;	// D12_AcknowledgeEndpoint(0)
		*D12_Comm=1;  *D12_Comm=0xF1;							// D12_AcknowledgeEndpoint(1)
		ControlData.wLength = ControlData.DeviceRequest.wLength;
		ControlData.wCount = 0;
		if(ControlData.DeviceRequest.bmRequestType & (unsigned char)USB_ENDPOINT_DIRECTION_MASK){
			control_state = USB_IDLE;		/* get command */
			control_handler();
		}else{
			if(ControlData.DeviceRequest.wLength == 0){
				control_state = USB_IDLE;		/* set command */
				control_handler();
			}else{
				if(ControlData.DeviceRequest.wLength > MAX_CONTROLDATA_SIZE){
					control_state = USB_IDLE;
					D12_SetEndpointStatus(0, 1);
					D12_SetEndpointStatus(1, 1);
				}else
					control_state = USB_RECEIVE;	/* set command with OUT token */
			} // set command with data
		} // else set command
	}else
		control_state = USB_IDLE;
}

void usb_isr(void) interrupt IE0_VECTOR
{
	BYTE stat,tmp;
	short s;
	*D12_Comm=0xF4;  stat=D12_Data[0];  tmp=D12_Data[0];		// Read Interrupt Register
	if(stat & D12_INT_ENDP0IN){			// EP0_IN(TX)(D12->PC)
		s = ControlData.wLength - ControlData.wCount;
		*D12_Comm=0x41;  tmp=D12_Data[0];// Clear Interrupt flag
		if(control_state == USB_TRANSMIT){
			if(s >= EP0_PACKET_SIZE){
				D12_WriteEndpoint(1, EP0_PACKET_SIZE, ControlData.pData + ControlData.wCount);
				ControlData.wCount += EP0_PACKET_SIZE;
				control_state = USB_TRANSMIT;
			}else if(s != 0){
				D12_WriteEndpoint(1, s, ControlData.pData + ControlData.wCount);
				ControlData.wCount += s;
				control_state = USB_IDLE;
			}else{
				D12_WriteEndpoint(1, 0, 0);// Send zero packet at the end ???
				control_state = USB_IDLE;
			}
		}

	}
	if(stat & D12_INT_ENDP0OUT)			// EP0_OUT(RX)(PC->D12)
		ep0_rxdone();
	if(stat & D12_INT_ENDP2IN){			// EP2_IN(TX)(D12->PC)
		*D12_Comm=0x45;  tmp=D12_Data[0];// Clear Interrupt flag
	}
	if(stat & D12_INT_ENDP2OUT){			// EP2_OUT(RX)(PC->D12)
		*D12_Comm=0x44;  tmp=D12_Data[0];// Clear Interrupt flag
		tmp=D12_ReadEndpoint(4, BUF_LEN, rx_buf);
		if(tmp==BUF_LEN)
			b_rx_done=1;
	}
}

void Send_Data(void)
{
	BYTE i;
	DISABLE_USBINT								// Disable USB interrupt
	*D12_Comm=5;  i=D12_Data[0];			// WriteEndpoint(5)
	*D12_Comm=0xF0;  *D12_Data=0;  *D12_Data=TXD_LEN;	// Write 36 bytes
	for(i=0; i<TXD_LEN; i++)
		*D12_Data=tx_buf[i];
	*D12_Comm=0xFA;							// Valid buffer(Start transfer)
	ENABLE_USBINT								// Enable USB interrupt
}

⌨️ 快捷键说明

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