Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 4 of 4

Thread: Failing to get Analog Comparator to work

  1. #1

    Failing to get Analog Comparator to work

    I am trying to use the built-in analog comparator functionality to work for my purposes. I wrote the below code:

    Code:
        CCM_CCGR3 |= CCM_CCGR3_ACMP3(CCM_CCGR_ON);
        CCM_CCGR3 |= CCM_CCGR3_ACMP4(CCM_CCGR_ON);
    
        attachInterruptVector(IRQ_ACMP3, ACMP3_ISR);
        attachInterruptVector(IRQ_ACMP4, ACMP4_ISR);
    
                //  Filter     Hysteresis Level
        CMP3_CR0 = (3 << 4) | (1 << 0);
        CMP3_FPR = 15; //# of bus cycles per sample interval (480Mhz bus clock I believe)
                    //IER      //IEF
        CMP3_SCR = (1 << 4) | (1 << 3);
        CMP3_DACCR = 0; //DAC disabled
                  // PSEL(40)   MSEL(39)
        CMP3_MUXCR = (3 << 3) + (6 << 0);
                //Sampling  Hi Speed  Enable ACMP
        CMP3_CR1 = (1<<7) | (1<<4) |  (1 << 0);
    
                //  Filter     Hysteresis Level
        CMP4_CR0 = (3 << 4) | (1 << 0);
        CMP4_FPR = 15; //# of bus cycles per sample interval (480Mhz bus clock) 480/15 = 32MHz
                    //IER      //IEF
        CMP4_SCR = (1 << 4) | (1 << 3);
        CMP4_DACCR = 0; //DAC disabled
                //   PSEL(17)   MSEL(41)
        CMP4_MUXCR = (1 << 3) + (3 << 0);
                //Sampling  Hi Speed  Enable ACMP
        CMP4_CR1 = (1<<7) | (1<<4) |  (1 << 0);
    
        NVIC_ENABLE_IRQ(IRQ_ACMP3);
        NVIC_ENABLE_IRQ(IRQ_ACMP4);
    The problem is, no interrupts fire. I am sending 600mV sine wave signals (approx 40mv to 640mv so always positive) on both pins which are out of phase to each other so I should be getting triggers but I don't. I am trying to do this with a function generator attached to pins 39 and 40 (and ground). The input is OK but no interrupt. Obviously I'm missing something in the configuration but I can't seem to figure out what. Do I need to actually have a pin output in order for the interrupt to fire? I'm not setting up an output pin because I'd really rather not waste a physical pin on a signal that I only need internally to the processor. I suppose maybe I ought to go ahead and configure the default ACMP3 output pin just to see if it is changing state, at least for debugging. But, it seems like I really must have something else wrong.

  2. #2
    I figured out the nature of my ignorance. For posterity: in the CR1 register I enabled sampling (1<<7). I had it in my head that this meant it would sample the input in discrete chunks and output the state accordingly. What it actually means is that I want to use an external sampling signal. I wasn't providing an external sampling signal so no sampling took place. All I really needed to do was set up CR0 to set the # of samples that must match in a row and hysteresis then set FPR to the number of bus clocks to filter the signals over. This is essentially what I had wanted by setting "sampling mode" above. So, the bottom line is that I just misunderstood the documentation and set an improper bit. There is no need to actually enable the COUT pin. It will interrupt just fine without toggling an actual pin. I can confirm that the ACMP hardware works perfectly fine if I program it properly.

  3. #3
    Junior Member
    Join Date
    Jan 2021
    Posts
    1
    I am also trying to get the comparator to work on Teensy 4. Will it be possible for you to post the piece of code after you made the correction?
    Thank you.

  4. #4
    Here is my full setup routine for ACMP as it currently sits:

    Code:
        //make sure the cycle counter register is active
        ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; 
    
        CCM_CCGR3 |= CCM_CCGR3_ACMP3(CCM_CCGR_ON);
        CCM_CCGR3 |= CCM_CCGR3_ACMP4(CCM_CCGR_ON);
    
        attachInterruptVector(IRQ_ACMP3, ACMP3_ISR);
        attachInterruptVector(IRQ_ACMP4, ACMP4_ISR);
    
        //level  typ      max     (hysteresis voltage)
        //00 =   1        2mv
        //1 =    21       54mv
        //2 =    42       108mv
        //3 =    64       184mv
    
        //ACMP uses IPG_CLK_ROOT which seems to perhaps be CPU clock / something.
        //It appears that the teensy core tries its best to set IPG clock to 150Mhz which is the 600MHz CPU clock / 4
    
                //  Filter     Hysteresis Level
        CMP3_CR0 = (2 << 4) | (1 << 0);
        CMP3_FPR = 2; //# of bus cycles per sample interval (150MHz clock?)
                    //IER      //IEF
        CMP3_SCR = (1 << 4) | (1 << 3);
        CMP3_DACCR = 0; //no need to use DAC
                  // (PSEL(40))   MSEL(39)
        CMP3_MUXCR = (3 << 3) + (6 << 0);
              //  Hi Speed   Enable ACMP
        CMP3_CR1 = (1<<4) |  (1 << 0);
    
                //  Filter     Hysteresis Level
        CMP4_CR0 = (2 << 4) | (1 << 0);
        CMP4_FPR = 2; //# of bus cycles per sample interval
                    //IER      //IEF
        CMP4_SCR = (1 << 4) | (1 << 3);
        CMP4_DACCR = 0; //DAC disabled
                //   PSEL(17)   MSEL(41)
        CMP4_MUXCR = (1 << 3) + (3 << 0);
                //  Hi Speed  Enable ACMP
        CMP4_CR1 =  (1<<4)   |  (1 << 0);
    
        NVIC_ENABLE_IRQ(IRQ_ACMP3);
        NVIC_ENABLE_IRQ(IRQ_ACMP4);

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •