📄 chap_9.asm
字号:
#include "Descriptor.h"
#include "PDIUSBD12.h"
#include "defBF531.h"
.global SetupPacket;
.section SECTION_Data; //8bit width, total size: 16K Byte
.align 4;
.byte4 ControlDataCount;
.byte4 ControlDataLength;
.byte4 ControlState; //=0 USB IDLE, =1 USB TRANSMIT, =2 USB RECEIVE
.byte4 SetupPacket; //=0 no, not a setup packet; =1 yes, a setup packet
.byte4 fConfig; //=0 device unconfigured; =1 device configured
.byte4 ControlData_pData;
.byte4 bRequestType;
.byte4 bRequest;
.byte4 wValue;
.byte4 wIndex;
.byte4 Remote_Wakeup;
.align 2;
.byte2 EP0RxBuf[16];
.byte2 EP0TxBuf[16];
.byte2 DeviceDescTable[18]={0x12, //bLength
USB_DEVICE_DESCRIPTOR_TYPE, //bDescriptorType
0x00,0x01, //bcdUSB(16 bit)
USB_CLASS_CODE_TEST_CLASS_DEVICE, //bDeviceClass
0x00, //bDeviceSubClass
0x00, //bDeviceProtocol
EP0_PACKET_SIZE, //bMaxPacketSize0
0x71,0x04, //idVendor(16 bit)
0x66,0x06, //idProduct(16 bit)
0x00,0x01, //bcdDevice(16 bit)
0x00, //iManufacturer
0x00, //iProduct
0x00, //iSerialNumber
0x01 //bNumConfigurations
};
.byte2 UsbDescTable[ConfigDescritorLen]= {
//Configuration Descriptor
0x09, //length of the configuration Descriptor
USB_CONFIGURATION_DESCRIPTOR_TYPE, //type=0x02
CONFIG_DESCRIPTOR_LENGTH,0x00, //total length
0x01, //support only 1 interface
0x01, //configuartion value
0x00, //iConfiguration=0,no string descriptor
0x60, //self powered, remote wakeup supported
0x32, //Max power consumption 100mA
//Interface Descriptor
0x09, //length of Interface descriptor
USB_INTERFACE_DESCRIPTOR_TYPE, //type=0x04
0x00, //interface number
0x00, //only 1 interface, no alternative
NUM_ENDPOINTS, //number of endpoints. 4(except control endpoint)
USB_CLASS_CODE_TEST_CLASS_DEVICE, //interface class
USB_SUBCLASS_CODE_TEST_CLASS_D12, //interface subclass
USB_PROTOCOL_CODE_TEST_CLASS_D12, //interface protocol
0x00, //iInterface
//Endpoint1 In Descriptor
0x07, //length of endpoint descriptor
USB_ENDPOINT_DESCRIPTOR_TYPE, //type=0x05
0x81, //endpoint1 In
USB_ENDPOINT_TYPE_INTERRUPT, //Interrupt Transfer Mode
EP1_PACKET_SIZE,0x00, //Endpoint1 max packet size=16
0xa, //interrupt interval is 10ms
//Endpoint1 Out Descriptor
0x07, //length of endpoint descriptor
USB_ENDPOINT_DESCRIPTOR_TYPE, //type=0x05
0x01, //endpoint1 Out
USB_ENDPOINT_TYPE_INTERRUPT, //Interrupt Transfer Mode
EP1_PACKET_SIZE,0x00, //Endpoint1 max packet size=16
0xa, //interrupt interval is 10ms
//Endpoint2 In Descriptor
0x07, //length of endpoint descriptor
USB_ENDPOINT_DESCRIPTOR_TYPE, //type=0x05
0x82, //endpoint2 In
USB_ENDPOINT_TYPE_BULK, //Bulk Transfer Mode
EP2_PACKET_SIZE,0x00, //Endpoint2 max packet size=64
0x0a, //interrupt interval is 10ms
//Endpoint2 Out Descriptor
0x07, //length of endpoint descriptor
USB_ENDPOINT_DESCRIPTOR_TYPE, //type=0x05
0x02, //endpoint2 Out
USB_ENDPOINT_TYPE_BULK, //Bulk Transfer Mode
EP2_PACKET_SIZE,0x00, //Endpoint2 max packet size=64
0x0a //interrupt interval is 10ms
};
.section SECTION_Code2;
/*************************************
** 函数名称: Stall_ep0(void)
** 功能描述: 使控制端点处于停止状态
**************************************/
.global Stall_ep0;
Stall_ep0:
[ --SP ] = RETS;
[ --SP ]=p0; //push p0
[ --SP ]=r0; //push r0
//Stall Endpoint0, control out
p0.l=lo(bEndp);
p0.h=hi(bEndp);
r0=0;
[p0]=r0;
p0.l=lo(bStalled);
p0.h=hi(bStalled);
r0=1;
[p0]=r0;
call SetEndpointStatus;
//Stall endpoint1, control in
p0.l=lo(bEndp);
p0.h=hi(bEndp);
r0=1;
[p0]=r0;
p0.l=lo(bStalled);
p0.h=hi(bStalled);
r0=1;
[p0]=r0;
call SetEndpointStatus;
r0=[ SP++ ]; //pop r0
p0=[ SP++ ]; //pop p0
RETS = [ SP++ ];
rts;
Stall_ep0.end:
/**********************************************
** 函数名称: init_unconfig(void)
** 功能描述: 进入地址状态,禁止0除外的所有端点
***********************************************/
.global Init_unconfig;
Init_unconfig:
[ --SP ] = RETS;
[ --SP ]=p0; //push p0
[ --SP ]=r0; //push r0
p0.l=lo(bEnable);
p0.h=hi(bEnable);
r0=0;
[p0]=r0;
call SetEndpointEnable;
r0=[ SP++ ]; //pop r0
p0=[ SP++ ]; //pop p0
RETS = [ SP++ ];
rts;
Init_unconfig.end:
/**********************************************
** 函数名称: Init_config(void)
** 功能描述: 配置处理,允许端点收发
***********************************************/
.global Init_config;
Init_config:
[ --SP ] = RETS;
[ --SP ]=p0; //push p0
[ --SP ]=r0; //push r0
p0.l=lo(bEnable);
p0.h=hi(bEnable);
r0=1;
[p0]=r0;
call SetEndpointEnable;
r0=[ SP++ ]; //pop r0
p0=[ SP++ ]; //pop p0
RETS = [ SP++ ];
rts;
Init_config.end:
/*********************************************************
** 函数名称: Single_transmit(* pBuf, bLen)
** 功能描述: 通过端点索引 1 发送数据(DATA 类型)
** 长度小于EP0最大信息包大小(16)才允许发送
** 输 入: * pBuf: 发送数据指针
bLen: 发送数据长度
** 输 出: 无
**********************************************************/
.global Single_transmit;
Single_transmit:
[ --SP ] = RETS;
[ --SP ]=p0; //push p0
[ --SP ]=r0; //push r0
[ --SP ]=r1; //push r1
p0.l=lo(bLen);
p0.h=hi(bLen);
r0=[p0];
r1=EP0_PACKET_SIZE;
cc=r0<=r1;
if !cc jump Single_transmit_Exit;
p0.l=lo(bEndp);
p0.h=hi(bEndp);
r0=0x1;
[p0]=r0;
//p0.l=lo(pBuf);
//p0.h=hi(pBuf);
//r0.l=lo(UsbCtrlBuf);
//r0.h=hi(UsbCtrlBuf);
//[p0]=r0;
call WriteEndpoint;
Single_transmit_Exit:
r1=[ SP++ ]; //pop r1
r0=[ SP++ ]; //pop r0
p0=[ SP++ ]; //pop p0
RETS = [ SP++ ];
rts;
Single_transmit.end:
/*************************************************************
** 函数名称: Code_transmit(* pBuf, bLen)
** 功能描述: 通过端点索引 1 发送数据
** 输 入: *pBuf: 发送数据指针
bLen: 发送数据长度
** 输 出: 无
**************************************************************/
.global Code_transmit;
Code_transmit:
[ --SP ] = RETS;
[ --SP ]=p0; //push p0
[ --SP ]=p1; //push p1
[ --SP ]=r0; //push r0
[ --SP ]=r1; //push r1
//ControlData_pData=pBuf;
p0.l=lo(pBuf);
p0.h=hi(pBuf);
r0=[p0];
p0.l=lo(ControlData_pData);
p0.h=hi(ControlData_pData);
[p0]=r0;
//ControlDataCount=0;
p0.l=lo(ControlDataCount);
p0.h=hi(ControlDataCount);
r0=0;
[p0]=r0;
//if ControlDataLength > bLen then ControlDataLength = bLen
p0.l=lo(ControlDataLength);
p0.h=hi(ControlDataLength);
r0=[p0];
p1.l=lo(bLen);
p1.h=hi(bLen);
r1=[p1];
cc=r1<r0;
if !cc jump Set_pBuf;
//ControlDataLength = bLen
[p0]=r1;
r0=r1;
Set_pBuf:
//if ControlDataLength >= EP0_PACKET_SIZE
r1=EP0_PACKET_SIZE;
cc=r1<=r0;
if !cc jump ControlDataLengthLessThan_EP0_PACKET_SIZE;
//WriteEndpoint(1, EP0_PACKET_SIZE, &EP0TxBuf);
////set bEndp=1;
p0.l=lo(bEndp);
p0.h=hi(bEndp);
r0=1;
[p0]=r0;
////set bLen=EP0_PACKET_SIZE;
[p1]=r1;
////pBuf has been set when Code_transmit is called
call WriteEndpoint;
//ControlDataCount+=EP0_PACKET_SIZE;
p0.l=lo(ControlDataCount);
p0.h=hi(ControlDataCount);
r0=[p0];
r0=r0+r1;
[p0]=r0;
//ControlState=1, means USB_TRANSMIT
p0.l=lo(ControlState);
p0.h=hi(ControlState);
r0=1;
[p0]=r0;
jump Code_transmit_Exit;
ControlDataLengthLessThan_EP0_PACKET_SIZE:
//WriteEndpoint(1, EP0_PACKET_SIZE, &EP0TxBuf);
////set bEndp=1;
p0.l=lo(bEndp);
p0.h=hi(bEndp);
r0=1;
[p0]=r0;
////set bLen=ControlDataLength;
p0.l=lo(ControlDataLength);
p0.h=hi(ControlDataLength);
r0=[p0];
[p1]=r0;
////pBuf has been set when Code_transmit is called
call WriteEndpoint;
//ControlDataCount+=EP0_PACKET_SIZE;
p0.l=lo(ControlDataCount);
p0.h=hi(ControlDataCount);
r0=[p0];
r0=r0+r1;
[p0]=r0;
//ControlState=1, means USB_IDLE
p0.l=lo(ControlState);
p0.h=hi(ControlState);
r0=0;
[p0]=r0;
Code_transmit_Exit:
r1=[ SP++ ]; //pop r1
r0=[ SP++ ]; //pop r0
p1=[ SP++ ]; //pop p1
p0=[ SP++ ]; //pop p0
RETS = [ SP++ ];
rts;
Code_transmit.end:
//*************************************************************************
// USB 标准设备请求服务程序
//*************************************************************************
/********************************************************************
** 函数名称: Get_Status(void)
** 功能描述: 主机要求获取状态,设备返回16位的状态描述给主机
*********************************************************************/
.global Get_Status;
Get_Status:
[ --SP ] = RETS;
[ --SP ]=p0; //push p0
[ --SP ]=r0; //push r0
[ --SP ]=r1; //push r1
//if bRequestType==USB_RECIPIENT_DEVICE
p0.l=lo(bRequestType);
p0.h=hi(bRequestType);
r0=[p0];
r1=USB_RECIPIENT;
r0=r0&r1;
r1=USB_RECIPIENT_DEVICE;
cc=r0==r1;
if !cc jump Not_USB_RECIPIENT_DEVICE_GetStatus;
p0.l=lo(Remote_Wakeup);
p0.h=hi(Remote_Wakeup);
r0=[p0];
r1=1;
cc=r0==r1;
if !cc jump NotSupportRemoteWakeup;
//Support remote wakeup, low 8 bit=3
p0.l=lo(EP0TxBuf);
p0.h=hi(EP0TxBuf);
r0=3;
w[p0]=r0.l;
p0+=2;
jump Send16bitData;
NotSupportRemoteWakeup:
//Do not support remote wakeup, low 8 bit=1
p0.l=lo(EP0TxBuf);
p0.h=hi(EP0TxBuf);
r0=1;
w[p0]=r0.l;
p0+=2;
Send16bitData:
//high 8 bit=0
r0=0;
w[p0]=r0.l;
//call Single_transmit(&EP0TxBuf,2)
r0.l=lo(EP0TxBuf);
r0.h=hi(EP0TxBuf);
p0.l=lo(pBuf);
p0.h=hi(pBuf);
[p0]=r0;
p0.l=lo(bLen);
p0.h=hi(bLen);
r0=2;
[p0]=r0;
call Single_transmit;
jump Get_Status_Exit;
Not_USB_RECIPIENT_DEVICE_GetStatus:
r1=USB_RECIPIENT_INTERFACE;
cc=r0==r1;
if !cc jump Not_USB_RECIPIENT_INTERFACE_GetStatus;
//low 8 bit=0
p0.l=lo(EP0TxBuf);
p0.h=hi(EP0TxBuf);
r0=0;
w[p0]=r0.l;
p0+=2;
//high 8 bit=0
w[p0]=r0.l;
//call Single_transmit(&EP0TxBuf,2)
r0.l=lo(EP0TxBuf);
r0.h=hi(EP0TxBuf);
p0.l=lo(pBuf);
p0.h=hi(pBuf);
[p0]=r0;
p0.l=lo(bLen);
p0.h=hi(bLen);
r0=2;
[p0]=r0;
call Single_transmit;
jump Get_Status_Exit;
Not_USB_RECIPIENT_INTERFACE_GetStatus:
r1=USB_RECIPIENT_ENDPOINT;
cc=r0==r1;
if !cc jump Stall_ep0_GetStatus;
p0.l=lo(wIndex);
p0.h=hi(wIndex);
r0=[p0];
r1=MAX_ENDPOINTS;
r1=r0&r1;
r2=USB_ENDPOINT_DIRECTION_MASK;
r2=r0&r2;
cc=r2==0;
if !cc jump ReadOutEPStatus;
//Read In Endpoint status
r1=r1<<1;
r1+=1;
p0.l=lo(bEndp);
p0.h=hi(bEndp);
[p0]=r1;
call SelectEndpoint;
jump ReadEPStatusEnd;
ReadOutEPStatus:
r1=r1<<1;
p0.l=lo(bEndp);
p0.h=hi(bEndp);
[p0]=r1;
call SelectEndpoint;
ReadEPStatusEnd:
//read EP status and compare it with 'D12_STALL'
p0.l=lo(D12Data);
p0.h=hi(D12Data);
r0=[p0];
r1=D12_STALL;
r0=r0&r1;
cc=r0==0;
if cc jump EPAvailable;
//endpoint disable, low 8 bit=1
p0.l=lo(EP0TxBuf);
p0.h=hi(EP0TxBuf);
r0=1;
w[p0]=r0.l;
p0+=2;
jump SetHigh8Bit;
EPAvailable:
//endpoint enable, low 8 bit=0
p0.l=lo(EP0TxBuf);
p0.h=hi(EP0TxBuf);
r0=0;
w[p0]=r0.l;
p0+=2;
SetHigh8Bit:
//High 8 bit=0
r0=0;
w[p0]=r0.l;
//call Single_transmit(&EP0TxBuf,2)
r0.l=lo(EP0TxBuf);
r0.h=hi(EP0TxBuf);
p0.l=lo(pBuf);
p0.h=hi(pBuf);
[p0]=r0;
p0.l=lo(bLen);
p0.h=hi(bLen);
r0=2;
[p0]=r0;
call Single_transmit;
jump Get_Status_Exit;
Stall_ep0_GetStatus:
call Stall_ep0;
Get_Status_Exit:
r1=[ SP++ ]; //pop r1
r0=[ SP++ ]; //pop r0
p0=[ SP++ ]; //pop p0
RETS = [ SP++ ];
rts;
Get_Status.end:
/****************************************
** 函数名称: Clear_Feature(void)
** 功能描述: 清除特性
*****************************************/
.global Clear_Feature;
Clear_Feature:
[ --SP ] = RETS;
[ --SP ]=p0; //push p0
[ --SP ]=r0; //push r0
[ --SP ]=r1; //push r1
[ --SP ]=r2; //push r2
//if bRequestType==USB_RECIPIENT_DEVICE
p0.l=lo(bRequestType);
p0.h=hi(bRequestType);
r0=[p0];
r1=USB_RECIPIENT;
r0=r0&r1;
r1=USB_RECIPIENT_DEVICE;
cc=r0==r1;
if !cc jump NotTo_USB_RECIPIENT_DEVICE_ClearFeature;
//if wValue==USB_FEATURE_REMOTE_WAKEUP
p0.l=lo(wValue);
p0.h=hi(wValue);
r0=[p0];
r1=USB_FEATURE_REMOTE_WAKEUP;
cc=r0==r1;
if !cc jump NotTo_USB_RECIPIENT_DEVICE_ClearFeature;
//set flag Remote_Wakeup=0
p0.l=lo(Remote_Wakeup);
p0.h=hi(Remote_Wakeup);
r0=0;
[p0]=r0;
//call Single_transmit(0,0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -