📄 pic_usb.h
字号:
#ELSE
BD1OST = 0x80; //set own
#ENDIF
BD1OAL=USB_Buffer+0x10;
BD1OBC=8;
#IF USB_PUT_DTS
BD1IST = 0x48; //set dts bit
#ELSE
BD1IST = 0x40;
#ENDIF
BD1IAL=USB_Buffer+0x18;
#IF USB_GET_DTS
BD2OST = 0x88; //set own and dts bit
#ELSE
BD2OST = 0x80; //set own
#ENDIF
BD2OAL=USB_Buffer+0x20;
BD2OBC=8;
/* //THERE IS NOT ENOUGH BUFFER RAM TO USE THIS ENPDOINT
BD2IST=0x08; //clear owns bit (PIC can write)
BD2IST=USB_Buffer+0x28;
*/
// Set up the Endpoint Control Registers. The following patterns are defined
// ENDPT_DISABLED - endpoint not used
// ENDPT_IN_ONLY - endpoint supports IN transactions only
// ENDPT_OUT_ONLY - endpoint supports OUT transactions only
// ENDPT_CONTROL - Supports IN, OUT and CONTROL transactions - Only use with EP0
// ENDPT_NON_CONTROL - Supports both IN and OUT transactions
UEP1=ENDPT_NON_CONTROL;
UEP2=ENDPT_OUT_ONLY;
}
/*******************************************************************************
/* usb_wrongstate()
/*
/* Summary: Tells the host that they asked us to do something (either illegal or something
/* we don't support) by stalling EP0. When the host gets the idea it will
/* either reset the device or un-stall EP0.
/*
/********************************************************************************/
void usb_wrongstate() {
bit_set(UEP0,0);
}
/// END Hardware layer functions required by USB.C
/// BEGIN USB Interrupt Service Routine
/*******************************************************************************
/* usb_isr()
/*
/* Summary: Checks the interrupt, and acts upon event. Processing finished
/* tokens is the majority of this code, and is handled by usb.c
/*
/********************************************************************************/
#int_usb
void usb_isr() {
int1 notdone=1;
int interrupts;
do {
interrupts=UIE & UIR;
debug(debug_txb,"\r\nI %X: ", interrupts);
if (interrupts & USB_RST) {usb_isr_rst(); bit_clear(UIR,0);} //usb reset has been detected
else if (interrupts & UERR) {usb_isr_uerr(); bit_clear(UIR,1);} //error has been detected
else if (interrupts & ACTIVITY) {usb_isr_activity(); bit_clear(UIR,2);} //activity detected. (only enable after sleep)
else if (interrupts & UIDLE) {usb_isr_uidle(); bit_clear(UIR,4);} //idle time, we can go to sleep
else if (interrupts & TOK_DNE) {usb_isr_tok_dne(); bit_clear(UIR,3);} //a token has been detected (majority of isrs)
else if (interrupts & STALL) {usb_isr_stall(); bit_clear(UIR,7);} //a stall handshake was sent
else {notdone=0;}
} while (notdone);
USBIF=0;
UIR=0;
}
/*******************************************************************************
/* usb_isr_rst()
/*
/* Summary: The host (computer) sent us a RESET command. Reset USB device
/* and token handler code to initial state.
/*
/********************************************************************************/
void usb_isr_rst() {
int8 * add=0x100;
int i;
debug(debug_txb,"R ");
usb_token_reset();
IS_IDLE=0;
for (i=0;i<USB_MAX_ENDPOINTS;i++) {
USB_endpoint_in_stalled[i]=0;
USB_endpoint_out_stalled[i]=0;
}
UIR_TOK_DNE=0; //do this 4 times to clear out the ustat fifo
UIR_TOK_DNE=0;
UIR_TOK_DNE=0;
UIR_TOK_DNE=0;
#IF USB_GET_DTS
BD0OST = 0x88; //set own and dts bit
#ELSE
BD0OST = 0x80; //set own
#ENDIF
BD0OAL=USB_Buffer; //Endpoint 0 OUT gets a buffer, set up buffer address
BD0OBC=USB_MAX_EP0_PACKET_LENGTH; //set byte count
#IF USB_PUT_DTS
BD0IST = 0x08; //set dts bit
#ELSE
BD0IST = 0x00;
#ENDIF
BD0IAL=USB_Buffer+8;
add+=USB_Buffer;
for (i=0;i<40;i++) {
*add=0;
add++;
}
UADDR=0; //set USB Address to 0
UIR_USB_RST=0; //clear reset flag
UEP0=ENDPT_CONTROL; //endpoint 0 is a control pipe and requires an ACK
UEP1=ENDPT_DISABLED; //turn on endpoint 1 is an IN/OUT pipe.
UEP2=ENDPT_DISABLED;
UIE=STANDARD_INTS; //enable all interrupts except activity
UEIE=ERROR_INTS; //enable all error interrupts
USWSTAT=(USWSTAT & 0xFC) | DEFAULT_STATE; //put usb mcu into default state, but keep top 6 bits
}
/*******************************************************************************
/* usb_isr_uerr()
/*
/* Summary: The USB peripheral had an error. If user specified, error counter
/* will incerement. I having problems check the status of these 8 bytes.
/*
/********************************************************************************/
void usb_isr_uerr() {
int ints;
debug(debug_txb,"E ");
#IFDEF ERROR_COUNTER_LEN
ints=UEIR & UEIE; //mask off the flags with the ones that are enabled
if ( bit_test(ints,0) ) {ERROR_COUNTER[0]++;} //increment pid_error counter
if ( bit_test(ints,1) ) {ERROR_COUNTER[1]++;} //increment crc5 error counter
if ( bit_test(ints,2) ) {ERROR_COUNTER[2]++;} //increment crc16 error counter
if ( bit_test(ints,3) ) {ERROR_COUNTER[3]++;} //increment dfn8 error counter
if ( bit_test(ints,4) ) {ERROR_COUNTER[4]++;} //increment bto error counter
if ( bit_test(ints,5) ) {ERROR_COUNTER[5]++;} //increment wrt error counter
if ( bit_test(ints,6) ) {ERROR_COUNTER[6]++;} //increment own error counter
if ( bit_test(ints,7) ) {ERROR_COUNTER[7]++;} //increment bts error counter
#ENDIF
UEIR=0; //clear flags
bit_clear(UIR,1); //clear UIR.UERR
}
/*******************************************************************************
/* usb_isr_uidle()
/*
/* Summary: USB peripheral detected IDLE. Put the USB peripheral to sleep.
/*
/********************************************************************************/
void usb_isr_uidle() {
debug(debug_txb,"I ");
bit_clear(UIR,4); //uidle
bit_set(UCTRL,1); //set suspend. we are now suspended
bit_clear(UIR,2); //clear activity interept flag
bit_set(UIE,2); //enable activity interrupt flag. (we are now suspended until we get an activity interrupt. nice)
IS_IDLE=1;
}
/*******************************************************************************
/* usb_isr_activity()
/*
/* Summary: USB peripheral detected activity on the USB device. Wake-up the USB
/* peripheral.
/*
/********************************************************************************/
void usb_isr_activity() {
debug(debug_txb,"A ");
bit_clear(UIR,2); //clear activity flag
bit_clear(UIE,2); //clear activity interupt enabling
bit_clear(UCTRL,1); //turn off low power suspending
bit_clear(UIR,4); //clear idle flag
bit_set(UIE,4); //turn on idle interrupts
IS_IDLE=0;
}
/*******************************************************************************
/* usb_isr_stall()
/*
/* Summary: Stall handshake detected.
/*
/********************************************************************************/
void usb_isr_stall() {
debug(debug_txb,"S ");
bit_clear(UIR,5); //stall
}
/*******************************************************************************
/* usb_isr_tok_dne()
/*
/* Summary: A Token (IN/OUT/SETUP) has been received by the USB peripheral.
/* Information about token is received, and sent to usb.c's token handling
/* code.
/*
/********************************************************************************/
void usb_isr_tok_dne() {
int8 i,PIDs, BD_count, BD_loc, BD_status, endpoint;
int8 * uep;
int8 * bd;
usb_ustat=USTAT; // copy USTAT register before..., 0x194
while (UIR_TOK_DNE) {
uep=0x1A0;
UIR_TOK_DNE=0; // clearing the token done interrupt., 0x190.3
// if next ustat fifo is valid then this will auto be reset to 1
uep+=usb_ustat;
BD_status=*uep; uep++;
BD_count=*uep; uep++;
BD_loc=*uep;
PIDs=BD_status & 0x3C;
PIDs=PIDs >> 2;
bd=BD_loc+0x100;
endpoint=(usb_ustat & 0x18) >> 3;
if (PIDs==PID_IN) {usb_isr_tok_in_dne(endpoint); debug(debug_txb,"TX ");} //pic -> host transfer completed
else if (PIDs==PID_OUT) {usb_isr_tok_out_dne(endpoint); debug(debug_txb,"RX ");} //host -> pic transfer completed
else if (PIDs==PID_SETUP) { //new setup token in the buffer
debug(debug_txb,"RX S ");
for(i=0;i<BD_count;i++) {
debug("%X ",*bd);
usb_ep0_rx_buffer[i]=*bd;
bd++;
}
#IF USB_GET_DTS
BD0OST=0x88; // set UOWNs bit back to SIE
#ELSE
BD0OST=0x80; // set UOWNs bit back to SIE
#ENDIF
BD0OBC=USB_MAX_EP0_PACKET_LENGTH; // reset the byte count too.
#IF USB_PUT_DTS
BD0IST=0x08; // return the in buffer to us (dequeue any pending requests)
#ELSE
BD0IST=0x00;
#ENDIF
usb_isr_tok_setup_dne();
bit_clear(UCTRL,4); // UCTRL,PKT_DIS ; Assuming there is nothing to dequeue, clear the packet disable bit
}
USB_USTAT=USTAT; // get next ustat, if there is one
}
}
/// END USB Interrupt Service Routine
#ENDIF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -