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

📄 usb_driver.c

📁 M68HC08 及HCS08系列单片机bootloader引导程序源码、示例
💻 C
📖 第 1 页 / 共 3 页
字号:
{
  return(usbStatus);
}

//---------------------------------------------------------------------------------------
// Decode USB commands
// Called when SETUP request received
//---------------------------------------------------------------------------------------
void USB_StandardRequest(void)
{
	word temp;
	uchar idxTmp;

  extern byte* ptrToConfigDsc;
  extern byte* ptrToDeviceDsc;
  extern byte* STRING_DSC_TAB[STRING_DSC_TAB_LEN];

  // Clear pending Data Control State
	// Standart reguest GET DESCRIPTOR
	if (((SetupPcktStrc *)ep0BufSh)->bRequest == RQST_GET_DESCRIPTOR)
	{
		switch ((byte)((SetupPcktStrc *)ep0BufSh)->wValue)
		{
		 	// Get CONFIGURATION Descriptor request
			case (DSC_CONFIGURATION_TYPE):
				// number of requested data
				temp = CHNG_ENDIAN(((SetupPcktStrc *)ep0BufSh)->wLength);
				if (temp > 0xFF) temp = 0xFF;


				if ((byte)temp > *(ptrToConfigDsc + 2))
  			  temp = *(ptrToConfigDsc + 2);

				(void) USB_TxBuff0(ptrToConfigDsc, (byte)temp);
				break;

			// Get DEVICE Descriptor
			case (DSC_DEVICE_TYPE):

        temp = CHNG_ENDIAN(((SetupPcktStrc *)ep0BufSh)->wLength);
				if (temp > 0xFF) temp = 0xFF;

				if (temp > *ptrToDeviceDsc)
				  temp = *ptrToDeviceDsc;

				// Upload Data to EP buffer
				(void) USB_TxBuff0(ptrToDeviceDsc, (byte)temp);
				break;

      // Get STRING Descriptor
			case (DSC_STRING_TYPE):

        // load STRING descriptor index number
        idxTmp = H_BYTE(((SetupPcktStrc *)ep0BufSh)->wValue);

				if (idxTmp <= STRING_DSC_TAB_LEN)
				{	// load requested number of bytes
          temp = CHNG_ENDIAN(((SetupPcktStrc *)ep0BufSh)->wLength);
  				if (temp > 0xFF) temp = 0xFF;

					// if string descriptor length is shorter than requested num of bytes, trim it
					if (temp > * STRING_DSC_TAB[idxTmp])
					  temp = * STRING_DSC_TAB[idxTmp];

				  (void) USB_TxBuff0(STRING_DSC_TAB[idxTmp], (byte)temp);
				}

        // Illegal String descriptor Index
				else
					USB_WRSTALL_EP0(1);
			break;

			// Illegal descriptor type
			default:
			{
	        #ifdef  USB_GET_DESCRIPTOR_CB
	        extern void USB_GET_DESCRIPTOR_CB(void);
	        USB_GET_DESCRIPTOR_CB();
	        #else
	        USB_WRSTALL_EP0(1);
	        #endif
			}
			break;
		} // end switch
	}
	else 	USB_WRSTALL_EP0(1);
}

//-------------------------------------------------------------------
// USB Interrupt Service Routines
//-------------------------------------------------------------------


interrupt void USB_EP_ISR(void)
{
/* ENDPOINT 0 - dedicated to control transfer */
  if(UEP0CSR & UEP0CSR_TFRC_IN_MASK)    // EP0 IN packet odeslan, naplnim zbytek?
  {
    UEP0CSR &= ~UEP0CSR_TFRC_IN_MASK;

		if(usbStatus & CTRL_READ_STATE)
		{
      pDst0 = EP0_BASE_ADR;
      cntDst0 = EP0_BUFFER_SIZE;

    	while(cntDst0 && cntSrc0)
    	{
        *pDst0++ = *pSrc0++;
        cntDst0--;
        cntSrc0--;
    	}

      if(cntDst0 > 0)
        usbStatus &= ~CTRL_READ_STATE;

      // set DVALID_IN flag and data length, others bits leave unchanged
    	UEP0CSR = (EP0_BUFFER_SIZE - cntDst0)<<4 | (UEP0CSR_DVALID_IN_MASK | UEP0CSR_TFRC_IN_MASK | UEP0CSR_TFRC_OUT_MASK | UEP0CSR_DVALID_OUT_MASK);
		}
  }

  if(UEP0CSR & UEP0CSR_TFRC_OUT_MASK)   //EP0 OUT packet prijat
  {
  	if(usbStatus & CTRL_WRITE_STATE)
  	{
  	  pSrc0 = EP0_BASE_ADR;
      cntSrc0 = EP0_BUFFER_SIZE;

    	while(cntDst0 && cntSrc0)
    	{
        *pDst0++ = *pSrc0++;
        cntDst0--;
        cntSrc0--;
      }

  	  if(cntSrc0 > 0)
 	    {
 	      // end of data state in OUT packet -> we must send IN packet with zero data length
      	UEP0CSR = (UEP0CSR_DVALID_IN_MASK | UEP0CSR_TFRC_IN_MASK | UEP0CSR_TFRC_OUT_MASK | UEP0CSR_DVALID_OUT_MASK);
  	    usbStatus &= ~CTRL_WRITE_STATE;
 	    }
 	    #ifndef USB_CALLBACK_EP0
        #define USB_CALLBACK_EP0 0
      #endif
      
 	    #if USB_CALLBACK_EP0 == 1
 	      USB_RxReadyCB0();
 	    #endif
  	}

  	UEP0CSR &= ~(UEP0CSR_TFRC_OUT_MASK | UEP0CSR_DVALID_OUT_MASK); // Clear TFRC0 and DVALID_OUT flag
  }

  // ENDPOINT 1
  // endpoint is enabled
  #ifndef USB_CALLBACK_EP1
    #define USB_CALLBACK_EP1 0
  #endif
  #if EP1_MODE
  	if(UEP1CSR & UEP1CSR_TFRC_MASK)
  	{
    	// EP in IN mode
    	#if EP1_DIR & EP_DIR_IN
     	  pDst1 = EP1_BASE_ADR;
     	  cntDst1 = EP1_BUFFER_SIZE;

     	  #if USB_CALLBACK_EP1 == 0
       	  while(cntDst1 && cntSrc1)
       	  {
       	    cntDst1--;
       	    cntSrc1--;
       	    *pDst1++ = *pSrc1++;
       	  }

       	  if((uchar)(EP1_BUFFER_SIZE - cntDst1) > 0)
       	  {
       	   	UEP1DSR = EP1_BUFFER_SIZE - cntDst1;
       	   	UEP1CSR |= UEP1CSR_DVALID_MASK;
       	  }
        #else
          USB_TxEmptyCB1(EP1_BUFFER_SIZE);
        #endif

			// EP in OUT mode
      #else
        pSrc1 = EP1_BASE_ADR;
        cntSrc1 = UEP1DSR;

        #if USB_CALLBACK_EP1 == 0
          while(cntSrc1 && cntDst1)
          {
            cntSrc1--;
            cntDst1--;
            *pDst1++ = *pSrc1++;
          }
          if(cntSrc1 == 0)
            UEP1CSR &= ~UEP1CSR_DVALID_MASK;
        #else
          USB_RxReadyCB1(UEP1DSR);
        #endif
      #endif
      UEP1CSR &= ~UEP1CSR_TFRC_MASK;
  	}
  #endif

  // ENDPOINT 2
  // endpoint is enabled
  #ifndef USB_CALLBACK_EP2
    #define USB_CALLBACK_EP2 0
  #endif
  #if EP2_MODE
  	if(UEP2CSR & UEP2CSR_TFRC_MASK)
  	{
    	// EP in IN mode
    	#if EP2_DIR & EP_DIR_IN
     	  pDst2 = EP2_BASE_ADR;
     	  cntDst2 = EP2_BUFFER_SIZE;

       	#if USB_CALLBACK_EP2 == 0
       	  while(cntDst2 && cntSrc2)
       	  {
       	    cntDst2--;
       	    cntSrc2--;
       	    *pDst2++ = *pSrc2++;
       	  }

       	  if((uchar)(EP2_BUFFER_SIZE - cntDst2) > 0)
       	  {
       	   	UEP2DSR = EP2_BUFFER_SIZE - cntDst2;
       	   	UEP2CSR |= UEP2CSR_DVALID_MASK;
       	  }
       	#else
       	  USB_TxEmptyCB2(EP2_BUFFER_SIZE);
       	#endif

			// EP in OUT mode
      #else
        pSrc2 = EP2_BASE_ADR;
        cntSrc2 = UEP2DSR;

        #if USB_CALLBACK_EP2 == 0
          while(cntSrc2 && cntDst2)
          {
            cntSrc2--;
            cntDst2--;
            *pDst2++ = *pSrc2++;
          }
          if(cntSrc2 == 0)
            UEP2CSR &= ~UEP2CSR_DVALID_MASK;

        #else
          USB_RxReadyCB2(UEP2DSR);
        #endif

      #endif
      UEP2CSR &= ~UEP2CSR_TFRC_MASK;
  	}
  #endif

  /* ENDPOINT 3 */
  // endpoint is enabled
#ifndef USB_CALLBACK_EP3
  #define	 USB_CALLBACK_EP3 0
#endif
  #if EP3_MODE
  	if(UEP3CSR & UEP3CSR_TFRC_MASK)
  	{
    	// EP in IN mode
    	#if EP3_DIR & EP_DIR_IN
     	  pDst3 = EP3_BASE_ADR;
     	  cntDst3 = EP3_BUFFER_SIZE;

        #if USB_CALLBACK_EP3 == 0
         	while(cntDst3 && cntSrc3)
         	{
         	  cntDst3--;
         	  cntSrc3--;
         	  *pDst3++ = *pSrc3++;
         	}

       	  if((uchar)(EP3_BUFFER_SIZE - cntDst3) > 0)
       	  {
       	   	UEP3DSR = EP3_BUFFER_SIZE - cntDst3;
       	   	UEP3CSR |= UEP3CSR_DVALID_MASK;
       	  }
     	  #else
     	    USB_TxEmptyCB3(EP3_BUFFER_SIZE);
     	  #endif

			// EP in OUT mode
      #else
        pSrc3 = EP3_BASE_ADR;
        cntSrc3 = UEP3DSR;

        #if USB_CALLBACK_EP3 == 0
          while(cntSrc3 && cntDst3)
          {
            cntSrc3--;
            cntDst3--;
            *pDst3++ = *pSrc3++;
          }
          if(cntSrc3 == 0)
            UEP3CSR &= ~UEP3CSR_DVALID_MASK;
        #else
          USB_RxReadyCB3(UEP3DSR);
        #endif
      #endif
      UEP3CSR &= ~UEP3CSR_TFRC_MASK;
  	}
  #endif


  // ENDPOINT 4
  // endpoint is enabled
  #ifndef USB_CALLBACK_EP4
    #define USB_CALLBACK_EP4 0
  #endif
  #if EP4_MODE
  	if(UEP4CSR & UEP4CSR_TFRC_MASK)
  	{
    	// EP in IN mode
    	#if EP4_DIR & EP_DIR_IN
     	  pDst4 = EP4_BASE_ADR;
     	  cntDst4 = EP4_BUFFER_SIZE;

     	  #if  USB_CALLBACK_EP4 == 0
       	  while(cntDst4 && cntSrc4)
       	  {
       	    cntDst4--;
       	    cntSrc4--;
       	    *pDst4++ = *pSrc4++;
       	  }

       	  if((uchar)(EP4_BUFFER_SIZE - cntDst4) > 0)
       	  {
       	   	UEP4DSR = EP4_BUFFER_SIZE - cntDst4;
       	   	UEP4CSR |= UEP4CSR_DVALID_MASK;
       	  }
        #else
          USB_TxEmptyCB4(EP4_BUFFER_SIZE);
        #endif

			// EP in OUT mode
      #else
        pSrc4 = EP4_BASE_ADR;
        cntSrc4 = UEP4DSR;

        #if  USB_CALLBACK_EP4 == 0
          while(cntSrc4 && cntDst4)
          {
            cntSrc4--;
            cntDst4--;
            *pDst4++ = *pSrc4++;
          }
          if(cntSrc4 == 0)
            UEP4CSR &= ~UEP4CSR_DVALID_MASK;
        #else
          USB_RxReadyCB4(UEP4DSR);
        #endif

      #endif
      UEP4CSR &= ~UEP4CSR_TFRC_MASK;
  	}
  #endif
}

//-------------------------------------------------------------------
// USB Interrupt Service Routines
//-------------------------------------------------------------------

interrupt void USB_SYS_ISR(void)
{

  // setup packet interrupt?
  #if USB_SETUPIE_ENA != 0
  	if(USBSR & USBSR_SETUP_MASK)
  	{
      // Copy ep0 data into shadow data buffer
      ep0BufSh[0] =  *(EP0_BASE_ADR + 0);
      ep0BufSh[1] =  *(EP0_BASE_ADR + 1);
      ep0BufSh[2] =  *(EP0_BASE_ADR + 2);
      ep0BufSh[3] =  *(EP0_BASE_ADR + 3);
      ep0BufSh[4] =  *(EP0_BASE_ADR + 4);
      ep0BufSh[5] =  *(EP0_BASE_ADR + 5);
      ep0BufSh[6] =  *(EP0_BASE_ADR + 6);
      ep0BufSh[7] =  *(EP0_BASE_ADR + 7);
      
        
      // GET_DESCRIPTOR, SYNC_FRAME, class/vendor specific request    
  		UEP0CSR &= ~(UEP0CSR_TFRC_OUT_MASK | UEP0CSR_DVALID_OUT_MASK); // Clear TFRC_0UT bit
  		USBSR &= ~USBSR_SETUP_MASK;		  						                   // Clear SETUP flag

  	  usbStatus &= ~(CTRL_READ_STATE | CTRL_WRITE_STATE);
      // standard requests
    	if ((((SetupPcktStrc *)ep0BufSh)->bmRequestType & M_COMMAND_TYPE_MASK) == M_STANDARD_COMMAND)
    	{
    		USB_StandardRequest();
    	}

    	// class specific requests
    	else if ((((SetupPcktStrc *)ep0BufSh)->bmRequestType & M_COMMAND_TYPE_MASK) == M_CLASS_COMMAND)
    	{
    	  #ifdef USB_CLASS_REQUEST_CB
    	    extern void USB_CLASS_REQUEST_CB(void);
          USB_CLASS_REQUEST_CB();
        #else
          USB_WRSTALL_EP0(1);
        #endif
    	}

      // vendor specific requests
    	else if ((((SetupPcktStrc *)ep0BufSh)->bmRequestType & M_COMMAND_TYPE_MASK) == M_VENDOR_COMMAND)
    	{
        #ifdef USB_VENDOR_REQUEST_CB
          extern void USB_VENDOR_REQUEST_CB(void);
          USB_VENDOR_REQUEST_CB();
        #else
        USB_WRSTALL_EP0(1);
        #endif
    	}

    	// all other illegal requests
    	else
    	{
    	  USB_WRSTALL_EP0(1);
    	}
  	}
  #endif

	// Start of frame interrupt
	#if USB_SOFIE_ENA != 0
	  if(USBSR & USBSR_SOF_MASK)
	  {
	    USBSR &= ~USBSR_SOF_MASK;			 // Clear SOF flag
  		USB_SofCB();
  	}
  #endif

	// Config change interrupt
  #if USB_CONFIGCHGIE_ENA != 0
	  if(USBSR & USBSR_CONFIG_CHG_MASK)
	  {
  		USBSR &= ~USBSR_CONFIG_CHG_MASK;						// Clear CONFIGCHG flag
  		USB_ConfigChngCB();
  	}
  #endif

	// Reset flag  - divne!!! Jak to ma byt?
	#if USB_USBRSTIE_ENA != 0
  	if (USBSR & USBSR_USBRST_MASK)
  	{
  		USBSR &= ~USBSR_USBRST_MASK;							// Clear USB Reset flag
  		// clear all unlatched STALL
  		USIMR_EP0_STALL = 0;
	    #if EP1_MODE
	      UEP1CSR_STALL = 0;
	    #endif
 	    #if EP2_MODE
 	      UEP2CSR_STALL = 0;
	    #endif
	    #if EP3_MODE
        UEP3CSR_STALL = 0;	    
	    #endif
	    #if EP4_MODE
	     UEP4CSR_STALL = 0;
	    #endif
	    USB_ResetCB();    // Custom RESET Handling
  	}
	#endif

	// Resume flag - budim procesor ze spanku
  #if USB_RESUMEFIE_ENA != 0
  	if (USBSR & USBSR_RESUMEF_MASK)
  	{
  		USBSR &= ~USBSR_RESUMEF_MASK;		// Clear USB RESUME flag
  		USB_ResumeCB(); 						    // User setting for USB resume
  		USBCR |= USBCR_USBCLKEN_MASK;	  // Enable USB clk
  	}
	#endif

	// Suspend flag
	#if USB_SUSPNDIE_ENA != 0
  	if (USBSR & USBSR_SUSPND_MASK)
  	{
  		USBSR &= ~USBSR_SUSPND_MASK;							// Clear USB Suspend
   		USBCR &= ~USBCR_USBCLKEN_MASK;					  // Stop USB module clock
      USB_SuspendCB();
  	}
 #endif
}

⌨️ 快捷键说明

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