This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How can I get an 8 MHz (PWM) signal out of a GPIO line?

I'm trying to just set up a Timer for 8 MHz frequency and have that output on a pin. It seems simple but I'm having some problems (the frequency is a lot lower). What am I doing wrong?

See code (I'm using the Soft Device). I imagine we only need to this:

main.c

#include "allneededheadersofcourse.h" // :)

#define PWM_OUTPUT_PIN_NUMBER (LED0) /*!< Pin number for PWM output / #define TIMER_PRESCALER 0U /!< Prescaler setting for timer */

/** Initializes Timer 2 peripheral. / static void pwm_timer_init(void) { / Start 16 MHz crystal oscillator */ uint32_t p_is_running;

sd_clock_hfclk_request();
do
{
	sd_clock_hfclk_is_running(&p_is_running);
} while (p_is_running == 0);

NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer; NRF_TIMER2->PRESCALER = TIMER_PRESCALER;

// Clears the timer, sets it to 0 NRF_TIMER2->TASKS_CLEAR = 1;

NRF_TIMER2->CC[2] = 1; }

/** Initializes GPIO Tasks/Events peripheral. */ static void pwm_gpiote_init(void) { // Configure PWM_OUTPUT_PIN_NUMBER as output nrf_gpio_cfg_output(PWM_OUTPUT_PIN_NUMBER);

// Configure GPIOTE channel 0 to toggle the PWM pin state // Note that we can only connect one GPIOTE task to an output pin nrf_gpiote_task_config(0, PWM_OUTPUT_PIN_NUMBER, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW); }

/** Initializes Programmable Peripheral Interconnect peripheral. */ static void pwm_ppi_init(void) { sd_ppi_channel_assign(PPI_CHEN_CH2_Pos, (uint32_t)&NRF_TIMER2->EVENTS_COMPARE[2], (uint32_t)&NRF_GPIOTE->TASKS_OUT[0]); sd_ppi_channel_enable_set(PPI_CHEN_CH2_Enabled << PPI_CHEN_CH2_Pos); }

/**

  • @brief Application main function.
  • @details Initializes the system and enters the main loop\
  • @param None
  • @return None */ int main(void) { pwm_gpiote_init(); pwm_ppi_init(); pwm_timer_init();

NRF_TIMER2->TASKS_START = 1;

while(1) { }

Thank you!!!

Gil

  • Have you seen this?

    Beware of PAN item 33, that causes it to not be possible to get an 8 MHz clock out of first revision chips. On second revision chips this is however not a problem, and the example works as-is.

    Edit: When I took a little closer look on your code, I see that you check call softdevice functions without checking error codes. That's a scary thing to do, especially when you haven't enabled the softdevice. No softdevice functions can be used when the softdevice is not enabled, and they all return 0x02, NRF_ERROR_SOFTDEVICE_NOT_ENABLED, meaning they have no effect. Lesson to be learned: Always check error codes when calling softdevice functions! :-)

    Also, you seem to lack the shortcut to clear the timer on CC, i.e. a line similar to this.

  • Thanks Ole! I will use that example on GitHub.

    This "Simple PWM" example (modified) came from a Nordic employee, including the lack of error checking on SD calls for the PPI, but he said it wasn't an "official Nordic example". :-)

    In my real code I initialize the SD first.

    Thanks again!

Related