I'm developing a simple USB printer device class emulator on 32u4. The task of 32u4 is to pretend to be a receipt printer to receive print data and forward to ESP32 for processing and that data are forwarded to a USB host that is connected to the actual printer. 32u4 could also receive occasional update on printer status from ESP32 so it will use this value when the USB host is asking for printer's status.
What I know is that 32u4 has dual fifo banks for each end point, say the EP1 OUT. I know that when one bank is filled ISR(USB_COM_vect) is called with EPINT1 bit set in UEINT. So I take each byte out of the fifo bank until it's empty and then I release the fifo bank with UEINTX=0x6B;. While I empty this bank, usb host may be filling up the other bank so I think the interrupt is called again when the other bank fills and I do the same, move data out of the bank and release the bank.
Here is my question: if I can't send the data in the bank to ESP32, say due to the actual printer not accepting data (producing NAKs) or ESP32 still processing data, I wish 32u4 to produce NAK to its usb host until it is able to forward data again. How do I go about doing that? My idea is that if 32u4 knows that it can't forward more data, it will just exit the ISR without doing anything. So now a second packet arrives and fill the second bank and causes another ISR. If the ISR continues to do nothing, then the 3rd packet from USB host will receive an NAK since both banks are now filled. And 32u4 will keep producing NAKs until either bank is emptied with UEINTX=0x6B; before accepting more packets. Am I thinking correctly?
From what I saw on USB, the actual printer produces a number of NAKs between some packets, sometimes 16 to 17 NAKs (shown on my USB sniffer as 16 or 17 polls). I suppose the printer is busy processing data or printing so NAKs at this quantity or even more are acceptable.