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

Comparator PPI timer counter issue

Hi,

SDK 16 using board NRF58240dk. PCA 10056. Segger studio on windows.

I am trying to read a current pulse train from a peripheral device. This device outputs a 4mA pulse when it is giving data. This data is handled inside of a statemachine using the number of pulses found to determine where in the pulse train the sensor is.

I therefore, need to read the number of current pulses which ranges from 0 to 4096. To do this I have used this example and modified it (from the nordic support example code : https://devzone.nordicsemi.com/f/nordic-q-a/53139/nrf52-calculation-method-between-rising-edges/217208#217208)

I then have tried to configure the counting to be running off the lpcomp as this should be determining if the input from the sensor is above 4mA. But my counter value is never incrementing and this is therefore  stopping my statemachine from running.

I believe this is a configuration issue please could someone resolve this.

How do I link the counter with the comparator output.  I have attached my main code below. Omitting the statemachine as I need the pulse count readings first.

void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
    NRF_LOG_INFO("H");
}

void timer_handler_count(nrf_timer_event_t event_type, void * p_context)
{
    
}

void timer_handler_read(nrf_timer_event_t event_type, void * p_context)
{
    uint32_t count = nrf_drv_timer_capture_get(&m_timer_count, NRF_TIMER_CC_CHANNEL0);
    /*if(count > 0)
    {
        NRF_LOG_INFO("C: %d",count);
    }*/
    Timer_counter = count;//Set the count value
}

/**
 * @brief Function for configuring: PIN_IN pin for input sensing change this to use the comparator
 */
static void gpiote_init(void)
{
    ret_code_t err_code;

    err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);//Alter this
    in_config.pull = NRF_GPIO_PIN_PULLDOWN;
    
    err_code = nrf_drv_gpiote_in_init(NRF_LPCOMP -> RESULT,&in_config, in_pin_handler);//Using the result of the LP comp?
    APP_ERROR_CHECK(err_code);

    //err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, in_pin_handler);
    //APP_ERROR_CHECK(err_code);
    nrf_drv_gpiote_in_event_enable(NRF_LPCOMP -> RESULT,false);//Enable to GPIOTE
    //nrf_drv_gpiote_in_event_enable(PIN_IN, false);
}

void timer_init()//Function to start the timers
{
    ret_code_t err_code;

    // Configure TIMER1 for counting of low to high events on GPIO
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
    timer_cfg.mode = NRF_TIMER_MODE_LOW_POWER_COUNTER;//Mode is set to a low power counter in nrf_timer.h Line 190
    err_code = nrf_drv_timer_init(&m_timer_count, &timer_cfg, timer_handler_count);
    APP_ERROR_CHECK(err_code);

    // Configure TIMER2 for reading the counter timer at a given interval COUNT_READ_INTERVAL
    timer_cfg.mode = NRF_TIMER_MODE_TIMER;
    err_code = nrf_drv_timer_init(&m_timer_read, &timer_cfg, timer_handler_read);
    APP_ERROR_CHECK(err_code);
    
    uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer_read, COUNT_READ_INTERVAL);
    nrf_drv_timer_extended_compare(&m_timer_read,
                                   NRF_TIMER_CC_CHANNEL0,
                                   ticks,
                                   NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                   true);
    nrf_drv_timer_enable(&m_timer_read);
}

void ppi_init()
{
    ret_code_t err_code;

    err_code = nrf_drv_ppi_init();
    APP_ERROR_CHECK(err_code);
    
    err_code = nrf_drv_ppi_channel_alloc(&ppi_channel_1);
    APP_ERROR_CHECK(err_code);
    
    err_code = nrf_drv_ppi_channel_alloc(&ppi_channel_2);
    APP_ERROR_CHECK(err_code);
    
    uint32_t gpiote_evt_addr_1              = nrf_drv_gpiote_in_event_addr_get(NRF_LPCOMP -> RESULT);
    //uint32_t gpiote_evt_addr_1              = nrf_drv_gpiote_in_event_addr_get(PIN_IN);
    uint32_t timer_count_count_task_addr    = nrf_drv_timer_task_address_get(&m_timer_count, NRF_TIMER_TASK_COUNT);
    uint32_t timer_count_capture_task_addr  = nrf_drv_timer_task_address_get(&m_timer_count, NRF_TIMER_TASK_CAPTURE0);
    uint32_t timer_count_clear_task_addr    = nrf_drv_timer_task_address_get(&m_timer_count, NRF_TIMER_TASK_CLEAR);
    
    uint32_t timer_read_compare_event_addr  = nrf_drv_timer_event_address_get(&m_timer_read, NRF_TIMER_EVENT_COMPARE0);
    
    
    err_code = nrf_drv_ppi_channel_assign(ppi_channel_1,
                                          gpiote_evt_addr_1,
                                          timer_count_count_task_addr); // Trigger timer count task when GPIOTE pin go from low to high.

    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_assign(ppi_channel_2,
                                          timer_read_compare_event_addr,
                                          timer_count_capture_task_addr); // Capture counter timer using PPI to make sure this is not delayed by BLE interrupt
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_fork_assign(ppi_channel_2,
                                               timer_count_clear_task_addr); // Clear counter timer using PPI to make sure this is not delayed by BLE interrupt
    APP_ERROR_CHECK(err_code);
    

    err_code = nrf_drv_ppi_channel_enable(ppi_channel_1);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_ppi_channel_enable(ppi_channel_2);
    APP_ERROR_CHECK(err_code);
}
//Comparator
/**
 * @brief LPCOMP event handler is called when LPCOMP detects voltage drop.
 *
 * This function is called from interrupt context so it is very important
 * to return quickly. Don't put busy loops or any other CPU intensive actions here.
 * It is also not allowed to call soft device functions from it (if LPCOMP IRQ
 * priority is set to APP_IRQ_PRIORITY_HIGH).
 */
static void lpcomp_event_handler(nrf_lpcomp_event_t event)
{
    if (event == NRF_LPCOMP_EVENT_DOWN)
    {
        //bsp_board_led_invert(BSP_BOARD_LED_0); // just change state of first LED
        voltage_falls_detected++;
        voltage_falls_total++;
    }
}
/**
 * @brief Initialize LPCOMP driver.
 */
static void lpcomp_init(void)
{
    uint32_t                err_code;

    //nrf_drv_lpcomp_config_t config = NRF_DRV_LPCOMP_DEFAULT_CONFIG;
    //config.input = NRF_LPCOMP_INPUT_2;//Use this as the input pin
    
    //Configuring lpcomp
    NRF_LPCOMP -> PSEL = (LPCOMP_PSEL_PSEL_AnalogInput2 << LPCOMP_PSEL_PSEL_Pos);//Use analog input 2 as an input P04
    NRF_LPCOMP -> EXTREFSEL = (LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference0 << LPCOMP_EXTREFSEL_EXTREFSEL_Pos);//Set up external reference 0 P02
    NRF_LPCOMP -> REFSEL = (LPCOMP_REFSEL_REFSEL_ARef << LPCOMP_REFSEL_REFSEL_Pos);//Use external reference
    NRF_LPCOMP -> ANADETECT = (LPCOMP_ANADETECT_ANADETECT_Cross << LPCOMP_ANADETECT_ANADETECT_Pos);//Detect a change over the reference upon crossing the reference
    
    //Enable and start the low power comparator
    NRF_LPCOMP -> ENABLE = LPCOMP_ENABLE_ENABLE_Enabled;
    NRF_LPCOMP -> TASKS_START = 1;
    //Then need to get the result

    // initialize LPCOMP driver, from this point LPCOMP will be active and provided
    // event handler will be executed when defined action is detected
    //err_code = nrf_drv_lpcomp_init(&config, lpcomp_event_handler);
    //APP_ERROR_CHECK(err_code);
    //nrf_drv_lpcomp_enable();
}


/**
 * @brief Function for application main entry.
 */
int main(void)
{
    uint32_t err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);
    uint16_t newTimeMs,oldTimeMs,elapsedMs;
    NRF_LOG_DEFAULT_BACKENDS_INIT();//Start the logging
    lpcomp_init();//Start the low power comparator
    gpiote_init();//Configure the GPIO task
    timer_init();//Start the timers
    ppi_init();//Start the PPI
    bsp_board_init(BSP_INIT_LEDS);//Inits onboard leds
    NRF_LOG_INFO("Example start\r\n");
    NRF_LOG_PROCESS();
    //Configure the sensor power GPIO
    nrf_gpio_pin_clear(Sensor_Power);//Set the sensor pin low P1.08
    nrf_gpio_cfg_output(30);
    nrf_gpio_pin_clear(30);
    
    while (1)
    {
        newTimeMs = countMs;   // Cache live value from IRQ
        elapsedMs = newTimeMs-oldTimeMs;
        oldTimeMs = newTimeMs;  // Ready for next time
        Read_Sensors(elapsedMs);  // Read the current pulse train and get the data
        //NRF_LOG_PROCESS();
        //nrf_delay_ms(100);
        //nrf_gpio_pin_toggle(30);
        /*
        while(NRF_LOG_PROCESS() == true);
        // Testing pin change (connect GPIO P0.30 to P0.28). This is not accurate, as log processing can take some time, but will show that example works.
        nrf_delay_ms(100);
        nrf_gpio_pin_toggle(30);
        */

    }
}

Thanks

Parents Reply Children
No Data
Related