MCF5329 PWM 16bits change duty cycle

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

MCF5329 PWM 16bits change duty cycle

832 Views
marcioaureliofu
Contributor I

Hi
I adapted the PWM program from M52233DEMO_PWM to M5329EVB.
Now I want to know how to update 16 bits duty cycle (PWMDTY0 and PWMDTY1 ) in one operation.

To avoid change duty cycle in wrong way.
Below is the adapted code. The code is working fine. I verified the period and duty cycle using an oscilloscope.

 

/*
* main implementation: use this sample to create your own application
*
*/
#include "support_common.h" /* include peripheral declarations and more */
#if (CONSOLE_IO_SUPPORT || ENABLE_UART_SUPPORT)
/* Standard IO is only possible if Console or UART support is enabled. */
#include <stdio.h>
#endif

/**
* \brief init_pin_assignments - Function for Pin Assignment and General Purpose I/O
* \author TIC Guadalajara adapted by Marcio A. F. Montezuma for M5329EVB
* \param void
* \return void
* \todo
* \warning
*/
static void init_pin_assignments (void)
{

/* Pin assignments for port PWM
Pin PWM1 : PWM output channel PWM1
*/
MCF_GPIO_PDDR_PWM = MCF_GPIO_PCLRR_PWM_PCLRR_PWM2;

/* 0xFC0A_401A (PDDR_PWM) - Bit 2 - PWM1
Bit 3 - PWM3
Bit 4 - PWM5
Bit 5 - PWM7
MCF5329 Ref. Manual pag. 13-17 and MCF5329_GPIO.h */

MCF_PAD_PAR_PWM = MCF_PAD_PAR_PWM_PAR_PWM1(3);

/* Define Pin PWM1 as PWM1 MBGA256 H16
0xFC0A_4051 (PAR_PWM) - Bits 0 e 1 - Value 0b11 - PWM1
MCF5329 Ref. Manual pag. 13-31 and MCF5329_PAD.h */

}

/**
* \brief init_pwm - Setup Pulse Width Modulation (PWM) Module
* \author TIC Guadalajara adapted by Marcio A. F. Montezuma for M5329EVB
* \param void
* \return void
* \todo
* \warning
*/
/*********************************************************************
* init_pwm - Pulse Width Modulation (PWM) Module *
**********************************************************************/
static void init_pwm (void)
{
/* Clock A frequency = 60.00 MHz, fsys = 180.00 MHz, bus clock = fsys/3
Clock B frequency = 60.00 MHz, fsys = 180.00 MHz, bus clock = fsys/3
PWM continues to run in freeze mode
PWM continues to run in wait mode

Settings for PWM Channel 1:
Clock source is Clock A
Left-Aligned output mode
Period = 60,000 clocks (0xEA60) (1 milisecond)
High for 6000 clocks (0x1770) per period (10.000% duty cycle)
*/
MCF_PWM_PWMPER0 = MCF_PWM_PWMPER_PERIOD(0xEA);
MCF_PWM_PWMPER1 = MCF_PWM_PWMPER_PERIOD(0x60);
MCF_PWM_PWMDTY0 = MCF_PWM_PWMDTY_DUTY(0x17);
MCF_PWM_PWMDTY1 = MCF_PWM_PWMDTY_DUTY(0x70);

 

MCF_PWM_PWMPOL = MCF_PWM_PWMPOL_PPOL1;

/*channel n output is high at the
beginning of the period, then goes
low when the duty count is reached*/

MCF_PWM_PWMCLK &= 0b11111101; // Define PWM1 Clock Source as Clock A.
MCF_PWM_PWMPRCLK = MCF_PWM_PWMPRCLK_PCKA(0); // Define Prescaler of Clock A as 1 - 0b000.
MCF_PWM_PWMCAE &= 0b11111101; // Define PWM1 as lef-aligned.
MCF_PWM_PWMCTL |= 0b00010000; // Concatenates PWM channels 0 and 1 to form one 16-bit PWM channel.
MCF_PWM_PWMSCLA = 0; // This hasn't effect because the choice of Clock A otherwise of Clock SA.
MCF_PWM_PWMSCLB = 0; // This hasn't effect because only affect PWM3 and PWM7.
/* Enable PWM channels*/
MCF_PWM_PWME = MCF_PWM_PWME_PWME1; // Enable PWM1 concatenated
MCF_PWM_PWMSDN = 0; // Disable Emergency shutdown
}

/**
* \brief main - Main Function
* \author TIC Guadalajara adapted by Marcio A. F. Montezuma for M5329EVB
* \param void
* \return No return.
* \todo
* \warning
*/
int main(void)
{
int counter = 0;

#if (CONSOLE_IO_SUPPORT || ENABLE_UART_SUPPORT)
printf("Hello World in C from MCF5329 derivative on M5329EVBDEMO board\n\r");
//fflush(stdout);
#endif

/** Setup GPIO*/
init_pin_assignments();

/** Setup PWM*/
init_pwm();

for(;;) {
counter++;
}
}

Labels (1)
0 Kudos
3 Replies

575 Views
TomE
Specialist II

> Now I want to know how to update 16 bits duty cycle (PWMDTY0 and PWMDTY1 )

> in one operation. To avoid change duty cycle in wrong way.

Section "26.3.2.7 PWM 16-Bit Functions" says "In concatenated mode, writes to the 16-bit counter by using a 16-bit access...".

I don't know if you know enough about programming in C to be able to do that from the above instruction.

There's at least a dozen different ways to do this badly, but the "best" way is the one that is clean and uses the existing headers.

I have no idea what is in "#include "support_common.h"", and I don't want to know. I don't know if the access macros were written by you or by Freescale. I don't know why there's a "_DUTY" macro as the all 8 buts of the register are written. So what is "MCF_PWM_PWMDTY0 = MCF_PWM_PWMDTY_DUTY(0x17);" really doing?

If the register access macros in those files have been written properly, there should be a definition in there for use when in concatenated mode that performs the 16-bit write for you.

If they look like this one, then the programmer didn't bother to write these for you:

FreeRTOS/MCF52235_PWM.h at master · jameswalmsley/FreeRTOS · GitHub 

You should write some definitions in your source file to do this. Hint, copy one of the 8-bit ones and simply change "(vuint8 *)" to "(vuint16 *)". Make sure you get the 16-bit address correct, remembering this is a big-endian CPU.

To check you might want to write the duty registers as 16 bit, and then read them back using the byte-access macros to make sure the correct values are getting into the right counter.

Tom

0 Kudos

575 Views
marcioaureliofu
Contributor I

Hi Tom,


You are right, I'm not expert in C programming, far from it.
And all macros were written by Freescale and they are in header files.
There are few literatures about coldfire V3 and V4 to help beginners with explanations about structures of files that change according version of the Codewarrior and if you are using Processor Expert or not.
I apreciate your help that is very importante to me. Let me answer your questions!
"#include "support_common.h" is the file to call MCF5329.h that will call other header files in "hello world" of the M5329EVB provided by Freescale.
"MCF_PWM_PWMDTY0 = MCF_PWM_PWMDTY_DUTY(0x17);" is the same thing that "MCF_PWM_PWMDTY0 = 0x17;" I kwon!!!
I already had tested change (vuint8 *) to (vuint16 *), but it didn't work.
Ex.: #define MCF_PWM_PWMDTY1 (*(vuint16 *)(0xFC09003D)).
I thought that it was the low byte address.
My mistake was use high and low byte convention to Duty Cycle register from Ref. Manual page 16-20, where PWM0 register is High and PWM1 resgister is Low, that is right to form the 16 bits Duty Cycle PWM value, but it isn't right to define the low and high memory addresses.
Seeing the addresses, I can verify that the low address is PWM0 0xFC09003C and high address is PWM1 0xFC09003D.
I will change the macro in MCF5329_PWM.h to "#define MCF_PWM_PWMDTY(x) (*(vuint16 *)(0xFC09003C + ((x)*0x1)))" instead of use (vuint8 *). or #define MCF_PWM_PWMDTY (*(vuint16 *)(0xFC09003C)) and verify.

Thanks a lot,

Marcio

0 Kudos

575 Views
marcioaureliofu
Contributor I

Tom 

Like you said in your answer, I need pay attention in Big-Endian CPU. As soon as possible I will test these suggestions.

Thanks again,

Marcio

0 Kudos