?? upsd3400_usb_app.c
字號:
/*------------------------------------------------------------------------------
upsd3400_usb_app.c
Version:
March 22, 2005 - Version 1.0 - Initial Release.
Description: USB Mass Storage Class application module.
Copyright (c) 2005 STMicroelectronics Inc.
This example demo code is provided as is and has no warranty,
implied or otherwise. You are free to use/modify any of the provided
code at your own risk in your applications with the expressed limitation
of liability (see below) so long as your product using the code contains
at least one uPSD product (device).
LIMITATION OF LIABILITY: NEITHER STMicroelectronics NOR ITS VENDORS OR
AGENTS SHALL BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA,
INTERRUPTION OF BUSINESS, NOR FOR INDIRECT, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER THIS AGREEMENT OR
OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
------------------------------------------------------------------------------*/
#pragma NOAREGS
#include "upsd3400.h"
#include "upsd3400_hardware.h"
#include "upsd3400_usb.h"
#include "upsd3400_upsd_usb.h"
#include "upsd3400_usb_app.h"
#define USB_MS_SectorSize 512
#define USB_MS_UnitSize (USB_MS_SectorSize*9*64)
extern xdata PSD_REGS UPSD_xreg;
data unsigned char gbCBWCB[16];
data unsigned long int gdwCBWTag;
data unsigned long int gdwCBWDataTransferLength;
data unsigned char gbCBWFlags;
data unsigned char gbCBWLUN;
data unsigned char gbCBWCBLength;
data unsigned char gbCSWStatus;
data unsigned char gbBulkPipeStage;
static data unsigned int TransferLength;
static data unsigned int PhysicalDataAddr;
extern unsigned char data usbState, ep0state, ep1state;
extern setup_buffer setupPacket;
#define USB_FIFO ((unsigned char volatile xdata *) USB_BASE_ADDR)
#define UMSC_IN_ENDPOINT SELEP1
#define UMSC_OUT_ENDPOINT SELEP3
#define UMSC_MASK_IN_ENDPOINT IN1F
#define UMSC_MASK_OUT_ENDPOINT OUT3F
void ReturnCSW(void)
/******************************************************************************
Function : void ReturnCSW(void)
Parameters : none
Description: Handle CSW package.
Command Status Wrapper (CSW) shall start on a packet boundary
and shall end as a short packet with exactly 13 (0Dh) bytes
transferred. Fields appear aligned to byte offsets equal to
a multiple of their byte size. All CSW transfers shall
be ordered with the LSB (byte 0) first (little endian).
Refer to the USB Specification Terms and Abbreviations
for clarification.
******************************************************************************/
{
USEL = INDIR | UMSC_IN_ENDPOINT; //Select EP1 IN
/*dCSWSignature:
Signature that helps identify this data packet as a CSW. The signature field
shall contain the value 53425355h (little endian), indicating CSW. */
USB_FIFO[ 0] = 0x55; // dCSWSignature
USB_FIFO[ 1] = 0x53;
USB_FIFO[ 2] = 0x42;
USB_FIFO[ 3] = 0x53;
/*dCSWTag:
The device shall set this field to the value received in the dCBWTag
of the associated CBW.*/
USB_FIFO[ 4] = *((uchar *)&gdwCBWTag+3); // dCSWTag, LSB read first
USB_FIFO[ 5] = *((uchar *)&gdwCBWTag+2);
USB_FIFO[ 6] = *((uchar *)&gdwCBWTag+1);
USB_FIFO[ 7] = *((uchar *)&gdwCBWTag+0);
/*dCSWDataResidue:
For Data-Out the device shall report in the dCSWDataResidue the difference
between
the amount of data expected as stated in the dCBWDataTransferLength,
and the actual amount of data processed by the device.
For Data-In the device shall report in the dCSWDataResidue the difference
between the amount of data expected as stated in the dCBWDataTransferLength
and the actual amount of relevant data sent by the device.
The dCSWDataResidue shall not exceed the value sent in the dCBWDataTransferLength.
We return always zero, it is simple.
*/
USB_FIFO[ 8] = 0x00; // dCSWDataResidue
USB_FIFO[ 9] = 0x00;
USB_FIFO[10] = 0x00;
USB_FIFO[11] = 0x00;
/*bCSWStatus:
bCSWStatus indicates the success or failure of the command.
The device shall set this byte to zero if the command completed successfully.
A non-zero value shall indicate a failure during command execution according
to the following table:
00h Command Passed ("good status")
01h Command Failed
02h Phase Error
03h and 04h Reserved (Obsolete)
05h to FFh Reserved
*/
USB_FIFO[12] = gbCSWStatus; // bCSWStatus
USIZE = 0x0D; // fire !
gbBulkPipeStage = BS_CSW_DONE_PHASE;
}
void SpecificIncrementSectorAddress(void)
/******************************************************************************
Function : void SpecificIncrementSectorAddress(void)
Parameters : none
Description: Increments PhysicalDataAddr of 512b (1 sector),
adjust PAGE and TransferLength.
Used in Read and Write Commands
******************************************************************************/
{
PhysicalDataAddr += 64; // next sector physical address
if (PhysicalDataAddr < 0x8000)
{
PhysicalDataAddr += 0x8000; // adjust address to the top half of memory
UPSD_xreg.PAGE += 1; // adjust PAGE
}
TransferLength--; // decrement sector counter
}
void WriteBufferToFlash(void)
/******************************************************************************
Function : void WriteBufferToFlash()
Parameters : (none)
Description: Receives (writes) sectors
******************************************************************************/
{
if (TransferLength != 0)
{
UIF2 &= ~UMSC_MASK_OUT_ENDPOINT; // clear INT Flag
#ifdef __RC51__ //Compiler: Raisonance
#pragma asm
;The following equates are also defined in usb.h
; and should be the same in both places.
;The following EQUates are only needed when using RIDE.
USB_BASE_ADDR EQU 7000H ;USB FIFO mapped in XDATA space
INDIR EQU 0
SELEP1 EQU 1
UMSC_IN_ENDPOINT EQU SELEP1
#pragma endasm
#endif
#pragma asm
mov DPTM,#0
mov DPTC,#1
mov DPTR,#USB_BASE_ADDR
mov DPTC,#0
mov DPH,PhysicalDataAddr+0
mov DPL,PhysicalDataAddr+1
mov DPTC,#64+1
mov DPTM,#10
mov B,#8
movx A,@DPTR
movx @DPTR,A
movx A,@DPTR
movx @DPTR,A
movx A,@DPTR
movx @DPTR,A
movx A,@DPTR
movx @DPTR,A
movx A,@DPTR
movx @DPTR,A
movx A,@DPTR
movx @DPTR,A
movx A,@DPTR
movx @DPTR,A
movx A,@DPTR
movx @DPTR,A
djnz B,$-16
mov DPTM,#0
mov DPTC,#0
#pragma endasm
UCON |= EPFIFO_BSY; // release buffer, new OUT data can come
SpecificIncrementSectorAddress();
}
if (TransferLength == 0)
{
ReturnCSW(); // return status
}
}
void ReadBufferFromFlash(void)
/******************************************************************************
Function : void ReadBufferFromFlash()
Parameters : (none)
Description: Reads (sends) sectors to a host
******************************************************************************/
{
if (TransferLength == 0)
{
ReturnCSW(); // return status
}
else
{
#pragma asm
mov DPTM,#0
mov DPTC,#1
mov DPH,PhysicalDataAddr+0
mov DPL,PhysicalDataAddr+1
mov DPTM,#10
mov USEL,#INDIR+UMSC_IN_ENDPOINT
mov DPTC,#0
mov DPTR,#USB_BASE_ADDR
mov DPTC,#64+1
mov B,#8
movx A,@DPTR
movx @DPTR,A
movx A,@DPTR
movx @DPTR,A
movx A,@DPTR
movx @DPTR,A
movx A,@DPTR
movx @DPTR,A
movx A,@DPTR
movx @DPTR,A
movx A,@DPTR
movx @DPTR,A
movx A,@DPTR
movx @DPTR,A
movx A,@DPTR
movx @DPTR,A
djnz B,$-16
mov USIZE,#64 ; FIRE!
mov DPTM,#0
mov DPTC,#0
#pragma endasm
SpecificIncrementSectorAddress();
/*gbCSWStatus = FAIL;*/
}
}
void DoReadWrite(void)
/*--------------------------------------------------------------------
Function : void DoReadWrite()
Parameters : none
Description: Handler for READ and WRITE command
---------------------------------------------------------------------*/
{
data unsigned long LogicalBlockAddr;
/* Decode the Command Descriptor Block (CDB)
Byte 0 OPERATION CODE
Byte 1 Reserved
Byte 2,3,4,5 (MSB) LOGICAL BLOCK ADDRESS (LSB)
Byte 6 Reserved
Byte 7 (MSB)
Byte 8 TRANSFER LENGTH (LSB)
Byte 9 CONTROL = 00h
The LOGICAL BLOCK ADDRESS field specifies the first logical block of the range
of logical blocks that shall be read.
The TRANSFER LENGTH field specifies the number of contiguous logical blocks of
data that shall be transferred. A TRANSFER LENGTH of zero indicates that no logical
blocks shall be transferred. This condition shall not be considered an error.
Any other value indicates the number of logical blocks that shall be transferred.
*/
LogicalBlockAddr = *(unsigned long int *)&gbCBWCB[2];
PhysicalDataAddr = ((unsigned int )(LogicalBlockAddr << 9)) | 0x8000;
UPSD_xreg.PAGE = (unsigned char)(LogicalBlockAddr >> 6);
TransferLength = *(unsigned int *)&gbCBWCB[7];
TransferLength = TransferLength*8;
gbBulkPipeStage = BS_DATA_PHASE;
if (gbCBWFlags & 0x80) // READ command
{
ReadBufferFromFlash();
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -