Other Parts Discussed in Thread: CONTROLSUITE, TMS320F28335
Hi All,
I am attempting to feed 1000 values from a sin LUT into EPWM2 via DMA. I am finding the wrap/burst/transfer process confusing. My current thinking is that 1 burst, which will be 1 value from the LUT, will be transferred each time TBCTR=0. This will continue on until 1000 values have been copied, at which point the wrap function will reset the source addr back to sin[0] and the process will repeat indefinitely. This is not working, so I must be missing something.
Relevant code:
void EPWM2_Config()
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; //Disable TBCLKSYNC
SysCtrlRegs.MAPCNF.bit.MAPEPWM = 1; //Remap ePWMs for DMA access
EDIS;
EPwm2Regs.TBPRD = 624; //for 240KHz set to 625
EPwm2Regs.CMPA.half.CMPA = 600; //this will change with sine table
EPwm2Regs.CMPB = 156; //ADC will sample here, needs testing
EPwm2Regs.TBCTR =0;
EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW; //use shadow register
EPwm2Regs.TBPHS.half.TBPHS = 0;
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; //single ramp mode
EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; //because this is the master to epwm3
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; //timers are software synced when TBCLKSYNC bit is set so this is not used
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; //TBCLK, time base clock, - HSPCLKDIV, high speed peripheral clock
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1; //TBCLK=SYSCLKOUT/(HSPCLKDIV x CLKDIV)
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; //use shadow register
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; //use shadow register
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; //load new value on CTR=0
EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; //load new value on CTR=0
EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET; //output EPwm2A goes high when TBCTR=0;
EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; //output EPwm2A goes low when TBCTR=CMPA;
EPwm2Regs.AQCTLB.bit.ZRO = AQ_CLEAR; //output EPwm2B goes low when TBCTR=CMPB;
EPwm2Regs.AQCTLB.bit.CAU = AQ_SET; //output EPwm2B goes high when TBCTR=0;
EPwm2Regs.ETSEL.bit.SOCASEL = 1; //ADCSOCA on TBCTR=0
EPwm2Regs.ETPS.bit.SOCAPRD = 1; //Generate SOCA on 1st event
EPwm2Regs.ETSEL.bit.SOCAEN = 1; //Enable SOCA generation
}
void DMACH1Config(void)
{
EALLOW;
// Set up MODE Register:
DmaRegs.CH1.MODE.bit.PERINTSEL = 20; // ePWM2 SOCA as peripheral interrupt source
DmaRegs.CH1.MODE.bit.PERINTE = 1; // Peripheral interrupt enabled
DmaRegs.CH1.MODE.bit.ONESHOT = 0; // 1 burst per SW interrupt
DmaRegs.CH1.MODE.bit.CONTINUOUS = 1; // Do not stop after each transfer
DmaRegs.CH1.MODE.bit.SYNCE = 0; // No sync signal
DmaRegs.CH1.MODE.bit.SYNCSEL = 0; // No sync signal
DmaRegs.CH1.MODE.bit.DATASIZE = 0; // 16-bit data size transfers
DmaRegs.CH1.MODE.bit.CHINTMODE = 0; // Generate interrupt to CPU at the beg of transfer
DmaRegs.CH1.MODE.bit.CHINTE = 0; // Channel Interrupt to CPU enabled
// Set up BURST registers:
DmaRegs.CH1.BURST_SIZE.all = 0; // Number (N-1) of 16-bit words transferred in a burst
DmaRegs.CH1.SRC_BURST_STEP = 0; // Not needed since BURST_SIZE = 0
DmaRegs.CH1.DST_BURST_STEP = 0; // Not needed since BURST_SIZE = 0
// Set up TRANSFER registers:
DmaRegs.CH1.TRANSFER_SIZE = 0x03E7; // Bursts (N-1) per transfer
DmaRegs.CH1.SRC_TRANSFER_STEP = 1; // Not needed since TRANSFER_SIZE = 0
DmaRegs.CH1.DST_TRANSFER_STEP = 0; // Not needed since TRANSFER_SIZE = 0
// Set up WRAP registers:
DmaRegs.CH1.SRC_WRAP_SIZE = 0x03E7; // wrap after 1000 bursts (n-1)
DmaRegs.CH1.DST_WRAP_SIZE = 0; // No destination wrap-around
DmaRegs.CH1.SRC_WRAP_STEP = 1;
DmaRegs.CH1.DST_WRAP_STEP = 0;
// Set up SOURCE address:
DmaRegs.CH1.SRC_ADDR_SHADOW = (Uint32) &sin[0]; // Point to variable in RAM
DmaRegs.CH1.SRC_BEG_ADDR_SHADOW= (Uint32) &sin[0]; // Source Begin Address Shadow Register
// Set up DESTINATION address:
DmaRegs.CH1.DST_ADDR_SHADOW = (Uint32) &EPwm2Regs.CMPA.half.CMPA; // Point to ePWM2 CMPA register remapped for DMA
// Clear any spurious flags:
DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1; // Clear any spurious interrupt flags
DmaRegs.CH1.CONTROL.bit.SYNCCLR = 1; // Clear any spurious sync flags
DmaRegs.CH1.CONTROL.bit.ERRCLR = 1; // Clear any spurious sync error flags
EDIS;
}
Does this look right for what I'm expecting?
Thanks,
Aron