![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Bollo
Joined: 01 Dec 2010 Posts: 25
|
PIC18F65J50 USB "Unknown Device" |
Posted: Fri Sep 23, 2011 12:26 pm |
|
|
Hello I'm trying to get USB HID working with this PIC. However windows claims the device is unknown and gives error code 43. I have double checked the D+ and D- connections and they are correct.
Here is my code. Is there anything missing that I should need to get this working?
I'm using compiler version 4.120
Code: |
#include <18F65J50.h>
#device adc=12
#FUSES NOWDT //No Watch Dog Timer
#FUSES PLL2 //Divide internal 8MHz RC OSC by 2 to get 4MHz input to PLL
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES DEBUG //Debug mode for ICD
#FUSES NOCPUDIV //No CPU divider
#FUSES INTRC_PLL_IO //Use the INT RC osc with the PLL, use clock pins as IO
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOIESO //Internal External Switch Over mode disabled
#use delay(clock=48M)
#define USB_HID_DEVICE TRUE
#define USB_EP1_TX_SIZE 64
#define USB_EP1_RX_SIZE 64
#define USB_CONFIG_HID_TX_SIZE 64
#define USB_CONFIG_HID_RX_SIZE 64
#include <pic18_usb.h>
#include <usb_desc_hid.h> //USB Configuration and Device descriptors for this USB device
#include <usb.c> //handles usb setup tokens and get descriptor reports
int8 out_data[USB_CONFIG_HID_TX_SIZE];
int8 in_data[USB_CONFIG_HID_RX_SIZE];
void initialise() {
setup_oscillator(OSC_8MHZ); //Set up internal RC osc
//Interrupts
enable_interrupts(GLOBAL);
enable_interrupts(INT_USB);
//Other devices
SETUP_SPI(SPI_DISABLED);
SETUP_ADC(ADC_OFF);
usb_init_cs(); //Initialise USB
memset(in_data, 0x00, USB_CONFIG_HID_RX_SIZE);
memset(out_data, 0x00, USB_CONFIG_HID_TX_SIZE);
}
void main(){
initialise();
do{
usb_task();
}
while(1);
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19360
|
|
Posted: Fri Sep 23, 2011 2:58 pm |
|
|
If you are using the INTRC clock, remember this is only rated for use for low speed USB. The cpu divider needs to be set to 10, and FSEN=0, for low speed USB selection, and this needs to be set in the CCS code as well. The CPU needs to run at 24MHz with these settings.
It will 'sometime' work for full speed USB, but is not rated for this, and _will_ be unreliable.
Have you got the 3.3v supply connected to Vusb, and properly smoothed?.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
Bollo
Joined: 01 Dec 2010 Posts: 25
|
|
Posted: Fri Sep 23, 2011 3:50 pm |
|
|
Thanks for the reply. I wasn't aware of the restriction imposed by the internal clock. The previous chip I had used with USB (PIC18F47J53) had a LS48MHZ fuse to set low speed. Having looked at the fuses for the PIC18F65J50 I can't see anything that would be of use. Do I have to set the FSEN register manually? Is there anything else needed to force low speed?
On the 3.3V side of things, yes, I have the 5V from the USB power being converted into 3.3V with an LDO reg. VUSB is connected and the proper filtering caps are present around the PIC. |
|
![](templates/subSilver/images/spacer.gif) |
Bollo
Joined: 01 Dec 2010 Posts: 25
|
|
Posted: Sat Sep 24, 2011 8:40 am |
|
|
OK. I think I have have it set properly for low speed usb. Problem is the device is still unrecognised. Does any one know if I'm missing something that is not being set in the CCS USB drivers? Or should this set up below be working correctly and therefore I should be focusing on finding a hardware problem.
Also is there no CCS code that will control the FSEN bit specifically, as I want to be sure that none of the CCS code is setting FSEN=1 after I set it to 0 manually?
Code: |
#include <18F65J50.h>
#device adc=12
#FUSES NOWDT //No Watch Dog Timer
#FUSES PLL2 //Divide internal 8MHz RC OSC by 2 to get 4MHz input to PLL
#FUSES XINST //Extended set extension and Indexed Addressing mode enabled
#FUSES DEBUG //Debug mode for ICD
#FUSES CPUDIV2 //2 x CPU divider, gives 8x USB clock divider also
#FUSES INTRC_PLL_IO //Use the INT RC osc with the PLL, use clock pins as IO
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOIESO //Internal External Switch Over mode disabled
#use delay(clock=24M)
#bit FSEN = 0xF5F.2 // 0 = Low-speed device: controls transceiver edge rates; requires input clock at 6 MHz
#bit UPUEN = 0xF5F.4 // 1 = On-chip pull-up enabled (pull-up on D+ with FSEN = 1 or D- with FSEN = 0)
#bit UTRDIS = 0xF5F.3 // 0 = On-chip transceiver active
#define USB_CONFIG_HID_TX_SIZE 64
#define USB_CONFIG_HID_RX_SIZE 64
#include <pic18_usb.h>
#include <usb_desc_hid.h> //USB Configuration and Device descriptors for this USB device
#include <usb.c> //handles usb setup tokens and get descriptor reports
int8 out_data[USB_CONFIG_HID_TX_SIZE];
int8 in_data[USB_CONFIG_HID_RX_SIZE];
void initialise() {
setup_oscillator(OSC_8MHZ); //Set up internal RC osc
//Interrupts
enable_interrupts(GLOBAL);
enable_interrupts(INT_USB);
//Other devices
SETUP_SPI(SPI_DISABLED);
SETUP_ADC(ADC_OFF);
FSEN = 0; //Set low speed USB
UPUEN = 1; // Set internal pullup
UTRDIS = 0; // Enable transceiver
usb_init_cs(); //Initialise USB
memset(in_data, 0x00, USB_CONFIG_HID_RX_SIZE);
memset(out_data, 0x00, USB_CONFIG_HID_TX_SIZE);
}
void main(){
initialise();
do{
usb_task();
}
while(1);
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19360
|
|
Posted: Sat Sep 24, 2011 9:45 am |
|
|
The more I look at the data sheet for this device, the more I find myself saying 'you need a crystal'.
Some of the devices in this family, have an internal clock that is certified as being good enough for low speed USB. Low speed USB, _requires_ a clock source that offers +/-1% or better accuracy. High speed requires 0.2%, which none of the internal clocks offer. However your device does not at any point say that the internal clock is adequate for low speed USB, and in fact the oscillator section specifically says that it is necessary to provide a separate clock source for USB operation. This is further backed by the clock frequency accuracy specification in the data, which quotes +/-1% as 'typical', but +/-2% as the min/max values, even working at a fixed 25C, while over the full device temperature range, the internal oscillator give +/-10%!...
Compare this with say the PIC18F46J50, where Microchip specifically say:
"The 8 MHz INTOSC included in all PIC18F46J50 Family
devices is extremely accurate. When the 8 MHz
INTOSC is used with the 96 MHz PLL, it may be used
to derive the USB module clock. The high accuracy of
the INTOSC will allow the application to meet
low-speed USB signal rate specifications."
The internal oscillator on this chip, is specified to give +/- 0.25% typical, and +/-1% worst case, meeting the low speed USB specs.
Your chip has no such specification, and I'm afraid is _not_ capable of operating USB, without an external clock source.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
Bollo
Joined: 01 Dec 2010 Posts: 25
|
|
Posted: Sat Sep 24, 2011 10:30 am |
|
|
Thanks for letting me know! When I chose this chip I took a look at the oscillator diagram in the data sheet and it does suggest the internal osc could be used. But yes you are sadly correct, TABLE 2-5 does not show any option to actually use the internal osc. Seems a bit sneaky to not be explicit about it but still my own fault for not being thorough. I'll have to sacrifice a couple of I/O pins for a crystal and I'll let you know how it goes. |
|
![](templates/subSilver/images/spacer.gif) |
Bollo
Joined: 01 Dec 2010 Posts: 25
|
|
Posted: Sun Sep 25, 2011 6:59 pm |
|
|
I think I have found a second problem here. It would seem the PLL is not being used with the code above. I set the osc to output on RA6 and I get a 1MHz output. This 1MHz x 4 x 2 gives you the 8MHz internal clock. The same thing happens when using a 8MHz crystal. I'm going to look into manually setting the PLLEN bit.
EDIT: Yes setting the PLLEN bit manually to 1 does indeed engage the PLL. Setting either HSPLL or INTRC_PLL fuses does not seem to set the PLLEN bit. This is assuming they are supposed to. Am I missing something fundamental here?
EDIT 2: Just for fun I ran the PIC on the internal oscillator and tried the USB. Everything seems to work fine. I'm reading in a lot of places the low speed USB clock can vary by as much as +/-1.5% making the internal osc *just* acceptable for LS USB if the 3.3V power is stable and the temperature is room. Of course this is not good enough for a commercial app or if the USB connection was critical or what not, but for prototypes and testing it seems it can be used successfully if desired. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19360
|
|
Posted: Mon Sep 26, 2011 2:11 am |
|
|
Setup_oscillator();
This chip, does not have the PLL settable from the fuses. The fuse controls whether the PLL is 'off', or _can_ be turned on in software.
So you have to select the PLL fuse, so the software can turn it on, and then turn it on with the setup_oscillator command.
Only the latest compilers have the PLL control implemented, so, simply defining the bit and turning it on, as you have done, is the work-round.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|