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

📄 usb_driver.c

📁 M68HC08 及HCS08系列单片机bootloader引导程序源码、示例
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2005 Freescale Semiconductor, Inc.
* (c) Copyright 2001-2004 Motorola, Inc.
* ALL RIGHTS RESERVED.
*
***************************************************************************//*!
*
* @file      usb_driver.c
*
* @author    B01119
*
* @version   1.0.3.0
*
* @date      Sep-8-2008
*
* @brief    USB Module Driver for HC08 MCUs
*
*******************************************************************************
*
* 
*
******************************************************************************/

#include <hidef.h> 			/* for EnableInterrupts macro */
#include <MC68HC908JW32.h> 	/* include peripheral declarations */
#include "usb.h"			/* USB Header file */
#include "usb_periph_cfg.h"
#include "usb_driver.h"

//-------------------------------------------------------------------
// Local Variables
//-------------------------------------------------------------------
#pragma DATA_SEG SHORT _DATA_ZEROPAGE

static volatile uchar* pSrc0;
static volatile uchar* pDst0;
static volatile uchar cntSrc0;
static volatile uchar cntDst0;

static volatile uchar* pSrc1;
static volatile uchar* pDst1;
static volatile uchar cntSrc1;
static volatile uchar cntDst1;

static volatile uchar* pSrc2;
static volatile uchar* pDst2;
static volatile uchar cntSrc2;
static volatile uchar cntDst2;

static volatile uchar* pSrc3;
static volatile uchar* pDst3;
static volatile uchar cntSrc3;
static volatile uchar cntDst3;

static volatile uchar* pSrc4;
static volatile uchar* pDst4;
static volatile uchar cntSrc4;
static volatile uchar cntDst4;

volatile uchar	usbStatus;
#pragma	  DATA_SEG	DEFAULT
uchar ep0BufSh[8];

//-------------------------------------------------------------------
// USB line initialization (needs to be done asap after chip reset)
//
// Description:
// - Enable D+ pullup resistor and 3.3V regulator & USB RESET
//-------------------------------------------------------------------
void USB_Init(void)
{

  // Set/reset the 3V3 voltage regulator and USB reset
#ifndef USB_3V3REGULATOR_DIS
#define USB_3V3REGULATOR_DIS 0
#endif

#ifndef USB_CHIP_RESET_DIS
#define USB_CHIP_RESET_DIS 0
#endif

#ifndef USB_PULLUP_ENA
#define USB_PULLUP_ENA 0x00
#endif

	CONFIG2 |= (USB_3V3REGULATOR_DIS | USB_CHIP_RESET_DIS);

// Enable D+ pullup
#if USB_PULLUP_ENA==0x01
  POCR2 |= POCR2_DPPULLEN_MASK;
#endif
}

//-------------------------------------------------------------------
// USB module Enable (shall be done right before interrupt enable)
//
// Description:
// - wait for D+ line to go high (out of USB reset state), if USB chip reset enabled
// - Enable 4 Data Endpoint
// - 16 byte endpoint data buffer
//-------------------------------------------------------------------
void USB_Enable(void)
{
  // If the USB reset is set as MCU reset we should avoid the
  // multiple chip resetting while long RESET signalling
  #if USB_CHIP_RESET_DIS == 0
  // Wait for RESET signal on USB D+ line (logic 0)
 
    while (!PTE_PTE2) 
    {
      USB_DO_NOTHING();
    __RESET_WATCHDOG();
    }
  #endif

  // Assign the End Points to the interfaces
	UINTFCR = UINTFCR_INI;

  // Endpoints settings
  // Clear EP0 Status Register
	UEP0CSR = 0;

	// Set EP1 - EP4 base addresses
	UEP12BPR = UEP12BPR_INI;
	UEP34BPR = UEP34BPR_INI;

  // initialise all used EP
	#if EP1_MODE
 	UEP1CSR = UEP1CSR_INI;
    #if EP1_DIR & EP_DIR_IN
      cntDst1 = EP1_BUFFER_SIZE;
      cntSrc1 = 0;
      pDst1 = EP1_BASE_ADR;
    #else
      cntDst1 = 0;
      cntSrc1 = 0;
    #endif
  #endif

	#if EP2_MODE
    UEP2CSR = UEP2CSR_INI;
    #if EP2_DIR & EP_DIR_IN
      cntDst2 = EP2_BUFFER_SIZE;
      cntSrc2 = 0;
      pDst2 = EP2_BASE_ADR;
    #else
      cntDst2 = 0;
      cntSrc2 = 0;
    #endif
  #endif

	#if EP3_MODE
	  UEP3CSR = UEP3CSR_INI;
    #if EP3_DIR & EP_DIR_IN
      cntDst3 = EP3_BUFFER_SIZE;
      cntSrc3 = 0;
      pDst3 = EP3_BASE_ADR;
    #else
      cntDst3 = 0;
      cntSrc3 = 0;
    #endif
  #endif

	#if EP4_MODE
	  UEP4CSR = UEP4CSR_INI;
    #if EP4_DIR & EP_DIR_IN
      cntDst4 = EP4_BUFFER_SIZE;
      cntSrc4 = 0;
      pDst4 = EP4_BASE_ADR;
    #else
      cntDst4 = 0;
      cntSrc4 = 0;
    #endif
  #endif

  USBSR = 0;				// Clear Status Register

  #ifndef USB_SETUPIE_ENA
    #define USB_SETUPIE_ENA      0
  #endif
  #ifndef USB_SOFIE_ENA
    #define USB_SOFIE_ENA        0
  #endif
  #ifndef USB_CONFIGCHGIE_ENA
    #define USB_CONFIGCHGIE_ENA  0
  #endif
  #ifndef USB_USBRSTIE_ENA
    #define USB_USBRSTIE_ENA     0
  #endif
  #ifndef USB_RESUMEFIE_ENA
    #define USB_RESUMEFIE_ENA    0
  #endif
  #ifndef USB_SUSPNDIE_ENA
    #define USB_SUSPNDIE_ENA     0
  #endif

	USIMR = (USB_SUSPNDIE_ENA?USIMR_SUSPNDIE_MASK:0)|\
	        (USB_RESUMEFIE_ENA?USIMR_RESUMEFIE_MASK:0)|\
	        (USB_USBRSTIE_ENA?USIMR_USBRSTIE_MASK:0)|\
	        (USB_CONFIGCHGIE_ENA?USIMR_CONFIG_CHGIE_MASK:0)|\
	        (USB_SOFIE_ENA?USIMR_SOFIE_MASK:0)|\
	        (USB_SETUPIE_ENA?USIMR_SETUPIE_MASK:0);

	USBCR = USBCR_USBCLKEN_MASK|USBCR_USBEN_MASK|USBCR_TFC0IE_MASK|\
	        (EP1_MODE?USBCR_TFC1IE_MASK:0)|\
	        (EP2_MODE?USBCR_TFC2IE_MASK:0)|\
	        (EP3_MODE?USBCR_TFC3IE_MASK:0)|\
	        (EP4_MODE?USBCR_TFC4IE_MASK:0);
}

//---------------------------------------------------------------------------------------
// USB line deinitialization
//---------------------------------------------------------------------------------------
void USB_Deinit(void)
{
  // Disable D+ pullup
  POCR2 &= ~POCR2_DPPULLEN_MASK;
}

//---------------------------------------------------------------------------------------
// USB module Disable
//---------------------------------------------------------------------------------------
void USB_Disable(void)
{
  // Disable USB Module
	USBCR = 0;
}

//---------------------------------------------------------------------------------------
// uchar USB_TxBuff0(uchar* adr, uchar cnt)
//---------------------------------------------------------------------------------------
uchar USB_TxBuff0(uchar* adr, uchar cnt)
{
  pDst0 = EP0_BASE_ADR;
  cntDst0 = EP0_BUFFER_SIZE;

  pSrc0 = adr;
  cntSrc0 = cnt;

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

  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);
	return(cntSrc0);
}

//---------------------------------------------------------------------------------------
// void USB_RxBuff0(uchar* adr, uchar cnt)
//---------------------------------------------------------------------------------------
void USB_RxBuff0(uchar* adr, uchar cnt)
{
  pDst0 = adr;
  cntDst0 = cnt;
  usbStatus |= CTRL_WRITE_STATE;
}

//---------------------------------------------------------------------------------------
// uchar USB_RxBuff1(uchar* adr, uchar cnt) - used for OUT bulk/interrupt packet
// NON BLOCKING function. Set user buffer address and number of bytes to be
// received. If there are any available data these will be copied intermidiately.
// The rest of the user buffer is filled during interrupt service routine.
// Function returns number of pending bytes in user buffer.
//---------------------------------------------------------------------------------------
uchar USB_RxBuff1(uchar* adr, uchar cnt)
{
  // Set address where to copy received data
  pDst1 = adr;
  // How many bytes to be copied
  cntDst1 = cnt;

  // If there are any data available, copy them intermidiately
  while(cntSrc1 && cntDst1)
  {
    cntSrc1--;
    cntDst1--;
    *pDst1++ = *pSrc1++;
  }

  // If all the received bytes are copied to the user buffer, enable to receive next OUT packet
  if(cntSrc1 == 0)
     UEP1CSR &= ~UEP1CSR_DVALID_MASK;

  // Return number of pending data in user buffer
  return(cntDst1);
}

//---------------------------------------------------------------------------------------
// uchar USB_RxChar1(void)
// BLOCKING function - wait till RxBuffPending and there are any received data in EP buffer
// then read one byte from EP buffer and return it.
//---------------------------------------------------------------------------------------
uchar USB_RxChar1(void)
{
  uchar retVal;
  // Wait until user buffer pending
  while(cntDst1)
    USB_DO_NOTHING();

  // Wait while data in EP buffer available
  while(!(cntSrc1))
    USB_DO_NOTHING();

  retVal = *pSrc1++;

  // If no more data in EP buffer, enable another packet receive
  if(!(--cntSrc1))
     UEP1CSR &= ~UEP1CSR_DVALID_MASK;

  // Return received data
  return(retVal);
}

//---------------------------------------------------------------------------------------
// uchar USB_RxBuffPending1(void)
// returns number of bytes pending to be received to user buffer
//---------------------------------------------------------------------------------------
uchar USB_RxBuffPending1(void)
{
  return(cntDst1);
}

//---------------------------------------------------------------------------------------
// uchar USB_GetRxReady1(void)
// return number of available data bytes in EP buffer
//---------------------------------------------------------------------------------------
uchar USB_GetRxReady1(void)
{
  return(cntSrc1);
}

//---------------------------------------------------------------------------------------
// uchar USB_GetTxEmpty1(void)
// returns number of available bytes in EP buffer (to be write)
//---------------------------------------------------------------------------------------
uchar USB_GetTxEmpty1(void)
{
  if(UEP1CSR_DVALID)	 // if transmit is pending
    return(0);				 // return zero
  else
    return(cntDst1);	 // else return free space in transmit buffer
}

//---------------------------------------------------------------------------------------
// uchar USB_TxChar1(uchar ch)  - used for IN bulk/interrupt packet
// BLOCKING function - waits till user Tx buffer is pending and
// EP buffer has free place. Then write character to EP buffer. When EP buffer
// is full, flushes this packet.
// Function returns number of available bytes in EP buffer
//---------------------------------------------------------------------------------------
#pragma MESSAGE DISABLE C1853
uchar USB_TxChar1(uchar ch)
{
  uchar retVal;
  // wait pending buffer
  while(cntSrc1)
    USB_DO_NOTHING();

  // wait while EP buffer not sent
  while(UEP1CSR_DVALID)
    USB_DO_NOTHING();

  // write character to buffer
  *pDst1++ = ch;

  cntDst1--;
  retVal = cntDst1;
  // if EP buffer is full, flush it
  if(retVal == 0)
  {
    UEP1DSR = EP1_BUFFER_SIZE;
    UEP1CSR |= UEP1CSR_DVALID_MASK;
  }
  return(retVal);
}
#pragma MESSAGE DEFAULT C1853
//---------------------------------------------------------------------------------------
// uchar USB_TxBuff1(uchar* adr, uchar cnt) user for IN interrupt/bulk packet
// NON BLOCKING function - function copy data from user buffer to EP
// buffer. If user buffer is larger then EP buffer the rest of data is send in interrupt
// service routine. Function returns number of bytes pending in user buffer
//---------------------------------------------------------------------------------------
#pragma MESSAGE DISABLE C1853
uchar USB_TxBuff1(uchar* adr, uchar cnt)
{
   uchar retVal;
	 // set address of buffer where the data to be send are placed
	 pSrc1 = adr;
	 // set number of bytes to send
	 cntSrc1 = cnt;

   // copy data from user buffer to EP buffer
	 while(cntSrc1 && cntDst1)
	 {
	  cntSrc1--;
	  cntDst1--;
	  *pDst1++ = *pSrc1++;
	 }

	 retVal = cntSrc1;
	 // flush it
   UEP1DSR = EP1_BUFFER_SIZE - cntDst1;
   UEP1CSR |= UEP1CSR_DVALID_MASK;

	 // return number of bytes pending in user buffer
	 return(retVal);
}
#pragma MESSAGE DEFAULT C1853
//---------------------------------------------------------------------------------------
// uchar USB_TxBuffPending1(void)
// function returns number of bytes pending in user buffer
//---------------------------------------------------------------------------------------
uchar USB_TxBuffPending1(void)
{
  return(cntSrc1);
}
//---------------------------------------------------------------------------------------
// uchar USB_TxFlush1(void)
// if there is at least one byte to be send in EP buffer, flush buffer
// Function returns number of send bytes
//---------------------------------------------------------------------------------------
#pragma MESSAGE DISABLE C1853
uchar USB_TxFlush1(void)
{
  UEP1DSR = EP1_BUFFER_SIZE - cntDst1;
  UEP1CSR |= UEP1CSR_DVALID_MASK;
  return(UEP1DSR);
}
#pragma MESSAGE DEFAULT C1853
//---------------------------------------------------------------------------------------
// uchar USB_RxBuff2(uchar* adr, uchar cnt) - used for OUT bulk/interrupt packet
// NON BLOCKING function. Set user buffer address and number of bytes to be
// received. If there are any available data these will be copied intermidiately.
// The rest of the user buffer is filled during interrupt service routine.
// Function returns number of pending bytes in user buffer.
//---------------------------------------------------------------------------------------
uchar USB_RxBuff2(uchar* adr, uchar cnt)
{
  // set address where to copy received data
  pDst2 = adr;
  // how many bytes to be copied
  cntDst2 = cnt;

  // if there are any data available, copy them intermidiately
  while(cntSrc2 && cntDst2)
  {
    cntSrc2--;
    cntDst2--;
    *pDst2++ = *pSrc2++;
  }

  // if all received bytes are copied to user buffe, enable to receive next OUT packet
  if(cntSrc2 == 0)
     UEP2CSR &= ~UEP2CSR_DVALID_MASK;

  // return number of pending data in user buffer
  return(cntDst2);
}

//---------------------------------------------------------------------------------------
// uchar USB_RxChar2(void)
// BLOCKING function - wait till RxBuffPending and there are any received data in EP buffer
// then read one byte from EP buffer and return it.
//---------------------------------------------------------------------------------------
uchar USB_RxChar2(void)
{
  uchar retVal;
  // wait until buffer pending
  while(cntDst2)
    USB_DO_NOTHING();

  // wait while data in EP buffer aviable
  while(!(cntSrc2))
    USB_DO_NOTHING();

  retVal = *pSrc2++;
  // if no more data in EP buffer, enalble another packet receive
  if(!(--cntSrc2))
     UEP2CSR &= ~UEP2CSR_DVALID_MASK;

  // return data

⌨️ 快捷键说明

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