This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

there is interference in pins used as output when I use BLE ???

Hello,

I am using a nrf51422 development kit with softdevice S310 and I have a problem in whatever pin I choose as output when I use the bluetooth.

I run the example ble_app_hts for nrf51822 but conditioned to be flashed in nrf51422. In this example, it is implemented a health thermometer profile and it works fine, but I've added to this code a little code to generate a clock signal and to send it to an output pin. The clock pulse works fine when I eliminate the "advertising_start()" line, but I can not connect with bluetooth when I eliminate it, obviously. But when advertising_start() is running, the clock pulse doesn't work fine, some times it stays high or low more time than needed.

So, someone can tell me why when bluetooth is working, there is interference in the output signal??? my code is the next:


int main(void)

{

// Initialize.
leds_init();
timers_init();
gpiote_init();
buttons_init();

ble_stack_init();
bond_manager_init();
gap_params_init();

advertising_init();
services_init();

sensor_sim_init();
conn_params_init();
sec_params_init();

// Start execution.
application_timers_start();
advertising_start();

// Enter main loop.
int contador=1;
for (;;)
{
    //power_manage();
		
		if (contador%2==1)
		{
			nrf_gpio_cfg_output(SALIDA);
			nrf_gpio_pin_set(SALIDA);
		}
		else
		{
			nrf_gpio_cfg_output(SALIDA);
			nrf_gpio_pin_clear(SALIDA);
		}
		contador++;
}

}

Parents
  • Read more about how softdevice works in S110_SoftDevice_Specification_v1.3A.pdf.

    It's because softdevice managing your advertising and every advertising event CPU goes from the main to the softdevice to send advertising packets so you some latency in the main.

  • and this is my code for timer to generate pwm

    //Define para TIMER

    #define PWM_OUTPUT_PIN_NUMBER (25)

    #define MAX_SAMPLE_LEVELS (256UL) /< Maximum number of sample levels. */ #define TIMER_PRESCALERS 6U /< Prescaler setting for timer. */ #define GPIOTE_CHANNEL_NUMBER_2 1

    ///// TIMER /////

    static __INLINE uint32_t next_sample_get(void) { static uint32_t sample_value = 8;

    // Read button input.
    sample_value = ((/*nrf_gpio_port_read(NRF_GPIO_PORT_SELECT_PORT0)*/0x000000BF) & 0x000000FFUL); // valor del ciclo de trabajo
    
    // This is to avoid having two CC events happen at the same time,
    // CC1 will always create an event on 0 so CC0 and CC2 should not.
    if (sample_value == 0) 
    {
        sample_value = 8;
    }
    
    return (uint32_t)sample_value;
    

    }

    /** @brief Function for handling timer 2 peripheral interrupts. */ void TIMER2_IRQHandler(void) { static bool cc0_turn = false; /**< Keeps track of which CC register to be used. */

    if ((NRF_TIMER2->EVENTS_COMPARE[1] != 0) && 
       ((NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE1_Msk) != 0))
    {
        // Sets the next CC1 value
        NRF_TIMER2->EVENTS_COMPARE[1] = 0;
        NRF_TIMER2->CC[1]             = (NRF_TIMER2->CC[1] + MAX_SAMPLE_LEVELS);
    
        // Every other interrupt CC0 and CC2 will be set to their next values.
        uint32_t next_sample = next_sample_get();
    
        if (cc0_turn)
        {
            NRF_TIMER2->CC[0] = NRF_TIMER2->CC[1] + next_sample;
        }
        else
        {
            NRF_TIMER2->CC[2] = NRF_TIMER2->CC[1] + next_sample;
        }
        // Next turn the other CC will get its value.
        cc0_turn = !cc0_turn;
    }
    

    }

    /** @brief Function for initializing the Timer 2 peripheral. */ static void timer2_init(void) { // Start 16 MHz crystal oscillator . NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->TASKS_HFCLKSTART = 1;

    // Wait for the external oscillator to start up.
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) 
    {
        //Do nothing.
    }
    
    NRF_TIMER2->MODE        = TIMER_MODE_MODE_Timer;
    NRF_TIMER2->BITMODE     = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
    NRF_TIMER2->PRESCALER   = TIMER_PRESCALERS;
    
    // Clears the timer, sets it to 0.
    NRF_TIMER2->TASKS_CLEAR = 1;
    
    // Load the initial values to TIMER2 CC registers.
    NRF_TIMER2->CC[0] = MAX_SAMPLE_LEVELS + next_sample_get();
    NRF_TIMER2->CC[1] = MAX_SAMPLE_LEVELS;
    
    // CC2 will be set on the first CC1 interrupt.
    NRF_TIMER2->CC[2] = 0;
    
    // Interrupt setup.
    NRF_TIMER2->INTENSET = (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos);
    

    } ///// TIMER /////

Reply
  • and this is my code for timer to generate pwm

    //Define para TIMER

    #define PWM_OUTPUT_PIN_NUMBER (25)

    #define MAX_SAMPLE_LEVELS (256UL) /< Maximum number of sample levels. */ #define TIMER_PRESCALERS 6U /< Prescaler setting for timer. */ #define GPIOTE_CHANNEL_NUMBER_2 1

    ///// TIMER /////

    static __INLINE uint32_t next_sample_get(void) { static uint32_t sample_value = 8;

    // Read button input.
    sample_value = ((/*nrf_gpio_port_read(NRF_GPIO_PORT_SELECT_PORT0)*/0x000000BF) & 0x000000FFUL); // valor del ciclo de trabajo
    
    // This is to avoid having two CC events happen at the same time,
    // CC1 will always create an event on 0 so CC0 and CC2 should not.
    if (sample_value == 0) 
    {
        sample_value = 8;
    }
    
    return (uint32_t)sample_value;
    

    }

    /** @brief Function for handling timer 2 peripheral interrupts. */ void TIMER2_IRQHandler(void) { static bool cc0_turn = false; /**< Keeps track of which CC register to be used. */

    if ((NRF_TIMER2->EVENTS_COMPARE[1] != 0) && 
       ((NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE1_Msk) != 0))
    {
        // Sets the next CC1 value
        NRF_TIMER2->EVENTS_COMPARE[1] = 0;
        NRF_TIMER2->CC[1]             = (NRF_TIMER2->CC[1] + MAX_SAMPLE_LEVELS);
    
        // Every other interrupt CC0 and CC2 will be set to their next values.
        uint32_t next_sample = next_sample_get();
    
        if (cc0_turn)
        {
            NRF_TIMER2->CC[0] = NRF_TIMER2->CC[1] + next_sample;
        }
        else
        {
            NRF_TIMER2->CC[2] = NRF_TIMER2->CC[1] + next_sample;
        }
        // Next turn the other CC will get its value.
        cc0_turn = !cc0_turn;
    }
    

    }

    /** @brief Function for initializing the Timer 2 peripheral. */ static void timer2_init(void) { // Start 16 MHz crystal oscillator . NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->TASKS_HFCLKSTART = 1;

    // Wait for the external oscillator to start up.
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) 
    {
        //Do nothing.
    }
    
    NRF_TIMER2->MODE        = TIMER_MODE_MODE_Timer;
    NRF_TIMER2->BITMODE     = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
    NRF_TIMER2->PRESCALER   = TIMER_PRESCALERS;
    
    // Clears the timer, sets it to 0.
    NRF_TIMER2->TASKS_CLEAR = 1;
    
    // Load the initial values to TIMER2 CC registers.
    NRF_TIMER2->CC[0] = MAX_SAMPLE_LEVELS + next_sample_get();
    NRF_TIMER2->CC[1] = MAX_SAMPLE_LEVELS;
    
    // CC2 will be set on the first CC1 interrupt.
    NRF_TIMER2->CC[2] = 0;
    
    // Interrupt setup.
    NRF_TIMER2->INTENSET = (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos);
    

    } ///// TIMER /////

Children
No Data
Related