Wednesday, May 25, 2011

MCPWM in LPC17xx

Motor Control PWM can be used to control AC and DC motors. It can also be used for many other purposes which require timing, counting, comparing or capturing. The MCPWM is used for generating audio signals in the 2d game console as the general PWM is used for color generation. And I will be discussing as to how it works and how to initialize it.

There are 3 MCPWM channels in LPC1768. Each channel contains its own 32-bit timer, 32-bit Limit register, 32-bit Match register, 10-bit deadtime register and 32-bit capture register. And there will be two output pins for each channel named A and B. The A and B outputs will be complementary to each other. Here the Limit register sets the TOP value of the timer. Hence the timer counts from 0 to the Limit value. So one can set the PWM frequency by choosing a correct prescaler (clock frequency divider) and the limit value.

There are two modes, one is edge aligned and the other is center aligned mode. In edge aligned mode, the timer will count upwards from 0 to limit and goes back to 0 and the output toggles when the timer value matches with the match register or the limit register. In center aligned mode, the timer will count upwards from 0 to limit and then counts downward from limit to 0 and the output toggles only when the timer value matches the match register value. If you are looking for a phase correct mode, then you should use center aligned mode.

You can even set the passive polarity of the output. If you select passive polarity state as LOW, then the MCPWM output signal will be LOW until the timer value matches the match register value and will be HIGH from the time when match occurs till the timer value matches the limit register value. If the polarity state is selected as HIGH, then the reverse will happen.


 Figure 1: Waveform indicating the output of MCPWM channel 0 with polarity as 0 in edge aligned mode. (Source: NXP user manual for LPC1768)




 Figure 2: Waveform indicating the output of MCPWM channel 0 with polarity as 0 in center aligned mode. (Source: NXP user manual for LPC1768)


For 2-channel audio generation purpose, MCPWM channels 1 and 2 were used. Follow the code below to initialize and use the MCPWM.

          // Power up MCPWM
    LPC_SC->PCONP |= 1<<17;


    // PCLK = CCLK (100MHz in our case)
    LPC_SC->PCLKSEL1 |= 1<<30;


          // Configuring P1.25 and P1.28 as MC1A and MC2A
    LPC_PINCON->PINSEL3 |= (1<<18) | (1<<24);

          // Set the Limit register (MCLIM0-2 is named as MCPER0-2 in CMSIS source file)
    LPC_MCPWM->MCPER1 = 255;
    LPC_MCPWM->MCPER2 = 255;

          //  Start MCPWM channels 1 and 2 and POLA = 1
    LPC_MCPWM->MCCON_CLR = 0xffffffff;
    LPC_MCPWM->MCCON_SET = (1<<10) | (1<<18) | (1<<16) | (1<<8);

Here the reason I am using POLA = 1 is that I want average value of the output signal to be my audio signal. I am using 8-bit audio and the audio sample value 0 should give less amplitude than the value 255. So the PWM signal should stay HIGH only till it matches with the match value (audio sample) and then should become LOW.

Now that the configuration is over, the only thing that is remaining is to get audio out of MC1A and MC2A. So we need to update the MCMAT1 and MCMAT2 at the PCM rate of the audio signal that needs to be played. For example we want to play a 16kHz 8-bit sample width audio (WAV file). So we need to update MCMAT1,2 once in (1/16kHz) = 62.5uS. Lets setup a timer to give an interrupt once in 62.5uS and update the match values in that interrupt.

          // Power up Timer1
    LPC_SC->PCONP |= 1<<2;

          // PCLK = CCLK (In my case it is 100MHz) 
    LPC_SC->PCLKSEL0 |= 1<<4;

          // Select 16kHz as timer frequency
          // (100MHz / 16kHz) = 6250. Therefore match value should be 6249 as the timer starts counting from 0.
    LPC_TIM1->MR0 = 6249;

          // Reset and interrupt on Match 0
    LPC_TIM1->MCR |= (1<<0) | (1<<1);
    
    // Enable Timer1 interrupt 
    NVIC_EnableIRQ(TIMER1_IRQn);

          // Reset and Start the timer
    LPC_TIM1->TCR = 2;
    LPC_TIM1->TCR = 1;

Now the interrupt routine looks like this

void TIMER1_IRQHandler()
{
    // Update the Match registers of MCPWM 
    // MCMAT0-2 is named as MCPW0-2 in CMSIS source file
    LPC_MCPWM->MCPW1 = <sample of audio channel 1>;
    LPC_MCPWM->MCPW2 =
<sample of audio channel 2>;
}

After doing this you can enjoy listening to music from LPC. You can very easily make an audio player with an SD card. See this for more information as to how to use an SD card with LPC1768. If anyone needs more help with MCPWM then post your queries in comments. I will try my best to find you the answer.

28 comments:

Chris said...

Hello Thejasvi and Sagar (I'm commenting on both of your blogs). I've been doing some very similar work recently, involving video and he LPC1768. Is there a common forum where I can share my ideas on this kind of project? I think I have some pretty innovative solutions. My application is a bit different from yours, but the technical details are very similar.

Sincerely,
-Chris

Thejasvi said...

Hello Chris,
Great to hear about people working on same things.

If you are using mbed, then you can post your ideas or findings in http://mbed.org/forum/.

Any video generation for TV related stuff can be posted in the off topic section of http://uzebox.org/forums/.

Or you could post it in http://www.lucidscience.com.

Please share the link of the post where you will share your ideas and findings. Eager to know what they are.

With Regards,
Thejasvi

Anonymous said...

I believe the last label at the bottom of figure 2 should say "MAT" rather than "LIM".

Thejasvi said...

@^^ Yes you are right. Sorry for the mistake.

Mbed said...

Is it possible to do this on mbed if so how, no pins are connected to MCMAT1 and MCMAT2.

Thejasvi said...

There are actually three MCPWM channels on the LPC1768. But sadly they are not exposed in mbed. So you cannot use the MCPWM in mbed.

You can go through the mbed schematics. In page 3 of the schematics they have given the pin diagram of LPC1768. The MCPWM 0 and 2 are not at all exposed and the pins of MCPWM1 are being used for LED_LINK and LED_SPEED. I do not know what these pins are actually used for on mbed. But if you know about it and if it is safe, you can try tapping these pins and configuring it as MCPWM output.

Thejasvi said...

Also you can try tapping the MCPWM 0 and 2 pins directly from the LPC1768 chip on the mbed. But this will require soldering expertise.

CAUTION: You might burn your mbed in this process. Be careful.

Mbed said...

I working on a reverse guitar code but getting clicking because of the interrupts I think what do you think it could be you seem to know abit and have been very helpful

http://mbed.org/users/mbed2f/notebook/usbmainc--the-main-file-of-the-usb-reverse-audio-c/

here we are discussing trying to figure it out

http://mbed.org/forum/mbed/topic/3022/?page=1#comment-15376

Thejasvi said...

@ Mbed
Can you please explain in detail as to what you are trying to do and what exactly the problem is? The details might help me to solve the issue.

Mbed said...

Here this is the aim of the project,
I published it but it still has clicking but it just so cool, I had to post it

http://mbed.org/users/mbed2f/programs/UsbReverseAudioguitarspeaker/m3hxp5

What I am trying to do now is to change the usb output to 8bits and drop the khz to 16khz and see if that will fix it.

but I can not get 8bits to work with out weird distortion.

someone said this

So you are receiving unsigned values. Try to send these raw data (without trying to convert the value or something else) to the speaker

I said
how would I send the raw data to the speaker.


but I am still trying to get it to work at 16bit as well, but It is complexed issue to fix.

Anonymous said...

what about the MCABORT - PIN? has it to be pulled up?

dinesh kumar.R said...

hi thejasvi,

In LPC1751, what is the handler to be used for GPIO interrupt, where we are using EINT3_IRQn as handler in LPC1768 since it is shared with GPIO interrupt.I am asking this because LPC175X has only one external interrupt EINT0.

Thanks & regards,
Dinesh.

dinesh kumar.R said...

i am using LPC1751.

forgot to mention in previous post.

Thejasvi said...

@ dinesh

I do not think that you can use any GPIO pin for an interrupt in LPC1751. Its datasheet says that you can use only one pin from Port 0 or 2 as an external interrupt at a time.

dinesh kumar.R said...

hi @thejasvi,

but in the datasheet of LPC175X, they had given gpio interrupt in the memory map & block diagram also. pls check it once.

Thanks & regards,
Dinesh.

Thejasvi said...

If you see the page 5 of the LPC175x datasheet, it says that only port 0 and 2 are connected to the GPIO interrupt. Which is what I indicated in my previous comment.

dinesh kumar.R said...

only one pin at a time which means we can configure multiple pins as GPIO interrupt but should not get interrupted at the same time.

am i right?

why because i am planning to configure two pins as GPIO int.

Thanks & regards,
Dinesh.

Thejasvi said...

The datasheet says that only one of the pins from P0 and P2 can be configured as an external interrupt pin at a time. That means you can configure one pin as ext int for say 5 seconds, use that interrupt, then configure another pin as ext int and use that interrupt. But you cannot configure both pins as ext int at the same time even though their interrupts might arrive at different times.

venkatesh said...

hi,

I got my new EM-LPC1700 board. when i tried to flash the code ISP through uart with flash magic tool.

It is showing auto baud rate error.

how to start with. i am new to this board. please provide me some pointer to start flashing the code.

thank you,
venkat.

Thejasvi said...

Venkatesh,

I have not used flashmagic before, but try to see if it works when the buad rate is kept at 9600 or below.

Also make sure you are selecting the correct COM port in the flash magic. (you can see device manager for this)

venkat said...

hi thejasvi,

everything s fine..

but even though i follow the steps to get into ISP mode, micro controller is not responding back...

i dono exactly whether it is a hard ware problem or wat?

i had tested with 2 boards i got. still the same :(

have you ever tried with EM-LPC1700 embest board, check once in the internet, you wil get an idea.

Thanks & regards,
Dinesh.

Thejasvi said...

As I have not worked with the board that you have and also as I have not used flashmagic before, I will suggest you to post this question in a forum where there are people who are familiar with these.

Sorry for not being able to help.

dinesh kumar.R said...

Hi thejasvi,

I generated 1 Mhz clock from LPC1768 micro controller through PWM module. I am gonna fed this clock to the sensor device. Is it possible to achieve the same 1 Mhz in MCPWM and give the clock to sensor device?

Regards,
Dinesh.

dinesh kumar.R said...

@thejasvi,

Forgot to ask this last comment, Is it possible to generate the pulse using MCPWM, which similar to dual edge control pulse in PWM. if so, how to configure it,

Now, i am able to generate single edge controlled PWM pulses through MCPWM.

I want to genearte pulse similar to dual edge controlled pulse. Please suggest me.

Regards,
Dinesh.

Thejasvi said...

MCPWMs are very limited with features - because they are specialized to control motors!! You can only obtain a certain duty cycle pulses for a given time period of the PWM signal. So it is not possible to generate any duty cycle pulse located in a random position in a given PWM period with MCPWMs.

If you still want to use this limited dual edge PWM feature, then setup the MCPWM in center mode, set the limit value depending on the PWM period and the match value depending on the duty cycle you need. Remember, by doing this you are controlling the positions of the edges of the pulse, but the caveat is that both the edges will be equidistant from the center. So you cannot "place" the pulse anywhere you want. Also if you choose a low limit value, then the you will be limited on the duty cycle steps.

Unknown said...

Hai all..
How to run split phase induction motor using LPC1769 MCPWM.

Unknown said...

Hi,
what is the differnce between PWM and MCPWM?
I want to control servo motors. What do you recommented?

Cicero Matos said...

And a dead_time insertion ??