This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2538 -- PWM Generator

Other Parts Discussed in Thread: CC2538

Greetings,

Trying to configure one of the GP Timers on CC2538 to function as a PWM Generator.  So far, absolutely no success.

Tried to configure as follows:

Timer 0, Section A

Mapped to I/O port A, Pin 0

Port A Pin 0 mapped to Input Capture 1

Nothing real fancy here.

  

Here is the test code (derived from TI Example Project GPTimer -- periodic_prescaler_16bit

found in the cc2538_foundation_firmware_1_0_1_0 driverlib stuff) :

====================================================================

int

main(void)

{

  int delayIndex;

  unsigned int pwmDutyCycle = 0x0000;

 

    //

    // Initialize the interrupt counter.

    //

    g_ui32Counter = 0;

 

   

    //

    // Set the clocking to run directly from the external crystal/oscillator.

    // (no ext 32k osc, no internal osc)

    //

    SysCtrlClockSet(false, false, SYS_CTRL_SYSDIV_32MHZ);

 

    //

    // Set IO clock to the same as system clock

    //

    SysCtrlIOClockSet(SYS_CTRL_SYSDIV_32MHZ);   

   

    //

    // The Timer0 peripheral must be enabled for use.

    //

    SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_GPT0);   

 

    //

    // Set up the serial console to use for displaying messages.  This is

    // just for this example program and is not needed for Timer operation.

    //

    InitConsole();  

 

    //

    // Display the example setup on the console.

    //

    UARTprintf("16-Bit Timer PWM ->");

    UARTprintf("\n   Timer = Timer0B");

    UARTprintf("\n   Mode = PWM with variable duty cycle");

 

    //

    // Configure GPTimer0A as a 16-bit PWM Timer.

    //

    TimerConfigure(GPTIMER0_BASE, GPTIMER_CFG_SPLIT_PAIR |

                   GPTIMER_CFG_A_PWM | GPTIMER_CFG_B_PWM);

 

    //

    // Set the GPTimer0B load value to 1sec by setting the timer load value

    // to SYSCLOCK / 255. This is determined by:

    //      Prescaled clock = 16Mhz / 255

    //      Cycles to wait = 1sec * Prescaled clock

    TimerLoadSet(GPTIMER0_BASE, GPTIMER_A, SysCtrlClockGet() / 4000);       

 

    TimerControlLevel(GPTIMER0_BASE, GPTIMER_A, false);

   

    // Configure GPIOPortA.0 as the Timer0_InputCapturePin.1

    IOCPinConfigPeriphOutput(GPIO_A_BASE, GPIO_PIN_0, IOC_MUX_OUT_SEL_GPT0_ICP1);

       

    // Tell timer to use GPIOPortA.0

    // Does Direction Selection and PAD Selection

    GPIOPinTypeTimer(GPIO_A_BASE, GPIO_PIN_0);

    

    //

    // Enable processor interrupts.

    //

    IntMasterEnable();    

 

    //

    // Enable GPTimer0B.

    //

    TimerEnable(GPTIMER0_BASE, GPTIMER_A);   

 

    UARTprintf("\n");

    //

    // Loop forever while the Timer0B runs.

    //

    while(1)

    {

      for (delayIndex = 0; delayIndex < 100000; delayIndex++);

     

      pwmDutyCycle += 0x0F;

      pwmDutyCycle &= 0xFFFF;

     

      TimerMatchSet(GPTIMER0_BASE, GPTIMER_A, pwmDutyCycle);

     

      UARTprintf("PWM DC Value: %04X -- %04X -- %04X\r",

                      pwmDutyCycle,

                      TimerValueGet(GPTIMER0_BASE, GPTIMER_A),

                      TimerMatchGet(GPTIMER0_BASE, GPTIMER_A) );

     

    }

}

 

====================================================================

 

 Thanks in advance.

mDupont

 

 

 

  • Ok, I solved this.

    The issue is that the function, void GPIOPinTypeTimer(uint32_t ui32Port, uint8_t ui8Pins) in gpio.c sets the output that I'm trying to drive to DISABLED (IOC_OVERRIDE_DIS).  To enable the output, I used IOC_OVERRIDE_OE instead.  Voila.  It works.

    Cheers,

    M.Dupont


  • Further disclosure for anyone who wants to use the example code above:

    Use PORTC.0 instead of PORTA.0 as the output.  This will map to LED-1 on the SmartRF06 board.

    M.Dupont

  • Hi,

    I have a problema when i define the prescale diferent from 0 ... " TimerPrescaleSet(GPTIMER0_BASE, GPTIMER_A, 4);  "

    Because the DutyCycle time isn't it proprotional.

     

    Why? anyone can help?

  • please... anyone can help...

  • hi, i'm trying to make the pwm work, i've followed the topic, changed the port A.0 to C.0 and used IOC_OVERRIDE_OE in void GPIOPinTypeTimer(uint32_t ui32Port, uint8_t ui8Pins) in gpio.c, but i have no led1 effects, how should i change the interrupt handler to make it work?

    thanks in advance
  • Instead of modifying gpio.c, just add 

    IOCPadConfigSet(GPIO_C_BASE, GPIO_PIN_0, IOC_OVERRIDE_OE);

    after call to GPIOPinTypeTimer

  • HI, I have been using the same code to generate a PWM signal with the changes made accordingly , yet I am not able to generate a 38 khz signal. ( I have removed all the Serial Console messages to be displayed) .

    #include <stdbool.h>
    #include <stdint.h>
    #include <hw_ints.h>
    #include <hw_memmap.h>
    #include <gpio.h>
    #include <ioc.h>
    #include <hw_ioc.h>
    #include <sys_ctrl.h>
    #include <gptimer.h>

    int
    main(void)
    {

       int delayIndex;

       unsigned int pwmDutyCycle = 0x0000;


        SysCtrlClockSet(false, false, SYS_CTRL_SYSDIV_32MHZ);
      
        SysCtrlIOClockSet(SYS_CTRL_SYSDIV_32MHZ);
     
        SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_GPT0);
        TimerConfigure(GPTIMER0_BASE, GPTIMER_CFG_SPLIT_PAIR | GPTIMER_CFG_A_PWM | GPTIMER_CFG_B_PWM ); 
        TimerLoadSet(GPTIMER0_BASE, GPTIMER_A, SysCtrlClockGet() / 38000);
        TimerControlLevel(GPTIMER0_BASE, GPTIMER_A, false);
        IOCPinConfigPeriphOutput(GPIO_C_BASE, GPIO_PIN_0,IOC_MUX_OUT_SEL_GPT0_ICP1);


        GPIOPinTypeTimer(GPIO_A_BASE, GPIO_PIN_0);


        IOCPadConfigSet(GPIO_A_BASE, GPIO_PIN_0, IOC_OVERRIDE_OE);

        GPIOPinTypeGPIOOutput(GPIO_A_BASE, GPIO_PIN_0);


        IntMasterEnable();
        TimerEnable(GPTIMER0_BASE, GPTIMER_A);
         

      while(1)

      {

         for (delayIndex = 0; delayIndex < 100000; delayIndex++);


    {
         pwmDutyCycle += 0x0F;

         pwmDutyCycle &= 0xFFFF;

         TimerMatchSet(GPTIMER0_BASE, GPTIMER_A, pwmDutyCycle);

     }

        }