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

Comparator External Connections

I am attempting to use the COMP section to build a relaxation oscillator. There appear to be a number of interactions between sections, some of which are subtly documented and some for which I find no documentation. For instance, the inability to set a GPIO output once a task is connected to a pin is documented but well-hidden. The fact that enabling a pin as a comparator input completely disables both digital inputs and digital outputs is not documented anywhere that I can find.

Bottom line is that I have everything working nicely as it should, except that the comparator sometimes appears to miss a transition and thereafter is hung. I fundamentally just need to be able to place the comparator output on a digital output pin, but the only way I can find to do that is via the crossing events from the comparator, feeding set and clr tasks of GPIOTE. This causes the same sort of problems as the early IBM PCs using edge-triggered interrupts: If you miss one, you're dead forever. Is there a better way to get the comparator output to appear on a pin? If not, how best can I initialize things to ensure that I don't miss a transition?

Parents
  • Hi, I'm doing the same thing - I'm building an RC generator that involves the COMP module.

    So far I haven't seen any glitches, so I decided to share my init code:

    #define CONFIG_COMP_OUT_PIN 28
    
    static nrf_ppi_channel_t m_ppi_channel;
    
    nrfx_comp_config_t const comp_config = {
    	    .reference = NRF_COMP_REF_VDD,
    	    .ext_ref = NRF_COMP_EXT_REF_7, //P0.31
    	    .main_mode = NRF_COMP_MAIN_MODE_SE,
    	    .threshold = {
    	    		.th_up = 34,
    				.th_down = 30
    	    },
    	    .speed_mode = NRF_COMP_SP_MODE_Low,
    	    .hyst = NRF_COMP_HYST_50mV,
    	    .isource = NRF_COMP_ISOURCE_Off, 
    	    .input = NRF_COMP_INPUT_1, //P0.03
    	    .interrupt_priority = 0
    };
    
    void nrfx_comp_irq_handler(void){
    
    }
    
    void init(void){
    	uint32_t gpiote_task_addr;
    	uint32_t comp_event_addr;
    
    	nrfx_comp_init(&comp_config, nrfx_comp_irq_handler);
    	nrfx_comp_start(NRFX_COMP_EVT_EN_CROSS_MASK, 0);
    
    	nrf_drv_ppi_init();
    
    	nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);
        nrf_drv_gpiote_out_init(CONFIG_COMP_OUT_PIN, &config);
    
    	nrf_drv_ppi_channel_alloc(&m_ppi_channel);
    
    	comp_event_addr = nrf_drv_comp_event_address_get(NRF_COMP_EVENT_CROSS);
    	gpiote_task_addr = nrf_drv_gpiote_out_task_addr_get(CONFIG_COMP_OUT_PIN);
    
    	nrf_drv_ppi_channel_assign(m_ppi_channel, comp_event_addr, gpiote_task_addr);
    	nrf_drv_ppi_channel_enable(m_ppi_channel);
    
    	nrf_drv_gpiote_out_task_enable(CONFIG_COMP_OUT_PIN);
    	nrf_drv_gpiote_set_task_trigger(CONFIG_COMP_OUT_PIN); //Start oscillations
    }

    I have inputs on P0.03 (-) and P0.31 (+), and an output on P0.28 (OUT) with this code.

    Hope this helps!

    Regards,

    L. B.

    p.s. My target is NRF52832 / nRF5_SDK_17.0.2_d674dde / gcc version 10.3.1 20210621 (release) (GNU Arm Embedded Toolchain 10.3-2021.07)

  • I started this thread several years ago, indeed I've forgotten what project was involved. It came up in a search just now, completely different project.

    I need to set up the comparator to use an external reference, with hysteresis specified by the TH register. That is, I need the thresholds to be proportional to an external voltage, but with the up and down thresholds significantly separated. The documentation is not very clear as to exactly how to set that up. I have tried a lot of combinations of HYST, TH, REFSEL, EXTREFSEL, etc, and can't seem to get what I need. Hints?

  • Unfortunately, I have no installation of the Nordic SDK at the moment. And I only used the nrfx library, so I have no experience on a register level. By looking at the datasheet, I can theorize that you can turn on/off a small hysteresis of 50 mV with the HYST register. I guess this is for the differential input of the operational amplifier (like setting the input offset voltage to 50 mV). My guess is that you would have to use external resistors and implement a classical Schmitt trigger circuit. 

  • I can, if I must, use the 50 mV hysteresis with an external reference voltage. But the best I can do so far, whether diff or SE, etc., is to have switching at 150 mV & 350 mV. None of the register settings seem to have any influence.

  • A closer read of the datasheet shows that, counterintuitively, I must run the comparator in single-ended mode to accomplish what I want. It appears to work correctly with REFSEL set to 4 (Vdd) and adjusting the values in the TH registers works as expected - except that they must be kept close to their limits. I can live with that. But according to the DS I should be able to set REFSEL to 7 (ext ref) and then select an ADC pin to use as the reference. I have an external voltage calibrator connected to my selected AinX pin, but even with the calibrator voltage set the same as Vdd (3.3V), I don't get any action from the comparator. There is no value given in the datasheet for AREFMIN - the only reference to that value is under REFSEL.

    It would be most helpful to have an actual schematic of what's going on inside the chip, because not all of the registers have the stated effects.

Reply
  • A closer read of the datasheet shows that, counterintuitively, I must run the comparator in single-ended mode to accomplish what I want. It appears to work correctly with REFSEL set to 4 (Vdd) and adjusting the values in the TH registers works as expected - except that they must be kept close to their limits. I can live with that. But according to the DS I should be able to set REFSEL to 7 (ext ref) and then select an ADC pin to use as the reference. I have an external voltage calibrator connected to my selected AinX pin, but even with the calibrator voltage set the same as Vdd (3.3V), I don't get any action from the comparator. There is no value given in the datasheet for AREFMIN - the only reference to that value is under REFSEL.

    It would be most helpful to have an actual schematic of what's going on inside the chip, because not all of the registers have the stated effects.

Children
  • The above works only if I select 4 (Vdd) for Vref. Per datasheet Figure 112: Comparator in single-ended mode, I should be able to feed Vref via Ain7 by selecting REFSEL 7 and EXTREFSEL 7. Even if I feed the same voltage as Vcc (external voltage calibrator), I can't get it to run correctly. Has anyone actually used these documented features of the COMP? Do they actually work? Nothing in the errata to suggest a problem.

  • Further (strange) info. I accidentally blipped 5V into Ain7, and things started working unexpectedly. Without doing that, only 4 (Vref = Vdd) works, and only if TH up & down are kept near the rails. But if I select other values for REFSEL, start it up, then blip Ain7 to 5V momentarily and back to 3V, I get the following results for the stated values of REFSEL:

    0 - 1.2V ref
    1 - 1.8V ref
    2 - 2.4V ref
    3 - 3.0V ref <<<<<undocumented
    4 - Vdd ref
    5 - no action
    6 - no action
    7 - no action <<<<<should use the AinX pin selected by EXTREFSEL

    I know about the parasitic clamp diodes, but why should smacking Vdd with a gentle nudge start COMP working? My voltage calibrator signal "overload" at 5V, so clearly the clamp diodes are doing there thing.

  • Careful on the clamp diodes they'll take very little. You should never see 5V on a scope as the pin will be Vcc+0.3v max otherwise it's passing current to Vcc through the ESD diode. 5V will be a big current and will blow them. Use a resistor ;)

    "I need to set up the comparator to use an external reference"

    I think you've already got what I was about to say which is do it the other way around, internal reference and external input, single ended, and adjust the lower&upper limits (these are basically acting as configurable hysteresis).

    I can't really understand what you're trying to do. If the input is 3v+ then refsel 0-3 won't work. Vdd will work if the chip is getting more than 3v. Same with Adc pin but remember Vdd must be greater than Adc pin voltage.

    Of course Vdd might be noisy, that's the whole point to the Adc ref pin. Maybe you should just do the normal thing of using refsel 0-2 and dropping the 3v+ down with a voltage divider (aka two resistors). Any reason why you haven't? For sure you need to if it gives to 5v!

    * I have guessed you're using an NRF52 series.

  • Slight misunderstanding on the 5V. I have no intention of running there. This was just an accidental, momentary, and current-limited blip to 5V that caused an unexpected event. After it happened it, I reported it as a potential troubleshooting clue.

    Likewise RefSel 3V was a coincidental discovery as I tried all values of REFSEL. Again no intention of using it.

    COMP works just as documented for all values of REFSEL except the one I really need to use, which is 7 - ExtRef. I'm also thinking there's something I'm not understanding correctly, in that the hysteresis using the other reference choices works only if I keep the limits near min & max; i.e. UP at 0x38 or above, and DN at 0x04 or below. Also why it doesn't work when I set ExtRef (on Ain7) to the same 3.3V as Vdd. REFSEL = 4 works, REFSEL = 7 does not, regardless of TH settings.

  • I just discovered this erratum. So, Nordic is just going to throw up their hands and say I bought a pig in a poke?!? I'm glad I didn't actually lay out a board based on the chip working as advertised!

    3.33 [113] COMP: Single-ended mode with external
    reference is not functional
    This anomaly applies to Revision 2, build codes CIAA-Ex0, QFAA-Ex0, QFAB-Ex0.
    It was inherited from the previous IC revision Revision 1.
    Symptoms
    COMP output is not correct.
    Conditions
    COMP is used in single-ended mode with external reference.
    Consequences
    COMP cannot be used in this mode.
    Workaround
    None.

Related