PIC24FJ64GA002 not running at speed

I'm trying to get my PIC24FJ64GA002 running at 32 Mhz. I measure the frequency on OSCO pin, and it's only 4 Mhz. Here's my code:

config  __FOSCSEL, FNOSC_FRCPLL & IESO_OFF
config  __FOSC, FCKSM_CSECMD & OSCIOFNC_ON

mov        #0x1182,        W0                    ; OSCCON
mov        #0x0000,        W1                    ; CLKDIV
mov        #0x0000,        W3                    ;OSCTUN

mov        W0,                OSCCON
mov        W3,                OSCTUN
mov        W1,                CLKDIV


It looks like you are not switching the clock - if it's anything like the dsPIC I recently used, you can only switch to the PLL after the primary oscillator (INTRC or EXT XTAL) is running.

To do this you use an unlock sequence that is detailed in the manual. I just had a quick look and it's there for your chip with explanation on page 93.

There are macros in the C30 library (just for info if you plan to use C at some point) to unlock and write to the necessary OSC registers and do the same thing, but I can't see them mentioned there (will be in the C30 manual).
Anyway, try following the instructions on that page and let us know, if it still doesn't work I'll look again (think I might have one of those PIC24s round here somewhere to test if necessary)

EDIT - For reference, below is the code in question. You need to put 0x03 (the code for external crystal with PLL) in W0 just before it executes. You probably want to have a small delay after the switch to allow the new clock to settle, and check OSWEN and the LOCK bit to make sure the switch was successful.

;Place the new oscillator selection in W0
OSCCONH (high byte) Unlock Sequence
MOV #OSCCONH, w1
MOV #0x78, w2
MOV #0x9A, w3
MOV.b w2, [w1]
MOV.b w3, [w1]
;Set new oscillator selection
MOV.b WREG, OSCCONH
;OSCCONL (low byte) unlock sequence
MOV #OSCCONL, w1
MOV #0x46, w2
MOV #0x57, w3
MOV.b w2, [w1]
MOV.b w3, [w1]
;Start oscillator switch operation
BSET OSCCON,#0


EDIT

I had another look and I think you should be able to start up with using the FRC with PLL on this chip (on the dsPIC it was only with xtal anyway IIRC) I'll leave the above there for reference about switching anyway.

My second guess is that I think you have the config wrong - looking and the .inc file shows that the configurations for the OSC, etc are in config2, not config.
Check for yourself in your ASM30 folder - it should be under something like:
C:\Program Files\Microchip\MPLAB ASM30 Suite\Support\PIC24F\inc)
Also note the notes regarding setting the config bits either with macro or the longer way. Make sure you have these correct.
Also, it might be worth putting in a check for the PLL LOCK bit (in the OSCCON register - see this FRM Oscillator document for the most thorough discussion. With the larger PICs you will need the family reference manual anyway, so grab all the parts from microchip if you haven't got them)

• Thanks for your suggestion! I added the code, and it does appear to switch speeds, but the PLL still won't come on. I'm using the FRC (Fast RC oscillator), so it's 0x01, not 0x03. – Adrian Sarli Dec 21 '11 at 2:16
• Ah, thought you were using an external crystal. After more reading I think you should be able to use the PLL without switching. See edits for more thoughts. Let me know how it goes.. – Oli Glaser Dec 21 '11 at 2:58
• It works! I changed the line to: – Adrian Sarli Dec 21 '11 at 12:41
• config __CONFIG2, FNOSC_FRCPLL & IESO_OFF – Adrian Sarli Dec 21 '11 at 12:41

According to the data sheet:

The processor clock source is divided by two to pro- duce the internal instruction cycle clock, FCY. In this document, the instruction cycle clock is also denoted by FOSC/2. The internal instruction cycle clock, FOSC/2, can be provided on the OSCO I/O pin for some operating modes of the primary oscillator.

So, if you are getting 4MHz out from the OSCO pin then the internal oscillator must be running at 8MHz.

8MHz is the base frequency of the internal Fast RC oscillator.

To get to 32MHz the 8MHz must go through the PLL to multiply it by 4.

In theory, with a clock of 32Mhz you should see 16MHz on the OSCO pin.

This you are supposedly already doing, both through the configuration settings and the OSCCON register.

All your postscalers are set to 1:1, which is good.

Things to try and/or clarify:

1. Is the core actually running at only 8MHz, or is the OSCO pin giving the pre-PLL frequency (unlikely)? Try running a simple program which toggles an IO pin HIGH and then LOW in the space of $2 T_{CY}$ and measure the width of the pulse.
2. Try running the chip with an external crystal at 8MHz and use the PLL to try and get 32MHz. This can just be a temporary arrangement to confirm the PLL is being enabled.
3. Investigate looking at the state of the PLL to ensure it has settled as the first thing your program does. I couldn't see exactly which flag to check for this during my cursory glance through the datasheet, but if using the PLL it should always be the first thing your program does.
• I implemented your idea of the test program, and it seems to be going 1/4 the expected speed if we had 16 MIPS. For some reason, the PLL isn't locking. I tried another chip, to see if it was defective, but it didn't help. – Adrian Sarli Dec 20 '11 at 19:00
• I am using MPLab X Beta 7.12. Haven't updated to the final yet. Don't know if that could possibly make a difference. – Adrian Sarli Dec 21 '11 at 2:22