How to output pwm using DMA for MPC55xx/MPC56xx ?

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

How to output pwm using DMA for MPC55xx/MPC56xx ?

1,501 Views
plabgh
Contributor I

Hi ,

 

Anybody know how to get the demo ?

i don't know how to use EMIOS_CCR[n]_DMA and EMIOS_CSR[n]_FLAG bit ?

and, how to write A and B registers ?

pastedImage_1.png

pastedImage_3.png

thank you ... 

Tags (4)
0 Kudos
7 Replies

1,254 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi, 

I did not see a demo using DMA for updating CADR/CBDR in PWM output modes. Maybe some code for input capture mode using DMA can be found.

Anyway, if DMA bit is set, the FLAG generates DMA request. You can program the DMA channel to do what you need finally. If DMA bit is set the FLAG is cleared by DMA controller after DMA transfer is done. 

I can recommend you to refer to AN2865 (https://www.nxp.com/docs/en/application-note/AN2865.pdf ). In this cookbook note you can find example for setting eMIOS output PWM mode as well as DMA codes. You can try to combine them together to achieve desired functionality on your MCU. 

BR, Petr

0 Kudos

1,254 Views
plabgh
Contributor I

Thank you for your answer. I have one more question:

In OPWFMB mode, when will the FLAG bit be set ? match CADR ? match CBDR ? or both ?

tks!!!

0 Kudos

1,254 Views
PetrS
NXP TechSupport
NXP TechSupport

this is determined by MODE[5] bit. FLAGs can be generated only on B1 matches when MODE[5] is cleared (MODE=0x58), or on both A1 and B1 matches when MODE[5] is set (MODE=0x5A).

BR, Petr

0 Kudos

1,254 Views
plabgh
Contributor I

Hi,I have tried to accomplish code follow your advice, but it can't ouput pwm waveform.

Could you tell me what the mistake is ???  Thank you !

void Dma_eMIOS_Init(void)
{
    EDMA.CR.R = 0x0000000C;
    SIU.PCR[179].B.PA = 1;
    SIU.PCR[179].B.OBE = 1;
    EMIOS.MCR.B.MDIS = 0;
    EMIOS.MCR.B.GPRE = 3;
    EMIOS.MCR.B.ETB = 0;
    EMIOS.MCR.B.GTBE = 1;
    EMIOS.MCR.B.FRZ = 1;
    EMIOS.MCR.B.GPREN = 1;

    // OPWFMB mode
    EMIOS.CH[0].CCR.B.MODE = 0x58;
    EMIOS.CH[0].CBDR.R = 1;
    EMIOS.CH[0].CCR.B.BSL = 3;
    EMIOS.CH[0].CCR.B.UCPREN = 1;
    EMIOS.CH[0].CCR.B.UCPRE = 0;
    EMIOS.CH[0].CCR.B.EDPOL = 0;
    EMIOS.CH[0].CCR.B.FEN = 1;
    EMIOS.CH[0].CCR.B.DMA = 1;
    EMIOS.CH[0].CSR.B.FLAG = 1;
}

void eMIOS_DmaSetPeriodAndDuty(int *DutyAndPeriod)
{

    // source address - duty and period array
    EDMA.TCD[20].SADDR = (int)DutyAndPeriod;
    // 32-bit

    EDMA.TCD[20].SSIZE = 2;

    // src addr increment 4 bytes
    EDMA.TCD[20].SOFF = 4;

    // after major loop, back to beginning
    EDMA.TCD[20].SLAST = -(4 * 2);

    // source modulo feature not used
    EDMA.TCD[20].SMOD = 0;

    // dest. address - Channel A Data Register
    EDMA.TCD[20].DADDR = (int)&(EMIOS.CH[0].CADR.R);
    // 32-bit

    EDMA.TCD[20].DSIZE = 2;
    // dest addr increment 4 bytes, the next register is Channel B Data Register (CBDR)

    EDMA.TCD[20].DOFF = 4;
    // after major loop, back to beginning

    EDMA.TCD[20].DLAST_SGA = -(4 * 2);
    EDMA.TCD[20].DMOD = 0;
    // 4 byte per minor loop

    EDMA.TCD[20].NBYTES = 4;
    // 2 major iteration count

    EDMA.TCD[20].BITER = 2;
    EDMA.TCD[20].CITER = 2;
    EDMA.TCD[20].CITERE_LINK = 0;
    EDMA.TCD[20].BITERE_LINK = 0;
    EDMA.TCD[20].MAJORE_LINK = 0;
    EDMA.TCD[20].MAJORLINKCH = 0;
    EDMA.TCD[20].D_REQ = 0;
    EDMA.TCD[20].INT_HALF = 0;
    EDMA.TCD[20].INT_MAJ = 0;
    EDMA.TCD[20].E_SG = 0;
    EDMA.TCD[20].BWC = 0;
    EDMA.TCD[20].START = 0;
    EDMA.TCD[20].DONE = 0;
    EDMA.TCD[20].ACTIVE = 0;

    // enable dma channel
    EDMA.SERQR.R = 20;
}

void mian(void)

{

    // duty=100, period=200

    int t_duty_and_period[2] = {100, 200};

    Dma_eMIOS_Init();

    eMIOS_DmaSetPeriodAndDuty(t_duty_and_period);

    for (;;);

}

0 Kudos

1,254 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

what is the MCU you have?

BR, Petr

0 Kudos

1,254 Views
plabgh
Contributor I

MPC5644A

0 Kudos

1,254 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi

try to set init value for CBDR higher then 1. Also write both CADR/CBDR per single DMA request. So set

NBYTES=8, CITER=BITER=1.

Check if SADDR point correctly to t_duty_and_period array.

BR, Petr

0 Kudos