// Start USB for 5V operation and wait till enumeration is completeAbove code shows the general program flow when using an USBFS user module to send data to the PC using an IN Endpoint. If you notice, the USBFS_LoadInEP function call before the while loop uses “USB_NO_TOGGLE” and the call inside the while loop uses “USB_TOGGLE”. What is this TOGGLE and NO_TOGGLE? What is the significance of these constants? I can understand from the above code that the first time I call the USBFS_LoadInEP function, I have to use NO_TOGGLE option and TOGGLE for further transactions. Why is it so? These are some of the questions a first time user of USB faces.
USBFS_Start(0, USB_5V_OPERATION);
while(!USBFS_bGetConfiguration());
// Load the IN endpoint with data with no toggle
USBFS_LoadInEP(1, Data, 8, USB_NO_TOGGLE);
while(1)
{
...
// Other code
...
// Wait till EP1 becomes free
while(!USBFS_bGetEPAckState(1));
// Load EP1 with gamepad report
USBFS_LoadInEP(1, Data, 8, USB_TOGGLE);
}
In the USB bus, data is transferred from the Peripheral to Host and vice versa using Data Packets.
A data packet comprises of a DATA0 / DATA1 flag, the payload data and the CRC of the payload data. The DATA0 / DATA1 flag is used to synchronize the data delivery. Whenever a data packet is delivered, the receiver checks the DATA flag with its own internal flag. The transaction is successful only if the flag matches. At the time of enumeration, both the peripheral and the host set the Data flag to DATA0. When the peripheral sends the first data packet, it sends it with DATA0 flag. The host on receiving the packet verifies that the received packet has the DATA0 flag and its own flag is also DATA0. So, the transaction is successful. Immediately, the host toggles its internal flag to DATA1. The peripheral when sending the next data packet should also toggle its own data flag and send the data packet with Data1 flag. This toggling continues on all successive transactions.
In the PSoC, the constants USB_TOGGLE and USB_NO_TOGGLE tell the USBFS_LoadInEP function whether toggle the DATA flag before sending the data to the host. When the USB is started and enumeration is complete, the USB hardware sets the DATA flag to DATA0. As the very first data packet should go with DATA0, the DATA flag should not be toggled and hence the USB_NO_TOGGLE option should be used. All further transactions will require the DATA flag to be toggled and should use the USB_TOGGLE option.
The sample code given in the beginning has one flaw. If the data is not initialized at the time of calling the LoadInEP function outside the while loop, the host will receive this uninitialized data as the first packet. This may be fine in certain applications like mouse where a data packet with zeroes does not affect the system.
But in other systems where the peripheral responds with data to the host when host sends some commands, then this call to LoadInEP with dummy data may not be good. The solution is to use a flag in the application and use NO_TOGGLE for the very first data packet and use TOGGLE for all further data transfers. The code will now look like this.
BYTE FirstPacket; // Flag to indicate first packet
// Start USB for 5V operation and wait till enumeration is complete
USBFS_Start(0, USB_5V_OPERATION);
while(!USBFS_bGetConfiguration());
FirstPacket = 1;
while(1)
{
...
// Other code
...
// Wait till EP1 becomes free
while(!USBFS_bGetEPAckState(1));
if(FirstPacket)
{
// This is the first packet
// Load the IN endpoint with data, and do not toggle the DATA flag
USBFS_LoadInEP(1, Data, 8, USB_NO_TOGGLE);
FirstPacket = 0;
}
else
{
// This is not the first packet
// Load the IN endpoint with data, and toggle the DATA flag
USBFS_LoadInEP(1, Data, 8, USB_TOGGLE);
}
}





