• AVR Freaks

AnsweredHot!dsPIC33FJ128GP802 speed test problem

Page: 12 > Showing page 1 of 2
Author
laserline
New Member
  • Total Posts : 17
  • Reward points : 0
  • Joined: 2010/04/16 15:44:11
  • Location: Brazil
  • Status: offline
2020/07/05 13:23:48 (permalink)
0

dsPIC33FJ128GP802 speed test problem

Hi guys,

I am making a simple test in order to start using the 33fj128gp802 and I think I am not reaching it's full 40MIPS velocity.

The code I am using is this:
==========================================================================
#define Fosc (80000000ULL)
#include "xc.h"
// FBS
#pragma config BWRP = WRPROTECT_OFF
#pragma config BSS = NO_FLASH
#pragma config RBS = NO_RAM
// FSS
#pragma config SWRP = WRPROTECT_OFF
#pragma config SSS = NO_FLASH
#pragma config RSS = NO_RAM
// FGS
#pragma config GWRP = OFF
#pragma config GSS = OFF
// FOSCSEL
#pragma config FNOSC = PRIPLL
#pragma config IESO = ON
// FOSC
#pragma config POSCMD = HS // Primary Oscillator Source (HS Oscillator Mode)
#pragma config OSCIOFNC = OFF // OSC2 Pin Function (OSC2 pin has clock out function)
#pragma config IOL1WAY = OFF // Peripheral Pin Select Configuration (Allow Only One Re-configuration)
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor (Both Clock Switching and Fail-Safe Clock Monitor are disabled)
// FWDT
#pragma config WDTPOST = PS32768 // Watchdog Timer Postscaler (1:32,768)
#pragma config WDTPRE = PR128 // WDT Prescaler (1:128)
#pragma config WINDIS = OFF // Watchdog Timer Window (Watchdog Timer in Non-Window mode)
#pragma config FWDTEN = OFF // Watchdog Timer Enable (Watchdog timer enabled/disabled by user software)
// FPOR
#pragma config FPWRT = PWR128 // POR Timer Value (128ms)
#pragma config ALTI2C = OFF // Alternate I2C pins (I2C mapped to SDA1/SCL1 pins)
// FICD
#pragma config JTAGEN = OFF // JTAG Port Enable (JTAG is Disabled)

int setup(void) {
    // Setting N1 to 4 (N1 = n+2)
    CLKDIVbits.PLLPRE0 = 0;
    CLKDIVbits.PLLPRE1 = 1;
    CLKDIVbits.PLLPRE2 = 0;
    CLKDIVbits.PLLPRE3 = 0;
    CLKDIVbits.PLLPRE4 = 0;
    // Setting M to 32 (M = m+2)
    PLLFBDbits.PLLDIV0 = 0;
    PLLFBDbits.PLLDIV1 = 1;
    PLLFBDbits.PLLDIV2 = 1;
    PLLFBDbits.PLLDIV3 = 1;
    PLLFBDbits.PLLDIV4 = 1;
    PLLFBDbits.PLLDIV5 = 0;
    PLLFBDbits.PLLDIV6 = 0;
    PLLFBDbits.PLLDIV7 = 0;
    PLLFBDbits.PLLDIV8 = 0;
    // Setting N2 to 2 (Output/2)
    CLKDIVbits.PLLPOST0 = 0;
    CLKDIVbits.PLLPOST1 = 0;

    __builtin_write_OSCCONH(0b00000011);
    __builtin_write_OSCCONL(0b00000001);
    TRISBbits.TRISB5 = 0;
}
 
int main(void) {
    setup();
    while(OSCCONbits.COSC != 0b011); // Wait for Clock switch to occur
    while(OSCCONbits.LOCK!=1) {}; // Wait for PLL to lock

    while(1){
        LATBbits.LATB5 =~ LATBbits.LATB5;
    }
}
==========================================================================

With the above program the PORT B5 is showing only a frequency of 1.42MHz in the oscilloscope.
The problem is that with a similar program in Proton Basic it is producing 6.67MHz!


Any ideas on what could be happening??
Thx in advance!


#1
ric
Super Member
  • Total Posts : 28009
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: dsPIC33FJ128GP802 speed test problem 2020/07/05 13:26:32 (permalink) ☼ Best Answerby laserline 2020/07/05 13:37:21
5 (1)
Which compiler optimisation settings are you using?
 
What if you change the line in the loop to?
LATB ^= (1 << 5);
post edited by ric - 2020/07/05 13:28:17

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#2
du00000001
Just Some Member
  • Total Posts : 3851
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: offline
Re: dsPIC33FJ128GP802 speed test problem 2020/07/05 13:39:37 (permalink)
5 (2)
6.67 MHz equates 3 instruction cycles @ 40 MHz for the loop, which would be extremely little.
1.42 MHz equates 14 cyles.
I'd check the machine code generated first.

PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
#3
laserline
New Member
  • Total Posts : 17
  • Reward points : 0
  • Joined: 2010/04/16 15:44:11
  • Location: Brazil
  • Status: offline
Re: dsPIC33FJ128GP802 speed test problem 2020/07/05 13:40:31 (permalink)
0
Hi Ric,
 
Yeah... the "LATB ^= (1<<5);" send the frequency to 3.34MHz now!
But still far from 6.67MHz of the Protom compiler.
I am new on tht XC16 and I don't know how to set the optimization settings, any tip?

Best,
Paulo


#4
ric
Super Member
  • Total Posts : 28009
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: dsPIC33FJ128GP802 speed test problem 2020/07/05 14:55:03 (permalink)
5 (1)
laserline
I am new on tht XC16 and I don't know how to set the optimization settings, any tip?

In MPLABX, edit your project properties by clicking the "spanner" icon.
Under "compiler" there should be a tab for "optimization settings".
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#5
ric
Super Member
  • Total Posts : 28009
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: dsPIC33FJ128GP802 speed test problem 2020/07/05 15:01:43 (permalink)
0
Also note, you can write this code
    CLKDIVbits.PLLPRE0 = 0;
    CLKDIVbits.PLLPRE1 = 1;
    CLKDIVbits.PLLPRE2 = 0;
    CLKDIVbits.PLLPRE3 = 0;
    CLKDIVbits.PLLPRE4 = 0;

in a much more compact, and less error-prone way
CLKDIVbits.PLLPRE = 0b00010;    // Setting N1 to 4 (N1 = n+2)

similarly
PLLFBDbits.PLLDIV = 0b000011110;    // Setting M to 32 (M = m+2)

or even
PLLFBDbits.PLLDIV = 30;    // Setting M to 32 (M = m+2)

and
CLKDIVbits.PLLPOST = 0;  // Setting N2 to 2 (Output/2)

(is that last comment correct?)
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#6
dan1138
Super Member
  • Total Posts : 3731
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: dsPIC33FJ128GP802 speed test problem 2020/07/05 15:31:34 (permalink)
0
@laserline,
 
Give this code a try:
/*
 * File:   main.c
 * Author: dan1138
 * Target: dsPIC33FJ128GP802
 * Compiler: XC16 v1.40
 * IDE: MPLABX v5.40
 *
 * Created on July 5, 2020, 2:49 PM
 */
#pragma config BWRP = WRPROTECT_OFF     // Boot Segment Write Protect (Boot Segment may be written)
#pragma config BSS = NO_FLASH           // Boot Segment Program Flash Code Protection (No Boot program Flash segment)
#pragma config RBS = NO_RAM             // Boot Segment RAM Protection (No Boot RAM)
#pragma config SWRP = WRPROTECT_OFF     // Secure Segment Program Write Protect (Secure segment may be written)
#pragma config SSS = NO_FLASH           // Secure Segment Program Flash Code Protection (No Secure Segment)
#pragma config RSS = NO_RAM             // Secure Segment Data RAM Protection (No Secure RAM)
#pragma config GWRP = OFF               // General Code Segment Write Protect (User program memory is not write-protected)
#pragma config GSS = OFF                // General Segment Code Protection (User program memory is not code-protected)
#pragma config FNOSC = FRC              // Oscillator Mode (Internal Fast RC (FRC))
#pragma config IESO = OFF               // Internal External Switch Over Mode (Start-up device with user-selected oscillator source)
#pragma config POSCMD = NONE            // Primary Oscillator Source (Primary Oscillator Disabled)
#pragma config OSCIOFNC = ON            // OSC2 Pin Function (OSC2 pin has digital I/O function)
#pragma config IOL1WAY = OFF            // Peripheral Pin Select Configuration (Allow Multiple Re-configurations)
#pragma config FCKSM = CSECMD           // Clock Switching and Monitor (Clock switching is enabled, Fail-Safe Clock Monitor is disabled)
#pragma config WDTPOST = PS32768        // Watchdog Timer Postscaler (1:32,768)
#pragma config WDTPRE = PR128           // WDT Prescaler (1:128)
#pragma config WINDIS = OFF             // Watchdog Timer Window (Watchdog Timer in Non-Window mode)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (Watchdog timer enabled/disabled by user software)
#pragma config FPWRT = PWR128           // POR Timer Value (128ms)
#pragma config ALTI2C = OFF             // Alternate I2C  pins (I2C mapped to SDA1/SCL1 pins)
#pragma config ICS = PGD1               // Comm Channel Select (Communicate on PGC1/EMUC1 and PGD1/EMUD1)
#pragma config JTAGEN = OFF             // JTAG Port Enable (JTAG is Disabled)

#include <xc.h>

/* Setup the clock to run at about 36.864 MIPS from FRC+PLL */
#define FSRC   (7372800L)   /* nominal fast RC frequency */
#define PLL_N1 (2L)         /* PLLPRE  CLKDIV<4:0> range 2 to 33 */
#define PLL_M  (40L)        /* PLLDIV  PLLFBD<8:0> range 2 to 513 */
#define PLL_N2 (2L)         /* PLLPOST CLKDIV<7:6> range 2, 4 or 8 */
#define FSYS (FSRC*PLL_M/(PLL_N1*PLL_N2))
#define FCYC (FSYS/2L)
/*
 * Initialize this PIC
 */
void PIC_Init( void )
{
    unsigned short ClockSwitchTimeout;
    
    /*
     * Disable all interrupt sources
     */
    __builtin_disi(0x3FFF); /* disable interrupts for 16383 cycles */
    IEC0 = 0;
    IEC1 = 0;
    IEC2 = 0;
    IEC3 = 0;
    IEC4 = 0;
    __builtin_disi(0x0000); /* enable interrupts */
    /*
     * Setup PLL with FRC
     * This requires that we start using the FRC oscillator.
     * Configure the PLL register.
     * Then switch to the PLL as the clock source.
     */
    
    /* Test if possible to change clock source */
    if(OSCCONbits.CLKLOCK == 0 )
    {
        /* Select FRC as the CPU clock source */
        __builtin_write_OSCCONH(0b000);

        /* start clock switch */
        __builtin_write_OSCCONL(OSCCON | _OSCCON_OSWEN_MASK);

        /* wait for oscillator switch to complete */
        for(ClockSwitchTimeout=60000;ClockSwitchTimeout;ClockSwitchTimeout--){if(!OSCCONbits.OSWEN)break;};

        /* configure PLL register */
        CLKDIVbits.DOZE = 0;
        CLKDIVbits.DOZEN = 0;
        CLKDIVbits.PLLPRE = PLL_N1-2;
        #if   PLL_N2==2
          CLKDIVbits.PLLPOST=0; /* N2=2 */
        #elif PLL_N2==4
          CLKDIVbits.PLLPOST=1; /* N2=4 */
        #elif PLL_N2==8
          CLKDIVbits.PLLPOST=3; /* N2=8 */
        #else
          #error invalid PLL_N2 paramenter
        #endif
        PLLFBDbits.PLLDIV = PLL_M-2; /* set PLL to multiply by 40 */

        /* select FRCDIVN with PLL as the CPU clock source */
        __builtin_write_OSCCONH(0b001);

        /* start clock switch */
        __builtin_write_OSCCONL(OSCCON | _OSCCON_OSWEN_MASK);

        /* wait for oscillator switch to complete */
        for(ClockSwitchTimeout=60000;ClockSwitchTimeout;ClockSwitchTimeout--){if(!OSCCONbits.OSWEN)break;};

        /* lock in this clock source */
        __builtin_write_OSCCONL(OSCCON | _OSCCON_LOCK_MASK);
    }
    /* Make GPIO pins digital I/O pins */
    AD1PCFGL = 0xFFFF;
}
/*
 * Main application
 */
int main(void)
{
    /*
     * Initialize application
     */
    PIC_Init();
    TRISBbits.TRISB5 = 0;
    /*
     * Application loop
     */
    for(;;)
    {
        /* The "Free" mode of XC16 generates crap code so we resort to inline assembly code */
        __asm("btg LATB,#5");
    }
    return 0;
}

post edited by dan1138 - 2020/07/06 15:10:49
#7
RISC
Super Member
  • Total Posts : 5776
  • Reward points : 0
  • Status: offline
Re: dsPIC33FJ128GP802 speed test problem 2020/07/05 15:49:43 (permalink)
0
Hi Laserline,
 
your configuration bits show that you select an external XTAL...
===================================================
// FOSCSEL
#pragma config FNOSC = PRIPLL
#pragma config IESO = ON
// FOSC
#pragma config POSCMD = HS // Primary Oscillator Source (HS Oscillator Mode)
===================================================
Do you have an external XTAL on your board ?
If so, what is the frequency of your XTAL ?
 
If you want to use the internal oscillator, try the code given by dan.
 
This is the initialization code should work with an external XTAL of 8MHz :
(if you have a different XTAL frequency you just need to recalculate M, N1, N2)

// Configure Oscillator to operate the device at Fcy = 40MIPS
// Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
// Fosc= 8M*40(2*2)=80Mhz for 8M input clock
PLLFBD=38;                  // M=40
CLKDIVbits.PLLPOST=0; // N1=2
CLKDIVbits.PLLPRE=0;   // N2=2
RCONbits.SWDTEN=0;   // Disable Watch Dog Timer
while(OSCCONbits.LOCK!=1) ; // Wait for PLL to lock
....

 
Regards

For support make sure to check first here : http://microchipdeveloper.com
There are hundreds of PIC, AVR, SAM...which one do YOU use ?
#8
laserline
New Member
  • Total Posts : 17
  • Reward points : 0
  • Joined: 2010/04/16 15:44:11
  • Location: Brazil
  • Status: offline
Re: dsPIC33FJ128GP802 speed test problem 2020/07/05 18:19:38 (permalink)
0
Hi guys,
 
Yes I am using a 20MHz external xtal. I will try the code tomorrow and will get back with the results.
Thanks a lot for now!
 
Best,
Paulo
 
#9
Gort2015
Klaatu Barada Nikto
  • Total Posts : 3984
  • Reward points : 0
  • Joined: 2015/04/30 10:49:57
  • Location: 0
  • Status: offline
Re: dsPIC33FJ128GP802 speed test problem 2020/07/05 19:42:03 (permalink)
3 (4)
Here is some code that will read back the cpu frequency.
Internal or External.
#include <xc.h>
// ----------------------------------------------------
unsigned long getcpufreq(unsigned long XTAL, bool External){
    unsigned int _N1 = CLKDIVbits.PLLPRE + 2,
                 _N2 = 2 + (CLKDIVbits.PLLPOST << 1),
                  _M = PLLFBD + 2;
    
    if(!External){
        XTAL      = 7370000;     // FRC
        long tune = OSCTUN > 31 ? (long)OSCTUN - 64 : OSCTUN;   // normalize
        tune     *= 27637;       // tuning freq per step +/- 0.375%
        XTAL     += tune;
    }
    return XTAL / _N1 * _M / _N2; // FOSC
}
// ----------------------------------------------------


MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
https://www.youtube.com/watch?v=Iu1qa8N2ID0
+ ST:Continues, "What Ships are Made for", Q's back.
#10
MBedder
Circuit breaker
  • Total Posts : 6901
  • Reward points : 0
  • Joined: 2008/05/30 11:24:01
  • Location: Zelenograd, Russia
  • Status: offline
Re: dsPIC33FJ128GP802 speed test problem 2020/07/06 07:04:31 (permalink)
4.5 (2)
dan1138
@laserline,
 
Give this code a try:
/*
 * File:   main.c
 * Author: dan1138
 * Target: dsPIC33FJ128GP802
 * Compiler: XC16 v1.40
 * IDE: MPLABX v5.40
 *
 * Created on July 5, 2020, 2:49 PM
 */
#pragma config BWRP = WRPROTECT_OFF     // Boot Segment Write Protect (Boot Segment may be written)
#pragma config BSS = NO_FLASH           // Boot Segment Program Flash Code Protection (No Boot program Flash segment)
#pragma config RBS = NO_RAM             // Boot Segment RAM Protection (No Boot RAM)
#pragma config SWRP = WRPROTECT_OFF     // Secure Segment Program Write Protect (Secure segment may be written)
#pragma config SSS = NO_FLASH           // Secure Segment Program Flash Code Protection (No Secure Segment)
#pragma config RSS = NO_RAM             // Secure Segment Data RAM Protection (No Secure RAM)
#pragma config GWRP = OFF               // General Code Segment Write Protect (User program memory is not write-protected)
#pragma config GSS = OFF                // General Segment Code Protection (User program memory is not code-protected)
#pragma config FNOSC = FRC              // Oscillator Mode (Internal Fast RC (FRC))
#pragma config IESO = OFF               // Internal External Switch Over Mode (Start-up device with user-selected oscillator source)
#pragma config POSCMD = NONE            // Primary Oscillator Source (Primary Oscillator Disabled)
#pragma config OSCIOFNC = ON            // OSC2 Pin Function (OSC2 pin has digital I/O function)
#pragma config IOL1WAY = OFF            // Peripheral Pin Select Configuration (Allow Multiple Re-configurations)
#pragma config FCKSM = CSECMD           // Clock Switching and Monitor (Clock switching is enabled, Fail-Safe Clock Monitor is disabled)
#pragma config WDTPOST = PS32768        // Watchdog Timer Postscaler (1:32,768)
#pragma config WDTPRE = PR128           // WDT Prescaler (1:128)
#pragma config WINDIS = OFF             // Watchdog Timer Window (Watchdog Timer in Non-Window mode)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (Watchdog timer enabled/disabled by user software)
#pragma config FPWRT = PWR128           // POR Timer Value (128ms)
#pragma config ALTI2C = OFF             // Alternate I2C  pins (I2C mapped to SDA1/SCL1 pins)
#pragma config ICS = PGD1               // Comm Channel Select (Communicate on PGC1/EMUC1 and PGD1/EMUD1)
#pragma config JTAGEN = OFF             // JTAG Port Enable (JTAG is Disabled)

#include <xc.h>

/* Setup the clock to run at about 36.864 MIPS from FRC+PLL */
#define FSRC   (7372800L)   /* nominal fast RC frequency */
#define PLL_N1 (2L)         /* PLLPRE  CLKDIV<4:0> range 2 to 33 */
#define PLL_M  (40L)        /* PLLDIV  PLLFBD<8:0> range 2 to 513 */
#define PLL_N2 (2L)         /* PLLPOST CLKDIV<7:6> range 2, 4 or 8 */
#define FSYS (FSRC*PLL_M/(PLL_N1*PLL_N2))
#define FCYC (FSYS/2L)
/*
 * Initialize this PIC
 */
void PIC_Init( void )
{
    unsigned short ClockSwitchTimeout;
    
    /*
     * Disable all interrupt sources
     */
    __builtin_disi(0x3FFF); /* disable interrupts for 16383 cycles */
    IEC0 = 0;
    IEC1 = 0;
    IEC2 = 0;
    IEC3 = 0;
    IEC4 = 0;
    __builtin_disi(0x0000); /* enable interrupts */
    /*
     * Setup PLL with FRC
     * This requires that we start using the FRC oscillator.
     * Configure the PLL register.
     * Then switch to the PLL as the clock source.
     */
    
    /* Test if possible to change clock source */
    if(OSCCONbits.CLKLOCK == 0 )
    {
        /* Select FRC as the CPU clock source */
        __builtin_write_OSCCONH(0b000);

        /* start clock switch */
        __builtin_write_OSCCONL(OSCCON | _OSCCON_OSWEN_MASK);

        /* wait for oscillator switch to complete */
        for(ClockSwitchTimeout=60000;ClockSwitchTimeout;ClockSwitchTimeout--){if(!OSCCONbits.OSWEN)break;};

        /* configure PLL register */
        CLKDIVbits.DOZE = 0;
        CLKDIVbits.DOZEN = 0;
        CLKDIVbits.PLLPRE = PLL_N1-2;
        #if   PLL_N2==2
          CLKDIVbits.PLLPOST=0; /* N2=2 */
        #elif PLL_N2==4
          CLKDIVbits.PLLPOST=1; /* N2=4 */
        #elif PLL_N2==8
          CLKDIVbits.PLLPOST=3; /* N2=8 */
        #else
          #error invalid PLL_N2 paramenter
        #endif
        PLLFBDbits.PLLDIV = PLL_M-2; /* set PLL to multiply by 32 */

        /* select FRCDIVN with PLL as the CPU clock source */
        __builtin_write_OSCCONH(0b001);

        /* start clock switch */
        __builtin_write_OSCCONL(OSCCON | _OSCCON_OSWEN_MASK);

        /* wait for oscillator switch to complete */
        for(ClockSwitchTimeout=60000;ClockSwitchTimeout;ClockSwitchTimeout--){if(!OSCCONbits.OSWEN)break;};

        /* lock in this clock source */
        __builtin_write_OSCCONL(OSCCON | _OSCCON_LOCK_MASK);
    }
    /* Make GPIO pins digital I/O pins */
    AD1PCFGL = 0xFFFF;
}
/*
 * Main application
 */
int main(void)
{
    /*
     * Initialize application
     */
    PIC_Init();
    TRISBbits.TRISB5 = 0;
    /*
     * Application loop
     */
    for(;;)
    {
        /* The "Free" mode of XC16 generates crap code so we resort to inline assembly code */
        __asm("btg LATB,#5");
    }
    return 0;
}



Or even better/faster use this epilogue instead:
   for(;;)
    {
        /* The "Free" mode of XC16 generates crap code so we resort to inline assembly code */
  __asm("repeat #16383");
       __asm("btg LATB,#5");
    }
 
#11
Gort2015
Klaatu Barada Nikto
  • Total Posts : 3984
  • Reward points : 0
  • Joined: 2015/04/30 10:49:57
  • Location: 0
  • Status: offline
Re: dsPIC33FJ128GP802 speed test problem 2020/07/06 09:58:20 (permalink)
1 (2)
The delay and clock switch looks messy.
 
It is not needed, wait for the current oscillator change
then wait for the lock.
 

MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
https://www.youtube.com/watch?v=Iu1qa8N2ID0
+ ST:Continues, "What Ships are Made for", Q's back.
#12
RISC
Super Member
  • Total Posts : 5776
  • Reward points : 0
  • Status: offline
Re: dsPIC33FJ128GP802 speed test problem 2020/07/06 10:07:45 (permalink)
1 (1)
edited

For support make sure to check first here : http://microchipdeveloper.com
There are hundreds of PIC, AVR, SAM...which one do YOU use ?
#13
Gort2015
Klaatu Barada Nikto
  • Total Posts : 3984
  • Reward points : 0
  • Joined: 2015/04/30 10:49:57
  • Location: 0
  • Status: offline
Re: dsPIC33FJ128GP802 speed test problem 2020/07/06 10:14:26 (permalink)
3 (2)
Here is one in asm with error checking (Internal and External)
.include    "xc.inc"
.include    "OSCLib2.inc"
.globl      _setfosc
; ----------------------------------------------------
.section    osccode, code
; ----------------------------------------------------
arg_M               = w0
_M                  = w0
arg_N1              = w1
N1                  = w1
arg_N2              = w2
N2                  = w2
arg_Tune            = w3
Tune                = w3
arg_External        = w4
_External           = w4
x                   = w5
divider             = w6
new                 = w7
; return error      = w0

; int
; setfosc(unsigned int M,
;         unsigned int N1,
;         unsigned int N2,
;                  int Tune,
;         unsigned int External
;        );

_setfosc:
    ; M [2 .. 513] ?
    cp       _M, #2
    bra      ltu, err_M
    mov      #513, x
    cp       _M, x
    bra      gtu, err_M
    ; - - - - - - - - - - - - - - - - - - -
    ; N1 [2 .. 33] ?
    cp       N1, #2
    bra      ltu, err_N1
    mov      #33, x
    cp       N1, x
    bra      gtu, err_N1
    ; - - - - - - - - - - - - - - - - - - -
    ; N2 [2, 4, 8] ?
    cp       N2, #2
    bra      z, $+10
    cp       N2, #4
    bra      z, $+6
    cp       N2, #8
    bra      nz, err_N2
    ; - - - - - - - - - - - - - - - - - - -
    ; attempt to tune external xtal ?
    btss     _External, #0
    bra      $+6
    cp0      Tune
    bra      nz, err_exttune
    ; - - - - - - - - - - - - - - - - - - -
    ; tune [-32 .. +31] ?
    cp       Tune, #31
    bra      gt, error_tune
    mov      #-32, x
    cp       Tune, x
    bra      lt, error_tune
    ; - - - - - - - - - - - - - - - - - - -
    ; set M PLL
    dec2     _M, _M
    mov      _M, PLLFBD
    ; - - - - - - - - - - - - - - - - - - -
    ; set N1, PLL PRE
    dec2     N1, divider
    ; - - - - - - - - - - - - - - - - - - -
    ; set N2, PLL POST
    lsr      N2, N2
    dec      N2, N2
    sl       N2, #6, N2
    ior      divider, N2, divider
    ; - - - - - - - - - - - - - - - - - - -
    ; DOZE = FCY / 8, FRCDIV = FRC / 1, DOZEN = 0
    mov      #0b11 << 12, x
    ior      divider, x, divider
    mov      divider, CLKDIV
    ; - - - - - - - - - - - - - - - - - - -
    ; set tune
    and      #0b111111, Tune
    mov      Tune, OSCTUN
    ; - - - - - - - - - - - - - - - - - - -
    ; xtal internal or external ?
    mov      #0b001, new
    btsc     External, #0
    mov      #0b011, new
    ; - - - - - - - - - - - - - - - - - - -
    ; unlock OSCCON high byte
    mov      #OSCCON + 1, x
    mov      #0x78, w0
    mov      #0x9a, w1
    mov.b    w0,  [x]
    mov.b    w1,  [x]
    mov.b    new, [x]            ; new oscilator
    ; - - - - - - - - - - - - - - - - - - -
    ;unlock OSCCON low byte
    mov      #OSCCON, x
    mov      #0x46, w0
    mov      #0x57, w1
    mov.b    w0, [x]
    mov.b    w1, [x]
    bset     OSCCON, #OSWEN      ; request NOSC
    ; - - - - - - - - - - - - - - - - - - -
    ; wait for current osc
    mov.b    OSCCON + 1, wreg
    lsr      w0, #4, w0
    cp.b     w0, new
    bra      nz, $-6
    ; - - - - - - - - - - - - - - - - - - -
    ;wait for lock
    btss     OSCCON, #LOCK
    bra      $-2
    retlw    #ERR_OK, w0
    ; - - - - - - - - - - - - - - - - - - -
err_M:
    retlw    #ERR_M, w0
    ; - - - - - - - - - - - - - - - - - - -
err_N1:
    retlw    #ERR_N1, w0
    ; - - - - - - - - - - - - - - - - - - -
err_N2:
    retlw    #ERR_N2, w0
    ; - - - - - - - - - - - - - - - - - - -
err_exttune:
    retlw    #ERR_EXTTUNE, w0
    ; - - - - - - - - - - - - - - - - - - -
err_tune:
    retlw    #ERR_TUNE, w0
; ----------------------------------------------------
.end

post edited by Gort2015 - 2020/07/06 18:20:17

MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
https://www.youtube.com/watch?v=Iu1qa8N2ID0
+ ST:Continues, "What Ships are Made for", Q's back.
#14
laserline
New Member
  • Total Posts : 17
  • Reward points : 0
  • Joined: 2010/04/16 15:44:11
  • Location: Brazil
  • Status: offline
Re: dsPIC33FJ128GP802 speed test problem 2020/07/06 10:56:18 (permalink)
0
Hi,
Firstly thanks guys for all the attention to the "problem". : )
Now I am really starting to learn how to write this initial codes on XC16!
 
ric, your tips were very usefull!
RISC, thx!
Gort2015, very usefull code... I will test it latter, noted.

dan1138, thank you, your code worked well and sent the frequency to 6.13MHz (with some small variations).
I replaced the loop line in my code with the asm you provided and obtained the same (6.13) freq.
MBedder, same 6.13MHz with your lines.

I think we reached the peak with this XC16 version. I really don't understand why the Proton24 basic is making it work on 6.67MHz, but I think I can live with that.  : ))
Unfortunately assembly code is still out of my comprehension but I intent to start to study very soon.
 
Regards!


#15
laserline
New Member
  • Total Posts : 17
  • Reward points : 0
  • Joined: 2010/04/16 15:44:11
  • Location: Brazil
  • Status: offline
Re: dsPIC33FJ128GP802 speed test problem 2020/07/06 11:07:06 (permalink)
2 (1)
Hi Gort2015, you were right.

These lines:
=============================================
while(OSCCONbits.COSC != 0b011);  // Wait for Clock switch to occur
while(OSCCONbits.LOCK!=1) {};       // Wait for PLL to lock
=============================================
were messing up with the code...
I removed them and the frequency now is on 6.67MHz., great!!
 
Thanks again to all.



 
 
 
#16
MBedder
Circuit breaker
  • Total Posts : 6901
  • Reward points : 0
  • Joined: 2008/05/30 11:24:01
  • Location: Zelenograd, Russia
  • Status: offline
Re: dsPIC33FJ128GP802 speed test problem 2020/07/06 13:14:05 (permalink)
0
laserlineMBedder, same 6.13MHz with your lines.
Wrong. Try again.


#17
ric
Super Member
  • Total Posts : 28009
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: dsPIC33FJ128GP802 speed test problem 2020/07/06 13:24:55 (permalink)
0
laserline
 
I think we reached the peak with this XC16 version. I really don't understand why the Proton24 basic is making it work on 6.67MHz, but I think I can live with that.  : ))

You never showed your basic code.
My guess would be it is selecting the internal oscillator with different dividers, not using your external clock.

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#18
laserline
New Member
  • Total Posts : 17
  • Reward points : 0
  • Joined: 2010/04/16 15:44:11
  • Location: Brazil
  • Status: offline
Re: dsPIC33FJ128GP802 speed test problem 2020/07/06 14:48:09 (permalink)
0
Hi ric,
 
The bacic code is very simple, here it goes:

=================================================================
Device = 33FJ128GP802
Declare Xtal = 80
Declare Optimiser_Level = 3

Config FBS = BWRP_WRPROTECT_OFF, BSS_NO_FLASH, RBS_NO_RAM ' Boot segment
Config FSS = SWRP_WRPROTECT_OFF, SSS_NO_FLASH, RSS_NO_RAM ' Secure segment
Config FGS = GWRP_OFF, GSS_OFF, GCP_OFF ' Code Protection
Config FOSCSEL = FNOSC_PRIPLL, IESO_ON ' Oscillator (20MHz ext Xtal) with 2 speed start-up
Config FOSC = POSCMD_HS, OSCIOFNC_OFF, IOL1WAY_OFF, FCKSM_CSDCMD
Config FWDT = WINDIS_OFF, FWDTEN_OFF ' Watchdog
Config FPOR = FPWRT_PWR128, ALTI2C_OFF ' Power up options (128ms)
Config FICD = JTAGEN_OFF ' JTAG

CLKDIV = %0000000000000010    ' N1 = 4 (valor binario + 2)
PLLFBD = %0000000000011110    ' M = 32 (valor binario + 2)
ACLKCON = %0000011110000000 ' N2 = 2 | Fclk = F(xtal) x (M/(N1xN2))

Symbol LED2 PORTB.5
DelayMS 250
'--------------------------------------
INI:
RPOR2 = 0
RPOR3 = 0
CNEN1 = 0
TRISA = %0000000000000001
TRISB = %0000000000000000

'--------------------------------------
MAIN:
PORTB.5 = ~PORTB.5
GoTo MAIN
 
=================================================================

It works very well at 6.67MHz. I can post the assembler code it generates if you want.

Now I am struggling to find some place I can find how I can write the Timer2/3 interrupt routine... 



#19
dan1138
Super Member
  • Total Posts : 3731
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: dsPIC33FJ128GP802 speed test problem 2020/07/06 15:05:09 (permalink)
5 (1)
@laserline,
 
This is one way to have XC16 perform the same oscillator setup as your BASIC example:
/*
 * File:   main.c
 * Author: dan1138
 * Target: dsPIC33FJ128GP802
 * Compiler: XC16 v1.40
 * IDE: MPLABX v5.40
 *
 * Created on July 6, 2020, 2:21 PM
 *
 * Description:
 *
 *  Setup system oscillator to use 20MHZ crystal with PLL for 40 MIPS instruction cycle.
 *  Use 3 instruction cycle loop to toggle output on RB5.
 *  Use PWM mode of OC1 to toggle output on RB2 every instruction cycle,
 */
#pragma config BWRP = WRPROTECT_OFF     // Boot Segment Write Protect (Boot Segment may be written)
#pragma config BSS = NO_FLASH           // Boot Segment Program Flash Code Protection (No Boot program Flash segment)
#pragma config RBS = NO_RAM             // Boot Segment RAM Protection (No Boot RAM)
#pragma config SWRP = WRPROTECT_OFF     // Secure Segment Program Write Protect (Secure segment may be written)
#pragma config SSS = NO_FLASH           // Secure Segment Program Flash Code Protection (No Secure Segment)
#pragma config RSS = NO_RAM             // Secure Segment Data RAM Protection (No Secure RAM)
#pragma config GWRP = OFF               // General Code Segment Write Protect (User program memory is not write-protected)
#pragma config GSS = OFF                // General Segment Code Protection (User program memory is not code-protected)
#pragma config FNOSC = FRC              // Oscillator Mode (Internal Fast RC (FRC))
#pragma config IESO = OFF               // Internal External Switch Over Mode (Start-up device with user-selected oscillator source)
#pragma config POSCMD = HS              // Primary Oscillator Source (HS Oscillator Mode)
#pragma config OSCIOFNC = ON            // OSC2 Pin Function (OSC2 pin has digital I/O function)
#pragma config IOL1WAY = OFF            // Peripheral Pin Select Configuration (Allow Multiple Re-configurations)
#pragma config FCKSM = CSECMD           // Clock Switching and Monitor (Clock switching is enabled, Fail-Safe Clock Monitor is disabled)
#pragma config WDTPOST = PS32768        // Watchdog Timer Postscaler (1:32,768)
#pragma config WDTPRE = PR128           // WDT Prescaler (1:128)
#pragma config WINDIS = OFF             // Watchdog Timer Window (Watchdog Timer in Non-Window mode)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (Watchdog timer enabled/disabled by user software)
#pragma config FPWRT = PWR128           // POR Timer Value (128ms)
#pragma config ALTI2C = OFF             // Alternate I2C  pins (I2C mapped to SDA1/SCL1 pins)
#pragma config ICS = PGD1               // Comm Channel Select (Communicate on PGC1/EMUC1 and PGD1/EMUD1)
#pragma config JTAGEN = OFF             // JTAG Port Enable (JTAG is Disabled)

#include <xc.h>

/* Setup the clock to run at 40.0 MIPS from HS+PLL */
#define FSRC   (20000000L)  /* nominal fast RC frequency */
#define PLL_N1 (4L)         /* PLLPRE  CLKDIV<4:0> range 2 to 33 */
#define PLL_M  (32L)        /* PLLDIV  PLLFBD<8:0> range 2 to 513 */
#define PLL_N2 (2L)         /* PLLPOST CLKDIV<7:6> range 2, 4 or 8 */
#define FSYS (FSRC*PLL_M/(PLL_N1*PLL_N2))
#define FCYC (FSYS/2L)
/*
 * Initialize this PIC
 */
void PIC_Init( void )
{
    unsigned short ClockSwitchTimeout;
    
    /*
     * Disable all interrupt sources
     */
    __builtin_disi(0x3FFF); /* disable interrupts for 16383 cycles */
    IEC0 = 0;
    IEC1 = 0;
    IEC2 = 0;
    IEC3 = 0;
    IEC4 = 0;
    __builtin_disi(0x0000); /* enable interrupts */
    /*
     * Setup PLL with HS oscillator
     * This requires that we start using the FRC oscillator.
     * Configure the PLL register.
     * Then switch to the PLL as the clock source.
     */
    
    /* Test if possible to change clock source */
    if(OSCCONbits.CLKLOCK == 0 )
    {
        /* Select FRC as the CPU clock source */
        __builtin_write_OSCCONH(0b000);

        /* start clock switch */
        __builtin_write_OSCCONL(OSCCON | _OSCCON_OSWEN_MASK);

        /* wait for oscillator switch to complete */
        for(ClockSwitchTimeout=60000;ClockSwitchTimeout;ClockSwitchTimeout--){if(!OSCCONbits.OSWEN)break;};

        /* configure PLL register */
        CLKDIVbits.DOZE = 0;
        CLKDIVbits.DOZEN = 0;
        CLKDIVbits.PLLPRE = PLL_N1-2;
        #if   PLL_N2==2
          CLKDIVbits.PLLPOST=0; /* N2=2 */
        #elif PLL_N2==4
          CLKDIVbits.PLLPOST=1; /* N2=4 */
        #elif PLL_N2==8
          CLKDIVbits.PLLPOST=3; /* N2=8 */
        #else
          #error invalid PLL_N2 paramenter
        #endif
        PLLFBDbits.PLLDIV = PLL_M-2; /* set PLL to multiply by 32 */

        /* select HS external oscillator with PLL as the CPU clock source */
        __builtin_write_OSCCONH(0b011);

        /* start clock switch */
        __builtin_write_OSCCONL(OSCCON | _OSCCON_OSWEN_MASK);

        /* wait for oscillator switch to complete */
        for(ClockSwitchTimeout=60000;ClockSwitchTimeout;ClockSwitchTimeout--){if(!OSCCONbits.OSWEN)break;};

        /* lock in this clock source */
        __builtin_write_OSCCONL(OSCCON | _OSCCON_LOCK_MASK);
    }
    /* Make GPIO pins digital I/O pins */
    AD1PCFGL = 0xFFFF;
}
/*
 * Main application
 */
int main(void)
{
    /*
     * Initialize application
     */
    PIC_Init();
    
    /*
     * Using the PWM setup RB2 to
     * toggle every instruction cycle.
     */
    TRISBbits.TRISB2 = 0;
    LATBbits.LATB2   = 0;
    _RP2R = 0b10010; /* map OC1 output to pin RP2/RB2 */
    
    /* set PWM period for 2 instruction cycles */
    T2CON  = 0;
    TMR2   = 0;
    PR2    = 1;
    
    /* Set PWM pulse width to 1 instruction cycle */
    OC1CON = 0;
    OC1R   = 0;
    OC1RS  = 0;
    OC1CONbits.OCM = 0b110;
    OC1RS  = 1;
    T2CONbits.TON    = 1;
    
    /*
     * Application loop
     *
     * Toggle RB5 every 3 instruction cycles
     */
    TRISBbits.TRISB5 = 0;
    for(;;)
    {
        /* The "Free" mode of XC16 generates crap code so we resort to inline assembly code */
        __asm("btg LATB,#5");
    }
    return 0;
}

I also added a method to use the hardware to toggle an output pin every instruction cycle.
post edited by dan1138 - 2020/07/06 15:08:49
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2020 APG vNext Commercial Version 4.5