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

COMP + PPI + TIMER

Hello there!

My project use comparator, timer capture and pwm to measure capacity of line.

The purpose is to encounter open circuit condition. So this does not require fine measuring with ADC .

I use COMP in differential mode, positive line is input from pwm controlled line (open drain), negative line is 3/4 of input voltage.

Comparator down event is connected to timer2 start task when comparator up event is connected to timer capture event.

After all peripherals is ready I fire pwm and then I waiting for timer compare interrupt (its enabled) to get the result.

The problem is this worked for me at first. But now does not.

Comparator events are set but timer does not starts.

Please help!

NRF_PPI_Type * ppi = NRF_PPI;
NRF_TIMER_Type * tim2 = NRF_TIMER2;
NRF_COMP_Type * cmp = NRF_COMP;

/////// init
ppi->CHENCLR= (1<<3);   // Disable ppi channel 3
ppi->CH[3].EEP= (uint32_t)&(cmp->EVENTS_DOWN);
ppi->CH[3].TEP= (uint32_t)&(tim2->TASKS_START);
ppi->CHENSET= (1<<3);   // Enable ppi channel 3

ppi->CHENCLR= (1<<4);   // Disable ppi channel 4
ppi->CH[4].EEP= (uint32_t)&(cmp->EVENTS_UP);
ppi->CH[4].TEP= (uint32_t)&(tim2->TASKS_CAPTURE[1]);
ppi->CHENSET= (1<<4);   // Enable ppi channel 4

//! COMP
cmp->REFSEL= 5; // ARef
cmp->EXTREFSEL= 0; // Mux In
cmp->MODE= 256|2; // High speed, Differential mode
//cmp->SHORTS= 8; // COMP UP->STOP
cmp->ENABLE= 0;

//! TIMER
tim2->SHORTS = 256; // Stop on compare (channel 0)
tim2->CC[0]= 16000;
tim2->PRESCALER= 1; // Divide by 2
tim2->MODE= 1; // Timer mode
tim2->BITMODE= 0; // 16bit timer
tim2->TASKS_START = 0;
NVIC_SetPriority(TIMER2_IRQn, 4);
NVIC_EnableIRQ(TIMER2_IRQn);

/////// Use
cmp->EVENTS_READY= 0;
cmp->EVENTS_DOWN= 0;
cmp->EVENTS_UP= 0;
cmp->ENABLE= 2;
cmp->PSEL= SAADC_CH_PSELP_PSELP_AnalogInput2-1;
tim2->INTENSET= (1 << TIMER_INTENSET_COMPARE0_Pos);
cmp->TASKS_START= 1;
__disable_irq();
pwmSetValue(PWM_MAX_VALUE-10);
nrf_delay_us(250); // Ставить таймер на половину шим периода и ждать здесь его переполнение
pwmSetValue(PWM_MAX_VALUE);
__enable_irq();

/////// TIMER ISR
cmp->ENABLE= 0;
tim2->INTENCLR= (1 << TIMER_INTENCLR_COMPARE0_Pos);
result= (tim2->CC[1]>0)?(0):(1);
tim2->EVENTS_COMPARE[0]= 0;
tim2->TASKS_STOP= 1;
tim2->TASKS_CLEAR= 1;

I removed all unrelated code and I don't use SDK

Related