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

timr1 or timer2 for PPI

test the gpiote_example for timer0 in pca10003, the function is ok, LED blinking 200ms. but I change the timer0 to timer1 or timer2, the LED always on,and never blinking. what is the problem? the source code is atteched!

#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
#include "nrf_gpiote.h"
#include "nrf_gpio.h"
#include "boards.h"


#define GPIO_OUTPUT_PIN_NUMBER LED_0  /**< Pin number for PWM output. */
#define GPIOTE_CHANNEL_NUMBER  0      /**< GPIOTE channel number. */


/** @brief Function for initializing the GPIO Tasks and Events peripheral.
*/
static void gpiote_init(void)
{
    // Configure GPIO_OUTPUT_PIN_NUMBER as an output.
    nrf_gpio_cfg_output(GPIO_OUTPUT_PIN_NUMBER);

    // Configure GPIOTE_CHANNEL_NUMBER to toggle the GPIO pin state with input.
    // @note Only one GPIOTE task can be coupled to an output pin.
    nrf_gpiote_task_config(GPIOTE_CHANNEL_NUMBER, GPIO_OUTPUT_PIN_NUMBER, \
                           NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
}

/** @brief Function for initializing Programmable Peripheral Interconnect (PPI) peripheral.
*   The PPI is needed to convert the timer event into a task.
 */
static void ppi_init(void)
{
    // Configure PPI channel 0 to toggle GPIO_OUTPUT_PIN on every TIMER0 COMPARE[0] match (200 ms)
    NRF_PPI->CH[0].EEP = (uint32_t)&NRF_TIMER2->EVENTS_COMPARE[0];
    NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[GPIOTE_CHANNEL_NUMBER];

    // Enable PPI channel 0
    NRF_PPI->CHEN = (PPI_CHEN_CH0_Enabled << PPI_CHEN_CH0_Pos);
}


/** @brief Function for initializing the Timer 0 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.
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) 
    {
        // Do nothing.
    }

    // Clear TIMER0
//		NRF_TIMER2->POWER = TIMER_POWER_POWER_Enabled;
    NRF_TIMER2->TASKS_CLEAR = 1;

    // Configure TIMER0 for compare[0] event every 200 ms.
    NRF_TIMER2->PRESCALER = 4;                // Prescaler 4 results in 1 tick equals 1 microsecond.
    NRF_TIMER2->CC[0]     = 200*1000UL;       // 1 tick equals 1µ , multiply by 1000 for ms value.
    NRF_TIMER2->MODE      = TIMER_MODE_MODE_Timer;
    NRF_TIMER2->BITMODE   = TIMER_BITMODE_BITMODE_24Bit;
    NRF_TIMER2->SHORTS    = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);
}


/**
 * @brief Function for application main entry.
 */
int main(void)
{
    gpiote_init();                // Configure a GPIO to toggle on a GPIOTE task.
    timer2_init();                // Use TIMER0 to generate events every 200 ms.
    ppi_init();                   // Use a PPI channel to connect the event to the task automatically.

    NRF_TIMER2->TASKS_START = 1;  // Start event generation.

    while (true)
    {
        // Do Nothing - GPIO can be toggled without software intervention.
    }
}
  • This is because the bit-width for timer1 and 2 is only 16 bit, as opposed to timer0 which goes to 32 bit. See nRF51822 Product Specification section 4.2.

    You set the CC[0] register to 200*1000 = 200000, which requires more than 16 bits, so the counter never reaches the compare value. The maximum compare value for 16 bits is 0xFFFF (= 65535).

    These values for CC and PRESCALER should give the same result:

    NRF_TIMER0->PRESCALER = 6;
    NRF_TIMER0->CC[0]     = 50000UL;
    
Related