CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

USB : how it works

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Jean FOUGERON



Joined: 30 Nov 2012
Posts: 110
Location: France

View user's profile Send private message Visit poster's website

USB : how it works
PostPosted: Mon Mar 25, 2013 8:20 am     Reply with quote

Hi friends,
I am looking for understanding how works usb on the PICs (PIC18F2550 for my own).
Do you know where I can find a course, or information like
1/ do usb_init() that does that and that,
then try and enumerate (it does not work on my project) that does that thing and wait for that answer from the Host, or the host expect that information.

You see what I mean ?

Thanks for your help.
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Mar 25, 2013 8:40 am     Reply with quote

Best start is to use the examples that CCS supplies.Try the cdc version first (looks like simple serial port).

I know it works for the 18F4550 device, though it took me some time (had D+, D- reversed....)

Be sure to read the comments in the 'header' files (*.h) used in the examples, as there's great info there!!

You can also 'search' this forum for past 'threads' about USB.

The 'bible' on USB is about 600+ pages......Jan's book. Heavy, heavy reading, 99% not needed.

Be aware that the USB 'driver' will consume about 1/3 code space! May or may not be a problem depending on your application.
After playing with it I 'cheated', bought $3 USB<>TTL module....

hth
jay
Jean FOUGERON



Joined: 30 Nov 2012
Posts: 110
Location: France

View user's profile Send private message Visit poster's website

PostPosted: Mon Mar 25, 2013 9:32 am     Reply with quote

I try a simple HID project, but (of course) it doesn't work.
Code:

usb_init();
while(TRUE)
     {
      restart_wdt();                              
      usb_task();
      if(usb_enumerated())
      {
         Light_Spy_Led(TRUE);
         if(usb_kbhit(1))
         {
            usb_get_packet(1,in_data,8);
            do_something();
         }   
      }   
     }


Simple, no ?
But the spy led never lit !
So I'm afraid it is not enumerated.
The Host says "windows does not recognize this peripheral ..."
Have an idea ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Mon Mar 25, 2013 10:21 am     Reply with quote

So what have you got as the descriptor file?.

Things that go wrong:
1) Wrong fuses/clock rate. The settings for the 4550, are unlike any earlier PIC. For full speed USB, you must have a master oscillator that is a multiple of 4MHz. Then either HSPLL (- XTPLL for 4Mhz only - running the CPU divided off the USB divider), or HS (running the CPU divided off the master clock). Then PLLx, where 'x' specifies the divider needed to get 4MHz. VREGEN (unless _you_ generate 3.3v external to the chip), USBDIV. Then CPUDIVx, and the right CPU clock selection.
So, what crystal are you running?. What speed do you want to run the CPU?. We will post if the CPU speed is possible, and the fuses needed.
2) Incorrect capacitor on Vusb. This needs good HF characteristics, not too large, or too small. 'best' is something like a 0.47uF polyester. Going to larger capacitors can cause problems with the regulator, going to small can give inadequate smoothing.
3) Incorrect connections to the USB header.
4) Descriptor file. Must match what you want to do. Start with usb_desc_cdc.h.
5) incorrect connections regarding sensing power on the USB bus. This is one that is often got 'wrong'. Technically, the device _must_ turn off it's drivers if the USB 5v goes down. If you are powering your device off the USB power, then this is OK. However if you have your own 5v, then the device really must sense the USB power. It causes all sorts of strange oddities if not done right.

You ask about initialisation. The first thing that happens, is that the buffers on each attached device must be off. The device has two resistors on the two lines. The pattern of these, defines the bus speed to be used. For this to work, the Vusb, must be working, and the resistors must be enabled in the right pattern. There are internal resistors that are enabled by the driver.
Then the master device now has it's speed configured, and does a broadcast on the bus at the specified speed to say "who's there". This is enumeration. The reply is the data in the descriptor. If this is working, the master should now study the data and know what driver _it_ needs. If your PC is not finding the device itself (things like keyboards), or asking for a driver, then 1,2,3 or 4 is probably wrong.
You only need the hardware setup right, the clocks etc., and:
Code:

#define PIN_USB_SENSE PIN_B1 //define to suit your hardware
#include <usb_cdc.h>


//Then in main
   usb_init();
   while(TRUE)
   {
      restart_wdt();                             
      usb_task();
      if(usb_enumerated())
      {
         Light_Spy_Led(TRUE);
         if(usb_kbhit(1))
         {
            data=usb_cdc_getc();
            do_something();
         }   
      }   
   }



Best Wishes
Jean FOUGERON



Joined: 30 Nov 2012
Posts: 110
Location: France

View user's profile Send private message Visit poster's website

PostPosted: Tue Mar 26, 2013 3:05 am     Reply with quote

Ttelmah wrote:
So what have you got as the descriptor file?.

Yes usb_desc_hid.h


Ttelmah wrote:

Things that go wrong:
1) Wrong fuses/clock rate. The settings for the 4550, are unlike any earlier PIC. For full speed USB, you must have a master oscillator that is a multiple of 4MHz. Then either HSPLL (- XTPLL for 4Mhz only - running the CPU divided off the USB divider), or HS (running the CPU divided off the master clock). Then PLLx, where 'x' specifies the divider needed to get 4MHz. VREGEN (unless _you_ generate 3.3v external to the chip), USBDIV. Then CPUDIVx, and the right CPU clock selection.

Yes it seems, when I fuse PLL5,VREGEN,USBDIV,CPUDIV1 that it suddenly works better. Windows now recognize the HID and have installed the correct driver. Thanks


Ttelmah wrote:
So, what crystal are you running?. What speed do you want to run the CPU?. We will post if the CPU speed is possible, and the fuses needed.

My crystal is 20MHz.
I use a Timer3 to sequence my application and it runs the correct delays for now


Ttelmah wrote:
2) Incorrect capacitor on Vusb. This needs good HF characteristics, not too large, or too small. 'best' is something like a 0.47uF polyester.

I have a 470nF polyester


Ttelmah wrote:
3) Incorrect connections to the USB header.
4) Descriptor file. Must match what you want to do. Start with usb_desc_cdc.h.

I use usb_desc_hid.h


Ttelmah wrote:

Code:

#define PIN_USB_SENSE PIN_B1 //define to suit your hardware
#include <usb_cdc.h>


What is this PIN_USB_SENSE ?

Thanks
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Tue Mar 26, 2013 3:35 am     Reply with quote

The connection sense pin. Connected to the 5v from the USB via a resistive divider. Allows the code to know that the USB power has gone off. With this used, the driver will then turn the USB transceivers off, and should correctly recover when the power goes back on. Without this, the device (if powered off it's own 5v), will give problems with reconnecting, if it is attached to a machine that goes to sleep. It is _required_ by the USB spec, but a thing that is often omitted. The problems it generates if not used, depend on the PC chipset, how hubs are powered (if used), and the exact working environment.

Best Wishes
Jean FOUGERON



Joined: 30 Nov 2012
Posts: 110
Location: France

View user's profile Send private message Visit poster's website

PostPosted: Thu Mar 28, 2013 9:25 am     Reply with quote

Now, it is seen by the host,
USBDeview report an VendorID = 0x0461 which seems to be Microchip and it reassures me Razz
But, I do not see where I can code my application, in other words when and where I find host requests ans where I post my application datas.

When I look to #int_usb I stay puzzle !

It appears that it is sometimes called, sometimes not ?!?

are data seen under usb_kbhit and usb_gets ? and do I answer with usb_puts ? and have I to call them in my main() loop ?
Jean FOUGERON



Joined: 30 Nov 2012
Posts: 110
Location: France

View user's profile Send private message Visit poster's website

PostPosted: Fri Mar 29, 2013 9:39 am     Reply with quote

My main routine is as follow

Code:

   usb_init();                                  // initialiser l'USB
   usb_wait_for_enumeration();                  // on attend que le PIC soit enuméré par le HOST
   
     while(TRUE)
     {
      restart_wdt();                              // resetter le watch dog !
      //usb_task();                                 // sinon le host boucle en attente !
      //usb_debug_task();
      if(usb_enumerated())
      {
         //Frequence();
         if(usb_kbhit(1))
         {
            Frequence();
            usb_get_packet(1,in_data,USB_CONFIG_HID_RX_SIZE);
            usb_put_packet(1,in_data,USB_CONFIG_HID_TX_SIZE,USB_DTS_DATA1);
            //usb_put_packet(1,Reponse,10,USB_DTS_DATA1);   // USB_DTS_TOGGLE dans usb_hw_layer.h
            Frequence();
         }   
      }   
     }


I made a VB program which send 8 bytes and read back the bytes.
Sometimes it read 64 "1" but more often it reads 64 (I think USB_CONFIG_HID_TX_SIZE) "0" as it must read in_data which is "1", "2", "3", "4", "5", "6", "7" and "8"

More, the VB progr waits so much time (more than 3s) before having the datas, as the PIC spends around 140µs to read and to write !!

Thanks for ideas where to search
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Mar 29, 2013 12:03 pm     Reply with quote

You might try 'realterm' or some other 'terminal emulation' program for basic testing.VB might be waiting for the USB buffer to be full ? or send some 'signal' saying 'data is here' ?
VB is way too 'cumbersome', high overhead..and I use Delphi for any serious work. It generates small, totally selfcontained code,doesn't rely upon Windows at all...
USB is NOT an easy communications method! Not interrupt driven,has to be polled,slow( going through Windows),HUGE overhead(code space) for even the most simple task.
Too bad it's the 'standard' today....RS232 was far better in everyway.
sigh,guess I'm 'old school'......

jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Fri Mar 29, 2013 12:08 pm     Reply with quote

The standard driver for CDC, implements buffering of the USB transactions, which you are not using.
If you are using CDC, usb_gets, getc, puts, use the buffered cdc transactions.
I'd guess you are using the old VB MSCOMM class, and it is set to not return data until a certain number of characters are seen, or when it times out.
The delay is at the VB end.
You seem to just be echoing the data at present:
Code:

         if(usb_kbhit(1))
         {
            Frequence();
            usb_cdc_putc(usb_cdc_getc());
            Frequence();
         }


Best Wishes
Jean FOUGERON



Joined: 30 Nov 2012
Posts: 110
Location: France

View user's profile Send private message Visit poster's website

PostPosted: Tue Apr 02, 2013 1:17 am     Reply with quote

temtronic wrote:

USB is NOT an easy communications method! Not interrupt driven,has to be polled,slow( going through Windows),HUGE overhead(code space) for even the most simple task.
Too bad it's the 'standard' today....RS232 was far better in everyway.
sigh,guess I'm 'old school'......

jay


Hehhh ! Surely, but we are obliged to go on with modernity. Lamps amplifiers had better sound also ...
Keep courage
Jean FOUGERON



Joined: 30 Nov 2012
Posts: 110
Location: France

View user's profile Send private message Visit poster's website

PostPosted: Tue Apr 02, 2013 1:32 am     Reply with quote

Ttelmah wrote:

I'd guess you are using the old VB MSCOMM class, and it is set to not return data until a certain number of characters are seen, or when it times out.
The delay is at the VB end.

I use http://semifluid.com/2006/03/27/pic18f2550-usb-hid-oscilloscope/ as example which implements API's and calls hid.dll I do not really know.
Yes, it seems that VB waits waits waits. The PIC receives the correct datas and send something. I will investigate in the VB prog to verify whether VB reads the real datas sent by the PIC.
Jean FOUGERON



Joined: 30 Nov 2012
Posts: 110
Location: France

View user's profile Send private message Visit poster's website

PostPosted: Thu Apr 04, 2013 8:10 am     Reply with quote

Help Ttelmah

I seems I cannot exchange (Host -> PIC and PIC -> host) more than 64 bytes each time
Which constant do I have to modify in order to increase up to 128 ?
Jean FOUGERON



Joined: 30 Nov 2012
Posts: 110
Location: France

View user's profile Send private message Visit poster's website

PostPosted: Fri May 03, 2013 8:35 am     Reply with quote

And now ...

It worked. The only issue I had was on VB6 side I think (VB "heard" my PIC answer only one time every 10 !)

I come back to this application after some days of travel, I switch on and ... nothing work !

Grrrr !

USBDeview does not see it, neither my VB6 program, neither Windows. Even though the rest of the program works perfectly, showing it is not a hardware issue.

What can happen ?
It does usb_init(); but is not enumerated. The voltage on pin 15 (PIC18F2550) is # 2V but I do not see any pulse on it.

Thanks for your ideas .
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group