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

📄 massstorage.c

📁 cortex-m0 LCD1602程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* Copyright (c) Nuvoton Technology Corp. All rights reserved.                                             */
/*                                                                                                         */
/*---------------------------------------------------------------------------------------------------------*/

#include <string.h>
#include "Driver\DrvUSB.h"
#include "USB\UDC.h"

#define VENDER_CMD  0x61

//#define TEST_DATA_FLASH

#define DATA_FLASH_STORAGE_SIZE    (64*1024)  /* Configure the DATA FLASH storage size */
#define MASS_BUFFER_SIZE    48                /* Mass Storage command buffer size */
#define STORAGE_BUFFER_SIZE 512               /* Data transfer buffer size in 512 bytes alignment */
#define UDC_SECTOR_SIZE   512               /* logic sector size */

#define VENDOR_ID   0x0416
#define PRODUCT_ID  0x501E

int32_t gTotalSectors = 0;
int32_t g_dataFlashTotalSectors = 0;

uint8_t volatile MassLUN=0;
uint8_t volatile F_DATA_FLASH_LUN = 0xFF;

/* DATA Flash Programming API */
extern void DataFlashRead(uint32_t addr, uint32_t size, uint32_t buffer);
extern void DataFlashWrite(uint32_t addr, uint32_t size, uint32_t buffer);

/* USB flow control variables */
uint8_t g_u8UsbState;
uint8_t g_u8Address;
uint8_t g_u8Config;
uint8_t g_u8Flag;
uint8_t g_u8BulkState;

uint8_t g_au8SenseKey[4];

uint32_t g_u32DataFlashStartAddr;
uint32_t g_u32Address;
uint32_t g_u32Length;
uint32_t g_u32LbaAddress;
uint32_t g_u32BytesInStorageBuf;
uint32_t g_u32OutToggle;  // for Error Detection
uint8_t preventflag=0;
uint8_t g_u8Size;
int32_t g_bCBWInvalid;
int32_t udcOnLine = 0;

/* CBW/CSW variables */
struct CBW g_sCBW;
struct CSW g_sCSW;

uint32_t MassBlock[MASS_BUFFER_SIZE / 4];
uint32_t Storage_Block[STORAGE_BUFFER_SIZE / 4];

#define MassCMD_BUF        ((uint32_t)&MassBlock[0])
#define STORAGE_DATA_BUF   ((uint32_t)&Storage_Block[0])

// code = 5Ah, Mode Sense
static uint8_t ModePage_01[12] = {
  0x01, 0x0A, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
  0x03, 0x00, 0x00, 0x00 };

static uint8_t ModePage_05[32] = {
  0x05, 0x1E, 0x13, 0x88, 0x08, 0x20, 0x02, 0x00,
  0x01, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x05, 0x1E, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00 };

static uint8_t ModePage_1B[12] = {
  0x1B, 0x0A, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00 };

static uint8_t ModePage_1C[8] = {
  0x1C, 0x06, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00 };

//======================================================
const uint8_t MassDeviceDescriptor[LEN_DEVICE] =
{
  LEN_DEVICE,       // bLength
  DESC_DEVICE,      // bDescriptorType
  0x10, 0x01,       // bcdUSB
  0x00,         // bDeviceClass
  0x00,         // bDeviceSubClass
  0x00,         // bDeviceProtocol
  MAX_PACKET_SIZE0, // bMaxPacketSize0
  (VENDOR_ID & 0xFF), 
  (VENDOR_ID >> 8),   // idVendor
  (PRODUCT_ID & 0xFF), 
  (PRODUCT_ID >> 8),  // idProduct
  0x00, 0x00,       // bcdDevice
  0x01,         // iManufacture
  0x02,         // iProduct
  0x01,         // iSerialNumber
  0x01          // bNumConfigurations
};

const uint8_t MassConfigurationBlock[LEN_CONFIG+LEN_INTERFACE+LEN_ENDPOINT*2] =
{
  LEN_CONFIG,                                         // bLength
  DESC_CONFIG,                                        // bDescriptorType
  (LEN_CONFIG+LEN_INTERFACE+LEN_ENDPOINT*2), 0x00,    // wTotalLength
  0x01,                                               // bNumInterfaces
  0x01,                                               // bConfigurationValue
  0x00,                                               // iConfiguration
  0xC0,                                               // bmAttributes
  0x32,                                               // MaxPower

/* const BYTE cbyInterfaceDescriptor[LEN_INTERFACE] = */
  LEN_INTERFACE,  // bLength
  DESC_INTERFACE, // bDescriptorType
  0x00,     // bInterfaceNumber
  0x00,     // bAlternateSetting
  0x02,     // bNumEndpoints
  0x08,     // bInterfaceClass
  0x05,     // bInterfaceSubClass
  0x50,     // bInterfaceProtocol
  0x00,     // iInterface

/* const BYTE cbyEndpointDescriptor1[LEN_ENDPOINT] = */
  LEN_ENDPOINT,           // bLength
  DESC_ENDPOINT,          // bDescriptorType
  0x82,                   // bEndpointAddress
  EP_BULK,                // bmAttributes
  MAX_PACKET_SIZE, 0x00,  // wMaxPacketSize
  0x00,                   // bInterval

/* const BYTE cbyEndpointDescriptor2[LEN_ENDPOINT] = */
  LEN_ENDPOINT,           // bLength
  DESC_ENDPOINT,          // bDescriptorType
  0x03,                   // bEndpointAddress
  EP_BULK,                // bmAttributes
  MAX_PACKET_SIZE, 0x00,  // wMaxPacketSize
  0x00                    // bInterval
};

const uint8_t MassStringDescriptor0[4] =
{
  4,            // bLength
  DESC_STRING,  // bDescriptorType
  0x09, 0x04
};

const uint8_t MassStringDescriptor1[16] =
{
  16,           // bLength
  DESC_STRING,  // bDescriptorType
  'N', 0, 'u', 0, 'v', 0, 'o', 0, 't', 0, 'o', 0, 'n', 0
};

const uint8_t InquiryID[36] = 
{
  0x00,         // Peripheral Device Type
  0x80,         // RMB
  0x00,         // ISO/ECMA, ANSI Version
  0x00,         // Response Data Format
  0x1F, 0x00, 0x00, 0x00, // Additional Length

  /* Vendor Identification */
  'N', 'u', 'v', 'o', 't', 'o', 'n', ' ',

  /* Product Identification */
  '1', '0', '0', ' ', 'M', 'a', 's', 's', ' ', 'S', 't', 'o', 'r', 'a', 'g', 'e',

  /* Product Revision */
  '1', '.', '0', '0'
};


static __INLINE uint32_t get_be32(uint8_t *buf)
{
  return ((uint32_t) buf[0] << 24) | ((uint32_t) buf[1] << 16) |
      ((uint32_t) buf[2] << 8) | ((uint32_t) buf[3]);
}

void RoughDelay(uint32_t t)
{
    volatile int32_t delay;

    delay = t;

    while(delay-- >= 0);
}

void my_memcpy(void *dest, void *src, int32_t size)
{
    int32_t i;

    for (i = 0; i < size; i++)
       *((uint8_t *)dest + i) = *((uint8_t *)src + i);
}


void ModeSenseCommand(void)
{
  uint8_t i,j;
  uint8_t NumHead,NumSector;
  uint16_t NumCyl;

    /* Clear the command buffer */
    *((uint32_t *)MassCMD_BUF  ) = 0;
    *((uint32_t *)MassCMD_BUF+1) = 0;

  switch (g_sCBW.au8Data[0])
  {
    case 0x01:
    {
      outpb(MassCMD_BUF, 19);
      i = 8;
      for (j = 0; j<12; j++, i++)
        outpb(MassCMD_BUF+i, ModePage_01[j]);
      break;
    }
    case 0x05:
    {
      outpb(MassCMD_BUF, 39);
      i = 8;
      for (j = 0; j<32; j++, i++)
        outpb(MassCMD_BUF+i, ModePage_05[j]);
      
      NumHead = 2;
      NumSector = 64;

      if (g_sCBW.bCBWLUN==F_DATA_FLASH_LUN)
        NumCyl = g_dataFlashTotalSectors/128;

      outpb(MassCMD_BUF+12, NumHead);
      outpb(MassCMD_BUF+13, NumSector);
      outpb(MassCMD_BUF+16, (uint8_t)(NumCyl >> 8));
      outpb(MassCMD_BUF+17, (uint8_t)(NumCyl & 0x00ff));
      break;
    }
    case 0x1B:
    {
      outpb(MassCMD_BUF, 19);
      i = 8;
      for (j = 0; j<12; j++, i++)
        outpb(MassCMD_BUF+i, ModePage_1B[j]);
      break;
    }
    case 0x1C:
    {
      outpb(MassCMD_BUF, 15);
      i = 8;
      for (j = 0; j<8; j++, i++)
        outpb(MassCMD_BUF+i, ModePage_1C[j]);
      break;
    }
    case 0x3F:
    {
      outpb(MassCMD_BUF, 0x47);
      i = 8;
      for (j = 0; j<12; j++, i++)
        outpb(MassCMD_BUF+i, ModePage_01[j]);
      for (j = 0; j<32; j++, i++)
        outpb(MassCMD_BUF+i, ModePage_05[j]);
      for (j = 0; j<12; j++, i++)
        outpb(MassCMD_BUF+i, ModePage_1B[j]);
      for (j = 0; j<8; j++, i++)
        outpb(MassCMD_BUF+i, ModePage_1C[j]);
      
      NumHead = 2;
      NumSector = 64;

      if (g_sCBW.bCBWLUN==F_DATA_FLASH_LUN)
        NumCyl = g_dataFlashTotalSectors/128;

      outpb(MassCMD_BUF+24, NumHead);
      outpb(MassCMD_BUF+25, NumSector);
      outpb(MassCMD_BUF+28, (uint8_t)(NumCyl >> 8));
      outpb(MassCMD_BUF+29, (uint8_t)(NumCyl & 0x00ff));
      break;
    }
    default:
      g_au8SenseKey[0] = 0x05;
      g_au8SenseKey[1] = 0x24;
      g_au8SenseKey[2] = 0x00;
  }
}


void ReqSenCommand(void)
{
    uint8_t tmp[20];
    
    if (preventflag==1)
    {
        preventflag=0;
    tmp[0] = 0x70;
    }
    else
    tmp[0] = 0xf0;

  tmp[1] = 0;
  tmp[3] = 0;
  tmp[4] = 0;
  tmp[5] = 0;
  tmp[6] = 0;
  tmp[7] = 0x0A;
  tmp[8] = 0;
  tmp[9] = 0;
  tmp[10] = 0;
  tmp[11] = 0;
  tmp[14] = 0;
  tmp[15] = 0;
  tmp[16] = 0;
  tmp[17] = 0;

  tmp[2] = g_au8SenseKey[0];
  tmp[12] = g_au8SenseKey[1];
  tmp[13] = g_au8SenseKey[2];

    my_memcpy(g_au8UsbBulk1, tmp, 20);
  
  // Sense Key
  g_au8SenseKey[0] = 0x00;
  g_au8SenseKey[1] = 0x00;
  g_au8SenseKey[2] = 0x00;
}


void RdFmtCapCommand(void)
{
    uint32_t i;
    uint32_t TotalSectors = 0;

  for (i = 0; i < 36; i++)
    outpb(MassCMD_BUF+i, 0);

  outpb(MassCMD_BUF+3, 0x10);

    if (g_sCBW.bCBWLUN==F_DATA_FLASH_LUN)
    TotalSectors = g_dataFlashTotalSectors;

  outpb(MassCMD_BUF+4, *((uint8_t *)&TotalSectors+3));
  outpb(MassCMD_BUF+5, *((uint8_t *)&TotalSectors+2));
  outpb(MassCMD_BUF+6, *((uint8_t *)&TotalSectors+1));
  outpb(MassCMD_BUF+7, *((uint8_t *)&TotalSectors+0));
  outpb(MassCMD_BUF+8, 0x02);
  outpb(MassCMD_BUF+10, 0x02);
  outpb(MassCMD_BUF+12, *((uint8_t *)&TotalSectors+3));
  outpb(MassCMD_BUF+13, *((uint8_t *)&TotalSectors+2));
  outpb(MassCMD_BUF+14, *((uint8_t *)&TotalSectors+3));
  outpb(MassCMD_BUF+15, *((uint8_t *)&TotalSectors+0));
  outpb(MassCMD_BUF+18, 0x02);
}


void RdCurCapCommand(void)
{
    int i;
    uint32_t temp;

  for (i = 0; i < 36; i++)
    outpb(MassCMD_BUF+i, 0);

    if (g_sCBW.bCBWLUN==F_DATA_FLASH_LUN)
        temp = g_dataFlashTotalSectors - 1;

  outpb(MassCMD_BUF+0, *((uint8_t *)&temp+3));
  outpb(MassCMD_BUF+1, *((uint8_t *)&temp+2));
  outpb(MassCMD_BUF+2, *((uint8_t *)&temp+1));
  outpb(MassCMD_BUF+3, *((uint8_t *)&temp+0));
  outpb(MassCMD_BUF+6, 0x02);
}


//======================================================
// USB Configuration
//======================================================
void UsbCfg(void)
{
    /* Init the USB device address to 0x0 */
    _DRVUSB_SET_FADDR(0x00);

    /* Init control end point */
    USBD->STBUFSEG.STBUFSEG = 0x1F;               /* Buffer for setup packet */
    _DRVUSB_SET_CFG_EP0(EPT_CFGP);                /* Clear EP0 CTRL IN Ready Flag */
    _DRVUSB_SET_CFG(0, CFG0_SETTING);             /* EP0 ==> control IN end point, address 0 */
    _DRVUSB_SET_EP_BUF(0, USB_SRAM_BASE + BUF0_SETTING);  /* Buffer for EP0 */
    _DRVUSB_SET_CFG_EP1(EPT_CFGP);                /* Clear EP1 CTRL OUT Ready Flag */
    _DRVUSB_SET_CFG(1, CFG1_SETTING);             /* EP1 ==> control OUT end point, address 0 */
    _DRVUSB_SET_EP_BUF(1, USB_SRAM_BASE + BUF1_SETTING);    /* Buffer for EP1 */
    
    /* Init Bulk IN end point */
    _DRVUSB_SET_CFG_EP2(EPT_CFGP);                /* Clear EP2 BULK IN Ready Flag */
    _DRVUSB_SET_CFG(2, CFG2_SETTING);             /* EP2 ==> Bulk IN end point, address 2 */
    _DRVUSB_SET_EP_BUF(2, USB_SRAM_BASE + BUF_BULK1);     /* Buffer for EP2 (Bulk IN) */  
  
    /* Init Bulk OUT end point */
    _DRVUSB_SET_CFG_EP3(EPT_CFGP);                /* Clear EP3 BULK OUT Ready Flag */
    _DRVUSB_SET_CFG(3, CFG3_SETTING);             /* EP3 ==> Bulk OUT end point, address 3 */
    _DRVUSB_SET_EP_BUF(3, USB_SRAM_BASE + BUF_BULK0);   /* Buffer for EP3 (Bulk OUT) */
  
    g_u8Address = 0;    /* Device address */
    g_u8Config = 0;
    g_u8Flag = 0;       /* Flag to record the USB request */
    
    g_u8BulkState = BULK_CBW;
    g_au8SenseKey[0] = 0;
    g_au8SenseKey[1] = 0;
    g_au8SenseKey[2] = 0;
    g_bCBWInvalid = FALSE;
    
    g_u32Address = 0;
    g_u32Length = 0;
    g_u8Size = 0;
    
    g_sCSW.dCSWSignature = CSW_SIGNATURE;
    
    udcOnLine = 0;
    g_u32OutToggle = 0; // for Error Detection
}

//======================================================
// USB Floating Detect
//======================================================
void UsbFdt(void)
{
    uint8_t u8FLDET = USBD->FLDET.FLDET;

    _DRVUSB_SET_EVENT_FLAG(INTSTS_FLDET);
  
    if (u8FLDET)
    {
        /* USB Plug In */

        if(g_u8UsbState & USB_STATE_ATTACHED)
        {
          /* Do nothing if it is already attached */
          return;
        }
    
        /* Update USB state */
        g_u8UsbState = USB_STATE_ATTACHED;

        /* Init the end points */
        UsbCfg();
    
        /* Enable USB and enable PHY */
        _DRVUSB_ENABLE_USB();
    }
    else
    {
        /* USB Un-plug */
  
        /* Update USB state */
        g_u8UsbState = USB_STATE_DETACHED;
    
        udcOnLine = 0;
    
        /* Disable USB, Disable remote weak up, and disable PHY */
        _DRVUSB_DISABLE_USB();
    }
}


//======================================================
// USB Bus Event
//======================================================
void UsbBus(void)
{
    uint8_t u8ATTR = *((__IO uint32_t *)(&USBD->ATTR)) & 0xFF;
    
    /* Clear event flag */
    _DRVUSB_SET_EVENT_FLAG(INTSTS_BUS);
    
    /* Just return if USB detached. */
    if (g_u8UsbState == USB_STATE_DETACHED)
        return;
  
    /* Process USB bus command if USB is attached. */
    if (u8ATTR & ATTR_USBRST)
    { 
        /* Enable USB and enable PHY */
        _DRVUSB_ENABLE_USB();   
      
        /* Enter default state */
        g_u8UsbState = USB_STATE_DEFAULT;
      
        /* Configure the end-points */
        UsbCfg();
    }
    else if (u8ATTR & ATTR_SUSPEND)
    { 
        /* Enable USB but disable PHY */
        _DRVUSB_DISABLE_PHY();
      
        /* Update the USB state */
        g_u8UsbState |= USB_STATE_FLAG_SUSPENDED;
    }
    else if (u8ATTR & ATTR_RESUME)
    {
        /* Enable USB and enable PHY */
        _DRVUSB_ENABLE_USB();
      
        /* Clear the suspend state */
        g_u8UsbState &= ~USB_STATE_FLAG_SUSPENDED;
    }
}


//======================================================
int32_t UsbStdReq(void)
{
  int volatile len, idx;
    uint8_t tmp[8];
    
    my_memcpy(tmp, g_au8UsbSetup, 8);
    
  /* check if after DEFAULT state (RESET) */
  if ((g_u8UsbState & USB_STATE_FLAG_DEFAULT) == 0x00)
    return FALSE;

  /* parse the request in setup packet */ 
    switch (tmp[1])
  {
    case GET_DESCRIPTOR:
    {
      len = tmp[6] + ((uint32_t)tmp[7] << 8);
            
      switch (tmp[3])
            {

⌨️ 快捷键说明

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