MCF5211 problem with PWM on pin 43 (PWM7)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MCF5211 problem with PWM on pin 43 (PWM7)

1,581 Views
ITABE
Contributor I

Dear all,

 

 In the company where I work we use the we use that microcontroller for more than one circuit. Now we need to generate a pulse and we decided to work with PWM.

I looked to the AN3511 doc and I seen the source related.

I changed many times the sources, I can see the modulation in the pins 40, 41  (PWM1, PWM3) but nothing in the pin 43 (PWM7). Really I'm worried that I'll never see the pulse out of that pin...

 

Follow the source:

 

in mainfunction:

..

    /* configure PWM */
    PWMInit(SCALEDCLOCK,208);
    /* show the output for selected channel */

    /* all PWM channels are @ 30 Hz */
    /* even channels through LEDs in EVB */            /* duty cycle */

    PWMStart(3,200,100,LOWPOL,LEFTALIGNED);        /* 50 %   */           
    PWMStart(7,200,100,LOWPOL,LEFTALIGNED);        /* 50 %   */           

..

   
/**********************************FUNCTIONS**********************************/

/*****************************************************************************
 * PWMInit: Set channels ready to show a PWM output in pins                     *
 *                                                                           *
 * Parameters: u8Clock:       clock or sclaled clock source                     *
 *               u8ScaledValue: scaled value to use                             *
 *                                                                           *
 * Return : none.                                                            *
 *****************************************************************************/
void PWMInit(uint8 u8Clock, uint8 u8ScaledValue)
{
#ifdef MAI

// comment parts

    /* associate odd PWM channels to a pin */
    MCF_GPIO_PTDPAR = 0
                    | MCF_GPIO_PTDPAR_PTDPAR0    /* PWM channel 1 */
                    | MCF_GPIO_PTDPAR_PTDPAR1    /* PWM channel 3 */
                    | MCF_GPIO_PTDPAR_PTDPAR2    /* PWM channel 5 */
                    | MCF_GPIO_PTDPAR_PTDPAR3;    /* PWM channel 7 */
   
    /* associate even PWM channels to a pin */
    MCF_GPIO_PTCPAR = 0
                    | MCF_GPIO_PTCPAR_TIN0_PWM0    /* PWM channel 0 */
                    | MCF_GPIO_PTCPAR_TIN1_PWM2 /* PWM channel 2 */
                    | MCF_GPIO_PTCPAR_TIN2_PWM4 /* PWM channel 4 */
                    | MCF_GPIO_PTCPAR_TIN3_PWM6;/* PWM channel 6 */
   
#endif

    /* associate even PWM channels to a pin */
    // Configure pins for PWM use
    MCF_GPIO_PTAPAR = 0
        | MCF_GPIO_PTAPAR_PTAPAR0(3) // PWM1 this work fine
        | MCF_GPIO_PTAPAR_PTAPAR1(3)
        | MCF_GPIO_PTAPAR_PTAPAR2(0)
        | MCF_GPIO_PTAPAR_PTAPAR3(3);   // PWM7 this is my pin


    /* associate every channel with a source clock */
    /* A, or B, SA or SB depending the channel */
    MCF_PWM_PWMCLK  = u8Clock;   
    /* change the prescaler of the clock source for every channel */   
    MCF_PWM_PWMPRCLK = 0
                     | MCF_PWM_PWMPRCLK_PCKA(BUSCLK_16)
                     | MCF_PWM_PWMPRCLK_PCKB(BUSCLK_16);
    /* set scaled value for scaled clock, if are activated */
    MCF_PWM_PWMSCLA = u8ScaledValue;
    MCF_PWM_PWMSCLB = u8ScaledValue;
   

    MCF_PWM_PWMCTL = 0;

    return;   
}

/*****************************************************************************
 * PWMStart: Start selected PWM channel pin with selected duty and polarity  *
 *                                                                           *
 * Parameters: u8Channel:  PWM channel to start                                 *
 *               u8Period:   PWM channel period                                 *
 *             u8Duty:        PWM channel duty cycle                             *
 *             u8Polarity: PWM channel polarity                                 *
 *               u8Alignment:smileytongue:WM channel alignment                             *
 *                                                                           *
 * Return : none.                                                            *
 *****************************************************************************/
void PWMStart(uint8 u8Channel, uint8 u8Period, uint8 u8Duty,
              uint8 u8Polarity, uint8 u8Alignment)
{   
    // MCF_PWM_PWME &= ~(1<<u8Channel);    really is need ?


    MCF_PWM_PWMPER(u8Channel) = u8Period;            /* set PWM period */
    MCF_PWM_PWMDTY(u8Channel) = u8Duty;                /* set PWM duty cycle */
    MCF_PWM_PWMPOL |= (u8Polarity<<u8Channel);         /* set PWM polarity */
    MCF_PWM_PWMCAE |= (u8Alignment<<u8Channel);     /* set PWM alignment */
    /* show the PWM channel in its respective pin*/
    MCF_PWM_PWME |= (1<<u8Channel);
   
    return;
}


thank you in advance.


// Andrea.

Labels (1)
0 Kudos
Reply
9 Replies

1,262 Views
mjbcswitzerland
Specialist V

Andrea

 

What is the define for SCALEDCLOCK?

 

The pin configuration is standard for each pin so there doesn't seem to be any problem in that area, but the PWM clocking may not be correct.

 

PWMCLK needs to be set for each PWM channel (0..7) to configure where each takes its clock from (A or SA for channels 0, 1, 4 and 5 - B or SB clock for channels 2, 3, 6 and 7).

As is seen, the clock source control for PWM 3 is different to PWM 0 and 1; since you have no problems with 0 and 1 but do with 3 this may be an indication.

 

Regards

 

Mark

 

www.uTasker.com

 

 

0 Kudos
Reply

1,262 Views
ITABE
Contributor I

Dear Mark,

 

  thank you for your answer,


/* PWM Scaled */
#define SCALEDCLOCK            0xFF
#define CLOCK                0x00

this is the define for scaled clock, did you suggest to use CLOCK instead ?

 

Best regards,

// Andrea.

0 Kudos
Reply

1,262 Views
mjbcswitzerland
Specialist V

Andrea

 

It looks as though all channels are using the divided clock source. I don't see any obvious problems.

 

What I have done is attach an SREC (project) for the M5213 which uses PWM1, 3 and 7 on the TA port - they are all set to about 1k and 50%. I set the RAM size to 16k and it doesn't use any Flash about 128k so it should run on your board with the M5211 too. Since I don't know what speed your device has, I set it up for 32MHz PLL from 8MHz clock so it should be able to run on any type too - so you can halt the operation with debugger and check all register setups, I also disabled the watchdog operation.

 

On my M5213EVB all outputs work nornally. If it works on your board (all 3 PWM outputs generate the signal) you can be sure that it i not a HW problem. You should be able to check the content of the pin set up (PTAPAR = 0xcf as reference) and the setup of the PWM registers to see what the SW problem could be. Note that this configuration uses a prescaler of 128 but then a scaler of only 1 (therefore the higher frequency).

 

I set it up using the PWM setup interface in the uTasker project which looks like this (this won't help a great deal since it is a higher level of abstraction) but the code is otherwise available in that project:

 

PWM_INTERRUPT_SETUP timer_setup;timer_setup.int_type = PWM_INTERRUPT;  // PWM setup typetimer_setup.pwm_reference = 1;         // PWM1timer_setup.pwm_mode  = (PWM_PRESCALER_128 | PWM_SCALED_CLOCK_INPUT | PWM_POLARITY); // modetimer_setup.pwm_frequency = (unsigned char)(PWM_US_DELAY(PWM_FREQUENCY_VALUE(960 * 128))); // frequency 960Hztimer_setup.pwm_value  = (unsigned char)_PWM_PERCENT(50, timer_setup.pwm_frequency); // 50%fnConfigureInterrupt((void *)&timer_setup); // configure and start PWM1timer_setup.pwm_reference = 3;          // same setup for PWM3fnConfigureInterrupt((void *)&timer_setup); // configure and start PWM3timer_setup.pwm_reference = 7;          // same setup for PWM7fnConfigureInterrupt((void *)&timer_setup); // configure and start PWM7

 

Regards

 

Mark

 

0 Kudos
Reply

1,262 Views
ITABE
Contributor I

Dear Mark,

  now I play with PWMCLK and Prescaled clock to understand why 2 channel's work and one no.

I see your code and I see something about interrupt but I don't use is now, just for a timer in temporise function.

I need to use interrupt for PWM too ?.

I can't load SREC in my project now, I use m68k under linux and load the binary output from objcopy through bdm device.

// Andrea.

0 Kudos
Reply

1,262 Views
mjbcswitzerland
Specialist V

Andrea

 

fnConfigureInterrupt() is used for setting up various peripherals (like timers, ADC, QSPI, edge ports etc.) which usually/often use interrupts - this is also used for PWM configuration without interrupt (some devices may be able to generate optional interrupts), so interrupts do not need to be used and are not used in this case.

 

If you can load binary files you can also use objcopy to convert the SREC to binary and then load it to your board. If you can debug, you can then check the content of PTA and PWM registers to see whether you can see a difference which explains why your code is not generating output on all channels.

 

In case you don't manage this, the following are the most register settings for the tested case:

PTAPAR = 0xcf (configures the 3 PWM pins to PWM mode)

 

PWME = 0x8a

PWMPOL = 0x8a

PWMCLK = 0x8a

PWMPRCLK = 0x77

PWMSCLA = 0x01

PWMSCLB = 0x01

PWMPER1 = 0x40

PWMPER3= 0x40

PWMPER7 = 0x40

PWMDTY1 = 0x20

PWMDTY3= 0x20

PWMDTY7= 0x20

 

When these are manually set and the PWME as last (to enable) you should also see the corresponding outputs.

 

Regards

 

Mark

 

 

0 Kudos
Reply

1,262 Views
ITABE
Contributor I

Dear Mark,

 after have very long played now the code seems to work, thank you for your time, but I need

another tips, how to synchronize PWM7 with PWM1, in other words I need the pulse from PWM1 then 30us start a
pulse from PWM7.
After some test I can't have the channels PWM1 and PWM7 synchronize beacuse they have different source
of clock this is true ?.

Best regards,

// Andrea.

0 Kudos
Reply

1,262 Views
mjbcswitzerland
Specialist V

Andrea

 

All PWM channels are driven from the internal clock and - when both clock dividers are equal - all clocks are in fact the same.

If all channels are activated at the same time [PWME = 0x8a in your case, written when the original value was 0x00] all outputs are synchronous.

 

If you want to have a specified delay from channel 1 to channel 7 this is possible by writing:

PWME = 0x8a;

PWMCNT7 = 0x05; // exampleof priming a count value in one channel

 

It is not possible to prime the count values before enabling the PWM output since the conter is held at 0x00 when the channel is not enabled but it is possible to change the value immediately after the PWM counters are activated (to avoid the possibility of the being unexpected counts taking place between the two instructions this can be performed with interrupts disabled).

 

The actual value to be written to the count value depends on the delay required and its resolution will depend on the value of PWMPER7 - when PWMPER7 is 0xff (it will usually be smaller) it would allow 1/256 resolution of the clock period. Thsi may or may not allow you to achieve the delay that you want with the required accuracy.

 

Regards

 

Mark

 

0 Kudos
Reply

1,262 Views
ITABE
Contributor I

Dear Mark,

 

  did you suggest to use output compare for this purpose ?

 

// Andrea.

0 Kudos
Reply

1,262 Views
mjbcswitzerland
Specialist V

Andrea

 

The PWM module has no output compare function (just period and duty compare).

 

I suggested modifying the counter value to introduce a controller offset between the PWM channels.

 

To generate single shot pulses other timer modules may be more suitable.

 

regards

 

Mark

 

0 Kudos
Reply