void ServiceUSB(void) { __data BUFDESC *buf_desc_ptr; if (UIRbits.UERRIF) { UEIR = 0x00; } else if (UIRbits.SOFIF) { UIRbits.SOFIF = 0; } else if (UIRbits.IDLEIF) { UIRbits.IDLEIF = 0; UCONbits.SUSPND = 1; } else if (UIRbits.ACTVIF) { UIRbits.ACTVIF = 0; UCONbits.SUSPND = 0; } else if (UIRbits.STALLIF) { UIRbits.STALLIF = 0; } else if (UIRbits.URSTIF) { USB_curr_config = 0x00; UIRbits.TRNIF = 0; // clear TRNIF four times to clear out the USTAT FIFO UIRbits.TRNIF = 0; UIRbits.TRNIF = 0; UIRbits.TRNIF = 0; /* disable all endpoints before resetting buffers */ UEP0 = 0x00; disableUEP(); BD0O.bytecount = MAX_PACKET_SIZE; BD0O.address = EP0_OUT_buffer; // EP0 OUT gets a buffer BD0O.status = 0x88; // set UOWN bit (USB can write) BD0I.address = EP0_IN_buffer; // EP0 IN gets a buffer BD0I.status = 0x08; // clear UOWN bit (MCU can write) BD1O.bytecount = MAX_PACKET_SIZE; BD1O.address = EP0_OUT_buffer; // EP1 OUT gets a buffer BD1O.status = 0x88; // set UOWN bit (USB can write) BD1I.address = EP0_IN_buffer; // EP1 IN gets a buffer BD1I.status = 0x08; // clear UOWN bit (MCU can write) UADDR = 0x00; // set USB Address to 0 UIR = 0x00; // clear all the USB interrupt flags UEP0 = ENDPT_CONTROL; // EP0 is a control pipe and requires an ACK UEIE = 0xFF; // enable all error interrupts USB_USWSTAT = DEFAULT_STATE; USB_device_status = 0x01; // self powered, remote wakeup disabled } else if (UIRbits.TRNIF) { buf_desc_ptr = (__data void *)((BD_BASE)+(USTAT&0x7C)); // mask out bits 0, 1, and 7 of USTAT for offset into the buffer descriptor table USB_buffer_desc.status = buf_desc_ptr->status; USB_buffer_desc.bytecount = buf_desc_ptr->bytecount; USB_buffer_desc.address = buf_desc_ptr->address; USB_USTAT = USTAT; // save the USB status register UIRbits.TRNIF = 0; // clear TRNIF interrupt flag USB_error_flags = 0x00; // clear USB error flags switch (USB_buffer_desc.status&0x3C) { // extract PID bits case TOKEN_SETUP: ProcessSetupToken(); break; case TOKEN_IN: ProcessInToken(); break; case TOKEN_OUT: ProcessOutToken(); } if (USB_error_flags&0x01) { // if there was a Request Error... BD0O.bytecount = MAX_PACKET_SIZE; // ...get ready to receive the next Setup token... BD0I.status = 0x84; BD0O.status = 0x84; // ...and issue a protocol stall on EP0 } } }
void ServiceUSB(void) { BUFDESC *buf_desc_ptr; if (UIRbits.UERRIF) { UEIR = 0x00; } else if (UIRbits.SOFIF) { UIRbits.SOFIF = 0; } else if (UIRbits.IDLEIF) { UIRbits.IDLEIF = 0; UCONbits.SUSPND = 1; #ifdef SHOW_ENUM_STATUS PORTB &= 0xE0; PORTBbits.RB4 = 1; #endif } else if (UIRbits.ACTVIF) { UIRbits.ACTVIF = 0; UCONbits.SUSPND = 0; #ifdef SHOW_ENUM_STATUS PORTB &= 0xE0; PORTB |= 0x01<<USB_USWSTAT; #endif } else if (UIRbits.STALLIF) { UIRbits.STALLIF = 0; } else if (UIRbits.URSTIF) { USB_curr_config = 0x00; UIRbits.TRNIF = 0; // clear TRNIF four times to clear out the USTAT FIFO UIRbits.TRNIF = 0; UIRbits.TRNIF = 0; UIRbits.TRNIF = 0; UEP0 = 0x00; // clear all EP control registers to disable all endpoints UEP1 = 0x00; UEP2 = 0x00; UEP3 = 0x00; UEP4 = 0x00; UEP5 = 0x00; UEP6 = 0x00; UEP7 = 0x00; UEP8 = 0x00; UEP9 = 0x00; UEP10 = 0x00; UEP11 = 0x00; UEP12 = 0x00; UEP13 = 0x00; UEP14 = 0x00; UEP15 = 0x00; BD0O.bytecount = MAX_PACKET_SIZE; BD0O.address = EP0_OUT_buffer; // EP0 OUT gets a buffer BD0O.status = 0x88; // set UOWN bit (USB can write) BD0I.address = EP0_IN_buffer; // EP0 IN gets a buffer BD0I.status = 0x08; // clear UOWN bit (MCU can write) UADDR = 0x00; // set USB Address to 0 UIR = 0x00; // clear all the USB interrupt flags UEP0 = ENDPT_CONTROL; // EP0 is a control pipe and requires an ACK UEIE = 0xFF; // enable all error interrupts USB_USWSTAT = DEFAULT_STATE; USB_device_status = 0x01; // self powered, remote wakeup disabled #ifdef SHOW_ENUM_STATUS PORTB &= 0xE0; PORTBbits.RB1 = 1; // set bit 1 of PORTB to indicate Powered state #endif } else if (UIRbits.TRNIF) { buf_desc_ptr = (BUFDESC *)((unsigned char *)(&BD0O)+(USTAT&0x7C)); // mask out bits 0, 1, and 7 of USTAT for offset into the buffer descriptor table USB_buffer_desc.status = buf_desc_ptr->status; USB_buffer_desc.bytecount = buf_desc_ptr->bytecount; USB_buffer_desc.address = buf_desc_ptr->address; USB_USTAT = USTAT; // save the USB status register UIRbits.TRNIF = 0; // clear TRNIF interrupt flag #ifdef SHOW_ENUM_STATUS switch (USB_USTAT&0x18) { // toggle bit 5, 6, or 7 of PORTB to reflect EP0, EP1, or EP2 activity case EP0: PORTB ^= 0x20; break; case EP1: PORTB ^= 0x40; break; case EP2: PORTB ^= 0x80; } #endif USB_error_flags = 0x00; // clear USB error flags switch (USB_buffer_desc.status&0x3C) { // extract PID bits case TOKEN_SETUP: ProcessSetupToken(); break; case TOKEN_IN: ProcessInToken(); break; case TOKEN_OUT: ProcessOutToken(); } if (USB_error_flags&0x01) { // if there was a Request Error... BD0O.bytecount = MAX_PACKET_SIZE; // ...get ready to receive the next Setup token... BD0I.status = 0x84; BD0O.status = 0x84; // ...and issue a protocol stall on EP0 } } }