# Okay for USB to send data without specific OUT command first?

I have been going back and forth between writing software for my device and the PC application trying to get the protocol right.

I have a pic18f4550 talking over interrupt transfers. It needs to regularly send the status of up to 128 switches, and also maintain the status of pin outputs based on commands from the PC (on/off, pulse, blink, etc).

Much of the examples I have encountered place IN-transfers inside of a block that makes sure an OUT-transfer always happens first, like this libUSBDotNet example. If there is no OUT data ready then no IN request will be made either. The template firmware was initially set up to handle something similar - It would always wait for there to be data in the OUT buffer, handle that, then set up the IN buffer and send.

When I got started I thought it was overrated, because my device was always going to send the switch status if it had the information and always ready to the commands should there be any. I adjusted my application to send OUT transfers and IN requests independently, and the firmware to handle each independently. But as my code gets more complex, I wonder if I was missing something.

If I ensured the OUT-IN back-to-back structure, I could reserve one or two initial OUT bytes to include a command to send the switch update. It would also allow me to easily stop requesting the data. Of course I could leave it as is and have certain commands reserved to set flags that would enable/disable certain behavior on the data collection/transfer side. I still don't know what might be necessary at the end of this project, so I guess I am looking for advise for best practice, and pros/cons of approaches. Or maybe I'm way overthinking this.

Thanks.

EDIT: Also, ping-pong buffer mode is turned off on my chip, so there are dedicated buffers for the IN EP and OUT EP, if I am not mistaken.

C# code (i've ported this into pyUSB as well). Compare to the libUSBDotNet sample I linked to. Run every 10ms with a timer

private static void RunUSB(Object source, ElapsedEventArgs e)
{
ErrorCode ec = ErrorCode.None;

if (true) // for now always do this.  In future only if we have commands to send.
{
int bytesWritten;
ec = writer.Write (commands, 0, 3, 2000, out bytesWritten);
if (ec != ErrorCode.None)
throw new Exception (UsbDevice.LastErrorString);
}

{
//handle input data
}
}


Firmware code (using mStack)

// initialize endpoint 1 IN buffer
unsigned char *INPacket = usb_get_in_buffer(1);
memset(INPacket, 0, EP_1_IN_LEN);

while (1) {
if (usb_is_configured())
{
// get data from PC
if (usb_out_endpoint_has_data(1))
{
unsigned char OUTLen;
const unsigned char *OUTPacket;
/* Data received from host */
OUTLen = usb_get_out_buffer(1, &OUTPacket);

// do stuff with OUT data
// rearm for out data
usb_arm_out_endpoint(1);
}

// send data to PC
if (!usb_in_endpoint_halted(1))
{
/* Wait for EP 1 IN to become free then send. This of
* course only works using interrupts. */
if(!usb_in_endpoint_busy(1))
{
// fill INPacket with data
usb_send_in_buffer(1, byteCount);
} else {
// send something
INPacket[0] = 0;
usb_send_in_buffer(1, 1);
}
}
}
}


Note that the if (!usb_in_endpoint_halted(1)) was originally inside of the if (usb_out_endpoint_has_data(1)) block

• The more I dig into this, the more I believe that the only potential problem is that because I am not ensuring OUT then IN back-to-back, I lose the ability to request certain formats of IN data in a reliable manner. My question was asked in concern for potential errors I may cause, but from what I can tell in the USB spec flow there's nothing that holds one to running an equal number of INs and OUTs or that they need to run in any specific order. – ptpaterson Mar 7 '15 at 4:41