Author Topic: PWM generation  (Read 15485 times)

Offline FAQ

  • Newbie
  • *
  • Posts: 27
    • View Profile
PWM generation
« on: December 25, 2010, 03:10:08 PM »

How do we configure 8 channel PWM timer hardware block(for LM3S1776) in uTasker?


Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3240
    • View Profile
    • uTasker
Re: PWM generation
« Reply #1 on: December 25, 2010, 03:31:57 PM »
Hi

The use of PWM is show in the file ADC_Timers.h.

The define TEST_PWM activates some code that configures two PWM outputs with different frequencies and PWM mark/space values, plus some code showing how to disable these if required. Thsi code however generates these signals form the general purpose timers, which als osupport PWM output.

The LM3S1766 has 4 PWM generator blocks, each of which can generate 2 PWM output signals (8 in total).
There is however presently no support for this PWM block in the uTasker project.

Regards

Mark



Offline Unmesh

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: PWM generation
« Reply #2 on: December 27, 2010, 07:52:06 AM »
Hi Mark,

            The configuration of PWM generator on AT91SAM7X without using timers is mentioned on the "uTaskerHWTimers.pdf"
under Appendix E. How do we configure the PWM generator with out usnging general purpose timers on the uTasker Luminary platform?

Thanks and Regards,
Unmesh

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3240
    • View Profile
    • uTasker
Re: PWM generation
« Reply #3 on: December 27, 2010, 04:10:30 PM »
Hi Unmesh

The SAM7X project does include support for its PWM generators as described in that document.

I will look into adding a compatible/similar interface for the Luminary devices. Once I have something tested I will report back.

Regards

Mark

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3240
    • View Profile
    • uTasker
Re: PWM generation
« Reply #4 on: January 01, 2011, 11:24:47 PM »
Hi Unmesh

I have tested an implementation on the LM3S8962. This has 3 PWM generators (up to 6 outputs).
The description has been updated in the HW timer document http://www.utasker.com/docs/uTasker/uTaskerHWTimers.PDF, whereby the following is an extract of the new part:



The LM3Sxxxx has optional PWM generators. Each available one has two channel outputs which are named internally channel A and B for each generator. Externally the naming of the PWM outputs counts from 0, 1 to the highest one. For example, a device with 2 PWM generators will have outputs PWM0, PWM1, PWM2 and PWM3, whereby PWM0 and PWM are channels 0 and 1 of the first generator module and PWM2 and PWM3 are the channels 0 and 1 of the second PWM generator module.
In addition to the PWM controller, the general purpose timers can also be used to generate PWM signals. Only the PWM controller is discussed here.

To enable the PWM controller support in the µTasker project the define SUPPORT_PWM_CONTROLLER must be set.
The following is an example of using the PWM controller together with the LM3S8962. It shows 2 PWM signals being generated, using 2 PWM from 2 generator modules. The LM3S8962 has 3 PWM modules and can thus generate up to 6 PWM output signals at the same time.


Code: [Select]
   TIMER_INTERRUPT_SETUP timer_setup = {0};       // interrupt configuration parameters
    timer_setup.int_type = PWM_CONFIGURATION;    
    timer_setup.timer_reference = 2;               // PWM channel 2
    timer_setup.int_type = PWM_CONFIGURATION;
    timer_setup.timer_mode  = PWM_DIV_1;           // don't start yet
    timer_setup.timer_value = PWM_FREQUENCY_VALUE(1000, 1); // generate 1000Hz on timer output
                                                                using PWM clock without divide
    timer_setup.pwm_value   = _PWM_PERCENT(20, PWM_FREQUENCY_VALUE(1000, 1));
                                                   // 20% PWM (high/low)
    fnConfigureInterrupt((void *)&timer_setup);    // enter configuration for PWM test
    timer_setup.timer_reference = 5;
    timer_setup.timer_mode  = (TIMER_PWM_START_2 | TIMER_PWM_START_5 | PWM_DIV_1);
                                                   // generate PWM signal on these outputs
    timer_setup.timer_value = PWM_FREQUENCY_VALUE(1500, 1);
    timer_setup.pwm_value   = _PWM_TENTH_PERCENT(706, PWM_FREQUENCY_VALUE(1500, 1));
                                                  // 70.6% PWM (high/low) on different channel  
    fnConfigureInterrupt((void *)&timer_setup);   // enter configuration for PWM test


Note the following points:
1)   Since the PWM controller is being used, and not a general purpose timer, the int_type is set to PWM_CONFIGURATION. The TIMER_INTERRUPT_SETUP is otherwise used as for timer control.
2)   timer_reference is used to specify the PWM controller channel (0..5). In the example 2 channels (2 and 5) are configured.
3)   The PWM outputs PWM2 and PWM5 are fixed on dedicated outputs, which may change with different parts. The driver code selects the appropriate peripheral function for the tested part but this needs to be verified for other parts in case they need a dedicated port configuration to be added.
4)   Although the 2 channels are configured independently, their operation is not actually started until the final channel is configured. All 2 are started using TIMER_PWM_START_2 | TIMER_PWM_START_5, which has the effect of (roughly) synchronising all 4 channels.
5)   To stop channels from operating the mode flags TIMER_PWM_STOP_2 and/or TIMER_PWM_STOP_5 can be used. Should no further channels be running after this command the PWM controller will be powered down to save energy.
6)   Since PWM0 and PWM1 (PWM2 and PWM3, etc.) are derived from the same PWM generator with a single 16 bit counter the output frequency must be the same for these two outputs. The PWM mark/space ration can however be configured independently. The two outputs are always syhchronised since they are derived from the same counter.
7)   PWM outputs not belonging to the same PWM generator are free to have different frequencies. The driver doesn’t synchronise the output signals between PWM generators although the PWM controller in the LM3Sxxxx has some global synchronisation capabilities.
8 )   The PWM generator has a high degree of flexibility as to how the PWM signals are generated. The driver uses one fixed method as follows to generate the signals:
Initially the PWM output signal is at logical level ‘0’.
The PWM counter is loaded with the base frequency value and remains at ‘0’ and counts down until the count value matches the PWM value for the specific channel (A or B), at which moment the output is set to logical ‘1’.
The counter continues to count down until it reaches the value 0x0000, at which moment it is automatically reloaded with the periodic value and the output is reset to logical ‘0’ again. This results in the configured PWM mark/space value with the ‘1’ phase occurring after the ‘’0 phase (right-aligned).
9)   When configuring the PWM frequency and mark/space % value a divider is also specified. This is a divider to the PWM module which must be the same for all PWM generators and channels used at the same time. It can have the values 1, 2, 4, 8, 16, 32 or 64, which must also be specified in the mode setting (PWM_DIV_1, PWM_DIV_2, PWM_DIV_4, PWM_DIV_8, PWM_DIV_16, PWM_DIV_32 or PWM_DIV_64) – if nothing is specified PWM_DIV_1 is valid.
The PWM generators are therefore clocked by the system clock divided by the PWM divide value; a divide value of 1 gives the highest frequency and PWM resolutions; higher divide values allow slower signals to be generated and slightly reduced power consumption.


The new code is included in the attached zip file, which incorporates the following files:

- ADC_Timers.h - new test code. It requires TEST_TIMER and TEST_PWM to be active in the file and SUPPORT_PWM_CONTROLLER generally (usually added to app_hw_lm3sxxxx.h).
- LM3SXXXX.c - see 27.12.2010 Add PWM controller support                                 {32} for the new interface code
- LM3SXXXX.h - see the following for the new defines:
  27.12.2010 Add PWM_CONFIGURATION                                      {30}
   27.12.2010 Add _LM3S1776                                              {31}


These new files will not be fully compatible with the released project so you may need to just copy the relevant parts.
You will also see that there is a new define _LM3S1776 which is also used in the PWM port peripheral interface code to set the PWM peripheral outputs since the location of these are not the same on all chips (eg. PWM0 is on PF0 in the LM3S8962 but on PD0 in the LM3S1776). I have tried to set these up to suit the LM3S1776, which has 8 PWMx pins, but you will need to verify that all really do work since I don't have such a device for testing on.

As noted in the documentation the implementation is general so that up to 8 PWM signals can easily be configured (with the restrictions as noted). The PWM generator is however quite flexible and can be controlled in various ways, so additional tuning can be added once you have verified that the basic case works correctly.

Regards

Mark