3 Replies Latest reply on Nov 26, 2019 4:22 PM by MoTa_728816

    I2C Question - Accelerometer with Interrupt

    StKe_3927516

      I have a custom board that has PSOC4 CYBLE 222014-01, LIS3DH accelerometer, push button and an RGB LED.

       

      I've created a simple push button interrupt project that changes the LED from red to blue, and it works!

      I also have a project that checks the WHO_AM_I register of the LIS3DH, and it works -- it writes to the register to send a response, and responds with the correct value.

       

      What I am having trouble with is setting the LIS3DH to send an interrupt on movement.

      The LIS3DH datasheet: https://www.st.com/resource/en/datasheet/lis3dh.pdf [PDF]

       

      I am not certain on how to set the registers, per the datasheet.

       

      The code I have:

       

      void int2_handler ()

      {

          //Disconnect_LED_Write( ~ Disconnect_LED_Read() ); //BLUE

          //LowPower_LED_Write( ~ Disconnect_LED_Read() ); //RED

          Disconnect_LED_Write(LED_ON); //BLUE

          LowPower_LED_Write(LED_OFF); //RED

         

          Pin_PB_SW_ClearInterrupt();

      }

       

       

      int main()

      {

       

          I2C_1_Start();

          CyGlobalIntEnable; 

       

          LowPower_LED_Write(LED_ON); //RED

       

          uint32 LIS3DH_ADDRESS = 0x18 ;

         

          uint8 WriteBuffer[10];

          WriteBuffer[0] = 0x34; //INT2_CFG -- 0,1,0,0,0,0,0,0 (???)

          WriteBuffer[1] = 1;

          WriteBuffer[2] = 1;

          WriteBuffer[3] = 1;

          WriteBuffer[4] = 1;

          WriteBuffer[5] = 1;

          WriteBuffer[6] = 1;

          WriteBuffer[7] = 1;

          WriteBuffer[8] = 1;

         

          uint8 WriteBuffer_THS[4]; //INT2_THS

          WriteBuffer_THS[0] = 0x36;

          WriteBuffer_THS[1] = 1;

          WriteBuffer_THS[2] = 1;

         

          uint8 WriteBuffer_DUR[4]; //INT2_DURATION

          WriteBuffer_DUR[0] = 0x37;

          WriteBuffer_DUR[1] = 1;

          WriteBuffer_DUR[2] = 1;

         

          I2C_1_I2CMasterSendStart(LIS3DH_ADDRESS, 1, I2C_1_I2C_MODE_COMPLETE_XFER);

         

          I2C_1_I2CMasterWriteBuf(LIS3DH_ADDRESS, WriteBuffer, 10, I2C_1_I2C_MODE_COMPLETE_XFER);

          I2C_1_I2CMasterWriteBuf(LIS3DH_ADDRESS, WriteBuffer_THS, 4, I2C_1_I2C_MODE_COMPLETE_XFER);

          I2C_1_I2CMasterWriteBuf(LIS3DH_ADDRESS, WriteBuffer_DUR, 4, I2C_1_I2C_MODE_COMPLETE_XFER);

         

          I2C_1_I2CMasterSendStop(I2C_1_I2C_MODE_COMPLETE_XFER);

         

          Pin_PB_SW_Int_StartEx( int2_handler );

       

          for(;;){

             

          }

      }

      /* END OF FILE */

       

      Thank you for any help,

      Steve

        • 1. Re: I2C Question - Accelerometer with Interrupt
          RakshithM_16

          Hi StKe_3927516,

           

          Can you try testing your project after changing

           

          void int2_handler ()

          {

              //Disconnect_LED_Write( ~ Disconnect_LED_Read() ); //BLUE

              //LowPower_LED_Write( ~ Disconnect_LED_Read() ); //RED

              Disconnect_LED_Write(LED_ON); //BLUE

              LowPower_LED_Write(LED_OFF); //RED

            

              Pin_PB_SW_ClearInterrupt();

          }

           

          to

           

          CY_ISR( int2_handler)

          {

               //Disconnect_LED_Write( ~ Disconnect_LED_Read() ); //BLUE

              //LowPower_LED_Write( ~ Disconnect_LED_Read() ); //RED

              Disconnect_LED_Write(LED_ON); //BLUE

              LowPower_LED_Write(LED_OFF); //RED

            

              Pin_PB_SW_ClearInterrupt();

          }

           

          If you are still facing the same issue, please share your project.

           

          Thanks and Regards,

          Rakshith M B

          • 2. Re: I2C Question - Accelerometer with Interrupt
            JoMe_264151

            Writing to slave Count bytes:

            I2C_MasterWriteBuf(SlaveAddress,DataPtr,Count,I2C_MODE_COMPLETE_XFER);

             

            Reading from Slave sending register/command byte first:

            I2C_MasterWriteBuf(SlaveAddress,&RegAddress,1,I2C_MODE_NO_STOP);

            I2C_MasterReadBuf(SlaveAddress,DataPtr,Count,I2C_MODE_REPEAT_START);

             

            The I2C_Master_SendStart() and _SendStop() APIs are called internally and should not be used.

            I would suggest you to check the results returned by the APIs for non-zero values which indicate an error.

             

            Bob

            • 3. Re: I2C Question - Accelerometer with Interrupt
              MoTa_728816

              Hi

               

              To access a register you need send it as a byte,

               

              so I would change

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

                  WriteBuffer[0] = 0x34; //INT2_CFG -- 0,1,0,0,0,0,0,0 (???)

                  WriteBuffer[1] = 1;

                  WriteBuffer[2] = 1;

                  WriteBuffer[3] = 1;

                  WriteBuffer[4] = 1;

                  WriteBuffer[5] = 1;

                  WriteBuffer[6] = 1;

                  WriteBuffer[7] = 1;

                  WriteBuffer[8] = 1;

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

              to

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

                  WriteBuffer[0] = 0x34 ; // INIT2_CFG

                  WirteBuffer[1] = 0x40 ; // 0100_0000

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

               

              moto