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

unable to use low-power comparator

I'm trying to use the low-power comparator. 

I've started up the comparator using "lpcomp_init()".

Following that, I wish to have a sample event, and then log the result register. I can tie the pin to 0 or 1, so I should be able to change the input and see the RESULT register change in the log. Can you let me know what this code is missing?

=====   extract from main starts here  =======

NRF_LOG_INFO("start comparator set-up.");
lpcomp_init(); // turn on low power comparator.

while(1)
{
NRF_LPCOMP->TASKS_SAMPLE = 1; // cause a sample event for the op amp
nrf_delay_ms(1); // short delay
uint32_t lpcomp_result_register = NRF_LPCOMP->RESULT; // read result

NRF_LOG_INFO("comp: %d", lpcomp_result_register); // log result
NRF_LOG_FLUSH();
}

Thanks,

Stephen

Parents
  • What is the gpio and lpcomp configuration? 

    why are you not using the event handler? 

    Why are you manually sampling the lpcomp instead of letting it run by itself? 


  • The LPCOMP configuration is set with P0.02/AIN0 as the comparator input.

    Here is most of LPCOMP section in sdk_config.h:

    ==================================


    //==========================================================
    // <e> LPCOMP_ENABLED - nrf_drv_lpcomp - LPCOMP peripheral driver - legacy layer
    //==========================================================
    #ifndef LPCOMP_ENABLED
    #define LPCOMP_ENABLED 1
    #endif
    // <o> LPCOMP_CONFIG_REFERENCE - Reference voltage

    // <0=> Supply 1/8
    // <1=> Supply 2/8
    // <2=> Supply 3/8
    // <3=> Supply 4/8
    // <4=> Supply 5/8
    // <5=> Supply 6/8
    // <6=> Supply 7/8
    // <8=> Supply 1/16 (nRF52)
    // <9=> Supply 3/16 (nRF52)
    // <10=> Supply 5/16 (nRF52)
    // <11=> Supply 7/16 (nRF52)
    // <12=> Supply 9/16 (nRF52)
    // <13=> Supply 11/16 (nRF52)
    // <14=> Supply 13/16 (nRF52)
    // <15=> Supply 15/16 (nRF52)
    // <7=> External Ref 0
    // <65543=> External Ref 1

    #ifndef LPCOMP_CONFIG_REFERENCE
    #define LPCOMP_CONFIG_REFERENCE 3
    #endif

    // <o> LPCOMP_CONFIG_DETECTION - Detection

    // <0=> Crossing
    // <1=> Up
    // <2=> Down

    #ifndef LPCOMP_CONFIG_DETECTION
    #define LPCOMP_CONFIG_DETECTION 2
    #endif

    // <o> LPCOMP_CONFIG_INPUT - Analog input

    // <0=> 0
    // <1=> 1
    // <2=> 2
    // <3=> 3
    // <4=> 4
    // <5=> 5
    // <6=> 6
    // <7=> 7

    #ifndef LPCOMP_CONFIG_INPUT
    #define LPCOMP_CONFIG_INPUT 0
    #endif

    // <q> LPCOMP_CONFIG_HYST - Hysteresis

    #ifndef LPCOMP_CONFIG_HYST
    #define LPCOMP_CONFIG_HYST 0
    #endif

    // <o> LPCOMP_CONFIG_IRQ_PRIORITY - Interrupt priority

    // <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
    // <0=> 0 (highest)
    // <1=> 1
    // <2=> 2
    // <3=> 3
    // <4=> 4
    // <5=> 5
    // <6=> 6
    // <7=> 7

    #ifndef LPCOMP_CONFIG_IRQ_PRIORITY
    #define LPCOMP_CONFIG_IRQ_PRIORITY 6
    #endif

    // </e>

    // <e> NRFX_LPCOMP_ENABLED - nrfx_lpcomp - LPCOMP peripheral driver
    //==========================================================
    #ifndef NRFX_LPCOMP_ENABLED
    #define NRFX_LPCOMP_ENABLED 1
    #endif
    // <o> NRFX_LPCOMP_CONFIG_REFERENCE - Reference voltage

    // <0=> Supply 1/8
    // <1=> Supply 2/8
    // <2=> Supply 3/8
    // <3=> Supply 4/8
    // <4=> Supply 5/8
    // <5=> Supply 6/8
    // <6=> Supply 7/8
    // <8=> Supply 1/16 (nRF52)
    // <9=> Supply 3/16 (nRF52)
    // <10=> Supply 5/16 (nRF52)
    // <11=> Supply 7/16 (nRF52)
    // <12=> Supply 9/16 (nRF52)
    // <13=> Supply 11/16 (nRF52)
    // <14=> Supply 13/16 (nRF52)
    // <15=> Supply 15/16 (nRF52)
    // <7=> External Ref 0
    // <65543=> External Ref 1

    #ifndef NRFX_LPCOMP_CONFIG_REFERENCE
    #define NRFX_LPCOMP_CONFIG_REFERENCE 3
    #endif

    // <o> NRFX_LPCOMP_CONFIG_DETECTION - Detection

    // I would like no detection here.
    // <0=> Crossing
    // <1=> Up
    // <2=> Down

    #ifndef NRFX_LPCOMP_CONFIG_DETECTION
    #define NRFX_LPCOMP_CONFIG_DETECTION 2
    #endif

    // <o> NRFX_LPCOMP_CONFIG_INPUT - Analog input

    // <0=> 0
    // <1=> 1
    // <2=> 2
    // <3=> 3
    // <4=> 4
    // <5=> 5
    // <6=> 6
    // <7=> 7

    #ifndef NRFX_LPCOMP_CONFIG_INPUT
    #define NRFX_LPCOMP_CONFIG_INPUT 0
    #endif

    // <q> NRFX_LPCOMP_CONFIG_HYST - Hysteresis

    #ifndef NRFX_LPCOMP_CONFIG_HYST
    #define NRFX_LPCOMP_CONFIG_HYST 0
    #endif

    // <o> NRFX_LPCOMP_CONFIG_IRQ_PRIORITY - Interrupt priority

    // <0=> 0 (highest)
    // <1=> 1
    // <2=> 2
    // <3=> 3
    // <4=> 4
    // <5=> 5
    // <6=> 6
    // <7=> 7

    #ifndef NRFX_LPCOMP_CONFIG_IRQ_PRIORITY
    #define NRFX_LPCOMP_CONFIG_IRQ_PRIORITY 6
    #endif

    ==============================================

    I have not made any changes to the GPIO settings. Is there a change that I need to apply to the GPIO settings to connect the pin with the comparator?

    As far as sampling the pin manually, I would like to verify that I have proper operation before moving to a level sense. In addition, I am going to let a time period (maybe 1 ms) pass. During that time period, I will sample the signal and count how many samples are low during that time. 

    "Letting it run by itself" - I assume this means moving my counter into the ISR. I want the sampling to be counter-based (not event-based), and I want to be sampling as fast as possible.

    It also might be a good idea for me to move this to the COMP (not the low-power comp) so that I get a faster response time from the comparator.

    Please advise on the above. I think it makes sense to be sampling the way that I want, and I appreciate your help on getting this working.

    Thanks,

    crengineer393

Reply
  • The LPCOMP configuration is set with P0.02/AIN0 as the comparator input.

    Here is most of LPCOMP section in sdk_config.h:

    ==================================


    //==========================================================
    // <e> LPCOMP_ENABLED - nrf_drv_lpcomp - LPCOMP peripheral driver - legacy layer
    //==========================================================
    #ifndef LPCOMP_ENABLED
    #define LPCOMP_ENABLED 1
    #endif
    // <o> LPCOMP_CONFIG_REFERENCE - Reference voltage

    // <0=> Supply 1/8
    // <1=> Supply 2/8
    // <2=> Supply 3/8
    // <3=> Supply 4/8
    // <4=> Supply 5/8
    // <5=> Supply 6/8
    // <6=> Supply 7/8
    // <8=> Supply 1/16 (nRF52)
    // <9=> Supply 3/16 (nRF52)
    // <10=> Supply 5/16 (nRF52)
    // <11=> Supply 7/16 (nRF52)
    // <12=> Supply 9/16 (nRF52)
    // <13=> Supply 11/16 (nRF52)
    // <14=> Supply 13/16 (nRF52)
    // <15=> Supply 15/16 (nRF52)
    // <7=> External Ref 0
    // <65543=> External Ref 1

    #ifndef LPCOMP_CONFIG_REFERENCE
    #define LPCOMP_CONFIG_REFERENCE 3
    #endif

    // <o> LPCOMP_CONFIG_DETECTION - Detection

    // <0=> Crossing
    // <1=> Up
    // <2=> Down

    #ifndef LPCOMP_CONFIG_DETECTION
    #define LPCOMP_CONFIG_DETECTION 2
    #endif

    // <o> LPCOMP_CONFIG_INPUT - Analog input

    // <0=> 0
    // <1=> 1
    // <2=> 2
    // <3=> 3
    // <4=> 4
    // <5=> 5
    // <6=> 6
    // <7=> 7

    #ifndef LPCOMP_CONFIG_INPUT
    #define LPCOMP_CONFIG_INPUT 0
    #endif

    // <q> LPCOMP_CONFIG_HYST - Hysteresis

    #ifndef LPCOMP_CONFIG_HYST
    #define LPCOMP_CONFIG_HYST 0
    #endif

    // <o> LPCOMP_CONFIG_IRQ_PRIORITY - Interrupt priority

    // <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
    // <0=> 0 (highest)
    // <1=> 1
    // <2=> 2
    // <3=> 3
    // <4=> 4
    // <5=> 5
    // <6=> 6
    // <7=> 7

    #ifndef LPCOMP_CONFIG_IRQ_PRIORITY
    #define LPCOMP_CONFIG_IRQ_PRIORITY 6
    #endif

    // </e>

    // <e> NRFX_LPCOMP_ENABLED - nrfx_lpcomp - LPCOMP peripheral driver
    //==========================================================
    #ifndef NRFX_LPCOMP_ENABLED
    #define NRFX_LPCOMP_ENABLED 1
    #endif
    // <o> NRFX_LPCOMP_CONFIG_REFERENCE - Reference voltage

    // <0=> Supply 1/8
    // <1=> Supply 2/8
    // <2=> Supply 3/8
    // <3=> Supply 4/8
    // <4=> Supply 5/8
    // <5=> Supply 6/8
    // <6=> Supply 7/8
    // <8=> Supply 1/16 (nRF52)
    // <9=> Supply 3/16 (nRF52)
    // <10=> Supply 5/16 (nRF52)
    // <11=> Supply 7/16 (nRF52)
    // <12=> Supply 9/16 (nRF52)
    // <13=> Supply 11/16 (nRF52)
    // <14=> Supply 13/16 (nRF52)
    // <15=> Supply 15/16 (nRF52)
    // <7=> External Ref 0
    // <65543=> External Ref 1

    #ifndef NRFX_LPCOMP_CONFIG_REFERENCE
    #define NRFX_LPCOMP_CONFIG_REFERENCE 3
    #endif

    // <o> NRFX_LPCOMP_CONFIG_DETECTION - Detection

    // I would like no detection here.
    // <0=> Crossing
    // <1=> Up
    // <2=> Down

    #ifndef NRFX_LPCOMP_CONFIG_DETECTION
    #define NRFX_LPCOMP_CONFIG_DETECTION 2
    #endif

    // <o> NRFX_LPCOMP_CONFIG_INPUT - Analog input

    // <0=> 0
    // <1=> 1
    // <2=> 2
    // <3=> 3
    // <4=> 4
    // <5=> 5
    // <6=> 6
    // <7=> 7

    #ifndef NRFX_LPCOMP_CONFIG_INPUT
    #define NRFX_LPCOMP_CONFIG_INPUT 0
    #endif

    // <q> NRFX_LPCOMP_CONFIG_HYST - Hysteresis

    #ifndef NRFX_LPCOMP_CONFIG_HYST
    #define NRFX_LPCOMP_CONFIG_HYST 0
    #endif

    // <o> NRFX_LPCOMP_CONFIG_IRQ_PRIORITY - Interrupt priority

    // <0=> 0 (highest)
    // <1=> 1
    // <2=> 2
    // <3=> 3
    // <4=> 4
    // <5=> 5
    // <6=> 6
    // <7=> 7

    #ifndef NRFX_LPCOMP_CONFIG_IRQ_PRIORITY
    #define NRFX_LPCOMP_CONFIG_IRQ_PRIORITY 6
    #endif

    ==============================================

    I have not made any changes to the GPIO settings. Is there a change that I need to apply to the GPIO settings to connect the pin with the comparator?

    As far as sampling the pin manually, I would like to verify that I have proper operation before moving to a level sense. In addition, I am going to let a time period (maybe 1 ms) pass. During that time period, I will sample the signal and count how many samples are low during that time. 

    "Letting it run by itself" - I assume this means moving my counter into the ISR. I want the sampling to be counter-based (not event-based), and I want to be sampling as fast as possible.

    It also might be a good idea for me to move this to the COMP (not the low-power comp) so that I get a faster response time from the comparator.

    Please advise on the above. I think it makes sense to be sampling the way that I want, and I appreciate your help on getting this working.

    Thanks,

    crengineer393

Children
  • You need to configure the GPIO pin as an input pin prior to enabling the LPCOMP, and you need to start the LPCOMP with the START task.

    I suggest you read LPCOMP — Low power comparator and GPIO — General purpose input/output, and study the LPCOMP example. 
     

    crengineer393 said:
    "Letting it run by itself" - I assume this means moving my counter into the ISR. I want the sampling to be counter-based (not event-based), and I want to be sampling as fast as possible.

    What do you mean by counter-based?



    You can disable an interrupt with the INTENCLR register. I suggest you use the driver as intended, but disable the interrupt for whatever detection you use, i.e do not disable the READY event interrupt. That way you can sample the LPCOMP manually after it has been properly set up. 

  • I'm now using the event handler to look at the comparator events. After I run lpcomp_init:

    =======

    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_0;
    // 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();
    }

    =======

    I can change AIN0 from GND to VDD, and I get confirmation that "lpcomp_event_handler" has run.

    The issue is that it only does it once. I would like to get notification of events each time they occur. I'm not seeing the flag that I need to reset to get the event handler to operate repeatedly.

    Here is the event_handler code:

    ========

    static void lpcomp_event_handler(nrf_lpcomp_event_t event)
    {
    NRF_LOG_INFO("lpcomp event handler");
    NRF_LOG_FLUSH();
    if (event == NRF_LPCOMP_EVENT_DOWN)
    {
    NRF_LOG_INFO("down event");
    NRF_LOG_FLUSH();
    bsp_board_led_invert(BSP_BOARD_LED_0); // just change state of first LED
    voltage_falls_detected++;
    voltage_falls_total++;
    }
    }

    ========

    Thanks for your help.

  • Hmm, that's strange, what SDK are you using? 

    Either the interrupt is not cleared or has been disabled, or the EVENTS_DOWN is not cleared or triggered. 

    Can you read out the state of the LPCOMP's EVENTS_DOWN and INTENSET register after you've initialized the LPCOMP and in the first LPCOMP event handler?

  • I am using njRF5_SDK_16.0.0_9810832

    I have added the log

    EVENTS_DOWN = 0;

    INTENSET = 2

    Thanks for your help. I will looking into EVENTS_DOWN set-up.

    Stephen

  • Comparator seems to be working now. The "lpcomp_event_handler" was not happy with LOG_INFO() and FLUSH_LOG() inside of it. I think the log statements were causing a lock-up.

Related