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

Activating PWM and 4MHz clock signal from GPIO

Hello

I am using nRF51822 Nordic controller, SDK 9 and S130 Soft-Device. I have used to generate a 1 KHz PWM signal successfully using timer 1. And generating a 4 MHz clock signal from GPIO using timer 2 also succeeded.

Each trial alone

But when I decided to combine both signal PWM and 4 MHz to work together, unfortunately only the 4 MHz signal was generated however PWM never!

Is there anyone have faced the same problem and has an idea for help?

In the following code PWM and 4Mhz are generated, only 4Mhz was probed!

		APP_PWM_INSTANCE(PWM1,1);                   // Create the instance "PWM1" using TIMER1.

		static volatile bool ready_flag;            // A flag indicating PWM status.

		void pwm_ready_callback(uint32_t pwm_id)    // PWM callback function
		{
			ready_flag = true;
		}
		//-------------------------------
		static void gpiote_init(void)
		{
			// Configure GPIO_OUTPUT_PIN_NUMBER as an output.
			nrf_gpio_cfg_output(CLK_PIN);

			// 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_configure(0, CLK_PIN, \
								   NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
		}

		static void timer2_init()
		{
			// 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;       // Set the timer in Timer Mode.
			NRF_TIMER2->PRESCALER   = 0;                          
			NRF_TIMER2->BITMODE     = TIMER_BITMODE_BITMODE_16Bit<< TIMER_BITMODE_BITMODE_Pos; // 16 bit mode.
			NRF_TIMER2->TASKS_CLEAR = 1;
			NRF_TIMER2->CC[0]       = 2;
			NRF_TIMER2->EVENTS_COMPARE[0] = 0;
			NRF_TIMER2->SHORTS    =
				(TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);
		}

		static void ppi_init(void)
		{
			// Configure PPI channel 0 to toggle GPIO_OUTPUT_PIN on every TIMER2 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[0];

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

		/**@brief Application main function.
		 */
		int main(void)
		{
			uint32_t err_code;
			bool erase_bonds;
			uint8_t  start_string[] = START_STRING;
			
			// Initialize.
			APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false);
			uart_init();
			buttons_leds_init(&erase_bonds);
			ble_stack_init();
			gap_params_init();
			services_init();
			advertising_init();
			conn_params_init();
			
			// PWM Block
			////////////////////////////
			/* 2-channel PWM, 200Hz, output on DK LED pins. */
			app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_1CH(1000L, CONV_PIN);
			
			/* Switch the polarity of the second channel. */
			pwm1_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;
			
			/* Initialize and enable PWM. */
			err_code = app_pwm_init(&PWM1,&pwm1_cfg,pwm_ready_callback);
			app_pwm_enable(&PWM1);
				while (app_pwm_channel_duty_set(&PWM1, 0, 50) == NRF_ERROR_BUSY);
				
			uint32_t value;
			/* Set the duty cycle - keep trying until PWM is ready... */
			while (app_pwm_channel_duty_set(&PWM1, 0, 50) == NRF_ERROR_BUSY);
			////////////////////////////
			
			// Timer Blocck
			////////////////////////////////////
			// configure TIMER2
			timer2_init();

			// configure PPI
			ppi_init();

			// configure GPIOTE
			gpiote_init();

			NRF_TIMER2->TASKS_START = 1;  // Start event generation.
			///////////////////////////////
			printf("%s",start_string);

			err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
			APP_ERROR_CHECK(err_code);
			///////////////////////////////
				
			// Enter main loop.
			for (;;)
			{
				power_manage();
			}
		}
Related