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

📄 usb.c

📁 PIC Kit serial source code.
💻 C
📖 第 1 页 / 共 2 页
字号:
//==================================================================== 
//--- COPYRIGHT
//==================================================================== 
// Copyright 2006 Microchip Technology Inc.
// 
// Microchip Technology Inc. ("Microchip") licenses this software to
// you solely for use with Microchip products. The software is owned
// by Microchip and is protected under applicable copyright laws. All
// rights reserved.
// 
// SOFTWARE IS PROVIDED IN AN "AS IS." MICROCHIP EXPRESSLY DISCLAIMS ANY
// WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL MICROCHIP
// BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
// DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
// PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
// BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
// ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
// 
//==================================================================== 
//--- TITLE
//==================================================================== 
//    Filename:            usb.c
//    Microcontroller:     PIC18F2550
//    Compiled using:      C18 V3.00
//
//    Author:              Mark Enochson
//    Company:             Microchip Technology Inc.
//
//==================================================================== 
//--- DESCRIPTION
//==================================================================== 
//
//==================================================================== 
//--- HISTORY
//==================================================================== 
//
//    12-05-07 - ME
//    -- added UCONbits.PKTDIS=0; to EP0,OUT,SETUP per errata
//
//    0001 - 08-01-06 - ME
//    - initial release
//
//==================================================================== 
#include "project.h"
#include "usb.h"
#include "usb_data_constants.h"
#ifdef __DEBUG_TRACE
#include "cbuf.h"
#endif

#pragma udata

//==========================================================
//--- DATA
//==========================================================
TD_BYTE     usb_state;
TD_BYTE     usb_addr;
TD_BYTE_B   usb_flags_B;
TD_BYTE     usb_config;

//--- LOCAL
TD_POINTER usb_src_p;
TD_POINTER usb_dst_p;
TD_BYTE usb_count;
TD_BYTE usb_count_temp;

//--- USB BUFFER DESCRIPTOR TABLE
#pragma udata usb4ram = 0x400
volatile far BDT usb_bdt_ep0_out;    // endpoint: 0, dir: out
volatile far BDT usb_bdt_ep0_in;     // endpoint: 0, dir: in
volatile far BDT usb_bdt_ep1_out;    // endpoint: 1, dir: out
volatile far BDT usb_bdt_ep1_in;     // endpoint: 1, dir: in

//--- USB BUFFERS
#pragma udata usb5ram = 0x500
volatile far USB_BUF_CONTROL usb_buf_ep0_out;
volatile far USB_BUF_CONTROL usb_buf_ep0_in;
volatile far TD_BYTE usb_buf_ep1_out[USB_EP1_SIZE_MAX];
volatile far TD_BYTE usb_buf_ep1_in[USB_EP1_SIZE_MAX];

//----------------------------------------------------------
//--- post "trace" messages to circular buffer: CBUF1
//----------------------------------------------------------

#pragma code _usb_ep0

//==========================================================
//=== UTILITIES
//==========================================================

//================================================
//--- usb_detach_soft()
//
//    overview:
//    execute "soft" detach
//================================================
void usb_detach_soft(void)
{
   usb_module_disable();
}

//================================================
//--- usb_module_disable()
//
//    overview:
//    disable USB control hardware
//================================================
void usb_module_disable(void)
{
   UCON = 0;                  //
   UIE = 0;
   usb_state = USB_STATE_DETACHED;
}

//================================================
//--- usb_init()
//
//    overview:
//    configure/enable USB controller
//    called once from "main"
//================================================
void usb_init(void)
{
   UCONbits.USBEN = 0;        // disable USB
   UCFGbits.UPUEN = 1;        // enable pullups
   UCFGbits.FSEN = 1;         // enable full speed
   UEP0 = _EPHSHK | _EPOUTEN | _EPINEN;
   UEP1 = _EPHSHK | _EPOUTEN | _EPINEN | _EPCONDIS;
   usb_bdt_load();            // load buffer descriptors
   UCONbits.USBEN = 1;        // enable USB
   usb_state = USB_STATE_ATTACHED;
}

//================================================
//--- usb_reset()
//    
//    overview:
//    executed as a result of 
//    USB "RESET" transaction
//================================================
void usb_reset(void)
{
#ifdef __DEBUG_TRACE
   cbuf1_put(0xF5);
#endif
   UIRbits.TRNIF = 0;
   UIRbits.TRNIF = 0;
   UIRbits.TRNIF = 0;
   UIRbits.TRNIF = 0;
   UADDR = 0;
   usb_flags_B._b = 0;
   usb_state = 0;
   usb_bdt_load();
}

//================================================
//--- usb_bdt_load()
//
//    overview:
//    load buffer descriptor table
//    with default values
//================================================
void usb_bdt_load(void)
{
   usb_bdt_ep0_out.status._b  = _BDS_UOWN;
   usb_bdt_ep0_out.count      = USB_EP0_SIZE_MAX;
   usb_bdt_ep0_out.addr       = (TD_BYTE *)&usb_buf_ep0_out;
   usb_bdt_ep0_in.status._b  = 0;
   usb_bdt_ep0_in.count      = USB_EP0_SIZE_MAX;
   usb_bdt_ep0_in.addr       = (TD_BYTE *)&usb_buf_ep0_in;

   usb_bdt_ep1_out.status._b  = _BDS_UOWN;
   usb_bdt_ep1_out.count      = USB_EP1_SIZE_MAX;
   usb_bdt_ep1_out.addr       = usb_buf_ep1_out;
   usb_bdt_ep1_in.status._b  = _BDS_DTS;
   usb_bdt_ep1_in.count      = USB_EP1_SIZE_MAX;
   usb_bdt_ep1_in.addr       = usb_buf_ep1_in;
}

//================================================
//--- usb_isr()
//
//    overview:
//    called from USB interrupt
//    -or-
//    called from main idle loop
//
//    react to interrupt flags
//================================================
void usb_isr(void)
{
   if(not UIR)    // if no flags, return/exit
      return;

   if((UIRbits.SOFIF)&&(UIEbits.SOFIE))
      UIRbits.SOFIF = 0;
   if((UIRbits.IDLEIF)&&(UIEbits.IDLEIE))
      UIRbits.IDLEIF = 0;
   if((UIRbits.ACTVIF)&&(UIEbits.ACTVIE))
      UIRbits.ACTVIF = 0;
   if((UIRbits.UERRIF)&&(UIEbits.UERRIE))
      UIRbits.UERRIF = 0;
   if((UIRbits.STALLIF)&&(UIEbits.STALLIE))
      UIRbits.STALLIF = 0;
   if((UIRbits.URSTIF)&&(UIEbits.URSTIE))
      UIRbits.URSTIF = 0;
   if((UIRbits.TRNIF)&&(UIEbits.TRNIE))
   {
      UIRbits.TRNIF = 0;
   } 
   if(UEIR)
   {
      // count errors
   } 
}

//================================================
//--- usb_svc()
//
//    overview:
//    called from caller's idle loop
//    reacts to interrupt flags
//================================================
void usb_svc(void)
{
   //--- 
   if(UIRbits.SOFIF)
   {
      UIRbits.SOFIF = 0;
   }

   //--- 
   if(UIRbits.IDLEIF)
   {
      UIRbits.IDLEIF = 0;
   }

   //--- 
   if(UIRbits.ACTVIF)
   {
      UIRbits.ACTVIF = 0;
   }

   //--- 
   if(UIRbits.UERRIF)
   {
      UIRbits.UERRIF = 0;
   }

   //--- 
   if(UIRbits.STALLIF)
   {
      UIRbits.STALLIF = 0;
   }
   
   //--- 
   if(UIRbits.URSTIF)
   {
      usb_reset();
      UIRbits.URSTIF = 0;
   }

   //--- 
   if(UIRbits.TRNIF)
   {
      usb_trn();
      UIRbits.TRNIF = 0;
   } 

   //--- 
   if(UEIR)
   {
      // count errors
   } 
   
   //---
   usb_ep1_check();
}

//==========================================================
//=== TRANSACTION PROCESSING
//==========================================================

//================================================
//--- usb_trn()
//
//    overview:
//    process USB transaction interrupt
//================================================
void usb_trn(void)
{
#ifdef __DEBUG_TRACE
   cbuf1_put(0xF0);
   //cbuf1_put(USTAT);
#endif

   //-------------------------
   //--- EP0, OUT
   //-------------------------
   if(USTAT == (_USTAT_EP00 | _USTAT_OUT))
   {

#ifdef __DEBUG_TRACE
      cbuf1_put(0xF3);
      cbuf1_put(usb_bdt_ep0_out.status._b);
#endif

      //--- EP0, OUT, SETUP
      if(usb_bdt_ep0_out.status.pid == _PID_SETUP)
      {
         UCONbits.PKTDIS = 0;
         usb_trn_setup();
      }

      //--- EP0, OUT
      else
         usb_trn_control_out();
      usb_ep0_out_finish();
   }

   //-------------------------
   //--- EP0, IN
   //-------------------------
   else if(USTAT == (_USTAT_EP00 | _USTAT_IN))
      usb_trn_control_in();
}

//================================================
//--- usb_trn_control_out()
//
//    overview:
//    process control "OUTPUT" transactions
//================================================
void usb_trn_control_out(void)
{
#ifdef __DEBUG_TRACE
   cbuf1_put(0xF2);
   cbuf1_put(usb_bdt_ep0_out.count);
#endif
}

//================================================
//--- usb_trn_control_in()
//
//    overview:
//    process control "INPUT" transactions
//================================================
void usb_trn_control_in(void)
{

#ifdef __DEBUG_TRACE
   cbuf1_put(0xF4);
   cbuf1_put(usb_bdt_ep0_in.count);
#endif

   if(usb_bdt_ep0_in.count == 0)
   {
      if(USB_ADDR_1_FLAG)
      {
         USB_ADDR_1_FLAG = 0;
         UADDR = usb_addr;
         usb_state = USB_STATE_ADDRESS;
      }
      USB_IN_BUSY_FLAG = 0;
   }
   else
   {
      if(USB_IN_BUSY_FLAG && usb_count)
         usb_ep0_load_flash();
   }
}

//================================================
//--- usb_trn_setup()
//
//    overview:
//    process "SETUP" transactions
//================================================
void usb_trn_setup(void)
{
   
#ifdef __DEBUG_TRACE
   cbuf1_put(0xF1);
   cbuf1_put(usb_buf_ep0_out.rq_type);
   cbuf1_put(usb_buf_ep0_out.request);
   cbuf1_put(usb_buf_ep0_out.length_W._b0);
#endif

   if((usb_buf_ep0_out.rq_type & _RQTYPE_TR_MASK) == _RQTYPE_TR_STD_DEV)
      usb_trn_setup_std_dev();
   else if((usb_buf_ep0_out.rq_type & _RQTYPE_TR_MASK) == _RQTYPE_TR_STD_INTF)
      usb_trn_setup_std_intf();
   else if((usb_buf_ep0_out.rq_type & _RQTYPE_TR_MASK) == _RQTYPE_TR_CLASS_INTF)
      usb_trn_setup_class_intf();
   else
      usb_ep0_trn_unsupported();
}

//================================================
//--- usb_trn_setup_std_dev()
//
//    overview:
//    process "SETUP" transactions for STD, DEV

⌨️ 快捷键说明

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