78 lines
2.4 KiB
C
78 lines
2.4 KiB
C
/**
|
|
* 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
|
|
// 0
|
|
// 1 @
|
|
// 2
|
|
// 3 @
|
|
// 4
|
|
// 5
|
|
// 6
|
|
// 7
|
|
//
|
|
// E.g. if slave addresses 0x12 and 0x34 were acknowledged.
|
|
|
|
#include <stdio.h>
|
|
#include "pico/stdlib.h"
|
|
#include "pico/binary_info.h"
|
|
#include "hardware/i2c.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;
|
|
}
|
|
|
|
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)
|
|
i2c_init(i2c_default, 100 * 1000);
|
|
gpio_set_function(PICO_DEFAULT_I2C_SDA_PIN, GPIO_FUNC_I2C);
|
|
gpio_set_function(PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C);
|
|
gpio_pull_up(PICO_DEFAULT_I2C_SDA_PIN);
|
|
gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN);
|
|
// Make the I2C pins available to picotool
|
|
bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C));
|
|
|
|
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(i2c_default, addr, &rxdata, 1, false);
|
|
|
|
printf(ret < 0 ? "." : "@");
|
|
printf(addr % 16 == 15 ? "\n" : " ");
|
|
}
|
|
printf("Done.\n");
|
|
return 0;
|
|
#endif
|
|
}
|