4 Replies Latest reply on Sep 20, 2017 9:01 AM by frederic.chasse_1669321

    Is it possible to sleep during I2C transactions?

    frederic.chasse_1669321

      Hi,

       

      I currently have some blocking I2C that runs perfectly on PSoC 4. I was wondering if it's possible to use the I2C interrupts instead and sleep between interrupts? According to AN86233, "All other peripherals and clocks continue to run" during sleep, so I'm assuming that it would be possible to sleep between the I2C transaction steps. However, My code is blocked in CySysPmSleep(). Here's my code for the I2C read:

       

      // buf[0]: ADDRESS + W

      // buf[1]: REG ADDRESS

      int I2C_Read(unsigned char *buf, int bufSize) {

       

          uint32_t slaveAdr = (buf[0] >> 1) & 0x7F;

         

          // Sending Start and register

          if ( I2C_I2CMasterSendStart(slaveAdr, 0) != I2C_I2C_MSTR_NO_ERROR ) {

              return -1;

          }

          if ( I2C_I2CMasterWriteByte(buf[1]) != I2C_I2C_MSTR_NO_ERROR ) {

              return -1;

          }

       

          // Sending Restart and reading data

          I2C_I2CMasterReadBuf(slaveAdr, buf, bufSize, I2C_I2C_MODE_COMPLETE_XFER | I2C_I2C_MODE_REPEAT_START);

       

          while( !(I2C_I2CMasterStatus() & I2C_I2C_MSTAT_RD_CMPLT) ) {

              CySysPmSleep();

          }

         

          return bufSize;

      }

       

       

      The code for a Write is pretty similar. However, it's stuck at CySysPmSleep(). Is it possible at all to sleep between I2C interrupts?

       

      Thank you,

       

      Fred

        • 1. Re: Is it possible to sleep during I2C transactions?
          hima

          Any interrupt can wake the device from sleep.Exit from sleep mode occurs when an interrupt is triggered. Upon exiting sleep, PSoC re-enters active mode. The configuration of sleep wakeup sources requires only that their interrupts be enabled. I2C interrupts will be enabled by default.

           

          Thanks,

          Hima

          • 2. Re: Is it possible to sleep during I2C transactions?
            frederic.chasse_1669321

            Thank you Hima.

             

            So that tells me that my idea is correct, so there must be a problem with my code. Do you see something wrong with my approach? Am I using the wrong API functions?

             

            Fred

            • 3. Re: Is it possible to sleep during I2C transactions?
              e.pratt_1639216

              From a code perspective:

              // Sending Restart and reading data

                  I2C_I2CMasterReadBuf(slaveAdr, buf, bufSize, I2C_I2C_MODE_COMPLETE_XFER | I2C_I2C_MODE_REPEAT_START);

               

                  while( !(I2C_I2CMasterStatus() & I2C_I2C_MSTAT_RD_CMPLT) ) {

                      CySysPmSleep();

                  }

              Looks like it will just try to go back to sleep on waking up? The CPU resumes execution at the instruction after where it went to sleep, so in your case the CPU will wake up at the end of the while loop, and will proceed to check the while loop conditions. If these are still true, then it will go back to sleep. And, unless I2C_I2CMasterStatus() or I2C_I2C_MSTAT_RD_CMPLT are getting set between the end of the while loop and the CySySPmSleep() call, then the unit will just sit in the while loop forever.

              • 4. Re: Is it possible to sleep during I2C transactions?
                frederic.chasse_1669321

                What I got from reading the API code (I think) is that the flags from MasterStatus are set in the I2C interrupt, so upon waking up from sleep and servicing the I2C interrupt, the while loop condition should not be satisfied anymore.

                 

                Anyways, I got it working by reducing the speed of the I2C bus. I think maybe that the 1 byte transactions were done too fast, so by the time the CPU was at the CySysPmSleep() line, the I2C transaction was already done.

                 

                Thank you!