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

How many pwm channels can capture?

Hello: I want use nrf51822's time/ppi/gpiote to capture the pwm rising/falling range duty.I want to know the most numbers of pwm channels duty parameters it can capture? The more the better. Thank you! PS:Now I've already capture PWM1 by pin1 and PWM2 by pin2.

static void gpiote_init(void)

{

// Configure port1 (pins 8-15) as outputs for showing duty cycle.
//nrf_gpio_range_cfg_output(LED_START, LED_STOP);

nrf_gpio_cfg_sense_input(INPUT_PIN_NUMBER, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);

// Enable interrupt on input 1 event.
NRF_GPIOTE->INTENSET = (GPIOTE_INTENSET_IN1_Enabled << GPIOTE_INTENSET_IN1_Pos);

nrf_gpiote_event_config(0, INPUT_PIN_NUMBER, NRF_GPIOTE_POLARITY_HITOLO);
	nrf_gpiote_event_config(1, INPUT_PIN_NUMBER, NRF_GPIOTE_POLARITY_LOTOHI);

  nrf_gpio_cfg_sense_input(8, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
NRF_GPIOTE->INTENSET = (GPIOTE_INTENSET_IN3_Enabled << GPIOTE_INTENSET_IN3_Pos);	
nrf_gpiote_event_config(2,8, NRF_GPIOTE_POLARITY_HITOLO);
	nrf_gpiote_event_config(3, 8, NRF_GPIOTE_POLARITY_LOTOHI);

}

static void ppi_init(void)

{

NRF_PPI->CH[0].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[0];
NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TIMER1->TASKS_CAPTURE[0];

NRF_PPI->CH[1].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[1];
NRF_PPI->CH[1].TEP = (uint32_t)&NRF_TIMER1->TASKS_CAPTURE[1];

  NRF_PPI->CH[2].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[2];
NRF_PPI->CH[2].TEP = (uint32_t)&NRF_TIMER2->TASKS_CAPTURE[0];

NRF_PPI->CH[3].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[3];
NRF_PPI->CH[3].TEP = (uint32_t)&NRF_TIMER2->TASKS_CAPTURE[1];
// Enable only PPI channels 0 and 1.
NRF_PPI->CHEN = (PPI_CHEN_CH0_Enabled << PPI_CHEN_CH0_Pos)
              | (PPI_CHEN_CH1_Enabled << PPI_CHEN_CH1_Pos)
								|	(PPI_CHEN_CH2_Enabled << PPI_CHEN_CH2_Pos)
              | (PPI_CHEN_CH3_Enabled << PPI_CHEN_CH3_Pos);

}

void GPIOTE_IRQHandler(void)

{

static uint32_t prev_cc1_pin1 = 0;
uint32_t curr_cc1_pin1;
uint32_t cycle_duration_pin1;
uint32_t duty_cycle_pin1;
uint32_t active_time_pin1;
  static uint32_t prev_cc1_pin0 = 0;
uint32_t curr_cc1_pin0;
uint32_t cycle_duration_pin0;
uint32_t duty_cycle_pin0;
uint32_t active_time_pin0;
	if((NRF_GPIOTE->EVENTS_IN[1]==1)&& (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN1_Msk))
	{		
curr_cc1_pin1 = NRF_TIMER1->CC[1];  
// Cycle duration is the difference between two low-to-high transitions.
cycle_duration_pin1 = (curr_cc1_pin1 - prev_cc1_pin1); 

active_time_pin1 = cycle_duration_pin1 - ((curr_cc1_pin1 - NRF_TIMER1->CC[0]));

if (cycle_duration_pin1 != 0)
{
    duty_cycle_pin1 = (DUTY_CYCLE_SCALE_VALUE * active_time_pin1) / cycle_duration_pin1;
    //nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, (uint8_t)duty_cycle_pin1);
			printf("%d\n\r",duty_cycle_pin1);
}
else
{
    // Do nothing.
}

// Clear the event causing the interrupt.
NRF_GPIOTE->EVENTS_IN[1] = 0;    
prev_cc1_pin1                 = curr_cc1_pin1;
}
else if((NRF_GPIOTE->EVENTS_IN[3]==1)&& (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN3_Msk))
{
		curr_cc1_pin0 = NRF_TIMER2->CC[1];  
		// Cycle duration is the difference between two low-to-high transitions.
		cycle_duration_pin0 = (curr_cc1_pin0 - prev_cc1_pin0); 
		
		active_time_pin0 = cycle_duration_pin0 - ((curr_cc1_pin0 - NRF_TIMER2->CC[0]));

		if (cycle_duration_pin0 != 0)
		{
				duty_cycle_pin0 = (DUTY_CYCLE_SCALE_VALUE * active_time_pin0) / cycle_duration_pin0;
				//nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, (uint8_t)duty_cycle_pin0);
				printf("%d\n\r",duty_cycle_pin0);
		}
		else
		{
				// Do nothing.
		}

		// Clear the event causing the interrupt.
		NRF_GPIOTE->EVENTS_IN[3] = 0;    
		prev_cc1_pin0                 = curr_cc1_pin0;
}

}

static void timer1_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_TIMER1->MODE        = TIMER_MODE_MODE_Timer;
NRF_TIMER1->PRESCALER   = 4;
NRF_TIMER1->BITMODE     = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
NRF_TIMER1->TASKS_CLEAR = 1;
NRF_TIMER1->TASKS_START = 1; // Start clocks

}

static void timer2_init(void)

{

NRF_TIMER2->MODE        = TIMER_MODE_MODE_Timer;
NRF_TIMER2->PRESCALER   = 4;
NRF_TIMER2->BITMODE     = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
NRF_TIMER2->TASKS_CLEAR = 1;
NRF_TIMER2->TASKS_START = 1; // Start clocks

}

Related