v-usb not really good for control transfers after all.
Posted: 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
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