/* * I2C Module * * Provides I2C Access routines for other modules/tasks. Provides a locking mechanism * since the underlying ESP IDF routines are not thread safe. * * Copyright 2020-2022 Dan Julio * * This file is part of tCam. * * tCam is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * tCam is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with tCam. If not, see . * */ // #include "system_config.h" #include "i2c.h" #include "driver/i2c.h" #include "lepton_system.h" // #include "freertos/FreeRTOS.h" // #include "freertos/semphr.h" // // I2C API // /** * i2c master initialization */ esp_err_t i2c_master_init(int scl_pin, int sda_pin) { int i2c_master_port = I2C_MASTER_NUM; i2c_config_t conf; // Configure the I2C controller in master mode using the pins provided conf.mode = I2C_MODE_MASTER; conf.sda_io_num = sda_pin; conf.sda_pullup_en = GPIO_PULLUP_ENABLE; conf.scl_io_num = scl_pin; conf.scl_pullup_en = GPIO_PULLUP_ENABLE; conf.master.clk_speed = I2C_MASTER_FREQ_HZ; conf.clk_flags = 0; esp_err_t err = i2c_param_config((i2c_port_t)i2c_master_port, &conf); if (err != ESP_OK) { return err; } // Install the I2C driver return i2c_driver_install((i2c_port_t)i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_LEN, I2C_MASTER_TX_BUF_LEN, 0); } /** * Read esp-i2c-slave * * _______________________________________________________________________________________ * | start | slave_addr + rd_bit +ack | read n-1 bytes + ack | read 1 byte + nack | stop | * --------|--------------------------|----------------------|--------------------|------| * */ esp_err_t i2c_master_read_slave(uint8_t addr7, uint8_t *data_rd, size_t size) { if (size == 0) { return ESP_OK; } i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (addr7 << 1) | I2C_MASTER_READ, ACK_CHECK_EN); if (size > 1) { i2c_master_read(cmd, data_rd, size - 1, ACK_VAL); } i2c_master_read_byte(cmd, data_rd + size - 1, NACK_VAL); i2c_master_stop(cmd); esp_err_t ret = i2c_master_cmd_begin((i2c_port_t)I2C_MODE_MASTER, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); return ret; } /** * Write esp-i2c-slave * * ___________________________________________________________________ * | start | slave_addr + wr_bit + ack | write n bytes + ack | stop | * --------|---------------------------|----------------------|------| * */ esp_err_t i2c_master_write_slave(uint8_t addr7, uint8_t *data_wr, size_t size) { i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (addr7 << 1) | I2C_MASTER_WRITE, ACK_CHECK_EN); i2c_master_write(cmd, data_wr, size, ACK_CHECK_EN); i2c_master_stop(cmd); esp_err_t ret = i2c_master_cmd_begin((i2c_port_t)I2C_MODE_MASTER, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); return ret; }