/** * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause */ // Sweep through all 7-bit I2C addresses, to see if any slaves are present on // the I2C bus. Print out a table that looks like this: // // I2C Bus Scan // 0 1 2 3 4 5 6 7 8 9 A B C D E F // 00 . . . . . . . . . . . . . . . . // 10 . . @ . . . . . . . . . . . . . // 20 . . . . . . . . . . . . . . . . // 30 . . . . @ . . . . . . . . . . . // 40 . . . . . . . . . . . . . . . . // 50 . . . . . . . . . . . . . . . . // 60 . . . . . . . . . . . . . . . . // 70 . . . . . . . . . . . . . . . . // E.g. if addresses 0x12 and 0x34 were acknowledged. #include #include "pico/stdlib.h" #include "pico/binary_info.h" #include "hardware/i2c.h" #include "pico/stdlib.h" #include "hardware/spi.h" #include "hardware/i2c.h" #include "hardware/dma.h" #include "hardware/pio.h" #include "hardware/interp.h" #include "hardware/timer.h" #include "hardware/pwm.h" #include "hardware/clocks.h" #include "hardware/uart.h" // I2C reserves some addresses for special purposes. We exclude these from the scan. // These are any addresses of the form 000 0xxx or 111 1xxx bool reserved_addr(uint8_t addr) { return (addr & 0x78) == 0 || (addr & 0x78) == 0x78; } #define PICO_DEFAULT_I2C_SDA_PIN 22 #define PICO_DEFAULT_I2C_SCL_PIN 19 int main() { // Enable UART so we can print status output stdio_init_all(); #if !defined(i2c_default) || !defined(PICO_DEFAULT_I2C_SDA_PIN) || !defined(PICO_DEFAULT_I2C_SCL_PIN) #warning i2c/bus_scan example requires a board with I2C pins puts("Default I2C pins were not defined"); #else // This example will use I2C0 on the default SDA and SCL pins (GP4, GP5 on a Pico) gpio_set_function(11, GPIO_FUNC_PWM); uint slice_num = pwm_gpio_to_slice_num(11); // 6 cycles (0 to 5), 125 MHz / 6 = ~20.83 MHz wrap rate pwm_set_wrap(slice_num, 5); pwm_set_gpio_level(11, 3); pwm_set_enabled(slice_num, true); sleep_ms(1000); i2c_init(i2c1, 100 * 1000); gpio_set_function(22, GPIO_FUNC_I2C); gpio_set_function(19, GPIO_FUNC_I2C); gpio_pull_up(22); gpio_pull_up(19); // Make the I2C pins available to picotool bi_decl(bi_2pins_with_func(22, 19, GPIO_FUNC_I2C)); while(true){ printf("\nI2C Bus Scan\n"); printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n"); for (int addr = 0; addr < (1 << 7); ++addr) { if (addr % 16 == 0) { printf("%02x ", addr); } // Perform a 1-byte dummy read from the probe address. If a slave // acknowledges this address, the function returns the number of bytes // transferred. If the address byte is ignored, the function returns // -1. // Skip over any reserved addresses. int ret; uint8_t rxdata; if (reserved_addr(addr)) ret = PICO_ERROR_GENERIC; else ret = i2c_read_blocking(i2c1, addr, &rxdata, 1, false); printf(ret < 0 ? "." : "@"); printf(addr % 16 == 15 ? "\n" : " "); } printf("Done.\n"); sleep_ms(1000); } return 0; #endif }