|
|
View previous topic :: View next topic |
Author |
Message |
Seaborgium
Joined: 23 Jul 2012 Posts: 14
|
Simple 18F4550 USB Communication |
Posted: Wed Aug 08, 2012 11:30 am |
|
|
Hi,
I'm working on getting USB CDC communication to work with an 18F4550, but I'm not really sure where to start. I haven't found any simple examples (most of them are very complex and seem more like ready-made code than examples), and the USB page in the CCS help isn't very thorough.
I'm using version 4.133. I'm using a board that was pre-built for another purpose, but I don't think the extra stuff should interfere. The setup definitely works (the original program functions fine), it's just my program doesn't seem to do anything. The LED flashes once, then stops: usb_init() never finishes.
main.c:
Code: | #include <main.h>
#include <usb_cdc.h>
void flash() {
output_high(PIN_D0);
delay_ms(150);
output_low(PIN_D0);
delay_ms(150);
}
void main() {
int16 num;
flash();
usb_init(); //Initialize USB - locks up on this command
flash(); //Program never gets to this point
while(!usb_cdc_connected()); //Wait until connected I guess?
flash();
while (TRUE) {
//Wait for header
while(!usb_cdc_kbhit()); //Wait for header byte
if(usb_cdc_getc()!=0x20) //Should be 0x20. If not, restart.
continue;
//Get data
while(!usb_cdc_kbhit());
num=usb_cdc_getc()<<8; //Get high byte
while(!usb_cdc_kbhit());
num+=usb_cdc_getc(); //Get low byte
//Transmit data
usb_cdc_putc(num+30); //Return number
}
} |
main.h:
Code: | #include <18F4550.h>
#device adc=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES CPUDIV4 //System Clock by 4
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(int=8000000) |
I have the board connected to my computer with a USB cable, but I'm not using any program to monitor USB communications or anything. Do I need to, or is the PC supposed to automatically recognize the USB connection? What could be the problem here?
Thanks! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Aug 08, 2012 12:25 pm |
|
|
Quote: | #include <18F4550.h>
#FUSES INTRC_IO
#use delay(int=8000000)
|
Download the 18F4550 data sheet and read section 2.3 which explains
the allowable oscillator settings for USB operation: http://ww1.microchip.com/downloads/en/DeviceDoc/39632e.pdf
Compare that table to your settings, and to the CCS USB examples. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Wed Aug 08, 2012 12:49 pm |
|
|
I _know_ that the CCS USB examples work.....and once you get it 'up and running', it's easy to 'add code' to do all sorts of 'things' with it.
I run my 4550s with a 4MHz xtal as I have lots left over from my 16C84 days. You do have to read the datasheet and look at the examples to see what combination of 'fuses' will work with you board. If it's already USB compatible there will be a cap on pin 18, without it you'll never have USB 'up and running'.
hth
jay |
|
|
Seaborgium
Joined: 23 Jul 2012 Posts: 14
|
|
Posted: Wed Aug 08, 2012 1:12 pm |
|
|
Oh, I see. I'll use a crystal for 6MHz/48MHz, examine the board some more, and see if that works. Thanks! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Wed Aug 08, 2012 2:43 pm |
|
|
6MHz, only supports _standard speed_ USB. This can be used, but the standard drivers are for _full speed_ USB.
For normal USB operation, you need a crystal that is 4MHz, 8MHz, 12MHz, 16MHz, 20MHz, or 24MHz.
The _maximum_ crystal frequency supported is 25MHz.
So neither of the crystal frequencies you mention would work.....
Best Wishes |
|
|
sseidman
Joined: 14 Mar 2005 Posts: 159
|
|
Posted: Wed Aug 08, 2012 4:00 pm |
|
|
I recommend emailing ccs and asking them nicely if they would send you the exercise book that comes with the USB development kit at http://ccsinfo.com/product_info.php?products_id=usbkit. I found it extremely helpful.
When you plug the usb cable in to the computer, and you don't hear the Ga-Dunk sound, you start to wonder where you've gone wrong! It could be anywhere, and its hard to figure out which. It could be that you've got your hardware wrong (I include fuse and clock setup issues here, for some reason), and nothing will work regardless of what your code says.
Next, the problem can be your code. Maybe there's just some bug in your code, it won't run, and it has absolutely nothing to do with the USB. (If your USB is right, you might hear the gadunk here, and wonder why your doohickey isn't doing what your doohickey should be doing even though your device enumerated).
Lastly, there's the the magic Descriptor or endpoint. You might have a wrong line in your descriptor, you might have counted characters in one of the structures wrong, and so on and so on. This is the most frustrating place to be, because you can tweak things forever and not get any closer to a working device. I encourage you to look at some of the resources at http://www.usb.org/developers/hidpage/ -- especially usage tables and the HID descriptor tool (though that won't be a big help for CDC). There are also some pricey tools that will help you sniff out your USB bus and make sure that you and the computer agree about what you're each looking at. Some of these tools, including more freebies, are at http://www.lvr.com/development_tools.htm
The latter is Jan Axelson's page. she wrote USB Complete, which is also a very valuable resource. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Thu Aug 09, 2012 4:54 am |
|
|
hmm...just remembered..
There's an INF file in the DEVICES subfolder you need to install into Windows to get it 'running'. CDCxxx.inf where xxx is the version of Windows you're running.
hth
jay |
|
|
Seaborgium
Joined: 23 Jul 2012 Posts: 14
|
|
Posted: Thu Aug 09, 2012 11:10 am |
|
|
I ended up using the same settings that the board was built for - a 20 MHz crystal, but software specified to have a 48 MHz clock. It seems to work fine.
Code: |
//Stalls until a target byte is received.
void waitFor(int target) {
//Wait forever until broken
while(TRUE) {
//If receive a byte...
if(usb_cdc_kbhit()) {
//And it matches, return.
if (usb_cdc_getc()==target) {
printf(usb_cdc_putc, "%c", target); //Echo byte
return;
}
}
}
}
void main() {
int inByte;
usb_init(); //Initialize USB
//while(!usb_cdc_connected()); //Wait until connected?
while (TRUE) {
//Wait for header
waitfor(IN_HEADER_1);
waitfor(IN_HEADER_2);
//Wait for next byte
while (!usb_cdc_kbhit());
inByte=usb_cdc_getc();
etc.
|
Code: | #include <18F4550.h>
#device adc=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES CPUDIV1 //No system clock postscaler
#FUSES HSPLL //High speed xtal
#FUSES PLL5 //??
#FUSES NOPROTECT //No code protection
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(clock=48000000) //Configured for 48 MHz |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Thu Aug 09, 2012 2:09 pm |
|
|
Your '?' against the PLL5, suggests this is part of what you want to understand.
First thing, if you set the oscillator to 'HS', rather than HSPLL, then your _CPU_ will run directly at the crystal frequency. So, with a 20Mhz crystal, 20MHz. You can select this if you'd prefer to run at a slower speed.
With HSPLL selected, the CPU runs from the USB PLL. The USB PLL _ always runs_ if the crystal oscillator is enabled, and the USBDIV fuse is on.
This requires a 4MHz input. Hence the 'PLL5'. 20/5=4.
Currently, the 20MHz, is divided by 5 (PLL5), and this is fed to the USB PLL. This generates 96MHz for the USB.
With 'HSPLL' selected, the CPU clock comes from the USB PLL, rather than directly from the crystal. This then gives:
CPUDIV1 - 48MHz to the CPU (the dividers going this route, differ from the fuse 'names'.
CPUDIV2 - 32MHz to the CPU.
CPUDIV3 - 24MHz to the CPU.
CPUDIV4 - 16MHz to the CPU.
You can change just these dividers, and the clock statement if required.
If you want to use a different crystal, change just the PLLn value.
With PLL2, you can run off an 8MHz crystal, and everything else remains the same.
Best Wishes |
|
|
Seaborgium
Joined: 23 Jul 2012 Posts: 14
|
|
Posted: Mon Aug 13, 2012 7:02 pm |
|
|
Oh, I understand now. Thanks for the info! |
|
|
|
|
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
|