PIC32MZ without Harmony (2) – USB basics

The scope of USB on PIC32MZ silicon

USB is quite a complicated protocol. I would like to use this post to explain a few terminologies and concepts that we will deal with while programming the USB module on PIC32MZ devices:

  • Data transfer between the host (usually a PC) and device (MCU in this case) is automatically handled by the PIC32MZ silicon. As an embedded engineer, we’re fortunate enough not to get ourselves involved in the actually bit/byte transfer, but rather to spend time (on a PC) preparing the data before sending to an enumerated USB address, and (on an MCU) processing the data after receiving them from the PIC32MZ silicon.
  • To understand the direction of USB data transaction, OUT/IN is always used from the host’s (usually a PC’s) perspective: OUT stands for data that goes OUT of a host whereas IN stands for data that goes INTO a host; TX/RX is always used from the device’s (usually an MCU’s) perspective: TX stands for transmission from the device whereas RX stands for transmission to the device. In short:
    • Host ➡ device: OUT or Rx
    • Host ⬅ device: IN or Tx
  • Your program running on the PIC32MZ chip has access only down to the USB endpoint’s FIFO, nothing beyond that. In the case of OUT/Rx, PIC32MZ silicon will automatically update its corresponding registers (usually the interrupt’s flag) when data has arrived in FIFO, so that the program can start using the data. In the case of IN/Tx, PIC32MZ only needs to load data into the FIFO and let the PIC32MZ know that the data is ready for transmission. The PIC32MZ silicon will take over the rest of the transactions.
  • Your efforts in terms of programming the USB module of the PIC32MZ is merely how to offload/load data from/to the FIFO, and thereafter.
  • The USB host program (written in Python in my case. Could be other programming language) can send large data to a USB endpoint in just one execution. In a case where the data is larger than a single USB transaction payload can hold (usually defined by the endpoint descriptor), the USB host will automatically break the large data into several smaller transactions. Each transaction will trigger one RXIF on the MCU when it reaches the device. If USBDMA Rx is used, then each transaction will also trigger one DMA. A complete transaction of such large data will cause multiple RXIF and DMA. In the case of DMA, you just need to make sure the buffer address is not re-arm on every transaction.
  • There are 8 endpoints available on the PIC32MZ device, 0th endpoint of which is reserved for control, 1st~7th endpoints are for user’s application. Each endpoint can be configured either as IN or OUT, but only function in one direction at a time. The descriptor of the endpoint has an address byte. When its MSB is 1, then it is configured as IN, e.g. 0x81 is the IN address for the 1st endpoint, whereas 0x01 is the OUT address for the 1st endpoint. The direction register of the endpoint needs to be updated on the fly for their associated OUT or IN application.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.