|
|
View previous topic :: View next topic |
Author |
Message |
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
PIC24 crystal with PLL setup help please [SOLVED] |
Posted: Fri Sep 30, 2016 5:28 pm |
|
|
Compiler: 5.026
MCU: PIC24EP512GP806
All right, I know this question has probably been answered many places but I guess it'll be quicker to just post the question and get the answer.
These are my settings:
Code: |
#fuses HS, WDT, PR, WPOSTS16
#use delay( oscillator = 36864000, clock = 73728000 ) |
So I am using a 36.864MHz oscillator (FXO-HC735R-36.864 from FOX electronics) and *I would guess* that the above settings would set the PLL to x2.... is this correct?
Now, I want to lower the current draw on my circuit to implement power management and the oscillator is the last thing to eliminate as it draws about 7.5mA (it is a powered oscillator, not a crystal).
I have in my hands a 7.3728MHz crystal and ideally, I'd like to up the internal frequency through the PLL.
I will change this to a faster crystal when I get a chance to order one but for now it's just a test.
If I try this code:
Code: |
#fuses XT, PR_PLL, WDT, PR, WPOSTS16
#use delay( crystal = 7372800, clock=14745600 ) --> Clock is x2 the crystal speed |
I get <Option invalid No PLL option> error.
If I change the <#use delay> line to this:
Code: | #use delay( crystal = 7372800, clock=73728000 ) --> Clock is x10 the crystal speed |
Then the code compiles but the circuit doesn't appear to be working (e.g. code is not executed as I don't see any data on my serial console)....
Then if I eliminate all PLL-related code altogether, the circuit initializes but the clock is wrong.
So, the big question:
Considering I have the 7.3728MHz external crystal connected and the crystal works, how do I configure the #fuses and #use delay in order for this crystal to use a PLL at the highest frequency (at least 73.728MHz)?
What am I doing wrong?
Thanks!
Benoit
Last edited by benoitstjean on Thu Oct 13, 2016 7:17 am; edited 1 time in total |
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
|
Posted: Sat Oct 01, 2016 2:01 am |
|
|
Hi! I see no answers yet (the big calibers in the forum went on a weekend? ) and I haven't worked with this chip but I'm going over the errata & data sheet:
There are MANY issues with the chip. Please go over the errata and check it carefully. One important issue is item #9 :
Quote: | BOR must always be enabled. |
It doesn't say why or what would happen if not. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Sat Oct 01, 2016 7:21 am |
|
|
There is no point in using a faster crystal.
The PLL on these chips is not the simple *N PLL of lesser chips.
Instead the incoming clock is _divided_ by a programmable ratio to bring it into the range 0.8 to 8MHz. The PLL can only accept frequencies in this range, so when running off your 36.864MHz oscillator the first thing that will be happening is to divide it down to get inside this range. The divisions supported are 2 to 18. Then this frequency is multiplied by a factor of 2 to 257, to give a frequency that has to be between 120 and 340 MHz. Then the output of this multiplier is divided by a third factor of between 2, and 18 in steps of 2. Phew....
Now your attempt to use 7.37MHz to give 14.74MHz.
If you try all the factors you can't quite get this frequency with the available multipliers and dividers, with the restricted range of frequencies allowed at each stage. You can get very close, but the compiler just tells you it can't do it. The *10, it can manage though, and it ought to be working.
First thing to test is that your crystal actually is oscillating. You say it works, but how do you know?.
If you use just XT, without the PLL (PR), and specify 7.37MHz, for the crystal, what happens?. These oscillators have problems that on many low gain crystals a resistor is needed across the crystal (typically 1.5MR) to get the oscillator to start. On some high gain crystals a series resistor is needed to prevent the oscillator locking onto a harmonic. Are you sure your loading capacitors are the correct value (remember this is not Cl - the capacitors are in parallel with the pin capacitance's and in then in series with each other. ).
As some further comments, in your original version, since you say 'oscillator=', and don't specify a clock fuse, it'll have been selecting EC (external crystal oscillator), not HS ot XT. In your second version, just as in the first, you don't actually have to specify the oscillator fuses. The compiler does it for you. The PLL setup is not actually a fuse option, These chips all boot using their internal oscillator, and then switch on the PLL after boot. This is setup by the clock statement.
As one further comment, you do realise there is nothing special about 7.37 MHz, except that it is the frequency used by the internal oscillator. If using your own crystal, something like 8MHz, is much easier. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Sat Oct 01, 2016 6:14 pm |
|
|
Lots of information to digest! As always, thanks for the help!
But.... These nitty gritty details are a bit beyond my knowledge of how all this stuff works internally and although I read and re-read, sometimes I just cannot wrap my head around some topics.
I know the crystal works because I was able somehow to get the MCU to start-up because I use UART2 to display information on a serial console (TeraTerm) and I saw the information go through clearly. I used XT in the fuses so I would guess it was from my crystal. And if I put my scope on the pins (39 or 40, not sure), I see the signal and the frequency is correct.
The reason I am using 7.3728 is because I had it on-hand to test and didn't have the time to order the correct part, whichever that part will be once the clocking and PLL are figured-out.
On my original design, I use a 36.864MHz because this frequency is the closest I can use to 40MHz (max speed of the 24HJ). I am changing my MCU to the 24EP which can go up to 60MHz. However, that exact frequency of 36.864MHz is required because it is used for many other clocks on my circuit (115200 BPS on my UARTs with a calculated 0% error rate, specific sampling frequencies for the attached audio CODEC, precise PWM frequencies out of the PIC etc)....
So I need to have a multiple of that frequency and it just so happens that 7.3728 is 1/5 of that initial oscillator and I happened to have one on-hand out of nowhere (pure luck). So this is perfect for me to test but I will get a faster one later if needed. For now, I'm just testing.
I want to use a crystal rather than an oscillator because the oscillator alone draws 7.5mA.
Really, all I want is to be able to have a clocking signal of at least 36.864MHz just like on my original design, or faster, as long as it is a multiple of that frequency. Trust me, I had to make many calculations to get all the 5-6 different clocking signals I require and that frequency was the only one closest to 40MHz (the one before that was 24.576MHz I think). Frequencies like 32.768 had errors on the UART. Others were OK on the UART but were off on the PWM etc. And others were OK on the UART and PWM but failed to give me the correct clock dividers on my CODEC.... So that frequency or a multiple of that frequency is needed.
And if I use a slower external crystal, then I need to be able to use a PLL internally to increase the frequency.
So.... how do I configure the fuses and is this at all possible (I think the answer is yes, I am just not sure how).
Thanks again, your help is always appreciated.
Ben |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Sun Oct 02, 2016 6:36 am |
|
|
You need to start and prove the crystal is working.
The chip will in a lot of modes, by default use CKSFSM, which means it will continue using the internal 7.37MHz oscillator if the external one is not working.
#fuses XT, NOWDT, PR, WPOSTS16, CKSNOFSM
#use delay(CRYSTAL=7.3728MHz )
Then have a simple program just flashing an LED at 1/second intervals, and see if the LED flashes, and at the right rate.
You are probably being 'misled' that the oscillator is working....
With the frequency set for 7.37MHz, your code will apparently run if the oscillator has failed, since this is the frequency of the internal 'fall back' oscillator. With any other frequency setup, it'll run, but everything involving timings (serial etc.), will fail, since the clock will be wrong.
You can test if it has failed by testing 'INT_OSCFAIL':
Code: |
if (interrupt_active(INT_OSCFAIL))
{
//get here if the chip is running in oscillator failed mode
}
|
|
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Sun Oct 02, 2016 10:32 am |
|
|
Hi Ttelmah,
Quote: |
You need to start and prove the crystal is working. |
If I see 7.3MHz on one of the OSC pins on the chip (39 or 40, don't remember) using my oscilloscope, doesn't this mean the crystal is working? Not sure how the PIC does it internally but I would guess that the external oscillator would not show a signal if it was failing or mis-configured, correct? The PIC does something internally for the crystal to oscillate therefore if the crystal is bad, no oscillation would be present... which is not the case.
Also, rather than using an LED to prove the crystal is working, since this is a fully functional circuit with tiny SMD components (a circuit I designed, not a development board with plenty of place to put stuff like LED's and such), I can assume that if I see the correct text on my serial console (TeraTerm) through UART2, most likely the crystal is working. But let's say it is NOT working and I am seeing text, then it means that the internal crystal has kicked-in.
I could further prove this by adding the INT_OSCFAIL interrupt (which I've never thought of adding so thanks for that pointer).... so if the unit starts and the external crystal fails and the PIC falls-back to its internal crystal upon external failure, then I will be able to display the OSC failure on my terminal when I catch the interruption. Or as you indicated, just use the interrupt_active() function and display it on the serial console.
I have a 16.834MHz crystal so I can use it to prove that the fuses are properly configured.
So if this code of yours works:
Code: | #fuses XT, NOWDT, PR, WPOSTS16, CKSNOFSM (or CKSFSM to get the clock failure interrupt)
#use delay(CRYSTAL=7.3728MHz ) |
I will also add the following:
Code: |
enable_interrupt( INT_OSCFAIL );
#INT_OSCFAIL
void oscfail( void )
{
fprintf( SERIAL_MONITOR, "External OSC failure" );
} |
-OR-
poll the interrupt with the interrupt_active() function.
Bottom line: all I want is the fastest clock possible that is a multiple of 36.864MHz (or 7.3728MHz)...
Thanks again.
Ben |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Mon Oct 03, 2016 2:48 am |
|
|
You don't have to add the INT_OSCFAIL interrupt, just test it as I show.
Or turn off the fall back, and _prove_ whether the oscillator is actually working.
The fall back is also to 7.37MHz. If the oscillator was running properly, the signal should be on _both_ oscillator pins. If it is only on one, then there is a problem.
Point is that if the master oscillator was working, then:
#use delay( crystal = 7372800, clock=73728000 ) --> Clock is x10 the crystal speed
would work.
However if the master oscillator is not working, this would result in serial at 1/10th the selected rate (so garbage, unless you were looking for it), as the fail safe will fall back to 7.37MHz from the internal oscillator.
Like Temtronic, I'm a great believer in always having at least one pin that can be used as a LED diagnostic. They are great, since even if you don't fit the LED in production, for basic debugging, they are the simplest and most powerful tool/informative.
Point is, I have tested on your compiler version, and this setup:
Code: |
#include <24EP512GP806.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOCKSNOFSM //Fail safe disabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOJTAG //JTAG disabled
#device ICSP=1
#use delay(CRYSTAL=8MHz,CLOCK=80MHz)
//I hadn't got an 8MHz crystal
void main()
{
while(TRUE)
{
output_toggle(PIN_F1);
delay_ms(5000);
}
}
|
Merrily compiles and runs (actually on an EP256, hadn't got the 512 in anything), and at the right clock rate. So you have a problem preventing it working. Obvious thing is that the clock is not actually running. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Mon Oct 03, 2016 4:50 am |
|
|
Ok for the INT_OSCFAIL but I like the idea that if the oscillator fails, it will generate an interrupt. I can add the code to catch it and I could (I guess) change the clock setting to revert to the default clock and then send myself an SMS from the modem.
Trust me, I am a big proponent of diagnostics options such as LED's and serial ports because they are life savers but this circuit is past the R&D stage. My R&D board was like a christmas tree. This is the production circuit. I am now working on the upgraded version and I am simply going through a list of things that were not implemented on the first rev due to time constraints and the external oscillator was one thing to get rid of.
As for the oscillation of the crystal 7.3728MHz external crystal, I said I tested on one pin (39 or 40) but to be honest, I didn't look on both... only one. My mistake. I just took for granted that it worked on.
I will try this morning all you've explained when I get to work and I will post the results.
Thanks a million. Explanations always thorough and concise.
Benoit |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Mon Oct 03, 2016 10:48 am |
|
|
All right. The results are in and I'm confused:
Code: |
#fuses XT, WDT, PR, WPOSTS16, NOCKSNOFSM
#use delay( CRYSTAL=7.3728MHz ) |
With the above settings, I see my text on my serial monitor. So external crystal works just fine.
Desoldering the wire going to my crystal and keeping the above settings will result in showing only a few of the serial data bytes I send-out but then the data becomes just garbage data.... so this is expected, I don't have an external clock and the failsafe is inactive.
If I re-solder the wire on the crystal, all is back and working. In both cases above, the x10 PLL fuse <clock=73.728MHz> is not yet enabled.
Now, if I add <clock=73.728MHz> to the #use delay, this time I get just garbage data on the serial console.. So the <clock=xxx> fuse is doing something.
If I change the NOCKSNOFSM fuse to CKSNOFSM, I get the same results as above witout the clock=xxx (good data on my serial console) and with the clock=xxx or no crystal connected, garbage data on the serial console.
So.... the external crystal _is_ working. The fuses are causing clock issues and garbled data....
And changing the fuse to CKSFSM still doesn't change a thing.
Side note: Earlier today, *somehow*, I did something that worked where I simply toggled a pin hi-lo in a loop with the default crystal of 7.3728MHz and the pin toggled at 307.3KHz. I then added the clock=73.728MHz and the pin toggled at 3.073MHz (10x PLL). Then I did something.... no clue what it was... but since then it is no longer working hence why I am now very confused.
Here is the assembly code generated by code with PLL enable that *I thought* should have worked but is not:
Code: | #fuses XT, WDT, PR, WPOSTS16, CKSFSM
#use delay( CRYSTAL=7372800, CLOCK=73728000 )
074A6: CP0 W0
074A8: BTSC.B 42.1
074AA: BRA 74BC
074AC: REPEAT #FFB
074AE: NOP
074B0: REPEAT #3FFE
074B2: NOP
074B4: REPEAT #3FFE
074B6: NOP
074B8: DEC W0,W0
074BA: BRA NZ,74AC
074BC: RETURN |
I will post more if I find anything and any suggestions are welcome.
******************************
UPDATE 13h30:
******************************
Using these fuses:
#fuses XT, NOWDT, PR, WPOSTS16, CKSFSM
#use delay( crystal = 7372800, clock = 73728000 )
Then in my main.c file:
main()
{
while(1)
{
output_high( PIN_E7 );
output_low( PIN_E7 );
}
}
The code above generates a 307.3kHz signal on pin E7. This morning, I was able _somewhow_ to get 3.073MHz with the <clock> option.... but now, although the <clock> option is in there, the pin toggling still runs at 307.3kHz.
If I remove the pin toggling code above and just let my code run normally, printing stuff on the screen fails but I remove the <clock> option, then the code on the screen is displayed just fine.
So it points to the <clock> option... But why now it's not working and this morning it was working? No idea.
******************************
UPDATE 15h22:
******************************
Ok, seriously... don't know what's going-on...
This works e.g. I have text correct text on my serial monitor:
#fuses XT, WDT, PR_PLL, WPOSTS16, NOCKSNOFSM
#use delay( crystal=7372800 )
This doesn't work e.g. nothing on my serial monitor:
#fuses XT, WDT, PR_PLL, WPOSTS16, NOCKSNOFSM
#use delay( crystal=7372800, clock=73728000 )
Only difference is the <clock> option. And in both cases, if I change PR_PLL to PR, same effect as above, the one with <clock> option fails, the one without it works.
If I bypass the the regular code and simply jump to an infinite while() loop toggling pin E7, same idea; in both cases above, I always see a 307.3kHz signal no-matter if I use <clock> or not but I would expect to see a 3.073MHz signal when <clock> is present.... just like I saw once this morning... which for the love of me, I'm not able to reproduce. Happened once. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Tue Oct 04, 2016 2:37 am |
|
|
You are never going to get the right rate enabling the PLL, without the clock settings.
You need to understand what I said earlier. The PLL on this chip is _not_ setup by the fuses (except to enable the branch in the oscillator). The PLL is not something you can just 'turn on'.
The chip never wakes up using the PLL. It always wakes using the internal RC oscillator. It then sets up the PLL (which involves writing three separate division factors to the registers for this), then switches to it. Turning it on with the fuses, says to switch to this path after booting, but the registers won't be configured, so you could get almost anything as an output....
The ratio of 'clock' to 'crystal', determines what is put into these dividers.
Now what you are describing, especially talking about a 'wire' to the crystal, suggests you may be hitting a problem of crystal gain and layout.
The PLL circuit is more sensitive than the standard oscillator to the purity of the actual signal. It requires a really clean oscillator running stably at the specified frequency, without significant harmonic or overtone signals present.
You can get the PLL to run at the wrong frequency, by having the oscillator overdriven, and even to lock onto another frequency completely by having other signal traces too close to the oscillator pins, or any significant length in the oscillator traces. The crystal should be as close as possible to the PIC. No more than a very few mm away. Your mention of a 'wire' begins to raise doubts here.
With an external oscillator, the 'clock' input, is just an ordinary logic signal. With a crystal, it is an input to a reasonably high gain amplifier. Needs very different design. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Tue Oct 04, 2016 5:05 am |
|
|
Ok for the PLL fuse, I will remove it.
I know you've explaine lots of things, which I appreciate, the datasheets are also full of info and wrapping my head around all that gets difficult.
Regardless if the fuse is there or not, as much as I thought the code would run, it doesn't appear to be doing anything... EXCEPT if I remove the <clock = 73728000> then it runs fine at 7.3728MHz. So is there a way to know if the PLL has actually kicked-in? I thought I saw a bit in a register somewhere that would tell if the PLL is locked or not.
Given that the code runs if I remove the <clock> option and add the NOCKSNOFSM fuse, I guess it's safe to say that the crystal is fine?
As for the 'wires', I thought also about that... but don't forget, this PCB has tiny components with very fine pitch pins and it's difficult to go in and add things. I have to do this using a microscope. I've soldered wire-wrap wires to pins 39 and 40 as short as possible and used through-hole capacitors (18pf - that's what I had on-hand) to solder from the crystal pins to a close GND pin. I made sure that there is not short between the pins (the code runs with the crystal alone so contacts are fine!).
Also, Figure 9-1 'Oscillator system diagram' page 178 of the DS70616G datasheet for this chip states that:
'If the oscillator is used with XT or HS modes, an external parallel resistor with the value of 1M must be connected'.
So I've added that as well in-between the crysal pins - Not the nicest of the setups but as close as possible to the MCU... and quite frankly, it's cleaner than back in the days when I was doing this on breadboards where contacts were always loose and dirty.
I will be at work shortly so I will go through the steps again and try different things.
Thanks again,
Ben |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Tue Oct 04, 2016 6:26 am |
|
|
Maybe take this away from the compiler and do it yourself? I faced a (somewhat) similar issue with a dsPIC33 some time ago which I eventually traced to the PIC not being able to start its oscillator with PLL enabled given the crystal value on the PCB. The compiler version I was using at the time couldn't get it to start reliably given my restrictions. ...So I just "did it myself":
- specify a #use delay statement that causes the processor to start using the internal oscillator
- immediately after cut your own clock switchover code. Might require some special unlock code, probably in assembly
Refer to this thread for ideas: http://www.ccsinfo.com/forum/viewtopic.php?t=47757&highlight=pll+internal |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Tue Oct 04, 2016 6:40 am |
|
|
On the oscillator, no. You are missing the critical point about what I'm saying.
You can have a crystal oscillator that apparently runs OK, but get wrong frequencies when you enable the PLL. Commonly when the oscillator is overdriven (crystal gain too high). Pull the sheet 00849a.pdf from Microchip. Look at Figure-9, which is their full recommended circuit for the PIC oscillator. Note Rfext (this is the external resistor you have added - probably not necessary for you it helps the 'start up', and is dependant on the gain of the crystal, and the internal resistances in the particular type of PIC - that your oscillator starts every time, suggests that you have a high gain crystal). Then notice Rs. This is essential if the crystal is high gain. It is what stops the oscillator input from being overdriven. Now if the oscillator is overdriven, it'll apparently run OK, but will prevent the PLL from locking onto the correct frequency....
Read the paragraph after the diagram "Examining the Oscillator Output Signal". You ideally want a smooth sinusoid just getting close to the supply rails. If there is clipping, then the PLL can lock onto the wrong frequency.
Typically Rs values around perhaps 2KR are enough to stop the PLL from having this problem, but they describe using values much higher |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Tue Oct 04, 2016 7:55 am |
|
|
All right.... Reading the suggested datasheet <http://www.t-es-t.hu/download/microchip/an849a.pdf> and looking at Figure 9 then under the <Examining the Oscillator Output Signal> section, it states:
"On an oscilloscope the Osc-Out signal should be a nice clean sine wave that easily spans the input minimum of the clock-input pin (as much as 4V peak-to-peak for a 5V VDD)". I guess that by Osc-Out, they mean pin 40 (OSC2)?
I added the 2K series resistor 'Rs' between the crystal and OSC 2 and disconnected the 1M parralel resistor (as per your indication that it was most likely not required, regardless, it does not seem to change the behaviour if it's there or not).
My oscilloscope is set to 1V/div. My circuit is running at 3.52V.
For pin 39 - OSC 1 (directly to Xtal and C1): A 7.3MHz signal of about 216mV pk-pk biased at around 1.52V.
For Pin 40 - OSC 2 (with Rs = 2K), my measurements seem to coincide with the explanation: A 7.3MHz signal biased at around 1.5V with a pk-pk of around 2.8v (voltage swings between approximately 566mV-2.88V). Frequency does not drift or anything. It seems pretty stable. It is a nice sinewave, no glitches, no clipping, nothing special.
Then on the crystal directly on the other side of Rs coming from pin 40, the amplitude is attenuated and very low, I'd say the pk-pk voltage is around 400mV and 7.3MHz.
Does this seem correct?
Ben |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Tue Oct 04, 2016 8:15 am |
|
|
Yes. Sounds good.
You'll see that the Rfext, they here say is likely to only be needed by ceramic resonators with a lower gain.
Does it make any difference?. |
|
|
|
|
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
|