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

📄 massstorage.c

📁 cortex-m0 LCD1602程序
💻 C
📖 第 1 页 / 共 3 页
字号:
        // Get Device Descriptor
        case DESC_DEVICE:
        {
          udcOnLine = 1;

          if (len > LEN_DEVICE)
              len = LEN_DEVICE;

                    my_memcpy(g_au8UsbCtrl, (void *)MassDeviceDescriptor, len);
          break;
        }
        // Get Configuration Descriptor
        case DESC_CONFIG:
        {
          if (len > MassConfigurationBlock[2])
              len = MassConfigurationBlock[2];
          
          my_memcpy(g_au8UsbCtrl, (void *)MassConfigurationBlock, len);                   
                    break;
        }
        // Get String Descriptor
        case DESC_STRING:
        {
          // Get Language
          if(tmp[4] == 0)
                    {
            if(len > MassStringDescriptor0[0])
                len = MassStringDescriptor0[0];
            
            my_memcpy(g_au8UsbCtrl, (void *)MassStringDescriptor0, len);
                        
                        break;
          }
          // Get String Descriptor
          if(len > MassStringDescriptor1[0])
              len = MassStringDescriptor1[0];
                    
          my_memcpy(g_au8UsbCtrl, (void *)MassStringDescriptor1, len);
                    
                    break;
        }
        default:
          return FALSE;
      }
      _DRVUSB_SET_CFG(0, DATA1 (CFG0_SETTING));
      _DRVUSB_TRIG_EP(0, len);
      g_u8Flag = FLAG_OUT_ACK;
      return TRUE;
    }
    case SET_ADDRESS:
    {
        /* Accept set address command only before USB configured */
      if((g_u8UsbState & USB_STATE_FLAG_CONFIGURED) == 0)
      {
        /* Get the device address */
        g_u8Address = tmp[2];
                
        _DRVUSB_SET_CFG(0, DATA1 (CFG0_SETTING));
        _DRVUSB_TRIG_EP(0, 0);
        g_u8Flag = FLAG_SET_ADDRESS;
        return TRUE;
      }
      return FALSE;
    }
    case SET_CONFIGURATION:
    {
      g_u8Config = tmp[2];
            
      _DRVUSB_SET_CFG(0, DATA1 (CFG0_SETTING));
      _DRVUSB_TRIG_EP(0, 0);
      g_u8Flag = FLAG_SET_CONFIG;
      return TRUE;
    }
    case CLEAR_FEATURE:
    case SET_FEATURE:
    {
      if (g_bCBWInvalid)
      {
            /* Invalid CBW */
      }
      else if((tmp[0] == 2) && (tmp[2] == FEATURE_ENDPOINT_HALT))
            {
        uint32_t u32CfgAddr;
                uint8_t  u8Cfg;

                u32CfgAddr = ((tmp[4] & 0xF) << 4) + USBD_CFGP0;
                
        u8Cfg = *((__IO uint32_t *) (u32CfgAddr)) & 0xFF;
        
        if(tmp[1] == CLEAR_FEATURE)
                  u8Cfg &= ~EPT_stall;
        else
          u8Cfg |= EPT_stall;
        *((__IO uint32_t *) (u32CfgAddr)) = u8Cfg;
      }
      else
        return FALSE;
        
      _DRVUSB_SET_CFG(0, DATA1 (CFG0_SETTING));
      _DRVUSB_TRIG_EP(0, 0);
      return TRUE;
    }
    case GET_CONFIGURATION:
    {
      g_au8UsbCtrl[0] = g_u8Config;
            
      _DRVUSB_SET_CFG(0, DATA1(CFG0_SETTING));
      _DRVUSB_TRIG_EP(0, 1);
      g_u8Flag = FLAG_OUT_ACK;
      return TRUE;
    }
    case GET_STATUS:
    {
            uint8_t u8Data;

            u8Data = tmp[0];
      // Device
      if (u8Data == 0x80)
              g_au8UsbCtrl[0] = 1;  // Self-Powered
      
      // Interface
      else if (u8Data == 0x81)
              g_au8UsbCtrl[0] = 0;
      
      // Endpoint
      else if (u8Data == 0x82)
            {
                uint32_t u32CfgAddr;
                u8Data = tmp[4];
                u32CfgAddr = ((u8Data & 0xF) << 4) + USBD_CFGP0;

        g_au8UsbCtrl[0] = (inp32(u32CfgAddr) >> 1) & 1;
      }
      else
        return FALSE;
        
            g_au8UsbCtrl[1] = 0;

      _DRVUSB_SET_CFG(0, DATA1 (CFG0_SETTING));
      _DRVUSB_TRIG_EP(0, 1);
      g_u8Flag = FLAG_OUT_ACK;
      return TRUE;
    }
    case GET_INTERFACE:
    {
      g_au8UsbCtrl[0] = 0;

      _DRVUSB_SET_CFG(0, DATA1(CFG0_SETTING));
      _DRVUSB_TRIG_EP(0, 1);
      g_u8Flag = FLAG_OUT_ACK;
      return TRUE;
    }
    case SET_INTERFACE:
    {
      g_u8Flag = FLAG_SET_INTERFACE;

      _DRVUSB_SET_CFG(0, DATA1(CFG0_SETTING));
      _DRVUSB_TRIG_EP(0, 0);
      return TRUE;
    }
    default:
      return FALSE;
  }
}


//======================================================
int32_t UsbClassReq(void)
{
    uint8_t tmp[8];

    my_memcpy(tmp, g_au8UsbSetup, 8);
    
  if ((tmp[2] != 0) || (tmp[3] != 0) || (tmp[4] != 0) || (tmp[5] != 0))
      return FALSE;

  switch(tmp[1])
    {
    // Bulk-Only Mass Storage Reset
    case BULK_ONLY_MASS_STORAGE_RESET:
    {
      if ((tmp[6] != 0) || (tmp[7] != 0))
              return FALSE;
      g_bCBWInvalid = FALSE;

      _DRVUSB_SET_CFG(0, DATA1 (CFG0_SETTING));
      _DRVUSB_TRIG_EP(0, 0);
      _DRVUSB_SET_CFG(2, DATA0 (CFG2_SETTING));
      
      g_u8BulkState = BULK_CBW;
      _DRVUSB_TRIG_EP(3, 31);
      return TRUE;
    }
    // Get Max LUN
    case GET_MAX_LUN:
    {
            if ((tmp[6] != 1) || (tmp[7] != 0))
        return FALSE;
      g_au8UsbCtrl[0] = MassLUN - 1;
            if (MassLUN != 1)
                while(1);
            
      _DRVUSB_SET_CFG(0, DATA1(CFG0_SETTING));
      _DRVUSB_SET_CFG(3, DATA0(CFG3_SETTING));
      _DRVUSB_TRIG_EP(0, 1);
      
      g_u8Flag = FLAG_OUT_ACK;
      return TRUE;
    }
  }
  return FALSE;
}


//======================================================
int32_t UsbSetup(void)
{
    /* Clear the data IN/OUT ready flag of control end-points */
  _DRVUSB_SET_CFG_EP0(CFGP_CLRRDY); 
  _DRVUSB_SET_CFG_EP1(CFGP_CLRRDY);
  
  /* USB device request in setup packet: offset 0, D[6..5]: 0=Stardard, 1=Class, 2=Vendor, 3=Reserved */
  switch (g_au8UsbSetup[0] & 0x60)
  {
    case REQ_STANDARD:
      return UsbStdReq();
    case REQ_CLASS:
      return UsbClassReq();
    default:
      return FALSE;
  }
}


//======================================================
void UsbInAck(void)
{
  switch (g_u8Flag)
  {
    // Out ACK
    case FLAG_OUT_ACK:
      _DRVUSB_TRIG_EP(1, 0);
      break;
    // Set Address
    case FLAG_SET_ADDRESS:
    {
      if (g_u8Address == 0)
        g_u8UsbState = USB_STATE_DEFAULT;
      else
        g_u8UsbState = USB_STATE_ADDRESS;
      
      _DRVUSB_SET_FADDR(g_u8Address);
      break;
    }
    // Set Interface
    case FLAG_SET_INTERFACE:
    // Set Configuration
    case FLAG_SET_CONFIG:
    {
      if (g_u8Config == 0)
        g_u8UsbState = USB_STATE_ADDRESS;
      else
      {
        g_u8UsbState = USB_STATE_CONFIGURED;
        // ---------------------------------
        _DRVUSB_SET_CFG(2, DATA0 (CFG2_SETTING));
        _DRVUSB_TRIG_EP(3, 31);
        // ---------------------------------
      }
      break;
    }
    // Get Max. LUN
    case FLAG_GET_MAX_LUN:
      _DRVUSB_TRIG_EP(1, 0);
      return;
    default:
      return;
  }
  g_u8Flag = 0;
}

//======================================================
void UsbOutAck(void)
{
  switch (g_u8Flag)
  {
    // Get Max. LUN
    case FLAG_GET_MAX_LUN:
    {
      // ---------------------------------
      _DRVUSB_SET_CFG(2, DATA0 (CFG2_SETTING));
      _DRVUSB_TRIG_EP(3, 31);
      // ---------------------------------
      break;
    }
    default:
      return;
  }
  g_u8Flag = 0;
}


//======================================================
void UsbRead(void)
{
    uint32_t u32Len;
    
  /* DATA0/DATA1 Toggle */
  if (*((__IO uint32_t *)(&USBD->EP[2].BUFSEG)) == BUF_BULK1)
    _DRVUSB_SET_EP_BUF(2, USB_SRAM_BASE + BUF_BULK0);
  else
    _DRVUSB_SET_EP_BUF(2, USB_SRAM_BASE + BUF_BULK1);
    
  /* Trigger to send out the data packet */ 
  _DRVUSB_TRIG_EP(2, g_u8Size);
  
  g_u32Length -= g_u8Size;
  g_u32BytesInStorageBuf -= g_u8Size;

    if (g_u32Length)
    {
        if (g_u32BytesInStorageBuf)
        {
          /* Prepare next data packet */
          g_u8Size = MAX_PACKET_SIZE;
          if (g_u8Size > g_u32Length)
              g_u8Size = g_u32Length;

          if (*((__IO uint32_t *)(&USBD->EP[2].BUFSEG)) == BUF_BULK1)
          {
            my_memcpy(g_au8UsbBulk0, (int8_t *)g_u32Address, g_u8Size);
          }
          else
          {
            my_memcpy(g_au8UsbBulk1, (int8_t *)g_u32Address, g_u8Size);
          }
          g_u32Address += g_u8Size;
      }
      else
      {
        u32Len = g_u32Length;
        if (u32Len > STORAGE_BUFFER_SIZE)
            u32Len = STORAGE_BUFFER_SIZE;
        
      DataFlashRead(g_u32LbaAddress, u32Len, (uint32_t)STORAGE_DATA_BUF);
        g_u32BytesInStorageBuf = u32Len;
        g_u32LbaAddress += u32Len;
            g_u32Address = STORAGE_DATA_BUF;        
        
          /* Prepare next data packet */
          g_u8Size = MAX_PACKET_SIZE;
          if (g_u8Size > g_u32Length)
              g_u8Size = g_u32Length;

          if (*((__IO uint32_t *)(&USBD->EP[2].BUFSEG)) == BUF_BULK1)
          {
            my_memcpy(g_au8UsbBulk0, (int8_t *)g_u32Address, g_u8Size);
          }
          else
          {
            my_memcpy(g_au8UsbBulk1, (int8_t *)g_u32Address, g_u8Size);
          }
          g_u32Address += g_u8Size;       
      }
  }
}


void UsbReadTrig(void)
{
    uint32_t u32Len;
    
    if (g_u32Length)
    {
        if (g_u32BytesInStorageBuf)
        {
          /* Prepare next data packet */
          g_u8Size = MAX_PACKET_SIZE;
          if (g_u8Size > g_u32Length)
              g_u8Size = g_u32Length;

          if (*((__IO uint32_t *)(&USBD->EP[2].BUFSEG)) == BUF_BULK1)
          {
            my_memcpy(g_au8UsbBulk0, (int8_t *)g_u32Address, g_u8Size);
          }
          else
          {
            my_memcpy(g_au8UsbBulk1, (int8_t *)g_u32Address, g_u8Size);
          }
          g_u32Address += g_u8Size;
      }
      else
      {
        u32Len = g_u32Length;
        if (u32Len > STORAGE_BUFFER_SIZE)
            u32Len = STORAGE_BUFFER_SIZE;
        
      DataFlashRead(g_u32LbaAddress, u32Len, (uint32_t)STORAGE_DATA_BUF);
        g_u32BytesInStorageBuf = u32Len;
        g_u32LbaAddress += u32Len;
            g_u32Address = STORAGE_DATA_BUF;        
        
          /* Prepare next data packet */
          g_u8Size = MAX_PACKET_SIZE;
          if (g_u8Size > g_u32Length)
              g_u8Size = g_u32Length;

          if (*((__IO uint32_t *)(&USBD->EP[2].BUFSEG)) == BUF_BULK1)
          {
            my_memcpy(g_au8UsbBulk0, (int8_t *)g_u32Address, g_u8Size);
          }
          else
          {
            my_memcpy(g_au8UsbBulk1, (int8_t *)g_u32Address, g_u8Size);
          }
          g_u32Address += g_u8Size;       
      }
  
    /* DATA0/DATA1 Toggle */
    if (*((__IO uint32_t *)(&USBD->EP[2].BUFSEG)) == BUF_BULK1)
      _DRVUSB_SET_EP_BUF(2, USB_SRAM_BASE + BUF_BULK0);
    else
      _DRVUSB_SET_EP_BUF(2, USB_SRAM_BASE + BUF_BULK1);
    
    /* Trigger to send out the data packet */ 
    _DRVUSB_TRIG_EP(2, g_u8Size);
  
    g_u32Length -= g_u8Size;
    g_u32BytesInStorageBuf -= g_u8Size;

  }
  else
    _DRVUSB_TRIG_EP(2, 0);  
}


//======================================================
void UsbBulkInAck(void)
{
  int32_t volatile idx;

  if (g_u8BulkState == BULK_CSW)
  {
      /* Prepare to receive the CBW */
    g_u8BulkState = BULK_CBW;

    _DRVUSB_SET_EP_BUF(3, USB_SRAM_BASE + BUF_BULK0);
    _DRVUSB_TRIG_EP(3, 31);
  }
  else if (g_u8BulkState == BULK_IN)
  {
    switch (g_sCBW.u8OPCode)
    {
      case UFI_READ_FORMAT_CAPACITY:
      case UFI_READ_CAPACITY:
      case UFI_MODE_SENSE_10:
      //case UFI_READ_10:
      {
        if (g_u32Length > 0)
        {
          UsbRead();
          return;
        }
      }
      case UFI_READ_10:
      {
        if (g_u32Length > 0)
        {
          //UsbRead();
          UsbReadTrig();
          return;
        }     
      }
      
      case UFI_REQUEST_SENSE:
      case UFI_INQUIRY:
      {
        g_sCSW.dCSWDataResidue = 0;
        g_sCSW.bCSWStatus = 0;
        break;
      }

      case UFI_PREVENT_ALLOW_MEDIUM_REMOVAL:
      case UFI_VERIFY_10:
      case UFI_START_STOP:
      case UFI_WRITE_10:
      case VENDER_CMD:
      {
        int32_t tmp;
        
        tmp = g_sCBW.dCBWDataTransferLength - STORAGE_BUFFER_SIZE;
        if (tmp < 0) 
          tmp = 0;
        
        g_sCSW.dCSWDataResidue = tmp;
        g_sCSW.bCSWStatus = 0;
        break;
      }
      case UFI_TEST_UNIT_READY:
      {
        g_sCSW.dCSWDataResidue = 0;
        g_sCSW.bCSWStatus = 0;
        break;
      }
      default:
      {
          /* Unsupported commmand. Return command fail status */
        g_sCSW.dCSWDataResidue = g_sCBW.dCBWDataTransferLength;
        g_sCSW.bCSWStatus = 0x01;
        break;
      }
    }
    
    /* Return the CSW */
    _DRVUSB_SET_EP_BUF(2, USB_SRAM_BASE + BUF_BULK1);

        my_memcpy(g_au8UsbBulk1, &g_sCSW.dCSWSignature, 16);

    g_u8BulkState = BULK_CSW;
    _DRVUSB_TRIG_EP(2, 13);
  }
}

//======================================================
void UsbWrite(void)
{
  uint32_t lba, len;

⌨️ 快捷键说明

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