1 /******************************************************************************
2 * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3 * All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************/
18 #include "i2c.h"
19
20 static unsigned char i2c_dma_tx_chn;
21 static unsigned char i2c_dma_rx_chn;
22
23 dma_config_t i2c_tx_dma_config = {
24 .dst_req_sel = DMA_REQ_I2C_TX, // tx req
25 .src_req_sel = 0,
26 .dst_addr_ctrl = DMA_ADDR_FIX,
27 .src_addr_ctrl = DMA_ADDR_INCREMENT, // increment
28 .dstmode = DMA_HANDSHAKE_MODE, // handshake
29 .srcmode = DMA_NORMAL_MODE,
30 .dstwidth = DMA_CTR_WORD_WIDTH, // must word
31 .srcwidth = DMA_CTR_WORD_WIDTH, // must word
32 .src_burst_size = 0, // must 0
33 .read_num_en = 0,
34 .priority = 0,
35 .write_num_en = 0,
36 .auto_en = 0, // must 0
37 };
38 dma_config_t i2c_rx_dma_config = {
39 .dst_req_sel = DMA_REQ_AUDIO0_TX,
40 .src_req_sel = DMA_REQ_I2C_RX,
41 .dst_addr_ctrl = DMA_ADDR_INCREMENT,
42 .src_addr_ctrl = DMA_ADDR_FIX,
43 .dstmode = DMA_NORMAL_MODE,
44 .srcmode = DMA_HANDSHAKE_MODE,
45 .dstwidth = DMA_CTR_WORD_WIDTH, // must word
46 .srcwidth = DMA_CTR_WORD_WIDTH, // must word
47 .src_burst_size = 0,
48 .read_num_en = 0,
49 .priority = 0,
50 .write_num_en = 0,
51 .auto_en = 0, // must 0
52 };
53
54 /*
55 * This parameter is 0x20 by default, that is, each write or read API opens the stop command.
56 * if g_i2c_stop_en=0x00,it means every write or read API will disable stop command.
57 */
58 unsigned char g_i2c_stop_en = 0x20;
59
60 /**
61 * @brief The function of this interface is equivalent to
62 * that after the user finishes calling the write or read interface, the stop signal is not sent,
63 * and then the write or read command is executed again.
64 * The driver defaults that every write or read API will send a stop command at the end
65 * @param[in] en - Input parameters.Decide whether to disable the stop function after each write or read interface
66 * @return none
67 */
i2c_master_send_stop(unsigned char en)68 void i2c_master_send_stop(unsigned char en)
69 {
70 if (en == 1) {
71 g_i2c_stop_en = 0x20;
72 } else {
73 g_i2c_stop_en = 0x00;
74 }
75 }
76
77 /**
78 * @brief This function selects a pin port for I2C interface.
79 * @param[in] sda_pin - the pin port selected as I2C sda pin port.
80 * @param[in] scl_pin - the pin port selected as I2C scl pin port.
81 * @return none
82 */
i2c_set_pin(i2c_sda_pin_e sda_pin,i2c_scl_pin_e scl_pin)83 void i2c_set_pin(i2c_sda_pin_e sda_pin, i2c_scl_pin_e scl_pin)
84 {
85 unsigned char val = 0;
86 unsigned char mask = 0xff;
87
88 // disable sda_pin and scl_pin gpio function.
89 gpio_function_dis(scl_pin);
90 gpio_function_dis(sda_pin);
91
92 // enable gpio as i2c sda function.
93 if (sda_pin == I2C_GPIO_SDA_B3) {
94 mask = (unsigned char)~(BIT(7) | BIT(6));
95 val = BIT(6);
96 } else if (sda_pin == I2C_GPIO_SDA_C2) {
97 mask = (unsigned char)~(BIT(5) | BIT(4));
98 val = 0;
99 } else if (sda_pin == I2C_GPIO_SDA_E2) {
100 mask = (unsigned char)~(BIT(5) | BIT(4));
101 val = 0;
102 } else if (sda_pin == I2C_GPIO_SDA_E3) {
103 mask = (unsigned char)~(BIT(7) | BIT(6));
104 val = 0;
105 }
106
107 reg_gpio_func_mux(sda_pin) = (reg_gpio_func_mux(sda_pin) & mask) | val;
108
109 // enable gpio as i2c scl function.
110 if (scl_pin == I2C_GPIO_SCL_B2) {
111 mask = (unsigned char)~(BIT(5) | BIT(4));
112 val = BIT(4);
113 } else if (scl_pin == I2C_GPIO_SCL_C1) {
114 mask = (unsigned char)~(BIT(3) | BIT(2));
115 val = 0;
116 } else if (scl_pin == I2C_GPIO_SCL_E0) {
117 mask = (unsigned char)~(BIT(1) | BIT(0));
118 val = 0;
119 } else if (scl_pin == I2C_GPIO_SCL_E1) {
120 mask = (unsigned char)~(BIT(3) | BIT(2));
121 val = 0;
122 }
123
124 reg_gpio_func_mux(scl_pin) = (reg_gpio_func_mux(scl_pin) & mask) | val;
125
126 gpio_set_up_down_res(sda_pin, GPIO_PIN_PULLUP_10K);
127 gpio_set_up_down_res(scl_pin, GPIO_PIN_PULLUP_10K);
128 gpio_input_en(sda_pin); // enable sda input
129 gpio_input_en(scl_pin); // enable scl input
130 }
131
132 /**
133 * @brief This function serves to enable i2c master function.
134 * @param[in] none.
135 * @return none.
136 */
i2c_master_init(void)137 void i2c_master_init(void)
138 {
139 reg_i2c_sct0 |= FLD_I2C_MASTER; // i2c master enable.
140 }
141
142 /**
143 * @brief This function serves to set the i2c clock frequency.The i2c clock is consistent with the system clock.
144 * @param[in] clock - the division factor of I2C clock,
145 * I2C frequency = System_clock / (4*DivClock).
146 * @return none
147 */
i2c_set_master_clk(unsigned char clock)148 void i2c_set_master_clk(unsigned char clock)
149 {
150 // i2c frequency = system_clock/(4*clock)
151 reg_i2c_sp = clock;
152
153 // set enable flag.
154 reg_clk_en0 |= FLD_CLK0_I2C_EN;
155 }
156
157 /**
158 * @brief This function serves to enable slave mode.
159 * @param[in] id - the id of slave device.it contains write or read bit,the laster bit is write or read bit.
160 * ID|0x01 indicate read. ID&0xfe indicate write.
161 * @return none
162 */
i2c_slave_init(unsigned char id)163 void i2c_slave_init(unsigned char id)
164 {
165 reg_i2c_sct0 &= (~FLD_I2C_MASTER); // enable slave mode.
166
167 reg_i2c_id = id; // defaul eagle slave ID is 0x5a
168 }
169
170 /**
171 * @brief The function of this API is to ensure that the data can be successfully sent out.
172 * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a.
173 * @param[in] data - The data to be sent, The first three bytes can be set as the RAM address of the slave.
174 * @param[in] len - This length is the total length, including both the length of the slave RAM address
175 * and the length of the data to be sent.
176 * @return 0 : the master receive NACK after sending out the id and then send stop.
177 * 1: the master sent the data successfully,(master does not detect NACK in data phase)
178 */
i2c_master_write(unsigned char id,unsigned char * data,unsigned char len)179 unsigned char i2c_master_write(unsigned char id, unsigned char *data, unsigned char len)
180 {
181 BM_SET(reg_i2c_status, FLD_I2C_TX_CLR); // clear index
182 // set i2c master write.
183 reg_i2c_data_buf(0) = id & (~FLD_I2C_WRITE_READ_BIT); // BIT(0):R:High W:Low;
184 reg_i2c_sct1 = (FLD_I2C_LS_ADDR | FLD_I2C_LS_START);
185 while (i2c_master_busy()) {
186 }
187 if (reg_i2c_mst & FLD_I2C_ACK_IN) {
188 reg_i2c_sct1 = (FLD_I2C_LS_STOP);
189 while (i2c_master_busy()) {
190 }
191 return 0;
192 }
193 reg_i2c_len = len;
194 // write data
195 unsigned int cnt = 0;
196 while (cnt < len) {
197 if (i2c_get_tx_buf_cnt() < 8) {
198 reg_i2c_data_buf(cnt % 4) = data[cnt]; // write data
199 cnt++;
200 if (cnt == 1) {
201 reg_i2c_sct1 = (FLD_I2C_LS_DATAW | g_i2c_stop_en); // launch stop cycle
202 }
203 }
204 }
205
206 while (i2c_master_busy()) {
207 }
208
209 return 1;
210 }
211
212 /**
213 * @brief This function serves to read a packet of data from the specified address of slave device
214 * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a.
215 * @param[in] data - Store the read data
216 * @param[in] len - The total length of the data read back.
217 * @return 0 : the master receive NACK after sending out the id and then send stop.
218 * 1: the master receive the data successfully.
219 */
i2c_master_read(unsigned char id,unsigned char * data,unsigned char len)220 unsigned char i2c_master_read(unsigned char id, unsigned char *data, unsigned char len)
221 {
222 // set i2c master read.
223 BM_SET(reg_i2c_status, FLD_I2C_RX_CLR); // clear index
224 reg_i2c_sct0 |= FLD_I2C_RNCK_EN; // i2c rnck enable.
225 reg_i2c_data_buf(0) = (id | FLD_I2C_WRITE_READ_BIT); // BIT(0):R:High W:Low;
226 reg_i2c_sct1 = (FLD_I2C_LS_ADDR | FLD_I2C_LS_START);
227 while (i2c_master_busy()) {
228 }
229 if (reg_i2c_mst & FLD_I2C_ACK_IN) {
230 reg_i2c_sct1 = (FLD_I2C_LS_STOP);
231 while (i2c_master_busy()) {
232 }
233 return 0;
234 }
235 reg_i2c_sct1 = (FLD_I2C_LS_DATAR | FLD_I2C_LS_ID_R | g_i2c_stop_en);
236 reg_i2c_len = len;
237 unsigned int cnt = 0;
238 while (cnt < len) {
239 if (i2c_get_rx_buf_cnt() > 0) {
240 data[cnt] = reg_i2c_data_buf(cnt % 4);
241 cnt++;
242 }
243 }
244 while (i2c_master_busy()) {
245 }
246 return 1;
247 }
248
249 /**
250 * @brief This function serves to write data and restart read data.
251 * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a.
252 * @param[in] wr_data - The data to be sent, The first three bytes can be set as the RAM address of the slave.
253 * @param[in] wr_len - This length is the total length, including both the length of the slave RAM address
254 * and the length of the data to be sent.
255 * @param[in] rd_data - Store the read data
256 * @param[in] rd_len - The total length of the data read back.
257 * @return 0 : the master receive NACK after sending out the id and then send stop.
258 * 1: the master receive the data successfully.
259 */
i2c_master_write_read(unsigned char id,unsigned char * wr_data,unsigned char wr_len,unsigned char * rd_data,unsigned char rd_len)260 unsigned char i2c_master_write_read(unsigned char id, unsigned char *wr_data, unsigned char wr_len,
261 unsigned char *rd_data, unsigned char rd_len)
262 {
263 BM_SET(reg_i2c_status, FLD_I2C_TX_CLR); // clear index
264 // set i2c master write.
265 reg_i2c_data_buf(0) = id & (~FLD_I2C_WRITE_READ_BIT); // BIT(0):R:High W:Low;
266 reg_i2c_sct1 = (FLD_I2C_LS_ADDR | FLD_I2C_LS_START);
267 while (i2c_master_busy()) {
268 }
269 if (reg_i2c_mst & FLD_I2C_ACK_IN) {
270 reg_i2c_sct1 = (FLD_I2C_LS_STOP);
271 while (i2c_master_busy()) {
272 }
273 return 0;
274 }
275 reg_i2c_len = wr_len;
276 // write data
277 unsigned int cnt = 0;
278 while (cnt < wr_len) {
279 if (i2c_get_tx_buf_cnt() < 8) {
280 reg_i2c_data_buf(cnt % 4) = wr_data[cnt]; // write data
281 cnt++;
282 if (cnt == 1) {
283 reg_i2c_sct1 = (FLD_I2C_LS_DATAW);
284 }
285 }
286 }
287 while (i2c_master_busy()) {
288 }
289
290 // set i2c master read.
291 BM_SET(reg_i2c_status, FLD_I2C_RX_CLR); // clear index
292 reg_i2c_sct0 |= FLD_I2C_RNCK_EN; // i2c rnck enable.
293 reg_i2c_data_buf(0) = (id | FLD_I2C_WRITE_READ_BIT); // BIT(0):R:High W:Low;
294 reg_i2c_sct1 = (FLD_I2C_LS_ADDR | FLD_I2C_LS_START);
295 while (i2c_master_busy()) {
296 }
297
298 reg_i2c_sct1 = (FLD_I2C_LS_DATAR | FLD_I2C_LS_ID_R | FLD_I2C_LS_STOP);
299 reg_i2c_len = rd_len;
300 cnt = 0;
301 while (cnt < rd_len) {
302 if (i2c_get_rx_buf_cnt() > 0) {
303 rd_data[cnt] = reg_i2c_data_buf(cnt % 4);
304 cnt++;
305 }
306 }
307 while (i2c_master_busy()) {
308 }
309
310 return 1;
311 }
312
313 /**
314 * @brief The function of this API is just to write data to the i2c tx_fifo by DMA.
315 * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a.
316 * @param[in] data - The data to be sent, The first three bytes represent the RAM address of the slave.
317 * @param[in] len - This length is the total length, including both the length of the slave RAM address
318 * and the length of the data to be sent.
319 * @return none.
320 */
i2c_master_write_dma(unsigned char id,unsigned char * data,unsigned char len)321 void i2c_master_write_dma(unsigned char id, unsigned char *data, unsigned char len)
322 {
323 // set id.
324 reg_i2c_id = (id & (~FLD_I2C_WRITE_READ_BIT)); // BIT(0):R:High W:Low
325
326 dma_set_size(i2c_dma_tx_chn, len, DMA_WORD_WIDTH);
327 dma_set_address(i2c_dma_tx_chn, (unsigned int)convert_ram_addr_cpu2bus(data), reg_i2c_data_buf0_addr);
328 dma_chn_en(i2c_dma_tx_chn);
329
330 reg_i2c_len = len;
331 reg_i2c_sct1 = (FLD_I2C_LS_ID | FLD_I2C_LS_START | FLD_I2C_LS_DATAW | g_i2c_stop_en);
332 }
333
334 /**
335 * @brief This function serves to read a packet of data from the specified address of slave device.
336 * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a.
337 * @param[in] rx_data - Store the read data
338 * @param[in] len - The total length of the data read back.
339 * @return none.
340 */
i2c_master_read_dma(unsigned char id,unsigned char * rx_data,unsigned char len)341 void i2c_master_read_dma(unsigned char id, unsigned char *rx_data, unsigned char len)
342 {
343 reg_i2c_sct0 |= FLD_I2C_RNCK_EN; // i2c rnck enable
344
345 // set i2c master read.
346 reg_i2c_id = (id | FLD_I2C_WRITE_READ_BIT); // BIT(0):R:High W:Low
347
348 dma_set_size(i2c_dma_rx_chn, len, DMA_WORD_WIDTH);
349 dma_set_address(i2c_dma_rx_chn, reg_i2c_data_buf0_addr, (unsigned int)convert_ram_addr_cpu2bus(rx_data));
350 dma_chn_en(i2c_dma_rx_chn);
351
352 reg_i2c_len = len;
353 reg_i2c_sct1 = (FLD_I2C_LS_ID | FLD_I2C_LS_DATAR | FLD_I2C_LS_START | FLD_I2C_LS_ID_R | g_i2c_stop_en);
354 }
355
356 /**
357 * @brief This function serves to send a packet of data to master device.
358 * It will trigger after the master sends the read sequence.
359 * @param[in] data - the pointer of tx_buff.
360 * @param[in] len - The total length of the data .
361 * @return none.
362 */
i2c_slave_set_tx_dma(unsigned char * data,unsigned char len)363 void i2c_slave_set_tx_dma(unsigned char *data, unsigned char len)
364 {
365 dma_set_address(i2c_dma_tx_chn, (unsigned int)convert_ram_addr_cpu2bus(data), reg_i2c_data_buf0_addr);
366 dma_set_size(i2c_dma_tx_chn, len, DMA_WORD_WIDTH);
367 dma_chn_en(i2c_dma_tx_chn);
368 }
369
370 /**
371 * @brief This function serves to receive a packet of data from master device,
372 * It will trigger after the master sends the write sequence.
373 * @param[in] data - the pointer of rx_buff.
374 * @param[in] len - The total length of the data.
375 * @return none.
376 */
i2c_slave_set_rx_dma(unsigned char * data,unsigned char len)377 void i2c_slave_set_rx_dma(unsigned char *data, unsigned char len)
378 {
379 dma_set_address(i2c_dma_rx_chn, reg_i2c_data_buf0_addr, (unsigned int)convert_ram_addr_cpu2bus(data));
380 dma_set_size(i2c_dma_rx_chn, len, DMA_WORD_WIDTH);
381 dma_chn_en(i2c_dma_rx_chn);
382 }
383
384 /**
385 * @brief This function serves to receive data .
386 * @param[in] data - the data need read.
387 * @param[in] len - The total length of the data
388 * @return none
389 */
i2c_slave_read(unsigned char * data,unsigned char len)390 void i2c_slave_read(unsigned char *data, unsigned char len)
391 {
392 unsigned int cnt = 0;
393 while (cnt < len) {
394 if (i2c_get_rx_buf_cnt() > 0) {
395 data[cnt] = reg_i2c_data_buf(cnt % 4);
396 cnt++;
397 }
398 }
399 }
400
401 /**
402 * @brief This function serves to receive uart data by byte with not DMA method.
403 * @param[in] data - the data need send.
404 * @param[in] len - The total length of the data.
405 * @return none
406 */
i2c_slave_write(unsigned char * data,unsigned char len)407 void i2c_slave_write(unsigned char *data, unsigned char len)
408 {
409 i2c_clr_fifo(I2C_TX_BUFF_CLR);
410 unsigned int cnt = 0;
411 while (cnt < len) {
412 if (i2c_get_tx_buf_cnt() < 8) {
413 reg_i2c_data_buf(cnt % 4) = data[cnt];
414 cnt++;
415 }
416 }
417 }
418
419 /**
420 * @brief This function serves to set i2c tx_dam channel and config dma tx default.
421 * @param[in] chn: dma channel.
422 * @return none
423 */
i2c_set_tx_dma_config(dma_chn_e chn)424 void i2c_set_tx_dma_config(dma_chn_e chn)
425 {
426 i2c_dma_tx_chn = chn;
427 dma_config(chn, &i2c_tx_dma_config);
428 }
429
430 /**
431 * @brief This function serves to set i2c rx_dam channel and config dma rx default.
432 * @param[in] chn: dma channel.
433 * @return none
434 */
i2c_set_rx_dma_config(dma_chn_e chn)435 void i2c_set_rx_dma_config(dma_chn_e chn)
436 {
437 i2c_dma_rx_chn = chn;
438 dma_config(chn, &i2c_rx_dma_config);
439 }
440