R32C PLL Clock Configuration

I am facing a aproblem when trying to configure the PLL clock in order to set the CPU clock to 50 Mhz

I am using an external Quartz of 8 Mhz and the following setup program:

;*******************************************************

;        Set PLL Speed

;*******************************************************

Set_pll_clock:

            mov.b        #0FFH,prcr        ; Enable write to control registers

            mov.b        #080H,prcr2        ; Enable write to CM3 register

            mov.b        #0AAH,prr          ; Enable write to CCR, FMCR, PBC register

            bclr                pm21            ; Enable clock change

            mov.b        #008H,cm0        ; System clock control register 0

            mov.b        #020H,cm1        ; System clock control register 1   

            mov.b        #000H,cm2        ; Oscillation stop detect register

            mov.b        #002H,cm3        ; Low speed mode clock control register

            mov.b        #000H,tcspr        ; Count source prescaler register   

            mov.b        #080H,tcspr        ; Count source prescaler register

            mov.b        #000H,cpsrf        ; Clock prescaler reset register

            mov.w        #0A0DH,pbc       ; Peripheral bus control register

                                                      ; value depends on setting of CCR register

            mov.b        #013H,ccr        ; Clock control register

            mov.b        #01FH,ccr        ; Clock control register   

            mov.b        #0FFH,prcr       

            mov.b        #004H,plc0        ; PLL control register 0

            mov.b        #0FFH,prcr       

            mov.b        #001H,plc1        ; PLL control register 1

            bclr        seo                       ; PLL mode

            bclr        bcs                       ; Base clock source is PLL

            mov.b        #0FFH,prcr

            mov.b        #020H,pm3        ; Peripheral clock  = PLL/6

            bset        pm21                  ; Disable clock change

            mov.b        #000H,prcr

rts

but can never the desired clock frequency of 100Mhz for the PLL

Thks in advance for your help

  • I believe this should work:

    void CLK_Init(void)

    {

      prr  = 0xAA;

      pbc  = 0x0504;

      ccr  = 0x1C;

      ccr  = 0x1F;

      prr  = 0x00;

      prcr = 0x04;

      plc  = 0x0104;

      prcr = 0x00;

      prcr = 0x01;

      cm0  = 0x00;

      prcr = 0x00;

      prcr = 0x02;

      pm2  = 0x40;

      prcr = 0x00;

    }

  • I tried your example (translated in asm) as follows:

    Set_pll_clock2:

             mov.b    #0AAH,prr        ; Write enable PBC register

             mov.w    #0504H,pbc        ; Define Peripheral Bus Control Register

            mov.b    #0AAH,prr        ; Write enable PBC register

            mov.b    #01CH,ccr        ;

            mov.b    #01FH,ccr

            mov.b    #000H,prr

            mov.b    #004H,prcr

             mov.b    #04H,plc0

            mov.b    #004H,prcr

            mov.b    #001H,plc1

            mov.b    #000H,prcr

              mov.b    #001H,prcr

            mov.b    #00H,cm0

             mov.b    #000H,prcr

            mov.b    #002H,prcr   

             mov.b    #040H,pm2

            mov.b    #000H,prcr

            mov.b        #0FFH,prcr        ; Write register enable   

            bclr        seo                ; Enable PLL mode

            mov.l        #0FFFH,R2R0

    clock_wait2:

            dec.l        R2R0               ; wait for clock stabilisation

            jne         clock_wait2

            mov.b        #0FFH,prcr        ; Write register enable   

            bclr         bcs                ; Base clock source is PLL

    rts 

    As I am using a 64 pins uP I do not have an external CPU pin to monitor the frequency, so I run the following routine

            bset        pd10_4

    freq:   

            bnot        p10_4

            jmp.b        freq

    Interrupt are disabled and I estimated this loop should be 4 cycles therefore with a 8Mhz quartz input frequency the cpu clock

    should be 50 Mhz (PLL clock 100Mhz/2) and the software clock 12,5Mhz (80ns) but when I measured it I found a 400 ns period !

    If I modify the plc0 & plc1 values the clock is effectively modified

    Do you have any explanation ?

    Regards

    JP

  • write to plc register must be 16 bit width, in C:

    *(unsigned short *)&plc0 = 0x0304;      // 50MHz, PLL = 100MHz Q=8MHz

  • Thanks for your help but unfortunately this is not the solution as plc0 & plc1 registers are both 8 bits.

    I guess you write the two registers in one shot within C but this does not solve my problem

  • You cannot use a port toggle to measure the execution time.

    - Every access to sfr has an additional wait.

    - Access from CPU to port is delayed because CPU bus and peripheral bus run at ifferent speed.

    - Additional delays may occure if the lable freq is placed at an odd address.

    If you want to measure clock speed, measure any timer output signal. A port toggle by a timer output signal has no additional delays and is a reliable indicator for clock speed.

    On RX PORT TOGGLE BY SOFTWARE IS NO RELIABLE INDICATOR FOR CLOCK SPEED.

  • Thanks for the update it sounds relevant, I will modify the program and let you know

    Regards

  • I have changed the program to monitor the clock through the Timer A0 and now see a 25Mhz frequency (40 ns period measured on Oscillo)

    rather then 50Mhz (PLL 100Mhz/2). here is the clock setup program:

    Set_pll_clock2:

             mov.b    #0AAH,prr        ; Write enable PBC register

             mov.w    #0504H,pbc        ; Define Peripheral Bus Control Register

            mov.b    #0AAH,prr        ; Write enable PBC register

            mov.b    #01CH,ccr        ;

            mov.b    #01FH,ccr

            mov.b    #000H,prr

            mov.b    #004H,prcr

             mov.b    #04H,plc0        ; Set PLL clock   

            mov.b    #004H,prcr

            mov.b    #001H,plc1        ; to 100Mhz   

            mov.b    #000H,prcr

              mov.b    #001H,prcr

            mov.b    #00H,cm0

             mov.b    #000H,prcr

            mov.b    #002H,prcr   

             mov.b    #040H,pm2

            mov.b    #000H,prcr

            mov.l    #0FFFH,R2R0

    clock_wait2:

            dec.l    R2R0

            jne     clock_wait2

            mov.b    #0FFH,prcr        ; Write register enable   

            bclr    seo                ; Enable PLL mode

            mov.b    #0FFH,prcr        ; Write register enable   

            mov.b    #060H,pm3        ; Set Peripheral Clock Source Divider to 2

    rts 

             bclr     bcs                ; Base clock source is PLL

    and here is the Timer A0 setup program:

    Init_timerA_0:

                mov.w    #0,ta0                ; Set timer counter to 0+1   

                mov.b     #0,ta0mr            ; Timer mode freq = f1

    rts

    Do you have any explanation why the TimerA0 frequency is not 50 Mhz? (PLL/2)

    Thanks for your help

  • May be because every timer overflow only toggles TA0 output? This adds an additional divider /2.

  • Sorry I did not get it, could you be more detailled in your explanation ?