Re: Need help with eMIOS

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Re: Need help with eMIOS

2,150 Views
martin_kovar
NXP Employee
NXP Employee

Hi,

 

please look at the example in the attachment. It shows, how to set emios channel with OPWM functionality. PWM frequency is 1KHz, duty cycle is set to 50%.

 

Regards,

Martin

Original Attachment has been moved to: MPC5676R-eMIOS_OPWM-CW210.zip

Labels (1)
0 Kudos
11 Replies

1,149 Views
snehakalkhair
Contributor III

Hi,

Can you please help me with the min and max frequency/frequency range in which eMIOS can work for MPC5674F?

I have a 40 MHz crystal.

0 Kudos

1,149 Views
martin_kovar
NXP Employee
NXP Employee

Hi,

I have already answered this question in the following thread:

min and max frequency of eMIOS for MPC5674F

Regards,

Martin

0 Kudos

1,149 Views
snehakalkhair
Contributor III

Following is my code for OPWM.

But I am unable to see the OPWM for Channel 1 of eMIOS.

The register values change as per Code Warrior.

How to configure the hardware pin?

Please help.

#include "mpc5674f.h"

void initEMIOS(void);

void initEMIOSch23(void);

void initEMIOSch0(void);

void initEMIOSch1(void);

//void initEMIOSch2(void);

static void FMPLL_init(void)

{

    /**** Use for 40 MHz crystal reference ****/

        // settings for 264 MHz

       SIU.ECCR.B.EBDF = 3; /* Divide sysclk by 3+1 for CLKOUT */

    FMPLL.ESYNCR2.R = 0x00000002;

    FMPLL.ESYNCR1.R = 0x70040032; // EPREDIV=4, EMFD=0x32=50

    while (FMPLL.SYNSR.B.LOCK != 1) {};

    FMPLL.ESYNCR2.R = 0x00000001; // ERFD=1

        // fextal=40 => fpll = 40*(50+16)/((4+1)*(1+1)) = 264MHz

        // fvco = 40*(50+16)/(4+1) = 528 < 600 and > 192 => correct

           #if 0

    // settings for 200 MHz

  

    SIU.ECCR.B.EBDF = 3; /* Divide sysclk by 3+1 for CLKOUT */

    FMPLL.ESYNCR2.R = 0x00000002;

    FMPLL.ESYNCR1.R = 0x70040022; // EPREDIV=4, EMFD=0x22=34

        // fextal=40 => fpll = 40*(34+16)/((4+1)*(1+1)) = 200MHz

        // fvco = 40*(34+16)/(4+1) = 400 < 600 and > 192 => correct

    while (FMPLL.SYNSR.B.LOCK != 1) {};

    FMPLL.ESYNCR2.R = 0x00000001;

    #endif

  

}

void initEMIOS(void) {

  EMIOS.MCR.B.GPRE= 131;     /* Divide 132 MHz periphclk by 131+1 = 132 for 1MHz eMIOS clk*/

  EMIOS.MCR.B.ETB = 0;      /* External time base is disabled; Ch 23 drives ctr bus A */

  EMIOS.MCR.B.GPREN = 1; /* Enable eMIOS clock */

  EMIOS.MCR.B.GTBE = 1; /* Enable global time base */

  EMIOS.MCR.B.FRZ = 1; /* Enable stopping channels when in debug mode */

}

void initEMIOSch23(void) {        /* EMIOS CH 23: Modulus Up Counter */

  EMIOS.CH[23].CADR.R = 999;     /* Period will be 999+1 = 1000 clocks (1 msec) */

  EMIOS.CH[23].CCR.B.MODE = 0x50; /* MPC551x, MPC563x: Mod Ctr Bufd (MCB) int clk */

  EMIOS.CH[23].CCR.B.BSL = 0x3;  /* Use internal counter */

  EMIOS.CH[23].CCR.B.UCPRE=0;  /* Set channel prescaler to divide by 1 */

  EMIOS.CH[23].CCR.B.FREN = 1;  /* Freeze channel counting when in debug mode */

  EMIOS.CH[23].CCR.B.UCPREN = 1;  /* Enable prescaler; uses default divide by 1 */

}

void initEMIOSch0(void) {         /* EMIOS CH 0: Output Pulse Width Modulation */

  EMIOS.CH[0].CADR.R = 250;       /* Leading edge when channel counter bus=250*/

  EMIOS.CH[0].CBDR.R = 500;       /* Trailing edge when channel counter bus=500*/

  EMIOS.CH[0].CCR.B.BSL = 0x0;  /* Use counter bus A (default) */

  EMIOS.CH[0].CCR.B.EDPOL = 1;  /* Polarity-leading edge sets output/trailing clears*/

  EMIOS.CH[0].CCR.B.MODE = 0x60;  /* MPC551x, MPC563x: Mode is OPWM Buffered */

  SIU.PCR[179].R = 0x0600;        /* Initialize pad for eMIOS chan. 0 output */

}

void initEMIOSch1(void) {         /* EMIOS CH 0: Output Pulse Width Modulation */

  EMIOS.CH[1].CADR.R = 250;       /* Leading edge when channel counter bus=250*/

  EMIOS.CH[1].CBDR.R = 999;       /* Trailing edge when channel counter bus=999*/

  EMIOS.CH[1].CCR.B.BSL = 0x0;  /* Use counter bus A (default) */

  EMIOS.CH[1].CCR.B.EDPOL = 1;  /* Polarity-leading edge sets output/trailing clears*/

  EMIOS.CH[1].CCR.B.MODE = 0x06;  /* MPC551x, MPC563x: Mode is OPWM Buffered */

  SIU.PCR[180].R = 0x0600;        /* Initialize pad for eMIOS chan. 1 output */

}

int main(void) {

  volatile int i = 0;

  FMPLL_init();

  initEMIOS(); /* Initialize eMIOS to provide 1 MHz clock to channels */

  initEMIOSch23();   /* Initialize eMIOS channel 23 as modulus counter*/

  initEMIOSch0(); /* Initialize eMIOS channel 0 as OPWM, using ch 23 as time base */

  initEMIOSch1();

  //initEMIOSch2(); /* Initialize eMIOS channel 2 as OPWM, using ch 23 as time base */

  /* Loop forever */

  for (;;) {

    i++;

  }

}

0 Kudos

1,149 Views
martin_kovar
NXP Employee
NXP Employee

Hi,

you have typo in your void initEMIOSch1(void) function. EMIOS.CH[1].CCR.B.MODE has to be set to 0x60 not 0x06 as you have in your function.

Regards,

Martin

0 Kudos

1,149 Views
snehakalkhair
Contributor III

Yes.

Thank you. Got that.

Please help me out with a sample code for input pulse period measurement.

eg. Can i measure the pulse period coming out of channel 0 and take it as input for measurement on channel 2?

0 Kudos

1,149 Views
martin_kovar
NXP Employee
NXP Employee

Hi,

please look at the following thread. There you find sample code for IPWM.

https://community.nxp.com/message/605249#comment-605249

You can use the signal from channel 0 as input for channel 2, but you have to externally interconnect the pins, where eMIOS channels are routed to.

Regards,

Martin

1,149 Views
snehakalkhair
Contributor III

Hi Martin,

I request you to please help me understand the calculation of the frequency of system clock , eMIOS clock and duty cycle if i am using a 40MHz crystal for MPC5674F.

I am confused with the values set for ESYNCR1 and ESYNCR2 in the following code:

    // settings for 264 MHz

    SIU.ECCR.B.EBDF = 3; /* Divide sysclk by 3+1 for CLKOUT */

    FMPLL.ESYNCR2.R = 0x00000002;

    FMPLL.ESYNCR1.R = 0x70040032;

0 Kudos

1,149 Views
martin_kovar
NXP Employee
NXP Employee

Hi,

the first line (SIU.ECCR...) is not relevant. This only set CLKOUT frequency.

pastedImage_0.png

     

FMPLL.ESYNCR2.R = 0x00000002;
FMPLL.ESYNCR1.R = 0x70040032;
      while (FMPLL.SYNSR.B.LOCK != 1) {}; /* Wait for FMPLL to LOCK  */
FMPLL.ESYNCR2.R = 0x00000001;                  /* Fsys =264Mhz */

This is correct FMPLL settings for Fsys = 264MHz.

ESYNCR1 and ESYNCR2 are used to set Fsys frequency. Please look at the reference manual especially look at the following formula:

pastedImage_1.png

eMIOS clock is half of the sys clock. This means, if you set FMPLL to 264MHz, eMIOS clock will be 132MHz. eMIOS module contains it's own prescaler, which can be used for frequency adjustment.

I suppose you do not know, how I calculated the OPWM frequency and duty cycle in the example I sent you.

Let's say you have Fsys = 264MHz and you want eMIOS clock 1MHz:

Fsys = 264MHz

eMIOS clock = 132MHz ---you want 1MHz, you have to set prescaler to 132.

Now you have 1MHz in eMIOS input. It means that eMIOS counter increase it's value by 1 each 1us (microsecond). So I created time base using channel 23 and set CADR register to 999. It means one period lasts 1000 timer's tick (1ms). This is the OPWM frequency. 

If duty cycle is 50%, it means that half period is signal in logical 1 and half period is logical 0.  This is determined by CADR and CBDR registers in appropriate eMIOS channel, which is set to generate OPWM.

Regards,

Martin

0 Kudos

1,149 Views
snehakalkhair
Contributor III

Hi Martin,

Following is my code for OPWM. I am unable to understand the calculation and relation of period and duty cycle in this following code. I am using a 4wire PC fan to run using my eMIOS PWM output. It needs 25KHz of frequency. When i set my period to 38 , i get a frequency of 25KHz on my DSO.

void Pwm_Ini(uint8_t Chn)

{

       SIU.PCR[Chn + 179].B.PA  = 1;     /*Initialize PORT*/

       SIU.PCR[Chn + 179].B.OBE = 1;

       EMIOS.MCR.B.MDIS= 0;                 /*EMIOS module enter normal mode */

       EMIOS.MCR.B.GPRE= 131;             /* eMIOS clk= sysclk/(GPRE+1)= 64MHz/64= 1MHz */

       EMIOS.MCR.B.ETB= 0;                  /*External time base is disabled  */

       EMIOS.MCR.B.GTBE= 1;                 /*Enable global time base */

       EMIOS.MCR.B.GPREN= 1;                /*Enable eMIOS clock */

       EMIOS.CH[Chn].CCR.B.MODE= 0x19;      /*Mode is OPWFM*/

       EMIOS.CH[Chn].CCR.B.BSL= 0x3;        /*All channels: internal counter */

       EMIOS.CH[Chn].CCR.B.UCPREN= 1;       /*Prescaler enabled */

       EMIOS.CH[Chn].CCR.B.FEN= 0;          /*Disable interupt */

       EMIOS.CH[Chn].CCR.B.UCPRE= 0;        /*Prescaler=0, Divide Ratio=1 */

       EMIOS.CH[Chn].CCR.B.EDPOL= 1;        /*Polarity-leading edge sets output/trailing clears */

}

void Pwm_Output(uint8_t Chn,uint32_t Period, uint32_t DutyCycle)

{

      EMIOS.CH[Chn].CBDR.R = Period;       /* Set  Period     */

      EMIOS.CH[Chn].CADR.R = DutyCycle;    /* Set  Duty Cycle */

}

int main(void)

{

  volatile int x;

  FMPLL_init();

    do

    {

  

     Pwm_Ini(0);      //initialize eMIOS[0]

     for(x=0; x<0x2000000; x++)

     Pwm_Output(0, 38, 35);       //period is set to 38 to get a frequency of 25KHz on oscilloscope

    

    for(x=0; x<0x2000000; x++)

    Pwm_Output(0, 38, 20);     

   

    for(x=0; x<0x2000000; x++)

    Pwm_Output(0, 38, 15);        

    } while(1);

}

Please help.

0 Kudos

1,149 Views
martin_kovar
NXP Employee
NXP Employee

Hi,

use the following code to set OPWM to 25KHz and duty cycle 50%.

void initEMIOSch23(void) {        /* EMIOS CH 23: Modulus Up Counter */

/*This register in channel 23 set OPWM frequency*/

 

  EMIOS.CH[23].CADR.R = 39;     /* Period will be 39+1 = 40 clocks (0.04 msec = 25KHz) */

  EMIOS.CH[23].CCR.B.MODE = 0x50; /* MPC551x, MPC563x: Mod Ctr Bufd (MCB) int clk */

  EMIOS.CH[23].CCR.B.BSL = 0x3;  /* Use internal counter */

  EMIOS.CH[23].CCR.B.UCPRE=0;  /* Set channel prescaler to divide by 1 */

  EMIOS.CH[23].CCR.B.FREN = 1;  /* Freeze channel counting when in debug mode */

  EMIOS.CH[23].CCR.B.UCPREN = 1;  /* Enable prescaler; uses default divide by 1 */

}

void initEMIOSch0(void) {         /* EMIOS CH 0: Output Pulse Width Modulation */

/*These two registers in channel 0 set duty cycle*/

  EMIOS.CH[0].CADR.R = 0;       /* Leading edge when channel counter bus=0*/

  EMIOS.CH[0].CBDR.R = 500;       /* Trailing edge when channel counter bus=500*/

  EMIOS.CH[0].CCR.B.BSL = 0x0;  /* Use counter bus A (default) */

  EMIOS.CH[0].CCR.B.EDPOL = 1;  /* Polarity-leading edge sets output/trailing clears*/

  EMIOS.CH[0].CCR.B.MODE = 0x60;  /* MPC551x, MPC563x: Mode is OPWM Buffered */

  SIU.PCR[179].R = 0x0600;        /* Initialize pad for eMIOS chan. 0 output */

}

Regards,

Martin

0 Kudos

1,149 Views
snehakalkhair
Contributor III

Thanks a lot.

It helped. I was able to see the PWM.

I request you to please help me with a code sample for IPM mode.

0 Kudos