lpcware

PWM0 and PWM1 synchronization

Discussion created by lpcware Employee on Jun 15, 2016
Content originally posted in LPCWare by justinx90 on Sun Sep 27 20:31:51 MST 2015
I am currently writing some firmware for an LPC4078FBD208 using the LPC Peripheral Driver Library.

I need to ensure syncronization between PWM0 and PWM1.

I would like some clarity on the use of the Master Disable (MDIS) bit in the PWM Timer Control Register. I have read the user manual (UM10562), but I find it is lacking in detail in this area.

These are the bullet pointed steps I have taken to enable syncronization between PWM0 and PWM1.

[list]
  [*]Enable power to PWM0 and PWM1.
  [*]Set PWM0 and PWM1 prescaler.
  [*]Set Master Disable (MIDS) to 1.
  [*]Set GPIO direction for each pwm channel pin.
  [*]Set IOCON for each pwm channel pin.
  [*]Set PWM0 and PWM1 match register 0.
  [*]Set PWM0 and PWM1 interrupt settings.
  [*]Set PWM0 and PWM1 channel 1-6 settings.
  [*]Reset PWM0 and PWM1 counter.
  [*]Enable PWM mode for PWM0 and PWM1.
  [*]Set counter enable for PWM0 and PWM1.
  [*]Set Master Disable (MIDS) to 0 to ensure syncronised starting of the counters.
[/list]

Any feedback on whether this is the correct procedure and use of MDIS to ensure syncronization would be much appreaciated.

PWM initilisation code:


void Hal_PWMInitialise(void)
{
    PWM_TIMERCFG_Type PWMCfgDat;
    PWM_MATCHCFG_Type PWMMatchCfgDat;
    size_t i;

    // Initialize PWM peripheral(s).
    PWMCfgDat.PrescaleOption = PWM_TIMER_PRESCALE_USVAL;
    PWMCfgDat.PrescaleValue = 10U;
    PWM_Init(BRD_OUTPUT_CHANNEL_LC_FET_PWMA_PERPH_N, PWM_MODE_TIMER, &PWMCfgDat);
    PWM_Init(BRD_OUTPUT_CHANNEL_LC_FET_PWMB_PERPH_N, PWM_MODE_TIMER, &PWMCfgDat);


    // Master disable for PWM0 and PWM1 peripherals.
    LPC_PWM0_TCR |= (1 << LPC_PWM0_TCR_MDIS_BIT);


    // Initialize PWM pin connect.
    for (i = 0; i < N_ELEMENTS(m_OutputChannelLowCurrentLayout); i++)
    {
        GPIO_SetDir(m_OutputChannelLowCurrentLayout.port, (1U << m_OutputChannelLowCurrentLayout.pin), GPIO_DIRECTION_OUTPUT);
        PINSEL_ConfigPin(m_OutputChannelLowCurrentLayout.port, m_OutputChannelLowCurrentLayout.pin, BRD_OUTPUT_CHANNEL_LC_FET_PWM_FUNC_NO);
    }
                         
    // Set match value for PWM match channel 0 and update immediately.
    // PWM levels are set between 0 - 1000ppt (0 - 100%). A level of 100% = 1000ppt.
    /* 26.4.1 Rules for Single Edge Controlled PWM Outputs
       1. All single edge controlled PWM outputs go high at the beginning of a PWM cycle
          unless their match value is equal to 0.
       2. Each PWM output will go low when its match value is reached. If no match occurs (i.e.
          the match value is greater than the PWM rate), the PWM output remains continuously
          high. */
    PWM_MatchUpdate(BRD_OUTPUT_CHANNEL_LC_FET_PWMA_PERPH_N, 0, (BRD_OUTPUT_CHANNEL_LC_FET_PWM_PERIOD - 1U), PWM_MATCH_UPDATE_NOW);
    PWM_MatchUpdate(BRD_OUTPUT_CHANNEL_LC_FET_PWMB_PERPH_N, 0, (BRD_OUTPUT_CHANNEL_LC_FET_PWM_PERIOD - 1U), PWM_MATCH_UPDATE_NOW);
   

    // PWM Timer/Counter will be reset when channel 0 matching
    PWMMatchCfgDat.IntOnMatch = ENABLE;
    PWMMatchCfgDat.MatchChannel = 0;
    PWMMatchCfgDat.ResetOnMatch = ENABLE;
    PWMMatchCfgDat.StopOnMatch = DISABLE;
    PWM_ConfigMatch(BRD_OUTPUT_CHANNEL_LC_FET_PWMA_PERPH_N, &PWMMatchCfgDat);

    PWMMatchCfgDat.IntOnMatch = DISABLE;
    PWM_ConfigMatch(BRD_OUTPUT_CHANNEL_LC_FET_PWMB_PERPH_N, &PWMMatchCfgDat);


    // Configure each PWM channel.
    for (i = 0; i < N_ELEMENTS(m_OutputChannelLowCurrentLayout); i++)
    {
        PWM_ChannelConfig(m_OutputChannelLowCurrentLayout.pwm, m_OutputChannelLowCurrentLayout.channel, PWM_CHANNEL_SINGLE_EDGE);
        PWM_MatchUpdate(m_OutputChannelLowCurrentLayout.pwm, m_OutputChannelLowCurrentLayout.channel, 0, PWM_MATCH_UPDATE_NEXT_RST);
       
        PWMMatchCfgDat.IntOnMatch = DISABLE;
        PWMMatchCfgDat.MatchChannel = m_OutputChannelLowCurrentLayout.channel;
        PWMMatchCfgDat.ResetOnMatch = DISABLE;
        PWMMatchCfgDat.StopOnMatch = DISABLE;
        PWM_ConfigMatch(m_OutputChannelLowCurrentLayout.pwm, &PWMMatchCfgDat);

        PWM_ChannelCmd(m_OutputChannelLowCurrentLayout.pwm, m_OutputChannelLowCurrentLayout.channel, ENABLE);
    }


    // Reset counter.
    PWM_ResetCounter(BRD_OUTPUT_CHANNEL_LC_FET_PWMA_PERPH_N);
    PWM_ResetCounter(BRD_OUTPUT_CHANNEL_LC_FET_PWMB_PERPH_N);

    // PWM mode enable.  
    PWM_Cmd(BRD_OUTPUT_CHANNEL_LC_FET_PWMA_PERPH_N, ENABLE);
    PWM_Cmd(BRD_OUTPUT_CHANNEL_LC_FET_PWMB_PERPH_N, ENABLE);

    // Start counter.
    PWM_CounterCmd(BRD_OUTPUT_CHANNEL_LC_FET_PWMA_PERPH_N, ENABLE);
    PWM_CounterCmd(BRD_OUTPUT_CHANNEL_LC_FET_PWMB_PERPH_N, ENABLE);

    // Master enable for PWM0 and PWM1 peripherals.
    LPC_PWM0_TCR &= ~(1U << LPC_PWM0_TCR_MDIS_BIT);
}

Outcomes