Using PWM messes up Sys Clk configuration?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Hi all,

We use this to start a PWM ...

  //Accessing the internal clock reference

  aclk_configure(512000, ACLK1, ACLK_FREQ_24_MHZ); // Configure to 512 kHz

  //Start the PWMs

  pwm_start(PWM_YELLOW_LED_2, PMU_CLK, 0x3E0, 0x3BF);  // Blink at 8 kHz

  //Setting the GPIO Pins

  gpio_configurePin(LEDS_PORT, GPIO_YELLOW_LED_2, GPIO_OUTPUT_ENABLE, LED_OFF);

... which works fine.  But when we are done we do this ...

  gpio_configurePin(LEDS_PORT, GPIO_YELLOW_LED_2, GPIO_INPUT_ENABLE | GPIO_PULL_UP, LED_OFF);

  //Stop the PWM

  pwm_disableChannel(1 << PWM_YELLOW_LED_2);

  gpio_configurePin(LEDS_PORT, GPIO_YELLOW_LED_2, GPIO_OUTPUT_ENABLE, LED_OFF);

  pwm_setReset(PWM_YELLOW_LED_2, 0);

... and the end result is that the system does not work reliably after that.

Sometimes we can't connect or send commands via BLE, etc.

We suspect that the "aclk_configure" does something that would require a reconfiguration call, but the pwm.h API does not tell us what to do.

Any ideas?

Thanks,

Gil

0 Likes
1 Solution
Anonymous
Not applicable

jakewtorres

- 1 of the PWM channels is working much better with the PWMx_OUTPUT_ENABLE_Pxx definition.

- I've tried LHL_CLK instead of PMU_CLK and that's much better.

I've found out what was causing the problem.  It was switching configuration for those pins from GPIO (for "full" brigthness), then to PWM (for partial brightness based on % duty cycle), then again to GPIO, etc.  I've decided to just configure it as PWM the whole time, and use 100% duty cycle if I wanted a "full" brightness, and some partial % duty cycle if I want to save power.

Turning an LED on/off now works like this:

void leds_turn_on_off(UINT8 port, UINT8 gpio, UINT8 on_off, UINT16 pwm_level)

{

      if (on_off == LED_OFF)

      {

              switch (gpio)

              {

                      case GPIO_RED_LED:

                              // Stop the PWM

                              pwm_disableChannel(1 << PWM_RED_LED);

                              // Ensure LED is off when done

                              gpio_configurePin(LEDS_PORT, GPIO_RED_LED, GPIO_INPUT_ENABLE | GPIO_PULL_UP, LED_OFF);

                              pwm_setReset(PWM_RED_LED, TRUE);

                              break;

                      // ... other LEDs

                      default:

                              break;

               }

      }

      else   // LEDs on

      {

              switch (gpio)

              {

                      case GPIO_RED_LED:

                              pwm_start(PWM_RED_LED, LHL_CLK, PWM_TOGGLE_COUNT, pwm_level);

                              // Setting the GPIO Pin

                              gpio_configurePin(LEDS_PORT, GPIO_RED_LED, ENABLE_PWM_RED, LED_OFF);    // Initial state is off

                              break;

                      // ... other LEDs

                      default:

                              break;

              }

      }

}

View solution in original post

0 Likes
6 Replies
JacobT_81
Employee
Employee
250 replies posted 100 replies posted 50 replies posted

I'm having trouble replicating this. Can you post your code?

What hardware are you on? Is it an eval board?

Jacob

0 Likes
Anonymous
Not applicable

Hi Jacob,

No it's our real product board (Loopd Badge).  I can't post the whole code, just snippets.

0 Likes

Hi gdepaula​,

I put your snippets into hello_sensor's create function as well as in the timeout loop, starting and stopping the PWM after 100ms. I couldn't get it to break anything.

I'll continue looking into this, and reattempt on different hardware tomorrow.

Jacob

Anonymous
Not applicable

Hello.

Which pin are you using?

In wiced_sense example in the SDK, uses enums from pwm.h when configuring the GPIOs:

pastedImage_0.png

line 588:

pastedImage_2.png

Also in the same application, it uses LHL_CLK.

So if you think ACLK is causing problems, try using LHL_CLK.

line 581:

pastedImage_1.png

From pwm.h:

pastedImage_3.png

So it can be that the sleep mode is messing things up. So if you are not using sleep, you can try to disable it and see everything works fine.

Sleep Deep_Sleep Explanation and Techniques

James

Anonymous
Not applicable

Thank you Jacob and James!

We have 4 LEDs and use all 4 PWM channels.

Yellow:  GPIO_PORT1, P26  (PWM0)

Yellow2:  GPIO_PORT1, P27  (PWM1)

Green:  GPIO_PORT0, P13  (PWM3)

Red:  GPIO_PORT0, P14  (PWM2)

I did find a problem with the GPIO_OUTPUT_ENABLE usage, so I'm now going to try PWMx_OUTPUT_ENABLE_Pxx definitions as suggested.

I will also try LHL_CLK, because we do use sleep modes and need them.

I will let you guys know what happens.

Gil

0 Likes
Anonymous
Not applicable

jakewtorres

- 1 of the PWM channels is working much better with the PWMx_OUTPUT_ENABLE_Pxx definition.

- I've tried LHL_CLK instead of PMU_CLK and that's much better.

I've found out what was causing the problem.  It was switching configuration for those pins from GPIO (for "full" brigthness), then to PWM (for partial brightness based on % duty cycle), then again to GPIO, etc.  I've decided to just configure it as PWM the whole time, and use 100% duty cycle if I wanted a "full" brightness, and some partial % duty cycle if I want to save power.

Turning an LED on/off now works like this:

void leds_turn_on_off(UINT8 port, UINT8 gpio, UINT8 on_off, UINT16 pwm_level)

{

      if (on_off == LED_OFF)

      {

              switch (gpio)

              {

                      case GPIO_RED_LED:

                              // Stop the PWM

                              pwm_disableChannel(1 << PWM_RED_LED);

                              // Ensure LED is off when done

                              gpio_configurePin(LEDS_PORT, GPIO_RED_LED, GPIO_INPUT_ENABLE | GPIO_PULL_UP, LED_OFF);

                              pwm_setReset(PWM_RED_LED, TRUE);

                              break;

                      // ... other LEDs

                      default:

                              break;

               }

      }

      else   // LEDs on

      {

              switch (gpio)

              {

                      case GPIO_RED_LED:

                              pwm_start(PWM_RED_LED, LHL_CLK, PWM_TOGGLE_COUNT, pwm_level);

                              // Setting the GPIO Pin

                              gpio_configurePin(LEDS_PORT, GPIO_RED_LED, ENABLE_PWM_RED, LED_OFF);    // Initial state is off

                              break;

                      // ... other LEDs

                      default:

                              break;

              }

      }

}

0 Likes