pico-sdk icon indicating copy to clipboard operation
pico-sdk copied to clipboard

I2C detect issue using GP4/GP5 or GP6/GP7

Open runwalle opened this issue 3 months ago • 3 comments

I was testing I2C with Pico2 using GP4/5 or GP6/7. Somehow Pico2 can't detect a slave device. I double checked wiring and external pull-up register...no issue

but I tested i2c with GP14/15 using same codes. It worked ! Using hardware/i2c functions.

Any thought? SDK: 2.2.0 IDE: Visual Studio Code

Below is snippet of my code.

///////

// I2C Configuration
#define I2C_PORT i2c1
#define I2C_SDA_PIN 4  // 14
#define I2C_SCL_PIN 5  // 15
#define I2C_BAUDRATE 100000  // 100 kHz

// Initialize I2C Master
void init_i2c_master() {
    printf("Initializing I2C Master...\n");
    
    i2c_init(I2C_PORT, I2C_BAUDRATE);
    
    gpio_set_function(I2C_SDA_PIN, GPIO_FUNC_I2C);
    gpio_set_function(I2C_SCL_PIN, GPIO_FUNC_I2C);
    
    // Enable internal pull-ups
    gpio_pull_up(I2C_SDA_PIN);
    gpio_pull_up(I2C_SCL_PIN);
    
    printf("I2C Master initialized: SDA=GPIO%d, SCL=GPIO%d, Speed=%d Hz\n", 
           I2C_SDA_PIN, I2C_SCL_PIN, I2C_BAUDRATE);
}

// Robust I2C scan with timeout
bool scan_i2c_bus() {
    printf("\n=== Scanning I2C Bus ===\n");
    printf("Searching for I2C devices at %d Hz...\n", I2C_BAUDRATE);
    printf("Note: Scanning with 100ms timeout per address\n");
    printf("   0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F\n");

    int devices_found = 0;
    uint8_t first_device_addr = 0;
    
    for (int addr = 0; addr < 128; ++addr) {
        if (addr % 16 == 0) {
            printf("%02x ", addr);
            fflush(stdout);
        }

        // Skip reserved addresses (0x00-0x07 and 0x78-0x7F)
        if (addr < 0x08 || addr > 0x77) {
            printf("   ");
        } else {
            // Use timeout version - 100ms timeout per address
            uint8_t rxdata;
            int ret = i2c_read_timeout_us(I2C_PORT, addr, &rxdata, 1, false, 100000);
            
            if (ret == 1) {
                // Successfully read 1 byte - device responded
                printf("%02X ", addr);
                devices_found++;
                if (first_device_addr == 0) {
                    first_device_addr = addr;
                }
            } else if (ret == PICO_ERROR_TIMEOUT) {
                printf("T  ");  // Timeout
            } else if (ret == PICO_ERROR_GENERIC) {
                printf(".  ");  // NACK - no device
            } else {
                printf("?  ");  // Unknown error
            }
        }
        
        if (addr % 16 == 15) {
            printf("\n");
            fflush(stdout);
        }
    }
    
    printf("\nScan complete!\n");
    printf("Legend: Address=device found, .=no device, T=timeout, ?=error\n");
    printf("Found %d device(s).\n", devices_found);
    
    // Use the first detected device
    detected_slave_addr = first_device_addr;
    printf("✓ Using slave at address 0x%02X for testing\n", detected_slave_addr);
   
    printf("\n");
    
    return true;
}

runwalle avatar Oct 03 '25 07:10 runwalle

Have a look at Table 3 in https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf

GP14 and GP15 are I2C1, but GP4 and GP5 are I2C0.

lurch avatar Oct 03 '25 12:10 lurch

I also did test GP6/7 as i2c1 or GP4/5 as i2c0. Same issue Somehow only GP14/15 works properly.

runwalle avatar Oct 03 '25 15:10 runwalle

Try with another Pico device?

peterharperuk avatar Oct 03 '25 16:10 peterharperuk