📄 chap_9.asm
字号:
** 函数名称: Control_Handler(void)
** 功能描述: 控制传输
**************************************************************/
.global Control_Handler;
Control_Handler:
[ --SP ] = RETS;
[ --SP ]=p0; //push p0
[ --SP ]=p1; //push p1
[ --SP ]=r0; //push r0
[ --SP ]=r1; //push r1
[ --SP ]=r2; //push r2
p0.l=lo(bRequestType);
p0.h=hi(bRequestType);
r0=[p0];
r1=USB_REQUEST_TYPE_MASK;
r0=r0&r1;
r1=USB_STANDARD_REQUEST;
cc=r0==r1;
if !cc jump NotStandardRequest;
//load device request from bRequest
p0.l=lo(bRequest);
p0.h=hi(bRequest);
r0=[p0];
r1=USB_REQUEST_MASK;
r0=r0&r1;
r1=0;
cc=r0==r1;
if !cc jump Not_GET_STATUS;
call Get_Status;
jump Control_Handler_Exit;
Not_GET_STATUS:
r1=1;
cc=r0==r1;
if !cc jump Not_CLEAR_FEATURE;
call Clear_Feature;
jump Control_Handler_Exit;
Not_CLEAR_FEATURE:
r1=3;
cc=r0==r1;
if !cc jump Not_SET_FEATURE;
call Set_Feature;
jump Control_Handler_Exit;
Not_SET_FEATURE:
r1=5;
cc=r0==r1;
if !cc jump Not_SET_ADDRESS;
call Set_Address;
jump Control_Handler_Exit;
Not_SET_ADDRESS:
r1=6;
cc=r0==r1;
if !cc jump Not_GET_DESCRIPTOR;
call Get_Descriptor;
jump Control_Handler_Exit;
Not_GET_DESCRIPTOR:
r1=8;
cc=r0==r1;
if !cc jump Not_GET_CONFIGURATION;
call Get_Configuration;
jump Control_Handler_Exit;
Not_GET_CONFIGURATION:
r1=9;
cc=r0==r1;
if !cc jump Not_SET_CONFIGURATION;
call Set_Configuration;
jump Control_Handler_Exit;
Not_SET_CONFIGURATION:
r1=0xa;
cc=r0==r1;
if !cc jump Not_GET_INTERFACE;
call Get_Interface;
jump Control_Handler_Exit;
Not_GET_INTERFACE:
r1=0xb;
cc=r0==r1;
if !cc jump NotStandardRequest;
call Set_Interface;
jump Control_Handler_Exit;
NotStandardRequest:
call Stall_ep0;
Control_Handler_Exit:
r2=[ SP++ ]; //pop r2
r1=[ SP++ ]; //pop r1
r0=[ SP++ ]; //pop r0
p1=[ SP++ ]; //pop p1
p0=[ SP++ ]; //pop p0
RETS = [ SP++ ];
rts;
Control_Handler.end:
/***************************************
** 函数名称: Ep0_RxDone(void)
** 功能描述: 通过端点索引 0 接收数据
** 输 入: 无
** 输 出: 无
***************************************/
.global Ep0_RxDone;
Ep0_RxDone:
[ --SP ] = RETS;
[ --SP ]=p0; //push p0
[ --SP ]=p1; //push p1
[ --SP ]=r0; //push r0
[ --SP ]=r1; //push r1
[ --SP ]=r2; //push r2
//read EP0 control out status
p0.l=lo(bEndp);
p0.h=hi(bEndp);
r0=0;
[p0]=r0;
call ReadLastTransactionStatus;
//rx setup packet or not?
p0.l=lo(D12Data);
p0.h=hi(D12Data);
r0=[p0];
r1=D12_SETUPPACKET;
r0=r0 & r1;
cc=r0==0;
if cc jump NotSetupPacket;
//it's a setup packet
////clear ControlDataLength
p0.l=lo(ControlDataLength);
p0.h=hi(ControlDataLength);
r0=0;
[p0]=r0;
////clear ControlDataCount
p0.l=lo(ControlDataCount);
p0.h=hi(ControlDataCount);
r0=0;
[p0]=r0;
//read 8 bytes from EP0 control out
////set bEndp=0
p0.l=lo(bEndp);
p0.h=hi(bEndp);
r0=0x0;
[p0]=r0;
////set bLen=8
p0.l=lo(bLen);
p0.h=hi(bLen);
r0=8; //the size of setup packet is always 8 bytes
[p0]=r0;
////put the data to buffer EP0RxBuf
p0.l=lo(pBuf);
p0.h=hi(pBuf);
r0.l=lo(EP0RxBuf);
r0.h=hi(EP0RxBuf);
[p0]=r0;
call ReadEndpoint;
//Rx the setup packet sucessfully?
p0.l=lo(D12Data);
p0.h=hi(D12Data);
r0=[p0];
r1=8;
cc=r0==r1;
if cc jump RxSetupPacketOK;
//Rx failed
////stall both control in & control out endpoint
call Stall_ep0;
////ControlState=0, means USB_IDLE,not busy
p0.l=lo(ControlState);
p0.h=hi(ControlState);
r0=0;
[p0]=r0;
jump Ep0_RxDone_Exit;
RxSetupPacketOK:
//Acknowledage both control in & control out endpoint
p0.l=lo(bEndp);
p0.h=hi(bEndp);
r0=0x0;
[p0]=r0;
call AcknowledgeEndpoint;
r0=0x1;
[p0]=r0;
call AcknowledgeEndpoint;
//read the device request length and set it as the value of ControlDataLength
p1.l=lo(EP0RxBuf);
p1.h=hi(EP0RxBuf);
//read the device request type. Control IN or Out?
r0.l=w[p1];
r0.h=0;
p0.l=lo(bRequestType);
p0.h=hi(bRequestType);
[p0]=r0; //save request type
p1+=2;
r0.l=w[p1];
r0.h=0;
p0.l=lo(bRequest);
p0.h=hi(bRequest);
[p0]=r0; //save request
p1+=2;
r0.l=w[p1];
r0.h=0;
p1+=2;
r1.l=w[p1];
r1.h=0;
r1=r1<<8;
r0=r1|r0;
p0.l=lo(wValue);
p0.h=hi(wValue);
[p0]=r0; //save value
p1+=2;
r0.l=w[p1];
r0.h=0;
p1+=2;
r1.l=w[p1];
r1.h=0;
r1=r1<<8;
r0=r1|r0;
p0.l=lo(wIndex);
p0.h=hi(wIndex);
[p0]=r0; //save index
p1+=2;
r0.l=w[p1];
r0.h=0;
p1+=2;
r1.l=w[p1];
r1.h=0;
r1=r1<<8;
r0=r1|r0;
p0.l=lo(ControlDataLength);
p0.h=hi(ControlDataLength);
[p0]=r0; //save length
p0.l=lo(bRequestType);
p0.h=hi(bRequestType);
r0=[p0];
r1=USB_ENDPOINT_DIRECTION_MASK;
r0=r0&r1;
cc=r0==0;
if cc jump ControlOutTransfer;
//Control In Transfer
////set SetupPacket=1
p0.l=lo(SetupPacket);
p0.h=hi(SetupPacket);
r0=1;
[p0]=r0;
////set ControlState=1
p0.l=lo(ControlState);
p0.h=hi(ControlState);
r0=1;
[p0]=r0;
jump Ep0_RxDone_Exit;
ControlOutTransfer:
p0.l=lo(ControlDataLength);
p0.h=hi(ControlDataLength);
r0=[p0];
cc=r0==0;
if !cc jump DeviceRequestLengthNotZero;
////set SetupPacket=1
p0.l=lo(SetupPacket);
p0.h=hi(SetupPacket);
r0=1;
[p0]=r0;
////set ControlState=1
p0.l=lo(ControlState);
p0.h=hi(ControlState);
r0=0;
[p0]=r0;
jump Ep0_RxDone_Exit;
DeviceRequestLengthNotZero:
r1=MAX_CONTROLDATA_SIZE;
cc=r1<r0;
if !cc jump DeviceRequestLengthCorrect;
//Tx failed
////stall both control in & control out endpoint
call Stall_ep0;
////ControlState=0, means USB IDLE
p0.l=lo(ControlState);
p0.h=hi(ControlState);
r0=0;
[p0]=r0;
jump Ep0_RxDone_Exit;
DeviceRequestLengthCorrect:
////ControlState=2, means USB RECEIVE
p0.l=lo(ControlState);
p0.h=hi(ControlState);
r0=2;
[p0]=r0;
jump Ep0_RxDone_Exit;
NotSetupPacket:
p0.l=lo(ControlState);
p0.h=hi(ControlState);
r0=[p0];
r1=2;
cc=r0==r1;
if !cc jump Not_USB_RECEIVE_State;
//read 8 bytes from EP0 control out
////set bEndp=0
p0.l=lo(bEndp);
p0.h=hi(bEndp);
r0=0x0;
[p0]=r0;
////set bLen=8
p0.l=lo(bLen);
p0.h=hi(bLen);
r0=EP0_PACKET_SIZE; //the size of setup packet is always 8 bytes
[p0]=r0;
p1.l=lo(ControlDataCount);
p1.h=hi(ControlDataCount);
r2=[p1];
r2<<=1; //left shift r2 means r2*2
////put the data to buffer EP0RxBuf
p0.l=lo(pBuf);
p0.h=hi(pBuf);
r0.l=lo(EP0RxBuf);
r0.h=hi(EP0RxBuf);
r0=r0+r2;
[p0]=r0;
call ReadEndpoint;
p0.l=lo(D12Data);
p0.h=hi(D12Data);
r0=[p0]; //how many bytes have been sent out?
//ControlDataCount = ControlDataCount + D12Data
r1=[p1];
r1=r1+r0;
[p1]=r1;
//if D12Data=EP0_PACKET_SIZE then exit
r2=EP0_PACKET_SIZE;
cc=r0==r2;
if cc jump Ep0_RxDone_Exit;
//if ControlDataCount>=ControlDataLeng then exit
p0.l=lo(ControlDataLength);
p0.h=hi(ControlDataLength);
r2=[p0];
cc=r2<=r1;
if !cc jump Ep0_RxDone_Exit;
//set SetupPacket=1
p0.l=lo(SetupPacket);
p0.h=hi(SetupPacket);
r0=1;
[p0]=r0;
//set ControlState=0, means USB_IDLE
p0.l=lo(ControlState);
p0.h=hi(ControlState);
r0=0;
[p0]=r0;
jump Ep0_RxDone_Exit;
Not_USB_RECEIVE_State:
//set ControlState=0, means USB_IDLE
p0.l=lo(ControlState);
p0.h=hi(ControlState);
r0=0;
[p0]=r0;
Ep0_RxDone_Exit:
r2=[ SP++ ]; //pop r2
r1=[ SP++ ]; //pop r1
r0=[ SP++ ]; //pop r0
p1=[ SP++ ]; //pop p1
p0=[ SP++ ]; //pop p0
RETS = [ SP++ ];
rts;
Ep0_RxDone.end:
/***************************************
** 函数名称: Ep0_TxDone(void)
** 功能描述: 通过端点索引 0 发送数据
** 输 入: 无
** 输 出: 无
***************************************/
.global Ep0_TxDone;
Ep0_TxDone:
[ --SP ] = RETS;
[ --SP ]=p0; //push p0
[ --SP ]=r0; //push r0
[ --SP ]=r1; //push r1
[ --SP ]=r2; //push r2
//caculate the nuber of bytes left
p0.l=lo(ControlDataLength);
p0.h=hi(ControlDataLength);
r0=[p0];
p0.l=lo(ControlDataCount);
p0.h=hi(ControlDataCount);
r1=[p0];
r1=r0-r1; //r1 keep the remains
//read EP0 OUT last transaction status
p0.l=lo(bEndp);
p0.h=hi(bEndp);
r0=0x1;
[p0]=r0;
call ReadLastTransactionStatus;
p0.l=lo(ControlState);
p0.h=hi(ControlState);
r0=[p0];
r2=1;
cc=r0==r2;
if cc jump PacketSendNeeded;
//D12 send out an empty package then exit
p0.l=lo(bLen);
p0.h=hi(bLen);
r0=0;
[p0]=r0;
call Single_transmit;
nop;nop;nop;nop;
jump Ep0_TxDone_Exit;
PacketSendNeeded:
r2=EP0_PACKET_SIZE;
cc=r2<=r1;
if !cc jump LessThan_EP0_PACKET_SIZE_Remains;
p0.l=lo(bEndp);
p0.h=hi(bEndp);
r0=0x1;
[p0]=r0;
p0.l=lo(bLen);
p0.h=hi(bLen);
r0=EP0_PACKET_SIZE;
[p0]=r0;
p0.l=lo(ControlDataCount);
p0.h=hi(ControlDataCount);
r2=[p0];
r2<<=1; //left shift r2 means r2*2
p0.l=lo(ControlData_pData);
p0.h=hi(ControlData_pData);
r0=[p0];
r0=r0+r2;
p0.l=lo(pBuf);
p0.h=hi(pBuf);
[p0]=r0;
call WriteEndpoint;
//ControlDataCount=ControlDataCount+EP0_PACKET_SIZE
p0.l=lo(ControlDataCount);
p0.h=hi(ControlDataCount);
r2=[p0];
r0=EP0_PACKET_SIZE;
r2=r0+r2;
[p0]=r2;
//ControlState=1, means some data needs to be sent
p0.l=lo(ControlState);
p0.h=hi(ControlState);
r0=1;
[p0]=r0;
jump Ep0_TxDone_Exit;
LessThan_EP0_PACKET_SIZE_Remains:
r0=0;
cc=r1==r0;
if cc jump Ep0_TxFinished;
p0.l=lo(bEndp);
p0.h=hi(bEndp);
r0=0x1;
[p0]=r0;
p0.l=lo(bLen);
p0.h=hi(bLen);
[p0]=r1;
p0.l=lo(ControlDataCount);
p0.h=hi(ControlDataCount);
r2=[p0];
r2<<=1; //left shift r2 means r2*2
p0.l=lo(ControlData_pData);
p0.h=hi(ControlData_pData);
r0=[p0];
r0=r0+r2;
p0.l=lo(pBuf);
p0.h=hi(pBuf);
[p0]=r0;
call WriteEndpoint;
//ControlDataCount=ControlDataCount+EP0_PACKET_SIZE
p0.l=lo(ControlDataCount);
p0.h=hi(ControlDataCount);
r2=[p0];
r2=r2+r1;
[p0]=r2;
//ControlState=0, means no data left
p0.l=lo(ControlState);
p0.h=hi(ControlState);
r0=0;
[p0]=r0;
jump Ep0_TxDone_Exit;
Ep0_TxFinished:
p0.l=lo(bEndp);
p0.h=hi(bEndp);
r0=0x1;
[p0]=r0;
p0.l=lo(bLen);
p0.h=hi(bLen);
r0=0;
[p0]=r0;
call WriteEndpoint;
//ControlState=0, means no data left
p0.l=lo(ControlState);
p0.h=hi(ControlState);
r0=0;
[p0]=r0;
Ep0_TxDone_Exit:
r2=[ SP++ ]; //pop r2
r1=[ SP++ ]; //pop r1
r0=[ SP++ ]; //pop r0
p0=[ SP++ ]; //pop p0
RETS = [ SP++ ];
rts;
Ep0_TxDone.end:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -