I2C
The Pico 2 can act as I2C master or I2C slave. The default setting is to be master. The SDK controls the I2C hardware and provides functions to configure I2C and read/write to a slave.
First, add hardware_i2c library to the CMakeList.txt for I2C support.
target_link_libraries(my_project pico_stdlib hardware_i2c)
Now the steps are: - Configure GPIO pin(s) for I2C. - Set the bus speed. - Read data from an I2C peripheral, in this example an LM75 temperature sensor, which use two bytes to represent the temperature.
void configureI2C()
{
uint32_t baudrate = 10000;
i2c_init(i2c_default, baudrate);
// configure GPIO pins
// This example will use I2C0 on the default SDA and SCL pins (GP4, GP5 on a Pico)
gpio_set_function(PICO_DEFAULT_I2C_SDA_PIN, GPIO_FUNC_I2C);
gpio_set_function(PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C);
// set pull-up on pins
gpio_pull_up(PICO_DEFAULT_I2C_SDA_PIN);
gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN);
}
The i2c_read_blocking function can be used to read data from a peripheral into a buffer. It handles I2C START and STOP signalling internally. The application should check the return value from the read function, to know if data was read and can be used. The function returns PICO_ERROR_GENERIC for all errors, so you should set a breakpoint inside its implementation in i2c.c and investigate there, what the error was.
void readTempFromLM75(uint8_t address)
{
// the temperature is two bytes
uint8_t byte[2];
int8_t rc; // to hold the return code
rc = i2c_read_blocking(i2c_default, address, &(byte[0]), 2, false);
if (rc != PICO_ERROR_GENERIC)
{
printf("byte0: %d, byte1: %d\r\n", byte[0], byte[1]);
}
else
{
printf("I2C error, return value was: %d\r\n", rc);
}
}