• AVR Freaks

Hot![RESOLVED] PIC24FJ256GB606 error in data sheet.

Page: 12 > Showing page 1 of 2
Author
cea
Starting Member
  • Total Posts : 88
  • Reward points : 0
  • Joined: 2006/02/17 00:01:25
  • Location: 0
  • Status: offline
2018/12/27 14:03:43 (permalink)
0

[RESOLVED] PIC24FJ256GB606 error in data sheet.

I have been trying to get fractional division to work with the reference oscillator output.
 
The integer division works as expected but I cannot set the REFOTRIML register to a non-zero value.
 
The data sheet (DS30010074F) does not document any special write methods for the REFOTRIML register.
 
The errata (DS80000674H) does not list any issues with the reference oscillator.
 
I have requested help from Microchip support (case 00366206) but the response is more clueless than I am.
So if any one can show me how to setup the reference oscillator fractional division it would be really helpful.
 
This is what I have so far:
    /* Setup reference oscillator output */
    REFOCONL = 0;
    while(REFOCONLbits.ROACTIVE) REFOCONL = 0;
    REFOCONH  = 3u;
    REFOCONL = (    (0b0110 << _REFOCONL_ROSEL_POSITION) \
                |   (0b1    << _REFOCONL_ROSLP_POSITION) \
                |   (0b1    << _REFOCONL_ROOUT_POSITION) \
                |   (0b1    << _REFOCONL_ROSWEN_POSITION) \
               );
    REFOTRIML = 464u<<7u;
 
 
 
    Nop();
    Nop();
    Nop();
 
 
 
    REFOCONLbits.ROEN    = 1;

I am trying to divide the 96MHz PLL output by 2*(3+464/512) to get a 12.288MHz output.
 
At this point though I would like to know if my issues with the fractional division is a silicon bug in the PIC24FJ256GB606. If it is does it also occur in the PIC24FJ128GA606, PIC24FJ256GA606, PIC24FJ512GA606, PIC24FJ1024GA606, PIC24FJ128GA610, PIC24FJ256GA610, PIC24FJ512GA610, PIC24FJ1024GA610, PIC24FJ128GB606, PIC24FJ256GB606, PIC24FJ512GB606, PIC24FJ1024GB606, PIC24FJ128GB610, PIC24FJ256GB610, PIC24FJ512GB610, PIC24FJ1024GB610 parts too.
 
<EDIT>
Update title.
post edited by cea - 2019/01/11 12:56:12
#1

20 Replies Related Threads

    davekw7x
    Entropy++
    • Total Posts : 1766
    • Reward points : 0
    • Joined: 2012/01/16 12:01:07
    • Location: Left Coast, USA
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2018/12/27 21:53:50 (permalink)
    4 (2)
    There was a recent thread about this for a specific device or two.  Search ROTRIM on this forum
     
    Here's my story:
    After updating XC16 v1.35 to v1.36, I discovered that one of my MCC projects (with a PIC24FJ256GA705) will no longer compile because the MCC-generated file has an assignment for REFOTRIMLbits.ROTRIM (to zero).  Sure enough, REFOTRIMLbits.ROTRIM is not defined in the most recent processor-specific header, but it was defined in the previous version.  Now, it happens that I don't need ROTRIM, so it didn't create any problem in the actual project once I commented out the ROTRIM assignment statement.
     
    Anyhow...
    I did a little search and found the following:
     
    By my count, there are 25 header files for which the ROTRIM stuff is defined in v1.35 but not in v1.36.  (See Footnote)
     
    < p24FJ1024GA606.h
    < p24FJ1024GA610.h
    < p24FJ1024GB606.h
    < p24FJ1024GB610.h
    < p24FJ128GA606.h
    < p24FJ128GA610.h
    < p24FJ128GA702.h
    < p24FJ128GA704.h
    < p24FJ128GA705.h
    < p24FJ128GB606.h
    < p24FJ128GB610.h
    < p24FJ256GA606.h
    < p24FJ256GA610.h
    < p24FJ256GA702.h
    < p24FJ256GA704.h
    < p24FJ256GA705.h
    < p24FJ256GB606.h
    < p24FJ256GB610.h
    < p24FJ512GA606.h
    < p24FJ512GA610.h
    < p24FJ512GB606.h
    < p24FJ512GB610.h
    < p24FJ64GA702.h
    < p24FJ64GA704.h
    < p24FJ64GA705.h


    Now, I could be wrong (wouldn't be the first time) but until I heard otherwise, I would assume that the ROTRIM stuff can't be expected to work on these devices.
     
     
    Regards,

    Dave
     
    Footnote:
    Note that there are a total of 134 header files in v1.36 that define the ROTRIM stuff, including six new ones (for dsPIC33CK devices) added since v1.35.  I haven't tested any others.
    post edited by davekw7x - 2018/12/27 22:55:55

    Sometimes I just can't help myself...
    #2
    cea
    Starting Member
    • Total Posts : 88
    • Reward points : 0
    • Joined: 2006/02/17 00:01:25
    • Location: 0
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2018/12/28 01:12:21 (permalink)
    0
    Dave,
     
    From what you have posted, the take away is that Microchip knows the fractional division function does not work in the PIC24FJ256GB606 but has not as yet updated the data sheet or errata to inform customers on this issue.
     
    Charles.
    post edited by cea - 2018/12/28 14:07:48
    #3
    davekw7x
    Entropy++
    • Total Posts : 1766
    • Reward points : 0
    • Joined: 2012/01/16 12:01:07
    • Location: Left Coast, USA
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2018/12/28 07:18:16 (permalink)
    4.33 (3)
    charles@socketcom
    ... is the take away that Microchip knows the fractional division function does not work in the PIC24FJ256GB606 but has not as yet updated the data sheet or errata to inform customers on this issue.

     
    That's my guess.
     
    I indicated in my comments on another thread that I had conducted some testing (with the previous revision of XC16) and I could not figure out a way to set ROTRIM to anything other than zero.  At first I was thinking that there was some undocumented "lock" bit that we need to know about.
     
    Then...
    The fact that the compiler group actually removed the definitions from the most recent compiler release sort of means (to me at least) that someone at Microchip knows about something more serious that they haven't made public.  It also seems to me that if it were something that they were planning to fix in future revisions of the chips it would have been added to the errata.  If they don't expect to fix it, then the data sheets would be revised, but I'm guessing that revising data sheets is a much longer process than producing errata.
     
    Your experience with the support team is particularly pathetic.  It seems that they should have been told as soon as the bug was discovered.


     
    Oh, well...
     
     
    Regards,

    Dave
    post edited by davekw7x - 2018/12/28 07:28:36

    Sometimes I just can't help myself...
    #4
    cea
    Starting Member
    • Total Posts : 88
    • Reward points : 0
    • Joined: 2006/02/17 00:01:25
    • Location: 0
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2018/12/28 14:02:53 (permalink)
    4 (1)
    I suspect that this is more of a documentation screw up and not a silicon bug.
     
    From looking at the devices in the PIC24FJ family none of those have fractional division functionality on the clock chain.
     
    The sections in the datasheet look like a cut and paste from dsPIC33 or PIC32MZ datasheets.
     
    It appears that Microchip has focused more on acquisitions than engineering and this is the result.
    #5
    davekw7x
    Entropy++
    • Total Posts : 1766
    • Reward points : 0
    • Joined: 2012/01/16 12:01:07
    • Location: Left Coast, USA
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2018/12/28 18:59:34 (permalink)
    4 (1)
    charles@socketcom
    I suspect that this is more of a documentation screw up and not a silicon bug.

    Maybe it's not an "either-or" thing.  Perhaps it is an "all of the above" thing.
     
    charles@socketcom
    From looking at the devices in the PIC24FJ family none of those have fractional division functionality on the clock chain.

    Actually that is not true.
    I have attached a file showing the 134 header files in XC16 version 1.36 that ROTRIM stuff defined.
     
    Some of them have REFOTRIML  mentioned in their data sheets; some do not.  (See Footnote)
     
    Now, just for kicks I resurrected an old PIC24FJ128GB204 project (since the use of ROTRIM is described in its data sheet) and added Reference Clock output to it and tried with different ROTRIM values.  I picked a low value for RODIV so that differences made by ROTRIM would be easy to see on a 'scope.
     
    Here is the result
        System clock is 32 MHz
        RODIV set to 4
     
    I looked at output on my 'scope and got the following (as close as I can read it):
     
    ROTRIM = 0 yields 4 MHz output (32 / 2*4)  Check!
    ROTRIM = 256 yields 3.55 MHz  (32 / (2*(4+256/512))  Check!
    ROTRIM = 511 yields 3.20 MHz (32 / (2*(4+511/512))  Close Enough!
     
     
    Bottom line: Before committing to a particular part and before generating the PC board, check it out.  Not only in the data sheet, but with real hardware.
     
     
    Regards,
     
    Dave
     
    Footnote: Note that ROTRIM is not mentioned in the Data Sheet for dsPIC33CH128MP508, even though its header file defines the ROTRIM.  I tried a quick check in my evaluation project and was neither shocked nor surprised to discover that ROTRIM does not work for this chip.  Oh, well...
     
     
    post edited by davekw7x - 2018/12/28 21:15:16

    Sometimes I just can't help myself...
    #6
    cea
    Starting Member
    • Total Posts : 88
    • Reward points : 0
    • Joined: 2006/02/17 00:01:25
    • Location: 0
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2018/12/28 23:18:54 (permalink)
    4 (1)
    davekw7x
    charles@socketcom
    I suspect that this is more of a documentation screw up and not a silicon bug.

    Maybe it's not an "either-or" thing.  Perhaps it is an "all of the above" thing.

    Well it seems I have got the attention of a technical support staffer.
     
    The staffer has ordered a real PIC24FJ256GB606 part to try to create a "working" example using real hardware.
     
    I have read most of the other forum threads related to this issue. Since the members here have not come up with a solution it probably does not exist.  So I wish the Microchip support staff luck but not holding my breath.
     
    <EDIT>
    p.s.
    davekw7x
    Bottom line: Before committing to a particular part and before generating the PC board, check it out.  Not only in the data sheet, but with real hardware.

    At this point we cannot trust that the datasheet or errata are accurate and up to date we now have to validate the functionality of all of the features we need to use now or plan to use in the future.
     
    It seem I have the privilege of paying Microchip for the opportunity to proof read datasheets, beta test silicon and train support staff. 
    post edited by cea - 2018/12/29 16:21:20
    #7
    MBedder
    Circuit breaker
    • Total Posts : 6767
    • Reward points : 0
    • Joined: 2008/05/30 11:24:01
    • Location: Zelenograd, Russia
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2018/12/29 02:15:28 (permalink)
    4 (1)
    charles@socketcomIt seem I have the privilege of paying Microchip to proof read datasheets, beta test silicon and train support staff.
    LoLLoLLoL


    #8
    Howard Long
    Super Member
    • Total Posts : 676
    • Reward points : 0
    • Joined: 2005/04/04 08:50:32
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2018/12/29 06:41:45 (permalink)
    0
    A quick note, the PIC24FJ256GA705 family doesn't claim to support REFOTRIM in the latest DS DS30010118D, but it does in the older DS30010118C.
     
    Edit: I just tried it on silicon and the REFOTRIM register doesn't even update.
    post edited by Howard Long - 2018/12/29 06:49:13
    #9
    cea
    Starting Member
    • Total Posts : 88
    • Reward points : 0
    • Joined: 2006/02/17 00:01:25
    • Location: 0
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2018/12/29 16:20:02 (permalink)
    0
    I diffed the DS30010118D and the DS30010118C datasheets.
     
    All occurrences of REFOTRIML in the DS30010118C datasheet have been removed from the DS30010118D datasheet.
     
    The document history section has no record of this change.
     
    Microchip is likely to do the same thing with the PIC24FJ256GB606 datasheet.
     
    This is going to be painful as we will need to return the reel of these we purchased. We going to try to get Microchip to wave the restocking fee.
    post edited by cea - 2018/12/29 23:07:54
    #10
    mlp
    boots too small
    • Total Posts : 760
    • Reward points : 0
    • Joined: 2012/09/10 15:12:07
    • Location: previously Microchip XC8 team
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2018/12/31 13:15:31 (permalink)
    0
    davekw7x
    The fact that the compiler group actually removed the definitions from the most recent compiler release

    I believe the headers for all 3 compilers are auto-generated from chip-description files produced outside of Software Tools (where the compiler developers live).
     
    someone at Microchip knows about something more serious that they haven't made public.

     
    This conclusion still holds.

    Mark (this opinion available for hire)
    #11
    Howard Long
    Super Member
    • Total Posts : 676
    • Reward points : 0
    • Joined: 2005/04/04 08:50:32
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2018/12/31 15:27:19 (permalink)
    4 (1)
    To add to this, I thought I'd try a PIC24FJ256GB410 which I have in stock on a PIM, and this series is very close to the OP's device in terms of features. Unfortunately, this device does not work either.
     
    What does work is a PIC24FJ128GA202 and PIC24FJ128GB202 that I have in stock, but almost certainly of little use to the OP. Other than these and the 'GB702 I tried earlier, I don't have any other PIC24FJ series in stock that purportedly features REFOTRIM.
     
    FWIW, here is the code that works on the PIC24FJ128[GA|GB]202
     


    // PIC24FJ128GA202 Configuration Bit Settings
    // 'C' source line config statements
    // CONFIG4
    #pragma config DSWDTPS = DSWDTPS1F // Deep Sleep Watchdog Timer Postscale Select bits (1:68719476736 (25.7 Days))
    #pragma config DSWDTOSC = LPRC // DSWDT Reference Clock Select (DSWDT uses LPRC as reference clock)
    #pragma config DSBOREN = OFF // Deep Sleep BOR Enable bit (DSBOR Disabled)
    #pragma config DSWDTEN = OFF // Deep Sleep Watchdog Timer Enable (DSWDT Disabled)
    #pragma config DSSWEN = OFF // DSEN Bit Enable (Deep Sleep operation is always disabled)
    #pragma config PLLDIV = DISABLED // USB 96 MHz PLL Prescaler Select bits (PLL Disabled)
    #pragma config I2C1SEL = DISABLE // Alternate I2C1 enable bit (I2C1 uses SCL1 and SDA1 pins)
    #pragma config IOL1WAY = OFF // PPS IOLOCK Set Only Once Enable bit (The IOLOCK bit can be set and cleared using the unlock sequence)
    // CONFIG3
    #pragma config WPFP = WPFP127 // Write Protection Flash Page Segment Boundary (Page 127 (0x1FC00))
    #pragma config SOSCSEL = OFF // SOSC Selection bits (Digital (SCLKI) mode)
    #pragma config WDTWIN = PS25_0 // Window Mode Watchdog Timer Window Width Select (Watch Dog Timer Window Width is 25 percent)
    #pragma config PLLSS = PLL_FRC // PLL Secondary Selection Configuration bit (PLL is fed by the on-chip Fast RC (FRC) oscillator)
    #pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset Disabled)
    #pragma config WPDIS = WPDIS // Segment Write Protection Disable (Disabled)
    #pragma config WPCFG = WPCFGDIS // Write Protect Configuration Page Select (Disabled)
    #pragma config WPEND = WPENDMEM // Segment Write Protection End Page Select (Write Protect from WPFP to the last page of memory)
    // CONFIG2
    #pragma config POSCMD = NONE // Primary Oscillator Select (Primary Oscillator Disabled)
    #pragma config WDTCLK = LPRC // WDT Clock Source Select bits (WDT uses LPRC)
    #pragma config OSCIOFCN = OFF // OSCO Pin Configuration (OSCO/CLKO/RA3 functions as CLKO (FOSC/2))
    #pragma config FCKSM = CSECMD // Clock Switching and Fail-Safe Clock Monitor Configuration bits (Clock switching is enabled, Fail-Safe Clock Monitor is disabled)
    #pragma config FNOSC = FRC // Initial Oscillator Select (Fast RC Oscillator (FRC))
    #pragma config ALTCMPI = CxINC_RB // Alternate Comparator Input bit (C1INC is on RB13, C2INC is on RB9 and C3INC is on RA0)
    #pragma config WDTCMX = WDTCLK // WDT Clock Source Select bits (WDT clock source is determined by the WDTCLK Configuration bits)
    #pragma config IESO = OFF // Internal External Switchover (Disabled)
    // CONFIG1
    #pragma config WDTPS = PS32768 // Watchdog Timer Postscaler Select (1:32,768)
    #pragma config FWPSA = PR128 // WDT Prescaler Ratio Select (1:128)
    #pragma config WINDIS = OFF // Windowed WDT Disable (Standard Watchdog Timer)
    #pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT disabled in hardware; SWDTEN bit disabled)
    #pragma config ICS = PGx1 // Emulator Pin Placement Select bits (Emulator functions are shared with PGEC1/PGED1)
    #pragma config LPCFG = OFF // Low power regulator control (Disabled - regardless of RETEN)
    #pragma config GWRP = OFF // General Segment Write Protect (Write to program memory allowed)
    #pragma config GCP = OFF // General Segment Code Protect (Code protection is disabled)
    #pragma config JTAGEN = OFF // JTAG Port Enable (Disabled)
    // #pragma config statements should precede project file includes.
    // Use project enums instead of #define for ON and OFF.
    #include <xc.h>
    #define FCY 4000000
    #include <libpic30.h>
    int main(void)
    {
    TRISBbits.TRISB5=0;

    // RPOR3bits.RP6R=28; // 28 => REFO, REFO PPS not applicable on 24FJ128Gx20x
    REFOCONLbits.ROSEL=0b0000; // 0b0000 => Fosc
    REFOCONLbits.ROOUT=1;
    REFOCONHbits.RODIV=16; // 16 => div-by-32
    REFOTRIMLbits.ROTRIM=0b100000000;
    REFOCONLbits.ROSWEN=1;
    REFOCONLbits.ROEN=1;

    while (1)
    {
    LATBbits.LATB5=1;
    __delay_ms(200);
    LATBbits.LATB5=0;
    __delay_ms(200);
    }
    return 0;
    }

    #12
    cea
    Starting Member
    • Total Posts : 88
    • Reward points : 0
    • Joined: 2006/02/17 00:01:25
    • Location: 0
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2018/12/31 18:28:13 (permalink)
    0
    Howard,
     
    I have a DM240004 PIC 24F Curiosity Development Board with a PIC24FJ128GA204 and created almost the same kind of test code:
    /*
     *     File: main.c
     *   Target: PIC24FJ128GA204, DM240004 PIC 24F Curiosity Development Board.
     *      IDE: MPLABX v4.05
     * Compiler: XC16   v1.35
     *
     * Description:
     *  The fractional division of the reference oscillator output.
     *
     *  Setup system clock for FRC+PLL at 32MHZ.
     *  Setup REFO to divide the system clock by 7.8125 to produce a 4.096 MHz output.
     *  Flash LED1 on for 500 milliseconds the off for 500 milliseconds.
     *
     * Notes:
     *
     *                                                    PIC24FJ128GA204
     *              +----------+              +----------+                 +----------+                 +----------+
     *        <>  1 : RB9      :   LED2 <> 12 : RA10     :           <> 23 : RB2      : 32.768KHz <- 34 : RA4/SOSCO:
     *  LED_G <>  2 : RC6      :        <> 13 : RA7      :           <> 24 : RB3      :      LED1 <> 35 : RA9      :
     *  LED_B <>  3 : RC7      :        <> 14 : RB14     :       POT <> 25 : RC0      :           <> 36 : RC3      :
     *     S2 <>  4 : RC8      :        <> 15 : RB15     :           <> 26 : RC1      :           <> 37 : RC4      :
     *     S1 <>  5 : RC9      :    GND -> 16 : AVSS     :           <> 27 : RC2      :     LED_R <> 38 : RC5      :
     *    3v3 ->  6 : VBAT     :    3v3 -> 17 : AVDD     :       3v3 -> 28 : VDD      :       GND -> 39 : VSS      :
     *   10uF ->  7 : VCAP     :   MCLR -> 18 : RA5/MCLR :       GND -> 29 : VSS      :       3v3 -> 40 : VDD      :
     *        <>  8 : RB10     :        <> 19 : RA0      :           <> 30 : RA2/OSCI :           <> 41 : RB5      :
     *        <>  9 : RB11     :        <> 20 : RA1      :           <> 31 : RA3/OSCO :           <> 42 : RB6      :
     *        <> 10 : RB12     :    PGD <> 21 : RB0/PGD1 :           <> 32 : RA8      :           <> 43 : RB7      :
     *        <> 11 : RB13/REFO:    PGC <> 22 : RB1/PGC1 : 32.768KHz -> 33 : RB4/SOSCI:           <> 44 : RB8      :
     *              +----------+              +----------+                 +----------+                 +----------+
     *                                                      TQFP-44
     *
     */
       
    // CONFIG4
    #pragma config DSWDTPS = DSWDTPS15      // Deep Sleep Watchdog Timer Postscale Select bits (1:67108864 (36.1 Minutes))
    #pragma config DSWDTOSC = LPRC          // DSWDT Reference Clock Select (DSWDT uses LPRC as reference clock)
    #pragma config DSBOREN = OFF            // Deep Sleep BOR Enable bit (DSBOR Disabled)
    #pragma config DSWDTEN = OFF            // Deep Sleep Watchdog Timer Enable (DSWDT Disabled)
    #pragma config DSSWEN = OFF             // DSEN Bit Enable (Deep Sleep operation is always disabled)
    #pragma config PLLDIV = PLL8X           // USB 96 MHz PLL Prescaler Select bits (8x PLL selected)
    #pragma config I2C1SEL = DISABLE        // Alternate I2C1 enable bit (I2C1 uses SCL1 and SDA1 pins)
    #pragma config IOL1WAY = OFF            // PPS IOLOCK Set Only Once Enable bit (The IOLOCK bit can be set and cleared using the unlock sequence)
       
    // CONFIG3
    #pragma config WPFP = WPFP127           // Write Protection Flash Page Segment Boundary (Page 127 (0x1FC00))
    #pragma config SOSCSEL = ON             // SOSC Selection bits (SOSC circuit selected)
    #pragma config WDTWIN = PS25_0          // Window Mode Watchdog Timer Window Width Select (Watch Dog Timer Window Width is 25 percent)
    #pragma config PLLSS = PLL_FRC          // PLL Secondary Selection Configuration bit (PLL is fed by the on-chip Fast RC (FRC) oscillator)
    #pragma config BOREN = OFF              // Brown-out Reset Enable (Brown-out Reset Disabled)
    #pragma config WPDIS = WPDIS            // Segment Write Protection Disable (Disabled)
    #pragma config WPCFG = WPCFGDIS         // Write Protect Configuration Page Select (Disabled)
    #pragma config WPEND = WPENDMEM         // Segment Write Protection End Page Select (Write Protect from WPFP to the last page of memory)
       
    // CONFIG2
    #pragma config POSCMD = NONE            // Primary Oscillator Select (Primary Oscillator Disabled)
    #pragma config WDTCLK = LPRC            // WDT Clock Source Select bits (WDT uses LPRC)
    #pragma config OSCIOFCN = ON            // OSCO Pin Configuration (OSCO/CLKO/RA3 functions as port I/O (RA3))
    #pragma config FCKSM = CSECMD           // Clock Switching and Fail-Safe Clock Monitor Configuration bits (Clock switching is enabled, Fail-Safe Clock Monitor is disabled)
    #pragma config FNOSC = FRC              // Initial Oscillator Select (Fast RC Oscillator (FRC))
    #pragma config ALTCMPI = CxINC_RB       // Alternate Comparator Input bit (C1INC is on RB13, C2INC is on RB9 and C3INC is on RA0)
    #pragma config WDTCMX = LPRC            // WDT Clock Source Select bits (WDT always uses LPRC as its clock source)
    #pragma config IESO = OFF               // Internal External Switchover (Disabled)
       
    // CONFIG1
    #pragma config WDTPS = PS1024           // Watchdog Timer Postscaler Select (1:1,024)
    #pragma config FWPSA = PR128            // WDT Prescaler Ratio Select (1:128)
    #pragma config WINDIS = OFF             // Windowed WDT Disable (Standard Watchdog Timer)
    #pragma config FWDTEN = OFF             // Watchdog Timer Enable (WDT disabled in hardware; SWDTEN bit disabled)
    #pragma config ICS = PGx1               // Emulator Pin Placement Select bits (Emulator functions are shared with PGEC1/PGED1)
    #pragma config LPCFG = OFF              // Low power regulator control (Disabled - regardless of RETEN)
    #pragma config GWRP = OFF               // General Segment Write Protect (Write to program memory allowed)
    #pragma config GCP = OFF                // General Segment Code Protect (Code protection is disabled)
    #pragma config JTAGEN = OFF             // JTAG Port Enable (Disabled)
       
    #include <xc.h>
       
    /*
     * Define the target system clock frequency.
     *
     * The initialization MUST set the system clock to support these definitions.
     *
     */
    #define FSYS (32000000UL)
    #define FCYC (FSYS/2UL)
       
    /* define map input pin numbers */
    enum
    {
        RPI_RB0  = 0x00, /* RPI0  */
        RPI_RB1  = 0x01, /* RPI1  */
        RPI_RB2  = 0x02, /* RPI2  */
        RPI_RB3  = 0x03, /* RPI3  */
        RPI_RB4  = 0x04, /* RPI4  */
        RPI_RB5  = 0x05, /* RPI5  */
        RPI_RB6  = 0x06, /* RPI6  */
        RPI_RB7  = 0x07, /* RPI7  */
        RPI_RB8  = 0x08, /* RPI8  */
        RPI_RB9  = 0x09, /* RPI9  */
        RPI_RB10 = 0x0A, /* RPI10 */
        RPI_RB11 = 0x0B, /* RPI11 */
        RPI_RB12 = 0x0C, /* RPI12 */
        RPI_RB13 = 0x0D, /* RPI13 */
        RPI_RB14 = 0x0E, /* RPI14 */
        RPI_RB15 = 0x0F, /* RPI15 */
        RPI_RC0  = 0x10, /* RPI16 */
        RPI_RC1  = 0x11, /* RPI17 */
        RPI_RC2  = 0x12, /* RPI18 */
        RPI_RC3  = 0x13, /* RPI19 */
        RPI_RC4  = 0x14, /* RPI20 */
        RPI_RC5  = 0x15, /* RPI21 */
        RPI_RC6  = 0x16, /* RPI22 */
        RPI_RC7  = 0x17, /* RPI23 */
        RPI_RC8  = 0x18, /* RPI24 */
        RPI_RC9  = 0x19, /* RPI25 */
        RPI_NONE = 0x3f
    };
       
    /* define map output function numbers */
    enum
    {
        RPO_C1OUT   = 1,  /* Comparator 1 Output      */
        RPO_C2OUT   = 2,  /* Comparator 2 Output      */
        RPO_U1TX    = 3,  /* UART1 Transmit           */
        RPO_U1RTS   = 4,  /* UART1 Request-to-Send    */
        RPO_U2TX    = 5,  /* UART2 Transmit           */
        RPO_U2RTS   = 6,  /* UART2 Request-to-Send    */
        RPO_SDO1    = 7,  /* SPI1 Data Output         */
        RPO_SCK1OUT = 8,  /* SPI1 Clock Output        */
        RPO_SS1OUT  = 9,  /* SPI1 Slave Select Output */
        RPO_SDO2    = 10, /* SPI2 Data Output         */
        RPO_SCK2OUT = 11, /* SPI2 Clock Output        */
        RPO_SS2OUT  = 12, /* SPI2 Slave Select Output */
        RPO_OC1     = 13, /* Output Compare 1         */
        RPO_OC2     = 14, /* Output Compare 2         */
        RPO_OC3     = 15, /* Output Compare 3         */
        RPO_OC4     = 16, /* Output Compare 4         */
        RPO_OC5     = 17, /* Output Compare 5         */
        RPO_OC6     = 18, /* Output Compare 6         */
        RPO_U3TX    = 19, /* UART3 Transmit           */
        RPO_U3RTS   = 20, /* UART3 Request-to-Send    */
        RPO_U4TX    = 21, /* UART4 Transmit           */
        RPO_U4RTS   = 22, /* UART4 Request-to-Send    */
        RPO_SDO3    = 23, /* SPI3 Data Output         */
        RPO_SCK3OUT = 24, /* SPI3 Clock Output        */
        RPO_SS3OUT  = 25, /* SPI3 Slave Select Output */
        RPO_C3OUT   = 26, /* Comparator 3 Output      */
        RPO_MDOUT   = 27, /* DSM Modulator Output     */
        RPO_NONE    = 0
    };
       
    /* Initialize this PIC */
    void PIC_init(void)
    {
        unsigned int ClockSwitchTimeout;
       
        /*
        ** Disable all interrupt sources
        */
        __builtin_disi(0x3FFF); /* disable interrupts for 16383 cycles */
        IEC0 = 0;
        IEC1 = 0;
        IEC2 = 0;
        IEC3 = 0;
        IEC4 = 0;
        IEC5 = 0;
        IEC6 = 0;
        IEC7 = 0;
        __builtin_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.
         */
       
        if(!OSCCONbits.CLKLOCK) /* if primary oscillator switching is unlocked */
        {
            /* Select primary oscillator as FRC */
            __builtin_write_OSCCONH(0b000);
       
            /* Request switch primary to new selection */
            __builtin_write_OSCCONL(OSCCON | (1 << _OSCCON_OSWEN_POSITION));
       
            /* wait, with timeout, for clock switch to complete */
            for(ClockSwitchTimeout=10000; --ClockSwitchTimeout && OSCCONbits.OSWEN;);
       
            CLKDIV   = 0x0100; /* set for FRC clock 4MHZ operations */
       
            /* Select primary oscillator as FRCPLL */
            __builtin_write_OSCCONH(0b001);
            /* Request switch primary to new selection */
            __builtin_write_OSCCONL(OSCCON | (1 << _OSCCON_OSWEN_POSITION));
       
            /* wait, with timeout, for clock switch to complete */
            for(ClockSwitchTimeout=10000; --ClockSwitchTimeout && OSCCONbits.OSWEN;);
       
            /* wait, with timeout, for the PLL to lock */
            for(ClockSwitchTimeout=10000; --ClockSwitchTimeout && !OSCCONbits.LOCK;);
       
            /* at this point the system oscillator should be 32MHz */
        }
       
        ANSA   =  0x0000; /* Set for digital I/O */
        ANSB   =  0x0000; /* Set for digital I/O */
        ANSC   =  0x0000; /* Set for digital I/O */
       
        _NSTDIS = 1;    /* disable interrupt nesting */
       
        TRISA   = 0xFFFF;
        TRISB   = 0xFFFF;
        TRISC   = 0xFFFF;
       
        /* Unlock Registers */
        __builtin_write_OSCCONL(OSCCON & ~(1<<_OSCCON_IOLOCK_POSITION));
       
        /* map all inputs */
        _IC1R     = RPI_NONE;       /*  Input Capture 1         */
        _IC2R     = RPI_NONE;       /*  Input Capture 2         */
        _IC3R     = RPI_NONE;       /*  Input Capture 3         */
        _IC4R     = RPI_NONE;       /*  Input Capture 4         */
        _IC5R     = RPI_NONE;       /*  Input Capture 5         */
        _IC6R     = RPI_NONE;       /*  Input Capture 6         */
        _INT1R    = RPI_NONE;       /*  External Interrupt 1    */
        _INT2R    = RPI_NONE;       /*  External Interrupt 2    */
        _INT3R    = RPI_NONE;       /*  External Interrupt 3    */
        _INT4R    = RPI_NONE;       /*  External Interrupt 4    */
        _MDC1R    = RPI_NONE;       /*  */
        _MDC2R    = RPI_NONE;       /*  */
        _MDMIRR   = RPI_NONE;       /*  */
        _OCFAR    = RPI_NONE;       /*  Output Compare Fault A  */
        _OCFBR    = RPI_NONE;       /*  Output Compare Fault B  */
        _OCTRIG1R = RPI_NONE;       /*  */
        _OCTRIG2R = RPI_NONE;       /*  */
        _SCK1R    = RPI_NONE;       /*  SPI1 Clock Input        */
        _SCK2R    = RPI_NONE;       /*  SPI2 Clock Input        */
        _SCK3R    = RPI_NONE;       /*  SPI3 Clock Input        */
        _SDI1R    = RPI_NONE;       /*  SPI1 Data Input         */
        _SDI2R    = RPI_NONE;       /*  SPI2 Data Input         */
        _SDI3R    = RPI_NONE;       /*  SPI3 Data Input         */
        _SS1R     = RPI_NONE;       /*  SPI1 Slave Select Input */
        _SS2R     = RPI_NONE;       /*  SPI2 Slave Select Input */
        _SS3RR    = RPI_NONE;       /*  */
        _TMRCKR   = RPI_NONE;       /*  */
        _U1CTSR   = RPI_NONE;       /*  UART1 Receive           */
        _U1RXR    = RPI_NONE;       /*  UART1 Clear To Send     */
        _U2CTSR   = RPI_NONE;       /*  UART2 Receive           */
        _U2RXR    = RPI_NONE;       /*  UART2 Clear To Send     */
        _U3CTSR   = RPI_NONE;       /*  UART3 Receive           */
        _U3RXR    = RPI_NONE;       /*  UART3 Clear To Send     */
        _U4CTSR   = RPI_NONE;       /*  UART4 Receive           */
        _U4RXR    = RPI_NONE;       /*  UART4 Clear To Send     */
       
        /* map all outputs                               Fixed  */
        _RP0R     = RPO_NONE;       /* RB0               PGD1   */
        _RP1R     = RPO_NONE;       /* RB1               PGC1   */
        _RP2R     = RPO_NONE;       /* RB2                      */
        _RP3R     = RPO_NONE;       /* RB3                      */
        _RP5R     = RPO_NONE;       /* RB5                      */
        _RP6R     = RPO_NONE;       /* RB6                      */
        _RP7R     = RPO_NONE;       /* RB7                      */
        _RP8R     = RPO_NONE;       /* RB8                      */
        _RP9R     = RPO_NONE;       /* RB9                      */
        _RP10R    = RPO_NONE;       /* RB10                     */
        _RP11R    = RPO_NONE;       /* RB11                     */
        _RP12R    = RPO_NONE;       /* RB12                     */
        _RP13R    = RPO_NONE;       /* RB13              REFO   */
        _RP14R    = RPO_NONE;       /* RB14                     */
        _RP15R    = RPO_NONE;       /* RB15                     */
        _RP16R    = RPO_NONE;       /* RC0                      */
        _RP17R    = RPO_NONE;       /* RC1                      */
        _RP18R    = RPO_NONE;       /* RC2                      */
        _RP19R    = RPO_NONE;       /* RC3                      */
        _RP20R    = RPO_NONE;       /* RC4                      */
        _RP21R    = RPO_NONE;       /* RC5                      */
        _RP22R    = RPO_NONE;       /* RC6                      */
        _RP23R    = RPO_NONE;       /* RC7                      */
        _RP24R    = RPO_NONE;       /* RC8                      */
        _RP25R    = RPO_NONE;       /* RC9                      */
       
        /* Lock Registers */
        __builtin_write_OSCCONL(OSCCON | (1<<_OSCCON_IOLOCK_POSITION));
    }
       
    /*
     * WARNING: Not a portable function.
     *          Maximum 16MHz instruction cycle clock.
     *          Minimum  8Khz instruction cycle clock.
     */
    void delay_ms( unsigned long delay )
    {
        do
        {
            asm("repeat  %0\n clrwdt\n":: "r" (FCYC/1000L-7L));
        } while(delay--);
    }
       
    #define GPIO_OUT 0
    #define GPIO_IN  1
       
    #define LED_ON   1
    #define LED_OFF  0
       
    #define LED1_DIR   TRISAbits.TRISA9
    #define LED1_PIN   LATAbits.LATA9
       
    #define REFO_DIR   TRISBbits.TRISB13
    #define REFO_PIN   LATBbits.LATB13
       
    int main()
    {
        PIC_init();
       
        LED1_DIR = GPIO_OUT;
       
        /* Setup reference oscillator output REFO = FSYS/(2*(3+464/512)) */
        REFOCONL = 0;
        while(REFOCONLbits.ROACTIVE) REFOCONL = 0;
        REFOCONH  = 3u;
        REFOTRIML = 464u<<7u;
        REFOCONL = (    (0b0000 << _REFOCONL_ROSEL_POSITION) \
                    |   (0b1    << _REFOCONL_ROSLP_POSITION) \
                    |   (0b1    << _REFOCONL_ROOUT_POSITION) \
                    |   (0b1    << _REFOCONL_ROSWEN_POSITION) \
                   );
        REFOCONLbits.ROEN    = 1;
       
        /* loop forever, main never exits */
        for(;;)
        {
       
            if (LED1_PIN == LED_OFF)
            {
                LED1_PIN = LED_ON;
            }
            else
            {
                LED1_PIN = LED_OFF;
            }
            delay_ms(500);
        }
        return 0;
    }

     
    In the process discovered that the PIC24FJ128GA204 tolerates overclocking at 64MHz when at 25°C. Not useful but interesting.
    post edited by cea - 2018/12/31 18:33:17
    #13
    Stromlo
    Starting Member
    • Total Posts : 42
    • Reward points : 0
    • Joined: 2005/10/25 07:55:42
    • Location: South Africa
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2019/01/01 12:16:13 (permalink)
    0
    Howard, thank you for that test. It sheds some light into this issue... 
    #14
    Howard Long
    Super Member
    • Total Posts : 676
    • Reward points : 0
    • Joined: 2005/04/04 08:50:32
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2019/01/02 03:25:23 (permalink)
    0
    A possible solution, depending on what you're trying to do, could be to use one of the CCP modules in PWM Variable Frequency Pulse mode.
     
    For example, say you're trying to generate a standard audio codec bit clock frequency of 12.288MHz, assuming a 32MHz input frequency, you can achieve 12.288086MHz (7ppm) with a CCPxRA = 50332.
     
    Even if ROTRIM worked, the best you could manage with the same reference input frequency is 12.281859MHz (500ppm) with N=1, M=155.
    #15
    Howard Long
    Super Member
    • Total Posts : 676
    • Reward points : 0
    • Joined: 2005/04/04 08:50:32
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2019/01/02 08:59:36 (permalink)
    4 (2)
    Here's some code that works on a PIC24FJ256GA705 on a Curiosity board to create a 12.288MHz output on the OCM1A pin using the 32MHz FRC+PLLx4.
     
    *** Please note that I could not get this to work on anything other than CCP1: it appears that only CCP1 supports Variable Frequency Mode on this device, I can;t find any reference to this in the latest DS or errata. I don't know about other devices.
     

    // PIC24FJ256GA705 Configuration Bit Settings
    // 'C' source line config statements
    // FSEC
    #pragma config BWRP = OFF // Boot Segment Write-Protect bit (Boot Segment may be written)
    #pragma config BSS = DISABLED // Boot Segment Code-Protect Level bits (No Protection (other than BWRP))
    #pragma config BSEN = OFF // Boot Segment Control bit (No Boot Segment)
    #pragma config GWRP = OFF // General Segment Write-Protect bit (General Segment may be written)
    #pragma config GSS = DISABLED // General Segment Code-Protect Level bits (No Protection (other than GWRP))
    #pragma config CWRP = OFF // Configuration Segment Write-Protect bit (Configuration Segment may be written)
    #pragma config CSS = DISABLED // Configuration Segment Code-Protect Level bits (No Protection (other than CWRP))
    #pragma config AIVTDIS = OFF // Alternate Interrupt Vector Table bit (Disabled AIVT)
    // FBSLIM
    #pragma config BSLIM = 0x1FFF // Boot Segment Flash Page Address Limit bits (Enter Hexadecimal value)
    // FSIGN
    // FOSCSEL
    #pragma config FNOSC = FRCPLL // Oscillator Source Selection (Fast RC Oscillator with divide-by-N with PLL module (FRCPLL) )
    #pragma config PLLMODE = PLL4X // PLL Mode Selection (4x PLL selected)
    #pragma config IESO = OFF // Two-speed Oscillator Start-up Enable bit (Start up with user-selected oscillator source)
    // FOSC
    #pragma config POSCMD = NONE // Primary Oscillator Mode Select bits (Primary Oscillator disabled)
    #pragma config OSCIOFCN = OFF // OSC2 Pin Function bit (OSC2 is clock output)
    #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 // Peripheral pin select configuration bit (Allow multiple reconfigurations)
    #pragma config FCKSM = CSECMD // Clock Switching Mode bits (Clock switching is enabled,Fail-safe Clock Monitor is disabled)
    // FWDT
    #pragma config WDTPS = PS32768 // Watchdog Timer Postscaler bits (1:32,768)
    #pragma config FWPSA = PR128 // Watchdog Timer Prescaler bit (1:128)
    #pragma config FWDTEN = OFF // Watchdog Timer Enable bits (WDT and SWDTEN disabled)
    #pragma config WINDIS = OFF // Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode)
    #pragma config WDTWIN = WIN25 // Watchdog Timer Window Select bits (WDT Window is 25% of WDT period)
    #pragma config WDTCMX = WDTCLK // WDT MUX 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 = OFF // Brown Out Enable bit (Brown Out Disabled)
    #pragma config LPCFG = OFF // Low power regulator control (No Retention Sleep)
    #pragma config DNVPEN = ENABLE // Downside Voltage Protection Enable bit (Downside protection enabled using ZPBOR when BOR is inactive)
    // FICD
    #pragma config ICS = PGD2 // ICD Communication Channel Select bits (Communicate on PGEC2 and PGED2)
    #pragma config JTAGEN = OFF // JTAG Enable bit (JTAG is 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 SOSCHP = OFF // SOSC High Power Enable bit (valid only when SOSCSEL = 1 (Enable SOSC low power mode)
    #pragma config ALTI2C1 = ALTI2CEN // Alternate I2C pin Location (SDA1 and SCL1 on RB9 and RB8)
    // #pragma config statements should precede project file includes.
    // Use project enums instead of #define for ON and OFF.
    #include <xc.h>
    #define FCY 16000000
    #include <libpic30.h>
    int main(void)
    {
    TRISAbits.TRISA8=0; // LED

    CCP1TMRL=0;
    CCP1RA=50332; // 12.288MHz for 32MHz clock
    CCP1CON1Lbits.CLKSEL=0b100; // 0b100 => 2x peripheral clock, i.e. 32MHz for FRC + PLLx4
    CCP1CON1Lbits.TMRPS=0b00; // 0b00 => div-by-1
    CCP1CON1Lbits.T32=0;
    CCP1CON2Hbits.OCAEN=1;
    CCP1CON1Lbits.CCSEL=0; // 0 => OC/PWM/Timer mode
    CCP1CON1Lbits.MOD=0b0111; // 0b0111 => Variable Frequency Mode
    CCP1CON1Lbits.CCPON=1;

    while (1)
    {
    LATAbits.LATA8=1;
    __delay_ms(250);
    LATAbits.LATA8=0;
    __delay_ms(250);
    Nop();
    }
    return 0;
    }

    post edited by Howard Long - 2019/01/02 09:07:56
    #16
    Howard Long
    Super Member
    • Total Posts : 676
    • Reward points : 0
    • Joined: 2005/04/04 08:50:32
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2019/01/02 12:30:11 (permalink)
    4 (1)
    Code for a 'GB410 PIM on an Explorer 16/32 using MCCP1.
     
    Quick vid: https://youtu.be/5zpBfvsgFOk
     

     

    // PIC24FJ256GB410 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 (Enter Hexadecimal value)
    // FSIGN
    // FOSCSEL
    #pragma config FNOSC = PRIPLL // Oscillator Select (Primary Oscillator with PLL module (XTPLL, HSPLL, ECPLL))
    #pragma config PLLMODE = PLL4X // Frequency Multiplier Select Bits (4x PLL selected)
    #pragma config IESO = OFF // Internal External Switchover (Start up with user-selected oscillator source)
    // FOSC
    #pragma config POSCMOD = XT // Primary Oscillator Select (XT oscillator mode selected)
    #pragma config OSCIOFCN = OFF // OSCO Pin Configuration (OSCO/CLKO/RC15 functions as CLKO (FOSC/2))
    #pragma config SOSCSEL = OFF // SOSC Power Selection Configuration bits (Digital (SCLKI) mode)
    #pragma config PLLSS = PLL_PRI // PLL Secondary Selection Configuration bit (PLL is fed by the Primary 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 = CSECMD // Clock Switching and Monitor Selection (Clock switching is enabled, Fail-Safe Clock Monitor is 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 = OFF // Watchdog Timer Enable (Watchdog Timer is disabled)
    #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 = OFF // Brown-out Reset Enable bits (Brown-out Reset Disabled)
    #pragma config LPCFG = OFF // Low power regulator control (Disabled)
    // FICD
    #pragma config ICS = PGx2 // Emulator Pin Placement Select bits (Emulator functions are shared with PGEC2/PGED2)
    #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 = OFF // Deep Sleep Zero-Power BOR Enable bit (Deep Sleep BOR disabled in Deep Sleep)
    #pragma config DSWDTEN = OFF // Deep Sleep Watchdog Timer Enable bit (DSWDT disabled)
    #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.
    // Use project enums instead of #define for ON and OFF.
    #include <xc.h>
    #define FCY 16000000
    #include <libpic30.h>
    int main(void)
    {
    TRISAbits.TRISA6=0;

    CCP1TMRL=0;
    CCP1RA=50332; // 12.288MHz for 32MHz clock
    CCP1CON1Lbits.CLKSEL=0b100; // 0b100 => 2x system clock, i.e. 32MHz for 8MHz XT + PLLx4
    CCP1CON1Lbits.TMRPS=0b00; // 0b00 => div-by-1
    CCP1CON1Lbits.T32=0;
    CCP1CON2Hbits.OCAEN=1;
    CCP1CON1Lbits.CCSEL=0; // 0 => OC/PWM/Timer mode
    CCP1CON1Lbits.MOD=0b0111; // 0b0111 => Variable Frequency Mode
    CCP1CON1Lbits.CCPON=1;

    while (1)
    {
    LATAbits.LATA6=1;
    __delay_ms(250);
    LATAbits.LATA6=0;
    __delay_ms(250);
    }
    return 0;
    }

    #17
    cea
    Starting Member
    • Total Posts : 88
    • Reward points : 0
    • Joined: 2006/02/17 00:01:25
    • Location: 0
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2019/01/02 18:27:22 (permalink)
    0
    Howard,
     
    A very clever way to get 12.288MHz from a 32MHz clock.
     
    The PIC24FJ256GB606 does have a CCP module with the variable frequency pulse mode.
    This is the code I used to test:
    /*  
     *     File: main.c
     *   Target: PIC24FJ256GB606
     *      IDE: MPLABX v4.05 
     * Compiler: XC16   v1.35
     * 
     * Description:
     * 
     *
     * Notes:
     *  Yellow LED on GPIO pin RB4. ON = 1, OFF = 0.
     *
     *                                                   PIC24FJ256GB606
     *             +----------+               +----------+               +----------+               +----------+
     *       <>  1 : RE5      :         <> 17 : RB6/RP6  :         <> 33 : RF3      :         <> 49 : RD1      :
     *       <>  2 : RE6      :         <> 18 : RB7/RP7  :         <> 34 : RF7      :         <> 50 : RD2      :
     *       <>  3 : RE7      :     3v3 -> 19 : AVDD     :     3v3 -> 35 : RF6      :         <> 51 : RD3      :
     *       <>  4 : RG6/OCM1A:     GND -> 20 : AVSS     :         <> 36 : RG3      :         <> 52 : RD4      :
     *       <>  5 : RG7/OCM1B:         <> 21 : RB8/RP8  :         <> 37 : RG2      :         <> 53 : RD5      :
     *       <>  6 : RG8/OCM2A:         <> 22 : RB9/RP9  :     3v3 -> 38 : VDD      :         <> 54 : RD6/OC4  :
     *   VPP ->  7 : MCLR     :         <> 23 : RB10     :         <> 39 : RC12     :         <> 55 : RD7/OC5  :
     *       <>  8 : RG9/OCM2B:         <> 24 : RB11     :         <> 40 : RC15     :    10uF -> 56 : VCAP     :
     *   GND ->  9 : VSS      :     GND -> 25 : VSS      :     GND -> 41 : VSS      :     3v3 -> 57 : VUSB     :
     *   3v3 -> 10 : VDD      :     3v3 -> 26 : VDD      :         <> 42 : RD8/RP2  :         <> 58 : RF0/OC6  :
     *       <> 11 : RB5/OCM3A:         <> 27 : RB12     :         <> 43 : RD9      :         <> 59 : RF1      :
     *   LED <> 12 : RB4/OCM3B:         <> 28 : RB13     :         <> 44 : RD10     :         <> 60 : RE0      :
     *       <> 13 : RB3      :         <> 29 : RB14     :         <> 45 : RD11     :         <> 61 : RE1      :
     *       <> 14 : RB2      :         <> 30 : RB15     :         <> 46 : RD0/RP11 :         <> 62 : RE2      :
     *   PGC <> 15 : RB1/PGC1 :         <> 31 : RF4      :         <> 47 : RC13     :         <> 63 : RE3      :
     *   PGD <> 16 : RB0/PGD1 :    REFO <> 32 : RF5/RP17 :         <> 48 : RC14     :         <> 64 : RE4      :
     *             +----------+               +----------+               +----------+               +----------+
     *                                                    TQFP-64
     * 
     */ 
       
    #pragma config BTMODE = SINGLE          /* Boot Mode Configuration bits (Device is in Single Boot (legacy) mode) */
    #pragma config BWRP = OFF               /* Boot Segment Write-Protect bit (Boot Segment may be written) */
    #pragma config BSS = DISABLED           /* Boot Segment Code-Protect Level bits (No Protection (other than BWRP)) */
    #pragma config BSEN = OFF               /* Boot Segment Control bit (No Boot Segment) */
    #pragma config GWRP = OFF               /* General Segment Write-Protect bit (General Segment may be written) */
    #pragma config GSS = DISABLED           /* General Segment Code-Protect Level bits (No Protection (other than GWRP)) */
    #pragma config CWRP = OFF               /* Configuration Segment Write-Protect bit (Configuration Segment may be written) */
    #pragma config CSS = DISABLED           /* Configuration Segment Code-Protect Level bits (No Protection (other than CWRP)) */
    #pragma config AIVTDIS = OFF            /* Alternate Interrupt Vector Table bit (Disabled AIVT) */
    #pragma config BSLIM = 0x1FFF           /* Boot Segment Flash Page Address Limit bits (Boot Segment Flash page address  limit) */
    #pragma config FNOSC = FRC              /* Power on default for FRC oscillator */
    #pragma config PLLMODE = PLL4X          /* PLL Mode Selection (4x PLL selected) */
    #pragma config IESO = OFF               /* Two-speed Oscillator Start-up Enable bit (Start up with user-selected oscillator source) */
    #pragma config POSCMD = NONE            /* Primary Oscillator Mode Select bits (Primary Oscillator disabled) */
    #pragma config OSCIOFCN = ON            /* OSC2 Pin Function bit (OSC2 is general purpose digital I/O pin) */
    #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            /* Peripheral pin select configuration bit (Allow multiple reconfigurations) */
    #pragma config FCKSM = CSECMD           /* Enable clock switching */
    #pragma config WDTPS = PS32768          /* Watchdog Timer Postscaler bits (1:32,768) */
    #pragma config FWPSA = PR128            /* Watchdog Timer Prescaler bit (1:128) */
    #pragma config FWDTEN = ON_SWDTEN       /* Watchdog Timer Enable bits (WDT Enabled/Disabled (controlled using SWDTEN bit)) */
    #pragma config WINDIS = OFF             /* Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode) */
    #pragma config WDTWIN = WIN25           /* Watchdog Timer Window Select bits (WDT Window is 25% of WDT period) */
    #pragma config WDTCMX = WDTCLK          /* WDT MUX 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) */
    #pragma config BOREN = SBOREN           /* Brown Out Enable bit (Controlled by SBOREN) */
    #pragma config LPCFG = OFF              /* Low power regulator control (No Retention Sleep) */
    #pragma config DNVPEN = ENABLE          /* Downside Voltage Protection Enable bit (Downside protection enabled using ZPBOR when BOR is inactive) */
    #pragma config ICS = PGD1               /* ICD Communication Channel Select bits (Communicate on PGEC1 and PGED1) */
    #pragma config JTAGEN = OFF             /* JTAG Enable bit (JTAG is disabled) */
    #pragma config BTSWP = OFF              /* BOOTSWP Disable (BOOTSWP instruction disabled) */
    #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 SOSCHP = ON              /* SOSC High Power Enable bit (valid only when SOSCSEL = 1 (Enable SOSC high power mode (default)) */
    #pragma config ALTVREF = ALTREFEN       /* Alternate Voltage Reference Location Enable bit (VREF+ and CVREF+ on RA10, VREF- and CVREF- on RA9) */
       
    #include <xc.h>
    /*
     * Define the target system clock frequency.
     *
     * The initialization MUST set the system clock to support these definitions.
     *
     */
    #define FSYS (32000000UL)
    #define FCYC (FSYS/2UL)
       
    /* define map input pin numbers */
    enum
    {  
        RPI_RB0  = 0,  /* RPI00 */
        RPI_RB1 ,      /* RPI01 */
        RPI_RD8 ,      /* RPI02 */
        RPI_RD10,      /* RPI03 */
        RPI_RD9 ,      /* RPI04 */
        RPI_RB6  = 6,  /* RPI06 */
        RPI_RB7 ,      /* RPI07 */
        RPI_RB8 ,      /* RPI08 */
        RPI_RB9 ,      /* RPI09 */
        RPI_RF4 ,      /* RPI10 */
        RPI_RD0 ,      /* RPI11 */
        RPI_RD11,      /* RPI12 */
        RPI_RB2 ,      /* RPI13 */
        RPI_RB14,      /* RPI14 */
        RPI_RF3  = 16, /* RPI16 */
        RPI_RF5 ,      /* RPI17 */
        RPI_RB5 ,      /* RPI18 */
        RPI_RG8 ,      /* RPI19 */
        RPI_RD5 ,      /* RPI20 */
        RPI_RG6 ,      /* RPI21 */
        RPI_RD3 ,      /* RPI22 */
        RPI_RD2 ,      /* RPI23 */
        RPI_RD1 ,      /* RPI24 */
        RPI_RD4 ,      /* RPI25 */
        RPI_RG7 ,      /* RPI26 */
        RPI_RG9 ,      /* RPI27 */
        RPI_RB4 ,      /* RPI28 */
        RPI_RB15,      /* RPI29 */
        RPI_RF2 ,      /* RPI30 */
        RPI_RC14 = 37, /* RPI37 */
        RPI_NONE = 0x3f
    }; 
       
    /* define map output function numbers */
    enum
    {  
        RPO_NONE    = 0,    /* (Pin Disabled)            */
        RPO_C1OUT   = 1,    /* Comparator 1 Output       */
        RPO_C2OUT   = 2,    /* Comparator 2 Output       */
        RPO_C3OUT   = 26,   /* Comparator 3 Output       */
        RPO_SDO1    = 7,    /* SPI1 Data Output          */
        RPO_SCK1OUT = 8,    /* SPI1 Clock Output         */
        RPO_SS1OUT  = 9,    /* SPI1 Slave Select Output  */
        RPO_SDO2    = 10,   /* SPI2 Data Output          */
        RPO_SCK2OUT = 11,   /* SPI2 Clock Output         */
        RPO_SS2OUT  = 12,   /* SPI2 Slave Select Output  */
        RPO_SDO3    = 23,   /* SPI3 Data Output          */
        RPO_SCK3OUT = 24,   /* SPI3 Clock Output         */
        RPO_SS3OUT  = 25,   /* SPI3 Slave Select Output  */
        RPO_OC1     = 13,   /* Output Compare 1          */
        RPO_OC2     = 14,   /* Output Compare 2          */
        RPO_OC3     = 15,   /* Output Compare 3          */
        RPO_OCM4    = 16,   /* CCP4 Output Compare       */
        RPO_OCM5    = 17,   /* CCP5 Output Compare       */
        RPO_OCM6    = 18,   /* CCP6 Output Compare       */
        RPO_OCM7    = 27,   /* CCP7 Output Compare       */
        RPO_U1TX    = 3,    /* UART1 Transmit            */
        RPO_U1RTS   = 4,    /* UART1 Request-to-Send     */
        RPO_U2TX    = 5,    /* UART2 Transmit            */
        RPO_U2RTS   = 6,    /* UART2 Request-to-Send     */
        RPO_U3TX    = 19,   /* UART3 Transmit            */
        RPO_U3RTS   = 20,   /* UART3 Request-to-Send     */
        RPO_U4TX    = 21,   /* UART4 Transmit            */
        RPO_U4RTS   = 22,   /* UART4 Request-to-Send     */
        RPO_REFO    = 28,   /* Reference Clock Output    */
        RPO_CLC1OUT = 29,   /* CLC1 Output               */
        RPO_CLC2OUT = 30,   /* CLC2 Output               */
        RPO_RTCC    = 31,   /* RTCC Output               */
    }; 
       
    /* Initialize this PIC */
    void PIC_Init(void)
    {  
        unsigned int ClockSwitchTimeout;
       
        /*
        ** Disable all interrupt sources
        */
        __builtin_disi(0x3FFF); /* disable interrupts for 16383 cycles */
        IEC0 = 0;
        IEC1 = 0;
        IEC2 = 0;
        IEC3 = 0;
        IEC4 = 0;
        IEC5 = 0;
        IEC6 = 0;
        IEC7 = 0;
        __builtin_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.
         */
       
        if(!OSCCONbits.CLKLOCK) /* if primary oscillator switching is unlocked */
        {
            /* Select primary oscillator as FRC */
            __builtin_write_OSCCONH(0b000);
       
            /* Request switch primary to new selection */
            __builtin_write_OSCCONL(OSCCON | (1 << _OSCCON_OSWEN_POSITION));
       
            /* wait, with timeout, for clock switch to complete */
            for(ClockSwitchTimeout=10000; --ClockSwitchTimeout && OSCCONbits.OSWEN;);
       
            CLKDIV   = 0x0000; /* set for FRC clock 8MHZ operations */
       
            /* Select primary oscillator as FRCPLL */
            __builtin_write_OSCCONH(0b001);
            /* Request switch primary to new selection */
            __builtin_write_OSCCONL(OSCCON | (1 << _OSCCON_OSWEN_POSITION));
           
            /* ALERT: This may be required only when the 96MHz PLL is used */
            CLKDIVbits.PLLEN = 1;
       
            /* wait, with timeout, for clock switch to complete */
            for(ClockSwitchTimeout=10000; --ClockSwitchTimeout && OSCCONbits.OSWEN;);
       
            /* wait, with timeout, for the PLL to lock */
            for(ClockSwitchTimeout=10000; --ClockSwitchTimeout && !OSCCONbits.LOCK;);
           
            /* at this point the system oscillator should be 32MHz */
        }
       
        ANSB   =  0x0000; /* Set for digital I/O */
        ANSC   =  0x0000; /* Set for digital I/O */
        ANSD   =  0x0000; /* Set for digital I/O */
        ANSE   =  0x0000; /* Set for digital I/O */
        ANSF   =  0x0000; /* Set for digital I/O */
        ANSG   =  0x0000; /* Set for digital I/O */
       
        CM1CON  = 0x0000;
        CM2CON  = 0x0000;
        CM3CON  = 0x0000;
       
        _NSTDIS = 1;    /* disable interrupt nesting */
           
        TRISB   = 0xFFFF;
        TRISC   = 0xFFFF;
        TRISD   = 0xFFFF;
        TRISE   = 0xFFFF;
        TRISF   = 0xFFFF;
        TRISG   = 0xFFFF;
       
        /* Unlock Registers */
        __builtin_write_OSCCONL(OSCCON & 0xBF);
       
        /* map all inputs */
        _INT1R    = RPI_NONE;       /*  External Interrupt 1    */
        _INT2R    = RPI_NONE;       /*  External Interrupt 2    */
        _INT3R    = RPI_NONE;       /*  External Interrupt 3    */
        _INT4R    = RPI_NONE;       /*  External Interrupt 4    */
        _IC1R     = RPI_NONE;       /*  Input Capture 1         */
        _IC2R     = RPI_NONE;       /*  Input Capture 2         */
        _IC3R     = RPI_NONE;       /*  Input Capture 3         */
        _OCFAR    = RPI_NONE;       /*  Output Compare Fault A  */
        _OCFBR    = RPI_NONE;       /*  Output Compare Fault B  */
        _SCK1R    = RPI_NONE;       /*  SPI1 Clock Input        */
        _SDI1R    = RPI_NONE;       /*  SPI1 Data Input         */
        _SS1R     = RPI_NONE;       /*  SPI1 Slave Select Input */
        _SCK2R    = RPI_NONE;       /*  SPI2 Clock Input        */
        _SDI2R    = RPI_NONE;       /*  SPI2 Data Input         */
        _SS2R     = RPI_NONE;       /*  SPI2 Slave Select Input */
        _SCK3R    = RPI_NONE;       /*  SPI3 Clock Input        */
        _SDI3R    = RPI_NONE;       /*  SPI3 Data Input         */
        _SS3R     = RPI_NONE;       /*  SPI3 Slave Select Input */
        _T2CKR    = RPI_NONE;       /*  Timer2 External Clock   */
        _T3CKR    = RPI_NONE;       /*  Timer3 External Clock   */
        _T4CKR    = RPI_NONE;       /*  Timer4 External Clock   */
        _T5CKR    = RPI_NONE;       /*  Timer5 External Clock   */
        _U1RXR    = RPI_NONE;       /*  UART1 Clear To Send     */
        _U1CTSR   = RPI_NONE;       /*  UART1 Receive           */
        _U2RXR    = RPI_NONE;       /*  UART2 Clear To Send     */
        _U2CTSR   = RPI_NONE;       /*  UART2 Receive           */
        _U3RXR    = RPI_NONE;       /*  UART3 Clear To Send     */
        _U3CTSR   = RPI_NONE;       /*  UART3 Receive           */
        _U4RXR    = RPI_NONE;       /*  UART4 Clear To Send     */
        _U4CTSR   = RPI_NONE;       /*  UART4 Receive           */
        _OCTRIG1R = RPI_NONE;       /*                          */
        _OCTRIG2R = RPI_NONE;       /*                          */
        _TCKIAR   = RPI_NONE;       /*                          */
        _TCKIBR   = RPI_NONE;       /*                          */
        _TXCKR    = RPI_NONE;       /*                          */
        _CLCINAR  = RPI_NONE;       /*                          */
        _CLCINBR  = RPI_NONE;       /*                          */
       
        /*                                       PWM out */
        /* map all outputs                        Fixed  */
        _RP0R   =   RPO_NONE;       /*  pin RB0          */
        _RP1R   =   RPO_NONE;       /*  pin RB1          */
        _RP2R   =   RPO_NONE;       /*  pin RD8          */
        _RP3R   =   RPO_NONE;       /*  pin RD10         */
        _RP4R   =   RPO_NONE;       /*  pin RD9          */
        _RP6R   =   RPO_NONE;       /*  pin RB6          */
        _RP7R   =   RPO_NONE;       /*  pin RB7          */
        _RP8R   =   RPO_NONE;       /*  pin RB8          */
        _RP9R   =   RPO_NONE;       /*  pin RB9          */
        _RP10R  =   RPO_NONE;       /*  pin RF4          */
        _RP11R  =   RPO_NONE;       /*  pin RD0          */
        _RP12R  =   RPO_NONE;       /*  pin RD11         */
        _RP13R  =   RPO_NONE;       /*  pin RB2          */
        _RP14R  =   RPO_NONE;       /*  pin RB14         */
        _RP16R  =   RPO_NONE;       /*  pin RF3          */
        _RP17R  =   RPO_REFO;       /*  pin RF5   REFO   */
        _RP18R  =   RPO_NONE;       /*  pin RB5   OCM3A  */
        _RP19R  =   RPO_NONE;       /*  pin RG8   OCM2A  */
        _RP20R  =   RPO_NONE;       /*  pin RD5          */
        _RP21R  =   RPO_NONE;       /*  pin RG6   OCM1A  */
        _RP22R  =   RPO_NONE;       /*  pin RD3          */
        _RP23R  =   RPO_NONE;       /*  pin RD2          */
        _RP24R  =   RPO_NONE;       /*  pin RD1          */
        _RP25R  =   RPO_NONE;       /*  pin RD4          */
        _RP26R  =   RPO_NONE;       /*  pin RG7   OCM1B  */
        _RP27R  =   RPO_NONE;       /*  pin RG9   OCM2B  */
        _RP28R  =   RPO_NONE;       /*  pin RB4   OCM3B  */
        _RP29R  =   RPO_NONE;       /*  pin RB15         */
    #ifdef __PIC24FJ256GA606__
        _RP30R  =   RPO_NONE;       /*  pin RF2          */
    #endif
       
        /* Lock Registers */
        __builtin_write_OSCCONL(OSCCON | 0x40);
    }
       
    /*
     * WARNING: Not a portable function.
     *          Maximum 16MHz instruction cycle clock.
     *          Minimum  8Khz instruction cycle clock.
     */
    void delay_ms( unsigned long delay )
    {
        do
        {
            asm("repeat  %0\n clrwdt\n":: "r" (FCYC/1000L-7L));
        } while(delay--);
    }
       
    #define GPIO_OUT 0
    #define GPIO_IN  1
       
    #define LED_ON   1
    #define LED_OFF  0
       
    #define YELLOW_LED_DIR   TRISBbits.TRISB4
    #define YELLOW_LED       LATBbits.LATB4
       
    volatile unsigned int ReadOf_REFOTRIML;
       
    int main()
    {
       
        PIC_Init();
       
        YELLOW_LED_DIR = GPIO_OUT;
       
        /* Setup reference oscillator output */
        REFOCONL = 0;
        while(REFOCONLbits.ROACTIVE) REFOCONL = 0;
        REFOCONL = (    (0b0110 << _REFOCONL_ROSEL_POSITION) \
                    |   (0b1    << _REFOCONL_ROSLP_POSITION) \
                    |   (0b1    << _REFOCONL_ROOUT_POSITION) \
                    |   (0b1    << _REFOCONL_ROSWEN_POSITION) \
                   );
        REFOCONH  = 3u;
        REFOTRIML = 464u<<7u;       /* For the PIC24FJ256GB606 this does not work */
        REFOCONLbits.ROEN    = 1;
       
        /* Setup CCP1 output */
        CCP1CON1L = 0;
        CCP1CON1H = 0;
        CCP1CON2L = 0;
        CCP1CON2H = 0;
        CCP1CON3L = 0;
        CCP1CON3H = 0;
       
        CCP1TMRL=0;
        CCP1RA=50332;               // 12.288MHz for 32MHz clock Windows Calc: "((12.288*(2Y17)/32)+.5);"
        CCP1CON1Lbits.CLKSEL=0b100; // 0b100 => 2x system clock, i.e. 32MHz for 8MHz XT + PLLx4
        CCP1CON1Lbits.TMRPS=0b00;   // 0b00 => div-by-1
        CCP1CON1Lbits.T32=0;        // 16-bit mode
        CCP1CON2Hbits.OCAEN=1;      // Single output OCM1A enabled
        CCP1CON1Lbits.CCSEL=0;      // 0 => OC/PWM/Timer mode
        CCP1CON1Lbits.MOD=0b0111;   // 0b0111 => Variable Frequency Mode
        CCP1CON1Lbits.CCPON=1;      // Turn on PWM for RG6, pin 4 of TQFP-64
       
        /* loop forever, main never exits */
        for(;;)
        {
            if (YELLOW_LED == LED_OFF)
            {
                YELLOW_LED = LED_ON;
            }
            else
            {
                YELLOW_LED = LED_OFF;
            }
            delay_ms(500);   
        }
        return 0;
    }

    I have yet to figure out if I can route the OCM1A output to the SPI clock source without an external jumper.
    Perhaps using one of the mapable OCM outputs can do this internally.
    #18
    Howard Long
    Super Member
    • Total Posts : 676
    • Reward points : 0
    • Joined: 2005/04/04 08:50:32
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2019/01/03 04:57:58 (permalink)
    0
    charles@socketcom
    The PIC24FJ256GB606 does have a CCP module with the variable frequency pulse mode.
    ...
    I have yet to figure out if I can route the OCM1A output to the SPI clock source without an external jumper.
    Perhaps using one of the mapable OCM outputs can do this internally.

     
    You can use any of the OCM1A-F outputs, assuming you enable them of course. I think the 64 pin version only has OCM1A & OCM1B.
     
    The 64 pin version also has OCM2A/B & OCM3A/B, and the DS states they're MCCP. However, note that when I tried using MCCP2 on the '705 it didn't seem to support Variable Frequency Pulse mode, it only seemed to be supported on MCCP1. YMMV of course, I don't have a '6xx device in stock to try.
     
    What you could do is to route a physical OCM output through a CLC input mapped to the same pin, the OCM pins seem to be RPnn pins. Then you could configure the CLC as a simple pass through and route the CLC's output to any arbitrary pin you choose.
     
    Edit: I was assuming you had an off-chip SPI/I2S SCK on a ready-made board, but it's likely you're referring to using an on-chip SPI clock input. There is should be nothing to stop you mapping a physical OCMx pin with an RPxx assignment directly to any on-chip mappable peripheral input, including directly into an SPI SCK input. You can also map multiple mappable inputs to a single physical pin if necessary.
     
    post edited by Howard Long - 2019/01/03 05:28:30
    #19
    Howard Long
    Super Member
    • Total Posts : 676
    • Reward points : 0
    • Joined: 2005/04/04 08:50:32
    • Status: offline
    Re: PIC24FJ256GB606 silicon bug, maybe. 2019/01/05 18:50:07 (permalink)
    0
    Here is some code to generate the 12.288MHz bit clock, an LR clock, and use an SPI as an I2S interface.
     
    The CCP1 output is then fed into CCP6 which generates an I2S LR clock.
     
    The CCP1 bit clock output also goes to the SPI1 peripheral configured for I2S, together with the CCP6 output for LR clock.
     
    Quick vid: https://youtu.be/NACHKez3Gdc
     


    // PIC24FJ1024GB610 Configuration Bit Settings
    // 'C' source line config statements
    // FSEC
    #pragma config BWRP = OFF // Boot Segment Write-Protect bit (Boot Segment may be written)
    #pragma config BSS = DISABLED // Boot Segment Code-Protect Level bits (No Protection (other than BWRP))
    #pragma config BSEN = OFF // Boot Segment Control bit (No Boot Segment)
    #pragma config GWRP = OFF // General Segment Write-Protect bit (General Segment may be written)
    #pragma config GSS = DISABLED // General Segment Code-Protect Level bits (No Protection (other than GWRP))
    #pragma config CWRP = OFF // Configuration Segment Write-Protect bit (Configuration Segment may be written)
    #pragma config CSS = DISABLED // Configuration Segment Code-Protect Level bits (No Protection (other than CWRP))
    #pragma config AIVTDIS = OFF // Alternate Interrupt Vector Table bit (Disabled AIVT)
    // FBSLIM
    #pragma config BSLIM = 0x1FFF // Boot Segment Flash Page Address Limit bits (Enter Hexadecimal value)
    // FSIGN
    // FOSCSEL
    #pragma config FNOSC = FRCPLL // Oscillator Source Selection (Fast RC Oscillator with divide-by-N with PLL module (FRCPLL) )
    #pragma config PLLMODE = DISABLED // PLL Mode Selection (No PLL used; PLLEN bit is not available)
    #pragma config IESO = OFF // Two-speed Oscillator Start-up Enable bit (Start up with user-selected oscillator source)
    // FOSC
    #pragma config POSCMD = NONE // Primary Oscillator Mode Select bits (Primary Oscillator disabled)
    #pragma config OSCIOFCN = OFF // OSC2 Pin Function bit (OSC2 is clock output)
    #pragma config SOSCSEL = ON // SOSC Power Selection Configuration bits (SOSC is used in crystal (SOSCI/SOSCO) 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 // Peripheral pin select configuration bit (Allow multiple reconfigurations)
    #pragma config FCKSM = CSECMD // Clock Switching Mode bits (Clock switching is enabled,Fail-safe Clock Monitor is disabled)
    // FWDT
    #pragma config WDTPS = PS32768 // Watchdog Timer Postscaler bits (1:32,768)
    #pragma config FWPSA = PR128 // Watchdog Timer Prescaler bit (1:128)
    #pragma config FWDTEN = OFF // Watchdog Timer Enable bits (WDT and SWDTEN disabled)
    #pragma config WINDIS = OFF // Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode)
    #pragma config WDTWIN = WIN25 // Watchdog Timer Window Select bits (WDT Window is 25% of WDT period)
    #pragma config WDTCMX = WDTCLK // WDT MUX 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 = OFF // Brown Out Enable bit (Brown Out Disabled)
    #pragma config LPCFG = OFF // Low power regulator control (No Retention Sleep)
    #pragma config DNVPEN = DISABLE // Downside Voltage Protection Enable bit (Downside protection disabled when BOR is inactive)
    // FICD
    #pragma config ICS = PGD2 // ICD Communication Channel Select bits (Communicate on PGEC2 and PGED2)
    #pragma config JTAGEN = OFF // JTAG Enable bit (JTAG is disabled)
    #pragma config BTSWP = OFF // BOOTSWP Disable (BOOTSWP instruction 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 SOSCHP = OFF // SOSC High Power Enable bit (valid only when SOSCSEL = 1 (Enable SOSC low power mode)
    #pragma config ALTVREF = ALTREFEN // Alternate Voltage Reference Location Enable bit (VREF+ and CVREF+ on RA10, VREF- and CVREF- on RA9)
    // #pragma config statements should precede project file includes.
    // Use project enums instead of #define for ON and OFF.
    #include <xc.h>
    #define FCY 16000000
    #include <libpic30.h>
    #include <stdio.h>
    // Bit clock 12.288MHz SCLK/OCM1A/RG6/RP21/TCKIA: I suspect that it should really be inverted for TCKIA CCP6 input for LRCK.
    // LRCK SS1/OCM6A/RG9/RP27
    // SDO RG8/RP19
    // SDI RG7/RP26 or RG8/RP19 (loopback)
    int main(void)
    {
    TRISAbits.TRISA6=0;
    // Set up 12.288MHz
    CCP1TMRL=0;
    CCP1RA=50332; // 12.288MHz for 32MHz clock
    CCP1CON1Lbits.CLKSEL=0b100; // 0b100 => 2x system clock, i.e. 32MHz for 8MHz XT + PLLx4
    CCP1CON1Lbits.TMRPS=0b00; // 0b00 => div-by-1
    CCP1CON1Lbits.T32=0;
    CCP1CON2Hbits.OCAEN=1;
    CCP1CON1Lbits.CCSEL=0; // 0 => OC/PWM/Timer mode
    CCP1CON1Lbits.MOD=0b0111; // 0b0111 => Variable Frequency Mode
    CCP1CON1Lbits.CCPON=1;

    // Frame LRCK sync
    // Wire up CCP clock input A to OCM1A (*** I suspect this clock needs to be inverted ***)
    RPINR12bits.TCKIAR=21; // RP21 is the same pin as RG6/OCM1A (P10 E16/32)
    ANSGbits.ANSG6=0;
    RPOR13bits.RP27R=18; // RP27/RG9 OCM6 (P14 E16/32)
    ANSGbits.ANSG9=0;

    CCP6TMRL=0;
    CCP6PRL=32-1;
    CCP6RA=1;
    CCP6RB=17;
    CCP6CON1Lbits.CLKSEL=0b111; // 0b111 => TCKIA pin
    CCP6CON1Lbits.TMRPS=0b00; // 0b00 => div-by-1
    CCP6CON1Lbits.T32=0;
    CCP6CON2Hbits.OCAEN=1;
    CCP6CON1Lbits.CCSEL=0; // 0 => OC/PWM/Timer mode
    CCP6CON1Lbits.MOD=0b0101; // 0b0101 => Dual Edge Compare mode, buffered
    CCP6CON1Lbits.CCPON=1;

    // Wire up SCK1 to OCM1A
    RPINR20bits.SCK1R=21; // RP21 is the same pin as RG6/OCM1A (P10 E16/32)
    ANSGbits.ANSG6=0;

    // Wire up SS1 to OCM6A
    RPINR21bits.SS1R=27; // RP27 is connected to RG9/OCM6A (P14 E16/32)
    ANSGbits.ANSG9=0;

    // Wire up SDO
    RPOR9bits.RP19R=7; // RP19 MOSI (P12 E16/32)
    ANSGbits.ANSG8=0;

    // Wire up SDI
    #define LOOPBACK
    #ifdef LOOPBACK
    RPINR20bits.SDI1R=19; // RP19 MOSI loopback (P12 E16/32)
    ANSGbits.ANSG8=0;
    #else
    RPINR20bits.SDI1R=26; // RP26 MISO (P11 E16/32)
    ANSGbits.ANSG7=0;
    #endif
    SPI1CON1Lbits.MSTEN=0; // 0 => slave mode
    SPI1CON1Lbits.ENHBUF=1;
    SPI1CON1Lbits.DISSDI=0;
    SPI1CON1Lbits.DISSDO=0;
    SPI1CON1Lbits.CKP=1;
    SPI1CON1Hbits.AUDEN=1; // CODEC mode
    SPI1CON1Lbits.MODE=0b00; // 0b00 => 16 bit/ch, 32 bit frame
    SPI1CON1Hbits.IGNROV=1; // 1=> ignore rx overflow
    SPI1CON1Hbits.IGNTUR=1; // 1 => ignore tx underrun
    SPI1CON1Hbits.AUDMOD=0b00; // 0b00 => I2S
    SPI1CON1Hbits.FRMPOL=0; // Frame Sync one word wide
    SPI1CON1Lbits.SPIEN=1;
    while (1)
    {
    static uint16_t u16=0;

    while (!SPI1STATLbits.SPIRBE)
    {
    SPI1BUFL; // Dummy read
    }

    while (!SPI1STATLbits.SPITBF)
    {
    SPI1BUFL=u16++;
    }

    if (u16==0)
    {
    LATAbits.LATA6=!LATAbits.LATA6;
    }
    }
    return 0;
    }

    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2019 APG vNext Commercial Version 4.5