This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28379D: Sinusoidal PWM in Delfino-TMS320F28379D

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

Greetings,

Facing almost similar issue. 

1. Isn't possible to generate sinusoidal pwm in f28379d using the same way as it was in f28335 (only asking about CMPA.bit.CMPA in f28379d)?

2. Although changed linker file containing IQmath but still sine_table value are zero and not changing?

Looking for solution.

Thanks

Singh 

  • Singh,

        Are you getting any warnings or errors when compiling?

    Are you using the suggested linker command file mentioned in the last post?

    You need to define a section of memory that indicates where the IQ math tables are in memory, the linker mentioned in the other post does this for you already.

    Regards,

    Cody

  • Yes, I am using the same linker file and there are no errors or warning being displayed. Code is running but PWM is fixed pulse width but not modulating. My code is as follows. Its only for  epwm1A right now. I have done similarly on f28335 earlier.

    #include "F28x_Project.h"


    #include "IQmathLib.h"
    #pragma DATA_SECTION(sine_table,"IQmathTables");

    _iq30 sine_table[512]; //Iqmath inbuilt sine table 512 look-values
    _iq30 one = _IQ30(0.9999);
    int index_a1=0;
    _iq30 ma = 0;


    #define EPWM1_TIMER_TBPRD 12500 // Period register


    // Function Prototypes
    void InitEPwm1(void);
    __interrupt void cpu_timer0_isr(void);
    __interrupt void epwm1_isr(void);


    ////////// Main code ///////////////
    void main(void)
    {

    InitSysCtrl(); // Initialize System Control,(PLL, WatchDog, enable Peripheral Clocks) (F2837xD_SysCtrl.c file)

    InitGpio(); // Initialize GPIO

    CpuSysRegs.PCLKCR2.bit.EPWM1=1; // enable PWM1

    InitEPwm1Gpio();

    DINT; //Clear all interrupts and Disable CPU interrupts
    InitPieCtrl(); // Initialize the PIE control registers

    IER = 0x0000; // Disable CPU interrupts
    IFR = 0x0000; // clear all CPU interrupt flags

    InitPieVectTable(); // Initialize the PIE vector table

    EALLOW; // Interrupts re-mapped to ISR functions
    PieVectTable.TIMER0_INT = &cpu_timer0_isr;
    PieVectTable.EPWM1_INT = &epwm1_isr;
    EDIS;


    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    EDIS;

    InitEPwm1();

    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;

    InitCpuTimers(); // Initialize the Device Peripheral

    ConfigCpuTimer(&CpuTimer0, 200, 32.5); // Configure CPU-Timer 0 to interrupt every second at 200MHz CPU Freq, 1 second Period (in uSeconds)

    CpuTimer0Regs.TCR.bit.TSS = 0; //Start Timer0


    PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // map TINT0 in the PIE: Group 1 interrupt 7
    PieCtrlRegs.PIEIER3.bit.INTx1 = 1; // map pwm1 interrupt entry in pie group3

    IER |= M_INT1; // Enable CPU int1 which is connected to CPU-Timer 0, C
    IER |= M_INT3; // Enable pwm1 interrupt

    EINT; // Enable Global interrupt INTM
    ERTM; // Enable Global realtime interrupt DBGM

    while(1) // IDLE loop.
    {
    EALLOW;
    WdRegs.WDKEY.all = 0x55; // service key #1
    WdRegs.WDKEY.all = 0xAA; // service key #2
    EDIS;
    }
    }

    void Gpio_setup1(void) // Enable PWM1-3 on GPIO0-GPIO5
    {
    EALLOW;
    GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0; // Enable pullup on GPIO0
    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0; // Enable pullup on GPIO1
    GpioCtrlRegs.GPAPUD.bit.GPIO2 = 0; // Enable pullup on GPIO2
    GpioCtrlRegs.GPAPUD.bit.GPIO3 = 0; // Enable pullup on GPIO3
    GpioCtrlRegs.GPAPUD.bit.GPIO4 = 0; // Enable pullup on GPIO4
    GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0; // Enable pullup on GPIO5

    GpioCtrlRegs.GPADIR.all = 0; // GPIO31-0 as input
    GpioCtrlRegs.GPBDIR.all = 0; // GPIO31-0 as input
    GpioCtrlRegs.GPCDIR.all = 0; // GPIO31-0 as input

    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // GPIO0 = PWM1A
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // GPIO1 = PWM1B
    GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; // GPIO2 = PWM2A
    GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1; // GPIO3 = PWM2B
    GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 1; // GPIO4 = PWM3A
    GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 1; // GPIO5 = PWM3B
    EDIS;
    }

    interrupt void cpu_timer0_isr(void) // cpu_timer0_isr - CPU Timer0 ISR with interrupt counter
    {
    EALLOW;
    WdRegs.WDKEY.all = 0x55; // service key #1
    WdRegs.WDKEY.all = 0xAA; // service key #2
    EDIS;

    CpuTimer0.InterruptCount++;

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge this interrupt to receive more interrupts from group 1
    }

    void InitEPwm1()
    {
    // Setup TBCLK
    EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD; // Set timer period 801 TBCLKs
    EPwm1Regs.TBPHS.bit.TBPHS =0x0000; // Phase is 0
    EPwm1Regs.TBCTR = 0x0000; // Clear counter

    // Set Compare values
    EPwm1Regs.CMPA.bit.CMPA = EPwm1Regs.TBPRD/2; // Set compare A value (initial)
    // EPwm1Regs.CMPB.bit.CMPB = EPWM1_MAX_CMPB; // Set Compare B value

    // Setup counter mode
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

    // Setup shadowing
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // no effect if SHDWAMODE =1
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // no effect if SHDWBMODE =1

    // Set actions
    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on event A, up count
    EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM1A on event A down count
    EPwm1Regs.AQCTLB.bit.CAU =AQ_CLEAR; // Set PWM1B on event A, down count
    EPwm1Regs.AQCTLB.bit.CAD = AQ_SET; // Clear PWM1B on event A, up count

    // Interrupt where we will change the Compare Values
    EPwm1Regs.ETSEL.bit.INTSEL = 4; // Select INT on Zero event or period
    EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
    EPwm1Regs.ETPS.bit.INTPRD = 1; // Generate INT on 1st event
    }

    __interrupt void epwm1_isr(void)
    {

    EALLOW;
    WdRegs.WDKEY.all = 0x55; // service key #1
    WdRegs.WDKEY.all = 0xAA; // service key #2
    EDIS;

    EPwm1Regs.CMPA.bit.CMPA = EPwm1Regs.TBPRD - _IQ30mpy((sine_table[index_a1]+ one)/2,EPwm1Regs.TBPRD);

    index_a1 +=1;
    if (index_a1 > 511)
    index_a1 = 0;

    EPwm1Regs.ETCLR.bit.INT = 1;


    // Acknowledge this interrupt to receive more interrupts from group 3

    PieCtrlRegs.PIEACK.all = 4;
    }

  • Singh,
    Nice code, have you done any debug yet? If so, let me know what the results were and we can go from there.


    Regards,
    Cody
  • yes, i did debug and got only fixed pulse output but not the sinusoidal. Also I checked that sine table value using index_a1 remains zero all the time. ( defined as sine_table[index_a1] in code). So, CMPA.bit.CMPA do not vary as sine table value remains zero. What could be the reason?

    Thanks and many regards,
    Sukhjit Singh
  • Singh,
    Ah, understood, that helps. Looking into why this would be blank it seems to be that this table was removed from ROM.

    What address were you reading from?! The documentation doesn't specify a location, were you just using the old address from the F28335?

    None the less, you should be able to use the FPU or the TMU to replace the sine table altogether or if you would like to use the same exact code then you can use the FPU or TMU functions to build a sine table in RAM and use that for you calculations.

    Regards,
    Cody
  • Yes, I am using the same old address from F28335 to read sine table from IQmath library. If there is any documentation or example available to use the FPU or the TMU to replace the sine table or to use the FPU or TMU functions to build a sine table in RAM?

    Regards,
    Sukhjit Singh
  • Take a look at the C2000Ware example found here : "C:\ti\c2000\C2000Ware_1_00_05_00\device_support\f2837xd\examples\cpu1\tmu_sinegen\cpu01"

    Regards,
    Cody
  • Thanks, already went through it, but I found that IQmath table can still be used in f28379d with some modifications in linker file as mentioned in the following thread link:
    e2e.ti.com/.../2565038

    I tried this but got an error:

    "../2837xD_RAM_IQMATH_lnk_cpu1.cmd", line 97: warning #10097: memory range not found: RAMGS2 on page 0
    "../2837xD_RAM_IQMATH_lnk_cpu1.cmd", line 97: error #10099-D: program will not fit into available memory. run placement with alignment/blocking fails for section "IQmathTables" size 0 page 0

    What could be the problem?

    Thanks and Regards,
    Sukhjit Singh
  • Singh,

           You have misunderstood Manish's post, he is simply stating that the sine and cos tables are no longer needed with the addition of the TMU. The tables were removed from the ROM memory on F28379D. IQ math is still usable, but only as a library.

    The errors you are getting are because:

    1. You don't have RAMGS2 defined, or it is defined in a memory section that doesn't exist.
      1. Define this and make sure its in valid memory
    2. Your linker command file memory specification for section "IQmathTables" isn't large enough to fit all of the contents you are trying to include.
      1. Place this in a different section or increase the size of this section.

    Regards,
    Cody