📄 upsd3400_usb_app.c
字号:
USEL = OUTDIR | UMSC_OUT_ENDPOINT; // Select EP OUT
/* dCBWSignature:
Signature that helps identify this data packet as a CBW. The signature field
shall contain the value 43425355h (little endian), indicating a CBW.*/
if((USB_FIFO[0]==0x55) && (USB_FIFO[1]==0x53) &&
(USB_FIFO[2]==0x42) && (USB_FIFO[3]==0x43))
{
/* dCBWTag:
A Command Block Tag sent by the host. The device shall echo the contents of
this field back to the host in the dCSWTag field of the associated CSW. The
dCSWTag positively associates a CSW with the corresponding CBW.*/
*((uchar *)&gdwCBWTag+3) = USB_FIFO[4]; // LSB first
*((uchar *)&gdwCBWTag+2) = USB_FIFO[5];
*((uchar *)&gdwCBWTag+1) = USB_FIFO[6];
*((uchar *)&gdwCBWTag+0) = USB_FIFO[7];
/* dCBWDataTransferLength:
The number of bytes of data that the host expects to transfer on the Bulk-In
or Bulk-Out endpoint (as indicated by the Direction bit) during the execution
of this command. If this field is zero, the device and the host shall transfer
no data between the CBW and the associated CSW, and the device shall ignore
the value of the Direction bit in bmCBWFlags.*/
*((uchar *)&gdwCBWDataTransferLength+3) = USB_FIFO[ 8]; // LSB first
*((uchar *)&gdwCBWDataTransferLength+2) = USB_FIFO[ 9];
*((uchar *)&gdwCBWDataTransferLength+1) = USB_FIFO[10];
*((uchar *)&gdwCBWDataTransferLength+0) = USB_FIFO[11];
/* bmCBWFlags:
The bits of this field are defined as follows:
Bit 7 Direction - the device shall ignore this bit if the dCBWDataTransferLength
field is zero, otherwise:
0 = Data-Out from host to the device, 1 = Data-In from the device to the host.
Bit 6 Obsolete. The host shall set this bit to zero.
Bits 5..0 Reserved - the host shall set these bits to zero.*/
gbCBWFlags = USB_FIFO[12];
/* bCBWLUN:
The device Logical Unit Number (LUN) to which the command block is being sent.
For devices that support multiple LUNs, the host shall place into this field
the LUN to which this command block is addressed. Otherwise, the host shall
set this field to zero. */
gbCBWLUN = USB_FIFO[13];
/* bCBWCBLength:
The valid length of the CBWCB in bytes. This defines the valid length of the
command block. The only legal values are 1 through 16 (01h through 10h). All
other values are reserved. */
gbCBWCBLength = USB_FIFO[14];
if (gbCBWCBLength>16)
{
gbCBWCBLength = 16;
}
/* CBWCB:
The command block to be executed by the device. The device shall interpret
the first bCBWCBLength bytes in this field as a command block as defined by
the command set identified by bInterfaceSubClass. If the command set supported
by the device uses command blocks of fewer than 16 (10h) bytes in
length, the significant bytes shall be transferred first, beginning with the
byte at offset 15 (Fh). The device shall ignore the content of the CBWCB field
past the byte at offset (15 + bCBWCBLength - 1).
*/
for(i = 0; i<gbCBWCBLength; i++)
{
gbCBWCB[i] = USB_FIFO[15+i];
}
UCON |= EPFIFO_BSY;
gbCSWStatus = PASS; // default CSW Status
gbBulkPipeStage = BS_DATA_PHASE;
if (gbCBWCBLength>0)
{
/* Now decode the CBWCB; the command block to be executed by the device. */
switch (gbCBWCB[0])
{
case OP_READ10:
{
DoReadWrite();
break;
}
case OP_WRITE10:
{
DoReadWrite();
break;
}
case OP_TEST_UNIT_READY:
{
/* This is called by WinXP typ. every 1 second to check the unit */
/* default: all OK */
ReturnCSW(); // return status
break;
}
case OP_REQUEST_SENSE:
{
OnRequestSense();
break;
}
case OP_INQUIRY:
{
OnInquiry();
break;
}
case OP_MODE_SENSE10:
{
OnModeSense10();
break;
}
case OP_MODE_SELECT10:
{
OnModeSelect10();
break;
}
case OP_MODE_SENSE6:
{
OnModeSense6();
break;
}
case OP_MODE_SELECT6:
{
OnModeSelect6();
break;
}
case OP_READ_CAPACITY:
{
DoReadCapacity();
break;
}
case OP_READ_FORMAT_CAPACITIES:
{
DoReadFormatCapacity();
break;
}
case OP_MEDIA_REMOVEAL:
{
gbCSWStatus = FAIL;
ReturnCSW(); // return status
break;
}
case OP_VERIFY:
{
gbCSWStatus = FAIL; //implement your own checking mechanism
ReturnCSW(); // return status
break;
}
default:
{
gbCSWStatus = FAIL;
STALL_EP1(); // unknown command
gbBulkPipeStage = BS_CSW_PHASE;
break;
}
}
}
else
{
ReturnCSW(); // no command, return status
}
}
else
{
gbCSWStatus = FAIL;
STALL_EP1(); // unknown command block type, STALL
gbBulkPipeStage = BS_CBW_PHASE;
}
}
unsigned char USB_ISR_Counter; // incremented every USB INT event
void UsbIsr(void) interrupt USB_VECTOR using 2
/******************************************************************************
Function : void UsbIsr()
Parameters : none
Description: USB interrupt service routine.
Note: Do not modify this routine !!!
******************************************************************************/
{
UCTL |= VISIBLE; // enable USB FIFO mapping in XDATA
if (RSTF)
{
OnUsbReset(); // USB Reset int
UIE1 |= UMSC_MASK_IN_ENDPOINT; //Enable EP0 IN INT
UIE2 |= UMSC_MASK_OUT_ENDPOINT; //Enable EP0 OUT INT
USEL = OUTDIR | UMSC_OUT_ENDPOINT; //Select EP OUT
UCON = ENABLE_FIFO | EPFIFO_BSY;
USEL = INDIR | UMSC_IN_ENDPOINT; //Select EP IN
UCON = ENABLE_FIFO;
UIF1 = 0;
UIF2 = 0;
UIF3 = 0;
UIF0 = 0;
RSTF = 0;
SUSPNDF = 0;
if (UCON & TOGGLE) //only silicon revision #0
{
USIZE = 0; //send an empty packet to reach DATA=0
}
USTA = 0; //silicon revision #0
UADDR = 0; //Reset device address, silicon revision #0
gbBulkPipeStage = BS_CBW_PHASE;
}
/* IN packets servicing, invoked when TuPSD+ sent an ACKed packet to a host */
if (INF)
{
if (UIF1 & IN0F) // EP0 IN
{
UIF1 &= ~IN0F;
TransmitEP0();
if (usbState == US_ADDRESSED) // DEVICE ADDRESS change after SET_ADDRESS
{
UADDR = setupPacket.wValue.lo; //device address
usbState = US_DEFAULT;
}
}
if (UIF1 & UMSC_MASK_IN_ENDPOINT) // EP IN
{
switch (gbBulkPipeStage)
{
case BS_DATA_PHASE:
{
UIF1 &= ~UMSC_MASK_IN_ENDPOINT;
ReadBufferFromFlash();
break;
}
case BS_CBW_PHASE:
{
//UIF1 &= ~UMSC_MASK_IN_ENDPOINT;
break;
}
case BS_CSW_PHASE: // DATA phase finished, preparing CSW
{
UIF1 &= ~UMSC_MASK_IN_ENDPOINT;
ReturnCSW();
break;
}
case BS_CSW_DONE_PHASE: //CSW sent, IN FIFO became empty
{
UIF1 &= ~UMSC_MASK_IN_ENDPOINT;
gbBulkPipeStage = BS_CBW_PHASE; //CBW
break;
}
}
}
/*
if (UIF1 & IN2F) //EP2 IN
{
UIF1 &= ~IN2F; // User code area
}
if (UIF1 & IN3F) //EP3 IN
{
UIF1 &= ~IN3F; // User code area
}
if (UIF1 & IN4F) //EP4 IN
{
UIF1 &= ~IN4F; // User code area
}
*/
}
/* OUT packets servicing,invoked when TuPSD+ receives an OUT packet from a host*/
if (OUTF)
{
if (UIF2 & OUT0F) // EP0 OUT
{
UIF2 &= ~OUT0F;
if (USTA & SETUP)
{
ReadSetupPacket();
OnSetupPacket();
if (usbState == US_CONFIGURED)
{
USEL = INDIR | UMSC_IN_ENDPOINT; //Select EP IN
if (UCON & TOGGLE) //only silicon revision #0
{
USIZE = 0; //send an empty packet to reach DATA=0
}
// UCON &= ~TOGGLE; //clear toggle
USEL = OUTDIR | UMSC_OUT_ENDPOINT;//Select EP OUT
// UCON &= ~TOGGLE; //clear toggle
}
}
else
{
}
gbBulkPipeStage = BS_CBW_PHASE;
}
/*
if (UIF2 & OUT1F) // EP1 OUT
{
UIF2 &= ~OUT1F; // User code area
}
if (UIF2 & OUT2F) // EP2 OUT
{
UIF2 &= ~OUT2F; // User code area
}
*/
if (UIF2 & UMSC_MASK_OUT_ENDPOINT) // EP3 OUT
{
switch (gbBulkPipeStage)
{
case BS_CBW_PHASE: // Command received
{
UIF2 &= ~UMSC_MASK_OUT_ENDPOINT;
CheckReceiveCBW();
break;
}
case BS_DATA_PHASE: // Data block received
{
UIF2 &= ~UMSC_MASK_OUT_ENDPOINT;
WriteBufferToFlash();
break;
}
case BS_CSW_PHASE:
{
break;
}
case BS_CSW_DONE_PHASE:
{
break;
}
}
}
/*
if (UIF2 & OUT4F) // EP4 OUT
{
UIF2 &= ~OUT4F; // User code area
}
*/
}
if (SUSPNDF)
{
if (RESUMF)
{
UIE0 |= SUSPENDIE;
UIE0 &= ~RESUMEIE;
OnUsbResume(); // resume int
RESUMF = 0;
SUSPNDF = 0;
gbBulkPipeStage = BS_CBW_PHASE;
// only for DK3420
ET0 = 1; // enable timer 0 interrupt
}
else
{
UIE0 |= RESUMEIE;
UIE0 &= ~SUSPENDIE;
OnUsbSuspend(); // suspend int
gbBulkPipeStage = BS_CBW_PHASE;
// only for DK3420
ET0 = 0; // disable timer 0 interrupt
P4_0 = 1; // GREEN LED OFF
UPSD_xreg.DATAOUT_D = 255; // RED LED OFF
}
}
UCTL &= ~VISIBLE; // Disable USB FIFO mapping in XDATA
USB_ISR_Counter++; // USB activity indicator
}
/* *************************************************************************
*** ***
** *** End of File *** **
*** ***
************************************************************************* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -