⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 upsd3400_usb_app.c

📁 uPSD34xx Disk driver
💻 C
📖 第 1 页 / 共 3 页
字号:
     }


// Now the sector is ready for write

    i = PhysicalDataAddr;
    j =0;
    while (j<64)                             //now burn the data into flash
     {
      if (WriteToMainFlash(i,~USB_FIFO[j]) == TRUE)
       {
                                             // an error occured, try it again
        gbCSWStatus = FAIL;                //error during write operation occured!
        j = 255;
       }
      else
       {
        i++;
        j++;
       }
     }


    UCON |= EPFIFO_BSY;


    SpecificIncrementSectorAddress();
   }

  if (TransferLength == 0)
   {
    ReturnCSW();                             // return status
   }

  UPSD_xreg.DATAOUT_D = 255;                 // WRITE done, RED LED OFF !
 }

void ReadBufferFromFlash(void)
/******************************************************************************
 Function   : void ReadBufferFromFlash()
 Parameters : (none)
 Description: Reads (sends) TransferLength sectors with length of 512 bytes
 ******************************************************************************/
 {


  if (TransferLength == 0)
   {
    ReturnCSW();                             // return status
   }
  else
   {
#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    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,#64
              movx   A,@DPTR
              cpl    A
              movx   @DPTR,A
              djnz   B,$-3
              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();
   }
 }

void OnRequestSense(void)
/*--------------------------------------------------------------------
 Function   : void OnRequestSense()
 Parameters : none
 Description: Handler for RequestSense command
        The REQUEST SENSE command requests that the device server
              transfer sense data to the application client.
---------------------------------------------------------------------*/
 {
  USEL  = INDIR | UMSC_IN_ENDPOINT;          //Select EP1 IN

  USB_FIFO[ 0] = 0x70;
  USB_FIFO[ 1] = 0x00;
  USB_FIFO[ 2] = 0x03;                       //sense key
  USB_FIFO[ 3] = 0x00;
  USB_FIFO[ 4] = 0x00;
  USB_FIFO[ 5] = 0x00;
  USB_FIFO[ 6] = 0x00;
  USB_FIFO[ 7] = 0x0A;                       //additional Length
  USB_FIFO[ 8] = 0x00;
  USB_FIFO[ 9] = 0x00;
  USB_FIFO[10] = 0x00;
  USB_FIFO[11] = 0x00;
  USB_FIFO[12] = 0x30;                       //ASC
  USB_FIFO[13] = 0x01;                       //ASCQ
  USB_FIFO[14] = 0x00;
  USB_FIFO[15] = 0x00;
  USB_FIFO[16] = 0x00;
  USB_FIFO[17] = 0x00;

  USIZE = 18;

  gbBulkPipeStage = BS_CSW_PHASE;
 }

void OnInquiry(void)
/*--------------------------------------------------------------------
 Function   : void OnInquiry()
 Parameters : none
 Description: Handler for Inquiry command
---------------------------------------------------------------------*/
 {
  USEL  = INDIR | UMSC_IN_ENDPOINT;          //Select EP1 IN
  USB_FIFO[ 0] = 0x00;
  USB_FIFO[ 1] = 0x80;                   //b7 = RMB = 1 if the medium is removable
  USB_FIFO[ 2] = 0x00;
  USB_FIFO[ 3] = 0x01;

  USB_FIFO[ 4] = 36-4;                       //additional Length (n-4)
  USB_FIFO[ 5] = 0x80;
  USB_FIFO[ 6] = 0x00;
  USB_FIFO[ 7] = 0x01;

#ifdef DK3400
  USB_FIFO[ 8] = 'S';                        //Vendor Information
  USB_FIFO[ 9] = 'T';
  USB_FIFO[10] = ' ';
  USB_FIFO[11] = ' ';
  USB_FIFO[12] = ' ';
  USB_FIFO[13] = ' ';
  USB_FIFO[14] = ' ';
  USB_FIFO[15] = ' ';

  USB_FIFO[16] = 'D';                        //Product Identification
  USB_FIFO[17] = 'K';
  USB_FIFO[18] = '3';
  USB_FIFO[19] = '4';
  USB_FIFO[20] = '0';
  USB_FIFO[21] = '0';
  USB_FIFO[22] = ' ';
  USB_FIFO[23] = 'D';
  USB_FIFO[24] = 'e';
  USB_FIFO[25] = 'm';
  USB_FIFO[26] = 'o';
  USB_FIFO[27] = ' ';
  USB_FIFO[28] = ' ';
  USB_FIFO[29] = ' ';
  USB_FIFO[30] = ' ';
  USB_FIFO[31] = ' ';

  USB_FIFO[32] = '1';                        //Product Revision Level
  USB_FIFO[33] = '0';
  USB_FIFO[34] = '0';
  USB_FIFO[35] = '1';

  USIZE = 36;

#else //DK3420
  USB_FIFO[ 8] = 'S';                        //Vendor Information
  USB_FIFO[ 9] = 'T';
  USB_FIFO[10] = ' ';
  USB_FIFO[11] = ' ';
  USB_FIFO[12] = ' ';
  USB_FIFO[13] = ' ';
  USB_FIFO[14] = ' ';
  USB_FIFO[15] = ' ';

  USB_FIFO[16] = 'D';                        //Product Identification
  USB_FIFO[17] = 'K';
  USB_FIFO[18] = '3';
  USB_FIFO[19] = '4';
  USB_FIFO[20] = '2';
  USB_FIFO[21] = '0';
  USB_FIFO[22] = ' ';
  USB_FIFO[23] = 'D';
  USB_FIFO[24] = 'e';
  USB_FIFO[25] = 'm';
  USB_FIFO[26] = 'o';
  USB_FIFO[27] = ' ';
  USB_FIFO[28] = ' ';
  USB_FIFO[29] = ' ';
  USB_FIFO[30] = ' ';
  USB_FIFO[31] = ' ';

  USB_FIFO[32] = '1';                        //Product Revision Level
  USB_FIFO[33] = '0';
  USB_FIFO[34] = '0';
  USB_FIFO[35] = '1';

  USIZE = 36;
#endif

  gbBulkPipeStage = BS_CSW_PHASE;
 }

void OnModeSelect6(void)
/******************************************************************************
 Function   : void OnModeSelect6()
 Parameters : (void)
 Description: The MODE SELECT(6) command provides a means for
              an initiator to specify device parameters to a RBC device.
              RBC devices shall also implement the MODE SENSE(6) command.
 ******************************************************************************/
 {
  gbCSWStatus = FAIL;
  ReturnCSW();                               // return status
 }

void OnModeSense6(void)
/******************************************************************************
 Function   : void OnModeSense6()
 Parameters : none
 Description: Handler for ModeSense6 command
              The MODE SENSE(6) command provides a means for a device server
              to report parameters to an application client.
              It is a complementary command to the MODE SELECT(6) command.
              Device servers that implement the MODE SENSE(6) command
              shall also implement the MODE SELECT(6) command.
 ******************************************************************************/
 {
  USEL  = INDIR | UMSC_IN_ENDPOINT;          //Select EP1 IN

  USB_FIFO[ 0] = 0x03;
  USB_FIFO[ 1] = 0x00;
  USB_FIFO[ 2] = 0x00;
  USB_FIFO[ 3] = 0x00;

  USIZE = 4;

  gbBulkPipeStage = BS_CSW_PHASE;
 }

void OnModeSelect10(void)
/******************************************************************************
 Function   : void OnModeSelect10()
 Parameters : (void)
 Description: The MODE SELECT(10) command provides a means for
              the application client to specify medium,
              logical unit, or peripheral device parameters to the device server.
              Application clients should issue MODE SENSE(10) prior
              to each MODE SELECT(10) to determine supported mode pages,
              mode page lengths, and other parameters.
              Device servers that implement the MODE SELECT(10) command shall
              also implement the MODE SENSE(10) command.
 ******************************************************************************/
 {
  gbCSWStatus = FAIL;
  ReturnCSW();                               // return status
 }

void OnModeSense10(void)
/******************************************************************************
 Function   : void OnModeSense10()
 Parameters : none
 Description: Handler for ModeSense10 command
 ******************************************************************************/
 {
  USEL  = INDIR | UMSC_IN_ENDPOINT;          //Select EP1 IN

  USB_FIFO[ 0] = 0x00;
  USB_FIFO[ 1] = 0x06;
  USB_FIFO[ 2] = 0x00;
  USB_FIFO[ 3] = 0x00;
  USB_FIFO[ 4] = 0x00;
  USB_FIFO[ 5] = 0x00;
  USB_FIFO[ 6] = 0x00;
  USB_FIFO[ 7] = 0x00;

  USIZE = 8;

  gbBulkPipeStage = BS_CSW_PHASE;
 }

void DoReadCapacity(void)
/*--------------------------------------------------------------------
 Function   : void DoReadCapacity()
 Parameters : none
 Description: Handler for ReadCapacity command
              This routine returns real capacity of the device-1
---------------------------------------------------------------------*/
 {
  USEL  = INDIR | UMSC_IN_ENDPOINT;          //Select EP1 IN

  USB_FIFO[ 0] = 0x00;                       //Last logical block
  USB_FIFO[ 1] = 0x00;
  USB_FIFO[ 2] = 0x01;
  USB_FIFO[ 3] = 0xBF;                       //7*32768B

  USB_FIFO[ 4] = 0x00;                       //block length
  USB_FIFO[ 5] = 0x00;
  USB_FIFO[ 6] = 0x02;                       //512B
  USB_FIFO[ 7] = 0x00;

  USIZE = 8;

  gbBulkPipeStage = BS_CSW_PHASE;
 }

void DoReadFormatCapacity(void)
/*--------------------------------------------------------------------
 Function   : void DoReadFormatCapacity()
 Parameters : none
 Description: Handler for ReadFormatCapacity command
---------------------------------------------------------------------*/
 {
  USEL  = INDIR | UMSC_IN_ENDPOINT;          //Select EP1 IN

  USB_FIFO[ 0] = 0x00;
  USB_FIFO[ 1] = 0x00;
  USB_FIFO[ 2] = 0x00;
  USB_FIFO[ 3] = 0x08;                       //capacity list length

/* The following values are used during disk format */
  USB_FIFO[ 4] = 0x00;                       //block count
  USB_FIFO[ 5] = 0x00;
  USB_FIFO[ 6] = 0x01;
  USB_FIFO[ 7] = 0xBB;
  USB_FIFO[ 8] = 0x00;                       //block length
  USB_FIFO[ 9] = 0x00;
  USB_FIFO[10] = 0x02;                       //512B
  USB_FIFO[11] = 0x00;

  USIZE = 12;

  gbBulkPipeStage = BS_CSW_PHASE;
 }

void CheckReceiveCBW(void)
/******************************************************************************
  Function   : void CheckReceiveCBW()
  Parameters : none
  Description: Handle CBW package.
               Command Block Wrapper (CBW) shall start on a packet boundary
               and shall end as a short packet with exactly 31 (1Fh)
               bytes transferred. Fields appear aligned to byte offsets equal to
               a multiple of their byte size. All subsequent data and the CSW
               shall start at a new packet boundary.
               All CBW transfers shall be ordered with the LSB (byte 0) first
               (little endian). 
  ******************************************************************************/
 {
  data unsigned char i;                      // FOR variable

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -