Page 1 of 1

is usb connected (the software method)

Posted: Fri Jun 13, 2014 4:42 am
by psc
Hi all,

I am trying to detect if there's a USB cable connected (i am using the v-usb midi firmware by horo if it matter). I am wondering what's the best method. I cannot change the pcb so I am looking for a software solution... Any insight would be useful (using register?, a special variable in v-usb? a timer?)...

Thanks

Re: is usb connected (the software method)

Posted: Fri Jun 13, 2014 4:43 pm
by ulao
I'm not familiar with the midi interface so I assume it gets power from the midi bus? Normally you get power from the USB so you are always connected to the usb. Though in the event your are not, you could watch for a pin change on the usb data lines, I'd do it wrapped in disable/enable interrupts. Or you could check for usb poll? Really depends on when you need to check for this. v-usb has its own usb connect disconnect function that merely pulls up on the data - line. So I'm guessing you want to init the usb when a users connects it? If so I would go the pin change way...

Re: is usb connected (the software method)

Posted: Fri Jun 13, 2014 4:55 pm
by psc
Yes I have a standalone mode (powering my circuit from another source than USB). I want the same firmware to work without the USB calls. So if I understand correctly, I can:

- use UsbPoll()
- watching for a pin change (D- or D+)

Any code example?

Re: is usb connected (the software method)

Posted: Fri Jun 13, 2014 5:14 pm
by ulao
well UsbPoll() is a bool 1 or 0 so its as simple as

if ( UsbPoll() )

but inorder to use that the USB init has to have run, and if you ran that its assumed you know the usb is connected, so I think that is out? Again depends how you do things.

Pin change is the best bet and very easy. You should not do this when the USB is running, only use it to detect it.
https://sites.google.com/site/qeewiki/b ... interrupts

When the usb is first plugged in I believe you will see many pin changes. You may want to set the pins lo to avoid a hi-z state false trigger.

Re: is usb connected (the software method)

Posted: Mon Aug 04, 2014 7:34 pm
by psc
Still trying to figure this out. I tried using this piece of code:

Code: Select all

PCMSK0 |= (1 << PCINT0);
PCICR |= (1 << PCIE0);

ISR(PCINT0_vect)
{
   usbConnected = 1;
}


I am using PCINT0 = D-: is it the right way?

Re: is usb connected (the software method)

Posted: Tue Aug 05, 2014 6:10 pm
by ulao
make sure you set your check before you init the usb. and make sure you turn on interrupts.

PCMSK0 |= (1 << PCINT0);
PCICR |= (1 << PCIE0);
sei(); // turn on interrupts

ISR(PCINT0_vect)
{
usbConnected = 1;
}

also don't you want PCINT17 or PCINT16
Image

PIND0 is PCINT16 which is in the PCIE2 group (there are 8 pins in each of 3 interrupts)

Code: Select all

int main(void) {
 PCICR |= (1<<PCIE2); // enable its group of 8
 PCMSK2 |= (1<<PCINT16); // enable just that 1 in 8
 sei(); // globally enable interrupts
 while(1); // sit and wait for one
}

ISR(PCINT2_vect) {
 // ta-da
}

Re: is usb connected (the software method)

Posted: Fri Aug 08, 2014 9:57 pm
by blargg
Have your main code sit in a loop waiting for usbConnected to become true, then light an LED or give some feedback. Does it trigger when you plug USB in (and your project is externally-powered)? Then it's set up right. :)

Re: is usb connected (the software method)

Posted: Fri Aug 08, 2014 10:10 pm
by psc
It's still not working on my end. Since I am using INT0 (d+) and INT1 (-d) I was not able to write a custom IRS for INT0 (already used in usbdrv), but I was able to use IRS INT1 vector. But I have a trigger on INT1 even when powering my board from an external supply (USB not even connected).

Is this define somewhat important?
#define USB_CFG_IS_SELF_POWERED 0
/* Define this to 1 if the device has its own power supply. Set it to 0 if the
* device is powered from the USB bus.

Thanks for all the help so far guys!
(For the time being I will use a switch on an I/O)

Re: is usb connected (the software method)

Posted: Sat Aug 09, 2014 8:04 am
by blargg
If I were in your position, I'd start a fresh test program, without usbdrv, and get the USB detection working on INT1 connected to a switch. Once that worked, I'd get it working with USB D-. And then finally integrate that back into the main code.

From what I've learned, on the AVR you generally want to have interrupts disabled, configure them, and then clear the appropriate interrupt flag so it doesn't fire the moment you enable them. Usually it's some xxxF register. On the '328, to set up INT1 to trigger on a level change, my reading of the manual is

Code: Select all

EICRA  = (EICRA & ~(3<<ISC10)) | 1<<ISC10; // int on level change
EIFR   = 1<<INTF1; // clear flag (yes, write, don't OR, the bit to clear it)
EIMSK |= 1<<INT1;
sei();

ISR( INT1_vect )
{
   usbConnected = 1;
}

Your original post mentioned using PCINT (rather than INT). If you go that route, using PCINT0 (PB0):

Code: Select all

PCMSK0 |= 1<<PCINT0;
PCIFR   = 1<<PCIF0;
PCICR  |= 1<<PCIE0;
sei();

ISR( PCINT0_vect )
{
   usbConnected = 1;
}


I'm not totally sure that writing to the flags register just after configuring the interrupt will avoid it being set immediately. Insert some nops just after the EICRA/PCMSK0 write if the above code doesn't work in your test.

Re: is usb connected (the software method)

Posted: Sun Jul 12, 2015 7:12 pm
by cpldcpu
It should be possible to detect if D+ is pulled low after the forced buis reset. The 10kOhm pull down of the host should do that. It may be beneficial to activate the pull up on the client side for D+.

Has anybody tried this, and does it work realiabilty?