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

📄 usb.c

📁 usb1.1程序,PHILIP 1.1的芯片
💻 C
📖 第 1 页 / 共 2 页
字号:
unsigned char D12_FULLEMPTY;
unsigned char D12_INT_BUSRESET;
unsigned char D12_INT_SUSPENDCHANGE;
unsigned char D12_INT_ENDP0IN;
unsigned char D12_INT_ENDP0OUT;
unsigned char D12_INT_ENDP1IN;
unsigned char D12_INT_ENDP1OUT;
unsigned char D12_INT_ENDP2IN;
unsigned char D12_INT_ENDP2OUT;
unsigned char D12_SETUPPACKET;
unsigned char USB_IDLE;
unsigned char USB_TRANSMIT;
unsigned char USB_RECEIVE;
unsigned char USB_ENDPOINT_DIRECTION_MASK;
unsigned char MAX_CONTROLDATA_SIZE;
unsigned char EP0_PACKET_SIZE;
unsigned char EP1_PACKET_SIZE;
unsigned char EP2_PACKET_SIZE;
unsigned char GenEpBuf[4];
unsigned char EpBuf[64];
unsigned char USB_REQUEST_TYPE_MASK;
unsigned char USB_REQUEST_MASK;
unsigned char USB_STANDARD_REQUEST;
unsigned char USB_RECIPIENT;
unsigned char USB_RECIPIENT_DEVICE;
unsigned char USB_RECIPIENT_INTERFACE;
unsigned char USB_RECIPIENT_ENDPOINT;
unsigned char MAX_ENDPOINTS;
unsigned char D12_STALL;
unsigned char DEVICE_ADDRESS_MASK;
unsigned int USB_FEATURE_REMOTE_WAKEUP;
unsigned char USB_DEVICE_DESCRIPTOR_TYPE;
unsigned int USB_FEATURE_ENDPOINT_STALL;
unsigned char D12_NOLAZYCLOCK;
unsigned char D12_SETTOONE;
unsigned char D12_CLOCK_12M;
unsigned char D12_SOFTCONNECT;
unsigned char DeviceDescr[12]={0x12,0x01,0x10,0x01,0x0dc,0x00,0x00,0x10,0x71,0x04,0x66,
                               0x06,0x00,0x01,0x00,0x00,0x00,0x01};
unsigned char ConfigDescr[46]={0x09,0x02,0x2e,0x00,0x01,0x01,0x00,0x0a0,0x32,0x09,0x04,0x00,
                               0x00,0x04,0x0dc,0x0a0,0x0b0,0x00,0x07,0x05,0x81,0x03,0x10,
                               0x00,0x0a,0x07,0x05,0x01,0x03,0x10,0x00,0x0a,0x07,0x05,0x82,
                               0x02,0x40,0x00,0x0a,0x07,0x05,0x02,0x02,0x40,0x00,0x0a};
                               
typedef union_epp_flags//USB事件标志
{struct_flags
 {unsigned char timer;//时间溢出
  unsigned char bus_reset;//总线复位标志
  unsigned char suspend;//挂起改变标志
  unsigned char setup_packet;//收到SETUP包
  unsigned char remote_wakeup;//远程唤醒标志(未使用)
  unsigned char in_isr;//USB中断服务标志
  unsigned char control_state;//控制端点处理状态:0为空闲IDEL,1为发送TRANSMIT,2为接收RECEIVE
  unsigned char configuration;//配置标志:0为未配置,1为已配置
  unsigned char command://未使用
  unsigned char ep1_rxdone;//端点1收到数据标志
  unsigned char ep2_rxdone;//端点2收到数据标志
  unsigned char ep1buf_full;//端点1输出双缓冲区满标志
  unsigned char ep2buf_full;//端点2输出双缓冲区满标志
 }bits;
 unsigned short value
}EPPFLAGS;
typedef struct_device_request//USB设备请求寄存器
{unsigned char bmRequesetType;//请求类型(数据传输类型、方向、接收器)
 unsigned char bRequest;//USB请求
 unsigned short wValue;//USB请求值
 unsigned short windex;//USB请求索引
 unsigned short wLength;//计数长度
}DEVICE_REQUEST;
typedef struct_control_xfer//SETUP包数据缓冲区
{DEVICE_REQUSET DeviceRequest;//USB设备请求结构体,8个字节
 unsigned short wLength;//传输数据的总字节数
 unsigned short wCount;//传输字节数统计
 unsigned char *pData;//传输数据的指针
 unsigned char dataBuffer[MAX_CONTROLDATA_SIZE];//请求的数据 
}CONTROL_XFER;
EPPFLAGS bEPPflags;//前后台之间工作状态标志
CONTROL_XFER ContralData;//保存SETUP包请求的类型和请求的数据
//若采用多地址/数据方式进行口的模拟,寄存器的更改频繁,故采用单地址/数据,用A0进行模拟
//函数用于将一个字节的数据输入PDIUSBD12,主副板不同,下面是主板程序
//下面是硬件提取层EPPHAL.C
void rom_initial(void)
{USB_FEATURE_REMOTE_WAKEUP=0x0001;
 D12_FULLEMPTY=0x01;//第0位有效
 D12_INT_BUSRESET=0x40;//第6位有效
 D12_INT_SUSPENDCHANGE=0x80;//第7位有效
 D12_INT_ENDP0IN=0x02;//第1位有效
 D12_INT_ENDP0OUT=0x01;//第0位有效
 D12_INT_ENDP1IN=0x08;//第3位有效
 D12_INT_ENDP1OUT=0x04;//第2位有效
 D12_INT_ENDP2IN=0x20;//第5位有效
 D12_INT_ENDP2OUT=0x10;//第4位有效
 D12_SETUPPACKET=0x20;//第5位有效
 USB_IDLE=0x00;
 USB_TRANSMIT=0x01;
 USB_RECEIVE=0x02;
 USB_ENDPOINT_DIRECTION_MASK=0x80;//第7位有效
 MAX_CONTROLDATA_SIZE=8;
 EP0_PACKET_SIZE=16;
 EP1_PACKET_SIZE=4;
 EP2_PACKET_SIZE=64;
 USB_REQUEST_TYPE_MASK=0x60;
 USB_REQUEST_MASK=0x0f;
 USB_STANDARD_REQUEST=0x00;
 USB_RECIPIENT=0x1f;
 USB_RECIPIENT_DEVICE=0x00;
 USB_RECIPIENT_INTERFACE=0x01;
 USB_RECIPIENT_ENDPOINT=0x02;
 MAX_ENDPOINTS=0x03;
 D12_STALL=0x02;
 DEVICE_ADDRESS_MASK=0x7f;
 USB_DEVICE_DESCRIPTOR_TYPE=0x01;
 USB_FEATURE_ENDPOINT_STALL=0x0000;
 D12_NOLAZYCLOCK=0x02;
 D12_SETTOONE=0x40;
 D12_CLOCK_12M=0x03;
 D12_SOFTCONNEC=0x10;
 }
unsigned int SWAP(unsigned int swap_data_in)//整型数据高低字节交换
{unsigned int swap_data_out;
 unsigned char swap_byte;						                                                                                                                                                                                                                                        
 asm{ldd awap_data;
     stab swap_byte
     tab
     ldaa swap_byte
     std swap_data_out
     }
 return swap_data_out;
 }
unsigned char MSB(unsigned int data)
{unsigned char aa;
 aa=data>>8;
 aa=aa & 0x0ff;
 return aa;
 }
void command_outportb(unsigned char data)//参数为命令类型要求输出的数值
{asm{ldaa #$97
     staa PORTE//片选
     ldaa #$0ff
     staa PORTB//A0
     ldaa #$95
     staa PORTE//WR
     ldaa data
     staa PORTA//数据线
     nop
     ldaa #$97
     staa PORTE//上升沿锁存
     ldaa #$9f
     staa PORTE//信号恢复
     }
}
void data_outportb(unsigned char data)//参数为数据类型要求输出的数值
{asm{ldaa #$97
     staa PORTE
     ldaa #$07f
     staa PORTB
     ldaa #$95
     staa PORTE
     nop
     ldaa data
     staa PORTA
     nop
     ldaa #$97
     staa PORTE
     ldaa #$9f
     staa PORTE
     }
}
unsigned char inportb(void)//参数为数据类型要求输入的数值
{unsigned char read_byte;
 asm{ldaa #$97
     staa PORTE
     ldaa #$07f
     staa PORTB
     ldaa #$87
     staa PORTE
     ldaa PORTA
     staa read_byte
     nop
     ldaa #$97
     staa PORTE
     ldaa #$9f
     staa PORTE
     }
 return read_byte;
 }
//下面是命令接口程序D12CI.C
//设置地址使能命令
void D12_SetAddressEnable(unsigned char bAddress, unsigned char bEnable)
{command_outportb(0x0D0);
 if(bEnable)
    bAddress |= 0x80;
 data_outportb(bAddress);
}
//设置端点使能命令
void D12_SetEndpointEnable(unsigned char bEnable)
{command_outportb(0x0D8);
 if(bEnable)
    data_outportb(1);
 else
    data_outportb(0);
}
//设置模式命令
void D12_SetMode(unsigned char bConfig, unsigned char bClkDiv)
{command_outportb(0x0F3);
 data_outportb(bConfig);
 data_outportb(bClkDiv);
}
//读取中断寄存器 注意整型数和浮点书字节的顺序
unsigned short D12_ReadInterruptRegister(void)
{unsigned char b1;
 unsigned int j;
 command_outportb(0x0F4);
 b1=inportb();
 j=inportb();
 j<<=8;//先读低字节,再读高字节
 j+=b1;
 return j;
}
//端点选择命令
unsigned char D12_SelectEndpoint(unsigned char bEndp)
{unsigned char c;
 command_outportb(bEndp);
 c=inportb();
 return c;
}
//读取端点最后处理状态
unsigned char D12_ReadLastTransactionStatus(unsigned char bEndp)
{command_outportb(0x40+bEndp);
 return inportb();
}
//读取端点状态
unsigned char D12_ReadEndpointStatus(unsigned char bEndp)
{unsigned char c;
 command_outportb(0x80+bEndp);
 c=inportb();
 return c;
}
//设置端点状态
void D12_SetEndpointStatus(unsigned char bEndp, unsigned char bStalled)
{command_outportb(0x40+bEndp);
 data_outportb(bStalled);
}
//发送恢复命令
void D12_SendResume(void)
{
 command_outportb(0x0F6);
}
//读取当前桢标志
unsigned short D12_ReadCurrentFrameNumber(void)
{unsigned short i,j;
 command_outportb(0x0F5);
 i=inportb();
 j=inportb();
 i+=(j<<8);
 return i;
}
/*//读取ID号
unsigned short D12_ReadChipID(void)
{unsigned short i,j;
 outportb(portbase+D12_COMMAND, 0xFD);
 i=inportb(portbase+D12_DATA);
 j=inportb(portbase+D12_DATA);
 i += (j<<8);
 return i;
}*/
//读取端点数据
unsigned char D12_ReadEndpoint(unsigned char endp, unsigned char *buf, unsigned char len)
{unsigned char i, j;
 command_outportb(endp);
 if((inportb() & D12_FULLEMPTY)==0)//判断缓冲区为满或空状态,值为0x01 
     {return 0; //缓冲区为空,返回
     }
 command_outportb(0x080+endp);
 i=inportb();
 i=i&0x60;
 if(endp==2)
   {if(i==0x60)
      bEPPflags.bits.ep1buf_full=1;//标志端点1缓冲区全满
    else bEPPflags.bits.ep1buf_full=0;
    }
 if(endp==4)
   {if(i==0x60)
      bEPPflags.bits.ep2buf_full=1;//标志端点2缓冲区全满
    else bEPPflags.bits.ep2buf_full=0;
    }
 command_outportb(0x0f0);
 j=inportb();//该字节为任意字节,没有意义
 j=inportb();//数据字节的数目/长度
 if(j>len)//用于将大于端点容量的数据分批传输
   j=len;
 for(i=0;i<j;i++)
    *(buf+i)=inportb();//传输数据到指定的地址
 command_outportb(0x0F2);//缓冲区清零
 return j;
}
//把数据写入端点
unsigned char D12_WriteEndpoint(unsigned char endp, unsigned char * buf, unsigned char len)
{unsigned char i;
 command_outportb(endp);//选择写入的端点
 inportb();
 command_outportb(0x0F0);
 data_outportb(0);//写入规定数据0
 data_outportb(len);//写入传送字节的数目
 for(i=0;i<len;i++)
    data_outportb(*(buf+i));
 command_outportb(0x0FA);//使缓冲区有效
 return len;//len的数值必须要由相关的计算而得
}
//端点应答处理
void D12_AcknowledgeEndpoint(unsigned char endp)
{command_outportb(endp);//选择端点
 command_outportb(0x0F1);//应答设置
 if(endp==0)
   command_outportb(0x0F2);//缓冲区清零
}
//下面是中断服务程序
//#pragma TRAP_PROC
void fn_usb_isr()
{unsigned int i_st;//为保持与子程序的一致性
 unsigned char i_st_byte;
 bEPPflags.bits.in_isr=1;//中断服务标志
 i_st=D12_ReadInterruptRegister();//读取中断寄存器
 asm{ldd i_st;
     stab i_st_byte;
     }//只取低字节,高字节没有意义
 if(i_st_byte!=0) 
   {if(i_st_byte & D12_INT_BUSRESET) 
       bEPPflags.bits.bus_reset=1;//复位
    //if(i_st & D12_INT_EOT)
    //   dma_eot();
    if(i_st_byte & D12_INT_SUSPENDCHANGE)
       bEPPflags.bits.suspend=1;//挂起改变
    if(i_st_byte & D12_INT_ENDP0IN)
       ep0_txdone();//端点0 IN 中断
    if(i_st_byte & D12_INT_ENDP0OUT)
       ep0_rxdone();//端点0 OUT 中断
    if(i_st_byte & D12_INT_ENDP1IN)
       ep1_txdone();//端点1 IN 中断
    if(i_st_byte & D12_INT_ENDP1OUT)
       ep1_rxdone();//端点1 OUT 中断
    if(i_st_byte & D12_INT_ENDP2IN)
      main_txdone();//端点2 IN 中断
    if(i_st_byte & D12_INT_ENDP2OUT)
      main_rxdone();//端点2 OUT 中断
    }
 }
 bEPPflags.bits.in_isr=0;//清中断服务标志
}
//端点0 OUT中断
void ep0_rxdone(void)
{unsigned char ep_last,i;
 ep_last=D12_ReadLastTransactionStatus(0); // Clear interrupt flag 清中断标志 
 if(ep_last & D12_SETUPPACKET)//接收到SETUP包 
   {ControlData.wLength=0;//传输数据的总字节数
    ControlData.wCount=0;//传输字节数统计
    if(D12_ReadEndpoint(0,sizeof(ControlData.DeviceRequest),(unsigned char *)(&(ControlData.DeviceRequest)))!=sizeof(DEVICE_REQUEST)) 
       //SETUP包出错,返回
      {D12_SetEndpointStatus(0,1);//停止控制输出端点
       D12_SetEndpointStatus(1,1);//停止控制输入端点
       bEPPflags.bits.control_state=USB_IDLE;//控制端点进入空闲状态
       return;
       }
    //数据高低字节交换,USB的结构与MOTOROLA 的数据结构不同,需要高低字节交换  
    ControlData.DeviceRequest.wValue=SWAP(ControlData.DeviceRequest.wValue);
    ControlData.DeviceRequest.wIndex=SWAP(ControlData.DeviceRequest.wIndex);
    ControlData.DeviceRequest.wLength=SWAP(ControlData.DeviceRequest.wLength);
    //对控制端点的输入/输出进行应答
    D12_AcknowledgeEndpoint(0);//对控制输出端点进行应答
    D12_AcknowledgeEndpoint(1);//对控制输入端点进行应答
    ControlData.wLength=ControlData.DeviceRequest.wLength;//将USB的请求计数长度赋给传输数据的字节数
    ControlData.wCount=0;//传输字节数统计清零
    if(ControlData.DeviceRequest.bmRequestType && (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
       //检查传输的类型,这里是从主机传输数据

⌨️ 快捷键说明

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