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
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!!!
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
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 (;;);
}
Hi,
what is the MCU you have?
BR, Petr
MPC5644A
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