📄 exp12.c
字号:
#include <stdio.h>
#include "system.h"
#include "alt_types.h"
#include "Exp12.h"
#include "sys/alt_irq.h"
#include "altera_avalon_pio_regs.h"
volatile int edge_capture;
alt_u8 USB_Buff[Bulk_Len];
alt_u8 Setup_Step=FALSE,Config;
int main()
{
void *edge_capture_ptr=(void *)&edge_capture;
IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,1);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_CS_BASE,1);
IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,1);
IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,1);
alt_irq_register(D12_INT_IRQ,edge_capture_ptr,D12_INT_ISR);
IOWR_ALTERA_AVALON_PIO_DIRECTION(D12_INT_BASE,0);
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(D12_INT_BASE,0);
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(D12_INT_BASE,1);
USB_Port_Init(); //枚举USB
while(1)
;
return 0;
}
void D12_INT_ISR(void * context,alt_u32 id)
{
volatile int* edge_capture_ptr = (volatile int*) context;
alt_u32 Int_Flag;
// DISABLE;
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(D12_INT_BASE,0);
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(D12_INT_BASE,0); //清除中断标志
Int_Flag=USB_Read_INT_Flag(); //读取中断标志
printf("\nInterrupt:%x\n",Int_Flag);
if(Int_Flag & 0x0001) //端点0 OUT中断
USB_EndPoint0_OUT();
if(Int_Flag & 0x0002) //端点0 IN 中断
USB_EndPoint0_IN();
if(Int_Flag & 0x0004) //端点1 OUT中断
USB_EndPoint1_OUT();
if(Int_Flag & 0x0008) //端点1 IN 中断
USB_EndPoint1_IN();
if(Int_Flag & 0x0010) //端点2 OUT中断
USB_EndPoint2_OUT();
if(Int_Flag & 0x0020) //端点2 IN 中断
USB_EndPoint2_IN();
if(Int_Flag & 0x0040) //总线复位
{
USB_SetEndPoint_Enable(0);
IOWR_ALTERA_AVALON_PIO_DATA(D12_SUSPEND_BASE,1);
}
if(Int_Flag & 0x0080) //挂起改变
{
USB_SetEndPoint_Enable(0);
IOWR_ALTERA_AVALON_PIO_DATA(D12_SUSPEND_BASE,1);
}
// ENABLE;
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(D12_INT_BASE,1);
}
/**********延迟程序*****************/
void Delay(alt_u32 m_Delay)
{
while(m_Delay--);
}
/**********D12操作程序*****************/
void USB_Write_Command(alt_u8 m_Command)//写命令
{
IOWR_ALTERA_AVALON_PIO_DIRECTION(D12_DB_BASE,0xff); //数据总线:输出
IOWR_ALTERA_AVALON_PIO_DATA(D12_A0_BASE,1); //选择命令
IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,0); //片选拉低
IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,0); //写信号有效
IOWR_ALTERA_AVALON_PIO_DATA(D12_DB_BASE,m_Command);
IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,1); //写信号无效
IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,1); //片选无效
}
void USB_Write_Data(alt_u8 m_Data) //写数据
{
IOWR_ALTERA_AVALON_PIO_DIRECTION(D12_DB_BASE,0xff); //数据总线:输出
IOWR_ALTERA_AVALON_PIO_DATA(D12_A0_BASE,0); //选择数据
IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,0); //片选拉低
IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,0); //写信号有效
IOWR_ALTERA_AVALON_PIO_DATA(D12_DB_BASE,m_Data);
IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,1); //写信号无效
IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,1); //片选无效
}
alt_u8 USB_Read_Data(void) //读数据
{
alt_u8 Temp;
IOWR_ALTERA_AVALON_PIO_DIRECTION(D12_DB_BASE,0x00); //数据总线:输入
IOWR_ALTERA_AVALON_PIO_DATA(D12_A0_BASE,0); //选择数据
IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,0); //片选拉低
IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,0); //读信号有效
Temp=IORD_ALTERA_AVALON_PIO_DATA(D12_DB_BASE);
IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,1); //读信号无效
IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,1); //片选无效
return Temp;
}
void USB_Port_Init(void)
{
IOWR_ALTERA_AVALON_PIO_DATA(D12_SUSPEND_BASE,0); //唤醒USB芯片
USB_SetDMA_Mode(0x00); //设置USB DMA
USB_Connect(0x02,0x4b); //断开USB
Delay(1000); //等待大约1秒钟
USB_Connect(0x12,0x45); //重新连接USB
USB_Read_INT_Flag();
}
void USB_Connect(alt_u8 m_Mode,alt_u8 m_Clk)
{
USB_Write_Command(0xf3);
USB_Write_Data(m_Mode);
USB_Write_Data(m_Clk);
}
void USB_SetAddr_Enable(alt_u8 m_Addr,alt_u8 m_Enable)
{
USB_Write_Command(0xd0);
if(m_Enable)
USB_Write_Data(m_Addr | 0x80);
else
USB_Write_Data(m_Addr);
}
void USB_SetEndPoint_Enable(alt_u8 m_Enable)
{
USB_Write_Command(0xd8);
if(m_Enable)
USB_Write_Data(0x01);
else
USB_Write_Data(0x00);
}
void USB_SetDMA_Mode(alt_u8 m_Mode)
{
USB_Write_Command(0xfb);
USB_Write_Data(m_Mode);
}
alt_u32 USB_Read_INT_Flag(void) //读中断标志
{
alt_u32 Temp1,Temp2;
USB_Write_Command(0xf4);
Temp2=USB_Read_Data();
Temp1=USB_Read_Data();
Temp1<<=8;
return Temp1+Temp2;
}
alt_u8 USB_Read_LastStatus(alt_u8 m_EndPoint) //读最后处理状态寄存器
{
alt_u8 Temp;
USB_Write_Command(0x40+m_EndPoint);
Temp=USB_Read_Data();
return Temp;
}
alt_u8 USB_Read_EndPoint_Buff(alt_u8 m_EndPoint,alt_u8 m_Len,alt_u8 *m_Buff) //读缓冲区
{
alt_u8 len,i,Temp;
USB_Write_Command(m_EndPoint); //选择目标端点
if(USB_Read_Data() & 0x01==0) //如果缓冲区为空,则返回
return 0;
else
{
USB_Write_Command(0xf0);
IOWR_ALTERA_AVALON_PIO_DIRECTION(D12_DB_BASE,0x00); //数据总线:输入
IOWR_ALTERA_AVALON_PIO_DATA(D12_A0_BASE,0); //选择数据
IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,0); //片选拉低
//Temp=USB_Read_Data();
IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,0); //读信号有效
Temp=IORD_ALTERA_AVALON_PIO_DATA(D12_DB_BASE);
IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,1); //读信号无效
//len=USB_Read_Data();
IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,0); //读信号有效
len=IORD_ALTERA_AVALON_PIO_DATA(D12_DB_BASE);
IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,1); //读信号无效
printf("receive data len: %d\n",len);
if(len>m_Len)
len=m_Len;
for(i=0;i<len;i++)
{
//m_Buff[i]=USB_Read_Data();
IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,0); //读信号有效
m_Buff[i]=IORD_ALTERA_AVALON_PIO_DATA(D12_DB_BASE);
IOWR_ALTERA_AVALON_PIO_DATA(D12_RD_BASE,1); //读信号无效
}
USB_Write_Command(0xf2); //清除缓冲区
return len;
}
}
void USB_Write_EndPoint_Buff(alt_u8 m_EndPoint,alt_u8 m_Len,alt_u8 *m_Buff) //写缓冲区
{
alt_u8 i;
USB_Write_Command(m_EndPoint);
USB_Write_Command(0xf0);
IOWR_ALTERA_AVALON_PIO_DATA(D12_A0_BASE,0); //选择数据
IOWR_ALTERA_AVALON_PIO_DATA(D12_CS_BASE,0); //片选拉低
//USB_Write_Data(0);
IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,0); //写信号有效
IOWR_ALTERA_AVALON_PIO_DATA(D12_DB_BASE,0);
IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,1); //写信号无效
//USB_Write_Data(m_Len);
IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,0); //写信号有效
IOWR_ALTERA_AVALON_PIO_DATA(D12_DB_BASE,m_Len);
IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,1); //写信号无效
for(i=0;i<m_Len;i++)
{
//USB_Write_Data(m_Buff[i]);
IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,0); //写信号有效
IOWR_ALTERA_AVALON_PIO_DATA(D12_DB_BASE,m_Buff[i]);
IOWR_ALTERA_AVALON_PIO_DATA(D12_WR_BASE,1); //写信号无效
}
USB_Write_Command(0xfa); //使缓冲区有效
}
void USB_EndPoint_Setup_Ack(alt_u8 m_EndPoint) //SetUp包应答
{
USB_Write_Command(m_EndPoint);
USB_Write_Command(0xf1);
if(m_EndPoint == 0)
USB_Write_Command(0xf2);
}
void USB_SetEndPoint_Status(alt_u8 m_EndPoint,alt_u8 m_Stall) //设置端点状态
{
USB_Write_Command(0x40+m_EndPoint);
USB_Write_Data(m_Stall);
}
alt_u8 USB_GetEndPoint_Status(alt_u8 m_EndPoint) //获取端点状态
{
alt_u8 Temp;
USB_Write_Command(0x40+m_EndPoint);
Temp=USB_Read_Data();
return Temp;
}
void USB_Stall(void) //设备停止
{
USB_SetEndPoint_Status(0,1);
USB_SetEndPoint_Status(1,1);
}
void USB_EndPoint0_IN(void) //端点0 IN 中断服务子程序
{
alt_u8 m_Status;
m_Status=USB_Read_LastStatus(1);
//printf("usb0in_read_last_Status:%x\n",m_Status);
if(Setup_Step==USB_Device_Setup_Flag) //发送设备描述符剩下的2字节
{
// printf("transmit_device_discrpitor+2:\n");
USB_Write_EndPoint_Buff(1,2,DEVICE_DISCRIPTOR+16);
Setup_Step=FALSE;
}
else if(Setup_Step==USB_Interface_Setup_Flag) //发送接口描述符
{
//printf("transmit_interface_discriptor+16:\n");
USB_Write_EndPoint_Buff(1,16,CONFIG_DISCRIPTOR+16);
Setup_Step=USB_EndPoint_Setup_Flag;
}
else if(Setup_Step==USB_EndPoint_Setup_Flag) //发送端点描述符
{
//printf("transmit_endpoint_discriptor:\n");
USB_Write_EndPoint_Buff(1,14,CONFIG_DISCRIPTOR+32);
Setup_Step=FALSE;
}
else
USB_Write_EndPoint_Buff(1,0,0);
}
void USB_EndPoint0_OUT(void) //端点0 OUT中断服务子程序
{
alt_u8 m_Status,i;
alt_u32 Data_Len=0;
for(i=0;i<8;i++)
USB_Buff[i]=0;
m_Status=USB_Read_LastStatus(0);
// printf("usb0out_read_last_Status:%x\n",m_Status);
Data_Len=USB_Read_EndPoint_Buff(0,8,USB_Buff); //读取数据到USB_Buff
// printf("receive data_len: %d\n",Data_Len);
USB_EndPoint_Setup_Ack(0); //应答Setup包
USB_EndPoint_Setup_Ack(1);
Data_Len = USB_Buff[7]*255 + USB_Buff[6]; //获取字节长度
// printf("read data_len:%d\n",Data_Len);
printf("Data:");
for(i=0;i<8;i++)
printf(" %x ",USB_Buff[i]);
printf("\n");
if((m_Status & 0x21) == 0x21) //接收到正确的setup包
{
if(USB_Buff[0]==0x00)
{
if(USB_Buff[1]==0x05) //设置地址
{
//printf("set_address:\n");
USB_SetAddr_Enable(USB_Buff[2],TRUE);
USB_Write_EndPoint_Buff(1,0,0);
}
else if(USB_Buff[1]==0x09) //设置配置
{
//printf("set_cinfig:\n");
if(USB_Buff[2]==0x00 && USB_Buff[3]==0x00)
{
Config=0;
USB_Write_EndPoint_Buff(1,0,0);
USB_SetEndPoint_Enable(0);
}
else if(USB_Buff[2]==0x01 && USB_Buff[3]==0x00)
{
Config=1;
USB_Write_EndPoint_Buff(1,0,0);
USB_SetEndPoint_Enable(1);
}
else //使端点0处于停止状态
USB_Stall();
}
else //使端点0处于停止状态
USB_Stall();
}
else if(USB_Buff[0]==0x80)
{
if(USB_Buff[1]==0x06) //获取描述符
{
if(USB_Buff[3]==0x01) //设备描述符
{
// printf("get_device_discriptor\n");
USB_Write_EndPoint_Buff(1,16,DEVICE_DISCRIPTOR);
if(Data_Len==18) //?????
Setup_Step=USB_Device_Setup_Flag;
}
else if(USB_Buff[3]==0x02) //获取配置描述符
{
//printf("get_config_discriptor\n");
if(Data_Len==9)
USB_Write_EndPoint_Buff(1,9,CONFIG_DISCRIPTOR);
else if(Data_Len>16)
{
USB_Write_EndPoint_Buff(1,16,CONFIG_DISCRIPTOR);
Setup_Step=USB_Interface_Setup_Flag;
}
}
else //使端点0处于停止状态
USB_Stall();
}
else if(USB_Buff[1]==0x08) //读取配置状态
USB_Write_EndPoint_Buff(1,1,&Config);
else //使端点0处于停止状态
USB_Stall();
}
else if(USB_Buff[0]==0x81)
{
if(USB_Buff[1]==0x0a) //获取接口状态
{
//printf("get_interface_discriptor\n");
USB_Buff[7]=0x00;
USB_Write_EndPoint_Buff(1,1,USB_Buff+7);
}
else //使端点0处于停止状态
USB_Stall();
}
else //使端点0处于停止状态
USB_Stall();
}
}
void USB_EndPoint1_IN(void) //端点1 IN中断服务子程序
{
}
void USB_EndPoint1_OUT(void) //端点1 OUT中断服务子程序
{
}
void USB_EndPoint2_IN(void) //端点02 IN中断服务子程序
{
}
void USB_EndPoint2_OUT(void) //端点2 OUT中断服务子程序
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -