SPC5606S EMIOS capture function

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

SPC5606S EMIOS capture function

1,643 Views
hansonhe
NXP Employee
NXP Employee

For SPC5606S speed signal capture, we set below code, and it could not work under DMA or polling mode. When set at polling mode, it still waiting at below code.

while(!EMIOS_0.CH[9].CSR.B.FLAG);

Could you help review? Thanks. EMIOSA9 GPIO68 pin input 100hz square waveform, below it is our configuration.

#include "MPC5606S_M07N.h"


#define SET_PIN_DIR_OUT_1(x,y) {SIU.GPDO[y].B.PDO = 1; SIU.PCR[y].R = 0x0200;}
#define SET_PIN_DIR_OUT_0(x,y) {SIU.GPDO[y].B.PDO = 0; SIU.PCR[y].R = 0x0200;}


#define eMIOS_CH 9 //8

#define GPIO_PIN 68
#define DMA_CH 0
#define DMA_ISRn 11+DMA_CH

uint32_t edges[2], period;

void initModesAndClock(void) {
ME.MER.R = 0x0000001D; /* Enable DRUN, RUN0, SAFE, RESET modes */
/* Initialize PLL before turning it on: */
CGM.FMPLL[0].CR.R = 0x02400100; /* 8 MHz xtal: Set PLL0 to 64 MHz */
ME.RUN[0].R = 0x001F0074; /* RUN0 cfg: 16MHzIRCON,OSC0ON,PLL0ON,syclk=PLL0 */
ME.RUNPC[1].R = 0x00000010; /* Peri. Cfg. 1 settings: only run in RUN0 mode */

ME.PCTL[68].R = 0x01; /* MPC56xxB/S SIU: select ME.RUNPC[1] */
ME.PCTL[72].R = 0x01; /* MPC56xxB/P/S EMIOS 0: select ME.RUNPC[1] */
ME.PCTL[23].R = 0x01; /* MPC56xxS DMAMUX: select ME.RUNPC[1] */

/* Mode Transition to enter RUN0 mode: */
ME.MCTL.R = 0x40005AF0; /* Enter RUN0 Mode & Key */
ME.MCTL.R = 0x4000A50F; /* Enter RUN0 Mode & Inverted Key */
while (ME.GS.B.S_MTRANS) {} /* Wait for mode transition to complete */
/* Note: could wait here using timer and/or I_TC IRQ */
while(ME.GS.B.S_CURRENTMODE != 4) {} /* Verify RUN0 is the current mode */
}

void disableWatchdog(void) {
SWT.SR.R = 0x0000c520; /* Write keys to clear soft lock bit */
SWT.SR.R = 0x0000d928;
SWT.CR.R = 0x8000010A; /* Clear watchdog enable (WEN) */
}

void initPeriClkGen(void) {
CGM.AC1_SC.R = 0x03000000; /* MPC56xxS: Select aux. set 1 clock to be FMPLL0 */
CGM.AC1_DC.B.DE0 = 1; /* MPC56xxS: Enable aux. clock to eMIOS0 */

CGM.SC_DC[0].R = 0x80; // MPC56xxS enable Periph clock div by 1
CGM.SC_DC[1].R = 0x80; // MPC56xxS enable Periph clock div by 1
CGM.SC_DC[2].R = 0x80; // MPC56xxS enable Periph clock div by 1
}

void initEMIOS(void) {

EMIOS_0.MCR.B.GPRE= 7; /* Divide 64 MHz sysclk by 63+1 = 64 for 1MHz eMIOS clk*/
EMIOS_0.MCR.B.GPREN = 1; /* Enable eMIOS clock */
EMIOS_0.MCR.B.GTBE = 1; /* Enable global time base */
EMIOS_0.MCR.B.FRZ =1; /* Enable stopping channels when in debug mode */
}

void initEMIOSch23(void) { /* EMIOS 0 CH 23: Modulus Up Counter */
EMIOS_0.CH[23].CADR.R = 0xFFFF; /* counts till 1000000, 1 count = 1us */
EMIOS_0.CH[23].CCR.B.MODE = 0x50; /* Modulus Counter Buffered (MCB) */
EMIOS_0.CH[23].CCR.B.BSL = 0x3; /* Use internal counter */
EMIOS_0.CH[23].CCR.B.UCPRE=0; /* Set channel prescaler to divide by 1 */
EMIOS_0.CH[23].CCR.B.UCPEN = 1; /* Enable prescaler; uses default divide by 1 */
EMIOS_0.CH[23].CCR.B.FREN = 1; /* Freeze channel counting when in debug mode */
//EMIOS_0.CH[23].CCR.B.UCPREN = 1; /* Enable prescaler; uses default divide by 1 */
}

void initEMIOSch(void) { /* EMIOS 0 CH x: SAIC */
EMIOS_0.CH[eMIOS_CH].CCR.B.BSL = 0x3; /* Use counter bus A (default) */
EMIOS_0.CH[eMIOS_CH].CCR.B.EDPOL = 1; /* capture on rising edge */
EMIOS_0.CH[eMIOS_CH].CCR.B.FEN = 1; /* flag generates and interrupt/DMA */
EMIOS_0.CH[eMIOS_CH].CCR.B.DMA = 1; /* DMA is selected */
EMIOS_0.CH[eMIOS_CH].CCR.B.UCPRE=0; /* Set channel prescaler to divide by 1 */
EMIOS_0.CH[eMIOS_CH].CCR.B.UCPEN = 1; /* Enable prescaler; uses default divide by 1 */
//EMIOS_0.CH[eMIOS_CH].CSR.R = 0x00000001;
EMIOS_0.CH[eMIOS_CH].CCR.B.MODE = 0x02; /* Mode is SAIC */
EMIOS_0.CH[eMIOS_CH].CCR.B.FCK = 1; /* System clock */

SIU.PCR[GPIO_PIN].R = 0x0d00; /* Initialize pad for eMIOS chan. x input */
}

void initTCD(void) {

EDMA.TCD[DMA_CH].SADDR = (vuint32_t) &EMIOS_0.CH[eMIOS_CH].CADR.R;; /* Load address of source data */
EDMA.TCD[DMA_CH].SSIZE = 2; /* Read 2**2 = 4 bytes per transfer */
EDMA.TCD[DMA_CH].SOFF = 0; /* Do not increment src addr*/
EDMA.TCD[DMA_CH].SLAST = 0 ; /* After major loop, no src addr change*/
EDMA.TCD[DMA_CH].SMOD = 0; /* Source modulo feature not used */

EDMA.TCD[DMA_CH].DADDR = (vuint32_t) &edges[0]; /* Load address of destination */
EDMA.TCD[DMA_CH].DSIZE = 2; /* Write 2**2 = 4 bytes per transfer */
EDMA.TCD[DMA_CH].DOFF = 4; /* After transfer, add 4 to dest addr */
EDMA.TCD[DMA_CH].DLAST_SGA = -8; /* After major loop, reset dest addr*/
EDMA.TCD[DMA_CH].DMOD = 0; /* Destination modulo feature not used */

EDMA.TCD[DMA_CH].NBYTESu.R = 4; /* Transfer 4 bytes per minor loop */
EDMA.TCD[DMA_CH].BITER = 2; /* 2 minor loop iterations */
EDMA.TCD[DMA_CH].CITER = 2; /* Initialize current iteraction count */
EDMA.TCD[DMA_CH].D_REQ = 1; /* do not disable channel when major loop is done*/
EDMA.TCD[DMA_CH].INT_HALF = 0; /* Interrupt used */
EDMA.TCD[DMA_CH].INT_MAJ = 1;
EDMA.TCD[DMA_CH].CITERE_LINK = 0; /* Linking is not used */
EDMA.TCD[DMA_CH].BITERE_LINK = 0;
EDMA.TCD[DMA_CH].MAJORE_LINK = 0; /* Dynamic program is not used */
EDMA.TCD[DMA_CH].MAJORLINKCH = 0;
EDMA.TCD[DMA_CH].E_SG = 0;
EDMA.TCD[DMA_CH].BWC = 0; /* Default bandwidth control- no stalls */
EDMA.TCD[DMA_CH].START = 0; /* Initialize status flags */
EDMA.TCD[DMA_CH].DONE = 0;
EDMA.TCD[DMA_CH].ACTIVE = 0;

EDMA.CR.R = 0x0000E400; /* Use fixed priority arbitration for DMA groups and channels */
EDMA.CPR[DMA_CH].R = 0x0; /* Channel 0 priorites: group priority = 0, channel priority = 0 */

EDMA.SERQ.R = DMA_CH; /* Enable EDMA channel 0 */

DMAMUX.CHCONFIG[DMA_CH].B.SOURCE = 0xf+eMIOS_CH-9; /* route emios0 chx DMA request to eDMA channel */
DMAMUX.CHCONFIG[DMA_CH].B.ENBL = 0x1; /* enable the DMA Channel */

}

void DMA_isr(void)
{

if(edges[1]>edges[0])
{
period = edges[1]-edges[0]; /* calculate signal period, in us */
}
else
{
period = (EMIOS_0.CH[23].CADR.R - edges[0]) + edges[1];
}


EDMA.CINT.R = DMA_CH; /* CLear DMA channel flag */
}

unsigned int PulseA;
unsigned int PulseB;
unsigned int Pulse;

int main(void) {
volatile int i = 0;

SET_PIN_DIR_OUT_1(0, 27); // open sensor1 power
SET_PIN_DIR_OUT_1(0, 114); // open sensor2 power

initModesAndClock(); /* Initialize mode entries and system clock */
initPeriClkGen(); /* Initialize peripheral clock generation */
disableWatchdog(); /* Disable watchdog */
initEMIOS(); /* Initialize eMIOS to provide 1 MHz clock to channels */
initEMIOSch23(); /* Initialize eMIOS channel 23 as modulus counter*/

//initTCD(); /* initialize DMA channel descriptor */


/* enable DMA interrupt in INTC */
//INTC_InstallINTCInterruptHandler(DMA_isr,DMA_ISRn,1);
INTC.CPR.R = 0x0; /* lower current priority - to enable INTC to process interrupts */

//EDMA.SERQ.R = DMA_CH; /* Enable EDMA channel */

//initEMIOSch(); /* Initialize eMIOS channel as SAIC, using ch 23 as time base */

/* Loop forever */
for (;;)
{
i++;
while(!EMIOS_0.CH[9].CSR.B.FLAG);
PulseA=EMIOS_0.CH[9].CADR.R;
PulseB=EMIOS_0.CH[9].CBDR.R;
Pulse =PulseA-PulseB;
EMIOS_0.CH[9].CSR.B.FLAG=1;

}
}

NXP Wuhan Hanson He:
[Photo]

0 Kudos
1 Reply

1,535 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi Hanson,

you should also program respective SIU.PSMI register to connect used pad to eMIOS0 ch9. So set

SIU.PSMI[16].R=1;

BR, Petr