• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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