Hi Martin,
Following is the code for IPWM which you had shared.
I am unable to get the pulse width since the CSR flag for channel 0 is not being set.
while (!EMIOS.CH[0].CSR.B.FLAG)/* Wait for flag to be set */
pulse_width = EMIOS.CH[0].CBDR.R;/* read pulse width from register B */
Please correct me where ever i am wrong.
#include "mpc5674f.h"
#include "fs_gpio.h"
uint32_t pulse_width, count;
FMPLL_init(void);
void initEMIOSch0(void);
void initEMIOSch1(void);
void initEMIOSch23(void);
void initEMIOS(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 main (void)
{
/* ------------------LED and Switch port init----------------------- */
SIU.PCR[65].R=0x0200;/* OBE on PE1 - LED connection */
SIU.GPDO[65].R = 0x01;
FMPLL_init();
initEMIOS();
initEMIOSch0();
initEMIOSch1();
initEMIOSch23();
while (1)
{
while (!EMIOS.CH[0].CSR.B.FLAG)/* Wait for flag to be set */
pulse_width = EMIOS.CH[0].CBDR.R;/* read pulse width from register B */
if (pulse_width == EMIOS.CH[1].CADR.R) /* Compare measured width at ch1 with original */
{
for (count=0; count<100000; count++)/* loops to toggle PE1, pulse width is correct */
SIU.GPDO[65].R = 0x01;
for (count=0; count<100000; count++)
SIU.GPDO[65].R = 0x00;
}
/* Clear flags and overruns */
EMIOS.CH[0].CSR.B.FLAG = 1;
EMIOS.CH[1].CSR.B.FLAG = 1;
EMIOS.CH[0].CSR.B.OVR = 1;
EMIOS.CH[1].CSR.B.OVR = 1;
}
}/* end of main() */
/**************************** Functions*******************************************/
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; /* Modulus Counter Buffered (MCB) */
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: Input Pulse Width Measurement (IPWM) */
{
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.EDSEL = 1; /* internal counter trigger by both edges */
EMIOS.CH[0].CCR.B.MODE = 0x04; /* Input pulse width measurement */
SIU.PCR[179].R = 0x0500; /* Initialize pad for eMIOS chan. 0 input */
}
void initEMIOSch1(void) /* EMIOS CH 1: Output Pulse Width Modulation (OPWMB) */
{
EMIOS.CH[1].CADR.R = 500; /* Leading edge when channel counter bus=500 */
EMIOS.CH[1].CBDR.R = 999; /* Trailing edge when channel's 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 = 0x60; /* MPC551x, MPC563x: Mode is OPWM Buffered */
SIU.PCR[180].R = 0x0600; /* Initialize pad for eMIOS chan. 1 output */
}
void initEMIOS(void)
{
EMIOS.MCR.B.GPRE= 131; /* Divide 40 MHz sysclk by 39+1 = 40 for 1MHz eMIOS clk */
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 */
}