5 Replies Latest reply on Jun 26, 2020 5:25 AM by MoTa_728816

    cannot clear interrupt

    HeGi_2497906

      We have a Bosch BMA253 Accelerometer generating interrupts for new data, I can clearly see the interrupts on the scope, image attached.

       

      IMG_20200625_203115.jpg

      We have a pin set with a dedicated interrupt, and we get data, we have an interrupt that will not clear, I get interrupted, even when my data sources tell me that there is no interrupt. 

       

      Also attached is a UART output of the data, and you can clearly see the many interrupts, but only a few with data, when I break on one it is always in the catch test where none of the accelerometer registers are validating the interrupt in the ISR below.

       

      Capture.PNG

       

       

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

      * Function Name: isr_Accel

      ********************************************************************************

      * Summary:

      *   interrupt service routine to the accelerometer interrupt.

      *   clear interrupt flag

      *   set the control flg

      *

      * Parameters: 

      *   void

      *

      * Return:

      *   void

      *

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

      CY_ISR(isr_ACCEL)

      {

          isr_Accel_Disable();

          isr_Accel_ClearPending();

          Accel_int_ClearInterrupt();

          accel1Flag = TRUE;

          DBG_PRINT_TEXT("\n\r Accel interrupt");

      }

       

       

      Here is a data trap, that will see that none of the accelerometer data registers have caused this interrupt, but that is the only external source.

      This is the ISR service code:

              /*==============================================================================*/

              // Lock

              /*==============================================================================*/ 

              if (accel1Flag)

              {

                 

                  accel1Flag = FALSE;

                  AccelReadByte(BMA253_STAT0_ADDR);

                  volatile uint8 temp1 = Accel_Byte;

                  if (( Accel_Byte & SLOPE_INT1 ) != FALSE )

                  {

                      if(BLE_Config[BLE_SWTYPE] == TWO_RELAY || BLE_Config[BLE_SWTYPE] == TWO_LIGHT)

                      {

                          isr_Accel_ClearPending();

                          Accel_int_ClearInterrupt();

                          isr_Accel_Enable();

                      }

                      else

                      {

                          //DBG_PRINT_TEXT("\n\r Undesired acceleration detected \n\r");

                          autoUnlockDuration = BLE_Config[BLE_AUTO_UNLOCK_DELAY] * 240;

                          deviceLocked = TRUE;

                          BLE_lockout = TRUE;

                          BLE_Config[BLE_lockout] = TRUE;

                          Readings[STATUS2] |= M_LOCK_STATUS2_MASK;

                          accel1Flag = FALSE;

                          Status = Status | MER;

                          displayTimeOut = displayReload;

                          BLE_Action = STOP;

                          BLE_PWM[0] = 0x00;

                          BLE_PWM[1] = 0x00;

                          PWM_1_WriteCompare(PWM_OFF);

                          PWM_2_WriteCompare(PWM_OFF);

                          //DBG_PRINT_TEXT("\n\r Device locked\n\r");

                      }

                  }

                   // if the bit is set and the device is not locked, the get data

                  AccelReadByte(BMA253_STAT1_ADDR);

                  volatile uint8 temp2 = Accel_Byte;

                  if (( Accel_Byte & DATA_READY_INT1 ) != FALSE && !deviceLocked)

                  {

                      AccelGetData();

                      isr_Accel_ClearPending();

                      Accel_int_ClearInterrupt();

                      isr_Accel_Enable();

                     

                  }

       

       

                  AccelReadByte(0x0B)       

         volatle uint8 temp3= Accel_Byte;

       

       

                  AccelReadByte(0x0C);

                  volatile uint8 temp4= Accel_Byte;           

                  /* trap for bad interrupts  all four interrupt source registers are false, why are we here!*/

                  // if all temps are false we are getting bad interrupts, this code can be removed for production.

                  if ( temp1 == FALSE && temp2 == FALSE && temp3== FALSE && temp4 == FALSE )

                  {

                      volatile uint32 temp7 = Accel_int_Read();

                      isr_Accel_ClearPending();

                      Accel_int_ClearInterrupt();

                      isr_Accel_Enable();

                  }

                }

       

       

      I cannot understand why the interrupt is firing all the time, when there should only be interrupts for the events shown on the scope, just under 10hz, what am I doing wrong?

       

      Bundle attached.

       

      Thanks for any help.

        • 1. Re: cannot clear interrupt
          MoTa_728816

          Hi,

           

          I tested your interrupt functions with CY8CKIT-044.

          I quoted your functions.

           

          As far as I tested, your function were working fine.

           

          So I would suspect

          (1) Actually there are interrupts from the sensor, when data is not ready

          (2) There may be a path in your if (accellFlag) { } block or somewhere else, which fails to clear interrupt but enables the isr again.

           

          schematic

          001-schematic.JPG

          TeraTerm log

          000-TeraTerm-log.JPG

           

          main.c

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

          #include "project.h"

          #include "stdio.h"

           

          #define STR_LEN 64

          char str[STR_LEN+1] ;

          void DBG_PRINT_TEXT(char *str)

          {

              UART_UartPutString(str) ;

          }

           

          #define TRUE 1u

          #define FALSE 0u

           

          volatile int accel1Flag = FALSE ;

           

          CY_ISR(isr_ACCEL)

          {

              isr_Accel_Disable();

              isr_Accel_ClearPending();

              Accel_int_ClearInterrupt();

              accel1Flag = TRUE;

              DBG_PRINT_TEXT("\n\r Accel interrupt");

          }

           

          void init_hardware(void)

          {

              CyGlobalIntEnable; /* Enable global interrupts. */

             

              UART_Start() ;

             

              // Start the Accel interrupt service routine

              isr_Accel_StartEx(isr_ACCEL);

              isr_Accel_ClearPending();

              Accel_int_SetInterruptMode( Accel_int_INTR_ALL,Accel_int_INTR_FALLING);

              Accel_int_ClearInterrupt();   

          }

           

          int main(void)

          {

              init_hardware() ;

             

              DBG_PRINT_TEXT("\x1b[2J\x1b[;H") ;

              DBG_PRINT_TEXT("PSoC 4 Interrupt Test (SW2)\n") ;

              snprintf(str, STR_LEN, "(%s %s)\n", __DATE__, __TIME__) ;   

              DBG_PRINT_TEXT(str) ;

           

              for(;;)

              {

                  if (accel1Flag) {

                      accel1Flag = FALSE ;

                      DBG_PRINT_TEXT("Interrupt!\n") ;

                      isr_Accel_ClearPending();

                      Accel_int_ClearInterrupt();

                      isr_Accel_Enable();

                  }

              }

          }

           

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

          • 2. Re: cannot clear interrupt
            HeGi_2497906

            Thank you for your response, as you can see by the scope, the interrupt is

            very regular and timed correctly.

            I suspected your number two from the start, but have spent alot time trying

            to isolate it and cannot find the interrupt source.

             

            Thank you again for your assistance,

            H

             

            Herb Gingold

            407-832-0501

            herb@rviqproducts.com

             

             

             

             

             

             

            On Thu, Jun 25, 2020 at 9:46 PM Motoo Tanaka <community-manager@cypress.com>

            • 3. Re: cannot clear interrupt
              MoTa_728816

              Dear Herb-san,

               

              I still have some suspect about the sensor that it may be generating interrupt(s), like very fine pulse(s).

              Will it be feasible, to disable the interrupt pin/signal after receiving some interrupts?

              Like pulling up the interrupt signal with resistor to VCC or physically disconnect the interrupt signal.

              If there will be no more interrupt, the sensor was generating some other interrupts.

              and if there will be still more interrupts... I wonder what I should do...

               

              Best Regards,

              26-Jun-2020

              Motoo Tanaka

              • 4. Re: cannot clear interrupt
                HeGi_2497906

                Motoo-san, domo arigato for the excellent suggestion, it did not solve the problem, but did isolate the issue to firmware of the PSoC4, if I take the Interrupt line (I cannot disconnect, but did pull directly to Vcc 3.3V) and tie to Vcc the interrupts pulses are overridden as you would expect, but the interrupts continue.  Again, flat line 3.3V interrupt line, yet the interrupts is still active.

                 

                So my processor is not responding to the interrupt, it is mere hitting constantly, and when the Accel says there is data, and it can get in between the constant interrupts, it grabs it, what they heck could be causing this in my firmware?

                 

                It is impacting all our other functions as well.

                 

                H

                • 5. Re: cannot clear interrupt
                  MoTa_728816

                  Dear Herb-san,

                   

                  Thank you very much for taking my word.

                  Although I lost the bit (it was not sensor interrupt), I'm glad that at least it could be confirmed.

                   

                  Now, still even without firmware, there could be a few more causes for triggering the interrupt of Accel_int.

                  (1) As interrupt of GPIO is generated by "Port", depending on the interrupt mask, all other P1[x] may be able to cause interrupt.

                       And the candidates are Hilo_A(P1[4]), Red_LED(P1[5]), SPI:ss1(P1[6]), SPI:sclk(P1[7]).

                       Can you test this? Temporary disable PWM and SPI and pull those pins to high and test the interrupt of Accel_int.

                   

                      Note: if GPIO_PRT1_INTR_CFG (0x4004010C) is 0x00000003 then those pins should not affect interrupt.

                      (Refer to the 17.1.14 PSoC 4 BLE Registers TRM)

                   

                  (2) May be Hilo_A and/or SPI:mosi_m has short to Accel_int, so that they are triggering the input.

                     (If this was the cause, doing the test above will also stop the interrupt.)

                   

                  Best Regards,

                  26-Jun-2020

                  Motoo Tanaka