Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC24FJ Seems to refuse to accept config bits

Status
Not open for further replies.

Rich D.

Active Member
It appears config bits are not being set or followed on my PIC. Is there some thing disabling this feature?

I have been struggling with programming this PIC, even though I have much experience with dsPIC30s. First, I haven't been able to get it to switch clock speeds from the FRC /4 which is default, no matter what I tried. Next, I haven't been able to get the timers to time correctly. Now, I find that I can't control the watchdog timer period. All my problems seem to be related to the config bits. The only thing that seemed to work was turning off the JTAG.

I have a UART working and sending debug messages to a LCD, so the baud rate generator is working (though it had to be programmed for 1/4 speed to match the slow clock). As a result I can clearly see that the COSC bits are 111, but the NOSC bits are 001, indicating it is not performing a clock switch to the FRCPLL. I also have interrupts working reliably from the timers, but the time periods are seemingly random and out of control. In short, everything that is giving me a problem is related to the config bits and/or clock timing in some way, and they seem to not affect any changes to the programming.

Specifically, I am using a PIC24FJ128GA406, programming it with MPLAB-X and a PICkit 3. I am writing in assembly. Here is the beginning of my code which has the PRAGMA stuff (generated via MPLAB-X by the way).

;..............................................................................
; CONFIGURATION BITS:
;..............................................................................
;// PIC24FJ128GA406 Configuration Bit Settings
#include <xc.h>
;// FSEC
#pragma config BWRP = OFF // Boot Segment Write Protect (Boot segment may be written)
#pragma config BSS = OFF // Boot segment Protect (No Protection (other than BWRP))
#pragma config BSEN = OFF // Boot Segment Control bit (No Boot Segment)
#pragma config GWRP = OFF // General Segment Write Protect (Writes to program memory are allowed)
#pragma config GSS = OFF // General Segment Code Protect (Code protection is disabled)
#pragma config CWRP = OFF // Configuration Segment Program Write Protection bit (Configuration Segment may be written)
#pragma config CSS = DIS // Configuration Segment Code Protection Level bits (No Protection (other than CWRP))
#pragma config AIVTDIS = DISABLE // Alternate Interrupt Vector Table Disable bit (Disable AIVT)
;// FBSLIM
#pragma config BSLIM = 0x1FFF // Boot Segment Code Flash Page Address Limit bits (Boot Segment Flash page address limit)
;// FSIGN

;// FOSCSEL
#pragma config FNOSC = FRCPLL // Oscillator Select (Fast RC Oscillator with PLL module (FRCPLL))
#pragma config PLLMODE = PLL4X // Frequency Multiplier Select Bits (4x PLL selected)
#pragma config IESO = ON // Internal External Switchover (Start up with user-selected oscillator source)
;// FOSC
#pragma config POSCMOD = NONE // Primary Oscillator Select (Primary Oscillator disabled)
#pragma config OSCIOFCN = ON // OSCO Pin Configuration (OSCO/CLKO/RC15 functions as port I/O (RC15))
#pragma config SOSCSEL = OFF // SOSC Power Selection Configuration bits (Digital (SCLKI) mode)
#pragma config PLLSS = PLL_FRC // PLL Secondary Selection Configuration bit (PLL is fed by the on-chip Fast RC (FRC) oscillator)
#pragma config IOL1WAY = OFF // IOLOCK One-Way Set Enable (The IOLOCK bit can be set and cleared using the unlock sequence)
#pragma config FCKSM = CSECME // Clock Switching and Monitor Selection (Clock switching is enabled, Fail-Safe Clock Monitor is enabled)

;// FWDT
#pragma config WDTPS = PS32 // Watchdog Timer Postscaler (1:32) PRODUCES ABOUT 4 SECONDS TIMEOUT?
#pragma config FWPSA = PR32 // WDT Prescaler (Prescaler ratio of 1:32), OTHER OPTION IS 1:128
#pragma config FWDTEN = ON // Watchdog Timer Enable (Watchdog Timer is enabled)
#pragma config WINDIS = OFF // Windowed Watchdog Timer Disable bit (Standard Watchdog Timer enabled (Windowed-mode is disabled))
#pragma config WDTWIN = PS75_0 // Watchdog Window Select bits (Watch Dog Timer Window Width is 75 percent)
#pragma config WDTCMX = LPRC // WDT Clock Source Select bits (WDT always uses LPRC as its clock source)
#pragma config WDTCLK = LPRC // WDT Clock Source Select bits (WDT uses LPRC)
;// FPOR
#pragma config BOREN = ON // Brown-out Reset Enable bits (Brown-out Reset Enable)
#pragma config LPCFG = OFF // Low power regulator control (Disabled)
;// FICD
#pragma config ICS = PGx3 // Emulator Pin Placement Select bits (Emulator functions are shared with PGEC3/PGED3)
#pragma config JTAGEN = OFF // JTAG Port Enable (JTAG port is disabled)
#pragma config BTSWP = OFF // BOOTSWP Instruction Enable bit (BOOTSWP instruction is disabled)
;// FDS
#pragma config DSWDTPS = DSWDTPS0B // Deep Sleep Watchdog Timer Postscale Select bits (1:65,536 (2.114s))
#pragma config DSWDTOSC = LPRC // DSWDT Reference Clock Select bit (DSWDT uses Low Power RC Oscillator (LPRC))
#pragma config DSBOREN = ON // Deep Sleep Zero-Power BOR Enable bit (Deep Sleep BOR enabled in Deep Sleep)
#pragma config DSWDTEN = ON // Deep Sleep Watchdog Timer Enable bit (DSWDT enabled)
#pragma config DSSWEN = OFF // Deep Sleep Software Control Select Bit (Deep Sleep disabled)
;// FDEVOPT1
#pragma config ALTCMPI = DISABLE // Alternate Comparator Input Enable bit (C1INC, C2INC, and C3INC are on their standard pin locations)
#pragma config TMPRPIN = OFF // Tamper Pin Enable bit (TMPRN pin function is disabled)
#pragma config TMPRWIPE = OFF // RAM Based Entryption Key Wipe Enable bit (Cryptographic Engine Key RAM is not erased onTMPR pin events)
#pragma config ALTVREF = ALTVREFDIS // Alternate VREF location Enable (VREF is on a default pin (VREF+ on RA10 and VREF- on RA9))
;// #pragma config statements should precede project file includes.

.include "p24Fxxxx.inc"

...and so on....


Is there some reason the config bits are being ignored? They are the first lines of code in the main '.s' assembly file.
 
Have you tried removing the #pragma at the beginning of each line?

Mike.
 
His problem is this
Code:
#include <xc.h>
it's in the wrong place
Should look like this
Code:
// PIC24FJ128GA406 Configuration Bit Settings
// 'C' source line config statements
// FSEC
#pragma config BWRP = OFF               // Boot Segment Write Protect (Boot segment may be written)
#pragma config BSS = OFF                // Boot segment Protect (No Protection (other than BWRP))
#pragma config BSEN = OFF               // Boot Segment Control bit (No Boot Segment)
#pragma config GWRP = OFF               // General Segment Write Protect (Writes to program memory are allowed)
#pragma config GSS = OFF                // General Segment Code Protect (Code protection is disabled)
#pragma config CWRP = OFF               // Configuration Segment Program Write Protection bit (Configuration Segment may be written)
#pragma config CSS = DIS                // Configuration Segment Code Protection Level bits (No Protection (other than CWRP))
#pragma config AIVTDIS = DISABLE        // Alternate Interrupt Vector Table Disable bit (Disable AIVT)
// FBSLIM
#pragma config BSLIM = 0x1FFF           // Boot Segment Code Flash Page Address Limit bits (Boot Segment Flash page address limit)
// FSIGN
// FOSCSEL
#pragma config FNOSC = FRCDIV           // Oscillator Select (Fast RC Oscillator with divide-by-n (FRCDIV))
#pragma config PLLMODE = DISABLED       // Frequency Multiplier Select Bits (No PLL used; PLLEN bit is not available)
#pragma config IESO = ON                // Internal External Switchover (Start up device with FRC, then switch to user-selected oscillator source)
// FOSC
#pragma config POSCMOD = NONE           // Primary Oscillator Select (Primary Oscillator disabled)
#pragma config OSCIOFCN = OFF           // OSCO Pin Configuration (OSCO/CLKO/RC15 functions as CLKO (FOSC/2))
#pragma config SOSCSEL = ON             // SOSC Power Selection Configuration bits (SOSC is used in crystal (SOSCI/SOSCO) mode)
#pragma config PLLSS = PLL_PRI          // PLL Secondary Selection Configuration bit (PLL is fed by the Primary oscillator)
#pragma config IOL1WAY = ON             // IOLOCK One-Way Set Enable (Once set the IOLOCK bit cannot be cleared)
#pragma config FCKSM = CSDCMD           // Clock Switching and Monitor Selection (Clock switching and Fail-Safe Clock Monitor are disabled)
// FWDT
#pragma config WDTPS = PS32768          // Watchdog Timer Postscaler (1:32,768)
#pragma config FWPSA = PR128            // WDT Prescaler (Prescaler ratio of 1:128)
#pragma config FWDTEN = ON              // Watchdog Timer Enable (Watchdog Timer is enabled)
#pragma config WINDIS = OFF             // Windowed Watchdog Timer Disable bit (Standard Watchdog Timer enabled (Windowed-mode is disabled))
#pragma config WDTWIN = PS25_0          // Watchdog Window Select bits (Watch Dog Timer Window Width is 25 percent)
#pragma config WDTCMX = WDTCLK          // WDT Clock Source Select bits (WDT clock source is determined by the WDTCLK Configuration bits)
#pragma config WDTCLK = LPRC            // WDT Clock Source Select bits (WDT uses LPRC)
// FPOR
#pragma config BOREN = ON               // Brown-out Reset Enable bits (Brown-out Reset Enable)
#pragma config LPCFG = OFF              // Low power regulator control (Disabled)
// FICD
#pragma config ICS = PGx1               // Emulator Pin Placement Select bits (Emulator functions are shared with PGEC1/PGED1)
#pragma config JTAGEN = OFF             // JTAG Port Enable (JTAG port is disabled)
#pragma config BTSWP = OFF              // BOOTSWP Instruction Enable bit (BOOTSWP instruction is disabled)
// FDS
#pragma config DSWDTPS = DSWDTPS1F      // Deep Sleep Watchdog Timer Postscale Select bits (1:68,719,476,736 (25.7 days))
#pragma config DSWDTOSC = LPRC          // DSWDT Reference Clock Select bit (DSWDT uses Low Power RC Oscillator (LPRC))
#pragma config DSBOREN = ON             // Deep Sleep Zero-Power BOR Enable bit (Deep Sleep BOR enabled in Deep Sleep)
#pragma config DSWDTEN = ON             // Deep Sleep Watchdog Timer Enable bit (DSWDT enabled)
#pragma config DSSWEN = ON              // Deep Sleep Software Control Select Bit (Deep Sleep enabled and controlled by the DSEN bit)
// FDEVOPT1
#pragma config ALTCMPI = DISABLE        // Alternate Comparator Input Enable bit (C1INC, C2INC, and C3INC are on their standard pin locations)
#pragma config TMPRPIN = OFF            // Tamper Pin Enable bit (TMPRN pin function is disabled)
#pragma config TMPRWIPE = OFF           // RAM Based Entryption Key Wipe Enable bit (Cryptographic Engine Key RAM is not erased onTMPR pin events)
#pragma config ALTVREF = ALTVREFDIS     // Alternate VREF location Enable (VREF is on a default pin (VREF+ on RA10 and VREF- on RA9))
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#pragma go above #include <xc.h> not after if you put it after there not used so any changes don't happen.
 
Your main c should start like this
Code:
/*
 * File:   newmainXC16.c
 * Author: burt
 *
 * Created on December 21, 2017, 5:48 AM
 */
// PIC24FJ128GA406 Configuration Bit Settings
// 'C' source line config statements
// FSEC
#pragma config BWRP = OFF               // Boot Segment Write Protect (Boot segment may be written)
#pragma config BSS = OFF                // Boot segment Protect (No Protection (other than BWRP))
#pragma config BSEN = OFF               // Boot Segment Control bit (No Boot Segment)
#pragma config GWRP = OFF               // General Segment Write Protect (Writes to program memory are allowed)
#pragma config GSS = OFF                // General Segment Code Protect (Code protection is disabled)
#pragma config CWRP = OFF               // Configuration Segment Program Write Protection bit (Configuration Segment may be written)
#pragma config CSS = DIS                // Configuration Segment Code Protection Level bits (No Protection (other than CWRP))
#pragma config AIVTDIS = DISABLE        // Alternate Interrupt Vector Table Disable bit (Disable AIVT)
// FBSLIM
#pragma config BSLIM = 0x1FFF           // Boot Segment Code Flash Page Address Limit bits (Boot Segment Flash page address limit)
// FSIGN
// FOSCSEL
#pragma config FNOSC = FRCDIV           // Oscillator Select (Fast RC Oscillator with divide-by-n (FRCDIV))
#pragma config PLLMODE = DISABLED       // Frequency Multiplier Select Bits (No PLL used; PLLEN bit is not available)
#pragma config IESO = ON                // Internal External Switchover (Start up device with FRC, then switch to user-selected oscillator source)
// FOSC
#pragma config POSCMOD = NONE           // Primary Oscillator Select (Primary Oscillator disabled)
#pragma config OSCIOFCN = OFF           // OSCO Pin Configuration (OSCO/CLKO/RC15 functions as CLKO (FOSC/2))
#pragma config SOSCSEL = ON             // SOSC Power Selection Configuration bits (SOSC is used in crystal (SOSCI/SOSCO) mode)
#pragma config PLLSS = PLL_PRI          // PLL Secondary Selection Configuration bit (PLL is fed by the Primary oscillator)
#pragma config IOL1WAY = ON             // IOLOCK One-Way Set Enable (Once set the IOLOCK bit cannot be cleared)
#pragma config FCKSM = CSDCMD           // Clock Switching and Monitor Selection (Clock switching and Fail-Safe Clock Monitor are disabled)
// FWDT
#pragma config WDTPS = PS32768          // Watchdog Timer Postscaler (1:32,768)
#pragma config FWPSA = PR128            // WDT Prescaler (Prescaler ratio of 1:128)
#pragma config FWDTEN = ON              // Watchdog Timer Enable (Watchdog Timer is enabled)
#pragma config WINDIS = OFF             // Windowed Watchdog Timer Disable bit (Standard Watchdog Timer enabled (Windowed-mode is disabled))
#pragma config WDTWIN = PS25_0          // Watchdog Window Select bits (Watch Dog Timer Window Width is 25 percent)
#pragma config WDTCMX = WDTCLK          // WDT Clock Source Select bits (WDT clock source is determined by the WDTCLK Configuration bits)
#pragma config WDTCLK = LPRC            // WDT Clock Source Select bits (WDT uses LPRC)
// FPOR
#pragma config BOREN = ON               // Brown-out Reset Enable bits (Brown-out Reset Enable)
#pragma config LPCFG = OFF              // Low power regulator control (Disabled)
// FICD
#pragma config ICS = PGx1               // Emulator Pin Placement Select bits (Emulator functions are shared with PGEC1/PGED1)
#pragma config JTAGEN = OFF             // JTAG Port Enable (JTAG port is disabled)
#pragma config BTSWP = OFF              // BOOTSWP Instruction Enable bit (BOOTSWP instruction is disabled)
// FDS
#pragma config DSWDTPS = DSWDTPS1F      // Deep Sleep Watchdog Timer Postscale Select bits (1:68,719,476,736 (25.7 days))
#pragma config DSWDTOSC = LPRC          // DSWDT Reference Clock Select bit (DSWDT uses Low Power RC Oscillator (LPRC))
#pragma config DSBOREN = ON             // Deep Sleep Zero-Power BOR Enable bit (Deep Sleep BOR enabled in Deep Sleep)
#pragma config DSWDTEN = ON             // Deep Sleep Watchdog Timer Enable bit (DSWDT enabled)
#pragma config DSSWEN = ON              // Deep Sleep Software Control Select Bit (Deep Sleep enabled and controlled by the DSEN bit)
// FDEVOPT1
#pragma config ALTCMPI = DISABLE        // Alternate Comparator Input Enable bit (C1INC, C2INC, and C3INC are on their standard pin locations)
#pragma config TMPRPIN = OFF            // Tamper Pin Enable bit (TMPRN pin function is disabled)
#pragma config TMPRWIPE = OFF           // RAM Based Entryption Key Wipe Enable bit (Cryptographic Engine Key RAM is not erased onTMPR pin events)
#pragma config ALTVREF = ALTVREFDIS     // Alternate VREF location Enable (VREF is on a default pin (VREF+ on RA10 and VREF- on RA9))
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
int main(void) {
    return 0;
}
 
Burt,

The OP is writing in assembler which is why I suggested removing the #pragma's.

Mike.
 
Burt,

The OP is writing in assembler which is why I suggested removing the #pragma's.

Mike.
Ok why the heck is he adding
;..............................................................................
; CONFIGURATION BITS:
;..............................................................................
;// PIC24FJ128GA406 Configuration Bit Settings
#include <xc.h>
;// FSEC
 
Ok why the heck is he adding
;..............................................................................
; CONFIGURATION BITS:
;..............................................................................
;// PIC24FJ128GA406 Configuration Bit Settings
#include <xc.h>
;// FSEC
Well spotted, missed that.

Mike.
 
I haven't tried removing the #pragma, since I've never seen any documentation suggesting such a thing. I just now tried, and it fails to compile, or even give meaningful error messages.

As for the #include, I tried it positioned after (as it was generated) & before & commented out. It appears to not make any difference no matter where it is or if it is in there at all.

I suspect something else is wrong.
 
I don't know the PIC24F processor but can appreciate why there is confusion.

Here is example code straight from Mirocchip for a PIC32:
Code:
 ********************************************************************/
/*
** Message in a bottle <snip>
*/
#include <p32xxxx.h>
// Config settings
// POSCMOD = HS, FNOSC = PRIPLL, FWDTEN = OFF
// PLLIDIV = DIV_2, PLLMUL = MUL_16
// PBDIV = 8 (default)
// Main clock = 8MHz /2 * 16    = 80MHz
// Peripheral clock = 80MHz /8  =  10MHz
// Configuration Bit settings
// SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)
// PBCLK = 10 MHz
// Primary Osc w/PLL (XT+,HS+,EC+PLL)
// WDT OFF
// Other options are don't care
//
#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_8
// 1. define timing constant
#define SHORT_DELAY (50*8)
#define LONG_DELAY    (400*8)

In that example #include <xxxxx.h> is listed earlier than the #pragma and #define statements. The rest of the code is in C, but I don't understand why that should make a difference. Shouldn't "includes" always precede the first access to them?
 
I haven't tried removing the #pragma, since I've never seen any documentation suggesting such a thing. I just now tried, and it fails to compile, or even give meaningful error messages.

As for the #include, I tried it positioned after (as it was generated) & before & commented out. It appears to not make any difference no matter where it is or if it is in there at all.

I suspect something else is wrong.

Microchip in their infinite and near God like wisdom have decided to make building an assembly language project for the PIC24F family as difficult as possible. From figuring out how to invoke the assembler to initialization of the configuration words there are no useful examples to be found.

This is an example of how to construct a "main.S" example (and the capital S is important in the file name):
Code:
    .nolist
    .title " Sample PIC24FJ128GA406 Assembler Source Code"
    .sbttl " PORTD bit pulser"
    .psize 1000,132
    .list
;
; File: main.S
; Target: PIC24FJ128GA406
; IDE: MPLABX v4.05
; Compiler: XC16 v1.33
;
; Description:
;   This is a simple "hello world" demo
;   it pulses the bits on PORTD from
;   bit 0 to bit 7.
;
    .include "p24Fxxxx.inc"
    .text
;
; Setup configuration words
;
    config  __FBOOT,(BTMODE_SINGLE)
    config  __FSEC,(BWRP_OFF & BSS_OFF & BSEN_OFF & GWRP_OFF & GSS_OFF & CWRP_OFF & CSS_DIS & AIVTDIS_DISABLE)
    config  __FBSLIM,(0x1FFF)
    config  __FOSCSEL,(FNOSC_FRC & PLLMODE_PLL96DIV2 & IESO_OFF)
    config  __FOSC,(POSCMOD_NONE & OSCIOFCN_ON & SOSCSEL_OFF & PLLSS_PLL_FRC & IOL1WAY_OFF & FCKSM_CSECMD)
    config  __FWDT,(WDTPS_PS32768 & FWPSA_PR128 & FWDTEN_SWON & WINDIS_OFF & WDTWIN_PS25_0 & WDTCMX_WDTCLK & WDTCLK_LPRC)
    config  __FPOR,(BOREN_OFF & LPCFG_OFF)
    config  __FICD,(ICS_PGx2 & JTAGEN_OFF & BTSWP_OFF)
    config  __FDS,(DSWDTPS_DSWDTPS1F & DSWDTOSC_LPRC & DSBOREN_ON & DSWDTEN_ON & DSSWEN_ON)
    config  __FDEVOPT1,(ALTCMPI_DISABLE & TMPRPIN_OFF & TMPRWIPE_OFF & ALTVREF_ALTVREFDIS)

    .global __reset
__reset:
    mov     #__SP_init,w15      ; Initalize the Stack Pointer
    mov     #__SPLIM_init,w0    ; Initialize the Stack Pointer Limit Register
    mov     w0, SPLIM
    nop                         ; Add NOP to follow SPLIM initialization

    call    _wreg_init          ; Set all working registers to zero

    call    _PIC_init           ; Initialize this PIC

    mov     #0xFF00,w0          ; Set  PORTD pins as outputs
    and     TRISD               ; Make PORTD bits <7:0> outputs
    and     ANSD                ; Make PORTD bits <7:0> digital I/O

;
; Do a simple "hello world" bit pulser
;
    clr.b   LATD
    bset    LATD,#0
HelloLoop:
    call    delay
    rlnc.b  LATD

    bra     HelloLoop
;
; Delay loop
;
delay:
    mov     #0xffff,w6
dloop:
    nop
    nop
    nop
    nop
    dec     w6,w6
    cp0     w6
    bra     nz,dloop
    return
;
; Initialize W registers to zero
;
_wreg_init:
    clr     w0
    mov     w0,w14
    repeat  #12
    mov     w0,[++w14]
    clr     w14
    return
;
; Oscillator switch
;   Input:  w0 = oscillator source selected
; Notes:
;   All interrupts must be disabled before
;   calling this function.
;
_OscSwitch:

    mov     #0x78, w1           ; OSCCONH unlock code 1
    mov     #0x9A, w2           ; OSCCONH unlock code 2
    mov     #OSCCONH, w3
    mov.b   w1, [w3]
    mov.b   w2, [w3]
    mov.b   w0, [w3]

    mov     #0x46, w1           ; OSCCONL unlock code 1
    mov     #0x57, w2           ; OSCCONL unlock code 2
    mov     #OSCCONL, w3
    mov.b   w1, [w3]
    mov.b   w2, [w3]
    bset.b  [w3],#OSWEN         ; Request switch to new oscillator selection

 
    mov     #10000, w0
_WaitForOscSwitchLoop:
    btss    OSCCON,#OSWEN
    return
    dec     w0, w0
    bra     NZ, _WaitForOscSwitchLoop
    return
;
; Wait for PLL to lock
;
_WaitForPllLock:
    mov     #10000, w0
_WaitForPllLockLoop:
    btsc    OSCCON,#LOCK
    return
    dec     w0, w0
    bra     NZ, _WaitForPllLockLoop
    return
;
; Initialize this PIC
;
_PIC_init:
    ;
    ; Disable all interrupt sources
    mov     #0,w0
    disi    #0x3FFF             ; disable interrupts for 16383 cycles
    mov.w   w0,IEC0
    mov.w   w0,IEC1
    mov.w   w0,IEC2
    mov.w   w0,IEC3
    mov.w   w0,IEC4
    mov.w   w0,IEC5
    mov.w   w0,IEC6
    mov.w   w0,IEC7
    disi    #0x0000             ; enable interrupts
;
; At Power On Reset the configuration words set the system clock
; to use the FRC oscillator. At this point we need to enable the
; PLL to get the system clock running at 32MHz.
;
; Clock switching on the 24FJ family with the PLL can be a bit tricky.
;
; First we need to check if the configuration words enabled clock
; switching at all, then turn off the PLL, then setup the PLL and
; finally enable it. Sounds simple, I know. Make sure you verify this
; clock setup on the real hardware.
;
    btsc    OSCCON,#CLKLOCK
    bra     _PIC_init_clock_locked
 
    mov     #0x00, w0           ; Select primary oscillator as FRC
    rcall   _OscSwitch
 
    mov     #0,w0
    mov.w   w0,CLKDIV           ; Set FRC for 8MHz operation
 
    mov     #0x01, w0           ; Select primary oscillator as FRC+PLL
    rcall   _OscSwitch
    rcall   _WaitForPllLock     ; FRC at 8MHz, PLL96 input divisor is 1:2
                                ; System clock is 32MHz
                                ; Instruction clock is 16MIPS
_PIC_init_clock_locked:

    bset    INTCON1,#NSTDIS     ; Disable interrupt nesting

    return

    .end
<EDIT>
This code did not switch to the oscillator correctly.
 
Last edited:
Thanks this is what I found
Microchip, in their infinite and god like wisdom, has decided to adopt the Linux (Unix) convention for naming source files.

This means that assembly language files MUST use a .s or .S as the last two characters of the file name.

IT MATTERS THAT THE S IS UPPER OR LOWER CASE. EVEN ON A WINDOZE BOX.

When the file name ends with an upper case S then the file is passed through the C pre-possessor before it goes to the assembler.

This may be optional for XC8 but it is mandatory for XC16 and XC32 unless you want to edit the make file each time the MPLABX IDE writes a new one before the build is started.

It been listed as a bug too there's post about it going to be fixed but thats been years ago.
 
I tried renaming from '.s' to '.S'....didn't make a difference. It compiled and loaded, but ran with no differences.
The config bits don't appear to be written for a PIC24FJ128GA406, but I tried them anyways.
For one thing, I believe this particular flavor of PIC doesn't have the 96MHz PLL clock, that is only for the GB chips with the USB.

Well gosh darn any old how! It did get the clock working at 16MHz, but I need to look into the rest of the config bits, and see if I can control the watchdog and timers correctly.

I've spent the better part of the last 4 months collecting documentation from Microchump, but I still haven't found any documentation that specifically includes all the wording to set config bits.
Anybody ever see any documentation like that?
 
OK, I found the descriptions for the config bits, they are in the Microchip supplied files for each processor. In my case it is "p24FJ128GA406.inc", but I must confess I gathered so many microchip files I don't know where I got it from, it might have been on their website, or maybe in the MPLAB-X directories installed, but they were somewhere.

I would have hoped and expected they could have placed this in the chip's specification file, or some other file specific to each processor type, but that would only be convenient to the users. Since I am an assembly programmer, I understand why they had to go out of their way to make my life a living hell to discourage me from ever trying to program a microchip product using assembly.

So why did I commit to microchip 12 years ago?
Their MPLAB software loaded ok, but my inquiry to Texas Instruments as to which assembly/programmer software to use (they supplied two of them) for the MPS430 was met with complete silence.
So I went with Microchip.
I wonder how different my life would have been if I had used TI parts instead?
 
So there is still a problem with this config setting. I am trying to use a watchdog timer. This config setting is (I think) a default) where the line of code is:
config __FWDT,(WDTPS_PS32768 & FWPSA_PR128 & FWDTEN_SWON & WINDIS_OFF & WDTWIN_PS25_0 & WDTCMX_WDTCLK & WDTCLK_LPRC)

To me that means a pre scaler of 1:128 and a post scaler of 1:32768 which would allow for hours or days or weeks before the watchdog timed-out. I'm looking for a second or two, so the value of "WDTPS_PS32768" as defined here and also in the microchip literature was changed to "WDTPS_PS32". Guess what...

Now the chip doesn't even fire up, no LED flashing. Nothing. Like it was dead. I try all different values, changing both pre-scaler and post-scaler, forcing the timer on with FWDTEN_ON, and WDTCMX_LPRC. nothing is working,
I believe I am still not actually controlling the config bits properly, it's a f#%^&ing mess. It only works when I revert back to the original config settings with a 96MHz PLL /2...which incidentally, should be 48 MHz which is both faster than the specs allow for and in direct conflict with what the specs and/or family reference manual states, which is that this particular flavor doesn't have that type of PLL!
C'mon now, I can't be this stupid, can I?!
 
I got this to work. I don't know how but it does. Kind of like putting 1000 monkeys at a MPLAB-X for 1000 years, you will eventually get some working code.

config __FWDT,(WDTPS_PS2048 & FWPSA_PR32 & FWDTEN_ON & WINDIS_OFF & WDTWIN_PS25_0 & WDTCMX_LPRC & WDTCLK_LPRC) ;SET FOR 2 SEC TIMEOUT.
 
Oh, this just keeps getting better and better!!!

I have had this in from the post #10, and it actually worked to get me to 16MHz. It has the clock switching OFF:

" config __FOSCSEL,(FNOSC_FRC & PLLMODE_PLL96DIV2 & IESO_OFF)"

and it's been working at 16 MHz, showing COSC=1 and NOSC=1. All good, right?

Well scrolling thru my code I found this line:

rcall ClockSwitch

which simply calls a short clock switch routine as described in all the chip specs...you know...the unlock sequence...setting the bit to start clock switching...yes, that.

It was an old piece of code when I was trying to switch to a new, faster clock that never was effective. I thought it was already removed.
Since I didn't think it was needed or even helpful, I removed it.
GUESS WHAT! Without that call to switch the clock, it again only ran at 4 MHZ.
I put it back in, and we are working at 16 MHz again.

So apparently my clock switching is working fine. Which is good since I am starting up with a 96MHz PLL that isn't supposed to be in the chip.

1000 Monkeys...
 
Rich,

It can take a very close reading of the PIC24FJ128GA406 data sheet and Family Reference Manual to resolve the issues that have confused you.

To help let me try to explain:
  • The GA406 does in fact have both PLL blocks implemented even though the GA parts do not have the USB function block.

  • The 96MHz PLL always provides a 32MHz to the CPU clock chain.
    This can be changed by the CPDIV bits in the CLKDIV register (default is for a system clock of 8MHz).
    For parts with USB this also provides a 48MHz clock to the USB function block.

  • The reason Microchip has two PLLs is that the 96MHz PLL uses more power than the x4/6/8 PLL.
This is the PLL block diagram:

FIG_9-2_PIC24FJ128GA406.png


I hope this is understandable.
 
Last edited:
The GA406 does in fact have both PLL blocks implemented

Yes, indeed it does! I am watching it work right now! The section of the PIC24F Family Reference Manual 6.4.2. Reads as follows, which lead me to believe it didn't have that part:

For PIC24F devices featuring USB functionality (for example, the PIC24FJ256GB110 family), the CPDIV<1:0> bits (CLKDIV<7:6>) select the system clock speed when the USB module is
enabled and active. Their function is covered in more detail in Section 6.6.2 “96 MHz PLL Block”.
Where available, the PLLEN bit (CLKDIV<5>) enables the 96 MHz PLL module that generates the 96 MHz clock source for USB and graphics controller modules. The G1CLKSEL bit
(CLKDIV<4>) further selects the clock source for the graphics controller module. This selection is also described in Section 6.6.2 “96 MHz PLL Block”.


That doesn't specifically say it's NOT there, it only suggests that. It says it is also described in section 6.6.2.
There in section 6.6.2 it starts with the following

For PIC24F devices with USB features (such as the PIC24FJ256GB110 family) and graphics controller features (such as the PIC24FJ256DA210 family), a 96 MHz PLL block is implemented
to generate the stable 48 MHz clock required for full-speed USB operation...

Which again leads me to believe that if devices with USB has this, is it fair to assume devices without USB don't have this? That's how I read it anyways. Not being absolutely sure, I read thru the specifications
at least 4 or 6 times and found nothing that specifically says that is or isn't there. And either way, it does say the 4X PLL is there, so I thought obviously if I were to use that all would be fine,
but apparently the plain-old 4X PLL mode wasn't working.


Still, I'm not sure setting up the clock in a different mode would have solved my problems...I did try all those modes. It appears that none of my config bit settings were being implemented anyways.
I only got control of the config bits when I scrapped all that pragma stuff and went back to the "older" config macro method you suggested I try again. The .S vs. .s change didn't seem to help.
By using config..., I not only got it to clock at 16MHz, but my watchdog suddenly started timing out when I asked it to.

In the past, I've only coded with config. I still don't know what a "pragma" is, how it's implemented, never heard of it, or even whether it works for assy code, I just know it wasn't working for me.
Either way, thanks Dan Soze for the help. You got me back in the ballgame.
 
as you can't be bothered to read the MicroChip
I'm not sure how to interpret this. If you were trying to take a jovial stab at me, then "Ha ha ha, you got me!"

But my first reaction was that you are being mean-spirited and insulting, and my reaction was quite negative. You imply that I am too stupid or lazy to bother reading the manual, which is far from accurate.
I have been reading all these manuals for 12 years now, and I have many megabytes of all those Microchip specs and references. I even printed out several binders full of specs and reference manuals, which I sometimes sit and read in my spare time. It is always my first course of action to re-read relevant sections, but please excuse me for not having memorized each and every paragraph of the thousands that are available for a new chip family I haven't worked with.

I suppose by not reading the manuals, I was just lucky getting my board powered up and working, and successfully got the UART and interrupt controllers working, as well as randomly typing in the correct assembly language code. I did the same to get everything working on the touch screen LC display too! And if that's not all, I have dozens of dsPIC projects I got working with many of Microchip's peripherals also by not reading any manuals! Yea...I'm that good! I've also done the same with
older Motorola 68302 processors, and those without peripherals, the 8080s, 8085s, 8086s, 80186s, and 6502 processors! But I would never sink so low as to read the manuals!

In short, I will give you the benefit of the doubt that you were trying to be funny. If I didn't I would be dismayed to think that with no direct evidence either way, you would assume I can't or didn't read the documentation related to my profession.
I will not think that although maybe I am not as bright or experienced as you, you would make it a regular practice to insult those that only seek the same knowledge? If I were to think that, I would have to wonder why you bother to respond if you are not willing to contribute constructively?
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top