www.pudn.com > CAN_USB.rar > D12.h


void Output(UINT addr, UCHAR data) 
{	 
	if(addr == D12_DATA_HARD) 
		D12_A0_0; 
	else 
		D12_A0_1;	 
	 
	D12_CMD = data; 
} 
 
UINT Input() 
{ 
	D12_A0_0;	 
	 
	return D12_DATA; 
} 
 
//设置地址使能 
void D12_SetAddressEnable(UINT bAddress, UCHAR bEnable) 
{ 
	Output(D12_CMD_HARD , 0xD0);//输出指令 
	if(bEnable) 
		bAddress |= 0x80; 
	 
	Output(D12_DATA_HARD , bAddress);//设置地址 
} 
 
 
//设置端点使能 
void D12_SetEndpointEnable(UCHAR bEnable) 
{ 
	Output(D12_CMD_HARD , 0xD8);//输出指令 
	 
	if(bEnable) 
		Output(D12_DATA_HARD , 1);//设置端点允许 
	else 
		Output(D12_DATA_HARD , 0);//设置端点禁止 
} 
 
//模式设置 
void D12_SetMode(UCHAR bConfig, UCHAR bClkDiv) 
{ 
	Output(D12_CMD_HARD , 0xF3);//设置模式 
	Output(D12_DATA_HARD , bConfig); 
	Output(D12_DATA_HARD , bClkDiv); 
} 
 
//读取中断寄存器 
UCHAR D12_ReadInterruptRegister(void) 
{ 
	unsigned int b1; 
	unsigned int j; 
 
	Output(D12_CMD_HARD , 0xF4);//读取中断寄存器 
	b1 = Input(); 
	j = Input(); 
 
	j <<= 8;  
	j = j & 0xFF00; 
	b1 = b1 & 0x00FF; 
	j += b1; 
 
	return j; 
} 
 
//端点选择 
UCHAR D12_SelectEndpoint(UCHAR bEndp) 
{ 
	UCHAR c; 
 
	Output(D12_CMD_HARD , bEndp);//端点选择 
	c = Input(); 
 
	return c; 
} 
     
//读取最后传输状态 
UCHAR D12_ReadLastTransactionStatus(UCHAR bEndp) 
{ 
	Output(D12_CMD_HARD , 0x40 + bEndp);//返回最后传输状态 
	return Input(); 
} 
 
 
//读取端点状态 
UCHAR D12_ReadEndpointStatus(UCHAR bEndp) 
{ 
	UCHAR c; 
 
	Output(D12_CMD_HARD , 0x80 + bEndp);//读取端点状态 
	c = Input(); 
 
	return c; 
}     
 
//设置端点状态 
void D12_SetEndpointStatus(UCHAR bEndp, UCHAR bStalled) 
{ 
	Output(D12_CMD_HARD , 0x40 + bEndp);//设置端点状态 
	Output(D12_DATA_HARD , bStalled); 
} 
 
//读取端点数据 
UINT D12_ReadEndpoint(UCHAR endp, UINT len, UCHAR * buf) 
{ 
	UINT i, j; 
 
	Output(D12_CMD_HARD , endp); 
	if((Input() & 0x01) == 0) 
		return 0; 
 
	Output(D12_CMD_HARD , 0xF0); 
	j = Input(); 
	j = Input(); 
 
	if(j > len) 
		j = len; 
 
	for(i=0; i len) 
		EP0_Request_wLength = len; 
 
	EP0_Request_PData = pRomData; 
	if( EP0_Request_wLength >= 16) 
    { 
		D12_WriteEndpoint(1, 16, EP0_Request_PData);//发送16字节数据 
		EP0_Request_wCount += 16; 
	    EP0_state = TRANSMIT; 
	} 
	else 
    { 
		D12_WriteEndpoint(1, EP0_Request_wLength, pRomData);//发送16字节内数据 
		EP0_Request_wCount += EP0_Request_wLength; 
        EP0_state = IDLE; 
	} 
} 
 
//返回stall应答 
void stall_ep0(void) 
{ 
	D12_SetEndpointStatus(0, 1); 
	D12_SetEndpointStatus(1, 1); 
} 
 
//从端点号1发送数据 
void single_transmit(UCHAR * buf, UINT len) 
{ 
	if( len <= 16) { 
		D12_WriteEndpoint(1, len, buf); 
	} 
} 
 
//获取描述符 
void get_descriptor(void) 
{ 
	UINT bDescriptor = device_request.wValue>>8; 
 
	if (bDescriptor == 0x01) {//获取设备描述符 
		code_transmit(DeviceDescr, 18); 
	} else if (bDescriptor == 0x02) {//获取配置描述符 
		code_transmit(ConfigDescr, 0x2e); 
	} else 
		stall_ep0(); 
} 
 
//设置地址 
void set_address(void) 
{ 
	D12_SetAddressEnable(device_request.wValue,1); 
	single_transmit(0, 0); 
} 
 
//设置配置状态 
void set_configuration(void) 
{ 
	if (device_request.wValue == 0) //设备进入未配置状态 
    { 
		single_transmit(0, 0); 
		D12_SetEndpointEnable(0); 
	} 
    else if (device_request.wValue == 1)  //配置设备 
    { 
    	USB_D12_OK = 1; 
		single_transmit(0, 0); 
		D12_SetEndpointEnable(1); 
	} 
    else 
		stall_ep0(); 
}   
 
void Set_Interface() 
{ 
    if (device_request.wValue == 0 && device_request.wIndex == 0) 
		single_transmit(0, 0); 
	else 
		stall_ep0(); 
} 
 
UINT GML = 0; 
void Get_Max_Lun() 
{ 
    D12_SetEndpointEnable(1); 
    //single_transmit(&GML, 1); 
    D12_WriteEndpoint(1, 1, &GML); 
} 
 
#define CMD_EXE_SUCCESS		0xAB 
#define CMD_EXE_FAILED		0x00 
 
#define ONLY_CAN0					0x00 
#define ONLY_CAN1					0x01 
#define CAN0_AND_CAN1				0x02 
 
#define CMD_OPEN_OR_CLOSE			0x01 
#define CMD_SET_BTR					0x02 
#define CMD_REQ_TEST				0x0E 
 
#define VLU_CLOSE_CAN				0x00 
#define VLU_OPEN_CAN				0x01 
 
#define	VLU_BTR_125k				0xD887 
#define	VLU_BTR_250k				0xD883 
#define	VLU_BTR_500k				0xD881 
 
void LW_Request(UINT req)//req是一个字节 
{	 
	UINT len = 0; 
	 
	if(device_request.bmRequestType & 0x80)//PC需要设备向上传输数据 
	{ 
		CMD_EXE_STATUS[0] = device_request.bRequest; 
		CMD_EXE_STATUS[1] = (UCHAR)device_request.wValue; 
		CMD_EXE_STATUS[2] = (UCHAR)(device_request.wValue>>8); 
		CMD_EXE_STATUS[3] = (UCHAR)device_request.wIndex; 
		CMD_EXE_STATUS[4] = (UCHAR)(device_request.wIndex>>8); 
		CMD_EXE_STATUS[5] = 0;//保留 
		CMD_EXE_STATUS[6] = 0;//保留 
		CMD_EXE_STATUS[7] = CMD_EXE_FAILED; 
		 
		switch(req) 
		{			 
			case CMD_REQ_TEST://(测试使用的) 
				EP0_Request_PData = my_buf; 
				 
				if(EP0_Request_wLength > 16) 
				{ 
					single_transmit(EP0_Request_PData, 16);	 
					EP0_Request_wCount += 16; 
					EP0_state = TRANSMIT; 
				} 
				else if(EP0_Request_wLength != 0) 
				{ 
					single_transmit(EP0_Request_PData, EP0_Request_wLength);	 
					EP0_Request_wCount += EP0_Request_wLength; 
					EP0_state = IDLE; 
				} 
				else if(EP0_Request_wLength == 0) 
				{ 
					D12_WriteEndpoint(1, 0, 0); 
					EP0_state = IDLE; 
				} 
				break; 
			case CMD_OPEN_OR_CLOSE://注意:这里要求返回的字节数一定是8 
				if(device_request.wIndex == ONLY_CAN0) 
				{ 
					if(device_request.wValue == VLU_OPEN_CAN) 
					{ 
						CAN0RIER = 0x01;//使能CAN0接受中断	 
						CAN0_RX_LED_ON; 
					} 
					else if(device_request.wValue == VLU_CLOSE_CAN) 
					{ 
						CAN0RIER = 0x00;// 
						CAN0_RX_LED_OFF; 
					} 
				} 
				else if(device_request.wIndex == ONLY_CAN1) 
				{ 
					if(device_request.wValue == VLU_OPEN_CAN) 
					{ 
						CAN1RIER = 0x01;//使能CAN1接受中断	 
						CAN1_RX_LED_ON; 
					} 
					else if(device_request.wValue == VLU_CLOSE_CAN) 
					{ 
						CAN1RIER = 0x00;// 
						CAN1_RX_LED_OFF; 
					} 
				} 
				else if(device_request.wIndex == CAN0_AND_CAN1) 
				{ 
					if(device_request.wValue == VLU_OPEN_CAN) 
					{ 
						CAN0RIER = 0x01; 
						CAN1RIER = 0x01;	 
						CAN0_RX_LED_ON; 
						CAN1_RX_LED_ON; 
					} 
					else if(device_request.wValue == VLU_CLOSE_CAN) 
					{ 
						CAN0RIER = 0x00; 
						CAN1RIER = 0x00;	 
						CAN0_RX_LED_OFF; 
						CAN1_RX_LED_OFF; 
					} 
				}			 
								 
				CMD_EXE_STATUS[7] = CMD_EXE_SUCCESS; 
				break;	 
								 
			case CMD_SET_BTR: 
				CAN_BTR0 = (UCHAR)device_request.wValue; 
				CAN_BTR1 = (UCHAR)(device_request.wValue>>8); 
				if(device_request.wIndex == 0)//设置CAN0的波特率 
				{					 
					CAN0_Initial(); 
				} 
				else if(device_request.wIndex == 1)//设置CAN1的波特率 
				{ 
					CAN1_Initial(); 
				} 
				else if(device_request.wIndex == 2)//设置CAN0和CAN1的波特率 
				{ 
					CAN0_Initial(); 
					CAN1_Initial(); 
				}	 
				//注意初始化之后,CAN端口接收中断是关闭的. 
				 
				CMD_EXE_STATUS[7] = CMD_EXE_SUCCESS;			 
				break; 
			default: 
				;				 
		} 
		if(req == CMD_REQ_TEST) 
			return; 
		 
		//回复8个字节的状态字 
		EP0_Request_PData = CMD_EXE_STATUS;		 
		single_transmit(EP0_Request_PData, 8);	 
		EP0_state = IDLE; 
	} 
	else//PC不需要设备向上传输数据 
	{ 
		switch(req) 
		{			 
			case 0x01: 
			 
				break; 
			case 0x02: 
				break; 
			case 0x03: 
				break; 
			default : 
				; 
		} 
	} 
	 
} 
 
void EP0_Out() 
{ 
    UCHAR ep_last; 
 
	ep_last = D12_ReadLastTransactionStatus(0); //清中断标志	 
 
	if (ep_last & 0x20)  //接收到SETUP包++++++++++ 
    {    	 
		EP0_Request_wLength = 0; 
		EP0_Request_wCount = 0; 
 
		if( D12_ReadEndpoint(0,8,&device_request) != 8) 
        { 
			//SETUP包出错,返回 
			D12_SetEndpointStatus(0, 1); 
			D12_SetEndpointStatus(1, 1); 
			return; 
		}		 
		 
		device_request.wValue = SWAP(device_request.wValue); 
		device_request.wIndex = SWAP(device_request.wIndex); 
		device_request.wLength = SWAP(device_request.wLength); 
		 
		//对控制端点的输入/输出进行应答 
		D12_AcknowledgeEndpoint(0); 
		D12_AcknowledgeEndpoint(1);		 
 
		EP0_Request_wLength = device_request.wLength; 
		EP0_Request_wCount = 0; 
 
        if(device_request.bmRequestType == 0xA1)//GET MAX LUN 
        { 
             Get_Max_Lun(); 
             return; 
        } 
        if(device_request.bmRequestType == 0x01)//Set_Interface 
        { 
             Set_Interface(); 
             return; 
        } 
        if((device_request.bmRequestType & 0x60) == 0x40)//厂商请求 
        { 
        	LW_Request(device_request.bRequest);//USB命令接收历程 
        	return; 
        } 
 
		if (device_request.bmRequestType & 0x80) //从主机传输数据 
            get_descriptor();    //获取设备描述符或者配置描述符    get command 
		else if (device_request.wLength == 0) 
        { 
			if(device_request.bRequest == 0x05) 
                set_address();    // set command 
            else if(device_request.bRequest == 0x09) 
                set_configuration();   // set command 
            else 
                stall_ep0(); 
		} 
    }//接收到SETUP包----------- 
    else 
    {    	 
    	EP0_Receive_wLength = 0;//注意:这句话放在这里不合适 
		EP0_Receive_wCount = 0;//注意:这句话放在这里不合适 
		 
		EP0_Receive_wLength = D12_ReadEndpoint(0,16,EP0_Receive_PData); 
		 
		//对控制端点的输入/输出进行应答 
		D12_AcknowledgeEndpoint(0); 
		D12_AcknowledgeEndpoint(1); 
		 
		//下面对所收到的数据进行处理... 
		; 
    } 
} 
 
void EP0_In() 
{ 
    unsigned int i = EP0_Request_wLength - EP0_Request_wCount; 
 
	D12_ReadLastTransactionStatus(1); //清中断标志位 
 
	if (EP0_state != TRANSMIT) 
		return;//非发送状态,返回 
 
	if( i >= 16)       //剩下数据大于16字节,发送16字节 
    { 
		D12_WriteEndpoint(1, 16, EP0_Request_PData + EP0_Request_wCount); 
		EP0_Request_wCount += 16; 
		EP0_state = TRANSMIT; 
	} 
	else if( i != 0)   //发送剩下数据 
    { 
		D12_WriteEndpoint(1, i, EP0_Request_PData + EP0_Request_wCount); 
		EP0_Request_wCount += i; 
		EP0_state = IDLE; 
	} 
	else if (i == 0)   //发送完毕,发送0字节 
    { 
		D12_WriteEndpoint(1, 0, 0); 
		EP0_state = IDLE; 
	} 
} 
 
UINT EP1_Send_to_PC(ULONG len,UINT * buf) 
{ 
//以下代码为测试使用 
	int i = 0; 
	for(i=0;i<64;i++) 
		EP1_Request_PData[i] = i;//注意:这里并没有使用函数传进来的buf。 
		 
	if (EP1_state != TRANSMIT) 
		return 0;//非发送状态,返回 
 
	if( len >= 16)       //剩下数据大于16字节,发送16字节 
    { 
		D12_WriteEndpoint(3, 16, EP1_Request_PData + (EP1_Request_wCount%64)); 
		EP1_Request_wCount += 16; 
		EP1_state = TRANSMIT; 
		return 16; 
	} 
	else if( len != 0)   //发送剩下数据 
    { 
		D12_WriteEndpoint(3, len, EP1_Request_PData + (EP1_Request_wCount%64)); 
		EP1_Request_wCount += len; 
		EP1_state = IDLE; 
		return len; 
	} 
	else if (len == 0)   //发送完毕,发送0字节 
    { 
		D12_WriteEndpoint(3, 0, 0); 
		EP1_state = IDLE; 
		return len; 
	}		 
} 
 
void EP1_Out() 
{ 
	UINT len = 0; 
	 
	D12_ReadLastTransactionStatus(2); //清中断标志位 
	 
	//对EP1端点的输入/输出进行应答 
	D12_AcknowledgeEndpoint(2); 
	 
	len = D12_ReadEndpoint(2,sizeof(EP1_Out_buf),EP1_Out_buf);	 
	 
	if(len == 4)//测试代码++++++++++++++++++++++ 
	{ 
		EP1_CMD = (0xFF00 & (EP1_Out_buf[0]<<8)) + (0x00FF & EP1_Out_buf[1]); 
		EP1_Request_wLength = (0xFF00 & (EP1_Out_buf[2]<<8)) + (0x00FF & EP1_Out_buf[3]); 
				 
		switch(EP1_CMD) 
		{ 
			case 0xAAAA: 
				EP1_Request_wCount = 0; 
				EP1_state = TRANSMIT; 
				EP1_Send_to_PC(EP1_Request_wLength-EP1_Request_wCount,EP1_Request_PData);				 
				break; 
			case 0xBBBB: 
				; 
				break; 
			default: 
				;		 
		} 
	}//测试代码--------------------------- 
} 
 
void EP1_In() 
{	 
	D12_ReadLastTransactionStatus(3); //清中断标志位	 
	D12_AcknowledgeEndpoint(3); 
	 
	if(EP1_Request_wLength > EP1_Request_wCount) 
		EP1_Send_to_PC(EP1_Request_wLength-EP1_Request_wCount,EP1_Request_PData);	 
} 
 
UINT EP2_Send_to_PC(ULONG len,UCHAR * buf) 
{ 
	if (EP2_state != TRANSMIT) 
		return 0;//非发送状态,返回 
 
	if( len >= 64)       //剩下数据大于64字节,发送64字节 
    { 
		D12_WriteEndpoint(5, 64, buf + EP2_Request_wCount); 
		EP2_Request_wCount += 64; 
		EP2_state = TRANSMIT; 
		return 64; 
	} 
	else if( len != 0)   //发送剩下数据 
    { 
		D12_WriteEndpoint(5, len, buf + EP2_Request_wCount); 
		EP2_Request_wCount += len; 
		EP2_state = IDLE; 
		return len; 
	} 
	else if (len == 0)   //发送完毕,发送0字节 
    { 
		D12_WriteEndpoint(5, 0, 0); 
		EP2_state = IDLE; 
		return len; 
	}		 
} 
 
void EP2_Out() 
{ 
	UINT len,epstatus,i; 
	ULONG CAN_packet_length; 
 
	 
	D12_ReadLastTransactionStatus(4); //清中断标志位 
	epstatus = D12_ReadEndpointStatus(4); 
	epstatus &= 0x60; 
	 
	//接受数据 现在还没有处理一次接收大于64字节的数据. 
	len = D12_ReadEndpoint(4,64,EP2_Out_buf); 
	if(epstatus == 0x60) 
		len = D12_ReadEndpoint(4,64,EP2_Out_buf);//读取双缓冲区的数据 
		 
	//对EP2端点的输入/输出进行应答 
	D12_AcknowledgeEndpoint(4);	 
	 
	if(len != 0)//测试代码++++++++++++++++++++++ 
	{ 
		EP2_CMD = (0xFF00 & (EP2_Out_buf[0]<<8)) + (0x00FF & EP2_Out_buf[1]); 
		EP2_Request_wLength = (0xFF00 & (EP2_Out_buf[2]<<8)) + (0x00FF & EP2_Out_buf[3]); 
				 
		switch(EP2_CMD) 
		{ 
		//----------------------------------------------------------------------------------------- 
			case 0x0001://读取CAN接收的数据 
				EP2_Request_wCount = 0; 
				EP2_state = TRANSMIT; 
				CAN_packet_length = 4 + 4 + USB_Packet.USB_Packet_struct.CAN_frame_num*sizeof(ASCL_CAN_OBJ) + 4; 
				if(CAN_packet_length > EP2_Request_wLength) 
					CAN_packet_length = EP2_Request_wLength; 
				else 
					EP2_Request_wLength = CAN_packet_length; 
				 
				USB_Packet.Bytes[CAN_packet_length-1] = 0xCD;//USB_Packet.USB_Packet_struct.end; 
				 
				EP2_Request_PData = USB_Packet.Bytes; 
				EP2_Send_to_PC(EP2_Request_wLength-EP2_Request_wCount,EP2_Request_PData); 
				 
				for(i=0;i EP2_Request_wCount) 
		EP2_Send_to_PC(EP2_Request_wLength-EP2_Request_wCount,EP2_Request_PData);			 
}