#include "driver/gpio.
h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#define SDA_PIN GPIO_NUM_21 // Define your SDA pin
#define SCL_PIN GPIO_NUM_22 // Define your SCL pin
#define I2C_DELAY 5 // Delay in microseconds
// Function to set the SDA line
static void i2c_set_sda(int level) {
gpio_set_level(SDA_PIN, level);
ets_delay_us(I2C_DELAY);
}
// Function to set the SCL line
static void i2c_set_scl(int level) {
gpio_set_level(SCL_PIN, level);
ets_delay_us(I2C_DELAY);
}
// Function to configure the GPIO pins
static void i2c_gpio_init() {
gpio_config_t conf;
conf.pin_bit_mask = (1ULL << SDA_PIN) | (1ULL << SCL_PIN);
conf.mode = GPIO_MODE_OUTPUT_OD;
conf.pull_up_en = GPIO_PULLUP_ENABLE;
conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
conf.intr_type = GPIO_INTR_DISABLE;
gpio_config(&conf);
gpio_set_level(SDA_PIN, 1);
gpio_set_level(SCL_PIN, 1);
}
// Function to generate I2C start condition
static void i2c_start() {
i2c_set_sda(1);
i2c_set_scl(1);
i2c_set_sda(0);
i2c_set_scl(0);
}
// Function to generate I2C stop condition
static void i2c_stop() {
i2c_set_sda(0);
i2c_set_scl(1);
i2c_set_sda(1);
i2c_set_scl(0);
}
// Function to write a byte to the I2C bus
static void i2c_write_byte(uint8_t byte) {
for (int i = 0; i < 8; i++) {
i2c_set_sda((byte & 0x80) != 0);
i2c_set_scl(1);
i2c_set_scl(0);
byte <<= 1;
}
// Release SDA for ACK
i2c_set_sda(1);
i2c_set_scl(1);
i2c_set_scl(0);
}
// Function to read a byte from the I2C bus
static uint8_t i2c_read_byte() {
uint8_t byte = 0;
gpio_set_direction(SDA_PIN, GPIO_MODE_INPUT); // Set SDA as input
for (int i = 0; i < 8; i++) {
i2c_set_scl(1);
byte = (byte << 1) | gpio_get_level(SDA_PIN);
i2c_set_scl(0);
}
gpio_set_direction(SDA_PIN, GPIO_MODE_OUTPUT_OD); // Set SDA back to output
return byte;
}
// Function to send ACK or NACK after reading a byte
static void i2c_send_ack(bool ack) {
i2c_set_sda(ack ? 0 : 1); // ACK is 0, NACK is 1
i2c_set_scl(1);
i2c_set_scl(0);
i2c_set_sda(1); // Release SDA
}
void app_main(void) {
i2c_gpio_init();
// Example: Write a byte to an I2C device
i2c_start();
i2c_write_byte(0xA0); // Device address (write)
i2c_write_byte(0x00); // Data
i2c_stop();
vTaskDelay(100 / portTICK_PERIOD_MS);
// Example: Read a byte from an I2C device
i2c_start();
i2c_write_byte(0xA1); // Device address (read)
uint8_t data = i2c_read_byte();
i2c_send_ack(true); // Send ACK
i2c_stop();
printf("Read data: 0x%02X\n", data);
}