i2c_private.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #pragma once
  7. #include <stdint.h>
  8. #include <stdatomic.h>
  9. #include <sys/queue.h>
  10. #include "esp_err.h"
  11. #include "driver/i2c_types.h"
  12. #include "hal/i2c_hal.h"
  13. #include "freertos/FreeRTOS.h"
  14. #include "freertos/semphr.h"
  15. #include "freertos/task.h"
  16. #include "freertos/ringbuf.h"
  17. #include "driver/i2c_slave.h"
  18. #include "esp_private/periph_ctrl.h"
  19. #include "esp_pm.h"
  20. #ifdef __cplusplus
  21. extern "C" {
  22. #endif
  23. #if SOC_PERIPH_CLK_CTRL_SHARED
  24. #define I2C_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC()
  25. #else
  26. #define I2C_CLOCK_SRC_ATOMIC()
  27. #endif
  28. #if !SOC_RCC_IS_INDEPENDENT
  29. #define I2C_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
  30. #else
  31. #define I2C_RCC_ATOMIC()
  32. #endif
  33. #if CONFIG_I2C_ISR_IRAM_SAFE
  34. #define I2C_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
  35. #else
  36. #define I2C_MEM_ALLOC_CAPS (MALLOC_CAP_DEFAULT)
  37. #endif
  38. // I2C driver object is per-mode, the interrupt source is shared between modes
  39. #if CONFIG_I2C_ISR_IRAM_SAFE
  40. #define I2C_INTR_ALLOC_FLAG (ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_LOWMED)
  41. #else
  42. #define I2C_INTR_ALLOC_FLAG (ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_LOWMED)
  43. #endif
  44. #define I2C_ALLOW_INTR_PRIORITY_MASK ESP_INTR_FLAG_LOWMED
  45. #define I2C_PM_LOCK_NAME_LEN_MAX 16
  46. #define I2C_STATIC_OPERATION_ARRAY_MAX 6
  47. #define ACK_VAL 0
  48. #define NACK_VAL 1
  49. #define I2C_TRANS_READ_COMMAND(ack_value) {.ack_val = (ack_value), .op_code = I2C_LL_CMD_READ}
  50. #define I2C_TRANS_WRITE_COMMAND(ack_check) {.ack_en = (ack_check), .op_code = I2C_LL_CMD_WRITE}
  51. #define I2C_TRANS_STOP_COMMAND {.op_code = I2C_LL_CMD_STOP}
  52. #define I2C_TRANS_START_COMMAND {.op_code = I2C_LL_CMD_RESTART}
  53. typedef struct i2c_bus_t i2c_bus_t;
  54. typedef struct i2c_master_bus_t i2c_master_bus_t;
  55. typedef struct i2c_bus_t *i2c_bus_handle_t;
  56. typedef struct i2c_master_dev_t i2c_master_dev_t;
  57. typedef struct i2c_slave_dev_t i2c_slave_dev_t;
  58. typedef enum {
  59. I2C_BUS_MODE_MASTER = 0,
  60. I2C_BUS_MODE_SLAVE = 1,
  61. } i2c_bus_mode_t;
  62. typedef enum {
  63. I2C_SLAVE_FIFO = 0,
  64. I2C_SLAVE_NONFIFO = 1,
  65. } i2c_slave_fifo_mode_t;
  66. enum {
  67. I2C_TRANS_QUEUE_READY,
  68. I2C_TRANS_QUEUE_PROGRESS,
  69. I2C_TRANS_QUEUE_COMPLETE,
  70. I2C_TRANS_QUEUE_MAX,
  71. };
  72. typedef struct {
  73. i2c_ll_hw_cmd_t hw_cmd; // I2C command, defined by hardware
  74. uint8_t *data; // Pointer to data
  75. uint16_t bytes_used; // I2C data has been used
  76. size_t total_bytes; // Total bytes to be transferred
  77. } i2c_operation_t;
  78. typedef struct {
  79. uint32_t device_address; // Address of I2C device
  80. i2c_operation_t *ops; // Pointer to I2C operation structure
  81. size_t cmd_count; // Record how many I2C hardware commands in one transaction
  82. } i2c_transaction_t;
  83. struct i2c_bus_t {
  84. i2c_port_num_t port_num; // Port(Bus) ID, index from 0
  85. portMUX_TYPE spinlock; // To protect pre-group register level concurrency access
  86. i2c_hal_context_t hal; // Hal layer for each port(bus)
  87. i2c_clock_source_t clk_src; // Record the port clock source
  88. uint32_t clk_src_freq_hz; // Record the clock source frequency
  89. int sda_num; // SDA pin number
  90. int scl_num; // SCL pin number
  91. bool pull_up_enable; // Enable pull-ups
  92. intr_handle_t intr_handle; // I2C interrupt handle
  93. esp_pm_lock_handle_t pm_lock; // power manange lock
  94. #if CONFIG_PM_ENABLE
  95. char pm_lock_name[I2C_PM_LOCK_NAME_LEN_MAX]; // pm lock name
  96. #endif
  97. i2c_bus_mode_t bus_mode; // I2C bus mode
  98. };
  99. typedef struct i2c_master_device_list {
  100. i2c_master_dev_t *device;
  101. SLIST_ENTRY(i2c_master_device_list) next;
  102. } i2c_master_device_list_t;
  103. struct i2c_master_bus_t {
  104. i2c_bus_t *base; // bus base class
  105. SemaphoreHandle_t bus_lock_mux; // semaphore to lock bus process
  106. int cmd_idx; //record current command index, for master mode
  107. _Atomic i2c_master_status_t status; // record current command status, for master mode
  108. i2c_master_event_t event; // record current i2c bus event
  109. int rx_cnt; // record current read index, for master mode
  110. i2c_transaction_t i2c_trans; // Pointer to I2C transfer structure
  111. i2c_operation_t i2c_ops[I2C_STATIC_OPERATION_ARRAY_MAX]; // I2C operation array
  112. _Atomic uint16_t trans_idx; // Index of I2C transaction command.
  113. SemaphoreHandle_t cmd_semphr; // Semaphore between task and interrupt, using for synchronizing ISR and I2C task.
  114. uint32_t read_buf_pos; // Read buffer position
  115. bool contains_read; // Whether command array includes read operation, true: yes, otherwise, false.
  116. uint32_t read_len_static; // Read static buffer length
  117. uint32_t w_r_size; // The size send/receive last time.
  118. bool trans_over_buffer; // Data length is more than hardware fifo length, needs interrupt.
  119. bool asnyc_trans; // asynchronous transaction, true after callback is installed.
  120. volatile bool trans_done; // transaction command finish
  121. SLIST_HEAD(i2c_master_device_list_head, i2c_master_device_list) device_list; // I2C device (instance) list
  122. // asnyc trans members
  123. bool async_break; // break transaction loop flag.
  124. i2c_addr_bit_len_t addr_10bits_bus; // Slave address is 10 bits.
  125. size_t queue_size; // I2C transaction queue size.
  126. size_t num_trans_inflight; // Indicates the number of transactions that are undergoing but not recycled to ready_queue
  127. size_t num_trans_inqueue; // Indicates the number of transaction in queue transaction.
  128. void* queues_storage; // storage of transaction queues
  129. bool sent_all; // true if the queue transaction is sent
  130. bool in_progress; // true if current transaction is in progress
  131. bool trans_finish; // true if current command has been sent out.
  132. bool queue_trans; // true if current transaction is in queue
  133. bool new_queue; // true if allow a new queue transaction
  134. size_t index; // transaction index
  135. QueueHandle_t trans_queues[I2C_TRANS_QUEUE_MAX]; // transaction queues.
  136. StaticQueue_t trans_queue_structs[I2C_TRANS_QUEUE_MAX]; // memory to store the static structure for trans_queues
  137. i2c_operation_t **i2c_anyc_ops; // pointer to asynchronous operation.
  138. uint8_t **anyc_write_buffer; // pointer to asynchronous write buffer.
  139. i2c_transaction_t i2c_trans_pool[]; // I2C transaction pool.
  140. };
  141. struct i2c_master_dev_t {
  142. i2c_master_bus_t *master_bus; // I2C master bus base class
  143. uint16_t device_address; // I2C device address
  144. uint32_t scl_speed_hz; // SCL clock frequency
  145. i2c_addr_bit_len_t addr_10bits; // Whether I2C device is a 10-bits address device.
  146. i2c_master_callback_t on_trans_done; // I2C master transaction done callback.
  147. void *user_ctx; // Callback user context
  148. };
  149. typedef struct {
  150. bool trans_complete; // Event of transaction complete
  151. bool slave_stretch; // Event of slave stretch happens
  152. bool addr_unmatch; // Event of address unmatched
  153. } i2c_slave_evt_t;
  154. typedef struct {
  155. uint8_t *buffer; // Pointer to the buffer need to be received in ISR
  156. uint32_t rcv_fifo_cnt; // receive fifo count.
  157. } i2c_slave_receive_t;
  158. struct i2c_slave_dev_t {
  159. i2c_bus_t *base; // bus base class
  160. SemaphoreHandle_t slv_rx_mux; // Mutex for slave rx direction
  161. SemaphoreHandle_t slv_tx_mux; // Mutex for slave tx direction
  162. RingbufHandle_t rx_ring_buf; // Handle for rx ringbuffer
  163. RingbufHandle_t tx_ring_buf; // Handle for tx ringbuffer
  164. uint8_t data_buf[SOC_I2C_FIFO_LEN]; // Data buffer for slave
  165. uint32_t trans_data_length; // Send data length
  166. i2c_slave_event_callbacks_t callbacks; // I2C slave callbacks
  167. void *user_ctx; // Callback user context
  168. i2c_slave_fifo_mode_t fifo_mode; // Slave fifo mode.
  169. QueueHandle_t slv_evt_queue; // Event Queue used in slave nonfifo mode.
  170. i2c_slave_evt_t slave_evt; // Slave event structure.
  171. i2c_slave_receive_t receive_desc; // Slave receive descriptor
  172. uint32_t already_receive_len; // Data length already received in ISR.
  173. };
  174. /**
  175. * @brief Acquire I2C bus handle
  176. *
  177. * @param port_num I2C port number.
  178. * @return
  179. * - ESP_OK: Acquire bus handle successfully.
  180. * - ESP_ERR_INVALID_ARG: Argument error.
  181. * - ESP_ERR_INVALID_STATE: Acquire bus invalid state because bus has already acquired.
  182. */
  183. esp_err_t i2c_acquire_bus_handle(i2c_port_num_t port_num, i2c_bus_handle_t *i2c_new_bus, i2c_bus_mode_t mode);
  184. /**
  185. * @brief Release I2C bus handle
  186. *
  187. * @param i2c_bus I2C bus handle, returned from `i2c_acquire_bus_handle`
  188. * @return ESP_OK: If release successfully
  189. * ESP_ERR_INVALID_STATE: Release bus failed because same bus has been required several times.
  190. * Otherwise: Other reasons.
  191. */
  192. esp_err_t i2c_release_bus_handle(i2c_bus_handle_t i2c_bus);
  193. /**
  194. * @brief Set clock source for I2C peripheral
  195. *
  196. * @param handle I2C bus handle
  197. * @param clk_src Clock source
  198. * @return
  199. * - ESP_OK: Set clock source successfully
  200. * - ESP_ERR_NOT_SUPPORTED: Set clock source failed because the clk_src is not supported
  201. * - ESP_ERR_INVALID_STATE: Set clock source failed because the clk_src is different from other I2C controller
  202. * - ESP_FAIL: Set clock source failed because of other error
  203. */
  204. esp_err_t i2c_select_periph_clock(i2c_bus_handle_t handle, i2c_clock_source_t clk_src);
  205. /**
  206. * @brief Set I2C SCL/SDA pins
  207. *
  208. * @param handle I2C bus handle
  209. * @return
  210. * - ESP_OK: I2C set SCL/SDA pins successfully.
  211. * - ESP_ERR_INVALID_ARG: Argument error.
  212. * - Otherwise: Set SCL/SDA IOs error.
  213. */
  214. esp_err_t i2c_common_set_pins(i2c_bus_handle_t handle);
  215. #ifdef __cplusplus
  216. }
  217. #endif