// see pic18_usb.h for documentation void usb_flush_out(int8 endpoint, USB_DTS_BIT tgl) { unsigned int8 i; unsigned int16 len; #if USB_IGNORE_RX_DTS if (tgl == USB_DTS_STALL) { debug_usb(debug_putc, '*'); EP_BDxCNT_O(endpoint) = 0x84; EP_BDxST_I(endpoint) = 0x84; return; } else i=0x80; #else i = EP_BDxST_O(endpoint); if (tgl == USB_DTS_TOGGLE) { if (bit_test(i,6)) tgl = USB_DTS_DATA0; //was DATA1, goto DATA0 else tgl = USB_DTS_DATA1; //was DATA0, goto DATA1 } if (tgl == USB_DTS_STALL) { i = 0x84; EP_BDxST_I(endpoint) = 0x84; //stall both in and out endpoints } else if (tgl == USB_DTS_DATA1) i = 0xC8; //DATA1, UOWN else //if (tgl == USB_DTS_DATA0) i = 0x88; //DATA0, UOWN #endif //bit_clear(__usb_kbhit_status,endpoint); len = usb_ep_rx_size[endpoint]; EP_BDxCNT_O(endpoint) = len; if (bit_test(len,8)) {bit_set(i,0);} if (bit_test(len,9)) {bit_set(i,1);} EP_BDxST_O(endpoint) = i; }
// see usb_hw_layer.h for documentation void usb_set_configured(int8 config) { int8 en; int16 addy; int8 new_uep; int16 len; int8 i; /*if (config == 0) { // if config=0 then set addressed state usb_state = USB_STATE_ADDRESS; usb_disable_endpoints(); } else */ { // else set configed state usb_state = USB_STATE_CONFIGURED; addy = (int16)USB_DATA_BUFFER_LOCATION+(2*USB_MAX_EP0_PACKET_LENGTH); for (en=1; en<USB_NUM_UEP; en++) { // enable and config endpoints based upon user configuration usb_disable_endpoint(en); new_uep = 0; if (usb_ep_rx_type[en] != USB_ENABLE_DISABLED) { new_uep = 0x04; len = usb_ep_rx_size[en]; EP_BDxCNT_O(en) = len; EP_BDxADR_O(en) = addy; addy += usb_ep_rx_size[en]; #if USB_IGNORE_RX_DTS i = 0x80; #else i = 0x88; #endif if (bit_test(len,8)) {bit_set(i,0);} if (bit_test(len,9)) {bit_set(i,1);} EP_BDxST_O(en) = i; } if (usb_ep_tx_type[en] != USB_ENABLE_DISABLED) { new_uep |= 0x02; EP_BDxADR_I(en) = addy; addy += usb_ep_tx_size[en]; EP_BDxST_I(en) = 0x40; } if (new_uep == 0x06) {new_uep = 0x0E;} if (usb_ep_tx_type[en] != USB_ENABLE_ISOCHRONOUS) {new_uep |= 0x10;} UEP(en) = new_uep; } } }
void usb_init_ep0_setup(void) { EP_BDxCNT_O(0) = USB_MAX_EP0_PACKET_LENGTH; EP_BDxADR_O(0) = USB_DATA_BUFFER_LOCATION; #if USB_IGNORE_RX_DTS EP_BDxST_O(0) = 0x80; //give control to SIE, data toggle synch off #else EP_BDxST_O(0) = 0x88; //give control to SIE, DATA0, data toggle synch on #endif EP_BDxST_I(0) = 0; EP_BDxADR_I(0) = USB_DATA_BUFFER_LOCATION + (int16)USB_MAX_EP0_PACKET_LENGTH; }
static int16 usb_get_packet_buffer(int8 endpoint, int8 *ptr, int16 max) { int8 * al; int8 st; int16 i; al = EP_BDxADR_O(endpoint); i = EP_BDxCNT_O(endpoint); st = EP_BDxST_O(endpoint); //read BC8 and BC9 if (bit_test(st,0)) {bit_set(i,8);} if (bit_test(st,1)) {bit_set(i,9);} if (i < max) {max = i;} memcpy(ptr, al ,max); return(max); }
// see pic18_usb.h for documentation int16 usb_rx_packet_size(int8 endpoint) { return(EP_BDxCNT_O(endpoint)); }
void usb_isr_tok_dne(void) { unsigned int8 en; en = USTATCopy>>3; debug_usb(debug_putc, "T "); debug_usb(debug_putc, "%X ", USTATCopy); if (USTATCopy == USTAT_OUT_SETUP_E0) { //new out or setup token in the buffer int8 pidKey; debug_usb(debug_putc,"%X ", EP_BDxST_O(0)); pidKey = EP_BDxST_O(0) & 0x3C; //save PID EP_BDxST_O(0) &= 0x43; //clear pid, prevent bdstal/pid confusion if (pidKey == USB_PIC_PID_SETUP) { if ((EP_BDxST_I(0) & 0x80) != 0x00) EP_BDxST_I(0)=0; // return the in buffer to us (dequeue any pending requests) debug_usb(debug_putc,"(%U) ", EP_BDxCNT_O(0)); debug_display_ram(EP_BDxCNT_O(0), usb_ep0_rx_buffer); usb_isr_tok_setup_dne(); UCON_PKTDIS=0; // UCON,PKT_DIS ; Assuming there is nothing to dequeue, clear the packet disable bit //if setup_0_tx_size==0xFF - stall ep0 (unhandled request) (see usb_request_stall()) //if setup_0_tx_size==0xFE - get EP0OUT ready for a data packet, leave EP0IN alone (see usb_request_get_data()) //else setup_0_tx_size=size of response, get EP0OUT ready for a setup packet, mark EPOIN ready for transmit (see usb_request_send_response()) if (__setup_0_tx_size == 0xFF) usb_flush_out(0, USB_DTS_STALL); else { usb_flush_out(0, USB_DTS_TOGGLE); if (__setup_0_tx_size != 0xFE) usb_flush_in(0 ,__setup_0_tx_size, USB_DTS_USERX); } //why was this here? //UCON_PKTDIS=0; // UCON,PKT_DIS ; Assuming there is nothing to dequeue, clear the packet disable bit } else if (pidKey == USB_PIC_PID_OUT) { usb_isr_tok_out_dne(0); usb_flush_out(0, USB_DTS_TOGGLE); if ((__setup_0_tx_size!=0xFE) && (__setup_0_tx_size!=0xFF)) { usb_flush_in(0,__setup_0_tx_size,USB_DTS_DATA1); //send response (usually a 0len) } } else { debug_usb(debug_putc, "!!! "); } } else if (USTATCopy == USTAT_IN_E0) { //pic -> host transfer completed //EP_BDxST_I(0) = EP_BDxST_I(0) & 0xC3; //clear up any BDSTAL confusion __setup_0_tx_size = 0xFF; usb_isr_tok_in_dne(0); if (__setup_0_tx_size!=0xFF) usb_flush_in(0, __setup_0_tx_size, USB_DTS_TOGGLE); else { //usb_init_ep0_setup(); //REMOVED JUN/9/2009 } } else { if (!bit_test(USTATCopy, 2)) { //EP_BDxST_O(en) = EP_BDxST_O(en) & 0xC3; //clear up any BDSTAL confusion usb_isr_tok_out_dne(en); } else { //EP_BDxST_I(en) = EP_BDxST_I(en) & 0xC3; //clear up any BDSTAL confusion usb_isr_tok_in_dne(en); } } }