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

📄 usb.c

📁 freescale badge board 开发板测试 源程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************
 *
 *            Copyright (c) 2006-2007 by CMX Systems, Inc.
 *
 * This software is copyrighted by and is the sole property of
 * CMX.  All rights, title, ownership, or other interests
 * in the software remain the property of CMX.  This
 * software may only be used in accordance with the corresponding
 * license agreement.  Any unauthorized use, duplication, transmission,
 * distribution, or disclosure of this software is expressly forbidden.
 *
 * This Copyright notice may not be removed or modified without prior
 * written consent of CMX.
 *
 * CMX reserves the right to modify this software without notice.
 *
 * CMX Systems, Inc.
 * 12276 San Jose Blvd. #511
 * Jacksonville, FL 32223
 * USA
 *
 * Tel:  (904) 880-1840
 * Fax:  (904) 880-1632
 * http: www.cmx.com
 * email: cmx@cmx.com
 *
 ***************************************************************************/
#include "hcc_types.h"
#include "mcf51xx_reg.h"
#include "usb.h"
//#include "target.h"

/*****************************************************************************
 * Local types.
 *****************************************************************************/
typedef struct {
  volatile hcc_u32 tlength;
  volatile hcc_u32 maxlength;
  void * volatile address;
  volatile usb_callback_t data_func;
  hcc_u16 psize;
  hcc_u32 data0_tx;
  hcc_u32 data0_rx;
  volatile hcc_u8 state;
  volatile hcc_u8 flags;
  volatile hcc_u8 error;
  hcc_u8 next_rx;
  hcc_u8 next_tx;
} ep_info_t;

/*****************************************************************************
 * Macro definitions.
 *****************************************************************************/
#define DIR_TX             BIT7

#define SOF_PID_VALUE		0xd
/* Note: BIT3 shows if the data packet is data0 or data1. */
#define DATA_PID_VALUE      0x3
#define DATA0_PID_VALUE     0x3
#define DATA1_PID_VALUE     0xb

#define MCF_USB_ENDPT(ep)  (((hcc_u8*)&MCF_USB_ENDPT0)[ep<<2])
#define MCF_USB_ENDPT_EP_HSHK      BIT0
#define MCF_USB_ENDPT_EP_STALL     BIT1
#define MCF_USB_ENDPT_EP_TX_EN     BIT2
#define MCF_USB_ENDPT_EP_RX_EN     BIT3
#define MCF_USB_ENDPT_EP_CTL_DIS   BIT4
#define MCF_USB_ENDPT_RETRY_DIS    BIT6
#define MCF_USB_ENDPT_HOST_WO_HUB  BIT7

#define MIN(a,b)     ((a) < (b) ? (a) : (b))

/* Control endpoint state machine state values. */
#define EPST_IDLE             0x0
#define EPST_DATA_TX          0x1
#define EPST_DATA_TX_LAST     0x2
#define EPST_DATA_RX          0x3
#define EPST_STATUS_TX        0x4
#define EPST_STATUS_RX        0x5
#define EPST_TX_STOP          0x6
#define EPST_ABORT_TX         0x7
#define EPST_DATA_TX_WAIT_DB  0x8
#define EPST_DATA_TX_EMPTY_DB 0x9

/* Standard USB feature selector values. */
#define FEAT_ENDPOINT_HALT        0u
#define FEAT_DEVICE_REMOTE_WAKEUP 1u

/* Endpoint flag bits. */
#define EPFL_ERROR    (hcc_u8)BIT0  /* There was an error during the ongoing
                               transfer. */
#define EPFL_ZPACKET  (hcc_u8)BIT1  /* After the last data packet an additional zero
                               length packet needs to be transmitted to close
                               the transfer. */

/* This macro shall evaluate to a uint32 pointer to the start address of the
   buffer descriptor table (BDT). The BDT has 32 bytes for each endpoint.
   The BDT shall be alignet to 512 byte boundary! */
extern hcc_u32 _BDT_MAP[];
#define BDT_BASE              ((hcc_u32*)(_BDT_MAP))
#define BDT_CTL_RX(ep, b)     (BDT_BASE[((ep)<<3)+((b)<<1)+0])
#define BDT_ADR_RX(ep, b)     (BDT_BASE[((ep)<<3)+((b)<<1)+1])
#define BDT_CTL_TX(ep, b)     (BDT_BASE[((ep)<<3)+((b)<<1)+4])
#define BDT_ADR_TX(ep, b)     (BDT_BASE[((ep)<<3)+((b)<<1)+5])

#define BDT_CTL_STALL BIT2
#define BDT_CTL_DTS   BIT3
#define BDT_CTL_DATA  BIT6
#define BDT_CTL_OWN   BIT7

/*****************************************************************************
 * Global variables.
 *****************************************************************************/
/* N/A */

/*****************************************************************************
 * Module variables.
 *****************************************************************************/
static volatile hcc_u8 usb_current_config;
static volatile hcc_u8 usb_state;
static volatile hcc_u8 new_address;
static ep_info_t ep_info[16];

/*****************************************************************************
 * Function predefinitions.
 *****************************************************************************/
static void enter_default_state(void);
static void disable_ep_rx(hcc_u8);
static void disable_ep_tx(hcc_u8);
static void ready_ep_rx(hcc_u8, hcc_u8);
static void ready_ep_tx(hcc_u8, hcc_u8);
static hcc_u8 select_tx_buf(hcc_u8 ep);
static void send_zero_packet(hcc_u8 ep);
static void _usb_send(hcc_u8 ep);
static void _usb_receive(hcc_u8 ep);
static callback_state_t cb_set_address(void);
static callback_state_t usb_stm_ctrl0(void);
static hcc_u8 usb_setup_ep(hcc_u8 addr, hcc_u8 type, hcc_u8 ep, hcc_u16 psize);

extern void enable_usb_pull_up();
/*****************************************************************************
 * Name:
 *   usb_get_rx_pptr
 * In:
 *   ep: number of endpoint.
 * Out:
 *   Pointer to the packet buffer containing data of the last received packet.
 *
 * Description:
 *   Returns te number of bytes that are left of the transfer. If
 *   usb_ep_is_busy returns false, then the transfer was aborted either
 *   by the host or by the application.
 *****************************************************************************/
hcc_u8* usb_get_rx_pptr(hcc_u8 ep)
{
  hcc_u8 cur_buf=(hcc_u8)(MCF_USB_STAT & MCF_USB_STAT_ODD ? 1 : 0);
  return((hcc_u8 *)(RD_LE32(&BDT_ADR_RX(ep, cur_buf))));
}

/*****************************************************************************
 * Name:
 *   select_tx_buf
 * In:
 *   ep: number of endpoint.
 * Out:
 *   The index of the next tx buffer.
 *
 * Description:
 *   Returns te number of bytes that are left of the transfer. If
 *   usb_ep_is_busy returns false, then the transfer was aborted either
 *   by the host or by the application.
 *****************************************************************************/
static hcc_u8 select_tx_buf(hcc_u8 ep)
{
/* SHALL ONLY BE CALLED WITH USB INTERRUPTS DISABLED. */
  hcc_u8 buf;
  hcc_u32 ctl;
  /* Find out which buffer shall be used. */
  ctl=(RD_LE32(&BDT_CTL_TX(ep, 0)) & BDT_CTL_OWN)
      | (RD_LE32(&BDT_CTL_TX(ep, 1)) & BDT_CTL_OWN) << 1;

  switch(ctl)
  {
  case 0:  /* No buffer is used by the USB module. Fill the one
           we think is the next. */
    buf=ep_info[ep].next_tx;
    ep_info[ep].next_tx ^= 0x1;
    break;
  case BDT_CTL_OWN: /* Buffer 0 is used by the USB. */
    buf=1;
    ep_info[ep].next_tx=0;
    break;
  case BDT_CTL_OWN<<1: /* Buffer 1 is used by the USB. */
    buf=0;
    ep_info[ep].next_tx=1;
    break;
  default: /* Both buffers are used by the usb. This is
              an error. */
    CMX_ASSERT(0);
  }
  return(buf);
}

/*****************************************************************************
 * Name:
 *   usb_get_done
 * In:
 *   ep: number of endpoint.
 * Out:
 *   The number of bytes the endpoint tansferred.
 *
 * Description:
 *   Returns te number of bytes that were transferred.
 *****************************************************************************/
hcc_u32 usb_get_done(hcc_u8 ep)
{
  return(ep_info[ep].maxlength-ep_info[ep].tlength);
}

/*****************************************************************************
 * Name:
 *    usb_ep_is_busy
 * In:
 *   ep: number of endpoint.
 * Out:
 *   nonzero if endpoint is buys (a transfer is ongoing).
 *
 * Description:
 *
 *****************************************************************************/
hcc_u8 usb_ep_is_busy(hcc_u8 ep)
{
  return(ep_info[ep].state != EPST_IDLE ? (hcc_u8)1 : (hcc_u8)0);
}

/*****************************************************************************
 * Name:
 *    usb_get_state
 * In:
 *   N/A
 * Out:
 *   Current USB state. See USBST_xxx in usb.h
 *
 * Description:
 *
 *****************************************************************************/
hcc_u8 usb_get_state(void)
{
  return(usb_state);
}

/*****************************************************************************
 * Name:
 *    usb_ep_error
 * In:
 *   ep: number fo endpoint
 * Out:
 *   Endpoint specific error code. (See USBEPERR_xx macro definitions in usb.h)
 *
 * Description:
 *
 *****************************************************************************/
hcc_u8 usb_ep_error(hcc_u8 ep)
{
  hcc_u8 tmp=ep_info[ep].error;
  ep_info[ep].error=USBEPERR_NONE;
  return(tmp);
}

/*****************************************************************************
 * Name:
 *    send_zero_packet
 * In:
 *    N/A
 * Out:
 *    N/A
 *
 * Description:
 *    Will send a zero length data packet.
 *
 * Assumptions:
 *    ep is the index of a TX endpoint.
 *****************************************************************************/
static void send_zero_packet(hcc_u8 ep)
{
  hcc_u8 buf;

  buf=select_tx_buf(ep);
  /* Write packet length. */
  WR_LE32(&BDT_CTL_TX(ep, buf), 0);

  /* Make buffer ready for transmission. */
  ready_ep_tx(ep, buf);
}

/*****************************************************************************
 * Name:
 *    usb_init
 * In:
 *   None
 * Out:
 *   0  - if all ok
 *   !0 - if failed
 *
 * Description:
 *   Initialises the usb driver. Will set the interrupt level.
 *   Note: clock source is the system clock (48MHz).
 *****************************************************************************/
hcc_u8 usb_init(void)
{
  /* Reset USB module first. */
  USBTRC0_USBRESET = 1;
  while (USBTRC0_USBRESET) {};

  /* exit suspend and select USB clock source
   * If you program CLK_SRC bits as 2’b11 in the USB_CTRL register then MCGPLLSCK is connected to the USB 48 Mhz clock. 
   * If you program CLK_SRC bits to 2’b00 then the usb_alt_clk input pin to the chip is used as the USB 48 Mhz clock . This is the PTG0 pad. (Pin number 32 for 80LQFP) 
   * Plz ignore programmation 2’b01,2’b10 for CLK_SRC bit. They are reserved. 
   */
  MCF_USB_USB_CTRL = MCF_USB_USB_CTRL_CLKSRC_SYS;

  /* Disable all USB interrupts. */
  MCF_USB_INT_ENB = 0x0;
  /* Disable all OTG interupts. */
  MCF_USB_OTG_INT_EN = 0x0;
  /* Disable all USB error interrupts. */
  MCF_USB_ERR_ENB = 0x0;

  /* Put USB to default state. */
  enter_default_state();

  /* Clear any pending OTG interupts. */
  MCF_USB_OTG_INT_STAT = 0xff;
  /* Clear any pending USB interrupts.*/
  MCF_USB_INT_STAT = 0xff;
  /* Clear any pending USB error interrupt. */
  MCF_USB_ERR_STAT = 0xff;

  /* Enable USB interrupts. */
  MCF_USB_INT_ENB = MCF_USB_INT_ENB_SLEEP | MCF_USB_INT_ENB_TOK_DNE
                    | MCF_USB_INT_ENB_ERROR | MCF_USB_INT_ENB_USB_RST
                    | MCF_USB_INT_ENB_STALL;

  /* Set BDT address. */
  MCF_USB_BDT_PAGE_01 = (hcc_u8)(((hcc_u32)BDT_BASE) >> 8);
  MCF_USB_BDT_PAGE_02 = (hcc_u8)(((hcc_u32)BDT_BASE) >> 16);
  MCF_USB_BDT_PAGE_03 = (hcc_u8)(((hcc_u32)BDT_BASE) >> 24);
  
   
  /* Enable USB PHY before enabling USB module */
  //USBTRC0 =  USBTRC0_USBVREN_MASK;
  
  enable_usb_pull_up();
 
   /* Enable USB functionality*/
  MCF_USB_CTL = MCF_USB_CTL_USB_EN_SOF_EN;

  return(0);
}


/*****************************************************************************
 * Name:
 *    usb_stop
 * In:
 *   n/a
 * Out:
 *   n/a
 *
 * Description:
 *   Stops USB driver.
 *****************************************************************************/
void usb_stop(void)
{
  /* Disable all USB interrupts. */
  MCF_USB_INT_ENB = 0x0;
  /* Disable all OTG interupts. */
  MCF_USB_OTG_INT_EN = 0x0;
  /* Disable all USB error interrupts. */
  MCF_USB_ERR_ENB = 0x0;

  /* Clear any pending OTG interupts. */
  MCF_USB_OTG_INT_STAT = 0xff;
  /* Clear any pending USB interrupts.*/
  MCF_USB_INT_STAT = 0xff;
  /* Clear any pending USB error interrupt. */
  MCF_USB_ERR_STAT = 0xff;

  MCF_USB_USB_CTRL=0;
  /* Disable USB module. */
  MCF_USB_CTL = 0;

  enter_default_state();
  usb_setup_ep(0, EP_TYPE_DISABLE, 0, 0);
  usb_state=USBST_DISABLED;
}

/*****************************************************************************
 * Name:
 *    usb_setup_ep

⌨️ 快捷键说明

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