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

📄 usb.c

📁 用AVR单片机实现USB口通信,特别是用CVAVR实现了系统应用
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <string.h> 
#include <avr/delay.h>
#include "usb.h"
#define BAUD  9600
#define uchar unsigned char

static EPPFLAGS bEPPflags;
CONTROL_XFER ControlData;
unsigned char GenEpBuf[EP1_PACKET_SIZE];
unsigned char EpBuf[EP2_PACKET_SIZE];


void delay1(void)
{
	asm("nop");
	asm("nop");
	asm("nop");
	asm("nop");
	asm("nop");
	asm("nop");
	asm("nop");
	asm("nop");
	asm("nop");
	asm("nop");
}
/*void put_c(unsigned char c) //发送采用查询方式
{
	while( !(UCSRA & (1<<UDRE)) );
	UDR=c;
}*/
//this part from Epphal.c
void outportb(unsigned char Addr,unsigned char Data)
{	
	 PORTB |=(1<<D12_ALE); //SET ALE H
	 DDRA=0xff;
	 PORTA=Addr; //load address
	 delay1();
	 PORTB &=~(1<<D12_ALE); //RESET ALE L
	 PORTA=Data;
	 PORTB &=~(1<<D12_WR); //Enalbe write
	 delay1(); //waite some time 
	 delay1();
	 PORTB |=(1<<D12_WR);
}

unsigned char inportb(unsigned char Addr)
{
	unsigned char rt;
	 PORTB |=(1<<D12_ALE); //SET ALE H
	 DDRA=0xff ;
	
	 PORTA=Addr; //load address
	 delay1();
	 PORTB &=~(1<<D12_ALE); //RESET ALE L
	 DDRA=0x00;
	 PORTA=0xff;  //
	 PORTB &=~(1<<D12_RD);
	
	 delay1();
	 rt=PINA;
	 PORTB |=(1<<D12_RD);
	return rt;
}


//this part from D12CI.C
/*设置/使能地址命令:D0H*/
void D12_SetAddressEnable(unsigned char bAddress, unsigned char bEnable)
{
    if(bEPPflags.bits.in_isr == 0)
         DISABLE;//EA=0
    outportb(D12_COMMAND, 0xD0);
	if(bEnable)
		bAddress |= 0x80;
	outportb(D12_DATA, bAddress);
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;//EA=1
}

/*设置端点使能命令:D8H*/
void D12_SetEndpointEnable(unsigned char bEnable)
{
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
	outportb(D12_COMMAND, 0xD8);
	if(bEnable)
		outportb(D12_DATA, 1);
	else
		outportb(D12_DATA, 0);
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
}

/*设置模式命令:F3H*/
void D12_SetMode(unsigned char bConfig, unsigned char bClkDiv)
{
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
	outportb(D12_COMMAND, 0xF3);
	outportb(D12_DATA, bConfig);
	outportb(D12_DATA, bClkDiv);
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
}

/*设置DMA命令:FBH*/
void D12_SetDMA(unsigned char bMode)
{
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
	outportb(D12_COMMAND, 0xFB);
	outportb(D12_DATA, bMode);
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
}

/*读中断寄存器命令:F4H*/
unsigned short D12_ReadInterruptRegister(void)
{
	unsigned char b1;
	unsigned int j;
	outportb(D12_COMMAND, 0xF4);
	b1 = inportb(D12_DATA);
	j = inportb(D12_DATA);
	j <<= 8;
	j += b1;
	return j;
}

/*选择端点命令:00~05H*/
unsigned char D12_SelectEndpoint(unsigned char bEndp)
{
	unsigned char c;
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
	outportb(D12_COMMAND, bEndp);
	c = inportb(D12_DATA);
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
	return c;
}

/*读最后处理状态寄存器命令:40~45H*/
unsigned char D12_ReadLastTransactionStatus(unsigned char bEndp)
{
	outportb(D12_COMMAND, 0x40 + bEndp);
	return inportb(D12_DATA);
}


/*设置端点状态命令:40~45H*/
void D12_SetEndpointStatus(unsigned char bEndp, unsigned char bStalled) 
{
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
	outportb(D12_COMMAND, 0x40 + bEndp);
	outportb(D12_DATA, bStalled);
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
}


/*设置端点状态命令:40~45H,专用于中断函数中*/
void D12_SetEndpointStatusIsr(unsigned char bEndp, unsigned char bStalled)
{
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
	outportb(D12_COMMAND, 0x40 + bEndp);
	outportb(D12_DATA, bStalled);
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
}


/*读端点缓冲区同时清缓冲区,包含读缓冲区命令:F0H*/
/*以及清缓冲区命令:F2H*/
unsigned char D12_ReadEndpoint(unsigned char endp, unsigned char len,unsigned char * buf)
{
	unsigned char i, j;
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
	outportb(D12_COMMAND, endp);
	if((inportb(D12_DATA) & D12_FULLEMPTY) == 0) 
	{
		if(bEPPflags.bits.in_isr == 0)
			ENABLE;
		return 0;
	}
	outportb(D12_COMMAND, 0xF0);
	j = inportb(D12_DATA);
	j = inportb(D12_DATA);
	if(j > len)
		j = len;
	for(i=0; i<j; i++)
		*(buf+i) = inportb(D12_DATA);
	outportb(D12_COMMAND, 0xF2);
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
	return j;
}


/*写端点缓冲区同时使缓冲区有效,包含写缓冲区命令:F0H*/
/*以及使缓冲区有效命令:FAH*/
unsigned char D12_WriteEndpoint(unsigned char endp, unsigned char len,unsigned char * buf) 
{
	unsigned char i;
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
	outportb(D12_COMMAND, endp);
	inportb(D12_DATA);
	outportb(D12_COMMAND, 0xF0);
	outportb(D12_DATA, 0);
	outportb(D12_DATA, len);
	for(i=0; i<len; i++)
		outportb(D12_DATA, *(buf+i));
	outportb(D12_COMMAND, 0xFA);
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
	return len;
}

/*写端点缓冲区同时使缓冲区有效,专用于中断函数*/
unsigned char D12_WriteEndpointIsr(unsigned char endp, unsigned char len,unsigned char * buf)
{
	unsigned char i;
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
	outportb(D12_COMMAND, endp);
	inportb(D12_DATA);
	outportb(D12_COMMAND, 0xF0);
	outportb(D12_DATA, 0);
	outportb(D12_DATA, len);
	for(i=0; i<len; i++)
		outportb(D12_DATA, *(buf+i));
	outportb(D12_COMMAND, 0xFA);
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
	return len;
}

/*应答SETUP命令:F1H*/
void D12_AcknowledgeEndpoint(unsigned char endp)
{
	outportb(D12_COMMAND, endp);
	outportb(D12_COMMAND, 0xF1);
	if(endp == 0)
		outportb(D12_COMMAND, 0xF2);
}


//this part from chap_9.c
USB_DEVICE_DESCRIPTOR DeviceDescr =
{
	sizeof(USB_DEVICE_DESCRIPTOR),
    USB_DEVICE_DESCRIPTOR_TYPE,
    0x0110,
    USB_CLASS_CODE_TEST_CLASS_DEVICE,
    0, 0,
	EP0_PACKET_SIZE,
	0x0471,//0x0471,
	0x0691,
	0x0100,
    0, 0, 0,
	1
};


CON_INT_ENDP_DESCRIPTOR_STRUCT TRANFER_DESC =
{
{
    sizeof(USB_CONFIGURATION_DESCRIPTOR),
    USB_CONFIGURATION_DESCRIPTOR_TYPE,
    CONFIG_DESCRIPTOR_LENGTH,
	1,
	1,
    0,
    0x60,//0x9F,   //	0x80,
	0xC8//0x32
},

{
    sizeof(USB_INTERFACE_DESCRIPTOR),
    USB_INTERFACE_DESCRIPTOR_TYPE,
    0,
    0,
	NUM_ENDPOINTS,
	USB_CLASS_CODE_TEST_CLASS_DEVICE,
	USB_SUBCLASS_CODE_TEST_CLASS_D12,
	USB_PROTOCOL_CODE_TEST_CLASS_D12,
	0
},

{
	sizeof(USB_ENDPOINT_DESCRIPTOR),
	USB_ENDPOINT_DESCRIPTOR_TYPE,
	0x81,
	USB_ENDPOINT_TYPE_INTERRUPT,
	EP1_PACKET_SIZE,
	10
},

{
	sizeof(USB_ENDPOINT_DESCRIPTOR),
	USB_ENDPOINT_DESCRIPTOR_TYPE,
	0x1,
	USB_ENDPOINT_TYPE_INTERRUPT,
	EP1_PACKET_SIZE,
	10
},

{
	sizeof(USB_ENDPOINT_DESCRIPTOR),
	USB_ENDPOINT_DESCRIPTOR_TYPE,
	0x82,
	USB_ENDPOINT_TYPE_BULK,
	EP2_PACKET_SIZE,
	10
},

{
	sizeof(USB_ENDPOINT_DESCRIPTOR),
	USB_ENDPOINT_DESCRIPTOR_TYPE,
	0x2,
	USB_ENDPOINT_TYPE_BULK,
	EP2_PACKET_SIZE,
	10
}
};

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

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

void reserved(void)
{
	stall_ep0();
}

void init_unconfig(void)
{
	D12_SetEndpointEnable(0);	/* Disable all endpoints but EPP0. */
}

void init_config(void)
{
	D12_SetEndpointEnable(1);	/* Enable  generic/iso endpoints. */
}

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) {
		if(bEPPflags.bits.remote_wakeup == 1)
			txdat[0] = 3;
		else
			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)
			c = D12_SelectEndpoint(endp*2 + 1);	/* Control-in */
		else
			c = 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) {
		DISABLE;
		bEPPflags.bits.remote_wakeup = 0;
		ENABLE;
		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)
{
	unsigned char endp;
	unsigned char bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
	if (bRecipient == USB_RECIPIENT_DEVICE
		&& ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP) {
		DISABLE;
		bEPPflags.bits.remote_wakeup = 1;
		ENABLE;
		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);

⌨️ 快捷键说明

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