📄 msd_fn_xfer.c
字号:
#include "DrvOTGMain.h"
//#include "uart.h"
__s32 USB_Get_Bits_From_Byte_Stream(__u8 *data_ptr,__u8 p,__u8 n, __s8 *err);
__s32 USB_Get_Nbits_Value(__u8 * Ndata,__u8 p,__u8 n);
__s32 USB_Set_Bits_In_Byte_Stream(__u8 *data_ptr, __s32 value, __u8 p, __u8 n);
void USB_Set_Bits_In_Byte(__u8 *data_ptr, __s32 value, __u8 p, __u8 n);
void USB_Set_Bits_In_Short(__u8 *data_ptr, __s32 value, __u8 p, __u8 n);
void USB_Set_Bits_In_3Bytes(__u8 *data_ptr, __s32 value, __u8 p, __u8 n);
void USB_Set_Bits_In_Int(__u8 *data_ptr, __s32 value, __u8 p, __u8 n);
__s32 USB_Get_Bits_From_Byte_Stream(__u8 *data_ptr,__u8 p,__u8 n, __s8 *err)
{
__s32 value = 0;
if(data_ptr)
{
if ( (p + n) <= MAX_BITS_INT )
{
value = USB_Get_Nbits_Value(data_ptr, p, n);
*err = 0;
}
else
{
*err = -2;
}
}
else
{
*err = -1;
}
return (value);
}
__s32 USB_Get_Nbits_Value(__u8 *Ndata,__u8 p,__u8 n)
{
__s32 tmp;
__s32 value;
//printf("\r\n D0=%x", *Ndata);
//printf("\r\n D1=%x", *(Ndata+1));
//printf("\r\n D2=%x", *(Ndata+2));
//printf("\r\n D3=%x", *(Ndata+3));
tmp = (__s32)((__s32)(*Ndata) +
(__s32)(*(Ndata+1)) * (POSITION_VALUE_8) +
(__s32)(*(Ndata+2)) * (POSITION_VALUE_16) +
(__s32)(*(Ndata+3)) * (POSITION_VALUE_24) );
if(n == 32)
value = ( (tmp >> (p) ) & 0xFFFFFFFF );
else
value = ( (tmp >> (p) ) & BIT_MASK(n) );
return(value);
}
__s32 USB_Set_Bits_In_Byte_Stream(__u8 *data_ptr, __s32 value, __u8 p, __u8 n)
{
__s32 ret_value = 0;
if(data_ptr)
{
if ( (p + n) <= MAX_BITS_BYTE )
{
USB_Set_Bits_In_Byte(data_ptr, value, p, n) ;
}
else if ( (p + n) <= MAX_BITS_SHORT)
{
USB_Set_Bits_In_Short(data_ptr, value, p, n);
}
else if ( (p + n) <= MAX_BITS_3BYTE)
{
USB_Set_Bits_In_3Bytes(data_ptr, value, p, n);
}
else if( (p + n) <= MAX_BITS_INT)
{
USB_Set_Bits_In_Int(data_ptr, value, p, n);
}
else
{
ret_value = -2;
}
}
else
{
ret_value = -1;
}
return(ret_value);
}
void USB_Set_Bits_In_Byte(__u8 *data_ptr, __s32 value, __u8 p, __u8 n)
{
*data_ptr = (*data_ptr & ~( BIT_MASK(n) << p )) |
( ( value & BIT_MASK(n) ) << p ) ;
return;
}
void USB_Set_Bits_In_Short(__u8 *data_ptr, __s32 value, __u8 p, __u8 n)
{
__u8 bits_in_1st_byte, bits_in_2nd_byte;
bits_in_1st_byte = MAX_BITS_BYTE - p ;
bits_in_2nd_byte = n - bits_in_1st_byte;
*data_ptr = (*data_ptr & ~( BIT_MASK(bits_in_1st_byte) << p )) |
( (value & BIT_MASK(bits_in_1st_byte) ) << p ) ;
*(data_ptr+1) = (*(data_ptr+1) & ~( BIT_MASK(bits_in_2nd_byte) )) |
(( value>>bits_in_1st_byte & BIT_MASK(bits_in_2nd_byte) ));
return;
}
void USB_Set_Bits_In_3Bytes(__u8 *data_ptr, __s32 value, __u8 p, __u8 n)
{
__u8 bits_in_1st_byte, bits_in_3rd_byte;
bits_in_1st_byte = MAX_BITS_BYTE - p ;
bits_in_3rd_byte = n - bits_in_1st_byte - MAX_BITS_BYTE ;
*data_ptr = (*data_ptr & ~( BIT_MASK(bits_in_1st_byte) << p )) |
( ( value & BIT_MASK(bits_in_1st_byte) ) << p ) ;
*(data_ptr+1) = value>>bits_in_1st_byte ;
*(data_ptr+2) = (*(data_ptr+2) & ~( BIT_MASK(bits_in_3rd_byte) )) |
( ( value>>(bits_in_1st_byte + MAX_BITS_BYTE) &
BIT_MASK(bits_in_3rd_byte) ) ) ;
return;
}
void USB_Set_Bits_In_Int(__u8 *data_ptr, __s32 value, __u8 p, __u8 n)
{
__u8 bits_in_1st_byte, bits_in_4th_byte;
bits_in_1st_byte = MAX_BITS_BYTE - p ;
bits_in_4th_byte = n - bits_in_1st_byte - MAX_BITS_SHORT ;
*data_ptr = (*data_ptr & ~( BIT_MASK(bits_in_1st_byte) << p )) |
( ( value & BIT_MASK(bits_in_1st_byte) ) << p ) ;
*(data_ptr+1) = value>>bits_in_1st_byte ;
*(data_ptr+2) = value>>(bits_in_1st_byte + MAX_BITS_BYTE) ;
*(data_ptr+3) = (*(data_ptr+3) & ~( BIT_MASK(bits_in_4th_byte) )) |
( ( value>>(bits_in_1st_byte + MAX_BITS_SHORT) &
BIT_MASK(bits_in_4th_byte) ) ) ;
return;
}
void USB_MSDFN_Decode_CBW(__u8 *cbwP, MSDFN_BOT_CBW_STRU *cbw)
{
__s8 err;
__u8 i;
cbw->signature = USB_Get_Bits_From_Byte_Stream(cbwP, 0, 32, &err);
cbw->tag = USB_Get_Bits_From_Byte_Stream(cbwP+4, 0, 32, &err);
cbw->dxfer_length = USB_Get_Bits_From_Byte_Stream(cbwP+8, 0, 32, &err);
cbw->dir_flag = cbwP[12];
cbw->max_lun = cbwP[13];
cbw->cmd_length = cbwP[14];
for (i=0;i<16;i++)
cbw->cmd_bytes[i]=cbwP[15+i];
return;
}
void USB_MSDFN_Encode_CSW(MSDFN_BOT_CSW_STRU csw, __u8 *cswP)
{
USB_Set_Bits_In_Byte_Stream(cswP, csw.signature, 0, 32);
USB_Set_Bits_In_Byte_Stream(cswP+4, csw.tag, 0, 32);
USB_Set_Bits_In_Byte_Stream(cswP+8, csw.residue, 0, 32);
cswP[12] = csw.status;
return;
}
__u8 USB_MSDFN_BOT_Err_Hndlr(MSDFN_BOT_CBW_STRU cbw,__u8 sts)
{
__u32 residue = 0;
__u8 status = CASEOK;
__u8 err;
err = USB_MSDFN_BOT_Calc_Case(cbw);
residue = otgfun_residue;
status = sts;
switch(err)
{
case CASEOK:
case CASE_Hn_eq_Dn : /* Hn=Dn*/
case CASE_Hi_eq_Di : /* Hi=Di*/
case CASE_Ho_eq_Do : /* Ho=Do*/
{
residue = 0;
break;
}
case CASE_Hi_gt_Dn : /* Hi>Dn */
{
status = MSDFN_BOT_COMMAND_FAILED;
printf("\r\n Hi_gt_Dn_STALL", 0);
USB_Endpoint_Bulk_In_Stall();
break;
}
case CASE_Hi_gt_Di : /* Hi>Di */
{
break;
}
case CASE_Ho_gt_Dn : /* Ho>Dn*/
case CASE_Ho_gt_Do : /* Ho>Do*/
{
status = MSDFN_BOT_COMMAND_FAILED;
printf("\r\n Ho_gt_Do_STALL",0);
USB_Endpoint_Bulk_Out_Stall();
break;
}
case CASE_Hn_lt_Di : /* Hn<Di*/
case CASE_Hn_lt_Do : /* Hn<Do*/
{
USB_Endpoint_Bulk_In_Stall();
printf("\r\n Hn_lt_Do_STALL",0);
otgfun_residue = 0;
status = MSDFN_BOT_PHASE_ERROR;
break;
}
case CASE_Hi_ne_Do : /* Hi<>Do */
{
printf("\r\n Hi_ne_Do_STALL",0);
USB_Endpoint_Bulk_In_Stall();
status = MSDFN_BOT_PHASE_ERROR;
break;
}
case CASE_Ho_lt_Do : /* Ho<Do */
{
printf("\r\n Ho_lt_Do_STALL",0);
otgfun_residue = -1;
status = MSDFN_BOT_PHASE_ERROR;
USB_Endpoint_Bulk_Out_Stall();
break;
}
case CASE_Ho_ne_Di : /* Ho<>Di */
{
printf("\r\n Ho_ne_Di_STALL",0);
otgfun_residue = -1;
status = MSDFN_BOT_PHASE_ERROR;
USB_Endpoint_Bulk_In_Stall();
break;
}
case CASE_Hi_lt_Di : /* Hi<Di*/
{
printf("\r\n Hi_lt_Di_STALL",0);
USB_Endpoint_Bulk_In_Stall();
otgfun_residue = -1;
status = MSDFN_BOT_PHASE_ERROR;
break;
}
case CASECBW : /* invalid CBW */
{
printf("\r\n invalid_CBW_STALL",0);
USB_Endpoint_Bulk_In_Stall();
status = MSDFN_BOT_PHASE_ERROR;
break;
}
case CASE_ERROR:
default:
break;
}
return status;
}
__u8 USB_MSDFN_BOT_Calc_Case(MSDFN_BOT_CBW_STRU cbw)
{
__u8 host_dev_case = 0;
__u32 dataXfer_len = 0;
__u8 dataXfer_dir = 0;
__u32 actualXfer_len = 0;
__u8 actualXfer_dir = 0;
dataXfer_len = cbw.dxfer_length;
dataXfer_dir = cbw.dir_flag;
actualXfer_len = otgactualXfer_len;
actualXfer_dir = otgdataXfer_dir;
if ( dataXfer_len == actualXfer_len )
host_dev_case = CASEOK;
else if ( actualXfer_dir != dataXfer_dir )
host_dev_case = dataXfer_dir ? CASE_Hi_ne_Do : CASE_Ho_ne_Di;
else if ( dataXfer_len == 0 )
host_dev_case = actualXfer_dir ? CASE_Hn_lt_Di : CASE_Hn_lt_Do;
else if ( actualXfer_len == 0 )
host_dev_case = dataXfer_dir ? CASE_Hi_gt_Dn : CASE_Ho_gt_Dn;
else if ( dataXfer_len > actualXfer_len )
host_dev_case = dataXfer_dir ? CASE_Hi_gt_Di : CASE_Ho_gt_Do;
else
host_dev_case = dataXfer_dir ? CASE_Hi_lt_Di : CASE_Ho_lt_Do;
return host_dev_case;
}
void USB_Endpoint_Bulk_In_Stall(void)
{
__u8 ep;
ep = usb_Ret_Blt_EP_Object(EP_TX);//EP_RX
USB_Send_Stall(ep);
//return;
}
void USB_Endpoint_Bulk_Out_Stall(void)
{
__u8 ep;
ep = usb_Ret_Blt_EP_Object(EP_RX);//EP_TX
USB_Send_Stall(ep);
//return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -