This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

OPT3001: INT pin not firing after one-shot measurement

Part Number: OPT3001
Other Parts Discussed in Thread: CC2650

Hi,

I am using a OPT3001 (on a EDU-MKII boosterpack) with a CC2650 launchpad.  My initialization is as follows (after initializing I2C interface):

Setup low-limit register for end of conversion mode:

// Initialize OPT3001 settings
  // Set low limit register to 0xC0 (End of Conversion Mode) so INT pin goes active on every measurement conversion. Cleared by R or W to config register.
  txBuffer[0] = OPT3001_LLIMIT_R;  // 0x02
  txBuffer[1] = 0xC0;
  txBuffer[2] = 0x00;

  i2cTrans.writeCount = 3;
  i2cTrans.writeBuf = txBuffer;
  i2cTrans.readCount = 0;
  i2cTrans.readBuf = rxBuffer;
  i2cTrans.slaveAddress = Board_OPT3001_ADDR;

  if (I2C_transfer(userI2CHandle, &i2cTrans))
  {
      Log_info0("OPT3001 low-limit register setup successful!");
  }
  else
      Log_info0("OPT3001 low-limit register setup failure!");

Setup Config Register (begin measurement):

 uint16_t configReg;
    // Setup OPT3001 configuration register
    txBuffer[0] = OPT3001_CONFIG_R;  // 0x01
    txBuffer[1] = 0xCA;
    txBuffer[2] = 0x10;
                                                  /* OPT3001 Setup:
                                                     15-12b = 1100    :   Automatic-full-scale mode
                                                     11b    = 1       :   Coversion time (1 = 800ms, more accurate)
                                                     10-9b  = 01      :   Mode of conversion operation (01 = single shot)
                                                     8b     = 0       :   Overflow flag (Read-Only)
                                                     7b     = 0       :   Conversion ready field (Read-Only)
                                                     6b     = 0       :   Flag high field (Read-Only)
                                                     5b     = 0       :   Flag low field (Read-Only)
                                                     4b     = 1       :   Latch field (1 = window-style comparision operation)
                                                     3b     = 0       :   Polarity field (INT pin reports active low)
                                                     2b     = 0       :   Mask exponent field (0 = do not mask exponent)
                                                     1-0b   = 00      :   Fault count field (0 = 1 fault until interrupt)
                                                    */
    i2cTrans.writeCount = 3;
    i2cTrans.writeBuf = txBuffer;
    i2cTrans.readCount = 2;
    i2cTrans.readBuf = rxBuffer;
    i2cTrans.slaveAddress = Board_OPT3001_ADDR;

    if (I2C_transfer(userI2CHandle, &i2cTrans))
    {
        configReg = (rxBuffer[0] << 8) | rxBuffer[1];
        Log_info1("OPT3001 configuration setup successful! 0x%04x", configReg);
    }
    else
        Log_info0("OPT3001 configuration setup failed!");
    }

Retrieve reading:

    txBuffer[0] = OPT3001_LOCAL_LUX;  // Local lux register 0x00
    i2cTrans.writeCount = 1;
    i2cTrans.writeBuf = txBuffer;
    i2cTrans.readCount = 2;
    i2cTrans.readBuf = rxBuffer;
    i2cTrans.slaveAddress = Board_OPT3001_ADDR;

    uint32_t newLux;
    if (I2C_transfer(userI2CHandle, &i2cTrans))
        // Process data from rxBuffer
        .........

Here is my pin table for interrupt config reference:

PIN_Config userPinTable[] = {
  // Other pins are irrelevant
  // ...........................................
  Board_DIO21 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,  // OPT3001 INT pin
  Board_DIO12 | PIN_GPIO_OUTPUT_EN | PIN_PUSHPULL | PIN_GPIO_LOW,
  PIN_TERMINATE
};


Everything is working perfectly except the INT pin firing. On my logic analyzer the INT pin is being held low all the time which doesn't make sense.  Currently to make this work I have a 5 second delay between readings which is enough time for the measurements to complete.  In reality I want to operate in window-latch, end of conversion, one-shot mode so the OPT3001 only reads one measurement until it can be processed.  

Am I missing something here? As I understand it, after setting up the config register the measurement should start immediately then the INT pin should be set (active low) and nothing should happen again until the config register is cleared and written to again (to setup one-shot mode as it will automatically revert back to shutdown mode). 

  • Figure it out! You have to read the config register BEFORE you write to it. This is not listed ANYWHERE in the datasheet or online (I've been searching for 2 weeks now to figure this out). Even though I was reading the config register immediately after writing in order to clear any flags, it only works if you read first. I can't believe this was left out of the data sheet considering the amount of detail and explanation they provided already.