PWM phase shift - help

hi,

is it possible to create 2 PWM-signals with one of them have a 90 degrees phase shift?
i am looking for a solution that uses the teensy's internal hardware timers.
i use a teensy 3.6.

kind regards
manuel
 
Yes. Depending on the frequency and accuracy you need there would be different ways to do it.
The Library interval timer gives you pretty robust access to up to 4 hardware timers.
What frequency/PWM step size/accuracy were you looking for?
 
Try this:

Code:
void setup()
{
        FTM3_SC = 0;    // halt timer
        FTM3_COMBINE = FTM_COMBINE_COMBINE1; // ch 2+3 = adjustable high/low points
        FTM3_C0V = 59;  // high at 50% of period
        FTM3_C2V = 29;  // high at 25% of period
        FTM3_C3V = 89;  // low at 75% of period
        FTM3_CNT = 0;   // reset timer
        FTM3_MOD = 119; // timer period (MOD+1 clocks of F_BUS)
        FTM3_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); // start timer
        // configure the pins to be controlled by FTM3 channels
        CORE_PIN2_CONFIG =  PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; // ch0
        CORE_PIN7_CONFIG =  PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; // ch2+3
}


void loop()
{
}

The signals will be on pins 2 and 7.
 
yes thanks it works well!!!! i was just studying the manual, its really complicated.
my last newbie question, why do the timers work only with 60MHz?
 
thank you very much for your help.

is there an elegant way to trigger a "single shot"-signal as soon as the PWM-signal repeated x-times?

my first idea was to create an ISR that counts the modulo-compare matches (PWM-periods) and after a specific count of repetitions i would output a short pulse,
but maybe there are better ways? Can someone give me an advise where to look in the manual?
 
Last edited:
Well, have you tried the obvious way of just writing zeros after a fixed amount of time? Did that not work? If so, what happened that wasn't good?

Look, I wrote some code for you last night. But that's not the norm. I can't do every step for you, and I can't quick answer every question. You're going to have to try to take it from here and solve some of these things.
 
i understand you and thanks for your help... I want to emulate an shaft encoder, it should output a small pulse everytime when the encoder turns 360 degrees (equate to e.g. 1000 pulses). It should be possible to variate the angular-speed of the shaft-encoder during the simulation. But now i found out by myself how to count my PWM-cycles with an additional timer, without using interrupts. ... when i finish my little project i will post it in the forum :)

regards
manuel
 
Last edited:
Try this:

Code:
void setup()
{
        FTM3_SC = 0;    // halt timer
        FTM3_COMBINE = FTM_COMBINE_COMBINE1; // ch 2+3 = adjustable high/low points
        FTM3_C0V = 59;  // high at 50% of period
        FTM3_C2V = 29;  // high at 25% of period
        FTM3_C3V = 89;  // low at 75% of period
        FTM3_CNT = 0;   // reset timer
        FTM3_MOD = 119; // timer period (MOD+1 clocks of F_BUS)
        FTM3_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); // start timer
        // configure the pins to be controlled by FTM3 channels
        CORE_PIN2_CONFIG =  PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; // ch0
        CORE_PIN7_CONFIG =  PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; // ch2+3
}


void loop()
{
}

The signals will be on pins 2 and 7.


Hello,

Can this code be used for Teensy 3.2? Thank you.

Best Regards,
Sipidel.
 
Code:
#include "imxrt.h"
#include "core_pins.h"
#include "debug/printf.h"


struct pwm_pin_info_struct {
  uint8_t type;    // 0=no pwm, 1=flexpwm, 2=quad
  uint8_t module;  // 0-3, 0-3
  uint8_t channel; // 0=X, 1=A, 2=B
  uint8_t muxval;  //
};


#define M(a, b) ((((a) - 1) << 4) | (b))

#if defined(__IMXRT1062__)

const struct pwm_pin_info_struct pwm_pin_info[] = {
  {1, M(1, 1), 0, 4},  // FlexPWM1_1_X   0  // AD_B0_03
  {1, M(1, 0), 0, 4},  // FlexPWM1_0_X   1  // AD_B0_02
  {1, M(4, 2), 1, 1},  // FlexPWM4_2_A   2  // EMC_04
  {1, M(4, 2), 2, 1},  // FlexPWM4_2_B   3  // EMC_05
  {1, M(2, 0), 1, 1},  // FlexPWM2_0_A   4  // EMC_06
  {1, M(2, 1), 1, 1},  // FlexPWM2_1_A   5  // EMC_08
  {1, M(2, 2), 1, 2},  // FlexPWM2_2_A   6  // B0_10
  {1, M(1, 3), 2, 6},  // FlexPWM1_3_B   7  // B1_01
  {1, M(1, 3), 1, 6},  // FlexPWM1_3_A   8  // B1_00
  {1, M(2, 2), 2, 2},  // FlexPWM2_2_B   9  // B0_11
  {2, M(1, 0), 0, 1},  // QuadTimer1_0  10  // B0_00
  {2, M(1, 2), 0, 1},  // QuadTimer1_2  11  // B0_02
  {2, M(1, 1), 0, 1},  // QuadTimer1_1  12  // B0_01
  {2, M(2, 0), 0, 1},  // QuadTimer2_0  13  // B0_03
  {2, M(3, 2), 0, 1},  // QuadTimer3_2  14  // AD_B1_02
  {2, M(3, 3), 0, 1},  // QuadTimer3_3  15  // AD_B1_03
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {2, M(3, 1), 0, 1},  // QuadTimer3_1  18  // AD_B1_01
  {2, M(3, 0), 0, 1},  // QuadTimer3_0  19  // AD_B1_00
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {1, M(4, 0), 1, 1},  // FlexPWM4_0_A  22  // AD_B1_08
  {1, M(4, 1), 1, 1},  // FlexPWM4_1_A  23  // AD_B1_09
  {1, M(1, 2), 0, 4},  // FlexPWM1_2_X  24  // AD_B0_12
  {1, M(1, 3), 0, 4},  // FlexPWM1_3_X  25  // AD_B0_13
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {1, M(3, 1), 2, 1},  // FlexPWM3_1_B  28  // EMC_32
  {1, M(3, 1), 1, 1},  // FlexPWM3_1_A  29  // EMC_31
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {1, M(2, 0), 2, 1},  // FlexPWM2_0_B  33  // EMC_07
#ifdef ARDUINO_TEENSY41
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {1, M(2, 3), 1, 6},  // FlexPWM2_3_A  36  // B1_00
  {1, M(2, 3), 2, 6},  // FlexPWM2_3_B  37  // B1_01
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {1, M(1, 1), 2, 1},  // FlexPWM1_1_B  42  // SD_B0_03
  {1, M(1, 1), 1, 1},  // FlexPWM1_1_A  43  // SD_B0_02
  {1, M(1, 0), 2, 1},  // FlexPWM1_0_B  44  // SD_B0_01
  {1, M(1, 0), 1, 1},  // FlexPWM1_0_A  45  // SD_B0_00
  {1, M(1, 2), 2, 1},  // FlexPWM1_2_B  46  // SD_B0_05
  {1, M(1, 2), 1, 1},  // FlexPWM1_2_A  47  // SD_B0_04
  {0, M(1, 0), 0, 0},  // duplicate FlexPWM1_0_B
  {0, M(1, 0), 0, 0},  // duplicate FlexPWM1_2_A
  {0, M(1, 0), 0, 0},  // duplicate FlexPWM1_2_B
  {1, M(3, 3), 2, 1},  // FlexPWM3_3_B  51  // EMC_22
  {0, M(1, 0), 0, 0},  // duplicate FlexPWM1_1_B
  {0, M(1, 0), 0, 0},  // duplicate FlexPWM1_1_A
  {1, M(3, 0), 1, 1},  // FlexPWM3_0_A  54  // EMC_29
#endif
};

#endif // __IMXRT1062__

void setup()
{
  analogWriteResolution(9);
  analogWriteFrequency(6, 195312);
  analogWrite(6, 50);
  MyanalogWriteFrequencyPS(9, 195312,100);
  analogWrite(9, 50);
}

void MyanalogWriteFrequencyPS(uint8_t pin, float mfrequency, int phaseshift)
{
  const struct pwm_pin_info_struct *info;

  if (pin >= CORE_NUM_DIGITAL) return;
  //printf("analogWriteFrequency, pin %d, freq %d\n", pin, (int)frequency);
  info = pwm_pin_info + pin;
  if (info->type == 1) {
    // FlexPWM pin
    IMXRT_FLEXPWM_t *flexpwm;
    switch ((info->module >> 4) & 3) {
      case 0: flexpwm = &IMXRT_FLEXPWM1; break;
      case 1: flexpwm = &IMXRT_FLEXPWM2; break;
      case 2: flexpwm = &IMXRT_FLEXPWM3; break;
      default: flexpwm = &IMXRT_FLEXPWM4;
    }
    MyflexpwmFrequencyPS(flexpwm, info->module & 0x03, info->channel, mfrequency, phaseshift);
  } else if (info->type == 2) {
    // QuadTimer pin
    //ignore
  }
}

void MyflexpwmFrequencyPS(IMXRT_FLEXPWM_t *p, unsigned int submodule, uint8_t channel, float mfrequency, int phaseshift)
{
  uint16_t mask = 1 << submodule;
  uint32_t olddiv = p->SM[submodule].VAL1;
  uint32_t newdiv = (uint32_t)((float)F_BUS_ACTUAL / mfrequency + 0.5f);
  uint32_t prescale = 0;
  //printf(" div=%lu\n", newdiv);
  while (newdiv > 65535 && prescale < 7) {
    newdiv = newdiv >> 1;
    prescale = prescale + 1;
  }
  if (newdiv > 65535) {
    newdiv = 65535;
  } else if (newdiv < 2) {
    newdiv = 2;
  }
  //printf(" div=%lu, scale=%lu\n", newdiv, prescale);
  p->MCTRL |= FLEXPWM_MCTRL_CLDOK(mask);
  p->SM[submodule].CTRL = FLEXPWM_SMCTRL_FULL | FLEXPWM_SMCTRL_PRSC(prescale);
  p->SM[submodule].VAL1 = newdiv - 1;
  p->SM[submodule].VAL2 = ((p->SM[submodule].VAL2 + phaseshift) * newdiv) / olddiv;  //offset from start at 0
  p->SM[submodule].VAL0 = (p->SM[submodule].VAL0 * newdiv) / olddiv;
  p->SM[submodule].VAL3 = ((p->SM[submodule].VAL3 + phaseshift) * newdiv) / olddiv;
  p->SM[submodule].VAL5 = (p->SM[submodule].VAL5 * newdiv) / olddiv;
  p->MCTRL |= FLEXPWM_MCTRL_LDOK(mask);
}


void loop()
{
}
this works for any phaseshift. for Teensy 3.x the pins have to be coppied from the github. the phaseshift value has to be found out. Once I got time I will work on it again to make it more convenient.
 
Code:
#include "imxrt.h"
#include "core_pins.h"
#include "debug/printf.h"


struct pwm_pin_info_struct {
  uint8_t type;    // 0=no pwm, 1=flexpwm, 2=quad
  uint8_t module;  // 0-3, 0-3
  uint8_t channel; // 0=X, 1=A, 2=B
  uint8_t muxval;  //
};


#define M(a, b) ((((a) - 1) << 4) | (b))

#if defined(__IMXRT1062__)

const struct pwm_pin_info_struct pwm_pin_info[] = {
  {1, M(1, 1), 0, 4},  // FlexPWM1_1_X   0  // AD_B0_03
  {1, M(1, 0), 0, 4},  // FlexPWM1_0_X   1  // AD_B0_02
  {1, M(4, 2), 1, 1},  // FlexPWM4_2_A   2  // EMC_04
  {1, M(4, 2), 2, 1},  // FlexPWM4_2_B   3  // EMC_05
  {1, M(2, 0), 1, 1},  // FlexPWM2_0_A   4  // EMC_06
  {1, M(2, 1), 1, 1},  // FlexPWM2_1_A   5  // EMC_08
  {1, M(2, 2), 1, 2},  // FlexPWM2_2_A   6  // B0_10
  {1, M(1, 3), 2, 6},  // FlexPWM1_3_B   7  // B1_01
  {1, M(1, 3), 1, 6},  // FlexPWM1_3_A   8  // B1_00
  {1, M(2, 2), 2, 2},  // FlexPWM2_2_B   9  // B0_11
  {2, M(1, 0), 0, 1},  // QuadTimer1_0  10  // B0_00
  {2, M(1, 2), 0, 1},  // QuadTimer1_2  11  // B0_02
  {2, M(1, 1), 0, 1},  // QuadTimer1_1  12  // B0_01
  {2, M(2, 0), 0, 1},  // QuadTimer2_0  13  // B0_03
  {2, M(3, 2), 0, 1},  // QuadTimer3_2  14  // AD_B1_02
  {2, M(3, 3), 0, 1},  // QuadTimer3_3  15  // AD_B1_03
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {2, M(3, 1), 0, 1},  // QuadTimer3_1  18  // AD_B1_01
  {2, M(3, 0), 0, 1},  // QuadTimer3_0  19  // AD_B1_00
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {1, M(4, 0), 1, 1},  // FlexPWM4_0_A  22  // AD_B1_08
  {1, M(4, 1), 1, 1},  // FlexPWM4_1_A  23  // AD_B1_09
  {1, M(1, 2), 0, 4},  // FlexPWM1_2_X  24  // AD_B0_12
  {1, M(1, 3), 0, 4},  // FlexPWM1_3_X  25  // AD_B0_13
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {1, M(3, 1), 2, 1},  // FlexPWM3_1_B  28  // EMC_32
  {1, M(3, 1), 1, 1},  // FlexPWM3_1_A  29  // EMC_31
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {1, M(2, 0), 2, 1},  // FlexPWM2_0_B  33  // EMC_07
#ifdef ARDUINO_TEENSY41
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {1, M(2, 3), 1, 6},  // FlexPWM2_3_A  36  // B1_00
  {1, M(2, 3), 2, 6},  // FlexPWM2_3_B  37  // B1_01
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {0, M(1, 0), 0, 0},
  {1, M(1, 1), 2, 1},  // FlexPWM1_1_B  42  // SD_B0_03
  {1, M(1, 1), 1, 1},  // FlexPWM1_1_A  43  // SD_B0_02
  {1, M(1, 0), 2, 1},  // FlexPWM1_0_B  44  // SD_B0_01
  {1, M(1, 0), 1, 1},  // FlexPWM1_0_A  45  // SD_B0_00
  {1, M(1, 2), 2, 1},  // FlexPWM1_2_B  46  // SD_B0_05
  {1, M(1, 2), 1, 1},  // FlexPWM1_2_A  47  // SD_B0_04
  {0, M(1, 0), 0, 0},  // duplicate FlexPWM1_0_B
  {0, M(1, 0), 0, 0},  // duplicate FlexPWM1_2_A
  {0, M(1, 0), 0, 0},  // duplicate FlexPWM1_2_B
  {1, M(3, 3), 2, 1},  // FlexPWM3_3_B  51  // EMC_22
  {0, M(1, 0), 0, 0},  // duplicate FlexPWM1_1_B
  {0, M(1, 0), 0, 0},  // duplicate FlexPWM1_1_A
  {1, M(3, 0), 1, 1},  // FlexPWM3_0_A  54  // EMC_29
#endif
};

#endif // __IMXRT1062__

void setup()
{
  analogWriteResolution(9);
  analogWriteFrequency(6, 195312);
  analogWrite(6, 50);
  MyanalogWriteFrequencyPS(9, 195312,100);
  analogWrite(9, 50);
}

void MyanalogWriteFrequencyPS(uint8_t pin, float mfrequency, int phaseshift)
{
  const struct pwm_pin_info_struct *info;

  if (pin >= CORE_NUM_DIGITAL) return;
  //printf("analogWriteFrequency, pin %d, freq %d\n", pin, (int)frequency);
  info = pwm_pin_info + pin;
  if (info->type == 1) {
    // FlexPWM pin
    IMXRT_FLEXPWM_t *flexpwm;
    switch ((info->module >> 4) & 3) {
      case 0: flexpwm = &IMXRT_FLEXPWM1; break;
      case 1: flexpwm = &IMXRT_FLEXPWM2; break;
      case 2: flexpwm = &IMXRT_FLEXPWM3; break;
      default: flexpwm = &IMXRT_FLEXPWM4;
    }
    MyflexpwmFrequencyPS(flexpwm, info->module & 0x03, info->channel, mfrequency, phaseshift);
  } else if (info->type == 2) {
    // QuadTimer pin
    //ignore
  }
}

void MyflexpwmFrequencyPS(IMXRT_FLEXPWM_t *p, unsigned int submodule, uint8_t channel, float mfrequency, int phaseshift)
{
  uint16_t mask = 1 << submodule;
  uint32_t olddiv = p->SM[submodule].VAL1;
  uint32_t newdiv = (uint32_t)((float)F_BUS_ACTUAL / mfrequency + 0.5f);
  uint32_t prescale = 0;
  //printf(" div=%lu\n", newdiv);
  while (newdiv > 65535 && prescale < 7) {
    newdiv = newdiv >> 1;
    prescale = prescale + 1;
  }
  if (newdiv > 65535) {
    newdiv = 65535;
  } else if (newdiv < 2) {
    newdiv = 2;
  }
  //printf(" div=%lu, scale=%lu\n", newdiv, prescale);
  p->MCTRL |= FLEXPWM_MCTRL_CLDOK(mask);
  p->SM[submodule].CTRL = FLEXPWM_SMCTRL_FULL | FLEXPWM_SMCTRL_PRSC(prescale);
  p->SM[submodule].VAL1 = newdiv - 1;
  p->SM[submodule].VAL2 = ((p->SM[submodule].VAL2 + phaseshift) * newdiv) / olddiv;  //offset from start at 0
  p->SM[submodule].VAL0 = (p->SM[submodule].VAL0 * newdiv) / olddiv;
  p->SM[submodule].VAL3 = ((p->SM[submodule].VAL3 + phaseshift) * newdiv) / olddiv;
  p->SM[submodule].VAL5 = (p->SM[submodule].VAL5 * newdiv) / olddiv;
  p->MCTRL |= FLEXPWM_MCTRL_LDOK(mask);
}


void loop()
{
}
this works for any phaseshift. for Teensy 3.x the pins have to be coppied from the github. the phaseshift value has to be found out. Once I got time I will work on it again to make it more convenient.


What do you mean by "for Teensy 3.x the pins have to be coppied from the github. the phaseshift value has to be found out"? Thank you.
 
https://github.com/PaulStoffregen/cores/blob/master/teensy4/pwm.c
on the github I haven't seen anything specific for the 3.x but just in case the two blocks I deleted to have a smaller code for testing:
Code:
#ifdef ARDUINO_TEENSY40
	{1, M(1, 1), 2, 1},  // FlexPWM1_1_B  34  // SD_B0_03
	{1, M(1, 1), 1, 1},  // FlexPWM1_1_A  35  // SD_B0_02
	{1, M(1, 0), 2, 1},  // FlexPWM1_0_B  36  // SD_B0_01
	{1, M(1, 0), 1, 1},  // FlexPWM1_0_A  37  // SD_B0_00
	{1, M(1, 2), 2, 1},  // FlexPWM1_2_B  38  // SD_B0_05
	{1, M(1, 2), 1, 1},  // FlexPWM1_2_A  39  // SD_B0_04
#endif
#ifdef ARDUINO_TEENSY_MICROMOD
	{1, M(1, 1), 2, 1},  // FlexPWM1_1_B  34  // SD_B0_03
	{1, M(1, 1), 1, 1},  // FlexPWM1_1_A  35  // SD_B0_02
	{1, M(1, 0), 2, 1},  // FlexPWM1_0_B  36  // SD_B0_01
	{1, M(1, 0), 1, 1},  // FlexPWM1_0_A  37  // SD_B0_00
	{1, M(1, 2), 2, 1},  // FlexPWM1_2_B  38  // SD_B0_05
	{1, M(1, 2), 1, 1},  // FlexPWM1_2_A  39  // SD_B0_04
	{2, M(2, 1), 0, 1},  // QuadTimer2_1  40  // B0_04
	{2, M(2, 2), 0, 1},  // QuadTimer2_2  41  // B0_05
	{0, M(1, 0), 0, 0},  // duplicate QuadTimer3_0
	{0, M(1, 0), 0, 0},  // duplicate QuadTimer3_1
	{0, M(1, 0), 0, 0},  // duplicate QuadTimer3_2
	{2, M(4, 0), 0, 1},  // QuadTimer4_0  45  // B0_09
#endif
right now the phaseshift value is not related to the frequency or So you have to try around with the last value in this command: MyanalogWriteFrequencyPS(9, 195312,100); /*PWM on pin 9 with a frequency of 195312Hz and a phaseshift value of 100*!
 
https://github.com/PaulStoffregen/cores/blob/master/teensy4/pwm.c
on the github I haven't seen anything specific for the 3.x but just in case the two blocks I deleted to have a smaller code for testing:
Code:
#ifdef ARDUINO_TEENSY40
	{1, M(1, 1), 2, 1},  // FlexPWM1_1_B  34  // SD_B0_03
	{1, M(1, 1), 1, 1},  // FlexPWM1_1_A  35  // SD_B0_02
	{1, M(1, 0), 2, 1},  // FlexPWM1_0_B  36  // SD_B0_01
	{1, M(1, 0), 1, 1},  // FlexPWM1_0_A  37  // SD_B0_00
	{1, M(1, 2), 2, 1},  // FlexPWM1_2_B  38  // SD_B0_05
	{1, M(1, 2), 1, 1},  // FlexPWM1_2_A  39  // SD_B0_04
#endif
#ifdef ARDUINO_TEENSY_MICROMOD
	{1, M(1, 1), 2, 1},  // FlexPWM1_1_B  34  // SD_B0_03
	{1, M(1, 1), 1, 1},  // FlexPWM1_1_A  35  // SD_B0_02
	{1, M(1, 0), 2, 1},  // FlexPWM1_0_B  36  // SD_B0_01
	{1, M(1, 0), 1, 1},  // FlexPWM1_0_A  37  // SD_B0_00
	{1, M(1, 2), 2, 1},  // FlexPWM1_2_B  38  // SD_B0_05
	{1, M(1, 2), 1, 1},  // FlexPWM1_2_A  39  // SD_B0_04
	{2, M(2, 1), 0, 1},  // QuadTimer2_1  40  // B0_04
	{2, M(2, 2), 0, 1},  // QuadTimer2_2  41  // B0_05
	{0, M(1, 0), 0, 0},  // duplicate QuadTimer3_0
	{0, M(1, 0), 0, 0},  // duplicate QuadTimer3_1
	{0, M(1, 0), 0, 0},  // duplicate QuadTimer3_2
	{2, M(4, 0), 0, 1},  // QuadTimer4_0  45  // B0_09
#endif
right now the phaseshift value is not related to the frequency or So you have to try around with the last value in this command: MyanalogWriteFrequencyPS(9, 195312,100); /*PWM on pin 9 with a frequency of 195312Hz and a phaseshift value of 100*!


Have you updated you code? It is not clear to me what is the unit of phaseshift. It is between 0 an 180? Does it work the same for all frequencies?
 
Back
Top