Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange behaviour with Yamaha THR10 USB device connected to Arduino Due native USB host port. #23

Open
martinzw opened this issue Mar 30, 2019 · 0 comments

Comments

@martinzw
Copy link

martinzw commented Mar 30, 2019

Hi ,
finally i got my "Yamaha THR10" (guitar amp, that can be configured via MIDI-SysEx) working with this library (arduino-libraries/USBHost) in conjunction with the" bbx10/USBH-Midi branch Due"-library on my "Arduino Due", but there were several problems to solve before:

Concerning this library (arduino-libraries/USBHost):

USB-Enumeration works only, if Debug-outputs are enabled in USBHost.h

#define TRACE_USBHOST(x) x
//#define TRACE_USBHOST(x)
otherwise device is not detected.

Don't ask me why...
Is it perhaps a timing problem, that is solved when a "printf" delays process at the right time?
EDIT:
In fact it is a timing issue, I found out after som research. There a two places to add delays (details at th bottom of this posting).

Just for further information

Issues concerning library (bbx10/USBH-Midi branch Due):

  • Adding an "else if" in descriptor parsing
        if( buf_ptr[5] == USB_CLASS_AUDIO && buf_ptr[6] == USB_SUBCLASS_MIDISTREAMING )
	{  //p[5]; bInterfaceClass = 1(Audio), p[6]; bInterfaceSubClass = 3(MIDI Streaming)
          isMidiFound = true; //MIDI device found.
          isMidi      = true;
        }
//**Yamaha THR10**
	else if( buf_ptr[5] == USB_CLASS_VENDOR_SPECIFIC && buf_ptr[6] == USB_SUBCLASS_MIDISTREAMING ) //**Yamaha THR10**
		{  
                   //p[5]; bInterfaceClass = 255(VENDOR), p[6]; bInterfaceSubClass = 3(MIDI Streaming)
		   isMidiFound = true; //MIDI device found.
		   isMidi      = true;
		}
		else
		{
#ifdef DEBUG
          Serial.print("No MIDI Device\n");
#endif
//          buf_ptr += total_length + 1;
//          bConfNum = 0;
            isMidi = false;
        }
        break;
  • Solving buffer problems:

always use (uint16_t) cast instead of (uint8_t) cast for epInfo[index].maxPktSize
e.g.
// Extract Max Packet Size from device descriptor
epInfo[0].maxPktSize = (uint16_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
quick and dirty change for buffersize, that works for THR10 (just a work around, no proper solution, i guess!!!):

if( isMidi )
{
            if ((epDesc->bEndpointAddress & 0x80) == 0x80) 
   	   {
              // Input
              index = epDataInIndex;
              epInfo[index].epAddr	= (epDesc->bEndpointAddress & 0x0F);
              //epInfo[index].maxPktSize	= (uint16_t)epDesc->wMaxPacketSize;
	      epInfo[index].maxPktSize	= (uint16_t)2048;  //necessary for YAMAHA THR10
              pipe = UHD_Pipe_Alloc(bAddress, epInfo[index].epAddr, UOTGHS_HSTPIPCFG_PTYPE_BLK, UOTGHS_HSTPIPCFG_PTOKEN_IN, epInfo[index].maxPktSize, 0, UOTGHS_HSTPIPCFG_PBK_1_BANK);
            }
            else 
	    {
              // Output
              index = epDataOutIndex;
              epInfo[index].epAddr	= (epDesc->bEndpointAddress & 0x0F);
              //epInfo[index].maxPktSize	= (uint8_t)epDesc->wMaxPacketSize;
			  epInfo[index].maxPktSize	= (uint16_t)2048;  //necessary for YAMAHA THR10
              pipe = UHD_Pipe_Alloc(bAddress, epInfo[index].epAddr, UOTGHS_HSTPIPCFG_PTYPE_BLK, UOTGHS_HSTPIPCFG_PTOKEN_OUT, epInfo[index].maxPktSize, 0, UOTGHS_HSTPIPCFG_PBK_1_BANK);
            }

After that modifikations, i can send System-Exlusive Messages to THR10, like

uint8_t msg1[]= {0xF0,0x43,0x7D,0x30,0x41,0x30,0x01,0x01,0xF7}; //Lamp off
uint8_t msg2[]= {0xF0,0x43,0x7D,0x30,0x41,0x30,0x01,0x00,0xF7}; //Lamp on`
that switches the light of the Guitar-Amp.

But more important, I can send sound-Patches, that are created as a file before with the THR10-Editor on PC.

This way I can build a foot-switch / pedal to change sound patches on the fly like

THR10 foot switch

But this guy did it with an ordinary Arduino Uno and the USB-Host Shield.
With the Due I can use the native USB-Host-Port, have got more memory and speed.
I want to inject Samples to the THR10 with this footswitch as well, as it can also act as IN-/OUT Audio Interface.

EDIT:

After days of research and examination i found out, which delays in "USB.cpp" are necessary (instead of the " #define TRACE_USBHOST(x) x", that solved the issue as well, but gives lots of Serial Prints and slows down everything.)
I would suggest this as a pull request, if i would understand the reason, but without that it is just a kind of work around.

1.) Add a delayMicroseconds(300ul); in function "USBHost::ctrlReq" where the following lines occure:

Code:

if (dataptr != 0)
{
 if (direction)
 {
   // IN transfer
   TRACE_USBHOST(printf("    => ctrlData IN\r\n");)

   Add here---->   delayMicroseconds(300ul);  //necessary!! 275ul does not work!!
  1. Add a delayMicroseconds(120ul); at start of function "USBHost::dispatchPkt"

Code:

uint32_t USBHost::dispatchPkt(uint32_t token, uint32_t hostPipeNum, uint32_t nak_limit)
{
   uint32_t timeout = millis() + USB_XFER_TIMEOUT;
   uint32_t nak_count = 0;
   uint32_t rcode = USB_ERROR_TRANSFER_TIMEOUT;

---> add here: delayMicroseconds(120ul);  //NECESSARY!!  (100ul does not work!)

   TRACE_USBHOST(printf("     => dispatchPkt token=%lu pipe=%lu nak_limit=%lu\r\n", token, hostPipeNum, nak_limit);) 

Don't really know w h y this have to be done. But it does nor work otherwise.
;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant