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
}