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);
}