📄 pic_usb.h
字号:
/////////////////////////////////////////////////////////////////////////
//// pic_usb.c ////
//// ////
//// Microchip PIC16C765 Hardware layer for CCS's PIC USB driver. ////
//// ////
//// This file is part of CCS's PIC USB driver code, which includes: ////
//// usb_desc.h - an example set of config and device descriptors ////
//// usb.c - USB token and request handler code ////
//// usb.h - definitions, prototypes and global variables ////
//// ////
//// ex_usb_hid.c is an example that uses pic_usb.c to act as a USB ////
//// HID device. ex_usb_hid.c shows how to use either the pic_usb.c ////
//// hardware layer or usbn960x.c (National USBN960x hardware ////
//// driver) hardware layer. ////
//// ////
//// Another example is provided: ex_usb_scope.c, an example written ////
//// specifically for the USBN960x, shows how to use the CCS PIC USB ////
//// driver with the USBN960x. CCS provides a demo board with the ////
//// National USBN960x that is compatable with this code. ////
//// Natoinal's USBN960x is a full speed device that supports bulk ////
//// and isochronous mode transfers. The PIC16C765 is a slow speed ////
//// device that only supports control and interrupt transfers. ////
//// ////
//// ************************* NOTE ************************** ////
//// Need a pullup resistor (1.5K) connecting Vusb (C3) to D- (C4). ////
//// PIC16C765 will not work as a USB device without this pull-up ////
//// resistor. ////
//// ////
//// PIC16C765 must run at 24Mhz. You can use a 24Mhz ////
//// crystal / osc, or a 6Mhz crstal / osc if you use a 4x fuse ////
//// setting. Either way this PIC has a fixed operation speed of ////
//// 24 MHZ. ////
//// ////
//// ************************* NOTE ************************** ////
//// The PIC16C765 provides for 6 uni-directional endpoints, but ////
//// only provides enough RX/TX endpoint buffer space for 5 ////
//// un-directional endpoints. (provided that you use 8bytes ////
//// per max packet size per endpoint). Because of this this ////
//// driver does not enable Endpoint 2 TX (Host -> PIC). ////
//// If you need to change this, see usb_set_configured(). ////
//// ////
//// ************************* NOTE ************************** ////
//// This driver uses INT_USB. It requires INT_USB to interrupt the ////
//// PIC when an event has happened on the USB Bus. Therfore ////
//// this code enables interrupts. A user modification can be made ////
//// to poll the USB interrupt flag instead of relying on an ////
//// interrupt. ////
//// ////
//// ********************** FUNCTIONS *********************** ////
//// ////
//// usb_init() - Initializes the USB code and USBN960x device. ////
//// NOTE - this enables interrupts. ////
//// ////
//// usb_isr() - Call this if you choose to poll instead of ////
//// interrupt. READ THE COMMENTS AT USB_ISR() FIRST. ////
//// ////
//// usb_put_packet() - Sends one packet to the host. ////
//// If you need to send a message that spans ////
//// more than one packet then see usb_puts() in ////
//// usb.c ////
//// ////
//// For more documentation on these functions read the comments at ////
//// each function. ////
//// ////
//// The other functions defined in this file are for use by the ////
//// USB code, and is not meant to be used by the user. ////
//// ////
/////////////////////////////////////////////////////////////////////////
//// ////
//// Version History: ////
//// ////
//// June 20th, 2003: Minor cleanup ////
//// ////
//// October 28th, 2002: Fixed typos ////
//// ////
//// October 25th, 2002: Changed IN Endpoints to initialize to DATA1 ////
//// after device configuration ////
//// ////
//// September 12th, 2002: Fixed a problem with usb_put_packet() ////
//// not sending packets or sending packets ////
//// with all zeros. ////
//// ////
//// August 28th, 2002: Fixed a problem with data toggle sync when ////
//// sending data to PC (host). ////
//// ////
//// August 2nd, 2002: Initial Public Release ////
//// ////
/////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2002 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS ////
//// C compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, ////
//// reproduction or distribution is permitted without written ////
//// permission. Derivative programs created using this software ////
//// in object code form are not restricted in any way. ////
/////////////////////////////////////////////////////////////////////////
#IFNDEF __USB_HARDWARE__
#DEFINE __USB_HARDWARE__
#INCLUDE "usb.h"
#DEFINE __PIC__ 1
#DEFINE USB_PUT_DTS TRUE
#DEFINE USB_GET_DTS TRUE
#define ERROR_COUNTER_LEN 8
int ERROR_COUNTER[ERROR_COUNTER_LEN];
/// user settings
//error_ints are what goes into UEIE
#IFNDEF ERROR_INTS
#define ERROR_INTS 0xFF
#ENDIF
//standard ints is what goes into UIE, EXCEPT FOR ACTIVITY BIT
#IFNDEF STANDARD_INTS
#define STANDARD_INTS 0x3B
#ENDIF
//start of input/output buffer. 1b8-1df are reserved for usb, so lets use it
//microchip has 6 endpoints (3 bi-directional endpoints, 1 endpoint per direction) but only enough buffer space for 5
#IFNDEF USB_Buffer
#define USB_Buffer 0xB8 //actual address 0x1B8
#ENDIF
//number of bi-directional endpoints
#DEFINE USB_MAX_ENDPOINTS 3
//---pic16c7xx memory locations
#byte UIR = 0x190
#byte UIE = 0x191
#byte UEIR = 0x192
#byte UEIE = 0x193
#byte USTAT = 0x194
#byte UCTRL = 0x195
#byte UADDR = 0x196
#byte USWSTAT = 0x197
#define UEP0_LOC 0x198
#byte UEP0 = 0x198
#byte UEP1 = 0x199
#byte UEP2 = 0x19A
#byte BD0OST = 0x1A0
#byte BD0OBC = 0x1A1
#byte BD0OAL = 0x1A2
#byte BD1OST = 0x1A8
#byte BD1OBC = 0x1A9
#byte BD1OAL = 0x1AA
#byte BD2OST = 0x1B0
#byte BD2OBC = 0x1B1
#byte BD2OAL = 0x1B2
#byte BD0IST = 0x1A4
#byte BD0IBC = 0x1A5
#byte BD0IAL = 0x1A6
#byte BD1IST = 0x1AC
#byte BD1IBC = 0x1AD
#byte BD1IAL = 0x1AE
#byte BD2IST = 0x1B4
#byte BD2IBC = 0x1B5
#byte BD2IAL = 0x1B6
#byte INTCON = 0x0B
//---some important bits
#BIT USBIE = 0x8C.3
#BIT USBIF = 0x0C.3
#BIT UIR_TOK_DNE = 0x190.3
#BIT UIR_USB_RST = 0x190.0
//---interrupt flag possibilites
#define USB_RST 0x01
#define UERR 0x02
#define ACTIVITY 0x04
#define TOK_DNE 0x08
#define UIDLE 0x10
#define STALL 0x20
//See UEPn (0x198-0x19A)
#define ENDPT_DISABLED 0x00 //endpoint not used
#define ENDPT_IN_ONLY 0x02 //endpoint supports IN transactions only
#define ENDPT_OUT_ONLY 0x04 //endpoint supports OUT transactions only
#define ENDPT_CONTROL 0x06 //Supports IN, OUT and CONTROL transactions - Only use with EP0
#define ENDPT_NON_CONTROL 0x0E //Supports both IN and OUT transactions
//Define the states that the USB interface can be in
//See USWST (0x197)
#define POWERED_STATE 0x00
#define DEFAULT_STATE 0x01
#define ADDRESS_STATE 0x02
#define CONFIG_STATE 0x03
//global variables that we need.
int8 usb_ustat; //save the USTAT register because the fifo buffer will munch it
int1 IS_IDLE;
//we can't read individual enpdoint stall status, so we must save it our selves
int8 USB_endpoint_in_stalled[USB_MAX_ENDPOINTS];
int8 USB_endpoint_out_stalled[USB_MAX_ENDPOINTS];
//interrupt handler, specific to PIC16C765 peripheral only
void usb_isr();
void usb_isr_rst();
void usb_isr_uerr();
void usb_isr_activity();
void usb_isr_stall();
void usb_isr_uidle();
void usb_isr_tok_dne();
//following functions standard part of CCS PIC USB driver, and used by usb.c
void usb_init();
int1 usb_put_packet(int endpoint, int * ptr, int len, PID_TOGGLE tgl);
int8 usb_get_packet(int8 endpoint, int8 ptr, int8 max);
void usb_stall_ep(int8 endpoint, int1 direction);
void usb_unstall_ep(int8 endpoint, int1 direction);
int1 usb_endpoint_stalled(int8 endpoint, int1 direction);
void usb_set_address(int8 address);
void usb_set_configured(int config);
void usb_wrongstate();
//// BEGIN User Functions:
/*******************************************************************************
/* usb_init()
/*
/* Summary: Resets and initalizes USB code and USB peripheral. You must call this
/* first before using code.
/*
/* If you have debug enabled it will enable TBE interrupts on the PIC.
/*
/* NOTE: this enables interrupts.
/*
/********************************************************************************/
void usb_init() {
USWSTAT=0; //default to powered state
UIE=1; //mask all interrupts except reset
UADDR=0; //we start at address 0
UCTRL=8; //device attached
usb_token_reset();
enable_interrupts(int_usb);
enable_interrupts(global);
#IF USB_DO_DEBUG
enable_interrupts(INT_TBE);
#ENDIF
}
/*******************************************************************************
/* usb_put_packet(endpoint,*ptr,len,toggle)
/*
/* Input: endpoint - endpoint to send packet to
/* ptr - points to data to send
/* len - amount of data to send
/* toggle - whether to send data with a DATA0 pid, a DATA1 pid, or toggle from the last DATAx pid.
/*
/* Output: TRUE if data was sent correctly, FALSE if it was not. The only reason it will
/* return FALSE is if because the TX buffer is still full from the last time you
/* tried to send a packet.
/*
/* Summary: Sends one packet out the EP to the host. Notice that there is a difference
/* between a packet and a message. If you wanted to send a 512 byte message you
/* would accomplish this by sending 8 64-byte packets, followed by a 0 length packet.
/* If the last (or only packet) being sent is less than the max packet size defined
/* in your descriptor then you do not need to send a 0 length packet to identify
/* an end of message.
/*
/* usb_puts() (provided in usb.c) will send a multi-packet message correctly.
/*
/********************************************************************************/
int1 usb_put_packet(int8 endpoint, int8 * ptr, int8 len, PID_TOGGLE tgl) {
int8 i;
int8 * add=0x1A4; //BD0IST - EP0 IN (out of PIC) Status
int8 * buff_add;
debug(debug_txb,"\r\nTX %X %X: ",endpoint,len);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -