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

📄 fw.c

📁 cy68013a USB2.0 highspeed mass storage source code
💻 C
📖 第 1 页 / 共 3 页
字号:
                           EP2CS = bmEPSTALL;         // Set stall bit
                        else if (wIndex == 0x86)
                           EP6CS = bmEPSTALL;         // Set stall bit
                        else if (wIndex == 0x81)
                           EP1INCS = bmEPSTALL;         // Set stall bit
                        else
                           EZUSB_STALL_EP0();   // Stall End Point 0
                        }
                     else
                        EZUSB_STALL_EP0();   // Stall End Point 0
                     break;
                  default:
                     EZUSB_STALL_EP0();      // Stall End Point 0
               }  
            break;
   
         default:                            // *** Invalid Command
               EZUSB_STALL_EP0();            // Stall End Point 0
         }
      }
   else if ((setupdat0 & SETUP_MASK) == SETUP_CLASS_REQUEST)
   {
      if (wIndex == 0 && wValue ==0)      // Interface 0 = Mass Storage
         {
         switch(SETUPDAT[1])
            {
            case SC_MASS_STORAGE_RESET:
                  // Verify that the command is actually a MS reset command sent to the proper interface
                  if (setupdat0 == 0x21 && wLength == 0)  // Our interface number is hard coded (0) in DSCR.A51
                  {
                     // All we really need to do in response to a MSC Reset is restart using
                     // a soft reset (jump to 0x00).  This will re-initialize the drive and
                     // endpoints.
                     EZUSB_IRQ_CLEAR();
                     INT2CLR = bmSUDAV;         // Clear SUDAV IRQ

                     phaseErrorState = 0;
         
                     // force a soft reset after the iret.
                     EA = 0;
                     softReset();
                  }
                  else
                     EZUSB_STALL_EP0();   // Stall End Point 0
                  break;
         
            case SC_GET_MAX_LUN:
               if (setupdat0 == 0xa1 && wLength == 1)  // Our interface number is hard coded (0) in DSCR.A51
               {
                  if (b2LUN_SET_BY_EEPROM)
                     EP0BUF[0] = 1;
                  else if (b1LUN_SET_BY_EEPROM)
                     EP0BUF[0] = 0;
                  else 
                     EP0BUF[0] = deviceCount-1;
                  EP0BCL = 1;
               }
               else
                  EZUSB_STALL_EP0();   // Stall End Point 0
               break;

            default:                            // *** Invalid Command
                  EZUSB_STALL_EP0();            // Stall End Point 0
   
            } // End Switch
         } // End error checking else
      else if (CSMIntrfcDscrOffset && halfKBuffer[CSMIntrfcDscrOffset+2] == wIndex)
         {
         switch(SETUPDAT[1])
            {
            case SC_GET_CHANNEL_SETTINGS:
               EP0BUF[0] = 1;
               EP0BCL = 1;
               break;
            case SC_SET_CHANNEL_SETTINGS:
               break;
            case SC_GET_UNIQUE_ID:
               mymemmovexxISR(EP0BUF, CSMSerial, IDE_ID_SERIAL_LEN);
               EP0BCL = min(wLength, IDE_ID_SERIAL_LEN);
               break;
            case GD_CS_GENERAL_DESCRIPTOR:
               sendDescriptor(CSMIntrfcDscrOffset+ (BYTE) &CSMGeneralDscrOffset);
               break;
            default:
               EZUSB_STALL_EP0();            // Stall End Point 0
               break;
            }

         }
      else
         {
         switch(SETUPDAT[1])
            {
            case SC_HID_SET_REPORT:
               EP0BCH = 0;
               EP0BCL = 0; // Clear bytecount to allow new data in; also stops NAKing
      
               while(EP0CS & bmEPBUSY); // wait for the report
      
               report[0] = EP0BUF[0];
               report[1] = EP0BUF[1];
               
               receivedReport_Flag = TRUE;
   
               break;
   
            case SC_HID_SET_IDLE:
               break;
   
            default:
               EZUSB_STALL_EP0();            // Stall End Point 0
               break;
            }
         }

   } // end elseif
   else if ((setupdat0 & SETUP_MASK) == SETUP_VENDOR_REQUEST)
   {  
      // bRequest
      switch(SETUPDAT[1])
      {
         // Load (write) config data
         case 0x01:
            if (wValue == 0 || wValue == 2)     // 0 = Write config bytes, 2 = Write EEPROM AND config bytes
               {
               EP0BCH = 0;
               EP0BCL = 0; // Clear bytecount to allow new data in; also stops NAKing

               while(EP0CS & bmEPBUSY)
                  ;

               if (wIndex < sizeof(MX2_CONFIG_DATA))
                  mymemmovexxISR((BYTE xdata *) &mx2_config_data + wIndex, EP0BUF, min(sizeof(MX2_CONFIG_DATA)-wIndex, wLength));
               if (wIndex + wLength >= sizeof(MX2_CONFIG_DATA))
                  mymemmovexxISR(halfKBuffer, EP0BUF, EP0BCL-max(0,sizeof(MX2_CONFIG_DATA)-wIndex));

               if (wValue == 2)     // Write EEPROM too
                  {      
                  for (i = 0; i <  EP0BCL; i+= EEPROM_PAGE_SIZE)
                     {
                     EEPROMWriteBlock(wIndex+i+CONFIG_SPACE_START, EP0BUF+i, min(EEPROM_PAGE_SIZE, EP0BCL-i));
                     }
                  }

               wLength -= EP0BCL;
               wIndex += EP0BCL;
               EP0BCL = 0;
               while (wLength)
                  {
                  while(EP0CS & bmEPBUSY)
                     ;
                  mymemmovexxISR(halfKBuffer + wIndex - sizeof(MX2_CONFIG_DATA), EP0BUF, EP0BCL);
                  if (wValue == 2)     // Write EEPROM too
                     {      
                     for (i = 0; i <  EP0BCL; i+= EEPROM_PAGE_SIZE)
                        {
                        EEPROMWriteBlock(wIndex+i+CONFIG_SPACE_START, EP0BUF+i, EEPROM_PAGE_SIZE);
                        }
                     }
                  wLength -= EP0BCL;
                  wIndex += EP0BCL;
                  EP0BCL = 0;
                  }

               IOEShadow = (mx2_config_data.GpioData << 2) | (IOEShadow & 3);    
               IOE = IOEShadow;
               OEE = mx2_config_data.GpioOE << 2 | (OEE & 3);
               checkGPIOonPA3();
               }
            break;
         // Read config data
         case 0x02:
               if (wValue == 2)     // Read EEPROM 
                  {      
                  while (wLength)
                     {
                     while(EP0CS & bmEPBUSY)
                        ;
   
                     EEPROMRead(wIndex+CONFIG_SPACE_START, 64, (BYTE xdata *) EP0BUF);
                     EP0BCL = min(64, wLength);
                     wLength -= min(64, wLength);
                     wIndex += 64;
                     }
                  }
               else
                  {
                  if (wIndex < sizeof(MX2_CONFIG_DATA))
                     mymemmovexxISR(EP0BUF, (BYTE xdata *) &mx2_config_data + wIndex, min(sizeof(MX2_CONFIG_DATA)-wIndex, wLength));
                  if (wIndex >= sizeof(MX2_CONFIG_DATA))
                     mymemmovexxISR(EP0BUF, halfKBuffer + wIndex, min(64, wLength));
                  else // transfer is split between the two sections
                      mymemmovexxISR(EP0BUF + max(sizeof(MX2_CONFIG_DATA)-wIndex, 0), 
                        halfKBuffer, 
                        64-max(0,sizeof(MX2_CONFIG_DATA)-wIndex));
                  EP0BCL = min(64, wLength);
                  wLength -= min(64, wLength);
                  wIndex += 64;
                  while (wLength)
                     {
                     while(EP0CS & bmEPBUSY)
                        ;
                     mymemmovexxISR(EP0BUF, halfKBuffer + wIndex - sizeof(MX2_CONFIG_DATA),  min(64, wLength));
                     EP0BCL = min(64, wLength);
                     wLength -= min(64, wLength);
                     wIndex += 64;
                     }
                  }
            break;
         default:
            EZUSB_STALL_EP0();            // Stall End Point 0
            break;
      }
   }
   else
       EZUSB_STALL_EP0();            // Stall End Point 0

   // Acknowledge handshake phase of device request
   EP0CS |= bmHSNAK;
}

// Wake-up interrupt handler
void resume_isr(void) interrupt WKUP_VECT
{
   EZUSB_CLEAR_RSMIRQ();
}


// Send descriptor without using autopointer.  The autopointer gets confused in several 
// situations, one of which is a host request len > 0x2000.
//
// This routine also allows the descriptors to be shared between full and high speed by
// changing the endpoint sizes of EP2 and EP6 on the fly.  
// 
void sendDescriptor(BYTE offset)
{
   BYTE len, j;

   if (SETUPDAT[3] == GD_CONFIGURATION || SETUPDAT[3] == GD_OTHER_SPEED_CONFIGURATION)
      len = halfKBuffer[offset + 2];
   else
      len = halfKBuffer[offset];


   AUTOPTR1H = MSB(halfKBuffer);
   AUTOPTR1L = offset;

   if (!SETUPDAT[7])
      len = min(len, SETUPDAT[6]);

   while (len)
      {
      for(j=0;j<64;j++)
         {
         EP0BUF[j]=XAUTODAT1;
         }
   
      EP0BCL = j = min(len, 64);
      len -= j;

      // Wait for the data to go out before we use the buffer again!
      while(EP0CS & bmEPBUSY)
         j=1;  // This line was inserted to work around a bug in the Keil v7.10 compiler optimization.
      }
}

// Add a GPIO on PA3 in 56 pin package with new pinout when we're not bus powered
// Note that this routine DOES NOT exist in AT2LP
void checkGPIOonPA3()
{
    if (!bBIG_PACKAGE && !VBUS_POWERED && bNewAt2pinout)
      {
      if (mx2_config_data.GpioOE & 0x80 )
          OEA |=  1 << 3;
      else
          OEA &=  ~(1 << 3);
      PA3 = (mx2_config_data.GpioData & 0x80) >> 7;
      }
}

⌨️ 快捷键说明

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