• AVR Freaks

AnsweredHot!Pic32 SYSCLK Issue

Author
Edwardsan2
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2019/04/05 11:30:20
  • Location: 0
  • Status: offline
2019/04/18 08:36:14 (permalink)
0

Pic32 SYSCLK Issue

Hi all, I'm trying to verify SYSCLK is working at 40MHZ properly to use it with UART. The code below is suppose to toggle and led on the PIC32MK1024GPE development board every second but instead toggles it around every 4 seconds. I've tried including 
SysConfigPerformance(40000000L), but including the dependency plib.h gives:fatal error: peripheral/adc10.h: No such file or directory
#include <peripheral/adc10.h> 
What code am i missing? The SYSCLK is causing baud rate mismatch issues for UART to serial.
Thanks
 
/* This program configures the PIC32 for communication with a computer at 57600 baud.
 * When the communication link is set up, the program will simply take input text
 * from the user and mock him/her. It demonstrates the basics of UART data Rx/Tx.
 */
// DEVCFG3
#pragma config USERID = 0xFFFF // Enter Hexadecimal value (Enter Hexadecimal value)

// DEVCFG2
#pragma config FPLLICLK=PLL_FRC // Primary oscillator is input to PLL
#pragma config FPLLIDIV = DIV_2 // PLL Input Divider:8Hz Divide by 2=4MHz (output of here must be between 4-5 MHz)
#pragma config FPLLMULT = MUL_20 // PLL Multiplier: 4MHz Multiply by 20=80MHz
#pragma config FPLLODIV = DIV_2 // PLL Output Divider: 80MHz/2=40Mhz=SYSCLK

// DEVCFG1
#pragma config FPLLRNG=RANGE_5_10_MHZ //SYSTEM PLL INPUT RANGE 5-10 MHZ
#pragma config FNOSC = FRC // Oscillator Selection Bits (8Mhz)
#pragma config FSOSCEN = OFF // Secondary Oscillator Enable (Enable Secondary Oscillator)
#pragma config POSCMOD = OFF // Use oscillator between osc1 and osc2
#pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Disabled)
#pragma config FDMTEN = OFF // Deadman Timer Enable (Deadman Timer is disabled)


// DEVCFG0
#pragma config DEBUG = OFF // Background Debugger Enable (Debugger is disabled)
#pragma config JTAGEN = OFF // JTAG Enable (JTAG Disabled)

// DEVCP
#pragma config CP = OFF // Code Protect (Protection Disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <p32xxxx.h>
#include <sys/attribs.h> //contains macros intended to simplify the application of attributes to interrupt functions
//Core timer increments once every SYSCLK/2, so 40 MHz/2
//To generate interrupt every 2 seconds. 2=[1/(40MHz)]*num_of_ticks
#define CORE_TICKS 20000000
//1st arg:interrupt src(pg.123-XC32VECTORNAME)
//2nd arg:priority level, and SOFT or SRS
void __ISR(_CORE_TIMER_VECTOR,IPL6SRS) CoreTimerISR(void){
    IFS0bits.CTIF=0;
    LATGINV=0x1000;
    _CP0_SET_COUNT(0); // set core timer counter to 0
    _CP0_SET_COMPARE(CORE_TICKS); // must set CP0_COMPARE again after interrupt
}

int main(void){
    //SysConfigPerformance(40000000L)
    TRISGbits.TRISG12=0; //set direction as output
    INTCONbits.MVEC=1; //set to enable multi-vector mode
    __builtin_disable_interrupts();
    _CP0_SET_COMPARE(CORE_TICKS); //CPO Compare Register set to 60M ticks
    IPC0bits.CTIP=6; // step 3: Interrupt priority bits, level 6
    IPC0bits.CTIS = 0; // step 4: Interrupt sub-priority bits is 0, which is the default
    //typically peripherals set interrupt in response to event, and software clears them
    IFS0bits.CTIF = 0; // step 5: clear CT interrupt flag
    IEC0bits.CTIE = 1; // step 6: enable core timer interrupt(make it available/initialize)
    __builtin_enable_interrupts(); // step 7: CPU interrupts enabled
    _CP0_SET_COUNT(0); // set core timer counter to 0
    while(1) { ; }
    return 0;
}

post edited by Edwardsan2 - 2019/04/18 09:08:42
#1
jg_ee
Super Member
  • Total Posts : 144
  • Reward points : 0
  • Joined: 2015/04/30 10:54:52
  • Location: Colorado
  • Status: offline
Re: Pic32 SYSCLK Issue 2019/04/18 09:25:01 (permalink)
0
Here is my simple PIC32MK config routine, (I think initially adapted from Mysil's):
 

 
#define hwUNLOCK_KEY_0 ( 0xAA996655UL )
#define hwUNLOCK_KEY_1 ( 0x556699AAUL )

/*-----------------------------------------------------------*/

void vHardwareConfigurePerformance( void )
{
 SYSKEY = hwUNLOCK_KEY_0;
 SYSKEY = hwUNLOCK_KEY_1;

    PB1DIVbits.PBDIV = 0b000; //PB1 at SYSCLK
    
 PB2DIVbits.PBDIV = 0b000; //PB2 at SYSCLK

 PB3DIVbits.PBDIV = 0b000; //PB3 at SYSCLK

 PB4DIVbits.PBDIV = 0b000; //PB4 at SYSCLK
    
    /* Configure CP0.K0 for optimal performance (cached instruction pre-fetch)*/
 __builtin_mtc0(16, 0,(__builtin_mfc0(16, 0) | 0x3));
    
    CHECONbits.PFMWS = 0x03; // 3 wait states for 120 MHz
    
    /* THIS MUST BE DISABLED FOR PIC32MK SILICON REV A1 (0x00)*/
    CHECONbits.PREFEN = 0x00; // enable predictive cache for both mem regions
    //CHECONbits.PREFEN = 0x01; // enable predictive cache for both mem regions

 SYSKEY = 0;

 /* Disable interrupts - note taskDISABLE_INTERRUPTS() cannot be used here as
 FreeRTOS does not globally disable interrupt. */
 __builtin_disable_interrupts();
}
 

post edited by jg_ee - 2019/04/18 09:26:51
#2
Larry.Standage
Super Member
  • Total Posts : 878
  • Reward points : 0
  • Joined: 2011/12/30 09:50:47
  • Location: 0
  • Status: offline
Re: Pic32 SYSCLK Issue 2019/04/18 09:27:55 (permalink)
0
SysConfigPerformance was part of the classic PLIBs, which have been deprecated in favor of Harmony.
 
The main thing SysConfigPerformance would have done anyway was to configure the prefetch module so that the wait states on the flash is appropriate for the speed. It defaults to the maximum wait states, so you can set it for minimum for 40 MHz, and you should be good to go.
#3
jg_ee
Super Member
  • Total Posts : 144
  • Reward points : 0
  • Joined: 2015/04/30 10:54:52
  • Location: Colorado
  • Status: offline
Re: Pic32 SYSCLK Issue 2019/04/18 09:31:30 (permalink)
0
Also, take a look at the the oscillator diagram in the PIC32MK datasheet, it has some different frequency requirements then the old PIC32MX, i wants 5-64 MHz as the PLL input.  You also need to set the PLLRANGE depending on your input.
#4
Mysil
Super Member
  • Total Posts : 3321
  • Reward points : 0
  • Joined: 2012/07/01 04:19:50
  • Location: Norway
  • Status: offline
Re: Pic32 SYSCLK Issue 2019/04/18 14:46:55 (permalink) ☼ Best Answerby Edwardsan2 2019/04/18 17:36:56
0
Hi,
In code shown in message #1, there is some effort put in to configure the system PLL,
but this have no effect, since a few lines further down,
the FRC clock is selected to be used directly,
so processor is actually running at 8 MHz, not 40 MHz as expected.
#pragma config FNOSC = FRC // Oscillator Selection Bits (8Mhz)
/* To use PLL clock,  change to : */
#pragma config FNOSC = SPLL             // Oscillator Selection Bits (System PLL)

 
But then, the PLL multiplier is too low, PLL shall run at a frequency between 350 MHz and 700 MHz,
so PLLMULT = MUL_80     might work better, 
    FPLLODIV = DIV_16     and then divide down to 40 MHz
when FRC oscillator is used as PLL input.
 
    Mysil
#5
Edwardsan2
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2019/04/05 11:30:20
  • Location: 0
  • Status: offline
Re: Pic32 SYSCLK Issue 2019/04/18 17:38:43 (permalink)
0
Thanks for the replies,Mysil was right about the output frequency to PLLODIV, and SPLL, ill make sure to check the Datasheet more
#6
Mysil
Super Member
  • Total Posts : 3321
  • Reward points : 0
  • Joined: 2012/07/01 04:19:50
  • Location: Norway
  • Status: offline
Re: Pic32 SYSCLK Issue 2019/04/18 23:16:07 (permalink)
5 (1)
Then, clearing the core timer register to zero for each interrupt is not good practice.
It will cause the time interval to creep, caused by the time passing from Compare register match and triggering the interrupt, until timer update is processed in the interrupt handler.
With the system clock frequency used, this seem to be about 1.2 microcecond.
 
Clearing the core timer Count register, will also make it impossible to use the core timer for other time measurement purposes at the same time. 
A better solution is to increment the Compare register with the interval value, and leave Count register unchanged:
//                                      /* This is not smart, Clearing the Core timer, */     
//    _CP0_SET_COUNT(0); // set core timer counter to 0 /* will cause interrupt timing to drift. */
//    _CP0_SET_COMPARE(  CORE_TICKS); // must set CP0_COMPARE again after interrupt.
                                        /* Instead, Increment Compare register with Core Ticks value. */
    _CP0_SET_COMPARE( _CP0_GET_COMPARE() + CORE_TICKS); 

 
Including the file  p32xxxx.h  is some remains from C32 compiler, and is redundant,
when  xc.h  have been included. 
 
    Mysil
 
#7
Jump to:
© 2019 APG vNext Commercial Version 4.5