6 Replies Latest reply on May 25, 2017 7:41 AM by thomas.younsi_2228536

    Issue Blinking 3 led using PWM on dual bonded pin

    thomas.younsi_2228536

      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