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

📄 usbd12.c

📁 smp860运动控制器USB驱动,对从事数控技术开发人员非常有用
💻 C
字号:
/************************************************************************
 *File	: Usbd12.c														*
 *By 	: hugang, hgx2000@mail.china.com								*
 替换以前的USBCMD.c文件
 ************************************************************************/ 

#include "usb.h"

/************************************************************************************************
 *设置地址使能命令																				*
 *命令代码: D0																					*
 *处理:写一个字节																				*
 ************************************************************************************************/
void UsbSetAddressEnable(unsigned char bAddress, unsigned char bEnable)
{
	if(bUSBFlags.bits.bIn_ISR == 0) USB_DISABLE_INTERRUPT;
	
	outportb_D12(D12_COMMAND, 0xD0);								
	
	if(bEnable) bAddress |= 0x80;								
	
	outportb_D12(D12_DATA, bAddress);						
	
	if(bUSBFlags.bits.bIn_ISR == 0) USB_ENABLE_INTERRUPT;
}

/************************************************************************************************
 *设置端点使能命令																				*
 *命令代码: D8																					*
 *处理: 写一个字节																				*
 ************************************************************************************************/
void UsbSetEndpointEnable(unsigned char bEnable)
{
	if(bUSBFlags.bits.bIn_ISR == 0) USB_DISABLE_INTERRUPT;
	
	outportb_D12(D12_COMMAND, 0xD8);								
	
	if(bEnable) outportb_D12(D12_DATA, 1);							
	else outportb_D12(D12_DATA, 0);
	
	if(bUSBFlags.bits.bIn_ISR == 0) USB_ENABLE_INTERRUPT;						
}

/************************************************************************************************
 *设置模式命令																					*
 *命令代码: F3																					*
 *处理: 写两个字节	1.模式字节  2.时钟分频系数字节												*
 ************************************************************************************************/
void UsbSetMode(unsigned char bConfig, unsigned char bClkDiv)
{
	if(bUSBFlags.bits.bIn_ISR == 0) USB_DISABLE_INTERRUPT;
	
	outportb_D12(D12_COMMAND, 0xF3);								
	outportb_D12(D12_DATA, bConfig);								
	outportb_D12(D12_DATA, bClkDiv);								
	
	if(bUSBFlags.bits.bIn_ISR == 0) USB_ENABLE_INTERRUPT;
}

/************************************************************************************************
 *设置DMA命令																					*
 *命令代码: F8																					*
 *处理:写一个字节																				*
 ************************************************************************************************/
void UsbSetDMA(unsigned char bMode)
{
	if(bUSBFlags.bits.bIn_ISR == 0) USB_DISABLE_INTERRUPT;
	
	outportb_D12(D12_COMMAND, 0xFB);								
	outportb_D12(D12_DATA, bMode);									
	
	if(bUSBFlags.bits.bIn_ISR == 0) USB_ENABLE_INTERRUPT;
}

/************************************************************************************************
 *读取中断寄存器命令																			*
 *命令代码: F4																					*
 *处理: 读两个字节																				*
 ************************************************************************************************/
unsigned short UsbReadInterruptRegister(void)
{
	volatile unsigned char b1;
	volatile unsigned short j;
	
	outportb_D12(D12_COMMAND, 0xF4);								
	b1 = inportb_D12(D12_DATA);									
	j = (unsigned short)inportb_D12(D12_DATA);									
	j <<= 8;
	j += (unsigned short)b1;
	return j;
	
}

/************************************************************************************************
 *选择端点命令																					*
 *命令代码: 00 + bEndp																			*
 *处理: 写一个字节																				*
 ************************************************************************************************/
unsigned char UsbSelectEndpoint(unsigned char bEndp)
{
	volatile unsigned char c;
	
	if(bUSBFlags.bits.bIn_ISR == 0) USB_DISABLE_INTERRUPT;
	
	outportb_D12(D12_COMMAND, bEndp);
	c = inportb_D12(D12_DATA);										
	
	if(bUSBFlags.bits.bIn_ISR == 0) USB_ENABLE_INTERRUPT;
	
	return c;
}

/************************************************************************************************
 *读取端点最后处理状态																			*
 *命令代码: 40 + bEndp																			*
 *处理: 读一个字节																				*
 ************************************************************************************************/
unsigned char UsbReadLastTransactionStatus(unsigned char bEndp)
{
	outportb_D12(D12_COMMAND, 0x40 + bEndp);					
	
	return inportb_D12(D12_DATA);
}

/************************************************************************************************
 *读取端点状态																					*
 *命令代码: 80 + bEndp																			*
 *处理: 读一个字节																				*
 ************************************************************************************************/
unsigned char UsbReadEndpointStatus(unsigned char bEndp)
{
	volatile unsigned char c;
	
	if(bUSBFlags.bits.bIn_ISR == 0) USB_DISABLE_INTERRUPT;
	
	outportb_D12(D12_COMMAND, 0x80 + bEndp);					
	c = inportb_D12(D12_DATA);
	
	if(bUSBFlags.bits.bIn_ISR == 0) USB_ENABLE_INTERRUPT;
	
	return c;
}

/************************************************************************************************
 *设置端点状态																					*
 *命令代码: 40 + bEndp																			*
 *处理: 写一个字节																				*
 ************************************************************************************************/
void UsbSetEndpointStatus(unsigned char bEndp, unsigned char bStalled)
{
	if(bUSBFlags.bits.bIn_ISR == 0) 
	    USB_DISABLE_INTERRUPT;
	
	outportb_D12(D12_COMMAND, 0x40 + bEndp);
	outportb_D12(D12_DATA, bStalled);
	
	if(bUSBFlags.bits.bIn_ISR == 0) 
	    USB_ENABLE_INTERRUPT;
}

/************************************************************************************************
 *发送恢复命令																					*
 *命令代码: F6																					*
 *处理: 读两个字节																				*
 ************************************************************************************************/
void UsbSendResume(void)
{
	outportb_D12(D12_COMMAND, 0xF6);
}


/************************************************************************************************
 *读取当前帧标志																				*
 *命令代码: F5																					*
 *处理: 读两个字节																				*
 ************************************************************************************************/
unsigned short UsbReadCurrentFrameNumber(void)
{
	volatile unsigned short i,j;
	
	if(bUSBFlags.bits.bIn_ISR == 0) USB_DISABLE_INTERRUPT;
	
	outportb_D12(D12_COMMAND, 0xF5);
	i= inportb_D12(D12_DATA);
	j = inportb_D12(D12_DATA);
	i += (j<<8);
	
	if(bUSBFlags.bits.bIn_ISR == 0) USB_ENABLE_INTERRUPT;
	
	return i;
}

/************************************************************************************************
 *读取端点数据																					*
 *命令代码: F0																					*
 *处理: 读n字节,n<len,返回读取字节的长度														*
 ************************************************************************************************/
unsigned char UsbReadEndpoint(unsigned char endp, unsigned char * buf, unsigned char len)
{
	volatile unsigned char i, j;
	
	outportb_D12(D12_COMMAND, endp);						// 选择端点
	if((inportb_D12(D12_DATA) & USB_D12_FULLEMPTY) == 0) 
	{		// 判断端点缓冲区状态,若未满则返回
		return 0;
	}
	
	outportb_D12(D12_COMMAND, 0xF0);						// 读缓冲命令
	j = inportb_D12(D12_DATA);
	j = inportb_D12(D12_DATA);								// 获取字节长度
	
	if(j > len)	j = len;
	
	for(i=0; i<j; i++)
		*(buf+i) = inportb_D12(D12_DATA);
		
	outportb_D12(D12_COMMAND, 0xF2);						// 缓冲区清零
	
	return j;
}

/************************************************************************************************
 *把数据写入端点																				*
 *命令代码: F0																					*
 *处理: 写n字节,n=len																			*
 ************************************************************************************************/
unsigned char UsbWriteEndpoint(unsigned char endp, unsigned char * buf, unsigned char len)
{
	volatile unsigned char i;

	outportb_D12(D12_COMMAND, endp);						// 选择端点	
	i = inportb_D12(D12_DATA);									// 端点状态
	
	outportb_D12(D12_COMMAND, 0xF0);						// 写缓冲区命令
	outportb_D12(D12_DATA, 0);								// 向缓冲区填充数据
	outportb_D12(D12_DATA, len);
	for(i=0; i<len; i++) 
	    outportb_D12(D12_DATA, *(buf+i));
	
	outportb_D12(D12_COMMAND, 0xFA);						// 使缓冲区有效
	
	return len;
}

/************************************************************************************************
 *端点应当处理																					*
 *命令代码: F1																					*
 *处理: 																						*
 ************************************************************************************************/
void UsbAcknowledgeEndpoint(unsigned char endp)
{
	outportb_D12(D12_COMMAND, endp);						// 选择端点
	outportb_D12(D12_COMMAND, 0xF1);
	if(endp == 0) outportb_D12(D12_COMMAND, 0xF2);
}


unsigned char UsbReadMainEndpoint(unsigned char * buf)
{
    unsigned char i, j,  bDblBuf;
    unsigned short k;
    
    //_UsbSendCmd(0x84);
    //_UsbRecData(&i,1);
    
    bDblBuf = 1;
    
    k = 0;
    outportb_D12(D12_COMMAND, 0x84);   //读端点状态
    i = inportb_D12(D12_DATA);         //i,读出的数据结构:端点停止 缓冲区1满 缓冲区0满 bit【4,3】保留 设置包 bit【1,0】保留
    
    if(( i & 0x60) == 0x60)        //查缓冲区0,1是否同时满
    {
        bDblBuf = 2;
    }
    
    while(bDblBuf) 
    {
        
        outportb_D12(D12_COMMAND, 0x04);            //选择缓冲区
        i = inportb_D12(D12_DATA);                  //i 的结构   bit[0] 满/空  1表示缓冲区已满0 表示缓冲区为空  bit[1] 停止1表示选择的端点处于停止状态
        
        if((i & D12_FULLEMPTY) == 0)            //D12_FULLEMPTY 0x01  查 满/空标志  如果是空则推出
            break;
        
        outportb_D12(D12_COMMAND, 0xf0);            //读多个字节
        j = inportb_D12(D12_DATA);                  //  读缓冲区字节结构,字节1:保留;可为任意值 
        j = inportb_D12(D12_DATA);                  //数据字节的数目/长度
        
        UsbRecData((unsigned char *)(buf+k),j);  //数据字节
        
        k += j;
        outportb_D12(D12_COMMAND, 0xf2);   //清除缓冲区
        bDblBuf --;
    }
    return k;
}

⌨️ 快捷键说明

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