• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 ASR Microelectronics (Shanghai) Co., Ltd. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef _DUET_I2C_H_
17 #define _DUET_I2C_H_
18 #include <stdint.h>
19 #include <errno.h>
20 
21 #define I2C_MASTER                  (0)
22 #define I2C_SLAVE                   (1)
23 #define I2C_ROLE_MODE               I2C_MASTER
24 #define I2C_ADDRESS                 0x66
25 
26 #define I2C_SCL_STATUS_BIT  (1)
27 #define I2C_SDA_STATUS_BIT  (0)
28 
29 // TWSI_NEW
30 #define I2C_INTERRUPT_RX_FIFO_OVERRUN_EN   (1 << 31)
31 #define I2C_INTERRUPT_RX_FIFO_FULL_EN      (1 << 30)
32 #define I2C_INTERRUPT_TX_FIFO_EMPTY_EN     (1 << 28)
33 #define I2C_INTERRUPT_RX_FIFO_HALF_FULL_EN (1 << 29)
34 #define I2C_INTERRUPT_TRANS_DONE_EN        (1 << 27)
35 #define I2C_INTERRUPT_SLAVE_ADDR_DET_EN    (1 << 23)
36 #define I2C_INTERRUPT_ARBT_LOSS_DET_EN     (1 << 18)
37 #define I2C_INTERRUPT_MASTER_STOP_DET_EN   (1 << 25)
38 #define I2C_INTERRUPT_SLAVE_STOP_DET_EN    (1 << 24)
39 #define I2C_INTERRUPT_BUS_ERROR_DET_EN     (1 << 22)
40 #define I2C_INTERRUPT_RX_BUFER_FULL_EN     (1 << 20)
41 #define I2C_INTERRUPT_TX_BUFFER_EMPTY_EN   (1 << 19)
42 
43 #define I2C_STATUS_RX_FIFO_OVERRUN         (1 << 31)
44 #define I2C_STATUS_RX_FIFO_FULL            (1 << 30)
45 #define I2C_STATUS_TX_FIFO_EMPTY           (1 << 28)
46 #define I2C_STATUS_TX_FIFO_FULL            (0xffff)
47 #define I2C_STATUS_RX_FIFO_HALF_FULL       (1 << 29)
48 #define I2C_STATUS_TRANS_DONE              (1 << 27)
49 #define I2C_STATUS_MASTER_STOP_DET         (1 << 26)
50 #define I2C_STATUS_SLAVE_STOP_DET          (1 << 24)
51 #define I2C_STATUS_SLAVE_ADDR_DET          (1 << 23)
52 #define I2C_STATUS_BUS_ERROR_DET           (1 << 22)
53 #define I2C_STATUS_RX_BUFER_FULL           (1 << 20)
54 #define I2C_STATUS_TX_BUFFER_EMPTY         (1 << 19)
55 #define I2C_STATUS_UNIT_BUSY               (1 << 15)
56 #define I2C_STATUS_BUS_BUSY                (1 << 16)
57 #define I2C_STATUS_ACK_NACK                (1 << 14)
58 #define I2C_STATUS_RW_MODE                 (1 << 13)
59 
60 #define I2C_TRANS_BEGIN                 (1 << 4)
61 #define I2C_MST_FIFO_MODE_ENABLE        (1 << 5)
62 #define I2C_MST_FIFO_MODE_DISABLE       (0)
63 
64 #define I2C_MODE_STANDARD           (0)
65 #define I2C_MODE_FAST               (1)
66 #define I2C_MODE_HIGH_SPEED_0       (2)    // not supported in sonata
67 #define I2C_MODE_HIGH_SPEED_1       (3)    // not supported in sonata
68 #define I2C_MODE_SET_POS            (8)
69 #define I2C_MODE_SET_MASK           (3 << I2C_MODE_SET_POS)
70 #define I2C_HS_MASTER_CODE          (0x0A)
71 
72 #define I2C_UNIT_RESET              (1 << 10)
73 #define I2C_DMA_ENABLE              (1 << 7)
74 #define I2C_UNIT_ENABLE             (1 << 14)
75 #define I2C_SCL_ENABLE              (1 << 13)
76 
77 /* fifo mode control */
78 #define I2C_TB                      (1 << 11)
79 #define I2C_SEND_NACK               (1 << 10)
80 #define I2C_SEND_STOP               (1 << 9)
81 #define I2C_SEND_START              (1 << 8)
82 #define I2C_MASTER_ABORT            (1 << 12)
83 
84 /* non fifo mode control */
85 #define I2C_CR_TB                   (I2C_TB >> 8)
86 #define I2C_CR_SEND_NACK            (I2C_SEND_NACK >> 8)
87 #define I2C_CR_SEND_STOP            (I2C_SEND_STOP >> 8)
88 #define I2C_CR_SEND_START           (I2C_SEND_START >> 8)
89 
90 #define I2C_DEVICE0     0
91 #define I2C_DEVICE1     1
92 #define DUET_I2C_NUM    2
93 
94 #define I2C_READ                    (1)
95 #define I2C_WRITE                   (0)
96 
97 #define I2C_TX_FIFO_DEPTH           (8)
98 #define I2C_RX_FIFO_DEPTH           (16)
99 
100 #define I2C_MEM_ADDR_SIZE_8         (0)
101 #define I2C_MEM_ADDR_SIZE_16        (1)
102 #define I2C_MEM_ADDR_SIZE_32        (3)
103 
104 #define DUMMY_BYTE                  (0x5a)
105 #define MAX_RX_SIZE                 (100)
106 #define TIME_OUT                    (1000)
107 #define I2C_WAIT_FOREVER            (0xffffffff)
108 
109 #define I2C_CLK               (52000000)
110 #define I2C_STANDARD_SPEED    (100000)
111 #define I2C_FAST_SPEED        (400000)
112 #define I2C_HIGH_SPEED        (1700000)
113 
114 // error number
115 #define I2C_SUCCESS     0 // success
116 #define EI2CNUMERR      1 // I2C port number error
117 #define ETIMEOUT        2 // I2C timeout
118 #define EBUSERR         3 // I2C bus error
119 
120 // I2C0 pad group 0: pad 2,3
121 // I2C0 pad group 1: pad 20, 21
122 // I2C1 pad group 0: pad 8, 9
123 // I2C1 pad group 1: pad 22, 23
124 #define I2C0_PAD_GROUP0_ENABLE          1
125 #define I2C0_PAD_GROUP1_ENABLE          0
126 #define I2C1_PAD_GROUP0_ENABLE          1
127 #define I2C1_PAD_GROUP1_ENABLE          0
128 
129 typedef void (*duet_i2c_slv_tx_callback_func)(void);
130 typedef void (*duet_i2c_slv_rx_callback_func)(uint8_t);
131 typedef struct {
132     duet_i2c_slv_tx_callback_func tx_func;
133     duet_i2c_slv_rx_callback_func rx_func;
134 } duet_i2c_slv_callback_t;
135 
136 typedef struct {
137     uint32_t address_width;
138     uint32_t freq;
139     uint8_t  mode;
140     uint16_t dev_addr;
141 } duet_i2c_config_t;
142 
143 typedef struct {
144     uint8_t     speed_mode;
145     uint8_t     fifo_mode;
146     uint8_t     dma_mode;
147     uint8_t     reserved;
148 } duet_i2c_priv_cfg_t;
149 
150 typedef struct {
151     uint8_t      port;    /* i2c port */
152     duet_i2c_config_t config;  /* i2c config */
153     void        *priv;    /* priv data */
154 } duet_i2c_dev_t;
155 
156 int32_t duet_i2c_init(duet_i2c_dev_t *i2c);
157 int32_t duet_i2c_master_send(duet_i2c_dev_t *i2c, uint16_t dev_addr, const uint8_t *data, uint16_t size,
158                              uint32_t timeout);
159 int32_t duet_i2c_master_recv(duet_i2c_dev_t *i2c, uint16_t dev_addr, uint8_t *data, uint16_t size, uint32_t timeout);
160 int8_t duet_i2c_master_repeated_write_read(I2C_TypeDef *I2Cx, uint8_t slave_addr,
161         const uint8_t *pwdata, uint8_t *rdata,
162         uint32_t wlen, uint32_t rlen);
163 int32_t duet_i2c_mem_write(duet_i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr,
164                            uint16_t mem_addr_size, const uint8_t *data, uint16_t len,
165                            uint32_t timeout);
166 
167 int32_t duet_i2c_mem_read(duet_i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr,
168                           uint16_t mem_addr_size, uint8_t *data, uint16_t len,
169                           uint32_t timeout);
170 int32_t duet_i2c_finalize(duet_i2c_dev_t *i2c);
171 void duet_i2c_master_dma_send(uint8_t iic_idx, uint32_t *data, uint16_t len);
172 void duet_i2c_master_dma_recv(uint8_t iic_idx, uint32_t *data, uint16_t len);
i2c_write_byte_cmd(I2C_TypeDef * I2Cx,uint8_t data)173 __STATIC_INLINE void i2c_write_byte_cmd(I2C_TypeDef *I2Cx, uint8_t data)
174 {
175     I2Cx->WFIFO = data | I2C_WRITE | I2C_TB;
176 }
177 
i2c_read_byte_cmd(I2C_TypeDef * I2Cx)178 __STATIC_INLINE void i2c_read_byte_cmd(I2C_TypeDef *I2Cx)
179 {
180     I2Cx->WFIFO = I2C_TB;
181 }
182 
183 /* read one byte from fifo or buffer register */
i2c_receive_byte(I2C_TypeDef * I2Cx)184 __STATIC_INLINE uint8_t i2c_receive_byte(I2C_TypeDef *I2Cx)
185 {
186     if (I2Cx->CR & I2C_MST_FIFO_MODE_ENABLE) {
187         return I2Cx->RFIFO;
188     } else {
189         return I2Cx->DBR;
190     }
191 }
192 
193 /* write one byte to fifo or buffer reigster */
i2c_write_byte(I2C_TypeDef * I2Cx,uint16_t data)194 __STATIC_INLINE void i2c_write_byte(I2C_TypeDef *I2Cx, uint16_t data)
195 {
196     // data = data_to_write | any_conrol_bit
197     if (I2Cx->CR & I2C_MST_FIFO_MODE_ENABLE) {
198         I2Cx->WFIFO = data;
199     } else {
200         I2Cx->DBR = data;
201     }
202 }
203 
i2c_clear_interrupt(I2C_TypeDef * I2Cx,uint32_t I2C_INTR)204 __STATIC_INLINE void i2c_clear_interrupt(I2C_TypeDef *I2Cx, uint32_t I2C_INTR)
205 {
206     I2Cx->SR |= I2C_INTR;
207 }
208 
209 /* I2C needs to set TB for transmitting and receiving a byte
210    this function is mainly for when I2C is used as a slave
211 */
i2c_set_tb(I2C_TypeDef * I2Cx)212 __STATIC_INLINE void i2c_set_tb(I2C_TypeDef *I2Cx)
213 {
214     I2Cx->CR |= I2C_CR_TB;
215 }
216 
217 #endif // _DUET_I2C_H_