Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to Set Custom I2C ID #1

Open
shivakumar-tekumatla opened this issue Aug 4, 2022 · 12 comments
Open

Unable to Set Custom I2C ID #1

shivakumar-tekumatla opened this issue Aug 4, 2022 · 12 comments
Labels
bug Something isn't working

Comments

@shivakumar-tekumatla
Copy link

I tried setting a new I2C ID using setI2CAddress function. The function returns True , but the communication fails. I tried the following program . I also attached the I2C communication data capturing using Saleae logic analyzer.

/*

  Example-01_Basic.ino

  This demo shows a basic use of a TMF882X device. The device is connected to, 
  and a single reading is taken for each loop iteration. 

  Supported Boards:
  
   SparkFun Qwiic dToF Imager - TMF8820        https://www.sparkfun.com/products/19036
   SparkFun Qwiic Mini dToF Imager - TMF8820   https://www.sparkfun.com/products/19218
   SparkFun Qwiic Mini dToF Imager - TMF8821   https://www.sparkfun.com/products/19451
   SparkFun Qwiic dToF Imager - TMF8821        https://www.sparkfun.com/products/19037
   
  Written by Kirk Benell @ SparkFun Electronics, April 2022

  Repository:
     https://github.com/sparkfun/SparkFun_Qwiic_TMF882X_Arduino_Library

  Documentation:
     https://sparkfun.github.io/SparkFun_Qwiic_TMF882X_Arduino_Library/

  SparkFun code, firmware, and software is released under the MIT License(http://opensource.org/licenses/MIT).
*/

#include "SparkFun_TMF882X_Library.h" //http://librarymanager/All#SparkFun_Qwiic_TMPF882X

SparkFun_TMF882X  myTMF882X;
uint8_t new_address = 0x50;

// Structure to hold the measurement results - this is defined by the TMF882X SDK.

static struct tmf882x_msg_meas_results myResults;

void setup()
{

    delay(1000);
    Serial.begin(115200);
    Serial.println("");

    Serial.println("In setup");
    Serial.println("==============================");

    // Initialize the TMF882X device
    if(!myTMF882X.begin())
    {
        Serial.println("Error - The TMF882X failed to initialize - is the board connected?");
        while(1);
    }else
        Serial.println("TMF882X started.");

    Serial.println("Change the device address");
    delay(2000);
    Serial.println(myTMF882X.setI2CAddress(new_address));
    delay(2000);

    // The device is now ready for operations
}

void loop()
{
    delay(2000);
    
    // get a Measurement
    if(myTMF882X.startMeasuring(myResults))
    {
        // print out results
        Serial.println("Measurement:");
        Serial.print("     Result Number: "); Serial.print(myResults.result_num);
        Serial.print("  Number of Results: "); Serial.println(myResults.num_results);       

        for (int i = 0; i < myResults.num_results; ++i) 
        {
            Serial.print("       conf: "); Serial.print(myResults.results[i].confidence);
            Serial.print(" distance mm: "); Serial.print(myResults.results[i].distance_mm);
            Serial.print(" channel: "); Serial.print(myResults.results[i].channel);
            Serial.print(" sub_capture: "); Serial.println(myResults.results[i].sub_capture);   

        }
        Serial.print("     photon: "); Serial.print(myResults.photon_count);    
        Serial.print(" ref photon: "); Serial.print(myResults.ref_photon_count);
        Serial.print(" ALS: "); Serial.println(myResults.ambient_light); Serial.println();
    }
}
[Session 0.zip](https://github.com/sparkfun/SparkFun_Qwiic_TMF882X_Arduino_Library/files/9263378/Session.0.zip)
@shivakumar-tekumatla
Copy link
Author

I have contacted AMS about this , and it seems to be procedure to change the device ID is different from what is given in the documentation. Update procedure looks like below. This is taken from their email to me, and also tested.

  1. EN = 1, download FW, confirm appid = 0x03
  2. Change 0x31 GPIO_0 & 0x32 GPIO_1 registers to 0x5 (Output high)
  3. Enter config page & change 0x3B I2C_SLAVE_ADDRESS to a value other than the default address 0x41 (I used 0x22)
  4. Write to 0x3E I2C_ADDR_CHANGE with value 0xF
  5. Write config page WRITE_CONFIG_PAGE into CMD_STAT register
  6. After confirming appid = 0x03, execute CMD_STAT 0x21 to change I2C address
    If someone planning to update this driver, you can follow these steps.

@ghost
Copy link

ghost commented Aug 8, 2022

Thanks for the detailed information. I'll take a look at this and get it fixed/tested - probably in the next couple weeks. -Kirk

@ghost ghost self-assigned this Aug 8, 2022
@ghost ghost added the bug Something isn't working label Aug 8, 2022
@hartmms
Copy link

hartmms commented Sep 26, 2022

@shivakumar-tekumatla, I took a crack at fixing the address change using your suggested code. I'm not able to get it to work. Perhaps you can post the actual code you used? Thanks.

@shivakumar-tekumatla
Copy link
Author

@hartmms , I was able to change using below program. I wrote the program in python .

def I2C_Chg_Fun(self,new_addr):
        new_addr = (((new_addr&0x7F) <<1) & 0xFE) # Shifting by one bit 
        self.bus.write_byte_data(self.I2C_ADDR,self.GPIO_0_REG,0x5)
        self.bus.write_byte_data(self.I2C_ADDR,self.GPIO_1_REG,0x5)
        self.bus.write_byte_data(self.I2C_ADDR, self.CMD_STAT_REG, self.LOAD_CONFIG_CMN )  #Step-1 
        self.STAT_OK = 0x20  #assigning a random value first 
        while self.STAT_OK>=0x10:  # Step-2 : Read until a value less than 0x10 is transmitted 
            self.STAT_OK = self.bus.read_byte_data(self.I2C_ADDR, self.CMD_STAT_REG)
            time.sleep(0.1)
        self.bus.write_byte_data(self.I2C_ADDR,self.I2C_SLAVE_ADDR_REG,new_addr)
        time.sleep(0.5)
        self.bus.write_byte_data(self.I2C_ADDR,self.I2C_ADDR_CHG_REG,0xF)
        time.sleep(0.5)
        self.bus.write_byte_data(self.I2C_ADDR,self.CMD_STAT_REG,0x15) 
        time.sleep(0.5)
        self.bus.write_byte_data(self.I2C_ADDR,self.CMD_STAT_REG,0x21)
        time.sleep(0.5)

Please note that I wrote this program after writing image to the sensor and confirming the application code to be 0x03.

@berickson
Copy link

I know it's been a while, but I tried getting a .cpp version of above working, and it isn't working for me. The code below seems to have no effect. Has anyone got this working from within the library?

   Serial.printf("setting I2C address to 0x%02x\n", address);

    // shift address by one bit 
    address = ((address&0x75)<<1)&0xfe;

    // Change 0x31 GPIO_0 & 0x32 GPIO_1 registers to 0x5 (Output high)
    _i2cBus->writeRegisterByte(_i2cAddress, TMF8X2X_COM_GPIO_0, 0x5);
    delay(500);
    _i2cBus->writeRegisterByte(_i2cAddress, TMF8X2X_COM_GPIO_1, 0x5);
    delay(500);
    _i2cBus->writeRegisterByte(_i2cAddress, TMF8X2X_COM_CMD_STAT, TMF8X2X_COM_CMD_STAT__cmd_stat__CMD_LOAD_CONFIG_PAGE_COMMON);
    delay(500);

    // wait for status to be less than 0x10
    uint8_t status = 0x20;
    while (status >= 0x10) // read until a value less than 0x10 is transmitted
    {
        _i2cBus->readRegisterRegion(_i2cAddress, TMF8X2X_COM_CMD_STAT, &status, 1);
        delay(100);
    }
    _i2cBus->writeRegisterByte(_i2cAddress, TMF8X2X_COM_I2C_SLAVE_ADDRESS, address);
    delay(500);
    _i2cBus->writeRegisterByte(_i2cAddress, TMF8X2X_COM_I2C_ADDR_CHANGE, 0xf);
    delay(500);
    _i2cBus->writeRegisterByte(_i2cAddress, TMF8X2X_COM_CMD_STAT, TMF8X2X_COM_CMD_STAT__cmd_stat__CMD_WRITE_CONFIG_PAGE);
    delay(500);
    _i2cBus->writeRegisterByte(_i2cAddress, TMF8X2X_COM_CMD_STAT, TMF8X2X_COM_CMD_STAT__cmd_stat__CMD_I2C_SLAVE_ADDRESS);

    Serial.printf("I2C address now reads as 0x%02x\n", getI2CAddress());

@shivakumar-tekumatla
Copy link
Author

@berickson , can you try with a different delay between the commands? Maybe 1 second ? I do not know if this is the case , but I remember changing the delays when switching from python to cpp.

@berickson
Copy link

@shivakumar-tekumatla Thanks for the reply. I tried changing all delays to 1 second and didn't get any change in behavior.

@shivakumar-tekumatla
Copy link
Author

shivakumar-tekumatla commented Nov 27, 2023

@berickson , another reason could be the factory firmware might have changed since then. Are you using the latest one ? if that is the case can you try following the actual method from the documentation. I remember talking to them to change the process and the documentation. They might have done that

@b1uep0nd
Copy link

b1uep0nd commented Dec 4, 2023

I encountered the same issue as described in this GitHub issue while working with C code. However, I was able to resolve it and would like to share my solution. It seems that the firmware defined in tof_bin_image.c is outdated and likely contains bugs related to TMF882X. I downloaded the latest hex file from the TMF882X website and resolved the issue by specifying hex mode when calling fwdl. I hope this information is helpful.

@shivakumar-tekumatla
Copy link
Author

shivakumar-tekumatla commented Dec 4, 2023

@b1uep0nd thanks for your comment. Please post your solution.

@berickson
Copy link

@b1uep0nd I'll try with the udpated hex. Before I start, I'm curious. After you set the I2C address, does it survive reboots and firmware uploads or does the address need to be set every time the devices start up?

@b1uep0nd
Copy link

b1uep0nd commented Dec 5, 2023

I modified the loadFirmware function like this. The firmwareBinImage is the latest HEX data downloaded.

    // Load the fireware.
    if (tmf882x_fwdl(&_TOF, FWDL_TYPE_HEX, firmwareBinImage, length))

@berickson You will need to set the address every time the device starts up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants