HPM SDK
HPMicro Software Development Kit
hpm_i2c_drv.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef HPM_I2C_DRV_H
9 #define HPM_I2C_DRV_H
10 #include "hpm_common.h"
11 #include "hpm_i2c_regs.h"
12 #include "hpm_soc_feature.h"
13 
24 enum {
30 };
31 
32 /* convert data count value into register(CTRL[DATACNT] and CTRL[DATACNT_HIGH] if exist) */
33 /* x range from 1 to I2C_SOC_TRANSFER_COUNT_MAX */
34 /* 0 for I2C_SOC_TRANSFER_COUNT_MAX */
35 #define I2C_DATACNT_MAP(x) (((x) == I2C_SOC_TRANSFER_COUNT_MAX) ? 0 : x)
36 
40 #define I2C_CMD_NO_ACTION (I2C_CMD_CMD_SET(0))
41 #define I2C_CMD_ISSUE_DATA_TRANSMISSION (I2C_CMD_CMD_SET(1))
42 #define I2C_CMD_ACK (I2C_CMD_CMD_SET(2))
43 #define I2C_CMD_NACK (I2C_CMD_CMD_SET(3))
44 #define I2C_CMD_CLEAR_FIFO (I2C_CMD_CMD_SET(4))
45 #define I2C_CMD_RESET (I2C_CMD_CMD_SET(5))
46 
50 #define I2C_DIR_MASTER_WRITE (0U)
51 #define I2C_DIR_MASTER_READ (1U)
52 #define I2C_DIR_SLAVE_READ (0U)
53 #define I2C_DIR_SLAVE_WRITE (1U)
54 
58 #define I2C_EVENT_TRANSACTION_COMPLETE I2C_INTEN_CMPL_MASK
59 #define I2C_EVENT_BYTE_RECEIVED I2C_INTEN_BYTERECV_MASK
60 #define I2C_EVENT_BYTE_TRANSMIT I2C_INTEN_BYTETRANS_MASK
61 #define I2C_EVENT_START_CONDITION I2C_INTEN_START_MASK
62 #define I2C_EVENT_STOP_CONDITION I2C_INTEN_STOP_MASK
63 #define I2C_EVENT_LOSS_ARBITRATION I2C_INTEN_ARBLOSE_MASK
64 #define I2C_EVENT_ADDRESS_HIT I2C_INTEN_ADDRHIT_MASK
65 #define I2C_EVENT_FIFO_HALF I2C_INTEN_FIFOHALF_MASK
66 #define I2C_EVENT_FIFO_FULL I2C_INTEN_FIFOFULL_MASK
67 #define I2C_EVENT_FIFO_EMPTY I2C_INTEN_FIFOEMPTY_MASK
68 
69 #define I2C_EVENT_ALL_MASK (I2C_INTEN_CMPL_MASK \
70  | I2C_INTEN_BYTERECV_MASK \
71  | I2C_INTEN_BYTETRANS_MASK \
72  | I2C_INTEN_START_MASK \
73  | I2C_INTEN_STOP_MASK \
74  | I2C_INTEN_ARBLOSE_MASK \
75  | I2C_INTEN_ADDRHIT_MASK \
76  | I2C_INTEN_FIFOHALF_MASK \
77  | I2C_INTEN_FIFOFULL_MASK \
78  | I2C_INTEN_FIFOEMPTY_MASK)
82 #define I2C_STATUS_LINE_SDA I2C_STATUS_LINESDA_MASK
83 #define I2C_STATUS_LINE_SCL I2C_STATUS_LINESCL_MASK
84 #define I2C_STATUS_GENERAL_CALL I2C_STATUS_GENCALL_MASK
85 #define I2C_STATUS_BUS_BUSY I2C_STATUS_BUSBUSY_MASK
86 #define I2C_STATUS_ACK I2C_STATUS_ACK_MASK
87 
88 #define I2C_WR 0x0000 /* not operable with read flags*/
89 #define I2C_RD (1u << 0) /* not operable with write flags*/
90 #define I2C_ADDR_10BIT (1u << 2) /* this is a ten bit chip address */
91 #define I2C_NO_START (1u << 4) /* no start */
92 #define I2C_NO_READ_ACK (1u << 6) /* when I2C reading, we do not ACK */
93 #define I2C_NO_STOP (1u << 7) /* no stop */
94 #define I2C_WRITE_CHECK_ACK (1u << 8) /* when I2C writing, need check the slave returns ack */
95 
99 typedef struct {
101  uint8_t i2c_mode;
102 } i2c_config_t;
103 
107 typedef enum i2c_mode {
112 
119 typedef enum i2c_seq_transfer_opt {
124 
125 #ifdef __cplusplus
126 extern "C" {
127 #endif
128 
134 static inline void i2c_respond_Nack(I2C_Type *ptr)
135 {
136  ptr->CMD = I2C_CMD_NACK;
137 }
138 
144 static inline void i2c_respond_ack(I2C_Type *ptr)
145 {
146  ptr->CMD = I2C_CMD_ACK;
147 }
148 
154 static inline void i2c_clear_fifo(I2C_Type *ptr)
155 {
156  ptr->CMD = I2C_CMD_CLEAR_FIFO;
157 }
158 
167 static inline uint16_t i2c_get_data_count(I2C_Type *ptr)
168 {
169  uint32_t i2c_ctrl = ptr->CTRL;
170 #ifdef I2C_CTRL_DATACNT_HIGH_MASK
171  return (I2C_CTRL_DATACNT_HIGH_GET(i2c_ctrl) << 8U) + I2C_CTRL_DATACNT_GET(i2c_ctrl);
172 #else
173  return I2C_CTRL_DATACNT_GET(i2c_ctrl);
174 #endif
175 }
176 
183 static inline bool i2c_fifo_is_full(I2C_Type *ptr)
184 {
185  return ptr->STATUS & I2C_STATUS_FIFOFULL_MASK;
186 }
187 
197 static inline bool i2c_fifo_is_half(I2C_Type *ptr)
198 {
199  return ptr->STATUS & I2C_STATUS_FIFOHALF_MASK;
200 }
201 
208 static inline bool i2c_fifo_is_empty(I2C_Type *ptr)
209 {
210  return ptr->STATUS & I2C_STATUS_FIFOEMPTY_MASK;
211 }
212 
222 static inline bool i2c_is_writing(I2C_Type *ptr)
223 {
224  return (ptr->CTRL & I2C_CTRL_DIR_MASK);
225 }
226 
236 static inline bool i2c_is_reading(I2C_Type *ptr)
237 {
238  return !i2c_is_writing(ptr);
239 }
240 
250 static inline bool i2c_get_line_sda_status(I2C_Type *ptr)
251 {
252  return I2C_STATUS_LINESDA_GET(ptr->STATUS);
253 }
254 
264 static inline bool i2c_get_line_scl_status(I2C_Type *ptr)
265 {
266  return I2C_STATUS_LINESCL_GET(ptr->STATUS);
267 }
268 
277 static inline void i2c_clear_status(I2C_Type *ptr, uint32_t mask)
278 {
279  ptr->STATUS = mask;
280 }
281 
290 static inline uint32_t i2c_get_status(I2C_Type *ptr)
291 {
292  return ptr->STATUS;
293 }
294 
303 static inline uint32_t i2c_get_irq_setting(I2C_Type *ptr)
304 {
305  return ptr->INTEN;
306 }
307 
316 static inline void i2c_disable_irq(I2C_Type *ptr, uint32_t mask)
317 {
318  ptr->INTEN &= ~mask;
319 }
320 
329 static inline void i2c_enable_irq(I2C_Type *ptr, uint32_t mask)
330 {
331  ptr->INTEN |= mask;
332 }
333 
341 static inline void i2c_disable_auto_ack(I2C_Type *ptr)
342 {
344 }
345 
353 static inline void i2c_enable_auto_ack(I2C_Type *ptr)
354 {
356 }
357 
368 static inline void i2c_enable_10bit_address_mode(I2C_Type *ptr, bool enable)
369 {
370  ptr->SETUP |= I2C_SETUP_ADDRESSING_SET(enable);
371 }
372 
384  uint32_t src_clk_in_hz,
385  i2c_config_t *config);
386 
402  const uint16_t device_address,
403  uint8_t *addr,
404  uint32_t addr_size_in_byte,
405  uint8_t *buf,
406  const uint32_t size_in_byte);
407 
423  const uint16_t device_address,
424  uint8_t *addr,
425  uint32_t addr_size_in_byte,
426  uint8_t *buf,
427  const uint32_t size_in_byte);
428 
442  const uint16_t device_address,
443  uint8_t *buf,
444  const uint32_t size);
445 
457 hpm_stat_t i2c_master_start_dma_write(I2C_Type *i2c_ptr, const uint16_t device_address, uint32_t size);
458 
470 hpm_stat_t i2c_master_start_dma_read(I2C_Type *i2c_ptr, const uint16_t device_address, uint32_t size);
471 
485  const uint16_t device_address,
486  uint8_t *buf,
487  const uint32_t size);
499 hpm_stat_t i2c_init_slave(I2C_Type *ptr, uint32_t src_clk_in_hz,
500  i2c_config_t *config, const uint16_t slave_address);
501 
513 hpm_stat_t i2c_slave_read(I2C_Type *ptr, uint8_t *buf, const uint32_t size);
514 
526 hpm_stat_t i2c_slave_write(I2C_Type *ptr, uint8_t *buf, const uint32_t size);
527 
533 void i2c_reset(I2C_Type *ptr);
534 
540 static inline void i2c_dma_enable(I2C_Type *ptr)
541 {
542  ptr->SETUP |= I2C_SETUP_DMAEN_MASK;
543 }
544 
550 static inline void i2c_dma_disable(I2C_Type *ptr)
551 {
552  ptr->SETUP &= ~I2C_SETUP_DMAEN_MASK;
553 }
554 
564 hpm_stat_t i2c_slave_dma_transfer(I2C_Type *ptr, const uint32_t size);
565 
572 static inline void i2c_write_byte(I2C_Type *ptr, uint8_t data)
573 {
574  ptr->DATA = I2C_DATA_DATA_SET(data);
575 }
576 
583 static inline uint8_t i2c_read_byte(I2C_Type *ptr)
584 {
585  return (uint8_t)I2C_DATA_DATA_GET(ptr->DATA);
586 }
587 
596 static inline uint8_t i2c_get_direction(I2C_Type *ptr)
597 {
598  return (uint8_t)I2C_CTRL_DIR_GET(ptr->CTRL);
599 }
600 
610 hpm_stat_t i2c_master_configure_transfer(I2C_Type *i2c_ptr, const uint16_t device_address, uint32_t size, bool read);
611 
623 hpm_stat_t i2c_master_seq_transmit_check_ack(I2C_Type *ptr, const uint16_t device_address,
624  uint8_t *buf, const uint32_t size, i2c_seq_transfer_opt_t opt, bool ack_check);
625 
636 #define i2c_master_seq_transmit(ptr, device_address, buf, size, opt) i2c_master_seq_transmit_check_ack(ptr, device_address, buf, size, opt, false)
637 
648 hpm_stat_t i2c_master_seq_receive(I2C_Type *ptr, const uint16_t device_address,
649  uint8_t *buf, const uint32_t size, i2c_seq_transfer_opt_t opt);
650 
651 #if defined(HPM_IP_FEATURE_I2C_SUPPORT_RESET) && (HPM_IP_FEATURE_I2C_SUPPORT_RESET == 1)
658 static inline void i2c_gen_reset_signal(I2C_Type *ptr, uint8_t clk_len)
659 {
660  ptr->CTRL = (ptr->CTRL & ~I2C_CTRL_RESET_LEN_MASK) | I2C_CTRL_RESET_LEN_SET(clk_len) \
662 }
663 #endif
664 
675 hpm_stat_t i2c_master_transfer(I2C_Type *ptr, const uint16_t device_address,
676  uint8_t *buf, const uint32_t size, uint16_t flags);
681 #ifdef __cplusplus
682 }
683 #endif
684 
685 #endif /* HPM_I2C_DRV_H */
686 
#define I2C_DATA_DATA_GET(x)
Definition: hpm_i2c_regs.h:336
#define I2C_STATUS_FIFOHALF_MASK
Definition: hpm_i2c_regs.h:292
#define I2C_STATUS_FIFOEMPTY_MASK
Definition: hpm_i2c_regs.h:310
#define I2C_CTRL_RESET_HOLD_SCKIN_MASK
Definition: hpm_i2c_regs.h:368
#define I2C_STATUS_LINESDA_GET(x)
Definition: hpm_i2c_regs.h:167
#define I2C_CTRL_DATACNT_HIGH_GET(x)
Definition: hpm_i2c_regs.h:351
#define I2C_STATUS_FIFOFULL_MASK
Definition: hpm_i2c_regs.h:301
#define I2C_CTRL_DATACNT_GET(x)
Definition: hpm_i2c_regs.h:456
#define I2C_CTRL_DIR_MASK
Definition: hpm_i2c_regs.h:439
#define I2C_CTRL_RESET_LEN_MASK
Definition: hpm_i2c_regs.h:358
#define I2C_DATA_DATA_SET(x)
Definition: hpm_i2c_regs.h:335
#define I2C_CTRL_RESET_LEN_SET(x)
Definition: hpm_i2c_regs.h:360
#define I2C_CTRL_RESET_ON_MASK
Definition: hpm_i2c_regs.h:379
#define I2C_CTRL_DIR_GET(x)
Definition: hpm_i2c_regs.h:442
#define I2C_SETUP_ADDRESSING_SET(x)
Definition: hpm_i2c_regs.h:573
#define I2C_SETUP_DMAEN_MASK
Definition: hpm_i2c_regs.h:547
#define I2C_STATUS_LINESCL_GET(x)
Definition: hpm_i2c_regs.h:178
uint32_t hpm_stat_t
Definition: hpm_common.h:123
#define MAKE_STATUS(group, code)
Definition: hpm_common.h:132
@ status_group_i2c
Definition: hpm_common.h:137
static void i2c_clear_fifo(I2C_Type *ptr)
clear I2C fifo
Definition: hpm_i2c_drv.h:154
hpm_stat_t i2c_master_start_dma_write(I2C_Type *i2c_ptr, const uint16_t device_address, uint32_t size)
I2C master start write data by DMA.
Definition: hpm_i2c_drv.c:719
static bool i2c_get_line_scl_status(I2C_Type *ptr)
get i2c scl line status
Definition: hpm_i2c_drv.h:264
static void i2c_respond_ack(I2C_Type *ptr)
respond ACK
Definition: hpm_i2c_drv.h:144
#define I2C_CMD_NACK
Definition: hpm_i2c_drv.h:43
hpm_stat_t i2c_init_slave(I2C_Type *ptr, uint32_t src_clk_in_hz, i2c_config_t *config, const uint16_t slave_address)
I2C slave initialization.
Definition: hpm_i2c_drv.c:559
hpm_stat_t i2c_master_write(I2C_Type *ptr, const uint16_t device_address, uint8_t *buf, const uint32_t size)
I2C master write data to certain slave device.
Definition: hpm_i2c_drv.c:466
#define I2C_EVENT_BYTE_RECEIVED
Definition: hpm_i2c_drv.h:59
hpm_stat_t i2c_master_address_write(I2C_Type *ptr, const uint16_t device_address, uint8_t *addr, uint32_t addr_size_in_byte, uint8_t *buf, const uint32_t size_in_byte)
I2C master write data to specific address of certain slave device.
Definition: hpm_i2c_drv.c:280
hpm_stat_t i2c_slave_dma_transfer(I2C_Type *ptr, const uint32_t size)
I2C slave dma transfer data.
Definition: hpm_i2c_drv.c:794
enum i2c_seq_transfer_opt i2c_seq_transfer_opt_t
I2c sequential transfer options.
static void i2c_write_byte(I2C_Type *ptr, uint8_t data)
I2C write byte into FIFO.
Definition: hpm_i2c_drv.h:572
i2c_seq_transfer_opt
I2c sequential transfer options.
Definition: hpm_i2c_drv.h:119
hpm_stat_t i2c_master_seq_transmit_check_ack(I2C_Type *ptr, const uint16_t device_address, uint8_t *buf, const uint32_t size, i2c_seq_transfer_opt_t opt, bool ack_check)
sequential transmit in master I2C mode an amount of data and checks ACK in blocking
Definition: hpm_i2c_drv.c:851
static void i2c_gen_reset_signal(I2C_Type *ptr, uint8_t clk_len)
generate SCL clock as reset signal
Definition: hpm_i2c_drv.h:658
static bool i2c_fifo_is_half(I2C_Type *ptr)
check if I2C FIFO is half
Definition: hpm_i2c_drv.h:197
static uint16_t i2c_get_data_count(I2C_Type *ptr)
check data count
Definition: hpm_i2c_drv.h:167
static void i2c_enable_auto_ack(I2C_Type *ptr)
enable auto ack
Definition: hpm_i2c_drv.h:353
static bool i2c_is_reading(I2C_Type *ptr)
check if I2C is reading
Definition: hpm_i2c_drv.h:236
static void i2c_disable_auto_ack(I2C_Type *ptr)
disable auto ack
Definition: hpm_i2c_drv.h:341
hpm_stat_t i2c_master_address_read(I2C_Type *ptr, const uint16_t device_address, uint8_t *addr, uint32_t addr_size_in_byte, uint8_t *buf, const uint32_t size_in_byte)
I2C master read data from specific address of certain slave device.
Definition: hpm_i2c_drv.c:161
static void i2c_dma_enable(I2C_Type *ptr)
Enable i2c DMA.
Definition: hpm_i2c_drv.h:540
static void i2c_respond_Nack(I2C_Type *ptr)
respond NACK
Definition: hpm_i2c_drv.h:134
static bool i2c_fifo_is_empty(I2C_Type *ptr)
check if I2C FIFO is empty
Definition: hpm_i2c_drv.h:208
static void i2c_dma_disable(I2C_Type *ptr)
Disable i2c DMA.
Definition: hpm_i2c_drv.h:550
static bool i2c_get_line_sda_status(I2C_Type *ptr)
get i2c sda line status
Definition: hpm_i2c_drv.h:250
static uint32_t i2c_get_irq_setting(I2C_Type *ptr)
i2c get interrupts setting
Definition: hpm_i2c_drv.h:303
static uint32_t i2c_get_status(I2C_Type *ptr)
get status
Definition: hpm_i2c_drv.h:290
#define I2C_CMD_ACK
Definition: hpm_i2c_drv.h:42
hpm_stat_t i2c_init_master(I2C_Type *ptr, uint32_t src_clk_in_hz, i2c_config_t *config)
I2C master initialization.
Definition: hpm_i2c_drv.c:135
static uint8_t i2c_get_direction(I2C_Type *ptr)
I2C get direction.
Definition: hpm_i2c_drv.h:596
void i2c_reset(I2C_Type *ptr)
reset I2C
Definition: hpm_i2c_drv.c:128
i2c_mode
I2C mode.
Definition: hpm_i2c_drv.h:107
hpm_stat_t i2c_master_read(I2C_Type *ptr, const uint16_t device_address, uint8_t *buf, const uint32_t size)
I2C master read data from certain slave device.
Definition: hpm_i2c_drv.c:374
static void i2c_disable_irq(I2C_Type *ptr, uint32_t mask)
disable interrupts
Definition: hpm_i2c_drv.h:316
static void i2c_clear_status(I2C_Type *ptr, uint32_t mask)
clear status
Definition: hpm_i2c_drv.h:277
static bool i2c_fifo_is_full(I2C_Type *ptr)
check if I2C FIFO is full
Definition: hpm_i2c_drv.h:183
static uint8_t i2c_read_byte(I2C_Type *ptr)
I2C read byte into FIFO.
Definition: hpm_i2c_drv.h:583
hpm_stat_t i2c_master_seq_receive(I2C_Type *ptr, const uint16_t device_address, uint8_t *buf, const uint32_t size, i2c_seq_transfer_opt_t opt)
sequential receive in master I2C mode an amount of data in blocking
Definition: hpm_i2c_drv.c:956
static bool i2c_is_writing(I2C_Type *ptr)
check if I2C is writing
Definition: hpm_i2c_drv.h:222
#define I2C_CMD_CLEAR_FIFO
Definition: hpm_i2c_drv.h:44
static void i2c_enable_10bit_address_mode(I2C_Type *ptr, bool enable)
enable 10 bit address mode
Definition: hpm_i2c_drv.h:368
hpm_stat_t i2c_master_configure_transfer(I2C_Type *i2c_ptr, const uint16_t device_address, uint32_t size, bool read)
I2C master configure transfer setting.
Definition: hpm_i2c_drv.c:816
static void i2c_enable_irq(I2C_Type *ptr, uint32_t mask)
enable interrupts
Definition: hpm_i2c_drv.h:329
enum i2c_mode i2c_mode_t
I2C mode.
hpm_stat_t i2c_master_transfer(I2C_Type *ptr, const uint16_t device_address, uint8_t *buf, const uint32_t size, uint16_t flags)
data transfer on master I2C mode in blocking
Definition: hpm_i2c_drv.c:1048
hpm_stat_t i2c_master_start_dma_read(I2C_Type *i2c_ptr, const uint16_t device_address, uint32_t size)
I2C master start read data by DMA.
Definition: hpm_i2c_drv.c:757
hpm_stat_t i2c_slave_read(I2C_Type *ptr, uint8_t *buf, const uint32_t size)
I2C slave read data.
Definition: hpm_i2c_drv.c:652
hpm_stat_t i2c_slave_write(I2C_Type *ptr, uint8_t *buf, const uint32_t size)
I2C slave write data.
Definition: hpm_i2c_drv.c:587
@ i2c_next_frame
Definition: hpm_i2c_drv.h:121
@ i2c_last_frame
Definition: hpm_i2c_drv.h:122
@ i2c_frist_frame
Definition: hpm_i2c_drv.h:120
@ status_i2c_invalid_data
Definition: hpm_i2c_drv.h:26
@ status_i2c_transmit_not_completed
Definition: hpm_i2c_drv.h:28
@ status_i2c_no_addr_hit
Definition: hpm_i2c_drv.h:27
@ status_i2c_no_ack
Definition: hpm_i2c_drv.h:25
@ status_i2c_not_supported
Definition: hpm_i2c_drv.h:29
@ i2c_mode_fast_plus
Definition: hpm_i2c_drv.h:110
@ i2c_mode_normal
Definition: hpm_i2c_drv.h:108
@ i2c_mode_fast
Definition: hpm_i2c_drv.h:109
static void size
Definition: hpm_math.h:6899
static hpm_stat_t read(void *ops, hpm_serial_nor_transfer_seq_t *cmd_seq)
Definition: hpm_serial_nor_host_spi.c:309
Definition: hpm_i2c_regs.h:12
__RW uint32_t STATUS
Definition: hpm_i2c_regs.h:16
__RW uint32_t CMD
Definition: hpm_i2c_regs.h:20
__RW uint32_t DATA
Definition: hpm_i2c_regs.h:18
__RW uint32_t CTRL
Definition: hpm_i2c_regs.h:19
__RW uint32_t SETUP
Definition: hpm_i2c_regs.h:21
__RW uint32_t INTEN
Definition: hpm_i2c_regs.h:15
I2C config.
Definition: hpm_i2c_drv.h:99
uint8_t i2c_mode
Definition: hpm_i2c_drv.h:101
bool is_10bit_addressing
Definition: hpm_i2c_drv.h:100