// see pic18_usb.h for documentation int1 usb_flush_in(int8 endpoint, int16 len, USB_DTS_BIT tgl) { unsigned int8 i; debug_usb(debug_putc,"\r\nPUT %X %U %LU",endpoint, tgl, len); if (usb_tbe(endpoint)) { EP_BDxCNT_I(endpoint)=len; debug_display_ram(len, EP_BDxADR_I(endpoint)); #if USB_IGNORE_TX_DTS i=0x80; #else if (tgl == USB_DTS_TOGGLE) { i = EP_BDxST_I(endpoint); if (bit_test(i,6)) tgl = USB_DTS_DATA0; //was DATA1, goto DATA0 else tgl = USB_DTS_DATA1; //was DATA0, goto DATA1 } else if (tgl == USB_DTS_USERX) { i = EP_BDxST_O(endpoint); if (bit_test(i,6)) tgl = USB_DTS_DATA1; else tgl = USB_DTS_DATA0; } if (tgl == USB_DTS_DATA1) i=0xC8; //DATA1, UOWN else //if (tgl == USB_DTS_DATA0) i=0x88; //DATA0, UOWN #endif //set BC8 and BC9 if (bit_test(len,8)) {bit_set(i,0);} if (bit_test(len,9)) {bit_set(i,1);} debug_usb(debug_putc, " %X", i); EP_BDxST_I(endpoint) = i;//save changes //putc('!'); return(1); } else { //putc('_'); debug_usb(debug_putc,"\r\nPUT ERR"); } return(0); }
// see pic18_usb.h for documentation int1 usb_flush_in(int8 endpoint, int16 len, USB_DTS_BIT tgl) { int8 i; if (usb_tbe(endpoint)) { EP_BDxCNT_I(endpoint)=len; #if USB_IGNORE_TX_DTS i=0x80; #else if (tgl == USB_DTS_TOGGLE) { i = EP_BDxST_I(endpoint); if (bit_test(i,6)) tgl = USB_DTS_DATA0; //was DATA1, goto DATA0 else tgl = USB_DTS_DATA1; //was DATA0, goto DATA1 } else if (tgl == USB_DTS_USERX) { i = EP_BDxST_O(endpoint); if (bit_test(i,6)) tgl = USB_DTS_DATA1; else tgl = USB_DTS_DATA0; } if (tgl == USB_DTS_DATA1) i=0xC8; //DATA1, UOWN else //if (tgl == USB_DTS_DATA0) i=0x88; //DATA0, UOWN #endif //set BC8 and BC9 if (bit_test(len,8)) {bit_set(i,0);} if (bit_test(len,9)) {bit_set(i,1);} EP_BDxST_I(endpoint) = i;//save changes //putc('!'); return(1); } return(0); }
// 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_disable_endpoint(int8 en) { UEP(en) = ENDPT_DISABLED; if (usb_endpoint_is_valid(en)) { EP_BDxST_O(en) = 0; //clear state, deque if necessary EP_BDxST_I(en) = 0; //clear state, deque if necessary } }
// 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; } } }
// see usb_hw_layer.h for documentation void usb_unstall_ep(int8 endpoint) { int1 direction; direction = bit_test(endpoint,7); endpoint &= 0x7F; if (direction) { #if USB_IGNORE_RX_DTS EP_BDxST_I(endpoint) = 0x80; #else EP_BDxST_I(endpoint) = 0x88; #endif } else { EP_BDxST_O(endpoint) = 0x00; } }
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; }
// see usb_hw_layer.h for documentation void usb_stall_ep(int8 endpoint) { int1 direction; direction = bit_test(endpoint,7); endpoint &= 0x7F; if (direction) { EP_BDxST_I(endpoint) = 0x84; } else { EP_BDxST_O(endpoint) = 0x84; } }
// see usb_hw_layer.h for documentation int1 usb_endpoint_stalled(int8 endpoint) { int1 direction; int8 st; direction = bit_test(endpoint,7); endpoint &= 0x7F; if (direction) { st=EP_BDxST_I(endpoint); } else { st=EP_BDxST_O(endpoint); } return(bit_test(st,7) && bit_test(st,2)); }
void main() { // mod, added to patch config bits patch_config(); output_high(LEDR); output_low(LEDG); usb_init(); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4); set_timer0(0x8ad0); enable_interrupts(GLOBAL); enable_interrupts(INT_TIMER0); while(1) { #if defined (BOARD_AVRUSB12_32) //Mod here we check pin status to see if we must reset device if(!input(PIN_B7)) { delay_ms(25); //debounce if(!input(PIN_B7)) { //its a press output_bit(LEDG,1); delay_ms(500); //for long press detection, if(!input(PIN_B7)) { //its still a press after 1 sec PINRST_BTL(); //reset device } output_bit(LEDG,0); } } #endif usb_task(); usb_isr(); if(DelayCount) continue; if(Connect) { if(UADDR != HubAddress) { usb_set_address(HubAddress); } DevicePort = Connect; port_status[Connect - 1] = PORT_FULL; port_change[Connect - 1] = C_PORT_CONN; TxBuf[0] = 1 << Connect; if(Force0DTS) usb_put_packet(1, TxBuf, 1, 0); else usb_put_packet(1, TxBuf, 1, USB_DTS_TOGGLE); Connect = 0; Force0DTS = 0; } if(Reset) { TxBuf[0] = 1 << Reset; usb_put_packet(1, TxBuf, 1, USB_DTS_TOGGLE); Reset = 0; } if(Disconnect) { if(UADDR != HubAddress) usb_set_address(HubAddress); DevicePort = Disconnect; port_status[Disconnect - 1] = PORT_EMPTY; port_change[Disconnect - 1] = C_PORT_CONN; TxBuf[0] = 1 << Disconnect; usb_put_packet(1, TxBuf, 1, USB_DTS_TOGGLE); Disconnecting = Disconnect; Disconnect = 0; } if(WaitJig) { if(WaitJig == 1) { if(usb_kbhit(2)) { unsigned char c; Chirp(); c = usb_get_packet(2, TxBuf, 8); nJigs++; EP_BDxST_I(1) = 0x40; //Clear IN endpoint if(nJigs == 8) { nJigs = 0; WaitJig = 2; Delay10ms(50); } } } else { int n = 0; for(n = 0; n < 8; ++n) { TxBuf[n] = jig_response[8 * nJigs + n]; } if(usb_put_packet(1, TxBuf, 8, nJigs == 0 ? 0 : USB_DTS_TOGGLE)) { Delay10ms(1); nJigs++; Chirp(); if(nJigs == 8) { nJigs = 0; WaitJig = 0; Delay10ms(15); Disconnect = 3; } } } } if(Address != -1) { delay_ms(1); usb_set_address(Address); Address = -1; } } }
// see usb_hw_layer.h for documentation int1 usb_tbe(int8 en) { return((UEP(en)!=ENDPT_DISABLED)&&(!bit_test(EP_BDxST_I(en),7))); }
void usb_isr_tok_dne(void) { int8 en; en = USTATCopy>>3; if (USTATCopy == USTAT_OUT_SETUP_E0) { //new out or setup token in the buffer int8 pidKey; 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) 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); } } 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 if (USTATCopy == USTAT_IN_E0) { //pic -> host transfer completed EP_BDxST_I(0) = EP_BDxST_I(0) & 0x43; //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) & 0x43; //clear up any BDSTAL confusion usb_isr_tok_out_dne(en); } else { EP_BDxST_I(en) = EP_BDxST_I(en) & 0x43; //clear up any BDSTAL confusion usb_isr_tok_in_dne(en); } } }