Issue Blinking 3 led using PWM on dual bonded pin

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

cross mob
ThYo_2228536
Level 3
Level 3
First like received First like given

I want to blink every second green, blue or red based on a state machine

green no connected

blue connected

red ready to send a special alarm notifcation

So every second the state is changed between off to on for green or blue or red

This is custom design board not the tag4 board or any EVK board...

Screen Shot 2017-05-18 at 10.42.10 AM.png

I will try to isolate/update the code using tones app but with the state machine I want for debug purpose

// Following structure defines GPIO configuration used by the application

const BLE_PROFILE_GPIO_CFG meatsitter_gpio_cfg =

{

    /*.gpio_pin =*/

    {

    -1,//GPIO_PIN_WP,      // This need to be used to enable/disable NVRAM write protect

    -1,//GPIO_PIN_BUTTON,  // Button GPIO is configured to trigger either direction of interrupt

    -1,//GPIO_PIN_LED,     // LED GPIO, optional to provide visual effects

    -1,//GPIO_PIN_BATTERY, // Battery monitoring GPIO. When it is lower than particular level, it will give notification to the application

    -1,//GPIO_PIN_BUZZER,  // Buzzer GPIO, optional to provide audio effects

    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // other GPIOs are not used

    },

    /*.gpio_flag =*/

    {

    0,//GPIO_SETTINGS_WP,

    0,//GPIO_SETTINGS_BUTTON,

    0,//GPIO_SETTINGS_LED,

    0,//GPIO_SETTINGS_BATTERY,

    0,//GPIO_SETTINGS_BUZZER,

    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

    }

};

// To use PWM, we will need the auxiliary clock and the PWM drier.

#include "aclk.h"

#include "pwm.h"

// Port = P#/16 and PIN = P# % 16

#define LED_RED    26

#define LED_GREEN  14

#define LED_BLUE   13

#define GPIO_PORT(x)  (x/16)

#define GPIO_PIN(x)   (x%16)

#define GPIO_PIN_28   28

/*

enum

{

  /// PWM0 Output enable on P26

  PWM0_OUTPUT_ENABLE_P26  = GPIO_OUTPUT_ENABLE,

  /// PWM1 Output enable on P27 N/A MOSI

  PWM1_OUTPUT_ENABLE_P27  = GPIO_OUTPUT_ENABLE,

  /// PWM2 Output enable on P28

  PWM2_OUTPUT_ENABLE_P28  = GPIO_OUTPUT_ENABLE,

  /// PWM2 Output enable on P6 N/A

  PWM2_OUTPUT_ENABLE_P6   = (GPIO_OUTPUT_ENABLE | (1 << 4)),

  /// PWM2 Output enable on P14

  PWM2_OUTPUT_ENABLE_P14  = (2 << 4),

  /// PWM3 Output enable on P29 N/A

  PWM3_OUTPUT_ENABLE_P29  = GPIO_OUTPUT_ENABLE,

  /// PWM3 Output enable on P13

  PWM3_OUTPUT_ENABLE_P13  = (2 << 4)

};

*/

#define ENABLE_LED_RED    PWM0_OUTPUT_ENABLE_P26

#define ENABLE_LED_GREEN  PWM2_OUTPUT_ENABLE_P14 // PWM3_OUTPUT_ENABLE_P13

#define ENABLE_LED_BLUE   PWM3_OUTPUT_ENABLE_P13 // PWM2_OUTPUT_ENABLE_P14

#define DISABLE_LED_GPIO     GPIO_INPUT_ENABLE | GPIO_PULL_DOWN

#define LED_BLUE_CHANNEL     (PWM2)

#define LED_GREEN_CHANNEL    (PWM3)

#define LED_RED_CHANNEL      (PWM0)

#define FULL_PMW             (0x000)

#define HALF_PMW             (0x210)

typedef enum {

  OFF = 0,

  ON,

  DIM

} state;

typedef enum {

  RED = 0,

  GREEN,

  BLUE

} led;

#define GPIO_HIGH GPIO_PIN_OUTPUT_HIGH

#define GPIO_LOW GPIO_PIN_OUTPUT_LOW

static state current_state_red = OFF;

static state current_state_green = OFF;

static state current_state_blue = OFF;

static led led_color = GREEN;

Init:

  bleprofile_Init(bleprofile_p_cfg);

    bleprofile_GPIOInit(bleprofile_gpio_p_cfg);

// Enable LED

    gpio_configurePin(GPIO_PORT(LED_RED), GPIO_PIN(LED_RED), GPIO_OUTPUT_ENABLE, GPIO_HIGH);

    gpio_configurePin(GPIO_PORT(LED_GREEN), GPIO_PIN(LED_GREEN), GPIO_OUTPUT_ENABLE, GPIO_HIGH);

    gpio_configurePin(GPIO_PORT(LED_BLUE), GPIO_PIN(LED_BLUE), GPIO_OUTPUT_ENABLE, GPIO_HIGH);

    gpio_configurePin((GPIO_PIN_28)/16, (GPIO_PIN_28)%16, GPIO_INPUT_ENABLE, 0);

    // Configure auxiliary clock 1 (needed for PWM when using PMU_CLK; not needed

    // when reference is LHL_CLK) and use the 24MHz system

    // clock as the reference. Since we will generating up to 8KHz in this

    // app, feeding a 512K signal to the PWM as the reference should give

    // us sufficient accuracy. For higher accuracy, use a higher reference

    // frequency. Typically, for LEDs, we use lower PWM frequency and lower

    // reference frequencies.

    aclk_configure(512000, ACLK1, ACLK_FREQ_24_MHZ);

// Initialize GATT database

void myapp_database_init(void)

{

}

/ Toggle every second between TONES_STATE_0 and TONES_STATE_4

void tones_go_to_next_state(void)

{

  if (tones_current_state == TONES_STATE_4)

  tones_current_state = TONES_STATE_0;

  else

  tones_current_state = TONES_STATE_4;

}

//  LEDs state machine

void tones_blink_led1(void)

{

  // Generates a random number of length (in units of UINT32s) into buffer.

  extern void ulp_rand(UINT32* buffer, UINT32 length);

  UINT32 rand1, rand2, init_value, toggle_value;

  static ref_clock = 0;

  if (turn_off_led == 1)

  return;

  ulp_rand(&rand1, 1);

  ulp_rand(&rand2, 1);

  // The max count all PWM channels can count up to is 0x3FF.

  // So truncate both random numbers to 10 bits.

  rand1 &= (0x3FF);

  rand2 &= (0x3FF);

  /*

  if (rand1 > rand2)

  {

  init_value = rand2;

  toggle_value = rand1;

  }

  else

  {

  init_value = rand1;

  toggle_value = rand2;

  }

  // This may be possible.

  if (rand1 == rand2)

  {

  // Oops?

  init_value = 0;

  toggle_value = 0x3FF / 2;

  }

*/

  switch(tones_current_state)

  {

  case TONES_STATE_0:

  // In state 0, start the PWM and output enable the GPIO

  // Use LHL_CLK instead of PMU_CLK so it will continue to run in sleep.

  if (ble_connected)

  {

  init_value = 0;

  toggle_value = 0x3FF;

  if (led_color == RED)

  {

  // don't ask me why we need to toggle LED_BLUE_CHANNEL to show some blood...

  // RED

  pwm_enableChannel(1 << LED_BLUE_CHANNEL);

  pwm_start(LED_BLUE_CHANNEL, LHL_CLK, toggle_value, init_value);

  gpio_configurePin((LED_BLUE) / 16, (LED_BLUE) % 16, ENABLE_LED_BLUE, 0);

  }

  else

  {

  if (led_color == BLUE)

  {

  // BLUE for some strange reason I have to toggle RED to see BLUE not sure if it is a schematics issue or not on my end

  pwm_enableChannel(1 << LED_RED_CHANNEL);

  pwm_start(LED_RED_CHANNEL, LHL_CLK, toggle_value, init_value);

  gpio_configurePin((LED_RED) / 16, (LED_RED) % 16, ENABLE_LED_RED, 0);

  }

  }

  }

  else

  {

  init_value = 0;

  toggle_value = 0x3FF;

  pwm_enableChannel(1 << LED_GREEN_CHANNEL);

  pwm_start(LED_GREEN_CHANNEL, LHL_CLK, toggle_value, init_value);

  gpio_configurePin((LED_GREEN) / 16, (LED_GREEN) % 16, ENABLE_LED_GREEN, 0);

  gpio_configurePin((GPIO_PIN_28)/16, (GPIO_PIN_28)%16, GPIO_INPUT_ENABLE, 0);

  }

  break;

  case TONES_STATE_1:

  // In state 1, switch to another set of values. Transition is not glitch-free.

  if (ble_connected)

  {

  init_value = 0;

  toggle_value = 0x3FF;

  pwm_transitionToSubstituteValues(LED_BLUE_CHANNEL, toggle_value, init_value);

  }

  else

  {

  init_value = 0;

  toggle_value = 0x3FF;

  pwm_transitionToSubstituteValues(LED_GREEN_CHANNEL, toggle_value, init_value);

  }

  break;

  case TONES_STATE_2:

  // In state 2, invert the output.

  // if we comment this we will create purple color if we don't we will have blue

  if (ble_connected)

  {

  pwm_setInversion(LED_BLUE_CHANNEL, TRUE);

  }

  else

  {

  pwm_setInversion(LED_GREEN_CHANNEL, TRUE);

  }

  break;

  case TONES_STATE_3:

  // In state 3, use another set of values. Transition is glitch-free

  if (ble_connected)

  {

  init_value = 0;

  toggle_value = 0x3FF;

  pwm_startWithAlternateValues(LED_BLUE_CHANNEL, LHL_CLK, toggle_value, init_value, TRUE);

  }

  else

  {

  init_value = 0;

  toggle_value = 0x3FF;

  pwm_startWithAlternateValues(LED_GREEN_CHANNEL, LHL_CLK, toggle_value, init_value, TRUE);

  }

  break;

  case TONES_STATE_4:

  {

  // In state 4, disable output and the PWM entirely and insert an internal pull-down on the GPIO.

// or some strange reason I have to toggle RED to see BLUE not sure if it is a schematics issue or not on my end

  pwm_disableChannel( 1 << LED_RED_CHANNEL );

  pwm_setReset(LED_RED, 1);

  gpio_configurePin((LED_RED) / 16, (LED_RED) % 16, GPIO_OUTPUT_DISABLE | GPIO_PULL_DOWN, 0);

  gpio_configurePin((GPIO_PIN_28)/16, (GPIO_PIN_28)%16, GPIO_INPUT_ENABLE, 0);

  pwm_disableChannel( 1 << LED_GREEN_CHANNEL );

  pwm_setReset(LED_GREEN_CHANNEL, 1);

  gpio_configurePin((LED_GREEN) / 16, (LED_GREEN) % 16, GPIO_OUTPUT_DISABLE | GPIO_PULL_DOWN, 0);

  gpio_configurePin((GPIO_PIN_28)/16, (GPIO_PIN_28)%16, GPIO_INPUT_ENABLE, 0);

  // Disable the channel.

  pwm_disableChannel( 1 << LED_BLUE );

  pwm_setReset(LED_BLUE, 1);

  gpio_configurePin((LED_BLUE) / 16, (LED_BLUE) % 16, GPIO_OUTPUT_DISABLE | GPIO_PULL_DOWN, 0);

  gpio_configurePin((GPIO_PIN_28)/16, (GPIO_PIN_28)%16, GPIO_INPUT_ENABLE, 0);

  }

  break;

  default:

  break;

  }

  // Get init and toggle counts for LED and trace it.

  //if (ble_connected)

  //{

    // ble_trace2("LED init count: 0x%03X, Toggle Count: 0x%03X\n", pwm_getInitValue(PWM2), pwm_getToggleCount(PWM2));

  //}

  //else

  //{

  //ble_trace2("LED init count: 0x%03X, Toggle Count: 0x%03X\n", pwm_getInitValue(PWM3), pwm_getToggleCount(PWM3));

  //}

}

Message was edited by: Thomas Younsi

1 Solution
lock attach
Attachments are accessible only for community members.

I did some modifications to include 3 LEDs turning on in response to an interrupt at P0 (sw2 of my tag4). For example:

At start,

R=0, B=1, G=0

Interrupt,

R=0, B=0, G=1

Interrupt,

R=1, B=0, G=0, and so on.

See the attached pix and source. If I have time, I will try out the dimming.

led.JPG

View solution in original post

6 Replies
JaeyoungY_71
Employee
Employee
First comment on KBA 25 solutions authored 10 solutions authored

Hello Thomas,

I'm afraid I do not understand your issue here. What are you having trouble with? Are you asking us to verify your state machine?

Thanks,

Jaeyoung

0 Likes

It doesn't work the green led is not turned off when toggling off and then

toggling blue...

0 Likes

Have you done unit testing? Does your green led toggle on and off when you are not toggling the blue?

0 Likes

Yes It can blink

When I toggle green off and blue on green is left in dimmed state...

0 Likes
lock attach
Attachments are accessible only for community members.

I did some modifications to include 3 LEDs turning on in response to an interrupt at P0 (sw2 of my tag4). For example:

At start,

R=0, B=1, G=0

Interrupt,

R=0, B=0, G=1

Interrupt,

R=1, B=0, G=0, and so on.

See the attached pix and source. If I have time, I will try out the dimming.

led.JPG

Thanks. I don't use interrupt but the 1000 ms interval timer to toggle.

Would it e be the reason why the line gets messed up over time.

You are using interrupt because you are using a button to toggle isn't it ?

0 Likes