From a5bdfe3f4ce5cd87c0ffafd2f2c2d5cc152208d3 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Tue, 10 Nov 2020 09:47:28 +0100 Subject: [PATCH] software/i2c: add i2c_scan command. --- litex/soc/software/bios/cmds/cmd_i2c.c | 30 +++++++++++++++++++++++++- litex/soc/software/include/base/i2c.h | 1 + litex/soc/software/libbase/i2c.c | 14 ++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/litex/soc/software/bios/cmds/cmd_i2c.c b/litex/soc/software/bios/cmds/cmd_i2c.c index de66ee120..7ef014cea 100644 --- a/litex/soc/software/bios/cmds/cmd_i2c.c +++ b/litex/soc/software/bios/cmds/cmd_i2c.c @@ -61,7 +61,7 @@ define_command(i2c_write, i2c_write_handler, "Write over I2C", I2C_CMDS); #endif /** - * Command "i2crd" + * Command "i2c_read" * * Read I2C slave memory using 7-bit slave address and 8-bit memory address. * @@ -119,3 +119,31 @@ static void i2c_read_handler(int nb_params, char **params) } define_command(i2c_read, i2c_read_handler, "Read over I2C", I2C_CMDS); #endif + + +/** + * Command "i2c_scan" + * + * Scan for available I2C devices + * + */ +#ifdef CSR_I2C_BASE +static void i2c_scan_handler(int nb_params, char **params) +{ + int slave_addr; + + printf("\n 0 1 2 3 4 5 6 7 8 9 a b c d e f"); + for (slave_addr = 0; slave_addr < 0x80; slave_addr++) { + if (slave_addr % 0x10 == 0) { + printf("\n0x%02x ", (slave_addr/0x10) * 0x10); + } + if (i2c_poll(slave_addr)) { + printf("+ "); + } else { + printf(". "); + } + } + printf("\n"); +} +define_command(i2c_scan, i2c_scan_handler, "Scan for I2C slaves", I2C_CMDS); +#endif diff --git a/litex/soc/software/include/base/i2c.h b/litex/soc/software/include/base/i2c.h index 7021c9424..8e149145b 100644 --- a/litex/soc/software/include/base/i2c.h +++ b/litex/soc/software/include/base/i2c.h @@ -18,6 +18,7 @@ extern "C" { void i2c_reset(void); bool i2c_write(unsigned char slave_addr, unsigned char addr, const unsigned char *data, unsigned int len); bool i2c_read(unsigned char slave_addr, unsigned char addr, unsigned char *data, unsigned int len, bool send_stop); +bool i2c_poll(unsigned char slave_addr); #ifdef __cplusplus } diff --git a/litex/soc/software/libbase/i2c.c b/litex/soc/software/libbase/i2c.c index cd15abb53..800f926f8 100644 --- a/litex/soc/software/libbase/i2c.c +++ b/litex/soc/software/libbase/i2c.c @@ -201,4 +201,18 @@ bool i2c_write(unsigned char slave_addr, unsigned char addr, const unsigned char return true; } +/* + * Poll I2C slave at given address, return true if it sends an ACK back + */ +bool i2c_poll(unsigned char slave_addr) +{ + bool result; + + i2c_start(); + result = i2c_transmit_byte(I2C_ADDR_RD(slave_addr)); + i2c_stop(); + + return result; +} + #endif /* CSR_I2C_BASE */