📄 sl811.h
字号:
/*#define SL811_nMS_LOW {PORTD &= ~0x80;}
#define SL811_nMS_HIGH {PORTD |= 0x80;}
#define SL811_nDACK_LOW {PORTD &= ~0x40;}
#define SL811_nDACK_HIGH {PORTD |= 0x40;}
#define SL811_RST_LOW {PORTD &= ~0x10;}
#define SL811_RST_HIGH {PORTD |= 0x10;}
*/
// SL811_INT @ PD0=INT0
// 对于全速设备应该注意设置control Reg 中的 SOF 位
// 接收无Data0 Data1 之分,可统一写成 0x23
// 发送有Data0 Data1 之分,一开始是 Data0
//declare memory mapped variables
volatile extern unsigned char SL811_ADDR;
volatile extern unsigned char SL811_COMM;
//define mappings
void mapping_init(void)
{
asm(
".area memory(abs)\n"
".org 0x8000\n"
" _SL811_ADDR:: .blkb 1\n"
".org 0x8001\n"
" _SL811_COMM:: .blkb 1\n"
".text\n"
);
}
#define SL811_USBA_Control 0x00
#define SL811_USBA_BaseAddress 0x01
#define SL811_USBA_BaseLength 0x02
#define SL811_USBA_PIDDEoUS 0x03
#define SL811_USBA_DAoTC 0x04
#define SL811_Control 0x05
#define SL811_Interrupt_Enable 0x06
#define SL811_USBB_Control 0x08
#define SL811_USBB_BaseAddress 0x09
#define SL811_USBB_BaseLength 0x0A
#define SL811_USBB_PIDDEoUS 0x0B
#define SL811_USBB_DAoTC 0x0C
#define SL811_Interrupt_Status 0x0D
#define SL811_SOF_DataSet 0x0E
#define SL811_SOF_Highbyte 0x0F
#define SETUP_PID 0xD0
#define IN_PID 0x90
#define OUT_PID 0x10
#define SOF_PID 0x50
#define PREAMBLE_PID 0xC0
#define NAK_PID 0xA0
#define STALL_PID 0xE0
#define DATA0_PID 0x30
#define DATA1_PID 0xB0
uint8 YES_UDisk = 0; //judge if it'is U disk
uint8 USBA_Status = 0;
uint8 USBB_Status = 0;
uint8 Endp0_DataLen = 8; //U盘控制端点0的长度
uint8 Config_DataLen = 0; //配置描述符加接口描述符数据长度
uint8 BulkOut_PortNum = 2; //批量输入端点号
uint8 BulkOut_DataLen = 0x40; //批量输入端点数据长度
uint8 BulkIn_PortNum = 1; //批量输出端点号
uint8 BulkIn_DataLen = 0x40; //批量输出端点数据长度
uint8 UDisk_Address = 1; //U盘设备地址固定分配为1
uint8 GetDataBuffer[64];
void Printf_buffer(void)
{
uint8 temp;
printf("Get: %x",GetDataBuffer[0]);
for(temp=1;temp<64;temp++)
printf(" %x",GetDataBuffer[temp]);
puts("");
printf("Means: %c",GetDataBuffer[0]);
for(temp=1;temp<64;temp++)
printf(" %c",GetDataBuffer[temp]);
puts("\n");
}
void init_sl811_master(void)
{
uint8 temp;
puts("Begin to run!");
puts("RESET SL811 for master mode!");
//for(temp=0;temp<4;temp++)delayms(250);
SL811_ADDR = SL811_SOF_DataSet;
SL811_COMM = 0xE0;
SL811_COMM = 0xAE; //Select Master Mode
SL811_ADDR = SL811_Control;
SL811_COMM = 0x08; //USB Engine reset
delayms(1);//50);
SL811_ADDR = SL811_Control;
SL811_COMM = 0x01; //USB Engine normal
delayms(1);//100);
SL811_ADDR = SL811_Interrupt_Enable;
SL811_COMM = 0x23; //Enable USB-A,USB-B,IR interrupts
}
void SL811_ReadEndPoint(uint8 endp,uint8 len,uint8* buf)
{
uint8 i,j;
SL811_ADDR = endp;
for(i=0;i<len;i++) //读取缓冲区数据
*(buf++)=SL811_COMM;
}
void SL811_WriteEndPoint(uint8 endp,uint8 len,uint8* buf)
{
uint8 i;
SL811_ADDR = endp; //选择端点
for(i=0;i<len;i++) //写缓冲区数据
SL811_COMM=*(buf++);
}
void SL811_FWriteEndPoint(uint8 endp,uint8 len,const uint8* buf)
{
uint8 i;
SL811_ADDR = endp; //选择端点
for(i=0;i<len;i++) //写缓冲区数据
SL811_COMM = *(buf++);
}
uint8 USBAGetPacket(uint8* buf, uint8 DE, uint8 DD)
{
uint8 len,temp;
SL811_ADDR = SL811_USBA_BaseAddress;
SL811_COMM = USBA_BASEADDRESS;
SL811_COMM = 0x40;
SL811_COMM = IN_PID | DE;
SL811_COMM = DD;
SL811_ADDR = SL811_Interrupt_Status;
SL811_COMM = 0xFF; // clear the DONE bit
SL811_ADDR = SL811_USBA_Control;
SL811_COMM = 0x23;
delayms(2);
if((USBA_Status & 0x01) == 0x01)
{
SL811_ADDR = SL811_USBA_DAoTC;
len = 0x40 - SL811_COMM;
//printf("Get data num is %x\n", len);
temp = len;
SL811_ADDR = USBA_BASEADDRESS;
do{
*buf++ = SL811_COMM;
}while(temp--);
return len; // return data num got
}
return 0xFF; // return error
}
uint8 USBASendZeroPacket(uint8 DE, uint8 DD, uint8 Data_Toggle)
{
uint8 len,temp;
SL811_ADDR = SL811_USBA_BaseAddress;
SL811_COMM = USBA_BASEADDRESS;
SL811_COMM = 0;
SL811_COMM = OUT_PID | DE;
SL811_COMM = DD;
SL811_ADDR = SL811_Interrupt_Status;
SL811_COMM = 0xFF; // clear the DONE bit
SL811_ADDR = SL811_USBA_Control;
if(Data_Toggle) SL811_COMM = 0x67;
else SL811_COMM = 0x27;
delayms(2);
if((USBA_Status & 0x01) == 0x01) return 0;
else return 0xFF; // return error
}
uint8 USBA_SendPacket(uint8* buf, uint8 len, uint8 PIDDE, uint8 DD, uint8 Data_Toggle)
{
SL811_WriteEndPoint(USBA_BASEADDRESS,len,buf);
SL811_ADDR = SL811_USBA_BaseAddress;
SL811_COMM = USBA_BASEADDRESS;
SL811_COMM = len;
SL811_COMM = PIDDE;
SL811_COMM = DD;
SL811_ADDR = SL811_Interrupt_Status;
SL811_COMM = 0xFF; // clear the DONE bit
SL811_ADDR = SL811_USBA_Control;
if(Data_Toggle) SL811_COMM = 0x67;
else SL811_COMM = 0x27;
delayms(2);
if((USBA_Status & 0x01) == 0x01) return 0;
else return 0xFF; //return error
}
uint8 USBA_FSendPacket(const uint8* buf, uint8 len, uint8 PIDDE, uint8 DD, uint8 Data_Toggle)
{
SL811_FWriteEndPoint(USBA_BASEADDRESS,len,buf);
SL811_ADDR = SL811_USBA_BaseAddress;
SL811_COMM = USBA_BASEADDRESS;
SL811_COMM = len;
SL811_COMM = PIDDE;
SL811_COMM = DD;
SL811_ADDR = SL811_Interrupt_Status;
SL811_COMM = 0xFF; // clear the DONE bit
SL811_ADDR = SL811_USBA_Control;
if(Data_Toggle) SL811_COMM = 0x67;
else SL811_COMM = 0x27;
delayms(2);
if((USBA_Status & 0x01) == 0x01) return 0;
else return 0xFF; //return error
}
uint8 USBAFirstSendPacket(const uint8* buf, uint8 len, uint8 PIDDE, uint8 DD)
{
SL811_FWriteEndPoint(USBA_BASEADDRESS,len,buf);
SL811_ADDR = SL811_USBA_BaseAddress;
SL811_COMM = USBA_BASEADDRESS;
SL811_COMM = len;
SL811_COMM = PIDDE;
SL811_COMM = DD;
//SL811_ADDR = SL811_Interrupt_Status;
//SL811_COMM = 0x01; // clear the DONE bit
SL811_ADDR = SL811_USBA_Control;
SL811_COMM = 0x03; //0x03, 0X07: SOF began to work! 0X23,0X27: No SOF!
//0x07 = Send to slave; 0x03 = Get from slave;
delayms(100);
SL811_ADDR = SL811_Interrupt_Status;
SL811_COMM = 0xFF; // clear the DONE bit
SL811_ADDR = SL811_USBA_Control;
SL811_COMM = 0x27; // Netac will reponse at this time
delayms(100);
if( USBA_Status != 0x01 ) return 0x01;
else return 0;
}
// *************************************************************************************
uint8 SL811_ConfigUDisk(void)
{
uint8 temp;
for(temp=0;temp<10;temp++) delayms(50);
SL811_ADDR = SL811_SOF_DataSet;
SL811_COMM = 0xE0;
SL811_COMM = 0xAE; // Select Master Mode
SL811_ADDR = SL811_Control;
SL811_COMM = 0x08; // USB bus reset
delayms(60); // 50ms or more
SL811_ADDR = SL811_Control;
SL811_COMM = 0x03; // USB select FS. SOF enable
delayms(150); // at least 100ms after bus reset
//Get_Device_Descriptor traction
if(USBAFirstSendPacket(Get_Device_Descriptor1,8,SETUP_PID|0x00,0)!= 0) return 0x01;
delayms(50); //一些U盘响应很慢,所以需要延时,Netac 的U盘在测试中不用。
if(USBAGetPacket(GetDataBuffer, 0, 0) == 0xFF ) return 0x02;
Endp0_DataLen = GetDataBuffer[7];
delayms(40); //一些U盘响应很慢,所以需要延时,Netac 的U盘在测试中不用。
USBASendZeroPacket(0,0,1); //一些U盘对空包没有响应,所以不用加错误判断
puts("Good when first Get_Device_Descriptor traction!");
//Set Address UDisk_Address = 1 traction
delayms(40); //一些U盘响应很慢,所以需要延时,Netac 的U盘在测试中不用。
if(USBA_FSendPacket(Set_Address,8,SETUP_PID|0x00,0,0) != 0) return 0x04;
delayms(40); //一些U盘响应很慢,所以需要延时,Netac 的U盘在测试中不用。
if(USBAGetPacket(GetDataBuffer, 0, 0) == 0xFF ) return 0x05;
puts("Good when Set Address!");
//Get_Config_Descriptor traction
delayms(40); //一些U盘响应很慢,所以需要延时,Netac 的U盘在测试中不用。
if(USBA_FSendPacket(Get_Config_Descriptor1,8,SETUP_PID|0x00,UDisk_Address,0) != 0) return 0x06;
delayms(40); //一些U盘响应很慢,所以需要延时,Netac 的U盘在测试中不用。
if(USBAGetPacket(GetDataBuffer, 0, UDisk_Address) == 0xFF ) return 0x07;
Config_DataLen = GetDataBuffer[2];
delayms(40); //一些U盘响应很慢,所以需要延时,Netac 的U盘在测试中不用。
USBASendZeroPacket(0,UDisk_Address,1); //一些U盘对空包没有响应,所以不用加错误判断
puts("Good when Get_Config_Descriptor traction!");
printf("Config_DataLen = %x\n",Config_DataLen);
printf("Endp0_DataLen = %x\n",Endp0_DataLen);
//Get_Config_Descriptor traction 2
delayms(40); //一些U盘响应很慢,所以需要延时,Netac 的U盘在测试中不用。
if(USBA_FSendPacket(Get_Config_Descriptor2,8,SETUP_PID|0x00,UDisk_Address,0) != 0) return 0x09;
delayms(40); //一些U盘响应很慢,所以需要延时,Netac 的U盘在测试中不用。
for(temp = 0; temp <= ((Config_DataLen / Endp0_DataLen)+0); temp++)
{
USBAGetPacket(GetDataBuffer + temp*Endp0_DataLen, 0, UDisk_Address);
delayms(40); //一些U盘响应很慢,所以需要延时,Netac 的U盘在测试中不用。
}
USBASendZeroPacket(0,UDisk_Address,1); //一些U盘对空包没有响应,所以不用加错误判断
puts("Good when Get_Config_Descriptor traction 2!");
if(GetDataBuffer[14] == 0x08 && GetDataBuffer[16] == 0x50 ) YES_UDisk = 1;
//得到U盘的批量端点设置。
if( GetDataBuffer[20] & 0x80)
{
BulkIn_PortNum = GetDataBuffer[20] & 0x0F;
BulkIn_DataLen = GetDataBuffer[22];
}
else
{
BulkOut_PortNum = GetDataBuffer[20] & 0x0F;
BulkOut_DataLen = GetDataBuffer[22];
}
if( GetDataBuffer[27] & 0x80)
{
BulkIn_PortNum = GetDataBuffer[27] & 0x0F;
BulkIn_DataLen = GetDataBuffer[29];
}
else
{
BulkOut_PortNum = GetDataBuffer[27] & 0x0F;
BulkOut_DataLen = GetDataBuffer[29];
}
//Printf_buffer();
//Set_configuration
if(USBA_FSendPacket(Set_Configuration,8,SETUP_PID|0x00,UDisk_Address,0) != 0) return 0x0b;
if(USBAGetPacket(GetDataBuffer, 0, UDisk_Address) == 0xFF ) return 0x0c;
puts("Finish Set_configuration!");
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -