Arduino Usb Host Shield 2.0, ch340 driver problem.

Arduino uno clone -- USB Host Shield -- Arduino uno clone (USB Device)

An old story, but I wanted to connect two Arduino Uno together using USB.
Being clones with ch340(g) in place of AtMega16u2, the setup did not work using the Usb Host Shield 2.0 with an Uno connected as the USB Device.
However, as it might be useful to have a ch340 driver, I went ahead and mostly by trial and error, ending with a partly working solution.

Attached is a ch340 driver for the Usb Host Shield 2.0, test or alpha version.
The Usb Host Shield 2.0 library must be present.

A simple oled terminal display using the 8x8lib is included. It sends UU with 5 seconds interval and is used to test the transmission from the USB device to the Host and vice versa.

With no knowledge of the USB protocol and a search for ch340 documentation gave no results, different source codes were analysed.
Using the cdcftdi as base, it was modified mainly using the linux ch340 driver as reference plus as a few other sources.

What is working:

  • set baud rate, number of bits (parity and number of stop bit not tested)
  • dtr/rts on/off tested using a ch340g usb serial converter with two wires soldered to the rts and dts pins.
  • get modem status, set modem status not tested.

Not implemented:

  • break on/off

Code present but commented out:

  • set flow control on/off.
    The code was found in a couple of places, but probably due to me making one or more mistakes, the set flow cotrol on returns with an error.

The set flow control code shown here is from the ch340.cpp in case a more competent person has a solution:

/**
 *  @brief SetCtrlStatus
 *
 *    Write a 16 bit int to the control register
 *
 *  @param[in] value 16 bit value to set
 *  @param[in] index index value
 *  @return USB result code
 */
uint8_t CH340::SetCtrlStatus(uint16_t value, uint16_t index) {
  uint8_t rv = ( pUsb->ctrlReq(bAddress, 0, bmREQ_CH340_OUT, CH340_REQ_WRITE_REG, value & 0xff, value >> 8,  index,  0, 0, NULL, NULL));
  return rv;
}

#ifdef USE_FLOW_CONTROL
//Setting flow control ON fails with return code 0x0d !
/**
 * @brief SetFlowControl
 *
 *  Send the xon/xoff control.
 * @param[in] on        true = xon/off active, false = xon/xoff inactive
 * @return USB result code
 */
uint8_t CH340::SetFlowControl(uint8_t on) {
  uint8_t rv = 0;
  if (on) {
    rv = SetCtrlStatus( 0x2727, 0x0101);
  } else {
    rv = SetCtrlStatus(0x2727, 0x0000);
  }
  if (rv && rv != hrNAK) {
    Release();
  }
  return rv;
}
#endif

ch340.zip (12.3 KB)

Thank you for this. This might be very useful when I try to connect to my 3Dprinter using a USB host shield instead of hotwiring it onto the serial port.