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

📄 ctrlrequest.c

📁 增强型51单片机fs7821cf卡读写程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
**********************************************************************************************
* Project:	TK7821
* File:		CtrlRequest.c
* Contents: 
*           
*
* $Date: 02/25/05    Jason    v0.1
*        04/21/05    Mingo    v0.2   www.fameg.com
*
* Copyright (c) 2005 Fameg, Inc. All rights reserved
***********************************************************************************************
*/

#include <reg51.h>
#include <stdio.h>
#include <string.h>
#include "sotatype.h"
#include "usbdisk.h"
#include "device.h"
#include "CtrlRequest.h"
#include "ScsiCmd.h"

void InitBulkPipe();

/*************************************************
   Global Variables
*************************************************/
BYTE xdata UsbBuf[USB_BUFFER_SIZE];
xdata PSOTA_USB_REQUEST pSotaUsbRequest;
xdata BYTE CtrlPktSize;

/*************************************************
   Local Variables
*************************************************/
static xdata SOTA_USB_REQUEST SotaUsbRequest;
static xdata BYTE UsbAddr = 0;
static xdata BYTE TestModeParam;

/* H/W b1 only support ep0~2 so we add this variable to pass chapter9 */
static bit EP3Halt = 0;

//----------------------------------------------------------------------------
// EP Index to Register Offset 
//  Note: Return value 0xff = Invalid EP Index
//                     0x00 = EP0 
//----------------------------------------------------------------------------
BYTE CtrlEPIndex2RegOffset(BYTE Index)
{
  BYTE Offset = 0xff;
    
  if ( (Index == 0) || (Index==0x80) )
    Offset = 0;  
  switch(Index)  
  {
    case EP1IN_NUMBER:
         Offset = EP1_TXCSR;
         break;	
 
    case EP2OUT_NUMBER:
         Offset = EP2_RXCSR;  
         break;   
 
    default:
         break;  
  }    
  return Offset;       
}  

//----------------------------------------------------------------------------
// Clear Halt Feature
//----------------------------------------------------------------------------
void CtrlClearHaltFeature()
{
  // EP0
  pSotaUsbRequest->HaltStatus = false;  
  // EP1
  ClearRegBit(USB_BASE + EP1_TXCSR, ~EN_TX1_STL);
  // EP2
  ClearRegBit(USB_BASE + EP2_RXCSR, BulkStallMask);
}  

//----------------------------------------------------------------------------
// Prepare status report data
//   Note: Unexpected condition, return false
//----------------------------------------------------------------------------
bool CtrlStatusReport(BYTE Recipient, BYTE Index, PBYTE Data)
{
  bit Rc = true;
  Data[1] = 0; // Reserved  
  
  switch(Recipient)
  {
    case 0x80:    // Device
    case 0x81:    // Interface
         Data[0] = 0;
         break;
         
    case 0x82:    // Endpoint
         {
           BYTE Offset = CtrlEPIndex2RegOffset(Index); 
           Data[0] = 0;
           
           if (Offset != 0xff)
           {
             if (Offset)
             {
               if (CSRRead(USB_BASE + Offset) &  0x02) 
                 Data[0] = 0x01;
             } 
             else
             { 
               if (pSotaUsbRequest->HaltStatus)
                 Data[0] = 0x01; 
             }    
           }
           break;
        }   
         
    default:
         Rc = false;
         break;          
  }  

  return Rc; 
}  

//----------------------------------------------------------------------------
// Get Status Request 
//----------------------------------------------------------------------------
void CtrlReqGetStatus()
{
  BYTE Token = pSotaUsbRequest->Token;
      
  switch(Token)
  {
    case SETUP_TOKEN:
         pSotaUsbRequest->LoadInDataOk = true;
         CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0_STL);
         break;

    case IN_TOKEN:
         {
           PUSB_REQUEST pReq = &(pSotaUsbRequest->Request);
           BYTE i;
           BYTE Len = (BYTE)(pReq->wLength);
           BYTE Data[2];
           BYTE Index = ((TDataCast *)&(pReq->wIndex))->ucByte[0];

           BYTE Recipient = pReq->bmRequestType;
           
           if (pSotaUsbRequest->LoadInDataOk)
           {
             if (Len > 2)
               Len = 2;
             if (!CtrlStatusReport(Recipient, Index, Data))  
               Len = 0;                  
             CSRWrite(USB_BASE + EP0_TXCNT, Len);
             for (i = 0; i < Len; i++)
               CSRWrite(USB_BASE + EP0_TXDATA, Data[i]);
             CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0);    
             pSotaUsbRequest->LoadInDataOk = false;
           }  
           CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0);    
           break;   
         }

    case IN_OK_TOKEN:
         CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0);    
         CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0_STL); 
         break;

    case OUT_TOKEN:
    default:
         // Ctrl Read End
         pSotaUsbRequest->InProgress = false;
         break;          
  }  
}

//--------------------------------------------------------------------
// Clear Feature Request
//--------------------------------------------------------------------
static bit FeatureCleared = 0;

void ClrFeatureEP()
{
    PUSB_REQUEST pReq = &(pSotaUsbRequest->Request);
    BYTE RegValue;
    BYTE wValue = (BYTE)ConvertEndian16(pReq->wValue);
    bit ReqAccept = true;
    bit ClrEP0 = false;
    bit ClrEP1 = false;
    bit ClrEP2 = false;
                                            
    if(wValue == ENDPOINT_HALT)
    {
        if((pReq->bmRequestType == 0x00)|| // Recipient = Device
           (pReq->bmRequestType == 0x01) ) // Recipient = Interface
        {
            RegValue = CSRRead(USB_BASE + EP0_RXCSR);
            if(RegValue & EN_RX0_STL)
                ClrEP0 = true;

            RegValue = CSRRead(USB_BASE + EP0_TXCSR);
            if(RegValue & EN_TX0_STL)
                ClrEP0 = true;

            RegValue = CSRRead(USB_BASE + EP1_TXCSR);
            if(RegValue & EN_TX1_STL)
                ClrEP1 = true;

            RegValue = CSRRead(USB_BASE + EP2_RXCSR);
            if(RegValue & EN_RX2_STL)
                ClrEP2 = true;
        }
        else if(pReq->bmRequestType == 0x02) // Recipient = EndPoint
        {
            BYTE Index = ((TDataCast *)&(pReq->wIndex))->ucByte[0];

            if((Index == 0)||(Index == 0x80)) // Clear EP0
                ClrEP0 = true;

            else if(Index == EP1IN_NUMBER)
                ClrEP1 = true;

            else if(Index == EP2OUT_NUMBER)
                ClrEP2 = true;

            else
                ReqAccept = false;
        }
        else
            ReqAccept = false;

        // Clear Endpoint Toggle Feature 
        RegValue = CSRRead(USB_BASE + EPCTL);
        if(ClrEP0)  RegValue |= CLR_EP0_TOG;
        if(ClrEP1)  RegValue |= CLR_EP1_TOG;
        if(ClrEP2)  RegValue |= CLR_EP2_TOG;
        CSRWrite(USB_BASE + EPCTL, RegValue);

        if(ClrEP0)
        {
            pSotaUsbRequest->HaltStatus = false;

            RegValue = CSRRead(USB_BASE + EP0_RXCSR); 
            RegValue &= ~EN_RX0_STL; 
            CSRWrite(USB_BASE + EP0_RXCSR, RegValue);

            RegValue = CSRRead(USB_BASE + EP0_TXCSR); 
            RegValue &= ~EN_TX0_STL; 
            CSRWrite(USB_BASE + EP0_TXCSR, RegValue);
        }

        if(ClrEP1 | ClrEP2)
        {
            RegValue = CSRRead(USB_BASE + EP1_TXCSR);
            RegValue &= ~EN_TX1_STL;
            CSRWrite(USB_BASE + EP1_TXCSR, RegValue);

            RegValue = CSRRead(USB_BASE + EP2_RXCSR);
            RegValue &= ~(EN_RX2_STL | EN_RX2);
            CSRWrite(USB_BASE + EP2_RXCSR, RegValue);
        }

        FeatureCleared = 1;
    }
    
    if(ReqAccept)
    {
        CSRWrite(USB_BASE + EP0_TXCNT, 0);
        CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0);
    }
    else
        CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0_STL);
}

void BulkReportHandle();

void CtrlReqClearFeature()
{
    BYTE Token = pSotaUsbRequest->Token;
    
    switch(Token)
    {
        case SETUP_TOKEN:
            FeatureCleared = 0;
            CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0_STL);
            break;
                  
        case IN_TOKEN:
            ClrFeatureEP();
            break;
        
        case OUT_TOKEN:
        case IN_OK_TOKEN:
        default:
            pSotaUsbRequest->InProgress = false;
            if(FeatureCleared)
            {
                if(ScsiCmdSTALLed)
                {
                    BulkReportHandle();
                    ScsiCmdSTALLed = false;
                }
            }
            break;
    }
}

//----------------------------------------------------------------------------
// Set USB Test Mode.
//----------------------------------------------------------------------------
void CtrlSetTestMode(BYTE TestItem)
{
  BYTE TestModeReg;

  if ((((UINT32)HwId() << 16) | HwVersion()) >= 0x60340100)
    TestModeReg = USB_TEST_MODE1;
  else
    TestModeReg = USB_TEST_MODE0;

  switch (TestItem)
  {
     case TEST_J:
          CSRWrite(USB_BASE + TestModeReg, SET_TM_J);
          break; 
                     
     case TEST_K:
          CSRWrite(USB_BASE + TestModeReg, SET_TM_K);
          break; 
                     
     case TEST_SE0_NAK:
          CSRWrite(USB_BASE + TestModeReg, SET_TM_SE0_NAK);
          break; 
                     
     case TEST_PACKET:
          while (true)
          {
            BYTE i;

            CSRWrite(USB_BASE + TestModeReg, SET_TM_PKT);
            for (i = 0; i < 120; i++); // Delay about 111us under 11MHz
            CSRWrite(USB_BASE + TestModeReg, 0);
          }
          break; 
                     
     case TEST_FORCE_ENABLE:
          // Not Support.                     
     default:
          TestModeParam = NO_TEST_PARAM;       
          break;
  }  	
}		

//----------------------------------------------------------------------------
// Check USB Test Mode Parameters.
//----------------------------------------------------------------------------
bool CtrlChkTestMode(PUSB_REQUEST pReq, PBYTE Param)
{
  bit Rc = false;
  	
  if (pReq->bmRequestType == 0)
  {
    if (((TDataCast *)&(pReq->wIndex))->ucByte[0] == 0)
    {
      if (pReq->wLength == 0)
      {
        *Param = (BYTE)(pReq->wIndex);
        Rc = true;		
      }  
    }  
  }  	
               
  return Rc;           
}

//----------------------------------------------------------------------------
// Set Feature Request,Only Support EP0 ~ EP3. 
//----------------------------------------------------------------------------
void CtrlReqSetFeature()
{
  BYTE Token = pSotaUsbRequest->Token;
    
  switch(Token)
  {
    case SETUP_TOKEN:
           CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0_STL);    
           TestModeParam = NO_TEST_PARAM;
           break;
                  
    case IN_TOKEN:
         {
           PUSB_REQUEST pReq = &(pSotaUsbRequest->Request);
           bit ReqAccept = false;
           BYTE Value = (BYTE)ConvertEndian16(pReq->wValue);
                                            
           if (ENDPOINT_HALT == Value)
           {
             if (pReq->bmRequestType == 0x02)
             {
               BYTE Index = ((TDataCast *)&(pReq->wIndex))->ucByte[0];
               BYTE Offset = CtrlEPIndex2RegOffset(Index);
                              
               if (Offset == 0xff)               
                 ReqAccept = false;    
               else
               {
               	 ReqAccept = true;
                 if (Offset)
                   CSRWrite(USB_BASE + Offset, 0x02);
                 else                                 // Set EP0                
                   pSotaUsbRequest->HaltStatus = true;                              
               }   
             }
           }
           if (TEST_MODE == Value)
             ReqAccept = CtrlChkTestMode(pReq, &TestModeParam);
                      	
           if (DEVICE_REMOTE_WAKEUP == Value) 
           {
             // Not Support Yet!
             ReqAccept = true;		
           }	
           
           if (ReqAccept)
           {
             CSRWrite(USB_BASE + EP0_TXCNT, 0);
             CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0);    
           }  
           else
             CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0_STL);    
           break;
         }  
 
    case IN_OK_TOKEN:
         CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0);    
         CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0_STL); 
       

⌨️ 快捷键说明

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