Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 2 of 2

Thread: Using FlexPWM on Teensy 4.0 for Interleaved PWM Signals with deadtime in between...

  1. #1
    Junior Member
    Join Date
    Jan 2020
    Posts
    15

    Using FlexPWM on Teensy 4.0 for Interleaved PWM Signals with deadtime in between...

    Hello

    for a project I need to generate two interleaved pwm signals with a deadtime of 2uS in between.
    The frequency and duty cycle have to be adjustable at any moment.
    the frequency's max value is about 100kHz

    My Problem is, that i don't know how to initialize the timers and set the corresponding registers.

    Perhaps anyone of you is a expert on this field and can help me out here

    All my notes until now are these:
    (I probably have to use FlexPWM2)


    IO Muxing:
    IOMUXC_FLEXPWM2_PWMA0_SELECT_INPUT = 0 => GPIO_EMC_06_ALT1 (Pin 4) => available pin on Teensy 4
    IOMUXC_FLEXPWM2_PWMB0_SELECT_INPUT = 0 => GPIO_EMC_07_ALT1 (Pin 33) = available pin on Teensy 4

    Clocking:
    CCM_CCGR4_PWM2 (clock enable) ??? set to 1 ???

    Clocksource:
    FLEXPWM_SMCTRL2_CLK_SEL = 0; // 0=UPbus, extclock=1, aux_clk =2
    Prescaler:
    FLEXPWM_SMCTRL_PRSC(n);

    FLEXPWM2_MCTRL2 => 0 = complementary Channels


    Register Reloading:
    CTRL[FULL] = every Cycle reload => used to get the ability to load new frequency and duty cycle values?

    Definitions from the imxrt.h file:
    (I don't know which register is for what... don't find clear information either in the reference manual)

    #define FLEXPWM2_SM0CNT (IMXRT_FLEXPWM2.SM[0].CNT)
    #define FLEXPWM2_SM0INIT (IMXRT_FLEXPWM2.SM[0].INIT)
    #define FLEXPWM2_SM0CTRL2 (IMXRT_FLEXPWM2.SM[0].CTRL2)
    #define FLEXPWM2_SM0CTRL (IMXRT_FLEXPWM2.SM[0].CTRL)
    #define FLEXPWM2_SM0VAL0 (IMXRT_FLEXPWM2.SM[0].VAL0)
    ... and many more definitions of course ...

  2. #2
    Junior Member
    Join Date
    Jan 2020
    Posts
    15
    I got It working thanks to the PWM.c file in the teensy 4 core. Two interleaved PWM signals are now beeing generated with flexible duty cycle and frequency and both signals obviously centered.

    Click image for larger version. 

Name:	flexPWMPic.jpg 
Views:	20 
Size:	38.6 KB 
ID:	18801

    Here is my code, if anyone is interested:

    #include "imxrt.h"
    #include "core_pins.h"
    #include "debug/printf.h"
    #define ChannelA 4
    #define ChannelB 33
    #define Maske 1
    #define ResolutionPWM 12 //12-Bit für PWM

    void setOutputPWM(uint16_t val) {
    uint32_t PeriodendauerCycles = FLEXPWM2_SM0VAL1; //Periodendauer
    uint32_t Cycles = ((uint32_t)val * (PeriodendauerCycles + 1)) >> ResolutionPWM;
    if (Cycles > PeriodendauerCycles) Cycles = PeriodendauerCycles;
    FLEXPWM2_MCTRL |= FLEXPWM_MCTRL_CLDOK(Maske);
    FLEXPWM2_SM0VAL3 = Cycles;
    FLEXPWM2_SM0VAL4 = FLEXPWM2_SM0VAL3 + (((FLEXPWM2_SM0VAL1 - 2 * Cycles) / 2)); //PauseOffset anpassen!
    FLEXPWM2_SM0VAL5 = FLEXPWM2_SM0VAL4 + (Cycles); //tOn für Channel B anpassen
    FLEXPWM2_OUTEN |= FLEXPWM_OUTEN_PWMA_EN(Maske); //ChannelA aktivieren
    FLEXPWM2_OUTEN |= FLEXPWM_OUTEN_PWMB_EN(Maske); //ChannelB aktivieren
    FLEXPWM2_MCTRL |= FLEXPWM_MCTRL_LDOK(Maske);
    *(portConfigRegister(ChannelA)) = Maske;
    *(portConfigRegister(ChannelB)) = Maske;
    }

    void setOutputFrequency(float frequency)
    {
    uint32_t CurrentCycles = (uint32_t)((float)F_BUS_ACTUAL / frequency + 0.5);
    uint32_t Prescaler = 0;

    //Falls Frequenz zu gering Prescaler switchen!
    while (CurrentCycles > 65535 && Prescaler < 7) {
    CurrentCycles = CurrentCycles >> 1;
    Prescaler = Prescaler + 1;
    }
    if (CurrentCycles > 65535) {
    CurrentCycles = 65535;
    } else if (CurrentCycles < 2) {
    CurrentCycles = 2; //minimale Cycles --> 10nS oder so
    }

    FLEXPWM2_MCTRL |= FLEXPWM_MCTRL_CLDOK(Maske);
    FLEXPWM2_SM0CTRL = FLEXPWM_SMCTRL_FULL | FLEXPWM_SMCTRL_PRSC(Prescaler); //Erst nach vollem Cycle updaten und Prescaler setzen!
    FLEXPWM2_SM0VAL1 = CurrentCycles - 1; //Cycles für Periodendauer setzen!
    FLEXPWM2_MCTRL |= FLEXPWM_MCTRL_LDOK(Maske);
    }

    void setup() {
    setOutputFrequency(100000); //100kHz
    setOutputPWM(410); //10% PWM
    }

    void loop() {
    }

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •