v-usb not really good for control transfers after all.

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
ulao
Rank 4
Rank 4
Posts: 454
Joined: Mon Aug 25, 2008 8:45 pm

v-usb not really good for control transfers after all.

Postby ulao » Fri Nov 10, 2017 5:59 pm

If anyone has looked in to the v-usb on the wire you will learn a few things...

sending the NACK consumes all the CPU time.and this can go on for quite a while. The host only stops sending IN packets right before the end of the frame, to avoid colliding with the 1 ms keep alive pulse. This finally leaves enough time for V-USB to process the data and prepare the TX buffer. This is extremely wasteful, since less than 10% of the USB bus traffic is actively transferring data and almost 90% of the CPU time is spent on “appeasing” the host. In the worst case, only one valid transmission can be processed per frame (1 ms). Since a low-speed USB data packet carries a maximum of 8 bytes, this limits the theoretical throughput to 8000 bytes/s and much less in practice due to additional protocol overhead. Although extremely ugly, it does work for V-USB.

this is not my original wording, complements to TIm for this. Though I see this is all very true. This does work out well if you have nothing you intend to do with the chip in any depth. For example, try running 300 us of ASM time sensitive code (were you need to cli) It simply will not work. If you try to place that ASM in the 1 ms window and not disable interrupts, the control transfer will run it over. Being they take seconds to complete, this likelihood goes way up.

Breaching the limits of v-usb... So in-part with tims research I devises a method I think is going to work.

pseudo code.

main
{
.
.

usbDisableAllRequests();//force NAK
EIMSK &= ~(1 << INT0);//disable int
do_ASM_sensitive_Code
EIMSK |= (1 << INT0); //enable int
usbEnableAllRequests();//free NAK condition.
.
.
}


asmcommon.lst change needed
sofError:
POP_RETI ;macro call
SBIC EIMSK, 1 ;if not set branch (int0)
RETI;was set
RET;was not


Idea here is that you can tell the driver to return NAK. This is ok but not if interrupts are disabled. So we change reti to ret in the SOF and allow it to constantly send NAK if the int. is cleared. This change will not effect any v-usb operation. It is only done if you disable the interrupt (could change to accept other pins) and in this case, this is best.


This is a work in progress... Thoughts

ulao
Rank 4
Rank 4
Posts: 454
Joined: Mon Aug 25, 2008 8:45 pm

Re: v-usb not really good for control transfers after all.

Postby ulao » Fri Nov 10, 2017 6:23 pm

One small addition. It may be wise to check for the interrupt arrest before enabling.

usbPoll(); //issue at least one for the check below
if (USB_INTR_PENDING & (1<<USB_INTR_PENDING_BIT)) // Usbpoll() collided with data packet
{
uint8_t ctr;

// loop takes 5 cycles
asm volatile(
" ldi %0,%1 \n\t"
"loop%=: sbis %2,%3 \n\t"
" ldi %0,%1 \n\t"
" subi %0,1 \n\t"
" brne loop%= \n\t"
: "=&d" (ctr)
: "M" ((uint8_t)(8.8f*(F_CPU/1.0e6f)/5.0f+0.5)), "I" (_SFR_IO_ADDR(USBIN)), "M" (USB_CFG_DMINUS_BIT)
);
USB_INTR_PENDING = 1<<USB_INTR_PENDING_BIT;
}

ulao
Rank 4
Rank 4
Posts: 454
Joined: Mon Aug 25, 2008 8:45 pm

Re: v-usb not really good for control transfers after all.

Postby ulao » Tue Nov 14, 2017 6:36 pm

Idea will not work because this function is only called based on the interrupt. I'd have to step back further. Unsure where to look at the moment, abandoning this ideas for now.


Return to “V-USB”

Who is online

Users browsing this forum: Bing [Bot] and 5 guests