Page 1 of 1

How to use STM32L152 COMP

Posted: Tue Dec 06, 2022 3:21 am
by radar_macgyver
I wish to use the COMP peripheral in an STM32L152RE to generate an interrupt. From other posts on the forum, I had found out about ChibiOS-Contrib, and the existence of a COMPv1 peripheral there. It looks like that LLD does not support the STM32L152 (it's meant for L0xx devices). I'm able to initialize the hardware with the following:

Code: Select all

   rccEnableAPB1(RCC_APB1ENR_COMPEN, TRUE);
   palSetPadMode(GPIOB, 4, PAL_MODE_INPUT_ANALOG);
   RI->ASCR2 = RI_ASCR2_GR6_1; /* Non-inv input is connected to PB4 */
   COMP->CSR =
      COMP_CSR_SPEED | /* Fast comparator */
      COMP_CSR_OUTSEL_2 | COMP_CSR_OUTSEL_1 | COMP_CSR_OUTSEL_0 | /* Output not redirected */
      COMP_CSR_INSEL_2 | COMP_CSR_INSEL_1; /* Inverted input connected to DAC_OUT_1 */

I can read COMP->CSR and see that COMP_CSR_CMP2IN changes state when PB4 value changes voltage. I'm stuck figuring out the interrupt part. From the RM, the COMP output is connected to EXTI line 21. The EXT driver is marked as obsolete, so what's the way forward?

Re: How to use STM32L152 COMP

Posted: Tue Dec 06, 2022 8:11 am
by Giovanni
Hi,

Now there is an STM32-specific helper driver under /os/hal/ports/STM32/LLD/EXTIv1 which also defines ISRs.

Unfortunately the driver is not yet enabled on the L1 because it is in "do not touch legacy thing" mode...

It should be simple to enable it if you want to give it a try, relevant files are stm32_isr.c/h under /os/hal/ports/STM32/STM32L1xx, compare them with the L4 ones and you should get it working, it just needs adding some definitions and include some files.

Giovanni

Re: How to use STM32L152 COMP

Posted: Tue Dec 06, 2022 10:24 pm
by radar_macgyver
Thank you Giovanni, I looked up the relevant information in the EXTIv1 peripheral and wrote the following:

Code: Select all

#define STM32_COMP_NUMBER 22
#define STM32_COMP_HANDLER Vector98
OSAL_IRQ_HANDLER(STM32_COMP_HANDLER)
{
   OSAL_IRQ_PROLOGUE();

   /* Clear the pending IRQ by writing a 1 */
   EXTI->PR |= ~(EXTI_PR_PR22);
   cmp_int_flag++;

   OSAL_IRQ_EPILOGUE();
}

void init_comp(void)
{
   rccEnableAPB1(RCC_APB1ENR_COMPEN, TRUE);
   palSetPadMode(GPIOB, 4, PAL_MODE_INPUT_ANALOG);
   RI->ASCR2 = RI_ASCR2_GR6_1; /* Non-inv input is connected to PB4 */
   COMP->CSR =
      COMP_CSR_SPEED | /* Fast comparator */
      COMP_CSR_OUTSEL_2 | COMP_CSR_OUTSEL_1 | COMP_CSR_OUTSEL_0 | /* Output not redirected */
      COMP_CSR_INSEL_2 | COMP_CSR_INSEL_1; /* Inverted input connected to DAC_OUT_1 */

   EXTI->RTSR |= EXTI_RTSR_TR22; /* Enable rising edge interrupt on COMP2 */
   EXTI->FTSR |= EXTI_FTSR_TR22; /* Enable rising edge interrupt on COMP2 */
   EXTI->IMR |= EXTI_IMR_MR22; /* Enable line 22, connected to COMP2 */

   nvicEnableVector(STM32_COMP_NUMBER, 7);
}

It seems like the EXTI peripheral in the STM32L152 has different registers than what the EXTIv1 code expected, for example EXTIv1 expected registers PR1 and PR2, while the hardware only contains a single register PR. Anyway, the above works as expected, and I can see the value of cmp_int_flag increase as I induce transitions on the COMP2 input.

Re: How to use STM32L152 COMP

Posted: Wed Dec 07, 2022 6:18 am
by Giovanni
Hi,

Those are differences in ST headers naming, PR1 is exactly the same PR register. Look at this "fix" in stm32_exti.h:

Code: Select all

/* Handling differences in ST headers.*/
#if !defined(STM32H7XX) && !defined(STM32L4XX) && !defined(STM32L4XXP) &&   \
    !defined(STM32G0XX) && !defined(STM32G4XX) && !defined(STM32WBXX) &&    \
    !defined(STM32WLXX)
#define EMR1    EMR
#define IMR1    IMR
#define PR1     PR
#define RTSR1   RTSR
#define FTSR1   FTSR
#endif


Probably you just need to add STM32L1xx among those others. If this works for you then I will add the change.

Giovanni

Re: How to use STM32L152 COMP

Posted: Fri Dec 09, 2022 3:01 am
by radar_macgyver
I added STM32_EXTI_REQUIRED to my halconf.h, even though this is normally something that's used by device drivers. After that, instead of directly writing the EXTI registers as I had previously, I could call

Code: Select all

extiEnableLine(22, EXTI_MODE_RISING_EDGE | EXTI_MODE_FALLING_EDGE | EXTI_MODE_ACTION_INTERRUPT);

The code behaves as before.

Also, in stm32_exti.h, the tests check if various MCU families that define PR1 and PR2 are *not* present, so that test is true for the STM32L1xx. I verified by adding a '#error' there, and the compiler was triggered on that error (I'm sure there's a more elegant way, though!)

Is the call to extiEnableLine considered deprecated? It seems like no other code in ChibiOS calls it.

Re: How to use STM32L152 COMP

Posted: Fri Dec 09, 2022 8:28 am
by Giovanni
Hi,

It is not deprecated.

Giovanni