// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef _DRIVER_I2C_H_ #define _DRIVER_I2C_H_ #ifdef __cplusplus extern "C" { #endif #include #include "esp_err.h" #include "esp_intr_alloc.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "freertos/xtensa_api.h" #include "freertos/task.h" #include "freertos/queue.h" #include "freertos/ringbuf.h" #include "driver/gpio.h" #define I2C_APB_CLK_FREQ APB_CLK_FREQ /*!< I2C source clock is APB clock, 80MHz */ #define I2C_FIFO_LEN (32) /*!< I2C hardware fifo length */ typedef enum{ I2C_MODE_SLAVE = 0, /*!< I2C slave mode */ I2C_MODE_MASTER, /*!< I2C master mode */ I2C_MODE_MAX, }i2c_mode_t; typedef enum { I2C_MASTER_WRITE = 0, /*!< I2C write data */ I2C_MASTER_READ, /*!< I2C read data */ } i2c_rw_t; typedef enum { I2C_DATA_MODE_MSB_FIRST = 0, /*!< I2C data msb first */ I2C_DATA_MODE_LSB_FIRST = 1, /*!< I2C data lsb first */ I2C_DATA_MODE_MAX } i2c_trans_mode_t; typedef enum{ I2C_CMD_RESTART = 0, /*!=0) The number of data bytes that pushed to the I2C slave buffer. */ int i2c_slave_write_buffer(i2c_port_t i2c_num, uint8_t* data, int size, TickType_t ticks_to_wait); /** * @brief I2C slave read data from internal buffer. When I2C slave receive data, isr will copy received data * from hardware rx fifo to internal ringbuffer. Then users can read from internal ringbuffer. * @note * Only call this function in I2C slave mode * * @param i2c_num I2C port number * @param data data pointer to write into internal buffer * @param max_size Maximum data size to read * @param ticks_to_wait Maximum waiting ticks * * @return * - ESP_FAIL(-1) Parameter error * - Others(>=0) The number of data bytes that read from I2C slave buffer. */ int i2c_slave_read_buffer(i2c_port_t i2c_num, uint8_t* data, size_t max_size, TickType_t ticks_to_wait); /** * @brief set I2C master clock period * * @param i2c_num I2C port number * @param high_period clock cycle number during SCL is high level, high_period is a 14 bit value * @param low_period clock cycle number during SCL is low level, low_period is a 14 bit value * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t i2c_set_period(i2c_port_t i2c_num, int high_period, int low_period); /** * @brief get I2C master clock period * * @param i2c_num I2C port number * @param high_period pointer to get clock cycle number during SCL is high level, will get a 14 bit value * @param low_period pointer to get clock cycle number during SCL is low level, will get a 14 bit value * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t i2c_get_period(i2c_port_t i2c_num, int* high_period, int* low_period); /** * @brief set I2C master start signal timing * * @param i2c_num I2C port number * @param setup_time clock number between the falling-edge of SDA and rising-edge of SCL for start mark, it's a 10-bit value. * @param hold_time clock num between the falling-edge of SDA and falling-edge of SCL for start mark, it's a 10-bit value. * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t i2c_set_start_timing(i2c_port_t i2c_num, int setup_time, int hold_time); /** * @brief get I2C master start signal timing * * @param i2c_num I2C port number * @param setup_time pointer to get setup time * @param hold_time pointer to get hold time * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t i2c_get_start_timing(i2c_port_t i2c_num, int* setup_time, int* hold_time); /** * @brief set I2C master stop signal timing * * @param i2c_num I2C port number * @param setup_time clock num between the rising-edge of SCL and the rising-edge of SDA, it's a 10-bit value. * @param hold_time clock number after the STOP bit's rising-edge, it's a 14-bit value. * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t i2c_set_stop_timing(i2c_port_t i2c_num, int setup_time, int hold_time); /** * @brief get I2C master stop signal timing * * @param i2c_num I2C port number * @param setup_time pointer to get setup time. * @param hold_time pointer to get hold time. * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t i2c_get_stop_timing(i2c_port_t i2c_num, int* setup_time, int* hold_time); /** * @brief set I2C data signal timing * * @param i2c_num I2C port number * @param sample_time clock number I2C used to sample data on SDA after the rising-edge of SCL, it's a 10-bit value * @param hold_time clock number I2C used to hold the data after the falling-edge of SCL, it's a 10-bit value * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t i2c_set_data_timing(i2c_port_t i2c_num, int sample_time, int hold_time); /** * @brief get I2C data signal timing * * @param i2c_num I2C port number * @param sample_time pointer to get sample time * @param hold_time pointer to get hold time * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t i2c_get_data_timing(i2c_port_t i2c_num, int* sample_time, int* hold_time); /** * @brief set I2C timeout value * @param i2c_num I2C port number * @param timeout timeout value for I2C bus (unit: APB 80Mhz clock cycle) * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t i2c_set_timeout(i2c_port_t i2c_num, int timeout); /** * @brief get I2C timeout value * @param i2c_num I2C port number * @param timeout pointer to get timeout value * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t i2c_get_timeout(i2c_port_t i2c_num, int* timeout); /** * @brief set I2C data transfer mode * * @param i2c_num I2C port number * @param tx_trans_mode I2C sending data mode * @param rx_trans_mode I2C receving data mode * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t i2c_set_data_mode(i2c_port_t i2c_num, i2c_trans_mode_t tx_trans_mode, i2c_trans_mode_t rx_trans_mode); /** * @brief get I2C data transfer mode * * @param i2c_num I2C port number * @param tx_trans_mode pointer to get I2C sending data mode * @param rx_trans_mode pointer to get I2C receiving data mode * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t i2c_get_data_mode(i2c_port_t i2c_num, i2c_trans_mode_t *tx_trans_mode, i2c_trans_mode_t *rx_trans_mode); #ifdef __cplusplus } #endif #endif /*_DRIVER_I2C_H_*/