ADC interrupt limit settings

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
JuSe_4659276
Employee
Employee

Dear Cypress Developer Community,

I am trying to do a simple application using the PSoC 6 BLE Pionner Kit (CY8CKIT-062-BLE) & PSoC Creator 4.3 (+ CyDWR) in which a distance sensor should trigger an interrupt when the value read is above a certain value, meaning the distance sensor is measuring a very short distance, let´s say, for example, 3 cm.

The distance sensor is working fine, I can read the value that it returns in volts and I can turn it into distance.

Unfortunately, I am not capable of correctly setting the interrupt limits and I am not sure how to do it. I found plenty of examples about interrupts, but none with this specific one. I am also following the instructions and information on the SAR ADC Component Datasheet and AN217666, but without success.

As soon as the debugger passes the NVIC_EnableIRQ line, the code jumps into the ISR_1_handler() function regardless of the position of the distance sensor or anything else, as the line Cy_SAR_GetResults16() comes later. In the ISR_1_handler() function, at the moment, I just blink a LED (and call the NVIC_ClearPendingIRW), so I guess it is just the setting of the ADC that it is wrong.

I also tried different “compare modes” and “low” and “high” values and checked the register values in ADC.h, but nothing seems to change. Sorry if the question seems too obvious, but any ideas on what could be wrong in here? Any example/sample code or description available?

Attached are pictures showing the CyDWR setting of the ADC, that I would expect to trigger the interrupt if the value read is above 1.65 V and some lines of code.

Many thanks,

Juan

0 Likes
1 Solution
Vasanth
Moderator
Moderator
Moderator
250 sign-ins 500 solutions authored First question asked

Hi  Juan,,

Add similar check in your ISR handler to solve the issue.

/* Scenario: Range detection has been enabled for at least one channel.

  * Check the range interrupt status in the ISR when an interrupt occurs. */

   uint32_t intr_status = 0u;

  /* Read the range detection interrupt status register. */

  intr_status = Cy_SAR_GetRangeInterruptStatus(SAR);

  if (intr_status > 0u)

  {

  /* One or more channels triggered the range detection interrupt, do something here. */

  }

  /* Clear the handled range interrupt. */

  Cy_SAR_ClearRangeInterrupt(SAR, intr_status);

  /* Perform a dummy read of the range interrupt status register for buffered writes. */

  (void)Cy_SAR_GetRangeInterruptStatus(SAR);

Best Regards,
Vasanth

View solution in original post

0 Likes
5 Replies
Vasanth
Moderator
Moderator
Moderator
250 sign-ins 500 solutions authored First question asked

Hi Juan,

1. Inside the ISR you can have check the interrupt status register (intrStatus = Cy_SAR_GetInterruptStatus(SAR); ) to verify whether the interrupt was originated due to end of conversion or due to some other reason. Based on the result using an if condition you choose what to happen on each type of interrupt. You just have to check the range bit in the register to confirm whether the interrupt is triggered due to that.

2. In the for loop you can call the ADC_IsEndConversion API with CY_SAR_WAIT_FOR_RESULT parameter before calling the y_SAR_GetResults16() API. This is to make sure that you are reading the value after conversion as the ADC is running in continuous sample mode.

Best Regards,
Vasanth

0 Likes
Vasanth
Moderator
Moderator
Moderator
250 sign-ins 500 solutions authored First question asked

Hi  Juan,,

Add similar check in your ISR handler to solve the issue.

/* Scenario: Range detection has been enabled for at least one channel.

  * Check the range interrupt status in the ISR when an interrupt occurs. */

   uint32_t intr_status = 0u;

  /* Read the range detection interrupt status register. */

  intr_status = Cy_SAR_GetRangeInterruptStatus(SAR);

  if (intr_status > 0u)

  {

  /* One or more channels triggered the range detection interrupt, do something here. */

  }

  /* Clear the handled range interrupt. */

  Cy_SAR_ClearRangeInterrupt(SAR, intr_status);

  /* Perform a dummy read of the range interrupt status register for buffered writes. */

  (void)Cy_SAR_GetRangeInterruptStatus(SAR);

Best Regards,
Vasanth

0 Likes

Thank you for the responses!

I am trying to implement the changes you propose. I started with the original code. In this case I can see some status different than 0, but I am trying to analyse, what does this mean.

In this example I get:

-Cy_SAR_GetInterruptStatus(SAR) returns 0x03

-Cy_SAR_GetRangeInterruptStatus(SAR); returns 0x01

I also found a similar question in the community (Re: ADC SAR SEQ interrupt triggering continuously irrespective of threshold limit set!!) that I also want to study, because it describes a similar behaviour. Sorry I didn´t see this before.

Later, I also tried some changes and even an alternative project using the Thermistor instead of the distance sensor, but no success in setting the interrupt limits yet. I will send more messages later today or next monday.

Best Regards,

Juan

0 Likes
Vasanth
Moderator
Moderator
Moderator
250 sign-ins 500 solutions authored First question asked

Hi Juan,

Use the second code snippet I have provided. I have tested it at my end. You have to make sure that the limit in range interrupt is set proper and the range values are proper. Then in the code snippet keep the LED blink functionality inside if (intr_status > 0u) then you can achieve the functionality.

Best Regards,
Vasanth

0 Likes

Thank you very much, VasanthR_91!

Yes, I think today morning I had one problem in the hardware, because when I connected the sensor again, it was working perfectly with the code provided!

For reference (taken from the header in cy_sar.h)

  • /*******************************************************************************

    * Function Name: Cy_SAR_GetRangeInterruptStatus

    ****************************************************************************//**

    *

    * Return the range interrupt register status.

    * If the status bit is low for a channel, the channel may not be enabled

    * (\ref Cy_SAR_SetChanMask), range detection is not enabled for the

    * channel (\ref Cy_SAR_SetRangeInterruptMask), or range detection was not

    * triggered for the channel.

    *

    * \param base

    * Pointer to structure describing registers

    *

    * \return

    * The range interrupt status for all channels. Bit 0 is for channel 0, etc.

    *

    * \funcusage

    *

    * \snippet sar_sut_01.cydsn/main_cm0p.c SNIPPET_SAR_GET_RANGE_INTERRUPT_STATUS

    *

    *******************************************************************************/

0 Likes