/* * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 *//* ... */#pragmaonce#include<stdint.h>#include<stdatomic.h>#include<sys/queue.h>#include"esp_err.h"#include"driver/i2c_types.h"#include"hal/i2c_hal.h"#include"freertos/FreeRTOS.h"#include"freertos/semphr.h"#include"freertos/task.h"#include"freertos/ringbuf.h"#include"driver/i2c_slave.h"#include"esp_private/periph_ctrl.h"#include"esp_pm.h"#include"sdkconfig.h"14 includes#ifdef__cplusplusextern"C"{#endif#ifSOC_PERIPH_CLK_CTRL_SHARED#defineI2C_CLOCK_SRC_ATOMIC()PERIPH_RCC_ATOMIC()#else#defineI2C_CLOCK_SRC_ATOMIC()#endif#if!SOC_RCC_IS_INDEPENDENT#defineI2C_RCC_ATOMIC()PERIPH_RCC_ATOMIC()#else#defineI2C_RCC_ATOMIC()#endif#ifSOC_LP_I2C_SUPPORTED#defineLP_I2C_SRC_CLK_ATOMIC()PERIPH_RCC_ATOMIC()#defineLP_I2C_BUS_CLK_ATOMIC()PERIPH_RCC_ATOMIC()/* ... */#endif#ifCONFIG_I2C_ISR_IRAM_SAFE#defineI2C_MEM_ALLOC_CAPS(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)#else#defineI2C_MEM_ALLOC_CAPS(MALLOC_CAP_DEFAULT)#endif// I2C driver object is per-mode, the interrupt source is shared between modes#ifCONFIG_I2C_ISR_IRAM_SAFE#defineI2C_INTR_ALLOC_FLAG(ESP_INTR_FLAG_SHARED|ESP_INTR_FLAG_IRAM|ESP_INTR_FLAG_LOWMED)#else#defineI2C_INTR_ALLOC_FLAG(ESP_INTR_FLAG_SHARED|ESP_INTR_FLAG_LOWMED)#endif// Use retention link only when the target supports sleep retention and PM is enabled#defineI2C_USE_RETENTION_LINK(SOC_I2C_SUPPORT_SLEEP_RETENTION&&CONFIG_PM_ENABLE&&CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP)#defineI2C_ALLOW_INTR_PRIORITY_MASKESP_INTR_FLAG_LOWMED#defineI2C_PM_LOCK_NAME_LEN_MAX16#defineI2C_STATIC_OPERATION_ARRAY_MAX6#defineACK_VAL0#defineNACK_VAL1#defineI2C_TRANS_READ_COMMAND(ack_value){.ack_val=(ack_value),.op_code=I2C_LL_CMD_READ}#defineI2C_TRANS_WRITE_COMMAND(ack_check){.ack_en=(ack_check),.op_code=I2C_LL_CMD_WRITE}#defineI2C_TRANS_STOP_COMMAND{.op_code=I2C_LL_CMD_STOP}#defineI2C_TRANS_START_COMMAND{.op_code=I2C_LL_CMD_RESTART}10 definestypedefstructi2c_bus_ti2c_bus_t;typedefstructi2c_master_bus_ti2c_master_bus_t;typedefstructi2c_bus_t*i2c_bus_handle_t;typedefstructi2c_master_dev_ti2c_master_dev_t;typedefstructi2c_slave_dev_ti2c_slave_dev_t;typedefenum{I2C_BUS_MODE_MASTER=0,I2C_BUS_MODE_SLAVE=1,}{ ... }i2c_bus_mode_t;typedefenum{I2C_SLAVE_FIFO=0,I2C_SLAVE_NONFIFO=1,}{ ... }i2c_slave_fifo_mode_t;enum{I2C_TRANS_QUEUE_READY,I2C_TRANS_QUEUE_PROGRESS,I2C_TRANS_QUEUE_COMPLETE,I2C_TRANS_QUEUE_MAX,}{ ... };typedefstruct{i2c_ll_hw_cmd_thw_cmd;// I2C command, defined by hardwareuint8_t*data;// Pointer to datauint16_tbytes_used;// I2C data has been usedsize_ttotal_bytes;// Total bytes to be transferred}{ ... }i2c_operation_t;typedefstruct{uint32_tdevice_address;// Address of I2C devicei2c_operation_t*ops;// Pointer to I2C operation structuresize_tcmd_count;// Record how many I2C hardware commands in one transaction}{ ... }i2c_transaction_t;structi2c_bus_t{i2c_port_num_tport_num;// Port(Bus) ID, index from 0boolis_lp_i2c;// true if current port is lp_i2c. false is hp_i2cportMUX_TYPEspinlock;// To protect pre-group register level concurrency accessi2c_hal_context_thal;// Hal layer for each port(bus)soc_module_clk_tclk_src;// Record the port clock sourceuint32_tclk_src_freq_hz;// Record the clock source frequencyintsda_num;// SDA pin numberintscl_num;// SCL pin numberboolpull_up_enable;// Enable pull-upsintr_handle_tintr_handle;// I2C interrupt handleesp_pm_lock_handle_tpm_lock;// power manage lock#ifCONFIG_PM_ENABLEcharpm_lock_name[I2C_PM_LOCK_NAME_LEN_MAX];// pm lock name#endifi2c_bus_mode_tbus_mode;// I2C bus mode#ifSOC_I2C_SUPPORT_SLEEP_RETENTIONboolretention_link_created;// mark if the retention link is created.#endif}{ ... };typedefstructi2c_master_device_list{i2c_master_dev_t*device;SLIST_ENTRY(i2c_master_device_list)next;}{ ... }i2c_master_device_list_t;structi2c_master_bus_t{i2c_bus_t*base;// bus base classSemaphoreHandle_tbus_lock_mux;// semaphore to lock bus processintcmd_idx;//record current command index, for master mode_Atomici2c_master_status_tstatus;// record current command status, for master modei2c_master_event_tevent;// record current i2c bus eventintrx_cnt;// record current read index, for master modei2c_transaction_ti2c_trans;// Pointer to I2C transfer structurei2c_operation_ti2c_ops[I2C_STATIC_OPERATION_ARRAY_MAX];// I2C operation array_Atomicuint16_ttrans_idx;// Index of I2C transaction command.SemaphoreHandle_tcmd_semphr;// Semaphore between task and interrupt, using for synchronizing ISR and I2C task.QueueHandle_tevent_queue;// I2C event queueuint32_tread_buf_pos;// Read buffer positionboolcontains_read;// Whether command array includes read operation, true: yes, otherwise, false.uint32_tread_len_static;// Read static buffer lengthuint32_tw_r_size;// The size send/receive last time.booltrans_over_buffer;// Data length is more than hardware fifo length, needs interrupt.boolasync_trans;// asynchronous transaction, true after callback is installed.boolack_check_disable;// Disable ACK checkvolatilebooltrans_done;// transaction command finishboolbypass_nack_log;// Bypass the error log. Sometimes the error is expected.SLIST_HEAD(i2c_master_device_list_head,i2c_master_device_list)device_list;// I2C device (instance) list// async trans membersboolasync_break;// break transaction loop flag.i2c_addr_bit_len_taddr_10bits_bus;// Slave address is 10 bits.size_tqueue_size;// I2C transaction queue size.size_tnum_trans_inflight;// Indicates the number of transactions that are undergoing but not recycled to ready_queuesize_tnum_trans_inqueue;// Indicates the number of transaction in queue transaction.void*queues_storage;// storage of transaction queuesboolsent_all;// true if the queue transaction is sentboolin_progress;// true if current transaction is in progressbooltrans_finish;// true if current command has been sent out.boolqueue_trans;// true if current transaction is in queueboolnew_queue;// true if allow a new queue transactionQueueHandle_ttrans_queues[I2C_TRANS_QUEUE_MAX];// transaction queues.StaticQueue_ttrans_queue_structs[I2C_TRANS_QUEUE_MAX];// memory to store the static structure for trans_queuesi2c_operation_t(*i2c_async_ops)[I2C_STATIC_OPERATION_ARRAY_MAX];// pointer to asynchronous operation(s).uint32_tops_prepare_idx;// Index for the operations can be written into `i2c_async_ops` array.uint32_tops_cur_size;// Indicates how many operations have already put in `i2c_async_ops`.i2c_transaction_ti2c_trans_pool[];// I2C transaction pool.}{ ... };structi2c_master_dev_t{i2c_master_bus_t*master_bus;// I2C master bus base classuint16_tdevice_address;// I2C device addressuint32_tscl_speed_hz;// SCL clock frequencyuint32_tscl_wait_us;// SCL await time (unit:us)i2c_addr_bit_len_taddr_10bits;// Whether I2C device is a 10-bits address device.boolack_check_disable;// Disable ACK checki2c_master_callback_ton_trans_done;// I2C master transaction done callback.void*user_ctx;// Callback user context}{ ... };typedefstruct{booltrans_complete;// Event of transaction completeboolslave_stretch;// Event of slave stretch happensbooladdr_unmatch;// Event of address unmatched}{ ... }i2c_slave_evt_t;typedefstruct{uint8_t*buffer;// Pointer to the buffer need to be received in ISRuint32_trcv_fifo_cnt;// receive fifo count.}{ ... }i2c_slave_receive_t;#if!CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2structi2c_slave_dev_t{i2c_bus_t*base;// bus base classSemaphoreHandle_tslv_rx_mux;// Mutex for slave rx directionSemaphoreHandle_tslv_tx_mux;// Mutex for slave tx directionRingbufHandle_trx_ring_buf;// Handle for rx ringbufferRingbufHandle_ttx_ring_buf;// Handle for tx ringbufferuint8_tdata_buf[SOC_I2C_FIFO_LEN];// Data buffer for slaveuint32_ttrans_data_length;// Send data lengthi2c_slave_event_callbacks_tcallbacks;// I2C slave callbacksvoid*user_ctx;// Callback user contexti2c_slave_fifo_mode_tfifo_mode;// Slave fifo mode.QueueHandle_tslv_evt_queue;// Event Queue used in slave nonfifo mode.i2c_slave_evt_tslave_evt;// Slave event structure.i2c_slave_receive_treceive_desc;// Slave receive descriptoruint32_talready_receive_len;// Data length already received in ISR.}{ ... };/* ... */#else// CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2structi2c_slave_dev_t{i2c_bus_t*base;// bus base classSemaphoreHandle_toperation_mux;// Mux for i2c slave operationi2c_slave_request_callback_trequest_callback;// i2c slave request callbacki2c_slave_received_callback_treceive_callback;// i2c_slave receive callbackvoid*user_ctx;// Callback user contextRingbufHandle_trx_ring_buf;// receive ringbufferRingbufHandle_ttx_ring_buf;// transmit ringbufferuint32_trx_data_count;// receive data counti2c_slave_receive_treceive_desc;// slave receive descriptor}{...};/* ... */#endif// CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2/** * @brief Acquire I2C bus handle * * @param port_num I2C port number. * @return * - ESP_OK: Acquire bus handle successfully. * - ESP_ERR_INVALID_ARG: Argument error. * - ESP_ERR_INVALID_STATE: Acquire bus invalid state because bus has already acquired. *//* ... */esp_err_ti2c_acquire_bus_handle(i2c_port_num_tport_num,i2c_bus_handle_t*i2c_new_bus,i2c_bus_mode_tmode);/** * @brief Release I2C bus handle * * @param i2c_bus I2C bus handle, returned from `i2c_acquire_bus_handle` * @return ESP_OK: If release successfully * ESP_ERR_INVALID_STATE: Release bus failed because same bus has been required several times. * Otherwise: Other reasons. *//* ... */esp_err_ti2c_release_bus_handle(i2c_bus_handle_ti2c_bus);/** * @brief Set clock source for I2C peripheral * * @param handle I2C bus handle * @param clk_src Clock source * @return * - ESP_OK: Set clock source successfully * - ESP_ERR_NOT_SUPPORTED: Set clock source failed because the clk_src is not supported * - ESP_ERR_INVALID_STATE: Set clock source failed because the clk_src is different from other I2C controller * - ESP_FAIL: Set clock source failed because of other error *//* ... */esp_err_ti2c_select_periph_clock(i2c_bus_handle_thandle,soc_module_clk_tclk_src);/** * @brief Set I2C SCL/SDA pins * * @param handle I2C bus handle * @return * - ESP_OK: I2C set SCL/SDA pins successfully. * - ESP_ERR_INVALID_ARG: Argument error. * - Otherwise: Set SCL/SDA IOs error. *//* ... */esp_err_ti2c_common_set_pins(i2c_bus_handle_thandle);/** * @brief Deinit I2C SCL/SDA pins * * @param handle I2C bus handle * @return * - ESP_OK: I2C set SCL/SDA pins successfully. * - ESP_ERR_INVALID_ARG: Argument error. * - Otherwise: Set SCL/SDA IOs error. *//* ... */esp_err_ti2c_common_deinit_pins(i2c_bus_handle_thandle);/** * @brief Check whether bus is acquired * * @param port_num number of port * @return true if the bus is occupied, false if the bus is not occupied.*//* ... */booli2c_bus_occupied(i2c_port_num_tport_num);/** * @brief Create sleep retention link * * @param handle I2C bus handle *//* ... */voidi2c_create_retention_module(i2c_bus_handle_thandle);#ifdef__cplusplus}{...}#endif
Details
Show: from
Types: Columns:
All items filtered out
All items filtered out
This file uses the notable symbols shown below. Click anywhere in the file to view more details.